from __future__ import annotations from pathlib import Path import pytest from adapter.matrix.bot import build_runtime from adapter.matrix.agent_registry import AgentDefinition, AgentRegistry from adapter.matrix.handlers.agent import make_handle_agent from adapter.matrix.store import get_room_meta, get_selected_agent_id, set_selected_agent_id, set_room_meta from core.chat import ChatManager from core.protocol import IncomingCommand, OutgoingMessage from core.settings import SettingsManager from core.store import InMemoryStore from sdk.mock import MockPlatformClient def _registry() -> AgentRegistry: return AgentRegistry( [ AgentDefinition(agent_id="agent-1", label="Analyst"), AgentDefinition(agent_id="agent-2", label="Research"), ] ) async def test_agent_command_lists_available_agents_with_selected_marker(): store = InMemoryStore() await set_selected_agent_id(store, "@alice:example.org", "agent-2") handler = make_handle_agent(store, _registry()) result = await handler( event=IncomingCommand( user_id="@alice:example.org", platform="matrix", chat_id="C1", command="agent", ), auth_mgr=None, platform=MockPlatformClient(), chat_mgr=ChatManager(None, store), settings_mgr=SettingsManager(MockPlatformClient(), store), ) assert result == [ OutgoingMessage( chat_id="C1", text=( "Доступные агенты:\n" "1. Analyst\n" "2. Research [текущий]\n" "\n" "Выбери агент: !agent <номер>" ), ) ] async def test_agent_command_persists_selected_agent_id(): store = InMemoryStore() handler = make_handle_agent(store, _registry()) result = await handler( event=IncomingCommand( user_id="@alice:example.org", platform="matrix", chat_id="C1", command="agent", args=["2"], ), auth_mgr=None, platform=MockPlatformClient(), chat_mgr=ChatManager(None, store), settings_mgr=SettingsManager(MockPlatformClient(), store), ) assert await get_selected_agent_id(store, "@alice:example.org") == "agent-2" assert result == [ OutgoingMessage( chat_id="C1", text="Агент переключен на Research. Продолжай через !new.", ) ] async def test_agent_command_binds_existing_unbound_room_to_selected_agent(): store = InMemoryStore() chat_mgr = ChatManager(None, store) await chat_mgr.get_or_create( user_id="@alice:example.org", chat_id="C1", platform="matrix", surface_ref="!room:example.org", name="Research", ) await set_room_meta( store, "!room:example.org", { "chat_id": "C1", "matrix_user_id": "@alice:example.org", "display_name": "Research", }, ) handler = make_handle_agent(store, _registry()) result = await handler( event=IncomingCommand( user_id="@alice:example.org", platform="matrix", chat_id="C1", command="agent", args=["1"], ), auth_mgr=None, platform=MockPlatformClient(), chat_mgr=chat_mgr, settings_mgr=SettingsManager(MockPlatformClient(), store), ) assert await get_selected_agent_id(store, "@alice:example.org") == "agent-1" assert await get_room_meta(store, "!room:example.org") == { "chat_id": "C1", "matrix_user_id": "@alice:example.org", "display_name": "Research", "agent_id": "agent-1", "platform_chat_id": "1", } assert result == [ OutgoingMessage( chat_id="C1", text="Агент Analyst выбран. Текущий чат готов к работе.", ) ] @pytest.mark.asyncio async def test_build_runtime_registers_agent_handler_when_registry_is_configured( monkeypatch: pytest.MonkeyPatch, tmp_path: Path, ): registry_path = tmp_path / "matrix-agents.yaml" registry_path.write_text( "agents:\n" " - id: agent-1\n" " label: Analyst\n" " - id: agent-2\n" " label: Research\n", encoding="utf-8", ) monkeypatch.setenv("MATRIX_AGENT_REGISTRY_PATH", str(registry_path)) runtime = build_runtime(platform=MockPlatformClient()) result = await runtime.dispatcher.dispatch( IncomingCommand( user_id="@alice:example.org", platform="matrix", chat_id="C1", command="agent", ) ) assert result == [ OutgoingMessage( chat_id="C1", text=( "Доступные агенты:\n" "1. Analyst\n" "2. Research\n" "\n" "Выбери агент: !agent <номер>" ), ) ]