docs(05-04): document split deployment artifacts
- document prod vs fullstack compose usage - align operator docs with shared /agents contract
This commit is contained in:
parent
85e2fda6bc
commit
22a3a2b60a
2 changed files with 50 additions and 24 deletions
41
README.md
41
README.md
|
|
@ -7,7 +7,7 @@
|
|||
| Поверхность | Статус |
|
||||
|---|---|
|
||||
| Telegram | 🔨 В разработке, отдельный worktree `feat/telegram-adapter` |
|
||||
| Matrix | ✅ Рабочий прототип, запускается через root `docker compose` вместе с `platform-agent` |
|
||||
| Matrix | ✅ MVP runtime: `docker-compose.prod.yml` для bot-only handoff, `docker-compose.fullstack.yml` для internal E2E |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ class PlatformClient(Protocol):
|
|||
Бот передаёт `user_id` + `chat_id` + сообщение; платформа сама решает нужно ли поднять контейнер.
|
||||
|
||||
Сейчас: `MockPlatformClient` в `sdk/mock.py`, а Matrix real backend собирается через `sdk/real.py` при `MATRIX_PLATFORM_BACKEND=real`.
|
||||
Файловый контракт уже path-based: бот пишет файлы в shared `/workspace` и передаёт платформе относительные пути в `attachments`.
|
||||
Файловый контракт уже path-based: бот пишет файлы в shared `/agents` и передаёт платформе относительные пути в `attachments`, которые агент читает внутри своего `/workspace`.
|
||||
Когда SDK готов: добавляем `SdkPlatformClient`, меняем одну строку в DI. Адаптеры и ядро не трогаем.
|
||||
|
||||
---
|
||||
|
|
@ -121,9 +121,13 @@ MATRIX_PASSWORD=... # или MATRIX_ACCESS_TOKEN=...
|
|||
# Выбор backend: mock (по умолчанию) или real (подключение к platform-agent)
|
||||
MATRIX_PLATFORM_BACKEND=real
|
||||
|
||||
# compose runtime: platform-agent service name + shared /workspace
|
||||
AGENT_BASE_URL=http://platform-agent:8000
|
||||
SURFACES_WORKSPACE_DIR=/workspace
|
||||
# production handoff: bot connects to externally managed agent endpoint
|
||||
AGENT_BASE_URL=https://lambda.coredump.ru/agent_0/
|
||||
SURFACES_WORKSPACE_DIR=/agents
|
||||
SURFACES_SHARED_VOLUME=surfaces-agents
|
||||
|
||||
# internal full-stack compose defaults
|
||||
AGENT_ID=matrix-dev
|
||||
|
||||
# platform-agent provider
|
||||
PROVIDER_MODEL=openai/gpt-4o-mini
|
||||
|
|
@ -137,19 +141,28 @@ PROVIDER_API_KEY=...
|
|||
2. Если готовишься к multi-agent routing, добавь `MATRIX_AGENT_REGISTRY_PATH=config/matrix-agents.yaml` в `.env`
|
||||
3. Этот registry сейчас является конфигурационным артефактом Task 1; текущий Matrix runtime его ещё не читает
|
||||
|
||||
### 4. Compose runtime
|
||||
### 4. Compose artifacts
|
||||
|
||||
Root `docker-compose.yml` теперь является основным локальным runtime для Matrix и platform-agent.
|
||||
Он поднимает `matrix-bot`, `platform-agent` и общий volume `/workspace`.
|
||||
Production handoff uses `docker-compose.prod.yml`.
|
||||
Этот файл поднимает только `matrix-bot`, монтирует shared volume в `/agents` и ожидает, что `AGENT_BASE_URL`
|
||||
указывает на уже управляемый внешней платформой agent endpoint.
|
||||
|
||||
```bash
|
||||
docker compose up --build
|
||||
docker compose --env-file .env -f docker-compose.prod.yml up -d --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`.
|
||||
Internal full-stack E2E uses `docker-compose.fullstack.yml`.
|
||||
Этот файл поднимает `matrix-bot` вместе с локальным `platform-agent`, использует тот же shared volume
|
||||
(`SURFACES_SHARED_VOLUME`) и ждёт `service_healthy` вместо sleep-based sequencing.
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env -f docker-compose.fullstack.yml up --build
|
||||
```
|
||||
|
||||
`docker-compose.fullstack.yml` собирает `platform-agent` из актуального upstream `external/platform-agent`
|
||||
(`development` target), монтирует live-код из `external/platform-agent/src` и `external/platform-agent_api`,
|
||||
а shared volume виден как `/agents` в bot container и как `/workspace` в `platform-agent`.
|
||||
Старый root compose harness остаётся только как historical local reference и больше не является рекомендуемым runtime path.
|
||||
|
||||
На `2026-04-21` локальный compose runtime использует vendored upstream-версии платформы без локальных патчей:
|
||||
|
||||
|
|
@ -159,7 +172,7 @@ Matrix бот подключается к `platform-agent` по service name, а
|
|||
### 4. Staged attachments в Matrix
|
||||
|
||||
Если Matrix-клиент отправляет файлы отдельными media events, бот не вызывает агента сразу.
|
||||
Вместо этого он сохраняет файлы в shared `/workspace`, ставит их в очередь для конкретного чата и пользователя, и ждёт следующего обычного сообщения.
|
||||
Вместо этого он сохраняет файлы в shared `/agents`, ставит их в очередь для конкретного чата и пользователя, и ждёт следующего обычного сообщения.
|
||||
|
||||
Как отправить файлы агенту:
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,18 @@
|
|||
|
||||
---
|
||||
|
||||
## Compose Artifacts
|
||||
|
||||
- **Production deploy:** `docker-compose.prod.yml`
|
||||
Bot-only handoff. Поднимает только `matrix-bot`, монтирует shared volume в `/agents`, требует внешний `AGENT_BASE_URL`.
|
||||
- **Internal full-stack E2E:** `docker-compose.fullstack.yml`
|
||||
Внутренний harness. Поднимает `matrix-bot` и `platform-agent`, использует тот же volume name и health-gated startup через `condition: service_healthy`.
|
||||
|
||||
Production operators should run the bot with `docker-compose.prod.yml`; internal verification should use `docker-compose.fullstack.yml`.
|
||||
Старый root compose harness больше не является primary runtime contract для Phase 05.
|
||||
|
||||
---
|
||||
|
||||
## Топология
|
||||
|
||||
```
|
||||
|
|
@ -22,7 +34,7 @@ lambda.coredump.ru
|
|||
|
||||
- **Один инстанс Matrix-бота** обслуживает всех пользователей.
|
||||
- **Один агент-контейнер на пользователя.** Изоляция по agent_id, не через chat_id внутри одного инстанса.
|
||||
- **Shared volume** `/agents/` смонтирован и в Matrix-бот, и в каждый агент-контейнер. Агент видит свой подкаталог как `/workspace`.
|
||||
- **Shared volume** `/agents/` смонтирован в Matrix-бот. В internal full-stack harness тот же volume mounted as `/workspace` inside `platform-agent`, чтобы bot-side absolute paths и agent workspace относились к одному и тому же хранилищу.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -58,24 +70,25 @@ agents:
|
|||
```python
|
||||
from lambda_agent_api.agent_api import AgentApi
|
||||
|
||||
connected_agents: dict[str, AgentApi] = {}
|
||||
connected_agents: dict[tuple[str, int], AgentApi] = {}
|
||||
|
||||
def on_agent_disconnect(agent: AgentApi):
|
||||
del connected_agents[agent.id]
|
||||
connected_agents.pop((agent.id, agent.chat_id), None)
|
||||
|
||||
async def on_message(matrix_user_id: str, text: str):
|
||||
async def on_message(matrix_user_id: str, matrix_room_id: str, text: str):
|
||||
agent_id = get_agent_id_by_user(matrix_user_id) # из user_agents конфига
|
||||
platform_chat_id = get_room_platform_chat_id(matrix_room_id)
|
||||
|
||||
agent = connected_agents.get(agent_id)
|
||||
agent = connected_agents.get((agent_id, platform_chat_id))
|
||||
if not agent:
|
||||
agent = AgentApi(
|
||||
agent_id,
|
||||
get_agent_base_url(agent_id), # ws://lambda.coredump.ru:7000/agent_0/
|
||||
on_disconnect=on_agent_disconnect,
|
||||
chat_id=0, # default, один чат на агента
|
||||
chat_id=platform_chat_id, # отдельный thread на Matrix room
|
||||
)
|
||||
await agent.connect()
|
||||
connected_agents[agent_id] = agent
|
||||
connected_agents[(agent_id, platform_chat_id)] = agent
|
||||
|
||||
async for event in agent.send_message(text):
|
||||
...
|
||||
|
|
@ -86,7 +99,7 @@ async def on_message(matrix_user_id: str, text: str):
|
|||
AgentApi(
|
||||
agent_id: str,
|
||||
base_url: str, # ws://host:port/agent_N/
|
||||
chat_id: int = 0, # default — один чат на агента
|
||||
chat_id: int = 0, # surfaces must supply per-room platform_chat_id
|
||||
on_disconnect: callable,
|
||||
)
|
||||
```
|
||||
|
|
@ -111,7 +124,7 @@ AgentApi(
|
|||
2. Matrix-бот читает файл: `/agents/{N}/output/report.pdf`
|
||||
3. Отправляет как Matrix file message пользователю
|
||||
|
||||
**Ключевое:** поверхность видит `/agents/` целиком через shared volume. Прямой HTTP-доступ к файлам не нужен.
|
||||
**Ключевое:** production handoff через `docker-compose.prod.yml` и internal E2E через `docker-compose.fullstack.yml` используют один и тот же `/agents` contract на стороне поверхности. Прямой HTTP-доступ к файлам не нужен.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -140,6 +153,6 @@ AgentApi(
|
|||
## Что НЕ решено / открытые вопросы
|
||||
|
||||
- Ветка `platform-agent_api #9-clientside-tool-call` убирает `attachments` и `MsgEventSendFile` — пока игнорируем, используем master. Уточнить у Азамата сроки мержа перед деплоем.
|
||||
- `chat_id` — при нашей модели C1/C2/C3 каждый чат должен иметь отдельный `chat_id`. Нужно решить: один `AgentApi` на агента (chat_id=0) или по инстансу на чат (chat_id=1/2/3). Пока берём `chat_id=0` (один контекст на пользователя).
|
||||
- `chat_id` — каждый Matrix chat room должен иметь собственный `platform_chat_id`. `!clear` должен ротировать `platform_chat_id` только для текущей комнаты, чтобы получить новый thread и чистый контекст без смены Matrix room.
|
||||
- Composio `AGENT_ID` в `.env` для каждого агента — уточнить у платформы значения.
|
||||
- Что происходит с историей при рестарте агента — `MemorySaver` не персистентный.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue