# 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 ` (тот же токен агента). **Примечание**: 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.