docs: generalize new surface guide and clean up legacy docs
This commit is contained in:
parent
0f79494fbe
commit
e7e3912b5f
9 changed files with 59 additions and 433 deletions
|
|
@ -279,3 +279,4 @@ pytest tests/adapter/matrix/ -v # только Matrix
|
||||||
| [`docs/matrix-prototype.md`](docs/matrix-prototype.md) | Команды бота, UX, передача файлов |
|
| [`docs/matrix-prototype.md`](docs/matrix-prototype.md) | Команды бота, UX, передача файлов |
|
||||||
| [`docs/known-limitations.md`](docs/known-limitations.md) | Известные ограничения и обходные пути |
|
| [`docs/known-limitations.md`](docs/known-limitations.md) | Известные ограничения и обходные пути |
|
||||||
| [`docs/surface-protocol.md`](docs/surface-protocol.md) | Внутренний протокол событий (для расширения) |
|
| [`docs/surface-protocol.md`](docs/surface-protocol.md) | Внутренний протокол событий (для расширения) |
|
||||||
|
| [`docs/new-surface-guide.md`](docs/new-surface-guide.md) | Руководство по созданию новой поверхности (Discord, Slack и др.) |
|
||||||
|
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
# API Contract — Lambda Platform
|
|
||||||
|
|
||||||
> **Статус:** ЧЕРНОВИК — проектируем сами, уточняем с Азаматом когда SDK будет готов
|
|
||||||
> **Последнее обновление:** 2026-03-29
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Архитектурный контекст
|
|
||||||
|
|
||||||
Каждому пользователю выделяется **один LXC-контейнер** с workspace 10 ГБ.
|
|
||||||
Workspace содержит директории чатов: `C1/`, `C2/`, `C3/` — файлы + `history.db` в каждом.
|
|
||||||
|
|
||||||
**Master** управляет lifecycle контейнера (запуск, заморозка, пробуждение).
|
|
||||||
Бот **не управляет lifecycle** — он передаёт `user_id` + `chat_id` + сообщение.
|
|
||||||
Master сам решает: нужно ли поднять контейнер, смонтировать нужный чат, запустить агента.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Base URL
|
|
||||||
|
|
||||||
```
|
|
||||||
https://api.lambda-platform.io/v1
|
|
||||||
```
|
|
||||||
|
|
||||||
## Аутентификация
|
|
||||||
|
|
||||||
```
|
|
||||||
Authorization: Bearer {SERVICE_TOKEN}
|
|
||||||
```
|
|
||||||
|
|
||||||
Сервисный токен выдаётся команде поверхностей. Не путать с токеном пользователя.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Users
|
|
||||||
|
|
||||||
### GET /users/{external_id}?platform={platform}
|
|
||||||
|
|
||||||
Получает или создаёт пользователя.
|
|
||||||
|
|
||||||
**Query params:**
|
|
||||||
- `platform` — `telegram` | `matrix`
|
|
||||||
|
|
||||||
**Response 200:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"user_id": "usr_abc123",
|
|
||||||
"external_id": "12345678",
|
|
||||||
"platform": "telegram",
|
|
||||||
"display_name": "Иван Иванов",
|
|
||||||
"created_at": "2025-01-15T10:30:00Z",
|
|
||||||
"is_new": false
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Messages
|
|
||||||
|
|
||||||
Бот не управляет сессиями явно. Отправка сообщения — единственная операция.
|
|
||||||
Master решает: нужен ли новый контейнер, или разбудить существующий.
|
|
||||||
|
|
||||||
### POST /users/{user_id}/chats/{chat_id}/messages
|
|
||||||
|
|
||||||
Отправляет сообщение пользователя агенту. Master поднимает/размораживает контейнер,
|
|
||||||
монтирует нужный чат (`C1/`, `C2/`...), запускает агента.
|
|
||||||
|
|
||||||
**Request:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"text": "Привет, что ты умеешь?",
|
|
||||||
"attachments": []
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response 200:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"message_id": "msg_qwe012",
|
|
||||||
"response": "Я AI-агент Lambda...",
|
|
||||||
"tokens_used": 142,
|
|
||||||
"finished": true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Settings
|
|
||||||
|
|
||||||
### GET /users/{user_id}/settings
|
|
||||||
|
|
||||||
Настройки пользователя: скиллы, коннекторы, SOUL, безопасность, план.
|
|
||||||
|
|
||||||
**Response 200:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"skills": {"web-search": true, "browser": false},
|
|
||||||
"connectors": {"gmail": {"connected": true, "email": "user@gmail.com"}},
|
|
||||||
"soul": {"name": "Лямбда", "style": "friendly"},
|
|
||||||
"safety": {"email-send": true, "file-delete": true},
|
|
||||||
"plan": {"name": "Beta", "tokens_used": 800, "tokens_limit": 1000}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### POST /users/{user_id}/settings
|
|
||||||
|
|
||||||
Применяет действие над настройками.
|
|
||||||
|
|
||||||
**Request:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"action": "toggle_skill",
|
|
||||||
"payload": {"skill": "browser", "enabled": true}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response 200:**
|
|
||||||
```json
|
|
||||||
{"ok": true}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Error format
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"error": "ERROR_CODE",
|
|
||||||
"message": "Human readable description",
|
|
||||||
"details": {}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Коды ошибок: `USER_NOT_FOUND`, `RATE_LIMITED`, `PLATFORM_ERROR`, `CONTAINER_UNAVAILABLE`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Открытые вопросы к команде платфрмы (SDK)
|
|
||||||
|
|
||||||
- [ ] Точный формат эндпоинта отправки сообщения — URL, поля
|
|
||||||
- [ ] Как передавать вложения (файлы, изображения)? Через S3 pre-signed URL или напрямую?
|
|
||||||
- [ ] Стриминговый ответ (SSE / WebSocket) или только sync?
|
|
||||||
- [ ] Формат `SettingsAction` — совпадает с нашим или другой?
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
# Matrix Direct-Agent Prototype
|
# Matrix Direct-Agent Prototype
|
||||||
|
|
||||||
|
> **ВНИМАНИЕ: Это исторический документ.**
|
||||||
|
> Описанный здесь прототип был интегрирован в `main` и стал основой для Matrix MVP, но архитектура претерпела значительные изменения. Для актуальной информации по деплою смотрите `docs/deploy-architecture.md`, а для создания новой поверхности — `docs/max-surface-guide.md`.
|
||||||
|
|
||||||
Русскоязычная заметка по прототипу Matrix surface, который ходит не в `MockPlatformClient`, а напрямую в живой agent backend по WebSocket.
|
Русскоязычная заметка по прототипу Matrix surface, который ходит не в `MockPlatformClient`, а напрямую в живой agent backend по WebSocket.
|
||||||
|
|
||||||
## Что сделали
|
## Что сделали
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ Matrix-клиенты отправляют файлы и текст отдель
|
||||||
## Передача файлов
|
## Передача файлов
|
||||||
|
|
||||||
### Пользователь → Агент
|
### Пользователь → Агент
|
||||||
Бот сохраняет файл в shared volume: `/agents/surfaces/matrix/{user}/{room}/inbox/{stamp}-{filename}`
|
Бот сохраняет файл в shared volume: `{workspace_path}/{filename}`
|
||||||
и передаёт агенту относительный путь как `workspace_path`.
|
и передаёт агенту относительный путь как `workspace_path`.
|
||||||
|
|
||||||
### Агент → Пользователь
|
### Агент → Пользователь
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Руководство по созданию новой поверхности Max
|
# Руководство по созданию новой поверхности
|
||||||
|
|
||||||
Этот документ описывает, как написать новую поверхность для Max по образцу текущей Matrix-поверхности в ветке `feat/deploy`.
|
Этот документ описывает, как написать новую новую поверхность (например, Discord, Slack или Custom Web) по образцу текущей Matrix-поверхности в ветке `main`.
|
||||||
|
|
||||||
Он основан на актуальной реализации Matrix surface в репозитории и отражает текущую продакшн-логику, а не устаревший легаси.
|
Он основан на актуальной реализации Matrix surface в репозитории и отражает текущую продакшн-логику, а не устаревший легаси.
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
### 1.1. Что такое поверхность
|
### 1.1. Что такое поверхность
|
||||||
|
|
||||||
Поверхность — это тонкий адаптер между конкретной платформой (Max) и общим ядром бота.
|
Поверхность — это тонкий адаптер между конкретной платформой (Платформа) и общим ядром бота.
|
||||||
|
|
||||||
В репозитории есть разделение:
|
В репозитории есть разделение:
|
||||||
|
|
||||||
|
|
@ -24,17 +24,17 @@
|
||||||
|
|
||||||
Поверхность должна:
|
Поверхность должна:
|
||||||
|
|
||||||
- принимать нативные события от Max
|
- принимать нативные события от Платформа
|
||||||
- преобразовывать их в единый внутренний контракт (`IncomingMessage`, `IncomingCommand`, `IncomingCallback`)
|
- преобразовывать их в единый внутренний контракт (`IncomingMessage`, `IncomingCommand`, `IncomingCallback`)
|
||||||
- передавать их в `core`
|
- передавать их в `core`
|
||||||
- получать ответы из `core` (`OutgoingMessage`, `OutgoingUI`, `OutgoingTyping`, `OutgoingNotification`)
|
- получать ответы из `core` (`OutgoingMessage`, `OutgoingUI`, `OutgoingTyping`, `OutgoingNotification`)
|
||||||
- преобразовывать ответы обратно в нативные Max-сообщения
|
- преобразовывать ответы обратно в нативные нативные сообщения
|
||||||
|
|
||||||
Поверхность не должна:
|
Поверхность не должна:
|
||||||
|
|
||||||
- управлять жизненным циклом агентских контейнеров
|
- управлять жизненным циклом агентских контейнеров
|
||||||
- хранить долгую историю бесед вне `core`/платформы
|
- хранить долгую историю бесед вне `core`/платформы
|
||||||
- аутентифицировать пользователей сама (если это не часть Max API)
|
- аутентифицировать пользователей сама (если это не часть Платформа API)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -42,10 +42,10 @@
|
||||||
|
|
||||||
### 2.1. Основные каталоги
|
### 2.1. Основные каталоги
|
||||||
|
|
||||||
Рекомендуемая структура для Max:
|
Рекомендуемая структура для новой платформы:
|
||||||
|
|
||||||
```
|
```
|
||||||
adapter/max/
|
adapter/<platform>/
|
||||||
bot.py
|
bot.py
|
||||||
converter.py
|
converter.py
|
||||||
agent_registry.py
|
agent_registry.py
|
||||||
|
|
@ -56,14 +56,14 @@ adapter/max/
|
||||||
|
|
||||||
### 2.2. Принцип reuse
|
### 2.2. Принцип reuse
|
||||||
|
|
||||||
По примеру Matrix surface, Max surface должен переиспользовать общий `core` и общий `sdk`.
|
По примеру Matrix surface, New surface должен переиспользовать общий `core` и общий `sdk`.
|
||||||
|
|
||||||
Не дублируйте бизнес-логику, а реализуйте только адаптер:
|
Не дублируйте бизнес-логику, а реализуйте только адаптер:
|
||||||
|
|
||||||
- `adapter/max/converter.py` — конвертация событий Max ⇄ внутренние структуры
|
- `adapter/<platform>/converter.py` — конвертация событий платформы ⇄ внутренние структуры
|
||||||
- `adapter/max/bot.py` — основной runtime, старт Max client, loop, отправка/прием
|
- `adapter/<platform>/bot.py` — основной runtime, старт Платформа client, loop, отправка/прием
|
||||||
- `adapter/max/agent_registry.py` — загрузка `config/max-agents.yaml`
|
- `adapter/<platform>/agent_registry.py` — загрузка `config/<platform>-agents.yaml`
|
||||||
- `adapter/max/files.py` — хранение входящих/исходящих вложений
|
- `adapter/<platform>/files.py` — хранение входящих/исходящих вложений
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ adapter/max/
|
||||||
- `!list`/`!remove` говорят не агенту, а surface-процессу
|
- `!list`/`!remove` говорят не агенту, а surface-процессу
|
||||||
- вложения `m.file`, `m.image`, `m.audio`, `m.video` нормализуются в `Attachment`
|
- вложения `m.file`, `m.image`, `m.audio`, `m.video` нормализуются в `Attachment`
|
||||||
|
|
||||||
Для Max реализуйте аналогичную логику для native команд вашего клиента.
|
Для Платформа реализуйте аналогичную логику для native команд вашего клиента.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -122,11 +122,11 @@ agents:
|
||||||
|
|
||||||
Это важно: именно на этом контракте строится разделение агентов по рабочим каталогам.
|
Это важно: именно на этом контракте строится разделение агентов по рабочим каталогам.
|
||||||
|
|
||||||
### 4.3. Рекомендуемая Max-версия
|
### 4.3. Рекомендуемая Версия для новой платформы
|
||||||
|
|
||||||
Создайте `config/max-agents.yaml` с тем же смыслом.
|
Создайте `config/<platform>-agents.yaml` с тем же смыслом.
|
||||||
|
|
||||||
- `user_agents` — маппинг Max user_id → agent_id
|
- `user_agents` — маппинг external user_id → agent_id
|
||||||
- `agents` — список агентов
|
- `agents` — список агентов
|
||||||
- `workspace_path` для каждого агента должен быть абсолютным путем внутри surface-контейнера, например `/agents/0`
|
- `workspace_path` для каждого агента должен быть абсолютным путем внутри surface-контейнера, например `/agents/0`
|
||||||
|
|
||||||
|
|
@ -181,15 +181,15 @@ Matrix-реализация использует `platform_chat_id` как ст
|
||||||
- `reconcile_startup_state()` восстанавливает отсутствующие `platform_chat_id` при рестарте
|
- `reconcile_startup_state()` восстанавливает отсутствующие `platform_chat_id` при рестарте
|
||||||
- `RoutedPlatformClient` перенаправляет запросы агенту по `agent_id` + `platform_chat_id`
|
- `RoutedPlatformClient` перенаправляет запросы агенту по `agent_id` + `platform_chat_id`
|
||||||
|
|
||||||
Для Max surface тот же принцип:
|
Для New surface тот же принцип:
|
||||||
|
|
||||||
- каждая внешняя беседа должна привязываться к одному внутреннему `chat_id`
|
- каждая внешняя беседа должна привязываться к одному внутреннему `chat_id`
|
||||||
- этот `chat_id` используется для вызовов агента
|
- этот `chat_id` используется для вызовов агента
|
||||||
- если в Max есть несколько комнат/топиков, каждая должна иметь свой `surface_ref`
|
- если в Платформа есть несколько комнат/топиков, каждая должна иметь свой `surface_ref`
|
||||||
|
|
||||||
### 6.2. Команды управления чатами
|
### 6.2. Команды управления чатами
|
||||||
|
|
||||||
Matrix поддерживает следующие команды, которые нужно сохранить в Max:
|
Matrix поддерживает следующие команды, которые нужно сохранить в Платформа:
|
||||||
|
|
||||||
- `!new [название]` — создать новый чат
|
- `!new [название]` — создать новый чат
|
||||||
- `!chats` — список активных чатов
|
- `!chats` — список активных чатов
|
||||||
|
|
@ -211,7 +211,7 @@ Matrix surface поддерживает staged attachments:
|
||||||
- surface сохраняет файл в `staged_attachments` для конкретного room_id + user_id
|
- surface сохраняет файл в `staged_attachments` для конкретного room_id + user_id
|
||||||
- следующий текст отправляется агенту вместе со всеми файлами из очереди
|
- следующий текст отправляется агенту вместе со всеми файлами из очереди
|
||||||
|
|
||||||
В Max можно реализовать ту же модель:
|
В Платформа можно реализовать ту же модель:
|
||||||
|
|
||||||
- `!list` показывает текущую очередь
|
- `!list` показывает текущую очередь
|
||||||
- `!remove` удаляет файл из очереди
|
- `!remove` удаляет файл из очереди
|
||||||
|
|
@ -233,10 +233,10 @@ Matrix surface поддерживает staged attachments:
|
||||||
- `AGENT_BASE_URL` — fallback URL агента
|
- `AGENT_BASE_URL` — fallback URL агента
|
||||||
- `SURFACES_WORKSPACE_DIR` — путь к shared volume внутри контейнера (по умолчанию `/workspace` в коде, но в docs рекомендуют `/agents`)
|
- `SURFACES_WORKSPACE_DIR` — путь к shared volume внутри контейнера (по умолчанию `/workspace` в коде, но в docs рекомендуют `/agents`)
|
||||||
|
|
||||||
Для Max surface используйте аналогичные переменные:
|
Для New surface используйте аналогичные переменные:
|
||||||
|
|
||||||
- `MAX_PLATFORM_BACKEND=real`
|
- `PLATFORM_PLATFORM_BACKEND=real`
|
||||||
- `MAX_AGENT_REGISTRY_PATH=/app/config/max-agents.yaml`
|
- `PLATFORM_AGENT_REGISTRY_PATH=/app/config/<platform>-agents.yaml`
|
||||||
- `SURFACES_WORKSPACE_DIR=/agents`
|
- `SURFACES_WORKSPACE_DIR=/agents`
|
||||||
- `AGENT_BASE_URL` — если хотите общий fallback
|
- `AGENT_BASE_URL` — если хотите общий fallback
|
||||||
|
|
||||||
|
|
@ -248,7 +248,7 @@ Matrix surface поддерживает staged attachments:
|
||||||
- `_load_agent_registry_from_env()` читает `MATRIX_AGENT_REGISTRY_PATH`
|
- `_load_agent_registry_from_env()` читает `MATRIX_AGENT_REGISTRY_PATH`
|
||||||
- `_build_platform_from_env()` выбирает `RealPlatformClient` при `MATRIX_PLATFORM_BACKEND=real`
|
- `_build_platform_from_env()` выбирает `RealPlatformClient` при `MATRIX_PLATFORM_BACKEND=real`
|
||||||
|
|
||||||
В Max surface реализуйте ту же логику, заменив префиксы на `MAX_`.
|
В New surface реализуйте ту же логику, заменив префиксы на `PLATFORM_`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -264,7 +264,7 @@ Matrix surface поддерживает staged attachments:
|
||||||
- `tests/adapter/matrix/test_reconciliation.py`
|
- `tests/adapter/matrix/test_reconciliation.py`
|
||||||
- `tests/adapter/matrix/test_context_commands.py`
|
- `tests/adapter/matrix/test_context_commands.py`
|
||||||
|
|
||||||
Для Max создайте аналогичные тесты:
|
Для Платформа создайте аналогичные тесты:
|
||||||
|
|
||||||
- проверка загрузки вложений
|
- проверка загрузки вложений
|
||||||
- проверка маршрутизации по `agent_id`
|
- проверка маршрутизации по `agent_id`
|
||||||
|
|
@ -275,11 +275,11 @@ Matrix surface поддерживает staged attachments:
|
||||||
|
|
||||||
Для Matrix surface есть `docker-compose.prod.yml` и `docker-compose.fullstack.yml`.
|
Для Matrix surface есть `docker-compose.prod.yml` и `docker-compose.fullstack.yml`.
|
||||||
|
|
||||||
Для Max surface должно быть достаточно:
|
Для New surface должно быть достаточно:
|
||||||
|
|
||||||
- bot-only production deployment
|
- bot-only production deployment
|
||||||
- shared volume `/agents`
|
- shared volume `/agents`
|
||||||
- независимая проверка `config/max-agents.yaml`
|
- независимая проверка `config/<platform>-agents.yaml`
|
||||||
- проверка, что surface запускается без локального агента
|
- проверка, что surface запускается без локального агента
|
||||||
|
|
||||||
### 8.3. Проверка контрактов
|
### 8.3. Проверка контрактов
|
||||||
|
|
@ -295,22 +295,22 @@ Matrix surface поддерживает staged attachments:
|
||||||
|
|
||||||
## 9. Реализация шаг за шагом
|
## 9. Реализация шаг за шагом
|
||||||
|
|
||||||
1. Скопировать `adapter/matrix/` как шаблон для `adapter/max/`.
|
1. Скопировать `adapter/matrix/` как шаблон для `adapter/<platform>/`.
|
||||||
2. Сделать `adapter/max/converter.py`:
|
2. Сделать `adapter/<platform>/converter.py`:
|
||||||
- превратить native Max-сообщения в `IncomingMessage`
|
- превратить native нативные сообщения в `IncomingMessage`
|
||||||
- превратить команды в `IncomingCommand`
|
- превратить команды в `IncomingCommand`
|
||||||
- превратить yes/no-подтверждения в `IncomingCallback`
|
- превратить yes/no-подтверждения в `IncomingCallback`
|
||||||
3. Сделать `adapter/max/agent_registry.py` на основе `adapter/matrix/agent_registry.py`.
|
3. Сделать `adapter/<platform>/agent_registry.py` на основе `adapter/matrix/agent_registry.py`.
|
||||||
4. Сделать `adapter/max/files.py` на основе `adapter/matrix/files.py`.
|
4. Сделать `adapter/<platform>/files.py` на основе `adapter/matrix/files.py`.
|
||||||
5. Сделать `adapter/max/bot.py`:
|
5. Сделать `adapter/<platform>/bot.py`:
|
||||||
- инстанцировать runtime
|
- инстанцировать runtime
|
||||||
- читать env vars `MAX_*`
|
- читать env vars `PLATFORM_*`
|
||||||
- загружать реестр агентов
|
- загружать реестр агентов
|
||||||
- обрабатывать входящие события
|
- обрабатывать входящие события
|
||||||
- отправлять `Outgoing*` обратно в Max
|
- отправлять `Outgoing*` обратно в Платформа
|
||||||
6. Реализовать команды управления чатами и очередь вложений.
|
6. Реализовать команды управления чатами и очередь вложений.
|
||||||
7. Прописать `config/max-agents.yaml`.
|
7. Прописать `config/<platform>-agents.yaml`.
|
||||||
8. Прописать `docker-compose.max.yml` или аналог, чтобы surface монтировал `/agents`.
|
8. Прописать `docker-compose.platform.yml` или аналог, чтобы surface монтировал `/agents`.
|
||||||
9. Написать тесты по аналогии с `tests/adapter/matrix/`.
|
9. Написать тесты по аналогии с `tests/adapter/matrix/`.
|
||||||
10. Проверить, что все env vars читаются из окружения и не зависят от устаревших Matrix-переменных.
|
10. Проверить, что все env vars читаются из окружения и не зависят от устаревших Matrix-переменных.
|
||||||
|
|
||||||
|
|
@ -318,10 +318,10 @@ Matrix surface поддерживает staged attachments:
|
||||||
|
|
||||||
## 10. Важные замечания
|
## 10. Важные замечания
|
||||||
|
|
||||||
- Текущий Matrix surface на ветке `feat/deploy` — активная реализация, а не устаревший легаси.
|
- Текущий Matrix surface на ветке `main` — активная реализация, а не устаревший легаси.
|
||||||
- Документация и код согласованы: `agent_registry`, `files`, `routed_platform`, `reconciliation` работают вместе.
|
- Документация и код согласованы: `agent_registry`, `files`, `routed_platform`, `reconciliation` работают вместе.
|
||||||
- Обязательно явно задавайте `SURFACES_WORKSPACE_DIR=/agents` в production, если `workspace_path` в реестре указывает на `/agents/*`.
|
- Обязательно явно задавайте `SURFACES_WORKSPACE_DIR=/agents` в production, если `workspace_path` в реестре указывает на `/agents/*`.
|
||||||
- Для Max surface сохраните ту же архитектуру: surface = thin adapter, агенты = внешние сервисы.
|
- Для New surface сохраните ту же архитектуру: surface = thin adapter, агенты = внешние сервисы.
|
||||||
- Не пытайтесь в surface реализовывать логику запуска/стопа агент-контейнеров.
|
- Не пытайтесь в surface реализовывать логику запуска/стопа агент-контейнеров.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -38,9 +38,10 @@ surfaces-bot/
|
||||||
converter.py — matrix-nio Event → IncomingEvent, OutgoingEvent → Matrix API
|
converter.py — matrix-nio Event → IncomingEvent, OutgoingEvent → Matrix API
|
||||||
bot.py — точка входа, клиент
|
bot.py — точка входа, клиент
|
||||||
|
|
||||||
platform/
|
sdk/
|
||||||
interface.py — Protocol: PlatformClient
|
interface.py — Protocol: PlatformClient (контракт к SDK)
|
||||||
mock.py — MockPlatformClient
|
real.py — RealPlatformClient (через AgentApi)
|
||||||
|
mock.py — MockPlatformClient (для локальных тестов)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -140,7 +141,7 @@ class UIButton:
|
||||||
```
|
```
|
||||||
|
|
||||||
Telegram рендерит это как InlineKeyboard.
|
Telegram рендерит это как InlineKeyboard.
|
||||||
Matrix рендерит как текст с описанием реакций или HTML-кнопки.
|
Matrix рендерит как текст (в MVP).
|
||||||
|
|
||||||
### OutgoingNotification
|
### OutgoingNotification
|
||||||
Асинхронное уведомление — агент закончил долгую задачу.
|
Асинхронное уведомление — агент закончил долгую задачу.
|
||||||
|
|
@ -209,7 +210,7 @@ class ConfirmationRequest:
|
||||||
```
|
```
|
||||||
|
|
||||||
Telegram показывает как Inline-кнопки.
|
Telegram показывает как Inline-кнопки.
|
||||||
Matrix показывает как реакции 👍 / ❌.
|
Matrix показывает как запрос для `!yes` / `!no`.
|
||||||
Ядро не знает как именно — только получает `IncomingCallback` с `action: "confirm"`.
|
Ядро не знает как именно — только получает `IncomingCallback` с `action: "confirm"`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -304,9 +305,9 @@ class PlatformClient(Protocol):
|
||||||
async def update_settings(self, user_id: str, action: Any) -> None: ...
|
async def update_settings(self, user_id: str, action: Any) -> None: ...
|
||||||
```
|
```
|
||||||
|
|
||||||
Бот **не управляет lifecycle контейнеров** — это делает Master (платформа).
|
Бот **не управляет lifecycle контейнеров** агентов. Запуск/перезапуск агентов — ответственность платформы.
|
||||||
Бот передаёт `user_id` + `chat_id` + текст; Master сам решает нужно ли поднять контейнер, смонтировать `C1/`/`C2/`, запустить агента.
|
Бот передаёт `user_id` + `chat_id` + текст.
|
||||||
|
|
||||||
`MockPlatformClient` реализует этот протокол сейчас.
|
`MockPlatformClient` реализует этот протокол для локальных тестов.
|
||||||
Реальный SDK — тоже реализует этот протокол, заменяя один файл.
|
Реальный SDK используется через `RealPlatformClient` (`sdk/real.py`), который подключается к `AgentApi` по WebSocket.
|
||||||
Адаптеры поверхностей и ядро не меняются вообще.
|
Адаптеры поверхностей и ядро не меняются вообще, привязка идёт через `config/matrix-agents.yaml`.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
# Telegram — описание прототипа
|
# Telegram — описание прототипа
|
||||||
|
|
||||||
|
> **ВНИМАНИЕ: Telegram-адаптер не является частью текущего MVP-деплоя.**
|
||||||
|
> Код Telegram-поверхности находится в отдельной ветке `feat/telegram-adapter`. Данный документ описывает возможности этого адаптера, но многие концепции (например, AuthFlow и MockPlatformClient) устарели по отношению к актуальной архитектуре `main`.
|
||||||
|
|
||||||
## Концепция
|
## Концепция
|
||||||
|
|
||||||
Один бот, несколько чатов через Topics в Forum-группе.
|
Один бот, несколько чатов через Topics в Forum-группе.
|
||||||
|
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
# User Flow — Lambda Bot
|
|
||||||
|
|
||||||
> **Статус:** ШАБЛОН — заполняет @architect после исследований
|
|
||||||
> **Зависит от:** docs/research/telegram-flows.md, docs/research/competitor-ux.md
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Основной сценарий (happy path)
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
actor User
|
|
||||||
participant Bot as Telegram/Matrix Bot
|
|
||||||
participant Platform as Lambda Platform (Master)
|
|
||||||
|
|
||||||
User->>Bot: /start
|
|
||||||
Bot->>Platform: GET /users/{tg_id}?platform=telegram
|
|
||||||
Platform-->>Bot: {user_id, is_new}
|
|
||||||
|
|
||||||
alt Новый пользователь
|
|
||||||
Bot->>User: Приветствие + инструкция
|
|
||||||
else Существующий пользователь
|
|
||||||
Bot->>User: Добро пожаловать обратно
|
|
||||||
end
|
|
||||||
|
|
||||||
loop Диалог (бот не управляет сессиями — Master делает это автоматически)
|
|
||||||
User->>Bot: Сообщение в чат C1/C2/...
|
|
||||||
Bot->>Platform: POST /users/{user_id}/chats/{chat_id}/messages
|
|
||||||
Note over Platform: Master поднимает контейнер,<br/>монтирует нужный чат, запускает агента
|
|
||||||
Platform-->>Bot: {message_id, response, tokens_used}
|
|
||||||
Bot->>User: Ответ агента
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Состояния FSM (Telegram)
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
stateDiagram-v2
|
|
||||||
[*] --> Unauthenticated: первый контакт
|
|
||||||
|
|
||||||
Unauthenticated --> Idle: /start (auth confirmed)
|
|
||||||
|
|
||||||
Idle --> WaitingResponse: сообщение пользователя
|
|
||||||
WaitingResponse --> Idle: ответ получен
|
|
||||||
WaitingResponse --> Error: ошибка платформы
|
|
||||||
|
|
||||||
Idle --> Idle: /new (создан новый чат)
|
|
||||||
Idle --> ConfirmAction: агент запрашивает подтверждение
|
|
||||||
ConfirmAction --> Idle: подтверждено / отменено
|
|
||||||
|
|
||||||
Error --> Idle: /start
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Открытые вопросы
|
|
||||||
|
|
||||||
> Заполняет @researcher и @architect после исследований
|
|
||||||
|
|
||||||
- [ ] Как выглядит онбординг новых пользователей у конкурентов?
|
|
||||||
- [ ] Нужна ли кнопка "Новая сессия" или сессия стартует автоматически?
|
|
||||||
- [ ] Что показываем пока агент думает (typing indicator)?
|
|
||||||
- [ ] Как обрабатываем timeout ответа от платформы?
|
|
||||||
|
|
@ -1,174 +0,0 @@
|
||||||
# Surfaces team — Lambda Lab 3.0
|
|
||||||
|
|
||||||
Telegram и Matrix боты для взаимодействия пользователя с AI-агентом Lambda.
|
|
||||||
|
|
||||||
## Правило №1: не быть ждуном
|
|
||||||
|
|
||||||
Платформа (SDK от Азамата) ещё не готова. Это **не блокер**.
|
|
||||||
|
|
||||||
- Все вызовы платформы — через `platform/interface.py` (Protocol)
|
|
||||||
- Реализация сейчас — `platform/mock.py` (MockPlatformClient)
|
|
||||||
- При подключении реального SDK — меняем только `platform/mock.py`
|
|
||||||
- Архитектурные решения принимаем сами, фиксируем в `docs/api-contract.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Архитектура
|
|
||||||
|
|
||||||
```
|
|
||||||
surfaces-bot/
|
|
||||||
core/
|
|
||||||
protocol.py — унифицированные структуры (IncomingMessage, OutgoingUI, ...)
|
|
||||||
handler.py — EventDispatcher: IncomingEvent → OutgoingEvent (общее для всех ботов)
|
|
||||||
handlers/ — обработчики по типам событий (start, message, chat, settings, callback)
|
|
||||||
store.py — StateStore Protocol + InMemoryStore + SQLiteStore
|
|
||||||
chat.py — ChatManager: метаданные чатов C1/C2/C3
|
|
||||||
auth.py — AuthManager: AuthFlow
|
|
||||||
settings.py — SettingsManager: SettingsAction
|
|
||||||
|
|
||||||
adapter/
|
|
||||||
telegram/ — aiogram адаптер
|
|
||||||
converter.py — aiogram Event → IncomingEvent и обратно
|
|
||||||
bot.py — точка входа
|
|
||||||
handlers/ — aiogram роутеры
|
|
||||||
keyboards/ — инлайн-клавиатуры
|
|
||||||
states.py — FSM состояния
|
|
||||||
matrix/ — matrix-nio адаптер
|
|
||||||
converter.py — matrix-nio Event → IncomingEvent и обратно
|
|
||||||
bot.py — точка входа
|
|
||||||
handlers/ — обработчики событий
|
|
||||||
|
|
||||||
platform/
|
|
||||||
interface.py — Protocol: PlatformClient (контракт к SDK)
|
|
||||||
mock.py — MockPlatformClient (заглушка)
|
|
||||||
|
|
||||||
docs/ — вся документация
|
|
||||||
tests/ — pytest тесты
|
|
||||||
.claude/agents/ — конфиги агентов
|
|
||||||
```
|
|
||||||
|
|
||||||
Подробно об унификации: `docs/surface-protocol.md`
|
|
||||||
Telegram функционал: `docs/telegram-prototype.md`
|
|
||||||
Matrix функционал: `docs/matrix-prototype.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Агенты
|
|
||||||
|
|
||||||
| Агент | Когда запускать | Модель | Токены |
|
|
||||||
|-------|----------------|--------|--------|
|
|
||||||
| `@researcher` | Изучить API, найти примеры | Haiku | ~дёшево |
|
|
||||||
| `@architect` | Спроектировать решение | Sonnet | ~средне |
|
|
||||||
| `@tg-developer` | Писать код Telegram-адаптера | Sonnet | ~средне |
|
|
||||||
| `@matrix-developer` | Писать код Matrix-адаптера | Sonnet | ~средне |
|
|
||||||
| `@core-developer` | Писать core/ и platform/ | Sonnet | ~средне |
|
|
||||||
| `@reviewer` | Проверить код перед PR | Sonnet | ~средне |
|
|
||||||
|
|
||||||
**Важно (Pro-лимиты):** не запускай больше двух Sonnet-агентов одновременно.
|
|
||||||
Haiku можно запускать параллельно сколько угодно.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Стратегия параллельной разработки
|
|
||||||
|
|
||||||
Два бота разрабатываются параллельно, но через общее ядро.
|
|
||||||
|
|
||||||
### Порядок работы
|
|
||||||
|
|
||||||
```
|
|
||||||
1. core/ — сначала (однократно, все ждут)
|
|
||||||
@core-developer пишет protocol.py, handler.py, session.py, auth.py, settings.py
|
|
||||||
|
|
||||||
2. platform/ — сразу после core/
|
|
||||||
@core-developer пишет interface.py и mock.py
|
|
||||||
|
|
||||||
3. adapter/telegram/ и adapter/matrix/ — параллельно
|
|
||||||
@tg-developer → adapter/telegram/
|
|
||||||
@matrix-developer → adapter/matrix/
|
|
||||||
Не пересекаются по файлам — можно одновременно в разных терминалах.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Что можно делать одновременно (разные терминалы)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Терминал 1 — Telegram адаптер
|
|
||||||
claude "Use @tg-developer to implement adapter/telegram/handlers/start.py"
|
|
||||||
|
|
||||||
# Терминал 2 — Matrix адаптер (параллельно)
|
|
||||||
claude "Use @matrix-developer to implement adapter/matrix/handlers/start.py"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Что нельзя делать одновременно
|
|
||||||
|
|
||||||
- Два агента в одном файле
|
|
||||||
- @core-developer параллельно с @tg-developer или @matrix-developer
|
|
||||||
(core/ должен быть готов до адаптеров)
|
|
||||||
- Больше двух Sonnet-агентов одновременно (Pro-лимит)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Git worktree workflow
|
|
||||||
|
|
||||||
Каждая фича в отдельном worktree — адаптеры не мешают друг другу:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Создать worktrees для параллельной работы
|
|
||||||
git worktree add .worktrees/telegram -b feat/telegram-adapter
|
|
||||||
git worktree add .worktrees/matrix -b feat/matrix-adapter
|
|
||||||
|
|
||||||
# Работать в каждом независимо
|
|
||||||
cd .worktrees/telegram && claude "Use @tg-developer to ..."
|
|
||||||
cd .worktrees/matrix && claude "Use @matrix-developer to ..."
|
|
||||||
|
|
||||||
# Смержить когда готово
|
|
||||||
git checkout main
|
|
||||||
git merge feat/telegram-adapter
|
|
||||||
git merge feat/matrix-adapter
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Команды запуска
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Установить зависимости
|
|
||||||
uv sync
|
|
||||||
|
|
||||||
# Запустить тесты
|
|
||||||
pytest tests/ -v
|
|
||||||
|
|
||||||
# Запустить только тесты Telegram
|
|
||||||
pytest tests/adapter/telegram/ -v
|
|
||||||
|
|
||||||
# Запустить только тесты Matrix
|
|
||||||
pytest tests/adapter/matrix/ -v
|
|
||||||
|
|
||||||
# Запустить только тесты ядра
|
|
||||||
pytest tests/core/ -v
|
|
||||||
|
|
||||||
# Запустить Telegram бота
|
|
||||||
python -m adapter.telegram.bot
|
|
||||||
|
|
||||||
# Запустить Matrix бота
|
|
||||||
python -m adapter.matrix.bot
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Переменные окружения
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cp .env.example .env
|
|
||||||
```
|
|
||||||
|
|
||||||
Никогда не коммить `.env`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Экономия токенов (Pro-лимиты)
|
|
||||||
|
|
||||||
- Исследования → всегда `@researcher` (Haiku), не Sonnet
|
|
||||||
- Точечные правки в одном файле → напрямую без агента
|
|
||||||
- Ревью → только перед PR, не после каждого коммита
|
|
||||||
- Длинный контекст → дай агенту конкретный файл, не весь проект
|
|
||||||
- Если агент "завис" в рассуждениях → прерви, переформулируй задачу точнее
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue