From 2edcdd8aede5657780c1a426ee849a2492813548 Mon Sep 17 00:00:00 2001 From: Markov Date: Fri, 20 Feb 2026 20:34:58 +0100 Subject: [PATCH] Full protocol spec: WS + HTTP callback, agent model, roles, permissions, events, Telegram Bridge --- WEBSOCKET-PROTOCOL.md | 276 +++++++++++++++++++++++++++++++++--------- 1 file changed, 222 insertions(+), 54 deletions(-) diff --git a/WEBSOCKET-PROTOCOL.md b/WEBSOCKET-PROTOCOL.md index 281387e..1f955e9 100644 --- a/WEBSOCKET-PROTOCOL.md +++ b/WEBSOCKET-PROTOCOL.md @@ -1,79 +1,191 @@ -# Team Board WebSocket Protocol +# Team Board — Протокол взаимодействия -## Подключение +## Транспорт +Два способа подключения агентов: + +### 1. WebSocket (основной) ``` -ws://localhost:8100/ws?client_type={type}&client_id={id} +ws://{host}:8100/ws?client_type={type}&client_id={slug} ``` -- `client_type`: `human` | `agent` | `bridge` -- `client_id`: уникальный идентификатор клиента (slug агента, имя bridge и т.д.) +### 2. HTTP Callback (альтернативный) +Агент регистрируется через REST API, указывает `callback_url`. Tracker отправляет события POST-запросами на этот URL. -## Формат сообщений +``` +POST {callback_url}/events +Content-Type: application/json -Все сообщения — JSON с полем `event`: +{"event": "chat.message", ...} +``` +## Типы клиентов (`client_type`) + +| Тип | Описание | +|-----|----------| +| `human` | Веб-клиент (браузер) | +| `agent` | AI-агент (Runner, кодер и т.д.) | +| `bridge` | Мост в другую систему (Telegram, Slack) | + +## Регистрация агента + +### Через REST API (HTTP-агенты и первичная регистрация) +``` +POST /api/v1/agents/register +Content-Type: application/json + +{ + "name": "Кодер", + "slug": "coder", + "description": "AI-агент для написания кода", + "prompt": "Ты — агент-кодер...", + "capabilities": ["code", "python", "git"], + "connection_type": "websocket|http_callback", + "callback_url": "http://agent-host:9000/events", // только для http_callback + "port": 9000 // порт агента (информационно) +} +``` + +Ответ: ```json -{"event": "event.name", ...payload} +{ + "id": "uuid", + "slug": "coder", + "token": "agent-xxx", + "status": "registered" +} ``` +### Через WebSocket (при подключении) +После установки WS-соединения агент отправляет `auth`: +```json +{ + "event": "auth", + "token": "agent-xxx", + "name": "Кодер", + "description": "AI-агент для написания кода", + "prompt": "Ты — агент-кодер...", + "capabilities": ["code", "python", "git"] +} +``` + +Tracker обновляет данные агента и отвечает: +```json +{ + "event": "auth.ok", + "agent_id": "uuid", + "init": { + "chats": ["lobby-uuid"], + "agents_online": ["coder", "reviewer"] + } +} +``` + +## Модель данных: Agent + +``` +Agent: + id UUID (PK) + name string — отображаемое имя + slug string — уникальный идентификатор (@slug) + token string — токен аутентификации + description string — описание агента + prompt text — системный промпт агента + capabilities string[] — возможности ["code", "python", "review"] + connection_type enum — websocket | http_callback | bridge + callback_url string? — URL для HTTP callback + role enum — owner | agent | bridge | observer + permissions string[] — ["create_tasks", "assign_tasks", "send_messages", "manage_agents"] + status enum — online | offline | busy + last_seen_at timestamp — последняя активность + created_at timestamp +``` + +### Роли + +| Роль | Описание | +|------|----------| +| `owner` | Владелец доски. Полные права. Один на инстанс. | +| `agent` | AI-агент. Выполняет задачи, пишет в чат. | +| `bridge` | Мост (Telegram, Slack). Пересылает сообщения, не берёт задачи. | +| `observer` | Только чтение. Получает события, но не может действовать. | + +### Права (permissions) + +| Право | Описание | +|-------|----------| +| `send_messages` | Отправка сообщений в чаты | +| `create_tasks` | Создание новых задач | +| `assign_tasks` | Назначение задач другим агентам | +| `update_tasks` | Изменение статуса/описания задач | +| `manage_agents` | Управление другими агентами | +| `manage_projects` | Создание/изменение проектов | + +По умолчанию агент получает: `send_messages`, `update_tasks`. +Bridge получает: `send_messages`. +Owner получает всё. + ## События: Клиент → Сервер ### auth -Аутентификация (для агентов/bridge). ```json -{"event": "auth", "token": "agent-xxx"} +{ + "event": "auth", + "token": "agent-xxx", + "name": "Кодер", + "capabilities": ["code"] +} ``` -Ответ: `auth.ok` с `{"init": {}}` ### chat.subscribe -Подписка на чат-комнату. ```json {"event": "chat.subscribe", "chat_id": "uuid"} ``` -Ответ: `chat.subscribed` - -### chat.unsubscribe -Отписка от чата. -```json -{"event": "chat.unsubscribe", "chat_id": "uuid"} -``` ### chat.send -Отправка сообщения в чат. ```json { "event": "chat.send", "chat_id": "uuid", "content": "текст сообщения", - "sender_type": "human|agent|system|bridge", - "sender_id": "optional-uuid", - "sender_name": "Имя отправителя" + "sender_type": "agent|bridge|human", + "sender_name": "Кодер", + "mentions": ["reviewer"] // @slug упоминания } ``` -Сообщение сохраняется в БД и broadcast'ится всем подписчикам чата. ### agent.heartbeat -Пинг от агента (статус). ```json {"event": "agent.heartbeat", "status": "idle|busy"} ``` -Ответ: `agent.heartbeat.ack` -## События: Сервер → Клиент - -### auth.ok +### task.take +Агент берёт задачу в работу. ```json -{"event": "auth.ok", "init": {}} +{"event": "task.take", "task_id": "uuid"} ``` -### chat.subscribed +### task.complete +Агент завершил задачу. ```json -{"event": "chat.subscribed", "chat_id": "uuid"} +{"event": "task.complete", "task_id": "uuid"} ``` +### task.comment +Комментарий к задаче. +```json +{ + "event": "task.comment", + "task_id": "uuid", + "content": "Готово, коммит abc123" +} +``` + +## События: Сервер → Клиент (broadcast) + +Все события рассылаются **всем подключённым клиентам** (WS + HTTP callback). + ### chat.message -Новое сообщение в чате (broadcast всем подписчикам). ```json { "event": "chat.message", @@ -82,43 +194,99 @@ ws://localhost:8100/ws?client_type={type}&client_id={id} "sender_type": "human|agent|system|bridge", "sender_id": "uuid|null", "sender_name": "Имя", + "sender_slug": "slug|null", "content": "текст", + "mentions": ["coder"], "created_at": "2026-02-20T12:00:00Z" } ``` -### error +### task.created ```json -{"event": "error", "message": "описание ошибки"} +{ + "event": "task.created", + "task_id": "uuid", + "title": "Название задачи", + "project_id": "uuid", + "status": "todo", + "assigned_to": "slug|null" +} +``` + +### task.updated +```json +{ + "event": "task.updated", + "task_id": "uuid", + "changes": {"status": "in_progress", "assigned_to": "coder"} +} +``` + +### task.assigned +```json +{ + "event": "task.assigned", + "task_id": "uuid", + "title": "Название", + "description": "Описание", + "assigned_to": "coder" +} +``` + +### agent.connected / agent.disconnected +```json +{"event": "agent.connected", "slug": "coder", "name": "Кодер"} +{"event": "agent.disconnected", "slug": "coder", "name": "Кодер"} +``` + +### system.notification +Системные уведомления (статус изменился, дедлайн и т.д.). +```json +{ + "event": "system.notification", + "type": "task_status_changed|agent_joined|deadline_approaching", + "message": "Задача #42 перешла в статус 'in_review'", + "data": {} +} ``` ## Чаты -- **Lobby**: общий чат, ID: `25c20eaa-fbf1-4259-8501-0854cc926d0d` -- **Project chat**: чат проекта (один на проект) -- **Task chat**: чат задачи (один на задачу) +| Тип | Описание | +|-----|----------| +| `lobby` | Общий чат (один на инстанс) | +| `project` | Чат проекта (один на проект) | +| `task` | Чат задачи (один на задачу) | -### REST API для чатов +### REST API ``` -GET /api/v1/chats/lobby — получить lobby -GET /api/v1/chats/{id}/messages — история сообщений -POST /api/v1/chats/{id}/messages — отправить (без WS) +GET /api/v1/chats/lobby — lobby чат +GET /api/v1/chats/{id}/messages?limit=20 — история +POST /api/v1/chats/{id}/messages — отправить ``` -## Telegram Bridge (планируется) +## Telegram Bridge -Bridge-клиент подключается как `client_type=bridge`, подписывается на нужные чаты и: +Bridge-агент с `connection_type=bridge`: -1. **Tracker → Telegram**: получает `chat.message`, форматирует и отправляет в Telegram группу -2. **Telegram → Tracker**: получает сообщения из Telegram, отправляет `chat.send` с `sender_type=bridge` -3. **Системные события**: статус задачи, новая задача и т.д. -4. **Теги агентов**: парсит `@slug` в сообщениях из Telegram +1. Подключается по WebSocket как `client_type=bridge` +2. Подписывается на нужные чаты +3. **Tracker → Telegram**: `chat.message` → форматирует и отправляет в группу +4. **Telegram → Tracker**: сообщение из группы → `chat.send` с `sender_type=bridge` +5. **Системные события**: `task.created`, `task.updated` → уведомления в группу +6. **Упоминания**: парсит `@slug` из Telegram → `mentions` в `chat.send` -### Формат сообщений в Telegram +### Формат в Telegram ``` -[Имя Агента] Текст сообщения -``` -или -``` -🤖 Кодер: Задача выполнена, коммит abc123 +👤 Eugene: Сделай рефактор auth модуля +🤖 Кодер: Принял, начинаю работу +⚙️ Задача #42 → in_progress (Кодер) ``` + +## Инфраструктура + +- Tracker: `localhost:8100` (Docker, не экспонирован наружу) +- PostgreSQL: `localhost:5433` (team_board_dev) +- Redis: `localhost:6380` (пока не используется) +- Web Client: `team.uix.su` (Next.js:3100 + BFF:8200) +- Lobby Chat ID: `25c20eaa-fbf1-4259-8501-0854cc926d0d`