14 KiB
Lambda Lab 3.0 — Surfaces
Matrix-бот для взаимодействия пользователя с AI-агентом Lambda.
Интеграция для платформы
Бот — это один Docker-контейнер (matrix-bot), который вы добавляете в свою инфраструктуру рядом с агентами. Production target — один surface container на 25-30 внешних agent containers/services.
Что бот ожидает от вас
1. HTTP-эндпоинт агента
Бот подключается к агенту через lambda_agent_api.AgentApi по адресу AGENT_BASE_URL.
Протокол — WebSocket поверх HTTP, контракт описан в docs/deploy-architecture.md.
2. Shared volume с per-agent поддиректориями
Shared volume монтируется в бот как /agents. Каждый агент видит свою поддиректорию.
Bot container Agent containers
/agents/0/ ←── volume ──→ agent_0: /workspace/
/agents/1/ ←── volume ──→ agent_1: /workspace/
/agents/N/ ←── volume ──→ agent_N: /workspace/
- Бот сохраняет входящий файл прямо в
{workspace_path}/{file}и передаёт агентуattachments=["{file}"] - Если файл с таким именем уже есть, бот сохраняет следующий как
file (1).ext,file (2).ext, как в Windows - Агент пишет исходящий файл прямо в свой
/workspace/file, бот читает его из{workspace_path}/file workspace_pathдля каждого агента задаётся вconfig/matrix-agents.yaml
3. Конфиг агентов
Файл config/matrix-agents.yaml — маппинг Matrix-пользователей на агентов. Вы заполняете его под свою инфраструктуру. Пример в config/matrix-agents.example.yaml.
Что бот не делает
- Не управляет lifecycle агент-контейнеров (запуск/остановка — на вашей стороне)
- Не хранит историю разговоров (это в памяти агента)
- Не обрабатывает аутентификацию пользователей — любой Matrix-пользователь, который пишет боту, получает доступ
Минимальный чеклист
- Взять опубликованный image
SURFACES_BOT_IMAGEили собрать production image из этого репозитория - Заполнить
config/matrix-agents.yaml— ID агентов,base_urlкаждого,workspace_path, маппинг пользователей - Задать переменные окружения (см.
.env.example): Matrix credentials,MATRIX_PLATFORM_BACKEND=real,MATRIX_AGENT_REGISTRY_PATH=/app/config/matrix-agents.yaml - Смонтировать в бот-контейнер shared volume как
/agents— каждый агент должен видеть свою поддиректорию как/workspace - Добавить bot-only service в свой compose; агенты в этот compose не входят и управляются платформой
Статус
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 для продакшна |
SURFACES_BOT_IMAGE |
✓ | Docker image поверхности: mput1/surfaces-bot:latest |
AGENT_BASE_URL |
Fallback URL агента если base_url не задан в matrix-agents.yaml |
|
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"
base_url: "http://lambda.coredump.ru:7000/agent_0/"
workspace_path: "/agents/0"
- id: agent-1
label: "Agent 1"
base_url: "http://lambda.coredump.ru:7000/agent_1/"
workspace_path: "/agents/1"
- id: agent-2
label: "Agent 2"
base_url: "http://lambda.coredump.ru:7000/agent_2/"
workspace_path: "/agents/2"
user_agents— маппинг Matrix user_id → agent_id. Если пользователь не найден — используется первый агент.base_url— HTTP URL агент-эндпоинта (path-based routing через reverse proxy).workspace_path— путь к воркспейсу агента внутри бот-контейнера на shared volume. Бот сохраняет входящие файлы прямо в{workspace_path}/, агент пишет исходящие прямо в свой/workspace/.- Для 25-30 агентов продолжайте тот же паттерн:
/agent_17/+/agents/17,/agent_29/+/agents/29.
Полный пример с комментариями: config/matrix-agents.example.yaml
Production (bot-only)
docker-compose.prod.yml — bot-only handoff через published image. Платформа добавляет этот сервис в свой compose рядом с agent containers, монтирует shared volume и задаёт переменные окружения. Этот compose не создаёт и не собирает агент-контейнеры.
Перед redeploy можно проверить реальные agent routes из той же сети, где будет работать бот:
PYTHONPATH=. uv run python -m tools.check_matrix_agents \
--config config/matrix-agents.yaml \
--timeout 5
Проверка открывает фактический WebSocket URL каждого агента (.../v1/agent_ws/{chat_id}/) и ждёт первый STATUS. Для проверки полного запроса к агенту добавьте --message "ping".
Для запуска опубликованного image:
export SURFACES_BOT_IMAGE=mput1/surfaces-bot:latest
docker compose --env-file .env -f docker-compose.prod.yml up -d
Опубликованный image:
mput1/surfaces-bot:latest
sha256:2f135f3535f7765d4377b440cdabe41195ad2efbc3e175def159ae4689ef90bd
Для сборки и публикации surface image:
docker login
export SURFACES_BOT_IMAGE=mput1/surfaces-bot:latest
docker build --target production \
--build-arg LAMBDA_AGENT_API_REF=master \
-t "$SURFACES_BOT_IMAGE" .
docker push "$SURFACES_BOT_IMAGE"
Если push возвращает insufficient_scope, текущий Docker login не имеет доступа к namespace/repository. Создайте repository в нужном Docker Hub namespace или перетегируйте image в namespace пользователя, под которым выполнен docker login.
Fullstack E2E (bot + agent)
docker compose --env-file .env -f docker-compose.fullstack.yml up --build
Поднимает matrix-bot вместе с локальным platform-agent. Это internal harness, не production topology на 25-30 агентов. matrix-bot собирается через Dockerfile target development и локальный external/platform-agent_api context, как в dev-сборке 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 = /agents/N/)
/agents/0/report.pdf ←──── одно и то же хранилище ────→ /workspace/report.pdf
/agents/0/result.txt ←────────────────────────────────→ /workspace/result.txt
- Входящий файл (пользователь → агент): бот сохраняет в
{workspace_path}/{file}, например/agents/17/report.pdf, и передаёт агентуattachments=["report.pdf"] - Коллизии имён: если
/agents/17/report.pdfуже существует, бот сохранит следующий файл как/agents/17/report (1).pdf, затем/agents/17/report (2).pdf - Исходящий файл (агент → пользователь): агент пишет в
/workspace/file, бот читает из{workspace_path}/file, например/agents/17/result.txt, и отправляет пользователю как Matrix file message workspace_pathдля каждого агента задаётся вconfig/matrix-agents.yaml
Онбординг пользователя
- Пользователь приглашает бота в личные сообщения (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 |
Внутренний протокол событий (для расширения) |
docs/new-surface-guide.md |
Руководство по созданию новой поверхности (Discord, Slack и др.) |