docs/ARCHITECTURE.md

15 KiB
Raw Blame History

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):

{
  "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