Serialize Matrix chat sends
This commit is contained in:
parent
4533118b68
commit
17d580096b
4 changed files with 281 additions and 79 deletions
|
|
@ -61,6 +61,35 @@ class LegacyAgentApi:
|
|||
self.last_tokens_used = 7
|
||||
|
||||
|
||||
class BlockingChatAgentApi:
|
||||
def __init__(self, chat_id: str) -> None:
|
||||
self.chat_id = chat_id
|
||||
self.calls: list[str] = []
|
||||
self.connect_calls = 0
|
||||
self.close_calls = 0
|
||||
self.last_tokens_used = 0
|
||||
self.active_calls = 0
|
||||
self.max_active_calls = 0
|
||||
self.started = asyncio.Event()
|
||||
self.release = asyncio.Event()
|
||||
|
||||
async def connect(self) -> None:
|
||||
self.connect_calls += 1
|
||||
|
||||
async def close(self) -> None:
|
||||
self.close_calls += 1
|
||||
|
||||
async def send_message(self, text: str):
|
||||
self.calls.append(text)
|
||||
self.active_calls += 1
|
||||
self.max_active_calls = max(self.max_active_calls, self.active_calls)
|
||||
self.started.set()
|
||||
await self.release.wait()
|
||||
self.active_calls -= 1
|
||||
yield FakeChunk(text)
|
||||
self.last_tokens_used = len(text)
|
||||
|
||||
|
||||
def test_agent_api_wrapper_uses_modern_constructor_when_available(monkeypatch):
|
||||
calls: list[dict[str, object]] = []
|
||||
|
||||
|
|
@ -263,6 +292,42 @@ async def test_real_platform_client_creates_distinct_clients_per_chat():
|
|||
assert agent_api.instances["chat-2"].calls == ["world"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_real_platform_client_serializes_same_chat_streams_across_send_paths():
|
||||
agent_api = FakeAgentApiFactory()
|
||||
agent_api.instances["chat-1"] = BlockingChatAgentApi("chat-1")
|
||||
agent_api.for_chat = lambda chat_id: agent_api.instances.setdefault(chat_id, BlockingChatAgentApi(chat_id))
|
||||
client = RealPlatformClient(
|
||||
agent_api=agent_api,
|
||||
prototype_state=PrototypeStateStore(),
|
||||
platform="matrix",
|
||||
)
|
||||
|
||||
async def consume_stream():
|
||||
chunks = []
|
||||
async for chunk in client.stream_message("@alice:example.org", "chat-1", "hello"):
|
||||
chunks.append(chunk)
|
||||
return chunks
|
||||
|
||||
stream_task = asyncio.create_task(consume_stream())
|
||||
await asyncio.wait_for(agent_api.instances["chat-1"].started.wait(), timeout=1)
|
||||
|
||||
send_task = asyncio.create_task(client.send_message("@alice:example.org", "chat-1", "again"))
|
||||
await asyncio.sleep(0)
|
||||
|
||||
assert agent_api.instances["chat-1"].calls == ["hello"]
|
||||
assert agent_api.instances["chat-1"].max_active_calls == 1
|
||||
|
||||
agent_api.instances["chat-1"].release.set()
|
||||
stream_chunks = await stream_task
|
||||
send_result = await send_task
|
||||
|
||||
assert [chunk.delta for chunk in stream_chunks] == ["hello", ""]
|
||||
assert send_result.response == "again"
|
||||
assert agent_api.instances["chat-1"].calls == ["hello", "again"]
|
||||
assert agent_api.instances["chat-1"].max_active_calls == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_real_platform_client_stream_message_emits_final_tokens_chunk():
|
||||
agent_api = FakeAgentApiFactory()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue