No description
Find a file
2026-04-22 00:22:20 +03:00
.planning feat: finalize matrix platform audit and docs 2026-04-21 15:35:03 +03:00
adapter feat: finalize matrix platform audit and docs 2026-04-21 15:35:03 +03:00
bot-examples feat(matrix): land QA follow-ups and refresh docs 2026-04-05 19:08:58 +03:00
core feat: support shared-workspace file flow for matrix 2026-04-21 00:26:21 +03:00
docs docs: add thin transport adapter plan 2026-04-22 00:17:15 +03:00
sdk refactor: shrink agent api wrapper to thin adapter 2026-04-22 00:22:20 +03:00
tests refactor: shrink agent api wrapper to thin adapter 2026-04-22 00:22:20 +03:00
.dockerignore fix(sdk): correct WebSocket URL pattern for platform-agent 2026-04-19 21:05:02 +03:00
.DS_Store init: surfaces-bot — Telegram & Matrix prototype 2026-03-27 00:35:42 +03:00
.env.example feat: finalize matrix platform audit and docs 2026-04-21 15:35:03 +03:00
.gitignore feat: finalize matrix platform audit and docs 2026-04-21 15:35:03 +03:00
conftest.py feat: implement core/ and platform/ with full test coverage 2026-03-29 21:42:02 +03:00
docker-compose.yml feat: support shared-workspace file flow for matrix 2026-04-21 00:26:21 +03:00
Dockerfile feat(04-03): add matrix bot containerization 2026-04-17 16:07:47 +03:00
forum_topics_research.md feat(matrix): land QA follow-ups and refresh docs 2026-04-05 19:08:58 +03:00
pyproject.toml fix prototype backend review issues 2026-04-08 01:43:44 +03:00
README.md docs: clarify matrix file sending flow 2026-04-21 23:47:06 +03:00
uv.lock fix prototype backend review issues 2026-04-08 01:43:44 +03:00

Lambda Lab 3.0 — Surfaces

Команда поверхностей. Telegram и Matrix боты для взаимодействия пользователя с AI-агентом Lambda.

Статус

Поверхность Статус
Telegram 🔨 В разработке, отдельный worktree feat/telegram-adapter
Matrix Рабочий прототип, запускается через root docker compose вместе с platform-agent

Концепция

Пользователь получает персонального AI-агента через привычный мессенджер. Агент выполняет реальные задачи: разбирает почту, ищет информацию, работает с файлами, управляет календарём.

Поверхности — тонкие клиенты. Вся бизнес-логика на стороне платформы. Задача команды: сделать интерфейс удобным, надёжным и легко расширяемым.


Архитектура

surfaces-bot/
  core/                  — общее ядро, не зависит от транспорта
    protocol.py          — унифицированные структуры (IncomingMessage, OutgoingUI, ...)
    handler.py           — EventDispatcher: IncomingEvent → OutgoingEvent
    handlers/            — обработчики по типам событий
    store.py             — StateStore Protocol + InMemoryStore + SQLiteStore
    chat.py              — ChatManager: метаданные чатов C1/C2/C3
    auth.py              — AuthManager: аутентификация
    settings.py          — SettingsManager: коннекторы, скиллы, SOUL, безопасность

  adapter/
    telegram/            — aiogram 3.x адаптер
    matrix/              — matrix-nio адаптер

  sdk/
    interface.py         — PlatformClient Protocol (контракт к SDK)
    mock.py              — MockPlatformClient (заглушка)

  docs/                  — документация
  .claude/agents/        — агенты для Claude Code

Ключевой принцип: добавить новую поверхность = написать один адаптер-конвертер. Ядро (core/) не трогается. Подробнее: docs/surface-protocol.md


Функционал прототипа

Telegram (подробнее)

  • Чаты — основной Telegram UX сейчас развивается в отдельном worktree feat/telegram-adapter
  • Forum Topics mode — бот умеет подключать forum-группу через /forum; чат может быть привязан к отдельной теме
  • DM-режим — базовый диалог и переключение чатов сохраняются
  • Аутентификация — привязка Telegram аккаунта к аккаунту платформы
  • Диалог — typing indicator, передача файлов, подтверждение опасных действий через inline-кнопки
  • Настройки через /settings: коннекторы (Gmail, GitHub, Notion...), скиллы, личность агента (SOUL), безопасность, подписка

Matrix (подробнее)

  • Онбординг — при первом invite бот создаёт private Space Lambda — {display_name} и первую комнату Чат 1, сразу приглашая туда пользователя
  • Чаты!new, !chats, !rename, !archive, !help; новые комнаты регистрируются в локальном ChatManager
  • Диалог — сообщения, вложения, подтверждения !yes / !no и routing через EventDispatcher
  • Стабильность — перед sync_forever() бот делает bootstrap sync и стартует с since, чтобы не переигрывать старую timeline после рестарта
  • Текущее ограничение — encrypted DM официально не поддержан; ручное тестирование Matrix ведётся в незашифрованных комнатах и зависит от локального state-store бота
  • Backend selectionMATRIX_PLATFORM_BACKEND=mock остаётся значением по умолчанию; MATRIX_PLATFORM_BACKEND=real использует platform-agent из compose и WebSocket contract /v1/agent_ws/{chat_id}/
  • Ограничения real backend — локальный runtime использует shared /workspace, а файлы передаются как относительные пути в attachments

Замена SDK

Вся работа с платформой идёт через PlatformClient Protocol:

class PlatformClient(Protocol):
    async def get_or_create_user(self, external_id: str, platform: str, ...) -> User: ...
    async def send_message(self, user_id: str, chat_id: str, text: str, ...) -> MessageResponse: ...
    async def get_settings(self, user_id: str) -> UserSettings: ...
    async def update_settings(self, user_id: str, action: Any) -> None: ...

Бот не управляет lifecycle контейнеров — это делает Master (платформа). Бот передаёт user_id + chat_id + сообщение; платформа сама решает нужно ли поднять контейнер.

Сейчас: MockPlatformClient в sdk/mock.py, а Matrix real backend собирается через sdk/real.py при MATRIX_PLATFORM_BACKEND=real. Файловый контракт уже path-based: бот пишет файлы в shared /workspace и передаёт платформе относительные пути в attachments. Когда SDK готов: добавляем SdkPlatformClient, меняем одну строку в DI. Адаптеры и ядро не трогаем.


Запуск Matrix-поверхности

1. Зависимости и тесты

uv sync
pytest tests/ -v

2. Переменные окружения

cp .env.example .env

Обязательные переменные:

# Matrix аккаунт бота
MATRIX_HOMESERVER=https://matrix.example.org
MATRIX_USER_ID=@lambda-bot:example.org
MATRIX_PASSWORD=...           # или MATRIX_ACCESS_TOKEN=...

# Выбор backend: mock (по умолчанию) или real (подключение к platform-agent)
MATRIX_PLATFORM_BACKEND=real

# compose runtime: platform-agent service name + shared /workspace
AGENT_WS_URL=ws://platform-agent:8000/v1/agent_ws/
AGENT_BASE_URL=http://platform-agent:8000
SURFACES_WORKSPACE_DIR=/workspace

# platform-agent provider
PROVIDER_MODEL=openai/gpt-4o-mini
PROVIDER_URL=https://openrouter.ai/api/v1
PROVIDER_API_KEY=...

3. Compose runtime

Root docker-compose.yml теперь является основным локальным runtime для Matrix и platform-agent. Он поднимает matrix-bot, platform-agent и общий volume /workspace.

docker compose up --build

Compose собирает platform-agent из актуального upstream external/platform-agent Dockerfile (development target), монтирует live-код из external/platform-agent/src и external/platform-agent_api, и подготавливает shared /workspace с правами для agent runtime. Matrix бот подключается к platform-agent по service name, а не к отдельно запущенному localhost.

На 2026-04-21 локальный compose runtime использует vendored upstream-версии платформы без локальных патчей:

  • platform-agent: 5e7c2df954cc3cd2f5bf8ae688e10a20038dde61
  • platform-agent_api: aa480bbec5bbf8e006284dd03aed1c2754e9bbee

4. Staged attachments в Matrix

Если Matrix-клиент отправляет файлы отдельными media events, бот не вызывает агента сразу. Вместо этого он сохраняет файлы в shared /workspace, ставит их в очередь для конкретного чата и пользователя, и ждёт следующего обычного сообщения.

