fix: implemented TD-07, chat await path with deadline
This commit is contained in:
@@ -279,6 +279,24 @@ defmodule BDS.AITest do
|
||||
end
|
||||
end
|
||||
|
||||
defmodule ShutdownAwareBlockingRuntime do
|
||||
def generate(endpoint, request, opts) do
|
||||
Process.flag(:trap_exit, true)
|
||||
|
||||
test_pid = Keyword.fetch!(opts, :test_pid)
|
||||
send(test_pid, {:blocking_runtime_started, endpoint, request, self()})
|
||||
|
||||
receive do
|
||||
{:EXIT, _from, :shutdown} ->
|
||||
send(test_pid, :blocking_runtime_shutdown)
|
||||
exit(:shutdown)
|
||||
after
|
||||
5_000 ->
|
||||
{:ok, %{content: "too late", usage: %{input_tokens: 1, output_tokens: 1}}}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Always returns another tool call and never a final answer, so a chat would
|
||||
# loop forever if the round count were not bounded.
|
||||
defmodule LoopingToolRuntime do
|
||||
@@ -1772,6 +1790,64 @@ defmodule BDS.AITest do
|
||||
assert Enum.map(messages, & &1.role) == [:user]
|
||||
end
|
||||
|
||||
@tag :chat_timeout
|
||||
test "send_chat_message times out a stalled chat round and keeps persisted state consistent" do
|
||||
original_chat_config = Application.get_env(:bds, :chat, [])
|
||||
original_http_config = Application.get_env(:bds, BDS.AI.HttpClient, [])
|
||||
|
||||
Application.put_env(
|
||||
:bds,
|
||||
:chat,
|
||||
original_chat_config
|
||||
|> Keyword.put(:max_tool_rounds, 1)
|
||||
|> Keyword.put(:await_timeout_margin_ms, 25)
|
||||
)
|
||||
|
||||
Application.put_env(
|
||||
:bds,
|
||||
BDS.AI.HttpClient,
|
||||
original_http_config
|
||||
|> Keyword.put(:connect_timeout_ms, 50)
|
||||
|> Keyword.put(:receive_timeout_ms, 50)
|
||||
)
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:bds, :chat, original_chat_config)
|
||||
Application.put_env(:bds, BDS.AI.HttpClient, original_http_config)
|
||||
end)
|
||||
|
||||
assert {:ok, _endpoint} =
|
||||
BDS.AI.put_endpoint(
|
||||
:online,
|
||||
%{
|
||||
url: "https://api.example.test/v1",
|
||||
api_key: "online-secret",
|
||||
model: "gpt-4o-mini"
|
||||
},
|
||||
secret_backend: FakeSecretBackend
|
||||
)
|
||||
|
||||
assert {:ok, conversation} = BDS.AI.start_chat(%{model: "gpt-4o-mini"})
|
||||
|
||||
started_at = System.monotonic_time(:millisecond)
|
||||
|
||||
assert {:error, :chat_timeout} =
|
||||
BDS.AI.send_chat_message(conversation.id, "Please wait forever",
|
||||
runtime: ShutdownAwareBlockingRuntime,
|
||||
test_pid: self(),
|
||||
secret_backend: FakeSecretBackend
|
||||
)
|
||||
|
||||
elapsed_ms = System.monotonic_time(:millisecond) - started_at
|
||||
|
||||
assert elapsed_ms < 1_000
|
||||
assert_receive {:blocking_runtime_started, _endpoint, %{operation: :chat}, _pid}, 500
|
||||
assert_receive :blocking_runtime_shutdown, 500
|
||||
|
||||
messages = BDS.AI.list_chat_messages(conversation.id)
|
||||
assert Enum.map(messages, & &1.role) == [:user]
|
||||
end
|
||||
|
||||
test "get_surface_state and put_surface_state persist and restore surface UI state" do
|
||||
assert {:ok, conversation} = BDS.AI.start_chat(%{title: "Surface State", model: "gpt-4.1"})
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
defmodule BDS.WxrParserTest do
|
||||
use ExUnit.Case, async: true
|
||||
use ExUnit.Case, async: false
|
||||
|
||||
alias BDS.WxrParser
|
||||
|
||||
@@ -102,6 +102,8 @@ defmodule BDS.WxrParserTest do
|
||||
</rss>
|
||||
"""
|
||||
|
||||
_warmup = WxrParser.parse_xml(sample_wxr_xml())
|
||||
|
||||
atom_count_before = :erlang.system_info(:atom_count)
|
||||
parsed = WxrParser.parse_xml(xml)
|
||||
atom_count_after = :erlang.system_info(:atom_count)
|
||||
|
||||
Reference in New Issue
Block a user