Agent routing: - Remove !agent command and manual agent selection flow - Registry auto-assigns agent from user_agents mapping (fallback: agents[0]) - provision_workspace_chat and !new both write agent_id to room_meta - Reconciliation backfills agent_id from registry on cold start - Fix duplicate agent_id block in auth.py Deployment stability: - Add bot-state named volume to persist lambda_matrix.db and matrix_store - Fix docker-compose.prod.yml duplicate environment: key (was silently losing all Matrix credentials) - Fix MATRIX_AGENT_REGISTRY_PATH to use absolute container path /app/config/... - Add bot-state volume declaration to docker-compose.fullstack.yml Docs and config: - Rewrite README.md for platform handoff (deploy table, working commands only) - Rewrite docs/matrix-prototype.md (remove stale commands and mock descriptions) - Remove !save/!load/!context/!agent from help text and welcome message - Add !clear, !list, !remove, !yes/!no to help text - Clean up .env.example (remove Telegram token, internal vars, real URLs) - Update config/matrix-agents.example.yaml with user_agents section and comments - Add explanatory comment to Dockerfile for --ignore-requires-python - Remove silent uv sync fallbacks in Dockerfile |
||
|---|---|---|
| .planning | ||
| adapter | ||
| bot-examples | ||
| config | ||
| core | ||
| docs | ||
| sdk | ||
| tests | ||
| .dockerignore | ||
| .DS_Store | ||
| .env.example | ||
| .gitignore | ||
| conftest.py | ||
| docker-compose.fullstack.yml | ||
| docker-compose.prod.yml | ||
| docker-compose.yml | ||
| Dockerfile | ||
| forum_topics_research.md | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
Lambda Lab 3.0 — Surfaces
Matrix-бот для взаимодействия пользователя с AI-агентом Lambda.
Статус
Matrix MVP готов к деплою. Telegram — в отдельном worktree, не входит в этот handoff.
Архитектура
surfaces-bot/
core/ — общее ядро, не зависит от транспорта
protocol.py — унифицированные структуры (IncomingMessage, OutgoingUI, ...)
handler.py — EventDispatcher: IncomingEvent → OutgoingEvent
store.py — StateStore Protocol + InMemoryStore + SQLiteStore
chat.py — ChatManager
auth.py — AuthManager
settings.py — SettingsManager
adapter/
matrix/ — matrix-nio адаптер
sdk/
interface.py — PlatformClient Protocol (контракт к SDK)
real.py — RealPlatformClient (через AgentApi)
mock.py — MockPlatformClient (заглушка для тестов)
config/
matrix-agents.yaml — реестр агентов
docs/ — документация
Подробнее: docs/surface-protocol.md
Деплой
Переменные окружения
cp .env.example .env
| Переменная | Обязательна | Описание |
|---|---|---|
MATRIX_HOMESERVER |
✓ | URL Matrix-сервера |
MATRIX_USER_ID |
✓ | @bot:example.org |
MATRIX_PASSWORD |
✓ | пароль (или MATRIX_ACCESS_TOKEN) |
MATRIX_PLATFORM_BACKEND |
✓ | real для продакшна |
AGENT_BASE_URL |
✓ | HTTP-URL агента, например http://platform-agent:8000 |
MATRIX_AGENT_REGISTRY_PATH |
✓ | путь к реестру внутри контейнера: /app/config/matrix-agents.yaml |
SURFACES_WORKSPACE_DIR |
путь к shared volume в контейнере (по умолчанию /agents) |
|
SURFACES_SHARED_VOLUME |
имя Docker volume (по умолчанию surfaces-agents) |
Реестр агентов
config/matrix-agents.yaml — статический маппинг пользователей на агентов:
user_agents:
"@user0:matrix.lambda.coredump.ru": agent-0
"@user1:matrix.lambda.coredump.ru": agent-1
agents:
- id: agent-0
label: "Agent 0"
- id: agent-1
label: "Agent 1"
Если user_agents не задан или пользователь не найден — используется первый агент из списка.
Production (bot-only)
docker compose --env-file .env -f docker-compose.prod.yml up -d --build
Поднимает только matrix-bot. Монтирует shared volume в /agents. Требует внешний AGENT_BASE_URL.
Fullstack E2E (bot + agent)
docker compose --env-file .env -f docker-compose.fullstack.yml up --build
Поднимает matrix-bot вместе с локальным platform-agent. AGENT_BASE_URL перекрывается на http://platform-agent:8000. Shared volume виден как /agents в боте и /workspace в агенте.
Сброс состояния (локально)
rm -f lambda_matrix.db && rm -rf matrix_store
Shared volume: передача файлов
Bot (/agents) Agent (/workspace)
└── surfaces/matrix/{user}/{room}/inbox/file ←── одно и то же хранилище
Бот пишет входящие файлы в /agents/surfaces/matrix/{user}/{room}/inbox/{stamp}-{filename} и передаёт агенту относительный путь. Исходящие файлы агент пишет в /workspace/..., бот читает из /agents/....
Онбординг пользователя
- Пользователь приглашает бота в личные сообщения (DM) на Matrix-сервере
- Бот создаёт private Space
Lambda — {display_name}и комнатуЧат 1 - Дальнейшее общение — в рабочих комнатах, не в DM
Требование: незашифрованные комнаты. E2EE не поддержан.
Команды Matrix
Работающие
| Команда | Действие |
|---|---|
| (любое сообщение) | Диалог с агентом, стриминг ответа |
!new [название] |
Создать новый чат |
!chats |
Список активных чатов |
!rename <название> |
Переименовать текущую комнату |
!archive |
Архивировать чат |
!clear |
Сбросить контекст текущего чата |
!yes / !no |
Подтвердить / отменить действие агента |
!list |
Файлы в очереди вложений |
!remove <n> / !remove all |
Удалить вложение из очереди |
!help |
Справка |
Не работают / заглушки
| Команда | Статус |
|---|---|
!save / !load / !context |
Нестабильны: зависят от агента, сессии теряются при рестарте |
!settings и подкоманды |
Заглушки MVP, требуют готового SDK платформы |
Отправка файлов агенту
Matrix-клиент отправляет файлы и текст отдельными событиями. Файл без текстовой инструкции ставится в очередь.
[отправил файл]
!list
1. report.pdf
прочитай и сделай summary ← файл уйдёт агенту вместе с этим текстом
Известные ограничения
| Проблема | Причина |
|---|---|
| История теряется при рестарте агента | platform-agent использует MemorySaver (in-memory) |
| E2EE | python-olm не собирается на macOS/ARM |
Разработка
uv sync
pytest tests/ -v
pytest tests/adapter/matrix/ -v # только Matrix
Документация
| Файл | Содержание |
|---|---|
docs/deploy-architecture.md |
Читать первым. Топология деплоя, volume-контракт, AgentApi, конфигурация |
docs/matrix-prototype.md |
Команды бота, UX, передача файлов |
docs/known-limitations.md |
Известные ограничения и обходные пути |
docs/surface-protocol.md |
Внутренний протокол событий (для расширения) |