Как отправить файлы агенту:

  1. Отправь один или несколько файлов в рабочую Matrix-комнату.
  2. При необходимости проверь очередь командой !list.
  3. Напиши обычное текстовое сообщение, например:
    • что на изображении?
    • прочитай pdf и сделай summary
    • сравни эти два файла
  4. Это сообщение уйдёт агенту вместе со всеми staged файлами из очереди.

Команды:

  • !list — показать staged вложения
  • !remove <n> — удалить вложение по номеру
  • !remove all — очистить все staged вложения

Следующее обычное сообщение пользователя уходит агенту вместе со всеми staged файлами.

Пример:

[отправил 2 изображения]
!list
1. IMG_3183.png
2. minion.jpeg

что изображено на фото

В этом сценарии вопрос что изображено на фото будет отправлен агенту вместе с обоими файлами.

Важно:

  • если после файлов отправить !list или !remove, агент не вызывается
  • если платформа вернула ошибку на этих вложениях, они остаются в staged-очереди
  • в таком случае следующее обычное сообщение снова попытается отправить те же файлы
  • чтобы разорвать этот цикл, используй !remove <n> или !remove all

Известное ограничение текущего platform-agent:

  • большие изображения могут не пройти в provider из-за лимита на размер data URI
  • в таком случае Matrix-бот ответит Сервис временно недоступен..., а проблемные файлы останутся в очереди до явного удаления

5. Запуск бота вручную

# Первый запуск или сброс состояния
rm -f lambda_matrix.db && rm -rf matrix_store

PYTHONPATH=. uv run python -m adapter.matrix.bot

6. Онбординг пользователя

Напиши боту в личные сообщения (DM) на Matrix-сервере. Для поддерживаемого dev-сценария используй незашифрованную комнату: E2EE сейчас не считается поддержанным режимом для Matrix-поверхности.

Бот автоматически:

  1. Создаст private Space Lambda — {твоё имя}
  2. Создаст рабочую комнату Чат 1 и пригласит туда

Дальнейшее общение ведётся в рабочей комнате, не в DM.


Функционал Matrix MVP

Работает

Функция Команда Примечание
Онбординг (автоматически при invite) Создаёт Space + рабочую комнату
Новый чат !new Создаёт дополнительную комнату
Список чатов !chats Активные чаты пользователя
Переименование !rename <название>
Архивация !archive
Диалог с агентом (любое сообщение) Стриминг ответа через WebSocket
Изоляция контекста (автоматически) Каждая комната получает отдельный platform_chat_id
Сохранение контекста !save [имя] Агент сохраняет краткое резюме разговора
Список сохранений !load Выбор по номеру
Состояние контекста !context Текущая сессия и список сохранений
Справка !help
Подтверждения !yes / !no Для опасных действий
Staged вложения !list, !remove <n>, !remove all Файлы без текстовой инструкции ставятся в очередь до следующего сообщения

Не работает — блокеры на стороне platform-agent

Функция Почему не работает
!load в другом чате platform-agent использует StateBackend — файлы живут в памяти отдельно для каждого thread_id. Файл, сохранённый в чате A, не виден в чате B. Фикс: переключить platform-agent на FilesystemBackend с общим хранилищем.
Счётчик токенов в !context platform-agent отдаёт tokens_used=0 хардкодом в MsgEventEnd. Наш код перехватывает значение корректно.
!reset platform-agent не имеет endpoint /reset. Задокументировано в ТЗ к платформе.
Персистентность между рестартами platform-agent использует MemorySaver (in-memory). Все разговоры теряются при рестарте процесса.
E2EE комнаты python-olm не собирается на macOS/ARM. Ограничение инфраструктуры.

Не работает — пока не реализовано нами

Функция Статус
!settings, !skills, !soul, !safety Заглушки MVP. Требуют готового SDK платформы.
Вложения без текстовой инструкции Поддержан staged UX только для Matrix. Для других поверхностей ещё не перенесено.

Документация

Файл Содержание
docs/surface-protocol.md Унификация поверхностей — все структуры, как добавить новую поверхность
docs/telegram-prototype.md Функционал Telegram прототипа
docs/matrix-prototype.md Функционал Matrix прототипа
docs/api-contract.md Контракт к SDK платформы
docs/user-flow.md FSM и user journey
docs/claude-code-guide.md Гайд по работе с Claude Code

Команда

Поверхности и интеграции Lambda Lab 3.0, МАИ