Full protocol spec: WS + HTTP callback, agent model, roles, permissions, events, Telegram Bridge

This commit is contained in:
Markov 2026-02-20 20:34:58 +01:00
parent ffe8f68806
commit 2edcdd8aed

View File

@ -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` ### 2. HTTP Callback (альтернативный)
- `client_id`: уникальный идентификатор клиента (slug агента, имя bridge и т.д.) Агент регистрируется через 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 ```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 ### auth
Аутентификация (для агентов/bridge).
```json ```json
{"event": "auth", "token": "agent-xxx"} {
"event": "auth",
"token": "agent-xxx",
"name": "Кодер",
"capabilities": ["code"]
}
``` ```
Ответ: `auth.ok` с `{"init": {}}`
### chat.subscribe ### chat.subscribe
Подписка на чат-комнату.
```json ```json
{"event": "chat.subscribe", "chat_id": "uuid"} {"event": "chat.subscribe", "chat_id": "uuid"}
``` ```
Ответ: `chat.subscribed`
### chat.unsubscribe
Отписка от чата.
```json
{"event": "chat.unsubscribe", "chat_id": "uuid"}
```
### chat.send ### chat.send
Отправка сообщения в чат.
```json ```json
{ {
"event": "chat.send", "event": "chat.send",
"chat_id": "uuid", "chat_id": "uuid",
"content": "текст сообщения", "content": "текст сообщения",
"sender_type": "human|agent|system|bridge", "sender_type": "agent|bridge|human",
"sender_id": "optional-uuid", "sender_name": "Кодер",
"sender_name": "Имя отправителя" "mentions": ["reviewer"] // @slug упоминания
} }
``` ```
Сообщение сохраняется в БД и broadcast'ится всем подписчикам чата.
### agent.heartbeat ### agent.heartbeat
Пинг от агента (статус).
```json ```json
{"event": "agent.heartbeat", "status": "idle|busy"} {"event": "agent.heartbeat", "status": "idle|busy"}
``` ```
Ответ: `agent.heartbeat.ack`
## События: Сервер → Клиент ### task.take
Агент берёт задачу в работу.
### auth.ok
```json ```json
{"event": "auth.ok", "init": {}} {"event": "task.take", "task_id": "uuid"}
``` ```
### chat.subscribed ### task.complete
Агент завершил задачу.
```json ```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 ### chat.message
Новое сообщение в чате (broadcast всем подписчикам).
```json ```json
{ {
"event": "chat.message", "event": "chat.message",
@ -82,43 +194,99 @@ ws://localhost:8100/ws?client_type={type}&client_id={id}
"sender_type": "human|agent|system|bridge", "sender_type": "human|agent|system|bridge",
"sender_id": "uuid|null", "sender_id": "uuid|null",
"sender_name": "Имя", "sender_name": "Имя",
"sender_slug": "slug|null",
"content": "текст", "content": "текст",
"mentions": ["coder"],
"created_at": "2026-02-20T12:00:00Z" "created_at": "2026-02-20T12:00:00Z"
} }
``` ```
### error ### task.created
```json ```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/lobby — lobby чат
GET /api/v1/chats/{id}/messages — история сообщений GET /api/v1/chats/{id}/messages?limit=20 — история
POST /api/v1/chats/{id}/messages — отправить (без WS) POST /api/v1/chats/{id}/messages — отправить
``` ```
## Telegram Bridge (планируется) ## Telegram Bridge
Bridge-клиент подключается как `client_type=bridge`, подписывается на нужные чаты и: Bridge-агент с `connection_type=bridge`:
1. **Tracker → Telegram**: получает `chat.message`, форматирует и отправляет в Telegram группу 1. Подключается по WebSocket как `client_type=bridge`
2. **Telegram → Tracker**: получает сообщения из Telegram, отправляет `chat.send` с `sender_type=bridge` 2. Подписывается на нужные чаты
3. **Системные события**: статус задачи, новая задача и т.д. 3. **Tracker → Telegram**: `chat.message` → форматирует и отправляет в группу
4. **Теги агентов**: парсит `@slug` в сообщениях из Telegram 4. **Telegram → Tracker**: сообщение из группы → `chat.send` с `sender_type=bridge`
5. **Системные события**: `task.created`, `task.updated` → уведомления в группу
6. **Упоминания**: парсит `@slug` из Telegram → `mentions` в `chat.send`
### Формат сообщений в Telegram ### Формат в Telegram
``` ```
[Имя Агента] Текст сообщения 👤 Eugene: Сделай рефактор auth модуля
``` 🤖 Кодер: Принял, начинаю работу
или ⚙️ Задача #42 → in_progress (Кодер)
```
🤖 Кодер: Задача выполнена, коммит abc123
``` ```
## Инфраструктура
- 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`