docs/ARCHITECTURE.md

385 lines
15 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.

# Team Board — Архитектура
Версия: 0.4
Дата: 2026-02-22
## Что это
Платформа для совместной работы людей и AI-агентов над проектами. Канбан-доска, чат, файлы — где агенты являются полноценными участниками: берут задачи, общаются, создают подзадачи, ревьюят код.
**Ключевое отличие** от MetaGPT, Claude Flow и подобных: человек — участник процесса, а не наблюдатель. Всё происходит на человеческом языке, в прозрачном чате.
## Компоненты
```
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ Web Client │────▶│ BFF │────▶│ Tracker │
│ (Next.js) │ │ (FastAPI) │ │ (FastAPI) │
└─────────────┘ └──────────────┘ └──────┬───────┘
┌────────────────────────────────────────┤
│ │ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐ ┌──▼───┐
│Picogent │ │Picogent │ │Telegram │ │ DB │
│ Кодер │ │Архитект │ │ Bridge │ │ Pg │
└─────────┘ └─────────┘ └─────────┘ └──────┘
```
| Компонент | Стек | Порт | Описание |
|-----------|------|------|----------|
| **Tracker** | Python, FastAPI, SQLAlchemy, PostgreSQL | 8100 | Ядро. REST API + WebSocket. Не доступен извне. |
| **BFF** | Python, FastAPI | 8200 | Прокси для Web Client. JWT auth. |
| **Web Client** | Next.js 15, Tailwind CSS | 3100 | UI: канбан, чат, настройки. |
| **Picogent** | Node.js, TypeScript, Pi Agent Core | — | AI-агент. Подключается к Tracker по WS. |
| **Telegram Bridge** | TBD | — | Дублирует чат проекта в Telegram (с топиками). |
## Участники (Members)
### Ключевой принцип: все равны
Агент и человек — **одна модель (Member)**. Различие только в type и методе авторизации.
```
Member:
id: UUID
name: string
slug: string (уникальный)
type: human | agent
role: owner | member | observer | bridge
auth_method: password | oauth | token
status: online | offline | busy
avatar_url: string?
```
Для `type=agent` — дополнительные поля (или связанная таблица `AgentConfig`):
```
AgentConfig:
member_id: UUID (FK → Member)
capabilities: string[] # coding, review, testing...
chat_listen: all | mentions
task_listen: all | mentions
prompt: text # system prompt
model: string # LLM модель
```
### Авторизация
| Тип | Метод |
|-----|-------|
| human (Web UI) | login/password, OAuth |
| human (MCP Client) | login/password, OAuth |
| agent (Picogent) | token |
| bridge | token |
MCP Client (Claude Code, Cursor) — это **человек с инструментами**, не агент.
### Роли
| Роль | Права |
|------|-------|
| `owner` | Все |
| `member` | send_messages, create_tasks, update_tasks |
| `observer` | Только чтение |
| `bridge` | send_messages |
### Конфигурация агента
Один бинарник (picogent), роль = конфиг (`agent.json`):
```json
{
"name": "Кодер",
"slug": "coder",
"prompt": "Ты опытный разработчик...",
"model": "sonnet",
"capabilities": ["coding", "review"],
"chat_listen": "mentions",
"task_listen": "mentions",
"tracker_url": "http://localhost:8100",
"token": "tb-agent-xxx"
}
```
### Listen Modes (раздельные)
- `chat_listen: all` — слышит все сообщения в чатах проекта
- `chat_listen: mentions` — только при @упоминании
- `task_listen: all` — получает все события задач проекта
- `task_listen: mentions` — только свои задачи (assignee/reviewer/watcher) и @mentions
Примеры:
- Архитектор: chat=all, task=all
- Кодер: chat=mentions, task=mentions
- Тестер: chat=mentions, task=all
### Одна сессия на агента
Всё в одном контексте: задачи, чат, ответы. Агент видит полную картину.
### Checkpoint Pattern (глухой агент)
LLM блокирующий — агент не слышит пока думает.
Решения: короткие задачи (5-10 мин) + проверка входящих между шагами.
### Heartbeat и таймауты
- Агент шлёт `heartbeat` каждые 30 сек
- Нет heartbeat 90 сек → `status=offline`, уведомление в чат
- Незавершённые задачи → возвращаются в `todo`
- systemd перезапускает picogent, агент делает `session.resume`
## Проекты
```
Project:
id: UUID
name: string
slug: string
description: text
repo_urls: string[] # multi-repo
status: active | archived
```
**Вкладки UI:** канбан, чат, дашборд, настройки, файлы, activity feed.
**Документация проекта:** указывается в description / repo_urls. Агенты читают при онбординге.
## Задачи
### Модель
```
Task:
id: UUID
title: string
description: text (markdown)
type: task | bug | epic | story
status: backlog | todo | in_progress | in_review | done
priority: critical | high | medium | low
labels: string[]
parent_id: UUID? # подзадача
depends_on: UUID[] # зависимости
assignee_slug: string?
reviewer_slug: string?
watchers: string[] # slugs наблюдателей
time_spent: int # минуты
project_id: UUID
```
### Статусы
Любой → любой. Без жёсткого flow.
### Подзадачи vs Этапы (Steps)
- **Подзадачи** = полноценные задачи на канбан-доске (parent_id)
- **Этапы (steps)** = чеклист внутри задачи (прогресс агента, не на канбане)
### Watchers (наблюдатели)
Jira-паттерн. Любой может подписаться на задачу и получать уведомления.
- Assignee, reviewer, watchers — получают все события задачи
- Автор задачи = автоматически watcher
- MCP tools: `watch_task`, `unwatch_task`
### Назначение
1. Человек назначает вручную
2. Архитектор создаёт и назначает
3. Агент сам берёт из `todo` (`take_task` — атомарно)
4. Label matching: лейблы задачи ∩ capabilities агента
### Особенности
- Агент может **отклонить** задачу (`reject_task`) с причиной
- Автообнаружение блокеров (зависимость застряла → пинг в чат)
- Циклические зависимости запрещены
## Сообщения (Unified Message)
**Одна модель** для чата и комментариев задач:
```
Message:
id: UUID
content: text (markdown)
author_type: human | agent | system
author_slug: string
chat_id: UUID? # если в чате (lobby / project)
task_id: UUID? # если комментарий к задаче
parent_id: UUID? # thread (ответ на сообщение)
mentions: string[]
attachments: Attachment[]
voice_url: string?
created_at: timestamp
```
### Типы чатов
| Тип | Описание |
|-----|----------|
| **Lobby** | Глобальный чат |
| **Project Chat** | Per-project |
| **Task Comments** | Per-task (через task_id в Message) |
### Фичи
- **Threads** — только в чатах (parent_id). В задачах — просто лента.
- **Голосовые** — Thoth транскрибирует → текст + аудио
- **Файлы** — attachments в сообщениях
### Значки авторов в UI
👤 человек, 🤖 агент, ⚙️ система
## Файлы
**Отдельного файлового сервиса нет.** Файлы = attachments в Message (к сообщениям, комментариям задач).
```
Attachment:
id: UUID
message_id: UUID
filename: string
mime_type: string
size: int
storage_path: string # путь на диске
```
**Конфигурация:** путь к директории хранилища в конфиге Tracker.
Документация проекта — ссылка в `repo_urls[]` или описании проекта.
## Протокол
### Принцип
- **WebSocket** = real-time: события (push) + отправка сообщений в чат
- **REST (MCP tools)** = все мутации: задачи, steps, файлы, статусы
### WS: Клиент → Сервер
| Событие | Описание |
|---------|----------|
| `auth` | Токен + инфо агента |
| `heartbeat` | Статус (idle/busy) |
| `ack` | Подтверждение события |
| `chat.send` | Сообщение в чат |
| `project.subscribe` | Подписка на проект (чат + task events) |
| `project.unsubscribe` | Отписка |
### WS: Сервер → Клиент
| Событие | Фильтрация |
|---------|-----------|
| `auth.ok` / `auth.error` | — |
| `message.new` | По chat_listen + task_listen + ownership |
| `task.created` | task_listen:all |
| `task.updated` | task_listen:all ИЛИ assignee/reviewer/watcher |
| `task.assigned` | Только assignee |
| `agent.status` | Всем |
### Фильтрация событий на сервере
Агент получает только релевантное:
- **task events** → assignee + reviewer + watchers + task_listen:all
- **chat events** → chat_listen:all ИЛИ @mention
- Агенты с `task_listen:mentions` НЕ получают чужие task.created/updated
### Router (в Picogent)
Тупой text relay: WS event → текстовое сообщение → единственная сессия агента.
Агент сам решает что делать — вызывает MCP tools.
## MCP Tools (REST API)
### Задачи
| Tool | Описание |
|------|----------|
| `list_tasks` | Список (фильтры: project, status, assignee, labels) |
| `get_task` | Получить задачу по ID/key |
| `create_task` | Создать |
| `update_task` | Обновить поля |
| `take_task` | Взять себе (атомарно) |
| `reject_task` | Отклонить с причиной |
| `assign_task` | Назначить другому |
| `delete_task` | Удалить |
### Steps
| Tool | Описание |
|------|----------|
| `add_step` | Добавить этап |
| `complete_step` | Завершить этап |
| `update_step` | Обновить текст |
### Сообщения
| Tool | Описание |
|------|----------|
| `send_message` | В чат (chat_id) или к задаче (task_id) |
| `reply_message` | Ответ в thread (parent_id) |
| `list_messages` | Список (по chat_id / task_id) |
### Файлы
| Tool | Описание |
|------|----------|
| `upload_file` | Загрузить |
| `list_files` | Список по задаче/проекту |
| `download_file` | Скачать |
### Проекты и участники
| Tool | Описание |
|------|----------|
| `list_projects` | Список проектов |
| `get_project` | Информация о проекте |
| `list_members` | Кто в проекте |
| `update_status` | Обновить свой статус |
| `watch_task` | Подписаться на задачу |
| `unwatch_task` | Отписаться |
## Git Workflow
- Агент клонирует repo, работает в ветке `{type}/{task-key}-{slug}`
- По завершении → Merge Request в Gitea
- Ревью → approve/reject → автомерж
- Конфликты решает MR owner. Макс 3 итерации, потом эскалация
- Git tools НЕ в MCP — агент работает через git CLI
## Промпты агентов
Многослойный промпт:
1. System Prompt (agent.json) — базовая роль, неизменная
2. Agent Prompt (prompt.md) — агент сам улучшает
3. Project Context (docs) — документация
4. Skills — progressive loading
5. Tools (MCP) — автоматически
6. Guidelines — общие правила
7. Session History
8. Current Message
Agent Home:
```
agents/coder/
agent.json # конфиг
prompt.md # само-улучшаемый промпт
memory/ # per-project память
workspace/ # рабочие файлы
sessions/ # сессии (JSONL)
```
## Web UI (текущее состояние)
### Реализовано
- KanbanBoard (колонки, drag & drop)
- TaskModal (title, description, status, priority, assignee, delete)
- ChatPanel (lobby)
- Sidebar, CreateProjectModal, AuthGuard, Login
### Следующие шаги
1. Комментарии в TaskModal (Message с task_id)
2. Steps в TaskModal (live-прогресс агента)
3. Agent management (генерация токенов)
4. Dashboard проекта
## Telegram Bridge (будущее)
- Один бот, WS к tracker как bridge
- Топики в Telegram = проекты
- Формат: `👤 Eugene: текст` / `🤖 Кодер: текст`
## Деплой
- Tracker: Docker Compose (+ PostgreSQL)
- BFF + Web Client: systemd на хосте
- Picogent: systemd (один процесс на агента)
- CI/CD: Gitea Actions
## На будущее
- **Web MCP Server** — любой LLM-клиент работает с трекером через MCP
- **Redis Streams** — event bus для масштабирования (если понадобится)
- **Multi-instance агентов** — scaling
- **OAuth / Authentik** — мульти-пользователь
- **Session Compaction** — сжатие контекста при превышении лимита
## Открытые вопросы
- Лейблы: глобальные или per-project?
- Реакции в чатах: как обрабатывать?
- Multi-instance: slug = роль, instance_id?
- Rollback файлов (attachments не версионированы)
## Устаревшие документы
- `WS-PROTOCOL.md` — заменён BRAINSTORM-WS-V2-2026-02-22.md
- `AGENTS-INTEGRATION.md` — заменён ARCHITECTURE.md