Add per-chat real client routing
This commit is contained in:
parent
5782001d3d
commit
414a8645bd
3 changed files with 138 additions and 18 deletions
|
|
@ -6,22 +6,49 @@ from sdk.prototype_state import PrototypeStateStore
|
|||
from sdk.real import RealPlatformClient
|
||||
|
||||
|
||||
class FakeAgentApi:
|
||||
def __init__(self) -> None:
|
||||
class FakeChunk:
|
||||
def __init__(self, text: str) -> None:
|
||||
self.text = text
|
||||
|
||||
|
||||
class FakeChatAgentApi:
|
||||
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
|
||||
|
||||
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)
|
||||
yield type("Chunk", (), {"text": text[:2]})()
|
||||
yield type("Chunk", (), {"text": text[2:]})()
|
||||
midpoint = len(text) // 2
|
||||
yield FakeChunk(text[:midpoint])
|
||||
yield FakeChunk(text[midpoint:])
|
||||
self.last_tokens_used = 3
|
||||
|
||||
|
||||
class FakeAgentApiFactory:
|
||||
def __init__(self) -> None:
|
||||
self.created_chat_ids: list[str] = []
|
||||
self.instances: dict[str, FakeChatAgentApi] = {}
|
||||
|
||||
def for_chat(self, chat_id: str) -> FakeChatAgentApi:
|
||||
chat_api = FakeChatAgentApi(chat_id)
|
||||
self.created_chat_ids.append(chat_id)
|
||||
self.instances[chat_id] = chat_api
|
||||
return chat_api
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_real_platform_client_get_or_create_user_uses_local_state():
|
||||
client = RealPlatformClient(
|
||||
agent_api=FakeAgentApi(),
|
||||
agent_api=FakeAgentApiFactory(),
|
||||
prototype_state=PrototypeStateStore(),
|
||||
)
|
||||
|
||||
|
|
@ -36,15 +63,15 @@ async def test_real_platform_client_get_or_create_user_uses_local_state():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_real_platform_client_send_message_collects_stream_output():
|
||||
agent_api = FakeAgentApi()
|
||||
async def test_real_platform_client_send_message_uses_chat_bound_client():
|
||||
agent_api = FakeAgentApiFactory()
|
||||
client = RealPlatformClient(
|
||||
agent_api=agent_api,
|
||||
prototype_state=PrototypeStateStore(),
|
||||
platform="matrix",
|
||||
)
|
||||
|
||||
result = await client.send_message("@alice:example.org", "C1", "hello")
|
||||
result = await client.send_message("@alice:example.org", "chat-7", "hello")
|
||||
|
||||
assert result == MessageResponse(
|
||||
message_id="@alice:example.org",
|
||||
|
|
@ -52,12 +79,50 @@ async def test_real_platform_client_send_message_collects_stream_output():
|
|||
tokens_used=3,
|
||||
finished=True,
|
||||
)
|
||||
assert agent_api.calls == ["hello"]
|
||||
assert agent_api.created_chat_ids == ["chat-7"]
|
||||
assert agent_api.instances["chat-7"].chat_id == "chat-7"
|
||||
assert agent_api.instances["chat-7"].calls == ["hello"]
|
||||
assert agent_api.instances["chat-7"].connect_calls == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_real_platform_client_reuses_cached_chat_client():
|
||||
agent_api = FakeAgentApiFactory()
|
||||
client = RealPlatformClient(
|
||||
agent_api=agent_api,
|
||||
prototype_state=PrototypeStateStore(),
|
||||
platform="matrix",
|
||||
)
|
||||
|
||||
await client.send_message("@alice:example.org", "chat-1", "hello")
|
||||
await client.send_message("@alice:example.org", "chat-1", "again")
|
||||
|
||||
assert agent_api.created_chat_ids == ["chat-1"]
|
||||
assert agent_api.instances["chat-1"].calls == ["hello", "again"]
|
||||
assert agent_api.instances["chat-1"].connect_calls == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_real_platform_client_creates_distinct_clients_per_chat():
|
||||
agent_api = FakeAgentApiFactory()
|
||||
client = RealPlatformClient(
|
||||
agent_api=agent_api,
|
||||
prototype_state=PrototypeStateStore(),
|
||||
platform="matrix",
|
||||
)
|
||||
|
||||
await client.send_message("@alice:example.org", "chat-1", "hello")
|
||||
await client.send_message("@alice:example.org", "chat-2", "world")
|
||||
|
||||
assert agent_api.created_chat_ids == ["chat-1", "chat-2"]
|
||||
assert agent_api.instances["chat-1"] is not agent_api.instances["chat-2"]
|
||||
assert agent_api.instances["chat-1"].calls == ["hello"]
|
||||
assert agent_api.instances["chat-2"].calls == ["world"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_real_platform_client_stream_message_emits_final_tokens_chunk():
|
||||
agent_api = FakeAgentApi()
|
||||
agent_api = FakeAgentApiFactory()
|
||||
client = RealPlatformClient(
|
||||
agent_api=agent_api,
|
||||
prototype_state=PrototypeStateStore(),
|
||||
|
|
@ -65,7 +130,7 @@ async def test_real_platform_client_stream_message_emits_final_tokens_chunk():
|
|||
)
|
||||
|
||||
chunks = []
|
||||
async for chunk in client.stream_message("@alice:example.org", "C1", "hello"):
|
||||
async for chunk in client.stream_message("@alice:example.org", "chat-1", "hello"):
|
||||
chunks.append(chunk)
|
||||
|
||||
assert chunks == [
|
||||
|
|
@ -88,13 +153,14 @@ async def test_real_platform_client_stream_message_emits_final_tokens_chunk():
|
|||
tokens_used=3,
|
||||
),
|
||||
]
|
||||
assert agent_api.calls == ["hello"]
|
||||
assert agent_api.created_chat_ids == ["chat-1"]
|
||||
assert agent_api.instances["chat-1"].calls == ["hello"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_real_platform_client_settings_are_local():
|
||||
client = RealPlatformClient(
|
||||
agent_api=FakeAgentApi(),
|
||||
agent_api=FakeAgentApiFactory(),
|
||||
prototype_state=PrototypeStateStore(),
|
||||
platform="matrix",
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue