385 lines
15 KiB
Markdown
385 lines
15 KiB
Markdown
# 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
|