docs/archive/AGENT-CONNECTION-RESEARCH.md

1119 lines
46 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Архитектура подключения AI-агентов к Team Board Tracker
> Исследовательский документ | Февраль 2026
---
## Содержание
1. [Обзор текущей архитектуры](#1-обзор-текущей-архитектуры)
2. [Долгосрочные сессии агентов](#2-долгосрочные-сессии-агентов)
3. [Работа агентов с задачами](#3-работа-агентов-с-задачами)
4. [Чат и коммуникация](#4-чат-и-коммуникация)
5. [Работа с кодом через Git](#5-работа-с-кодом-через-git)
6. [Паттерны из индустрии](#6-паттерны-из-индустрии)
7. [Рекомендуемая архитектура](#7-рекомендуемая-архитектура)
---
## 1. Обзор текущей архитектуры
```
┌─────────────┐ WebSocket :8100 ┌─────────────────┐
│ Agent 1 │◄──────────────────────►│ │
├─────────────┤ │ Tracker │
│ Agent 2 │◄──────────────────────►│ (FastAPI + │
├─────────────┤ │ PostgreSQL + │
│ Agent N │◄──────────────────────►│ Redis) │
└─────────────┘ │ │
└────────┬────────┘
┌─────────────┐ HTTP/WS │
│ Web Client │◄────────────────────────┘
│ (Next.js) │ via BFF
└─────────────┘
```
### Текущий протокол (baseline)
| Событие | Направление | Описание |
|---------|-------------|----------|
| `auth` | Agent → Tracker | Аутентификация по токену |
| `auth.ok` | Tracker → Agent | Подтверждение + init context |
| `agent.heartbeat` | Agent → Tracker | Keep-alive |
| `agent.heartbeat.ack` | Tracker → Agent | Подтверждение |
| `chat.send` | Agent → Tracker | Отправка сообщения |
| `chat.message` | Tracker → Agent | Входящее сообщение |
| `task.assigned` | Tracker → Agent | Назначение задачи |
| `task.take` | Agent → Tracker | Взятие задачи |
| `task.complete` | Agent → Tracker | Завершение задачи |
| `task.comment` | Agent → Tracker | Комментарий к задаче |
### Модель агента в БД
```sql
CREATE TABLE agents (
id UUID PRIMARY KEY,
name VARCHAR(100),
slug VARCHAR(50) UNIQUE,
token VARCHAR(256),
capabilities TEXT[], -- ['code', 'review', 'test', 'deploy']
subscription_mode VARCHAR(20), -- all | mentions | assigned
max_concurrent INT DEFAULT 3,
timeout_seconds INT DEFAULT 3600,
status VARCHAR(20) -- online | offline | busy
);
```
**Проблемы текущей архитектуры:**
- Нет персистентных сессий — при реконнекте контекст теряется
- Нет механизма зависимостей между задачами
- Нет конкурентного контроля при взятии задач
- Отсутствует контекстное окно / история для агента
- Нет интеграции с Git/CI
---
## 2. Долгосрочные сессии агентов
### 2.1 Проблема
AI-агент работает над задачей часами или днями. WebSocket соединение может оборваться. LLM имеет ограниченное контекстное окно. Нужен механизм, который:
- Сохраняет состояние сессии между реконнектами
- Управляет контекстным окном (compaction)
- Позволяет агенту «вспомнить» где он остановился
### 2.2 Модель сессии
```sql
CREATE TABLE agent_sessions (
id UUID PRIMARY KEY,
agent_id UUID REFERENCES agents(id),
task_id UUID REFERENCES tasks(id) NULL, -- привязка к задаче (опционально)
status VARCHAR(20), -- active | suspended | completed | expired
context_summary TEXT, -- compacted summary текущего контекста
created_at TIMESTAMPTZ,
updated_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ,
metadata JSONB -- произвольные данные сессии
);
CREATE TABLE session_messages (
id UUID PRIMARY KEY,
session_id UUID REFERENCES agent_sessions(id),
role VARCHAR(20), -- agent | tracker | user | system
content TEXT,
created_at TIMESTAMPTZ,
seq BIGINT -- порядковый номер для восстановления
);
```
### 2.3 Протокол управления сессиями
**Создание/возобновление сессии при подключении:**
```json
// Agent → Tracker
{
"type": "session.resume",
"session_id": "uuid-of-previous-session", // null для новой
"last_seq": 1842 // последнее известное сообщение
}
// Tracker → Agent
{
"type": "session.restored",
"session_id": "abc-123",
"context_summary": "Работаю над задачей PROJ-42: рефакторинг auth модуля. Создал ветку feat/proj-42, изменил 3 файла...",
"missed_messages": [...], // сообщения после last_seq
"active_tasks": [...]
}
```
### 2.4 Compaction (сжатие контекста)
Аналогия с OpenClaw persistent sessions: когда история сессии превышает порог (например, 50K токенов), Tracker выполняет compaction:
```
┌──────────────────────────────────────────────┐
│ Session History │
│ │
│ [msg1][msg2]...[msg200] ← старые сообщения│
│ ↓ compaction │
│ [SUMMARY: 500 tokens] │
│ [msg195][msg196]...[msg210] ← свежие │
└──────────────────────────────────────────────┘
```
**Два подхода к compaction:**
| Подход | Где выполняется | Плюсы | Минусы |
|--------|----------------|-------|--------|
| Server-side | Tracker вызывает LLM | Единообразие, контроль | Нагрузка на сервер, нужен LLM API |
| Agent-side | Агент присылает summary | Агент лучше знает контекст | Доверие к агенту |
**Рекомендация:** гибридный подход — агент периодически отправляет `session.checkpoint` со своим пониманием контекста, Tracker сохраняет:
```json
// Agent → Tracker
{
"type": "session.checkpoint",
"session_id": "abc-123",
"summary": "Рефакторинг auth: создал ветку, изменил models.py и routes.py, осталось написать тесты",
"working_state": {
"branch": "feat/proj-42",
"modified_files": ["src/auth/models.py", "src/auth/routes.py"],
"next_steps": ["write tests", "update docs"]
}
}
```
### 2.5 Reconnect и State Recovery
```
Agent disconnect (сеть упала)
Tracker: помечает agent.status = "away" (не offline сразу)
grace period = 60s
▼ (agent reconnects within grace)
Agent → auth + session.resume(session_id, last_seq)
Tracker → session.restored (missed messages + context_summary)
Agent продолжает работу
```
**Если grace period истёк:**
- Статус → offline
- Незавершённые задачи → возвращаются в очередь (или ждут, зависит от политики)
- Сессия → suspended (можно возобновить позже)
---
## 3. Работа агентов с задачами
### 3.1 Жизненный цикл задачи
```
┌──────────┐
│ BACKLOG │
└────┬─────┘
│ task.assigned / task.available
┌──────────┐
┌────────│ TODO │
│ └────┬─────┘
│ │ task.take
│ ▼
│ ┌──────────────┐
│ │ IN_PROGRESS │
│ └──┬───────┬───┘
│ │ │ task.blocked
│ │ ▼
│ │ ┌─────────┐
│ │ │ BLOCKED │──► (dependency resolved) → IN_PROGRESS
│ │ └─────────┘
│ │
│ │ task.review_request
│ ▼
│ ┌──────────┐
│ │ IN_REVIEW│
│ └────┬─────┘
│ │ task.complete / task.reject
│ ▼
│ ┌──────────┐
└───────►│ DONE │
└──────────┘
```
### 3.2 Расширенный протокол задач
**Взятие задачи (с атомарной блокировкой):**
```json
// Agent → Tracker
{
"type": "task.take",
"task_id": "proj-42",
"estimated_minutes": 120
}
// Tracker → Agent (успех)
{
"type": "task.take.ok",
"task_id": "proj-42",
"task": {
"id": "proj-42",
"title": "Рефакторинг auth модуля",
"description": "...",
"dependencies": ["proj-40", "proj-41"],
"dependencies_status": "all_resolved",
"attachments": [...],
"comments": [...],
"git_branch": "feat/proj-42" // предложенная ветка
},
"session_id": "new-session-uuid" // автоматически создаётся сессия
}
// Tracker → Agent (отказ — уже взята)
{
"type": "task.take.conflict",
"task_id": "proj-42",
"taken_by": "agent-coder-1",
"taken_at": "2026-02-15T10:30:00Z"
}
```
**Конкурентность — реализация в Tracker:**
```python
# Атомарная операция через PostgreSQL advisory lock
async def take_task(agent_id: str, task_id: str) -> bool:
async with db.transaction():
# Advisory lock по task_id
await db.execute(
"SELECT pg_advisory_xact_lock(hashtext($1))", task_id
)
task = await db.fetchrow(
"SELECT * FROM tasks WHERE id = $1 AND status = 'todo' "
"AND assigned_to IS NULL FOR UPDATE", task_id
)
if not task:
return False # уже взята или не в нужном статусе
await db.execute(
"UPDATE tasks SET assigned_to = $1, status = 'in_progress' "
"WHERE id = $2", agent_id, task_id
)
return True
```
**Обновление прогресса:**
```json
// Agent → Tracker
{
"type": "task.progress",
"task_id": "proj-42",
"progress_pct": 60,
"status_text": "Написал модели и роуты, пишу тесты",
"artifacts": [
{"type": "commit", "ref": "abc123", "message": "refactor auth models"}
]
}
```
**Перемещение по канбану:**
```json
// Agent → Tracker
{
"type": "task.move",
"task_id": "proj-42",
"to_status": "in_review",
"comment": "Готово к ревью. PR: https://git.example.com/repo/pulls/15"
}
```
### 3.3 Зависимости задач
```sql
CREATE TABLE task_dependencies (
task_id UUID REFERENCES tasks(id),
depends_on UUID REFERENCES tasks(id),
PRIMARY KEY (task_id, depends_on)
);
```
**Уведомление о разблокировке:**
```json
// Tracker → Agent (когда все зависимости resolved)
{
"type": "task.unblocked",
"task_id": "proj-42",
"resolved_dependencies": ["proj-40", "proj-41"],
"can_start": true
}
```
### 3.4 Очередь задач и автоназначение
```
┌──────────────┐ task.available ┌──────────┐
│ Task Queue │────────────────────────►│ Agent │
│ (Redis) │◄────────────────────────│ Pool │
│ │ task.take │ │
└──────────────┘ └──────────┘
Стратегии назначения:
1. PULL: агент сам берёт из очереди (task.available → task.take)
2. PUSH: Tracker назначает по capabilities (task.assigned)
3. HYBRID: Tracker предлагает, агент подтверждает (task.offer → task.accept/decline)
```
**Рекомендация:** HYBRID модель — Tracker предлагает задачу наиболее подходящему агенту (по capabilities, загрузке, специализации), но агент может отклонить:
```json
// Tracker → Agent
{
"type": "task.offer",
"task_id": "proj-42",
"reason": "matches capabilities: ['code', 'python']",
"deadline": "2026-02-16T12:00:00Z",
"offer_expires_in": 30 // секунд
}
// Agent → Tracker
{
"type": "task.accept",
"task_id": "proj-42"
}
// или
{
"type": "task.decline",
"task_id": "proj-42",
"reason": "at max concurrent capacity"
}
```
---
## 4. Чат и коммуникация
### 4.1 Модель чат-комнат
```
Rooms:
├── #lobby (глобальный)
├── #project-{slug} (по проекту)
│ ├── #project-{slug}-tasks (задачи проекта)
│ └── #project-{slug}-dev (разработка)
├── #task-{id} (привязан к задаче)
├── @agent-to-agent (прямые между агентами)
└── @agent-to-user (прямые с людьми)
```
### 4.2 Подписки
```json
// Agent → Tracker (при подключении или динамически)
{
"type": "chat.subscribe",
"rooms": ["#lobby", "#project-alpha"],
"mode": "mentions" // all | mentions | assigned
}
// Tracker → Agent (подтверждение)
{
"type": "chat.subscribed",
"rooms": ["#lobby", "#project-alpha"],
"unread_counts": {"#lobby": 5, "#project-alpha": 0}
}
```
### 4.3 Маршрутизация сообщений
Агент получает сообщение и должен решить: отвечать или нет, и куда.
```json
// Tracker → Agent
{
"type": "chat.message",
"room": "#project-alpha",
"from": {"id": "user-123", "name": "Алекс", "type": "human"},
"content": "@coder-agent можешь посмотреть баг в auth?",
"mentions": ["coder-agent"],
"reply_to": null,
"thread_id": "thread-456",
"context": {
"recent_messages": 3, // кол-во недавних сообщений в треде
"related_tasks": ["proj-42"]
}
}
```
**Логика принятия решения агентом:**
```
Получено сообщение
├─ Прямое упоминание (@agent)? → ОТВЕЧАТЬ (в тот же room/thread)
├─ subscription_mode == "all" и room подписан? → АНАЛИЗИРОВАТЬ контент
│ └─ Могу помочь? → ОТВЕЧАТЬ
│ └─ Не моя тема → МОЛЧАТЬ
├─ Связано с моей активной задачей? → ОТВЕЧАТЬ
└─ Иначе → МОЛЧАТЬ
```
### 4.4 Межагентная коммуникация
Агенты общаются через те же чат-комнаты, но с дополнительным протоколом для структурированных запросов:
```json
// Agent A → Tracker
{
"type": "agent.request",
"target_agent": "reviewer-agent",
"request_type": "code_review",
"payload": {
"pr_url": "https://git.example.com/repo/pulls/15",
"description": "Рефакторинг auth модуля, нужен ревью"
},
"timeout": 300,
"callback_type": "agent.response"
}
// Tracker → Agent B (reviewer)
{
"type": "agent.request",
"from_agent": "coder-agent",
"request_id": "req-789",
"request_type": "code_review",
"payload": { ... }
}
// Agent B → Tracker
{
"type": "agent.response",
"request_id": "req-789",
"status": "completed",
"result": {
"approved": false,
"comments": ["Line 42: потенциальный SQL injection", "..."]
}
}
```
---
## 5. Работа с кодом через Git
### 5.1 Архитектура Git-интеграции
```
┌─────────┐ clone/push ┌──────────┐ webhooks ┌─────────┐
│ Agent │◄────────────────►│ Gitea │──────────────►│ Tracker │
│ sandbox │ │ Server │ │ │
│ /work/ │ │ │◄──────────────│ │
└─────────┘ └──────────┘ API calls └─────────┘
```
### 5.2 Рабочее пространство агента
Каждый агент получает изолированное рабочее пространство:
```
/agent-workspaces/
├── coder-agent/
│ ├── repos/
│ │ ├── project-alpha/ ← клон репозитория
│ │ └── project-beta/
│ ├── .ssh/ ← deploy keys
│ └── .gitconfig
└── reviewer-agent/
└── repos/
└── project-alpha/ ← свой клон для ревью
```
### 5.3 Branch Strategy
```
main
├── develop
│ │
│ ├── feat/PROJ-42-auth-refactor ← создаёт coder-agent
│ │ └── (commits by agent)
│ │
│ ├── feat/PROJ-43-api-endpoints ← создаёт другой агент
│ │
│ └── fix/PROJ-44-login-bug
└── release/v1.2
```
**Правила:**
- Ветка = `{type}/{task-id}-{slug}` (type: feat/fix/refactor/docs)
- Один агент — одна ветка на задачу
- Merge только через PR после ревью
- Конфликты: агент пытается resolve, при неудаче — эскалация человеку
### 5.4 Git-протокол в WebSocket
```json
// Tracker → Agent (при назначении задачи с git-контекстом)
{
"type": "task.take.ok",
"task_id": "proj-42",
"task": { ... },
"git_context": {
"repo_url": "git@gitea.example.com:team/project-alpha.git",
"base_branch": "develop",
"suggested_branch": "feat/proj-42-auth-refactor",
"related_files": ["src/auth/models.py", "src/auth/routes.py"]
}
}
// Agent → Tracker (после создания PR)
{
"type": "git.pr.created",
"task_id": "proj-42",
"pr": {
"url": "https://gitea.example.com/team/project-alpha/pulls/15",
"number": 15,
"branch": "feat/proj-42-auth-refactor",
"base": "develop",
"title": "PROJ-42: Рефакторинг auth модуля",
"files_changed": 5,
"additions": 120,
"deletions": 45
}
}
```
### 5.5 Code Review Flow
```
coder-agent Tracker reviewer-agent
│ │ │
│── git.pr.created ─────────►│ │
│ │── task.offer (review) ────►│
│ │◄── task.accept ────────────│
│ │ │
│ │ (reviewer клонирует, │
│ │ читает diff, анализирует)│
│ │ │
│ │◄── git.review.complete ────│
│◄── git.review.result ──────│ {approved: false, │
│ (с комментариями) │ comments: [...]} │
│ │ │
│ (агент исправляет) │ │
│── git.pr.updated ─────────►│ │
│ │── (notify reviewer) ──────►│
│ │ │
│ │◄── git.review.complete ────│
│◄── git.review.result ──────│ {approved: true} │
│ │ │
│── task.move(in_review→done)│ │
```
### 5.6 Интеграция с Gitea
**Webhooks от Gitea → Tracker:**
| Событие | Действие Tracker |
|---------|-----------------|
| `push` | Обновить прогресс задачи, уведомить подписчиков |
| `pull_request.opened` | Создать задачу на ревью или назначить reviewer |
| `pull_request.reviewed` | Уведомить автора о результате |
| `pull_request.merged` | Переместить задачу в DONE |
| `issues.opened` | Создать задачу в Tracker |
**Tracker → Gitea API:**
```python
# Создание ветки
POST /api/v1/repos/{owner}/{repo}/branches
{"new_branch_name": "feat/proj-42", "old_branch_name": "develop"}
# Создание PR
POST /api/v1/repos/{owner}/{repo}/pulls
{"title": "PROJ-42: ...", "head": "feat/proj-42", "base": "develop"}
# Комментирование PR
POST /api/v1/repos/{owner}/{repo}/pulls/{index}/reviews
{"body": "...", "event": "REQUEST_CHANGES"}
```
---
## 6. Паттерны из индустрии
### 6.1 Сравнение систем
| Система | Архитектура | Сессии | Multi-agent | Git | Длинные задачи |
|---------|-------------|--------|-------------|-----|----------------|
| **Devin** | Монолит, VM-sandbox | Persistent, часы | Нет (single) | Да, полный цикл | VM не убивается |
| **SWE-Agent** | CLI + Docker | Per-task | Нет | Да, patch-based | Нет (одна попытка) |
| **OpenHands** | Docker sandbox + event stream | Event log replay | Нет | Да | Event sourcing |
| **AutoGPT** | Loop agent + plugins | Memory module | Ограниченно | Через плагины | Memory + file storage |
| **CrewAI** | Agent → Task → Tool | Per-crew-run | Да, role-based | Через tools | Delegation chain |
| **LangGraph** | State machine graph | Checkpointing | Да, graph nodes | Через tools | Persistent checkpoints |
| **Claude Code** | CLI + session | Session compaction | Нет | Полный git CLI | Persistent sessions |
| **Team Board** | WebSocket hub | **Нужно** | **Да** | **Нужно** | **Нужно** |
### 6.2 Ключевые паттерны
#### Паттерн 1: Event Sourcing (OpenHands)
Вся работа агента — поток событий. Воспроизведя события, можно восстановить состояние.
```
Event Stream: [FileRead, CodeEdit, CmdRun, FileRead, CodeEdit, CmdRun, ...]
Checkpoint (snapshot)
Resume: load snapshot + replay events after it
```
**Применимость для Team Board:** ★★★★★ — отлично подходит для восстановления сессий. Каждое действие агента = событие в `session_messages`.
#### Паттерн 2: Persistent Checkpointing (LangGraph)
Граф состояний с возможностью сохранения checkpoint в любой точке. При сбое — восстановление с последнего checkpoint.
```python
# LangGraph-style checkpoint
checkpoint = {
"state": {"task": "proj-42", "step": "writing_tests"},
"channel_values": {"messages": [...last_5...]},
"metadata": {"step_count": 42}
}
```
**Применимость для Team Board:** ★★★★☆ — модель `session.checkpoint` в нашем протоколе реализует этот паттерн.
#### Паттерн 3: Role-Based Delegation (CrewAI)
Агенты имеют роли (coder, reviewer, tester, PM). Задачи маршрутизируются по ролям. Агент может делегировать подзадачу другому.
```
PM Agent: "Нужно реализовать фичу X"
├──► Coder Agent: "Напиши код"
│ └──► Tester Agent: "Напиши тесты"
└──► Reviewer Agent: "Проверь когда будет PR"
```
**Применимость для Team Board:** ★★★★★ — capabilities + agent.request протокол реализуют это.
#### Паттерн 4: Sandbox Isolation (Devin, SWE-Agent)
Каждый агент работает в изолированном окружении (Docker/VM), где может безопасно выполнять код.
```
┌─────────────────────────────────┐
│ Agent Sandbox │
│ ┌─────────┐ ┌──────────────┐ │
│ │ Git │ │ Shell/Code │ │
│ │ clone │ │ execution │ │
│ └─────────┘ └──────────────┘ │
│ ┌─────────┐ ┌──────────────┐ │
│ │ Files │ │ Network │ │
│ │ /work/ │ │ (filtered) │ │
│ └─────────┘ └──────────────┘ │
└─────────────────────────────────┘
```
**Применимость для Team Board:** ★★★★☆ — важно для безопасности, но можно реализовать позже. На первом этапе — Docker containers per agent.
#### Паттерн 5: Tool-Use Protocol (Claude, GPT Function Calling)
Агент не выполняет действия напрямую — он запрашивает выполнение «инструментов» у среды. Среда выполняет и возвращает результат.
```json
// Agent → Tracker
{"type": "tool.call", "tool": "git.diff", "args": {"branch": "feat/proj-42"}}
// Tracker → Agent
{"type": "tool.result", "result": "diff --git a/..."}
```
**Применимость для Team Board:** ★★★☆☆ — полезно для агентов без собственного sandbox. Tracker может проксировать инструменты. Но увеличивает нагрузку на Tracker.
### 6.3 Подходы к долгим задачам
| Подход | Как работает | Пример |
|--------|-------------|--------|
| **Checkpoint + Resume** | Периодическое сохранение состояния, возобновление после сбоя | LangGraph, OpenHands |
| **Plan → Execute → Verify** | Агент сначала планирует, потом выполняет шаги, проверяет результат | Devin, SWE-Agent |
| **Hierarchical Decomposition** | Большая задача разбивается на подзадачи, каждая — отдельный цикл | CrewAI, AutoGPT |
| **Event Sourcing + Replay** | Все действия записываются, состояние воспроизводимо | OpenHands |
| **Session Compaction** | Длинная история сжимается в summary + recent window | Claude Code, OpenClaw |
**Рекомендация для Team Board:** комбинация Checkpoint + Resume и Session Compaction с Hierarchical Decomposition для сложных задач.
---
## 7. Рекомендуемая архитектура
### 7.1 Целевая архитектура
```
┌─────────────────────────────────────────────────────────┐
│ TRACKER v2 │
│ │
│ ┌──────────┐ ┌───────────┐ ┌──────────┐ │
│ │ WS Hub │ │ Session │ │ Task │ │
│ │ :8100 │ │ Manager │ │ Engine │ │
│ └────┬─────┘ └─────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ┌────┴──────────────┴──────────────┴─────┐ │
│ │ Event Bus (Redis Streams) │ │
│ └────┬──────────────┬──────────────┬─────┘ │
│ │ │ │ │
│ ┌────┴─────┐ ┌─────┴─────┐ ┌────┴──────┐ │
│ │ Chat │ │ Git │ │ Agent │ │
│ │ Router │ │Integration│ │ Registry │ │
│ └──────────┘ └───────────┘ └───────────┘ │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ PostgreSQL + Redis │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
▲ ▲ ▲
│ WS │ WS │ Webhooks
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│ Agent 1 │ │ Agent 2 │ │ Gitea │
│(sandbox)│ │(sandbox)│ │ │
└─────────┘ └─────────┘ └─────────┘
```
### 7.2 Полный протокол v2
#### Lifecycle
```
CONNECT → auth → auth.ok
├── session.resume / session.create
│ → session.restored / session.created
├── chat.subscribe → chat.subscribed
├── task.offer → task.accept/decline
│ task.take → task.take.ok/conflict
│ (работа над задачей)
│ task.progress
│ session.checkpoint
│ git.pr.created
│ agent.request → agent.response
├── task.move → task.moved
├── task.complete → task.completed
├── agent.heartbeat → agent.heartbeat.ack
DISCONNECT → (grace period) → session.suspend
```
#### Полный список событий
**Аутентификация и сессии:**
| Событие | Направление | Описание |
|---------|-------------|----------|
| `auth` | A→T | Аутентификация |
| `auth.ok` | T→A | Подтверждение с init context |
| `auth.error` | T→A | Ошибка аутентификации |
| `session.create` | A→T | Создать новую сессию |
| `session.resume` | A→T | Возобновить существующую |
| `session.created` | T→A | Сессия создана |
| `session.restored` | T→A | Сессия восстановлена |
| `session.checkpoint` | A→T | Сохранить контрольную точку |
| `session.checkpoint.ok` | T→A | Контрольная точка сохранена |
**Задачи:**
| Событие | Направление | Описание |
|---------|-------------|----------|
| `task.available` | T→A | Доступна новая задача (broadcast) |
| `task.offer` | T→A | Предложение задачи конкретному агенту |
| `task.accept` | A→T | Принятие предложенной задачи |
| `task.decline` | A→T | Отклонение предложенной задачи |
| `task.take` | A→T | Взятие задачи из очереди |
| `task.take.ok` | T→A | Задача назначена |
| `task.take.conflict` | T→A | Конфликт — задача уже взята |
| `task.progress` | A→T | Обновление прогресса |
| `task.move` | A→T | Перемещение по канбану |
| `task.moved` | T→A | Подтверждение перемещения |
| `task.complete` | A→T | Завершение задачи |
| `task.completed` | T→A | Подтверждение завершения |
| `task.comment` | A→T | Комментарий к задаче |
| `task.blocked` | A→T | Агент заблокирован зависимостью |
| `task.unblocked` | T→A | Зависимость разрешена |
| `task.assigned` | T→A | Задача назначена (push) |
| `task.release` | A→T | Агент отказывается от задачи |
**Чат:**
| Событие | Направление | Описание |
|---------|-------------|----------|
| `chat.subscribe` | A→T | Подписка на комнаты |
| `chat.subscribed` | T→A | Подтверждение подписки |
| `chat.unsubscribe` | A→T | Отписка |
| `chat.send` | A→T | Отправка сообщения |
| `chat.message` | T→A | Входящее сообщение |
| `chat.history` | A→T | Запрос истории |
| `chat.history.result` | T→A | История сообщений |
**Межагентная коммуникация:**
| Событие | Направление | Описание |
|---------|-------------|----------|
| `agent.request` | A→T / T→A | Запрос к другому агенту |
| `agent.response` | A→T / T→A | Ответ на запрос |
| `agent.broadcast` | A→T | Широковещательное сообщение агентам |
**Git:**
| Событие | Направление | Описание |
|---------|-------------|----------|
| `git.pr.created` | A→T | PR создан |
| `git.pr.updated` | A→T | PR обновлён |
| `git.review.request` | T→A | Запрос на ревью |
| `git.review.complete` | A→T | Ревью завершено |
| `git.review.result` | T→A | Результат ревью |
| `git.webhook` | External→T | Webhook от Gitea |
**Системные:**
| Событие | Направление | Описание |
|---------|-------------|----------|
| `agent.heartbeat` | A→T | Keep-alive |
| `agent.heartbeat.ack` | T→A | Подтверждение |
| `agent.status` | A→T | Обновление статуса |
| `error` | T→A | Ошибка |
### 7.3 Что добавить в Tracker
**Приоритет 1 (MVP):**
1. `agent_sessions` + `session_messages` таблицы
2. `session.resume` / `session.restored` протокол
3. `task.take` с advisory lock (конкурентность)
4. `task_dependencies` таблица + `task.unblocked`
5. `task.offer` / `task.accept` / `task.decline`
6. `task.progress` с progress_pct
**Приоритет 2 (Git):**
7. Gitea webhook handler
8. `git.pr.created` / `git.review.request` протокол
9. Автоматическое создание веток при task.take
**Приоритет 3 (Advanced):**
10. `session.checkpoint` + compaction
11. `agent.request` / `agent.response` (inter-agent)
12. Redis Streams для event bus
13. Rate limiting per agent
### 7.4 Agent SDK
Минимальный SDK на Python:
```python
from team_board_sdk import Agent, TaskHandler
class CoderAgent(Agent):
name = "coder-agent"
capabilities = ["code", "python", "javascript"]
subscription_mode = "mentions"
max_concurrent = 3
async def on_task_offer(self, task):
"""Вызывается при предложении задачи"""
if self.active_tasks_count < self.max_concurrent:
await self.accept_task(task)
else:
await self.decline_task(task, reason="busy")
async def on_task_assigned(self, task):
"""Вызывается при назначении задачи"""
# Автоматически создаётся сессия
session = self.current_session
# Клонируем/обновляем репо
repo = await self.git.ensure_repo(task.git_context.repo_url)
branch = await repo.create_branch(task.git_context.suggested_branch)
# Работаем
await self.update_progress(task, 10, "Анализирую задачу")
plan = await self.llm.plan(task.description, repo.get_context())
for i, step in enumerate(plan.steps):
await self.execute_step(step)
pct = int((i + 1) / len(plan.steps) * 80) + 10
await self.update_progress(task, pct, step.description)
# Checkpoint каждые 5 шагов
if i % 5 == 0:
await self.session.checkpoint(
summary=f"Выполнено {i+1}/{len(plan.steps)} шагов",
working_state={"step": i, "branch": branch.name}
)
# Создаём PR
pr = await self.git.create_pr(
repo, branch, task.git_context.base_branch,
title=f"{task.id}: {task.title}"
)
await self.notify_pr_created(task, pr)
await self.move_task(task, "in_review")
async def on_chat_message(self, message):
"""Вызывается при упоминании в чате"""
if self.is_mentioned(message):
response = await self.llm.respond(message, self.current_context)
await self.chat.send(message.room, response, reply_to=message.id)
async def on_reconnect(self, session):
"""Вызывается при восстановлении сессии"""
print(f"Resumed: {session.context_summary}")
# SDK автоматически восстанавливает состояние
agent = CoderAgent(token="agent-token-xxx")
agent.run("ws://tracker:8100")
```
**Структура SDK:**
```
team-board-sdk/
├── team_board_sdk/
│ ├── __init__.py
│ ├── agent.py # Базовый класс Agent
│ ├── connection.py # WebSocket connection + reconnect
│ ├── session.py # Session management + checkpoints
│ ├── task.py # Task lifecycle helpers
│ ├── chat.py # Chat routing
│ ├── git.py # Git operations (clone, branch, PR)
│ ├── llm.py # LLM interface (pluggable)
│ └── types.py # Pydantic models для протокола
├── examples/
│ ├── coder_agent.py
│ ├── reviewer_agent.py
│ └── pm_agent.py
└── pyproject.toml
```
### 7.5 Production Requirements
**Логирование:**
- Structured logging (JSON) для всех событий
- Отдельный лог-стрим на агента
- Retention: 30 дней events, 7 дней debug
**Мониторинг:**
- Метрики: active agents, tasks/hour, avg task duration, session count
- Alerting: agent offline > 5min, task stuck > timeout, error rate > threshold
- Dashboard: Grafana с WS connections, task flow, agent utilization
**Rate Limiting:**
```python
RATE_LIMITS = {
"chat.send": "30/min per agent",
"task.progress": "10/min per task",
"session.checkpoint": "5/min per session",
"agent.request": "20/min per agent",
"git.*": "10/min per agent"
}
```
**Security:**
- Token rotation (30 дней)
- Per-agent capability enforcement (агент с capabilities=["code"] не может делать review)
- Audit log всех действий
- Sandbox isolation (Docker) для агентов с code execution
**Масштабирование:**
- Tracker горизонтально масштабируется через Redis pub/sub (sticky sessions по agent_id)
- WebSocket connections: ~1000 на инстанс (с nginx upstream)
- PostgreSQL: partitioning session_messages по дате
---
## Приложение A: Миграции БД
```sql
-- Сессии агентов
CREATE TABLE agent_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id UUID NOT NULL REFERENCES agents(id),
task_id UUID REFERENCES tasks(id),
status VARCHAR(20) NOT NULL DEFAULT 'active',
context_summary TEXT,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
expires_at TIMESTAMPTZ
);
CREATE INDEX idx_sessions_agent ON agent_sessions(agent_id, status);
CREATE INDEX idx_sessions_task ON agent_sessions(task_id);
-- Сообщения сессий
CREATE TABLE session_messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID NOT NULL REFERENCES agent_sessions(id) ON DELETE CASCADE,
role VARCHAR(20) NOT NULL,
content TEXT NOT NULL,
seq BIGSERIAL,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_session_msgs ON session_messages(session_id, seq);
-- Зависимости задач
CREATE TABLE task_dependencies (
task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
depends_on UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
PRIMARY KEY (task_id, depends_on)
);
-- Межагентные запросы
CREATE TABLE agent_requests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
from_agent_id UUID NOT NULL REFERENCES agents(id),
to_agent_id UUID REFERENCES agents(id),
request_type VARCHAR(50) NOT NULL,
payload JSONB NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
result JSONB,
created_at TIMESTAMPTZ DEFAULT now(),
resolved_at TIMESTAMPTZ,
timeout_at TIMESTAMPTZ
);
```
## Приложение B: Roadmap внедрения
```
Phase 1 (2 недели): Sessions + Task Concurrency
├── agent_sessions таблица
├── session.resume/restore протокол
├── task.take с advisory lock
└── task_dependencies + task.unblocked
Phase 2 (2 недели): Enhanced Tasks + Chat
├── task.offer/accept/decline
├── task.progress
├── chat.subscribe с modes
└── agent.request/response
Phase 3 (3 недели): Git Integration
├── Gitea webhook handler
├── git.pr.created/review протокол
├── Auto branch creation
└── Agent SDK v0.1
Phase 4 (2 недели): Production Hardening
├── Rate limiting
├── Monitoring + alerting
├── Session compaction
└── Agent SDK v1.0
```
---
*Документ подготовлен: Февраль 2026*
*Автор: AI Research Agent*
*Версия: 1.0*