11 KiB
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 по WebSocketsdk/prototype_state.py— локальный user/settings state для прототипа
Это позволило не переписывать Matrix-логику под нестабильный platform/master и при этом подключить живого агента вместо мока.
Что поменялось в surfaces-bot
Добавлено:
sdk/agent_session.pysdk/prototype_state.pysdk/real.py- тесты для transport/state/real backend
Изменено:
adapter/matrix/bot.pyadapter/matrix/handlers/auth.pyREADME.md- интеграционные и Matrix dispatcher тесты
Функционально это дало:
- переключение Matrix backend через env:
MATRIX_PLATFORM_BACKEND=mockMATRIX_PLATFORM_BACKEND=real
- прямую отправку текста в live agent через
AGENT_BASE_URL - локальное хранение settings и user mapping
- изоляцию backend memory по
thread_id - исправление повторных invite: бот теперь сначала
join(), а уже потом решает, нужно ли пере-провиженить Space/chat tree
Что поменяли в platform-agent
Для прототипа потребовался минимальный локальный патч в клонированном external/platform-agent.
Изменения:
src/api/external.pysrc/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
Текущая архитектура прототипа
Поток сообщения сейчас такой:
- Matrix room event попадает в
adapter/matrix - адаптер переводит его в
IncomingMessage/IncomingCommand EventDispatcherвызывает handler изcore/- handler вызывает
PlatformClient - при real backend это
RealPlatformClient RealPlatformClientстроитthread_keyAgentSessionClientоткрывает WebSocket наagent_ws/?thread_id=...- ответ агента возвращается обратно в 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:
И связанный SDK clone:
Первичная подготовка:
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, сначала сделайте:
deactivate
Иначе uv pip install может поставить пакет не в тот interpreter.
2. Запустить agent backend
Пример с OpenRouter:
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 должен быть доступен по:
ws://127.0.0.1:8000/agent_ws/
3. Запустить Matrix bot
В отдельном терминале:
cd /Users/a/MAI/sem2/lambda/surfaces-bot
export MATRIX_PLATFORM_BACKEND=real
export AGENT_BASE_URL=http://127.0.0.1:8000
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
Если всё ок, в логах будет что-то вроде:
Matrix bot starting ...
Точные команды
Ниже команды в том виде, в котором реально поднимался рабочий прототип.
Platform / agent backend
cd /Users/a/MAI/sem2/lambda/surfaces-bot/external/platform-agent
deactivate 2>/dev/null || true
uv sync
uv pip install --python .venv/bin/python -e ../platform-agent_api
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
Matrix bot
cd /Users/a/MAI/sem2/lambda/surfaces-bot
export MATRIX_PLATFORM_BACKEND=real
export AGENT_BASE_URL=http://127.0.0.1:8000
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
Перезапуск Matrix state с нуля
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
Smoke test
Рекомендуемый сценарий ручной проверки:
- Пригласить бота в fresh unencrypted room
- Дождаться join
- Если это первый invite для данного локального state:
- бот создаст private Space
- бот создаст room
Чат 1
- Открыть
Чат 1 - Отправить
!start - Отправить обычное текстовое сообщение
- Проверить, что ответ пришёл от live backend, а не от
[MOCK] - Проверить
!new - Проверить, что память разделяется между чатами
Если бот уже был однажды провиженен и локальный state не очищался:
- повторный invite не создаст новую Space-структуру
- бот просто зайдёт в room и будет отвечать там
Это нормальное поведение текущей реализации.
Сброс локального Matrix state
Если нужно повторно проверить именно first-invite provisioning:
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 агента.
Исправление:
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_URLPROVIDER_MODELPROVIDER_API_KEY