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/known-limitations.md`](docs/known-limitations.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
|
||||
|
||||
> **ВНИМАНИЕ: Это исторический документ.**
|
||||
> Описанный здесь прототип был интегрирован в `main` и стал основой для Matrix MVP, но архитектура претерпела значительные изменения. Для актуальной информации по деплою смотрите `docs/deploy-architecture.md`, а для создания новой поверхности — `docs/max-surface-guide.md`.
|
||||
|
||||
Русскоязычная заметка по прототипу 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`.
|
||||
|
||||
### Агент → Пользователь
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Руководство по созданию новой поверхности Max
|
||||
# Руководство по созданию новой поверхности
|
||||
|
||||
Этот документ описывает, как написать новую поверхность для Max по образцу текущей Matrix-поверхности в ветке `feat/deploy`.
|
||||
Этот документ описывает, как написать новую новую поверхность (например, Discord, Slack или Custom Web) по образцу текущей Matrix-поверхности в ветке `main`.
|
||||
|
||||
Он основан на актуальной реализации Matrix surface в репозитории и отражает текущую продакшн-логику, а не устаревший легаси.
|
||||
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
### 1.1. Что такое поверхность
|
||||
|
||||
Поверхность — это тонкий адаптер между конкретной платформой (Max) и общим ядром бота.
|
||||
Поверхность — это тонкий адаптер между конкретной платформой (Платформа) и общим ядром бота.
|
||||
|
||||
В репозитории есть разделение:
|
||||
|
||||
|
|
@ -24,17 +24,17 @@
|
|||
|
||||
Поверхность должна:
|
||||
|
||||
- принимать нативные события от Max
|
||||
- принимать нативные события от Платформа
|
||||
- преобразовывать их в единый внутренний контракт (`IncomingMessage`, `IncomingCommand`, `IncomingCallback`)
|
||||
- передавать их в `core`
|
||||
- получать ответы из `core` (`OutgoingMessage`, `OutgoingUI`, `OutgoingTyping`, `OutgoingNotification`)
|
||||
- преобразовывать ответы обратно в нативные Max-сообщения
|
||||
- преобразовывать ответы обратно в нативные нативные сообщения
|
||||
|
||||
Поверхность не должна:
|
||||
|
||||
- управлять жизненным циклом агентских контейнеров
|
||||
- хранить долгую историю бесед вне `core`/платформы
|
||||
- аутентифицировать пользователей сама (если это не часть Max API)
|
||||
- аутентифицировать пользователей сама (если это не часть Платформа API)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -42,10 +42,10 @@
|
|||
|
||||
### 2.1. Основные каталоги
|
||||
|
||||
Рекомендуемая структура для Max:
|
||||
Рекомендуемая структура для новой платформы:
|
||||
|
||||
```
|
||||
adapter/max/
|
||||
adapter/<platform>/
|
||||
bot.py
|
||||
converter.py
|
||||
agent_registry.py
|
||||
|
|
@ -56,14 +56,14 @@ adapter/max/
|
|||
|
||||
### 2.2. Принцип reuse
|
||||
|
||||
По примеру Matrix surface, Max surface должен переиспользовать общий `core` и общий `sdk`.
|
||||
По примеру Matrix surface, New surface должен переиспользовать общий `core` и общий `sdk`.
|
||||
|
||||
Не дублируйте бизнес-логику, а реализуйте только адаптер:
|
||||
|
||||
- `adapter/max/converter.py` — конвертация событий Max ⇄ внутренние структуры
|
||||
- `adapter/max/bot.py` — основной runtime, старт Max client, loop, отправка/прием
|
||||
- `adapter/max/agent_registry.py` — загрузка `config/max-agents.yaml`
|
||||
- `adapter/max/files.py` — хранение входящих/исходящих вложений
|
||||
- `adapter/<platform>/converter.py` — конвертация событий платформы ⇄ внутренние структуры
|
||||
- `adapter/<platform>/bot.py` — основной runtime, старт Платформа client, loop, отправка/прием
|
||||
- `adapter/<platform>/agent_registry.py` — загрузка `config/<platform>-agents.yaml`
|
||||
- `adapter/<platform>/files.py` — хранение входящих/исходящих вложений
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ adapter/max/
|
|||
- `!list`/`!remove` говорят не агенту, а surface-процессу
|
||||
- вложения `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` — список агентов
|
||||
- `workspace_path` для каждого агента должен быть абсолютным путем внутри surface-контейнера, например `/agents/0`
|
||||
|
||||
|
|
@ -181,15 +181,15 @@ Matrix-реализация использует `platform_chat_id` как ст
|
|||
- `reconcile_startup_state()` восстанавливает отсутствующие `platform_chat_id` при рестарте
|
||||
- `RoutedPlatformClient` перенаправляет запросы агенту по `agent_id` + `platform_chat_id`
|
||||
|
||||
Для Max surface тот же принцип:
|
||||
Для New surface тот же принцип:
|
||||
|
||||
- каждая внешняя беседа должна привязываться к одному внутреннему `chat_id`
|
||||
- этот `chat_id` используется для вызовов агента
|
||||
- если в Max есть несколько комнат/топиков, каждая должна иметь свой `surface_ref`
|
||||
- если в Платформа есть несколько комнат/топиков, каждая должна иметь свой `surface_ref`
|
||||
|
||||
### 6.2. Команды управления чатами
|
||||
|
||||
Matrix поддерживает следующие команды, которые нужно сохранить в Max:
|
||||
Matrix поддерживает следующие команды, которые нужно сохранить в Платформа:
|
||||
|
||||
- `!new [название]` — создать новый чат
|
||||
- `!chats` — список активных чатов
|
||||
|
|
@ -211,7 +211,7 @@ Matrix surface поддерживает staged attachments:
|
|||
- surface сохраняет файл в `staged_attachments` для конкретного room_id + user_id
|
||||
- следующий текст отправляется агенту вместе со всеми файлами из очереди
|
||||
|
||||
В Max можно реализовать ту же модель:
|
||||
В Платформа можно реализовать ту же модель:
|
||||
|
||||
- `!list` показывает текущую очередь
|
||||
- `!remove` удаляет файл из очереди
|
||||
|
|
@ -233,10 +233,10 @@ Matrix surface поддерживает staged attachments:
|
|||
- `AGENT_BASE_URL` — fallback URL агента
|
||||
- `SURFACES_WORKSPACE_DIR` — путь к shared volume внутри контейнера (по умолчанию `/workspace` в коде, но в docs рекомендуют `/agents`)
|
||||
|
||||
Для Max surface используйте аналогичные переменные:
|
||||
Для New surface используйте аналогичные переменные:
|
||||
|
||||
- `MAX_PLATFORM_BACKEND=real`
|
||||
- `MAX_AGENT_REGISTRY_PATH=/app/config/max-agents.yaml`
|
||||
- `PLATFORM_PLATFORM_BACKEND=real`
|
||||
- `PLATFORM_AGENT_REGISTRY_PATH=/app/config/<platform>-agents.yaml`
|
||||
- `SURFACES_WORKSPACE_DIR=/agents`
|
||||
- `AGENT_BASE_URL` — если хотите общий fallback
|
||||
|
||||
|
|
@ -248,7 +248,7 @@ Matrix surface поддерживает staged attachments:
|
|||
- `_load_agent_registry_from_env()` читает `MATRIX_AGENT_REGISTRY_PATH`
|
||||
- `_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_context_commands.py`
|
||||
|
||||
Для Max создайте аналогичные тесты:
|
||||
Для Платформа создайте аналогичные тесты:
|
||||
|
||||
- проверка загрузки вложений
|
||||
- проверка маршрутизации по `agent_id`
|
||||
|
|
@ -275,11 +275,11 @@ Matrix surface поддерживает staged attachments:
|
|||
|
||||
Для Matrix surface есть `docker-compose.prod.yml` и `docker-compose.fullstack.yml`.
|
||||
|
||||
Для Max surface должно быть достаточно:
|
||||
Для New surface должно быть достаточно:
|
||||
|
||||
- bot-only production deployment
|
||||
- shared volume `/agents`
|
||||
- независимая проверка `config/max-agents.yaml`
|
||||
- независимая проверка `config/<platform>-agents.yaml`
|
||||
- проверка, что surface запускается без локального агента
|
||||
|
||||
### 8.3. Проверка контрактов
|
||||
|
|
@ -295,22 +295,22 @@ Matrix surface поддерживает staged attachments:
|
|||
|
||||
## 9. Реализация шаг за шагом
|
||||
|
||||
1. Скопировать `adapter/matrix/` как шаблон для `adapter/max/`.
|
||||
2. Сделать `adapter/max/converter.py`:
|
||||
- превратить native Max-сообщения в `IncomingMessage`
|
||||
1. Скопировать `adapter/matrix/` как шаблон для `adapter/<platform>/`.
|
||||
2. Сделать `adapter/<platform>/converter.py`:
|
||||
- превратить native нативные сообщения в `IncomingMessage`
|
||||
- превратить команды в `IncomingCommand`
|
||||
- превратить yes/no-подтверждения в `IncomingCallback`
|
||||
3. Сделать `adapter/max/agent_registry.py` на основе `adapter/matrix/agent_registry.py`.
|
||||
4. Сделать `adapter/max/files.py` на основе `adapter/matrix/files.py`.
|
||||
5. Сделать `adapter/max/bot.py`:
|
||||
3. Сделать `adapter/<platform>/agent_registry.py` на основе `adapter/matrix/agent_registry.py`.
|
||||
4. Сделать `adapter/<platform>/files.py` на основе `adapter/matrix/files.py`.
|
||||
5. Сделать `adapter/<platform>/bot.py`:
|
||||
- инстанцировать runtime
|
||||
- читать env vars `MAX_*`
|
||||
- читать env vars `PLATFORM_*`
|
||||
- загружать реестр агентов
|
||||
- обрабатывать входящие события
|
||||
- отправлять `Outgoing*` обратно в Max
|
||||
- отправлять `Outgoing*` обратно в Платформа
|
||||
6. Реализовать команды управления чатами и очередь вложений.
|
||||
7. Прописать `config/max-agents.yaml`.
|
||||
8. Прописать `docker-compose.max.yml` или аналог, чтобы surface монтировал `/agents`.
|
||||
7. Прописать `config/<platform>-agents.yaml`.
|
||||
8. Прописать `docker-compose.platform.yml` или аналог, чтобы surface монтировал `/agents`.
|
||||
9. Написать тесты по аналогии с `tests/adapter/matrix/`.
|
||||
10. Проверить, что все env vars читаются из окружения и не зависят от устаревших Matrix-переменных.
|
||||
|
||||
|
|
@ -318,10 +318,10 @@ Matrix surface поддерживает staged attachments:
|
|||
|
||||
## 10. Важные замечания
|
||||
|
||||
- Текущий Matrix surface на ветке `feat/deploy` — активная реализация, а не устаревший легаси.
|
||||
- Текущий Matrix surface на ветке `main` — активная реализация, а не устаревший легаси.
|
||||
- Документация и код согласованы: `agent_registry`, `files`, `routed_platform`, `reconciliation` работают вместе.
|
||||
- Обязательно явно задавайте `SURFACES_WORKSPACE_DIR=/agents` в production, если `workspace_path` в реестре указывает на `/agents/*`.
|
||||
- Для Max surface сохраните ту же архитектуру: surface = thin adapter, агенты = внешние сервисы.
|
||||
- Для New surface сохраните ту же архитектуру: surface = thin adapter, агенты = внешние сервисы.
|
||||
- Не пытайтесь в surface реализовывать логику запуска/стопа агент-контейнеров.
|
||||
|
||||
---
|
||||
|
|
@ -38,9 +38,10 @@ surfaces-bot/
|
|||
converter.py — matrix-nio Event → IncomingEvent, OutgoingEvent → Matrix API
|
||||
bot.py — точка входа, клиент
|
||||
|
||||
platform/
|
||||
interface.py — Protocol: PlatformClient
|
||||
mock.py — MockPlatformClient
|
||||
sdk/
|
||||
interface.py — Protocol: PlatformClient (контракт к SDK)
|
||||
real.py — RealPlatformClient (через AgentApi)
|
||||
mock.py — MockPlatformClient (для локальных тестов)
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -140,7 +141,7 @@ class UIButton:
|
|||
```
|
||||
|
||||
Telegram рендерит это как InlineKeyboard.
|
||||
Matrix рендерит как текст с описанием реакций или HTML-кнопки.
|
||||
Matrix рендерит как текст (в MVP).
|
||||
|
||||
### OutgoingNotification
|
||||
Асинхронное уведомление — агент закончил долгую задачу.
|
||||
|
|
@ -209,7 +210,7 @@ class ConfirmationRequest:
|
|||
```
|
||||
|
||||
Telegram показывает как Inline-кнопки.
|
||||
Matrix показывает как реакции 👍 / ❌.
|
||||
Matrix показывает как запрос для `!yes` / `!no`.
|
||||
Ядро не знает как именно — только получает `IncomingCallback` с `action: "confirm"`.
|
||||
|
||||
---
|
||||
|
|
@ -304,9 +305,9 @@ class PlatformClient(Protocol):
|
|||
async def update_settings(self, user_id: str, action: Any) -> None: ...
|
||||
```
|
||||
|
||||
Бот **не управляет lifecycle контейнеров** — это делает Master (платформа).
|
||||
Бот передаёт `user_id` + `chat_id` + текст; Master сам решает нужно ли поднять контейнер, смонтировать `C1/`/`C2/`, запустить агента.
|
||||
Бот **не управляет lifecycle контейнеров** агентов. Запуск/перезапуск агентов — ответственность платформы.
|
||||
Бот передаёт `user_id` + `chat_id` + текст.
|
||||
|
||||
`MockPlatformClient` реализует этот протокол сейчас.
|
||||
Реальный SDK — тоже реализует этот протокол, заменяя один файл.
|
||||
Адаптеры поверхностей и ядро не меняются вообще.
|
||||
`MockPlatformClient` реализует этот протокол для локальных тестов.
|
||||
Реальный SDK используется через `RealPlatformClient` (`sdk/real.py`), который подключается к `AgentApi` по WebSocket.
|
||||
Адаптеры поверхностей и ядро не меняются вообще, привязка идёт через `config/matrix-agents.yaml`.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
# Telegram — описание прототипа
|
||||
|
||||
> **ВНИМАНИЕ: Telegram-адаптер не является частью текущего MVP-деплоя.**
|
||||
> Код Telegram-поверхности находится в отдельной ветке `feat/telegram-adapter`. Данный документ описывает возможности этого адаптера, но многие концепции (например, AuthFlow и MockPlatformClient) устарели по отношению к актуальной архитектуре `main`.
|
||||
|
||||
## Концепция
|
||||
|
||||
Один бот, несколько чатов через 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