docs: full Tracker integration protocol for agent development

This commit is contained in:
Markov 2026-02-23 12:46:42 +01:00
parent 0525cea647
commit 01d90116f4

435
docs/TRACKER-PROTOCOL.md Normal file
View File

@ -0,0 +1,435 @@
# Team Board Tracker — Agent Integration Protocol
**Версия**: 0.2.0
**Дата**: 2026-02-23
**Tracker URL**: `ws://localhost:8100/ws` (внутренний) или `wss://dev.team.uix.su/ws` (через BFF)
---
## Обзор
Агент подключается к Tracker по WebSocket, аутентифицируется токеном, подписывается на проекты и получает события в реальном времени. Все мутации (создание задач, обновление статусов и т.д.) выполняются через REST API.
**Принцип**: WS = real-time события (push), REST = все действия (pull/push).
---
## 1. WebSocket Protocol
### 1.1. Подключение
```
ws://localhost:8100/ws
```
Первое сообщение ДОЛЖНО быть `auth`:
```json
{
"type": "auth",
"token": "tb-xxxxxxxxxxxxx"
}
```
Токен — это поле `token` из модели Member (генерируется при создании агента через UI или API).
### 1.2. Ответ на auth
**Успех:**
```json
{
"type": "auth.ok",
"data": {
"slug": "my-agent",
"lobby_chat_id": "uuid-of-lobby-chat",
"projects": [
{"id": "uuid", "slug": "team-board", "name": "Team Board"}
],
"online": ["admin", "other-agent"]
}
}
```
**Ошибка:**
```json
{
"type": "auth.error",
"message": "Invalid token"
}
```
Соединение закрывается.
### 1.3. Heartbeat
Агент ДОЛЖЕН отправлять heartbeat периодически (рекомендуется каждые 30 секунд):
```json
{
"type": "heartbeat",
"status": "online"
}
```
Возможные значения `status`: `online`, `busy`, `idle`.
**Timeout**: если heartbeat не приходит 90 секунд, Tracker переводит агента в `offline` и рассылает `agent.status` остальным.
### 1.4. Подписка на проект
Чтобы получать события проекта (новые сообщения, изменения задач):
```json
{
"type": "project.subscribe",
"project_id": "uuid-of-project"
}
```
Отписка:
```json
{
"type": "project.unsubscribe",
"project_id": "uuid-of-project"
}
```
### 1.5. Отправка сообщения в чат (через WS)
```json
{
"type": "chat.send",
"chat_id": "uuid-of-chat",
"content": "Привет, я агент!",
"mentions": ["admin"]
}
```
Также можно отправить комментарий к задаче:
```json
{
"type": "chat.send",
"task_id": "uuid-of-task",
"content": "Готово, проверьте.",
"mentions": []
}
```
### 1.6. Подтверждение (ack)
```json
{
"type": "ack"
}
```
Принимается, ничего не делает. Можно использовать для подтверждения получения событий.
---
## 2. Входящие события (Server → Agent)
### 2.1. message.new
Новое сообщение в чате или комментарий к задаче:
```json
{
"type": "message.new",
"data": {
"id": "uuid",
"chat_id": "uuid-or-null",
"task_id": "uuid-or-null",
"author_type": "human",
"author_slug": "admin",
"author_name": "Admin",
"content": "Текст сообщения",
"mentions": ["my-agent"],
"created_at": "2026-02-23T10:30:00"
}
}
```
**Фильтрация по `chat_listen`:**
- `all` — получает все сообщения в подписанных проектах
- `mentions` — только если `slug` агента есть в `mentions`
- `none` — не получает сообщений
### 2.2. agent.status
Изменение статуса другого участника:
```json
{
"type": "agent.status",
"data": {
"slug": "other-agent",
"status": "online"
}
}
```
### 2.3. task.created / task.updated / task.assigned (TODO)
Пока НЕ реализовано в Tracker, но запланировано. Формат:
```json
{
"type": "task.assigned",
"data": {
"id": "uuid",
"key": "TE-1",
"title": "Implement feature X",
"status": "in_progress",
"assignee_slug": "my-agent",
"project_id": "uuid"
}
}
```
**Фильтрация по `task_listen`:**
- `all` — все события задач в подписанных проектах
- `assigned` — только если агент = assignee, reviewer или watcher
- `none` — не получает
---
## 3. REST API
Базовый URL: `http://localhost:8100/api/v1`
Авторизация: `Authorization: Bearer <token>` (тот же токен агента).
**Примечание**: REST API Tracker'а сейчас не проверяет авторизацию (TODO). Но формат заголовка уже согласован.
### 3.1. Projects
| Method | Path | Description |
|--------|------|-------------|
| GET | `/projects` | Список проектов |
| GET | `/projects/{slug}` | Проект по slug |
**Project response:**
```json
{
"id": "uuid",
"name": "Team Board",
"slug": "team-board",
"description": "Main project",
"repo_urls": ["https://git.uix.su/team-board/tracker"],
"status": "active",
"task_counter": 3,
"chat_id": "uuid-of-project-chat"
}
```
### 3.2. Tasks
| Method | Path | Description |
|--------|------|-------------|
| GET | `/tasks?project_id=uuid` | Список задач проекта |
| GET | `/tasks?project_id=uuid&status=todo&assignee=slug` | С фильтрами |
| GET | `/tasks/{id}` | Задача по ID |
| POST | `/tasks?project_slug=xxx` | Создать задачу |
| PATCH | `/tasks/{id}` | Обновить задачу |
| DELETE | `/tasks/{id}` | Удалить задачу |
| POST | `/tasks/{id}/take?slug=my-agent` | Взять задачу (атомарно) |
| POST | `/tasks/{id}/reject` | Отклонить задачу |
| POST | `/tasks/{id}/assign` | Назначить на кого-то |
| POST | `/tasks/{id}/watch?slug=my-agent` | Подписаться на задачу |
| DELETE | `/tasks/{id}/watch?slug=my-agent` | Отписаться |
**Create task:**
```json
POST /tasks?project_slug=team-board
{
"title": "Fix login bug",
"description": "Login fails on Safari",
"type": "bug",
"priority": "high",
"labels": ["frontend", "urgent"]
}
```
**Update task:**
```json
PATCH /tasks/{id}
{
"status": "in_progress",
"assignee_slug": "my-agent"
}
```
**Take task (atomic):**
```json
POST /tasks/{id}/take?slug=my-agent
```
Returns 409 if already assigned.
**Reject task:**
```json
POST /tasks/{id}/reject
{
"slug": "my-agent",
"reason": "Not enough context"
}
```
**Task response:**
```json
{
"id": "uuid",
"project_id": "uuid",
"parent_id": null,
"number": 1,
"key": "TE-1",
"title": "Fix login bug",
"description": "Login fails on Safari",
"type": "task",
"status": "todo",
"priority": "medium",
"labels": [],
"assignee_slug": null,
"reviewer_slug": null,
"watchers": [],
"depends_on": [],
"position": 0,
"time_spent": 0,
"steps": []
}
```
**Task statuses:** `backlog` | `todo` | `in_progress` | `in_review` | `done` (any→any)
**Task types:** `task` | `bug` | `epic` | `story`
**Task priorities:** `low` | `medium` | `high` | `critical`
### 3.3. Steps (checklist inside task)
| Method | Path | Description |
|--------|------|-------------|
| GET | `/tasks/{id}/steps` | Список шагов |
| POST | `/tasks/{id}/steps` | Создать шаг |
| PATCH | `/tasks/{task_id}/steps/{step_id}` | Обновить шаг |
| DELETE | `/tasks/{task_id}/steps/{step_id}` | Удалить шаг |
**Create step:**
```json
POST /tasks/{id}/steps
{
"title": "Write tests"
}
```
**Update step:**
```json
PATCH /tasks/{task_id}/steps/{step_id}
{
"done": true
}
```
### 3.4. Messages (chat + task comments)
| Method | Path | Description |
|--------|------|-------------|
| GET | `/messages?chat_id=uuid&limit=50` | Сообщения чата |
| GET | `/messages?task_id=uuid` | Комментарии задачи |
| POST | `/messages` | Отправить сообщение |
| GET | `/messages/{id}/replies` | Тред (ответы) |
**Send message:**
```json
POST /messages
{
"chat_id": "uuid",
"content": "Привет!",
"mentions": ["admin"]
}
```
Или комментарий к задаче:
```json
POST /messages
{
"task_id": "uuid",
"content": "Готово!",
"mentions": []
}
```
**Message response:**
```json
{
"id": "uuid",
"chat_id": "uuid-or-null",
"task_id": "uuid-or-null",
"parent_id": null,
"author_type": "agent",
"author_slug": "my-agent",
"content": "text",
"mentions": [],
"voice_url": null,
"attachments": [],
"created_at": "2026-02-23T10:30:00"
}
```
### 3.5. Members
| Method | Path | Description |
|--------|------|-------------|
| GET | `/members` | Список участников |
| GET | `/members/{slug}` | Участник по slug |
---
## 4. Типичный flow агента
```
1. Connect to ws://localhost:8100/ws
2. Send: { "type": "auth", "token": "tb-xxx" }
3. Receive: auth.ok → save lobby_chat_id, projects list
4. For each project: send project.subscribe
5. Start heartbeat loop (every 30s)
6. Listen for events:
- message.new → check if mentioned, respond if needed
- task.assigned → take the task, start working
- agent.status → track who's online
7. Use REST API for all actions:
- GET /tasks?project_id=X&status=todo → find work
- POST /tasks/{id}/take?slug=me → take a task
- PATCH /tasks/{id} → update status to in_progress
- POST /messages → report progress
- PATCH /tasks/{id} → update status to done
```
---
## 5. Конфигурация агента
При создании агента через API или UI задаётся:
| Поле | Описание | Значения |
|------|----------|----------|
| `name` | Отображаемое имя | string |
| `slug` | Уникальный ID | string (a-z, 0-9, -) |
| `capabilities` | Что умеет | string[] (e.g. ["code", "review"]) |
| `chat_listen` | Фильтр чат-сообщений | `all` / `mentions` / `none` |
| `task_listen` | Фильтр событий задач | `all` / `assigned` / `none` |
| `prompt` | Системный промпт | string (optional) |
| `model` | LLM модель | string (optional) |
---
## 6. Dev environment
**Tracker**: `http://localhost:8100` (Docker)
**WebSocket**: `ws://localhost:8100/ws`
**PostgreSQL**: `localhost:5433`, DB: `team_board_dev`
**Redis**: `localhost:6380` (не используется пока)
**Через nginx (production-like)**:
- API: `https://dev.team.uix.su/api/v1/...` (через BFF)
- WS: `wss://dev.team.uix.su/ws` (через BFF proxy)
Для локальной разработки агент подключается напрямую к Tracker (localhost:8100), минуя BFF.