diff --git a/docs/matrix-direct-agent-prototype-ru.md b/docs/matrix-direct-agent-prototype-ru.md new file mode 100644 index 0000000..284c4b7 --- /dev/null +++ b/docs/matrix-direct-agent-prototype-ru.md @@ -0,0 +1,256 @@ +# Matrix Direct-Agent Prototype + +Русскоязычная заметка по прототипу Matrix surface, который ходит не в `MockPlatformClient`, а напрямую в живой agent backend по WebSocket. + +## Что сделали + +В этой ветке собран рабочий Matrix-only прототип с минимальным вмешательством в существующую архитектуру. + +Ключевая идея: +- Matrix-адаптер и `core/` остаются на старом контракте `PlatformClient` +- вместо `sdk/mock.py` можно включить `sdk/real.py` +- `sdk/real.py` внутри разделяет две ответственности: + - `sdk/agent_session.py` — прямое общение с agent по WebSocket + - `sdk/prototype_state.py` — локальный user/settings state для прототипа + +Это позволило не переписывать Matrix-логику под нестабильный `platform/master` и при этом подключить живого агента вместо мока. + +## Что поменялось в `surfaces-bot` + +Добавлено: +- `sdk/agent_session.py` +- `sdk/prototype_state.py` +- `sdk/real.py` +- тесты для transport/state/real backend + +Изменено: +- `adapter/matrix/bot.py` +- `adapter/matrix/handlers/auth.py` +- `README.md` +- интеграционные и Matrix dispatcher тесты + +Функционально это дало: +- переключение Matrix backend через env: + - `MATRIX_PLATFORM_BACKEND=mock` + - `MATRIX_PLATFORM_BACKEND=real` +- прямую отправку текста в live agent через `AGENT_WS_URL` +- локальное хранение settings и user mapping +- изоляцию backend memory по `thread_id` +- исправление повторных invite: бот теперь сначала `join()`, а уже потом решает, нужно ли пере-провиженить Space/chat tree + +## Что поменяли в `platform-agent` + +Для прототипа потребовался минимальный локальный патч в клонированном `external/platform-agent`. + +Изменения: +- `src/api/external.py` +- `src/agent/service.py` + +Смысл патча: +- agent больше не использует один общий hardcoded `thread_id="default"` +- `thread_id` читается из query parameter WebSocket-соединения +- дальше этот `thread_id` передаётся в config memory/checkpointer + +Локальный commit в clone: +- `1dca2c1` — `feat: support websocket thread ids` + +Важно: +- этот commit живёт в `external/platform-agent` +- он не входит в git-историю `surfaces-bot` +- если прототип должен запускаться у других людей без ручных патчей, этот commit надо отдельно запушить или повторить в platform repo + +## Текущая архитектура прототипа + +Поток сообщения сейчас такой: + +1. Matrix room event попадает в `adapter/matrix` +2. адаптер переводит его в `IncomingMessage` / `IncomingCommand` +3. `EventDispatcher` вызывает handler из `core/` +4. handler вызывает `PlatformClient` +5. при real backend это `RealPlatformClient` +6. `RealPlatformClient` строит `thread_key` +7. `AgentSessionClient` открывает WebSocket на `agent_ws/?thread_id=...` +8. ответ агента возвращается обратно в Matrix + +Что остаётся локальным в v1: +- `!settings` +- `!skills` +- `!soul` +- `!safety` +- user registration mapping + +Что реально идёт в живого агента: +- обычные текстовые сообщения +- память по чатам через `thread_id` + +## Ограничения прототипа + +Сейчас это не полный platform integration, а рабочий direct-agent prototype. + +Ограничения: +- только текстовый чат +- без attachments в agent +- без async task callbacks/webhooks +- без реального control-plane из `platform/master` +- encrypted Matrix rooms пока не поддержаны +- repeat invite не создаёт новую Space-структуру, если user уже был провиженен локально +- backend/provider ошибки пока не везде деградируют в user-facing reply; часть ошибок всё ещё может уронить процесс surface + +## Как запускать + +Нужно поднять два процесса: +- patched `platform-agent` +- Matrix bot из `surfaces-bot` + +### 1. Подготовить `platform-agent` + +Локальный clone: +- [external/platform-agent](/Users/a/MAI/sem2/lambda/surfaces-bot/external/platform-agent) + +И связанный SDK clone: +- [external/platform-agent_api](/Users/a/MAI/sem2/lambda/surfaces-bot/external/platform-agent_api) + +Первичная подготовка: + +```bash +cd /Users/a/MAI/sem2/lambda/surfaces-bot/external/platform-agent +uv sync +uv pip install --python .venv/bin/python -e ../platform-agent_api +``` + +Если у вас был активирован чужой venv, сначала сделайте: + +```bash +deactivate +``` + +Иначе `uv pip install` может поставить пакет не в тот interpreter. + +### 2. Запустить agent backend + +Пример с OpenRouter: + +```bash +cd /Users/a/MAI/sem2/lambda/surfaces-bot/external/platform-agent + +export PROVIDER_URL=https://openrouter.ai/api/v1 +export PROVIDER_API_KEY='YOUR_OPENROUTER_KEY' +export PROVIDER_MODEL='qwen/qwen3.5-122b-a10b' + +uv run uvicorn src.main:app --host 0.0.0.0 --port 8000 +``` + +После этого WebSocket endpoint должен быть доступен по: + +```text +ws://127.0.0.1:8000/agent_ws/ +``` + +### 3. Запустить Matrix bot + +В отдельном терминале: + +```bash +cd /Users/a/MAI/sem2/lambda/surfaces-bot + +export MATRIX_PLATFORM_BACKEND=real +export AGENT_WS_URL=ws://127.0.0.1:8000/agent_ws/ +export MATRIX_HOMESERVER=https://matrix.lambda.coredump.ru +export MATRIX_USER_ID=@lambda_surface_test_bot:matrix.lambda.coredump.ru +export MATRIX_PASSWORD='YOUR_PASSWORD' + +PYTHONPATH=. uv run python -m adapter.matrix.bot +``` + +Если всё ок, в логах будет что-то вроде: + +```text +Matrix bot starting ... +``` + +## Smoke test + +Рекомендуемый сценарий ручной проверки: + +1. Пригласить бота в fresh unencrypted room +2. Дождаться join +3. Если это первый invite для данного локального state: + - бот создаст private Space + - бот создаст room `Чат 1` +4. Открыть `Чат 1` +5. Отправить `!start` +6. Отправить обычное текстовое сообщение +7. Проверить, что ответ пришёл от live backend, а не от `[MOCK]` +8. Проверить `!new` +9. Проверить, что память разделяется между чатами + +Если бот уже был однажды провиженен и локальный state не очищался: +- повторный invite не создаст новую Space-структуру +- бот просто зайдёт в room и будет отвечать там + +Это нормальное поведение текущей реализации. + +## Сброс локального Matrix state + +Если нужно повторно проверить именно first-invite provisioning: + +```bash +cd /Users/a/MAI/sem2/lambda/surfaces-bot +rm -f lambda_matrix.db +rm -rf matrix_store +PYTHONPATH=. uv run python -m adapter.matrix.bot +``` + +После этого можно снова приглашать бота как "с нуля". + +## Частые проблемы + +### 1. `ModuleNotFoundError: lambda_agent_api` + +Значит `platform-agent_api` не установлен в `.venv` агента. + +Исправление: + +```bash +cd /Users/a/MAI/sem2/lambda/surfaces-bot/external/platform-agent +uv pip install --python .venv/bin/python -e ../platform-agent_api +``` + +### 2. `CERTIFICATE_VERIFY_FAILED` при запуске Matrix bot + +Это не ошибка surface logic. Это TLS trust problem до Matrix homeserver. + +Нужно: +- либо установить системные/Python certificates +- либо передать корпоративный CA через `SSL_CERT_FILE` + +### 3. Бот заходит в room, но не создаёт новую Space + +Скорее всего user уже есть в локальном state. + +Варианты: +- это ожидаемо для repeat invite +- либо очистить `lambda_matrix.db` и `matrix_store` + +### 4. Бот падает после message send + +Значит backend/provider вернул ошибку, которая ещё не была деградирована в user-facing ответ. + +Пример уже встречавшегося кейса: +- неверный model id +- key не имеет доступа к model + +Сначала проверяйте: +- `PROVIDER_URL` +- `PROVIDER_MODEL` +- `PROVIDER_API_KEY` + +## Полезные ссылки внутри repo + +- [README.md](/Users/a/MAI/sem2/lambda/surfaces-bot/README.md) +- [adapter/matrix/bot.py](/Users/a/MAI/sem2/lambda/surfaces-bot/adapter/matrix/bot.py) +- [sdk/agent_session.py](/Users/a/MAI/sem2/lambda/surfaces-bot/sdk/agent_session.py) +- [sdk/real.py](/Users/a/MAI/sem2/lambda/surfaces-bot/sdk/real.py) +- [sdk/prototype_state.py](/Users/a/MAI/sem2/lambda/surfaces-bot/sdk/prototype_state.py) +- [2026-04-08-matrix-direct-agent-prototype-design.md](/Users/a/MAI/sem2/lambda/surfaces-bot/docs/superpowers/specs/2026-04-08-matrix-direct-agent-prototype-design.md) +- [2026-04-08-matrix-direct-agent-prototype.md](/Users/a/MAI/sem2/lambda/surfaces-bot/docs/superpowers/plans/2026-04-08-matrix-direct-agent-prototype.md)