diff --git a/README.md b/README.md index 318a45d..b2f69fb 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## Статус -Прототип в разработке. SDK платформы ещё не готов — работаем через `MockPlatformClient`. +Прототип в разработке. Matrix-адаптер по умолчанию работает через `MockPlatformClient`, но может переключаться на реальный direct-agent backend через `MATRIX_PLATFORM_BACKEND=real`. | Поверхность | Статус | Описание | |---|---|---| @@ -71,6 +71,8 @@ surfaces-bot/ - **Диалог** — сообщения, вложения, подтверждения `!yes` / `!no` и routing через `EventDispatcher` - **Стабильность** — перед `sync_forever()` бот делает bootstrap sync и стартует с `since`, чтобы не переигрывать старую timeline после рестарта - **Текущее ограничение** — encrypted DM пока не поддержан; ручное тестирование Matrix ведётся в незашифрованных комнатах и зависит от локального state-store бота +- **Backend selection** — `MATRIX_PLATFORM_BACKEND=mock` остаётся значением по умолчанию; `MATRIX_PLATFORM_BACKEND=real` требует `AGENT_WS_URL=ws://host:port/agent_ws/` +- **Ограничения real backend** — пока это текстовый direct-agent прототип без вложений и без асинхронных callbacks; локальные настройки и user-state хранятся в `PrototypeStateStore` --- @@ -89,7 +91,7 @@ class PlatformClient(Protocol): Бот не управляет lifecycle контейнеров — это делает Master (платформа). Бот передаёт `user_id` + `chat_id` + сообщение; платформа сама решает нужно ли поднять контейнер. -Сейчас: `MockPlatformClient` в `sdk/mock.py`. +Сейчас: `MockPlatformClient` в `sdk/mock.py`, а Matrix real backend собирается через `sdk/real.py` при `MATRIX_PLATFORM_BACKEND=real`. Когда SDK готов: добавляем `SdkPlatformClient`, меняем одну строку в DI. Адаптеры и ядро не трогаем. --- diff --git a/adapter/matrix/bot.py b/adapter/matrix/bot.py index 08638cb..a413fad 100644 --- a/adapter/matrix/bot.py +++ b/adapter/matrix/bot.py @@ -35,7 +35,11 @@ from core.protocol import ( ) from core.settings import SettingsManager from core.store import InMemoryStore, SQLiteStore, StateStore +from sdk.agent_session import AgentSessionClient, AgentSessionConfig +from sdk.interface import PlatformClient from sdk.mock import MockPlatformClient +from sdk.prototype_state import PrototypeStateStore +from sdk.real import RealPlatformClient logger = structlog.get_logger(__name__) @@ -44,7 +48,7 @@ load_dotenv(Path(__file__).resolve().parents[2] / ".env") @dataclass class MatrixRuntime: - platform: MockPlatformClient + platform: PlatformClient store: StateStore chat_mgr: ChatManager auth_mgr: AuthManager @@ -52,7 +56,7 @@ class MatrixRuntime: dispatcher: EventDispatcher -def build_event_dispatcher(platform: MockPlatformClient, store: StateStore) -> EventDispatcher: +def build_event_dispatcher(platform: PlatformClient, store: StateStore) -> EventDispatcher: chat_mgr = ChatManager(platform, store) auth_mgr = AuthManager(platform, store) settings_mgr = SettingsManager(platform, store) @@ -64,12 +68,24 @@ def build_event_dispatcher(platform: MockPlatformClient, store: StateStore) -> E return dispatcher +def _build_platform_from_env() -> PlatformClient: + backend = os.environ.get("MATRIX_PLATFORM_BACKEND", "mock").strip().lower() + if backend == "real": + ws_url = os.environ["AGENT_WS_URL"] + return RealPlatformClient( + agent_sessions=AgentSessionClient(AgentSessionConfig(base_ws_url=ws_url)), + prototype_state=PrototypeStateStore(), + platform="matrix", + ) + return MockPlatformClient() + + def build_runtime( - platform: MockPlatformClient | None = None, + platform: PlatformClient | None = None, store: StateStore | None = None, client: AsyncClient | None = None, ) -> MatrixRuntime: - platform = platform or MockPlatformClient() + platform = platform or _build_platform_from_env() store = store or InMemoryStore() chat_mgr = ChatManager(platform, store) auth_mgr = AuthManager(platform, store) diff --git a/tests/adapter/matrix/test_dispatcher.py b/tests/adapter/matrix/test_dispatcher.py index dce9243..7f064f2 100644 --- a/tests/adapter/matrix/test_dispatcher.py +++ b/tests/adapter/matrix/test_dispatcher.py @@ -11,6 +11,7 @@ from adapter.matrix.handlers.auth import handle_invite from adapter.matrix.store import get_room_meta, get_user_meta, set_user_meta from core.protocol import IncomingCallback, IncomingCommand, OutgoingMessage from sdk.mock import MockPlatformClient +from sdk.real import RealPlatformClient async def test_matrix_dispatcher_registers_custom_handlers(): @@ -254,3 +255,12 @@ async def test_prepare_live_sync_returns_next_batch_from_bootstrap_sync(): client.sync.assert_awaited_once_with(timeout=0, full_state=True) assert since == "s123" + + +async def test_build_runtime_uses_real_platform_when_matrix_backend_is_real(monkeypatch): + monkeypatch.setenv("MATRIX_PLATFORM_BACKEND", "real") + monkeypatch.setenv("AGENT_WS_URL", "ws://agent.example/agent_ws/") + + runtime = build_runtime() + + assert isinstance(runtime.platform, RealPlatformClient)