# 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}/incoming/{stamp}-{file}` и передаёт агенту `attachments=["incoming/{stamp}-{file}"]` - Агент пишет исходящий файл в свой `/workspace/output/file`, бот читает его из `{workspace_path}/output/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`](docs/surface-protocol.md) --- ## Деплой ### Переменные окружения ```bash 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` — статический маппинг пользователей на агентов: ```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}/incoming/`, агент пишет исходящие в свой `/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 не создаёт и не собирает агент-контейнеры. Для запуска опубликованного image: ```bash export SURFACES_BOT_IMAGE=mput1/surfaces-bot:latest docker compose --env-file .env -f docker-compose.prod.yml up -d ``` Опубликованный image: ```text mput1/surfaces-bot:latest sha256:26ba3a49290ab7c1cf0fa97f3de3fefdc70b59df7e6f1e0c2255728f8e2369be ``` Для сборки и публикации surface image: ```bash 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) ```bash 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` в агенте. ### Сброс состояния (локально) ```bash rm -f lambda_matrix.db && rm -rf matrix_store ``` --- ## Shared volume: передача файлов ``` Bot (/agents) Agent (/workspace = /agents/N/) /agents/0/incoming/ ←──── одно и то же хранилище ────→ /workspace/incoming/ /agents/0/output/ ←────────────────────────────────→ /workspace/output/ ``` - **Входящий файл** (пользователь → агент): бот сохраняет в `{workspace_path}/incoming/{stamp}-{file}`, например `/agents/17/incoming/report.pdf`, и передаёт агенту `attachments=["incoming/{stamp}-{file}"]` - **Исходящий файл** (агент → пользователь): агент пишет в `/workspace/output/file`, бот читает из `{workspace_path}/output/file`, например `/agents/17/output/file`, и отправляет пользователю как Matrix file message - `workspace_path` для каждого агента задаётся в `config/matrix-agents.yaml` --- ## Онбординг пользователя 1. Пользователь приглашает бота в личные сообщения (DM) на Matrix-сервере 2. Бот создаёт private Space `Lambda — {display_name}` и комнату `Чат 1` 3. Дальнейшее общение — в рабочих комнатах, не в DM **Требование:** незашифрованные комнаты. E2EE не поддержан. --- ## Команды Matrix ### Работающие | Команда | Действие | |---|---| | *(любое сообщение)* | Диалог с агентом, стриминг ответа | | `!new [название]` | Создать новый чат | | `!chats` | Список активных чатов | | `!rename <название>` | Переименовать текущую комнату | | `!archive` | Архивировать чат | | `!clear` | Сбросить контекст текущего чата | | `!yes` / `!no` | Подтвердить / отменить действие агента | | `!list` | Файлы в очереди вложений | | `!remove ` / `!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 | --- ## Разработка ```bash uv sync pytest tests/ -v pytest tests/adapter/matrix/ -v # только Matrix ``` ## Документация | Файл | Содержание | |---|---| | [`docs/deploy-architecture.md`](docs/deploy-architecture.md) | **Читать первым.** Топология деплоя, volume-контракт, AgentApi, конфигурация | | [`docs/matrix-prototype.md`](docs/matrix-prototype.md) | Команды бота, UX, передача файлов | | [`docs/known-limitations.md`](docs/known-limitations.md) | Известные ограничения и обходные пути | | [`docs/surface-protocol.md`](docs/surface-protocol.md) | Внутренний протокол событий (для расширения) |