docs: full Tracker integration protocol for agent development
This commit is contained in:
parent
0525cea647
commit
01d90116f4
435
docs/TRACKER-PROTOCOL.md
Normal file
435
docs/TRACKER-PROTOCOL.md
Normal 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.
|
||||||
Loading…
Reference in New Issue
Block a user