ARCHITECTURE.md v0.4 — unified source of truth, all contradictions resolved
This commit is contained in:
parent
036e5ff481
commit
49a9c7dc50
611
ARCHITECTURE.md
611
ARCHITECTURE.md
@ -1,6 +1,6 @@
|
|||||||
# Team Board — Архитектура
|
# Team Board — Архитектура
|
||||||
Версия: 0.3 (драфт)
|
Версия: 0.4
|
||||||
Дата: 2026-02-21
|
Дата: 2026-02-22
|
||||||
|
|
||||||
## Что это
|
## Что это
|
||||||
|
|
||||||
@ -19,8 +19,8 @@
|
|||||||
┌────────────────────────────────────────┤
|
┌────────────────────────────────────────┤
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
┌────▼────┐ ┌────▼────┐ ┌────▼────┐ ┌──▼───┐
|
┌────▼────┐ ┌────▼────┐ ┌────▼────┐ ┌──▼───┐
|
||||||
│Picogent │ │Picogent │ │Telegram │ │ DB │
|
│Picogent │ │Picogent │ │Telegram │ │ DB │
|
||||||
│ Кодер │ │Архитект │ │ Bridge │ │Pg+Red│
|
│ Кодер │ │Архитект │ │ Bridge │ │ Pg │
|
||||||
└─────────┘ └─────────┘ └─────────┘ └──────┘
|
└─────────┘ └─────────┘ └─────────┘ └──────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -31,110 +31,11 @@
|
|||||||
| **Web Client** | Next.js 15, Tailwind CSS | 3100 | UI: канбан, чат, настройки. |
|
| **Web Client** | Next.js 15, Tailwind CSS | 3100 | UI: канбан, чат, настройки. |
|
||||||
| **Picogent** | Node.js, TypeScript, Pi Agent Core | — | AI-агент. Подключается к Tracker по WS. |
|
| **Picogent** | Node.js, TypeScript, Pi Agent Core | — | AI-агент. Подключается к Tracker по WS. |
|
||||||
| **Telegram Bridge** | TBD | — | Дублирует чат проекта в Telegram (с топиками). |
|
| **Telegram Bridge** | TBD | — | Дублирует чат проекта в Telegram (с топиками). |
|
||||||
| **OpenClaw Bridge** | TBD | — | Фильтрует @markov mentions → webhook в OpenClaw. |
|
|
||||||
| **PostgreSQL** | 16 | 5433 | БД Tracker. |
|
|
||||||
| **Redis** | 7 | 6380 | Пока не используется. |
|
|
||||||
|
|
||||||
## Проекты
|
|
||||||
|
|
||||||
Проект = workspace для команды (людей + агентов).
|
|
||||||
|
|
||||||
**Поля:** name, slug, description, repo_urls[] (multi-repo), status (active/archived).
|
|
||||||
|
|
||||||
**Вкладки UI:** канбан, чат, дашборд, настройки, файлы, activity feed.
|
|
||||||
|
|
||||||
**Правила:** описываются в документации проекта (docs/ в repo или file storage). Агенты читают при онбординге.
|
|
||||||
|
|
||||||
**Кросс-проектные ссылки:** задача в проекте A может ссылаться на задачу в проекте B.
|
|
||||||
|
|
||||||
## Задачи
|
|
||||||
|
|
||||||
### Модель
|
|
||||||
| Поле | Тип | Описание |
|
|
||||||
|------|-----|----------|
|
|
||||||
| id | UUID | |
|
|
||||||
| title | string | Название |
|
|
||||||
| description | text | Markdown |
|
|
||||||
| type | enum | task, bug, epic, story |
|
|
||||||
| status | enum | backlog, todo, in_progress, in_review, done |
|
|
||||||
| priority | enum | critical, high, medium, low |
|
|
||||||
| labels | string[] | bug, feature, refactor, docs... |
|
|
||||||
| parent_id | UUID? | Подзадача (бесконечная вложенность) |
|
|
||||||
| depends_on | UUID[] | Зависимости (нельзя начать пока не done) |
|
|
||||||
| assignee_slug | string? | Исполнитель |
|
|
||||||
| reviewer_slug | string? | Ревьюер |
|
|
||||||
| steps | Step[] | Этапы (прогресс агента, не видны на канбане) |
|
|
||||||
| time_spent | int | Минуты (для аналитики) |
|
|
||||||
| project_id | UUID | |
|
|
||||||
|
|
||||||
### Статусы
|
|
||||||
Любой → любой. Без жёсткого flow. `todo → done` — нормально, если задача простая.
|
|
||||||
|
|
||||||
### Подзадачи vs Этапы
|
|
||||||
- **Подзадачи** = полноценные задачи на канбан-доске (parent_id)
|
|
||||||
- **Этапы (steps)** = чеклист внутри задачи. Агент обновляет по ходу работы. Не засоряют доску.
|
|
||||||
|
|
||||||
### Комментарии
|
|
||||||
```
|
|
||||||
TaskComment: id, task_id, author_type (human|agent|system),
|
|
||||||
content, mentions[], voice_url?, attachments[],
|
|
||||||
parent_comment_id? (threads), created_at
|
|
||||||
```
|
|
||||||
Mentions (@slug) → уведомление агенту через WS.
|
|
||||||
|
|
||||||
### Связи между задачами (Task Links)
|
|
||||||
Помимо parent/child и depends_on, задачи поддерживают дополнительные связи:
|
|
||||||
- **relates_to** — связанные задачи (информационно)
|
|
||||||
- **duplicates** — дубликат другой задачи
|
|
||||||
- **blocks / blocked_by** — блокировка (аналог depends_on, но для человеческого UI)
|
|
||||||
|
|
||||||
Агенты используют `depends_on` для автоматики, остальные связи — для людей в UI.
|
|
||||||
|
|
||||||
### Назначение задач
|
|
||||||
1. Человек назначает вручную
|
|
||||||
2. Архитектор создаёт и назначает
|
|
||||||
3. Агент сам берёт из `todo` по capabilities (`task.take` — атомарная операция)
|
|
||||||
4. Через чат с @mention: "ребята, новая задача"
|
|
||||||
5. Auto-assign: Tracker предлагает задачу по capabilities + загрузке (HYBRID модель)
|
|
||||||
|
|
||||||
### Приоритизация очереди
|
|
||||||
- По приоритету задачи (critical → high → medium → low)
|
|
||||||
- Если задача назначена на конкретного агента → он берёт первым
|
|
||||||
- Label matching: лейблы задачи ∩ capabilities агента
|
|
||||||
|
|
||||||
### Особенности
|
|
||||||
- Агент может **отклонить** задачу (reject_task) с обоснованием
|
|
||||||
- **Автообнаружение блокеров**: зависимость застряла → пинг в чат
|
|
||||||
- **Задача-наблюдатель**: не на выполнение, а мониторинг ("следи за CI", "проверяй X раз в час"). Периодическая/фоновая задача.
|
|
||||||
- Задача порождает подзадачи автоматически (агент создаёт через create_task)
|
|
||||||
- Циклические зависимости запрещены (валидация при создании)
|
|
||||||
|
|
||||||
## Чаты
|
|
||||||
|
|
||||||
### Типы
|
|
||||||
| Тип | Описание | Файлы |
|
|
||||||
|-----|----------|-------|
|
|
||||||
| **Lobby** | Глобальный чат для всех | Нет хранилища |
|
|
||||||
| **Project Chat** | Per-project, координация | Да |
|
|
||||||
| **Task Comments** | Per-task, обсуждение задачи | Да |
|
|
||||||
|
|
||||||
### Фичи
|
|
||||||
- **Threads** (как в Slack) — ответ на сообщение создаёт ветку
|
|
||||||
- **Голосовые** — запись → Thoth транскрибирует → текст + аудио
|
|
||||||
- **Файлы в чат** — документы, изображения
|
|
||||||
- **Реакции** — TBD (не попадают в промпт агента, чисто UI)
|
|
||||||
|
|
||||||
### Модель сообщения
|
|
||||||
```
|
|
||||||
ChatMessage: id, chat_id, author_type, author_slug,
|
|
||||||
content (markdown), thread_id?, mentions[],
|
|
||||||
voice_url?, attachments[], reactions[], created_at
|
|
||||||
```
|
|
||||||
|
|
||||||
## Участники (Members)
|
## Участники (Members)
|
||||||
|
|
||||||
### Ключевой принцип: все равны
|
### Ключевой принцип: все равны
|
||||||
Агент и человек — **одна модель**. Различие только в type и методе авторизации.
|
Агент и человек — **одна модель (Member)**. Различие только в type и методе авторизации.
|
||||||
|
|
||||||
```
|
```
|
||||||
Member:
|
Member:
|
||||||
@ -144,45 +45,41 @@ Member:
|
|||||||
type: human | agent
|
type: human | agent
|
||||||
role: owner | member | observer | bridge
|
role: owner | member | observer | bridge
|
||||||
auth_method: password | oauth | token
|
auth_method: password | oauth | token
|
||||||
capabilities: string[] # для агентов: coding, review...
|
|
||||||
listen_mode: all | mentions # для агентов (human сам решает)
|
|
||||||
prompt: string? # system prompt (только для агентов)
|
|
||||||
model: string? # LLM модель (только для агентов)
|
|
||||||
status: online | offline | busy
|
status: online | offline | busy
|
||||||
avatar_url: string?
|
avatar_url: string?
|
||||||
```
|
```
|
||||||
|
|
||||||
### Авторизация
|
Для `type=agent` — дополнительные поля (или связанная таблица `AgentConfig`):
|
||||||
| Тип | Метод | Пример |
|
```
|
||||||
|-----|-------|--------|
|
AgentConfig:
|
||||||
| human (Web UI) | login/password, OAuth (Authentik) | Человек в браузере |
|
member_id: UUID (FK → Member)
|
||||||
| human (MCP Client) | login/password, OAuth | Claude Code CLI, Cursor |
|
capabilities: string[] # coding, review, testing...
|
||||||
| agent (Picogent) | token (сгенерирован в UI) | Автономный AI-агент |
|
chat_listen: all | mentions
|
||||||
| agent (Марков/OpenClaw) | token (REST API) | AI через скилл |
|
task_listen: all | mentions
|
||||||
| bridge | token | Telegram Bridge |
|
prompt: text # system prompt
|
||||||
|
model: string # LLM модель
|
||||||
|
```
|
||||||
|
|
||||||
MCP Client (Claude Code, Cursor) — это **человек с инструментами**, не агент. Авторизация как у человека.
|
### Авторизация
|
||||||
|
| Тип | Метод |
|
||||||
|
|-----|-------|
|
||||||
|
| human (Web UI) | login/password, OAuth |
|
||||||
|
| human (MCP Client) | login/password, OAuth |
|
||||||
|
| agent (Picogent) | token |
|
||||||
|
| bridge | token |
|
||||||
|
|
||||||
|
MCP Client (Claude Code, Cursor) — это **человек с инструментами**, не агент.
|
||||||
|
|
||||||
### Роли
|
### Роли
|
||||||
| Роль | Описание | Права по умолчанию |
|
| Роль | Права |
|
||||||
|------|----------|-------------------|
|
|------|-------|
|
||||||
| `owner` | Владелец доски. Полные права. | Все |
|
| `owner` | Все |
|
||||||
| `member` | Участник. Выполняет задачи, пишет в чат. | send_messages, create_tasks, update_tasks |
|
| `member` | send_messages, create_tasks, update_tasks |
|
||||||
| `observer` | Только чтение. | — |
|
| `observer` | Только чтение |
|
||||||
| `bridge` | Мост (Telegram). Пересылает сообщения, не берёт задачи. | send_messages |
|
| `bridge` | send_messages |
|
||||||
|
|
||||||
### Права (permissions)
|
### Конфигурация агента
|
||||||
| Право | Описание |
|
Один бинарник (picogent), роль = конфиг (`agent.json`):
|
||||||
|-------|----------|
|
|
||||||
| `send_messages` | Отправка сообщений в чаты |
|
|
||||||
| `create_tasks` | Создание новых задач |
|
|
||||||
| `assign_tasks` | Назначение задач другим агентам |
|
|
||||||
| `update_tasks` | Изменение статуса/описания задач |
|
|
||||||
| `manage_agents` | Управление другими агентами |
|
|
||||||
| `manage_projects` | Создание/изменение проектов |
|
|
||||||
|
|
||||||
### Конфигурация
|
|
||||||
Один бинарник, роль = конфиг (`agent.json`):
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "Кодер",
|
"name": "Кодер",
|
||||||
@ -190,236 +87,298 @@ MCP Client (Claude Code, Cursor) — это **человек с инструме
|
|||||||
"prompt": "Ты опытный разработчик...",
|
"prompt": "Ты опытный разработчик...",
|
||||||
"model": "sonnet",
|
"model": "sonnet",
|
||||||
"capabilities": ["coding", "review"],
|
"capabilities": ["coding", "review"],
|
||||||
"listen_mode": "mentions",
|
"chat_listen": "mentions",
|
||||||
|
"task_listen": "mentions",
|
||||||
"tracker_url": "http://localhost:8100",
|
"tracker_url": "http://localhost:8100",
|
||||||
"token": "tb-agent-xxx"
|
"token": "tb-agent-xxx"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Режимы прослушивания
|
### Listen Modes (раздельные)
|
||||||
- `listen: all` — слышит всё в чате (архитектор, PM)
|
- `chat_listen: all` — слышит все сообщения в чатах проекта
|
||||||
- `listen: mentions` — только при @упоминании (кодер, тестер)
|
- `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 (глухой агент)
|
||||||
При подключении к проекту агент получает контекст: README, docs, архитектуру.
|
LLM блокирующий — агент не слышит пока думает.
|
||||||
|
Решения: короткие задачи (5-10 мин) + проверка входящих между шагами.
|
||||||
|
|
||||||
### Memory
|
### Heartbeat и таймауты
|
||||||
Per-agent + per-project. Агент дописывает findings после задач.
|
- Агент шлёт `heartbeat` каждые 30 сек
|
||||||
|
- Нет heartbeat 90 сек → `status=offline`, уведомление в чат
|
||||||
|
- Незавершённые задачи → возвращаются в `todo`
|
||||||
|
- systemd перезапускает picogent, агент делает `session.resume`
|
||||||
|
|
||||||
### Что агент получает
|
## Проекты
|
||||||
Текстовые сообщения (максимум разговорной речи):
|
|
||||||
- `"Тебе назначена задача TB-42: Добавить авторизацию. Приоритет: high."`
|
|
||||||
- `"[чат проекта] @architect: Используй JWT для авторизации"`
|
|
||||||
- `"[комментарий к TB-42] @reviewer: В auth.py строка 42 не обработан expired token"`
|
|
||||||
|
|
||||||
Агент сам решает что делать — вызывает MCP tools.
|
|
||||||
|
|
||||||
### Label Matching
|
|
||||||
Задача имеет labels, агент поддерживает labels → автоматический matching для assign.
|
|
||||||
|
|
||||||
### Проблема "глухого агента" (Checkpoint Pattern)
|
|
||||||
LLM `query()` блокирующий — агент не слышит новых сообщений пока думает.
|
|
||||||
|
|
||||||
**Решения:**
|
|
||||||
- **Короткие задачи** — декомпозиция на шаги по 5-10 минут
|
|
||||||
- **Checkpoint pattern** — агент проверяет входящие между шагами работы
|
|
||||||
- **session.checkpoint** — агент сохраняет своё понимание контекста в Tracker, чтобы при сбое продолжить с того же места
|
|
||||||
|
|
||||||
### Зависший агент / Таймауты
|
|
||||||
- **Heartbeat** — агент шлёт `agent.heartbeat` каждые 30 секунд
|
|
||||||
- Если heartbeat не пришёл 90 секунд → `agent.status = offline`
|
|
||||||
- Уведомление в чат: "Агент X перестал отвечать"
|
|
||||||
- **Grace period**: при дисконнекте статус сначала `away` (60 сек), потом `offline`
|
|
||||||
- Незавершённые задачи: возвращаются в `todo` или ждут (зависит от политики)
|
|
||||||
- **Рестарт**: systemd перезапускает picogent, агент делает session.resume
|
|
||||||
|
|
||||||
### Reconnect и восстановление сессии
|
|
||||||
При реконнекте агент отправляет `session.resume` с `last_seq` (последнее известное сообщение). Tracker возвращает `context_summary` + пропущенные сообщения. Агент продолжает работу.
|
|
||||||
|
|
||||||
### Контракт агента (contract)
|
|
||||||
Описывает capabilities, лимиты и разрешённые tools:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"capabilities": ["coding", "review"],
|
|
||||||
"max_concurrent_tasks": 2,
|
|
||||||
"timeout_seconds": 600,
|
|
||||||
"tools": {"file_read": true, "git_commit": true, "shell_exec": false},
|
|
||||||
"limits": {"max_file_size_mb": 10, "max_files_per_task": 20}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
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) + сообщения чата
|
- **WebSocket** = real-time: события (push) + отправка сообщений в чат
|
||||||
- **REST (MCP tools)** = все мутации: задачи, этапы, файлы, статусы
|
- **REST (MCP tools)** = все мутации: задачи, steps, файлы, статусы
|
||||||
|
|
||||||
### WS Protocol
|
### WS: Клиент → Сервер
|
||||||
|
| Событие | Описание |
|
||||||
|
|---------|----------|
|
||||||
|
| `auth` | Токен + инфо агента |
|
||||||
|
| `heartbeat` | Статус (idle/busy) |
|
||||||
|
| `ack` | Подтверждение события |
|
||||||
|
| `chat.send` | Сообщение в чат |
|
||||||
|
| `project.subscribe` | Подписка на проект (чат + task events) |
|
||||||
|
| `project.unsubscribe` | Отписка |
|
||||||
|
|
||||||
**Инфраструктура:**
|
### WS: Сервер → Клиент
|
||||||
```
|
| Событие | Фильтрация |
|
||||||
Agent → Tracker: auth, heartbeat, ack
|
|---------|-----------|
|
||||||
Tracker → Agent: auth.ok, auth.error, event
|
| `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` | Всем |
|
||||||
|
|
||||||
**События (push):**
|
### Фильтрация событий на сервере
|
||||||
| Событие | В промпт? | |
|
Агент получает только релевантное:
|
||||||
|---------|-----------|--|
|
- **task events** → assignee + reviewer + watchers + task_listen:all
|
||||||
| task.assigned | ✅ | Текстом |
|
- **chat events** → chat_listen:all ИЛИ @mention
|
||||||
| chat.message | ✅/❌ | По listen_mode |
|
- Агенты с `task_listen:mentions` НЕ получают чужие task.created/updated
|
||||||
| task.comment (mention) | ✅ | Текстом |
|
|
||||||
| task.taken | ❌ | Internal |
|
|
||||||
| task.status_changed | ❌ | Internal (кроме разблокировки зависимости) |
|
|
||||||
|
|
||||||
### MCP Tools (REST)
|
|
||||||
| Tool | Описание |
|
|
||||||
|------|----------|
|
|
||||||
| get_task, list_tasks | Чтение задач |
|
|
||||||
| create_task | Создать задачу/подзадачу |
|
|
||||||
| update_task | Обновить поля |
|
|
||||||
| take_task | Взять себе (атомарно) |
|
|
||||||
| reject_task | Отклонить с причиной |
|
|
||||||
| add_step, complete_step | Управление этапами |
|
|
||||||
| add_comment | Комментарий (с mentions) |
|
|
||||||
| send_message | Сообщение в чат |
|
|
||||||
| upload_file, list_files | Файлы |
|
|
||||||
|
|
||||||
### Router (в Picogent)
|
### Router (в Picogent)
|
||||||
Тупой relay: WS event → текст → единственная сессия агента. Агент сам вызывает tools.
|
Тупой text relay: WS event → текстовое сообщение → единственная сессия агента.
|
||||||
|
Агент сам решает что делать — вызывает MCP tools.
|
||||||
|
|
||||||
### Межагентная коммуникация
|
## MCP Tools (REST API)
|
||||||
Агенты общаются через чат (send_message с @mention). Для структурированных запросов — протокол `agent.request` / `agent.response`:
|
|
||||||
```
|
|
||||||
Кодер → Tracker: agent.request {target: "reviewer", type: "code_review", payload: {pr_url}}
|
|
||||||
Tracker → Ревьюер: agent.request {from: "coder", request_id, payload}
|
|
||||||
Ревьюер → Tracker: agent.response {request_id, result: {approved, comments}}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Файловое хранилище
|
### Задачи
|
||||||
|
| Tool | Описание |
|
||||||
|
|------|----------|
|
||||||
|
| `list_tasks` | Список (фильтры: project, status, assignee, labels) |
|
||||||
|
| `get_task` | Получить задачу по ID/key |
|
||||||
|
| `create_task` | Создать |
|
||||||
|
| `update_task` | Обновить поля |
|
||||||
|
| `take_task` | Взять себе (атомарно) |
|
||||||
|
| `reject_task` | Отклонить с причиной |
|
||||||
|
| `assign_task` | Назначить другому |
|
||||||
|
| `delete_task` | Удалить |
|
||||||
|
|
||||||
- Per-project директории
|
### Steps
|
||||||
- Upload/download через REST API
|
| Tool | Описание |
|
||||||
- Связь с git repos (repo_urls[])
|
|------|----------|
|
||||||
- Версионирование файлов — TBD
|
| `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
|
## Git Workflow
|
||||||
|
|
||||||
### Принцип
|
- Агент клонирует repo, работает в ветке `{type}/{task-key}-{slug}`
|
||||||
- Агент клонирует repo в свою рабочую директорию
|
- По завершении → Merge Request в Gitea
|
||||||
- Работает в отдельной ветке: `{type}/{task-id}-{slug}` (feat/fix/refactor/docs)
|
- Ревью → approve/reject → автомерж
|
||||||
- По завершении → **Merge Request** в Gitea
|
- Конфликты решает MR owner. Макс 3 итерации, потом эскалация
|
||||||
- Ревью (агент/человек) → approve/reject
|
- Git tools НЕ в MCP — агент работает через git CLI
|
||||||
- **Автомерж** после approve
|
|
||||||
|
|
||||||
### Конфликты
|
## Промпты агентов
|
||||||
- Решает тот, чей MR. После разрешения — повторный review.
|
|
||||||
- Lock на файлы — **не нужен**
|
|
||||||
- Максимум 3 итерации ревью, потом эскалация к человеку
|
|
||||||
|
|
||||||
### Gitea интеграция
|
Многослойный промпт:
|
||||||
- Webhooks от Gitea → Tracker: push, PR opened/reviewed/merged
|
1. System Prompt (agent.json) — базовая роль, неизменная
|
||||||
- Tracker → Gitea API: создание веток, PR, комментирование
|
2. Agent Prompt (prompt.md) — агент сам улучшает
|
||||||
- PR merged → задача автоматически в Done
|
3. Project Context (docs) — документация
|
||||||
- CI/CD через Gitea Actions — автотесты на MR
|
4. Skills — progressive loading
|
||||||
|
5. Tools (MCP) — автоматически
|
||||||
|
6. Guidelines — общие правила
|
||||||
|
7. Session History
|
||||||
|
8. Current Message
|
||||||
|
|
||||||
### Ревью
|
Agent Home:
|
||||||
- Автор ≠ ревьюер (всегда)
|
```
|
||||||
- Не каждая задача требует PR (определяется лейблами: `coding` → PR, `analytics` → нет)
|
agents/coder/
|
||||||
- Все комментарии ревью в задаче (единый контекст)
|
agent.json # конфиг
|
||||||
|
prompt.md # само-улучшаемый промпт
|
||||||
|
memory/ # per-project память
|
||||||
|
workspace/ # рабочие файлы
|
||||||
|
sessions/ # сессии (JSONL)
|
||||||
|
```
|
||||||
|
|
||||||
## Telegram Bridge (MVP)
|
## Web UI (текущее состояние)
|
||||||
|
|
||||||
- Один бот, подключается по WS к Tracker как `client_type=bridge`
|
### Реализовано
|
||||||
- Дублирует сообщения из project chats в Telegram
|
- KanbanBoard (колонки, drag & drop)
|
||||||
- **Топики**: если в Telegram включены topics → бот пишет в топик с именем проекта (каждый проект = отдельный топик)
|
- TaskModal (title, description, status, priority, assignee, delete)
|
||||||
- Форматирование: `👤 Eugene: текст` / `🤖 Кодер: текст` / `⚙️ Задача #42 → in_progress`
|
- ChatPanel (lobby)
|
||||||
- **Telegram → Tracker**: сообщение из группы → `chat.send` с `sender_type=bridge`
|
- Sidebar, CreateProjectModal, AuthGuard, Login
|
||||||
- **Упоминания**: парсит `@slug` из Telegram → `mentions` в `chat.send`
|
|
||||||
- Системные события (task.created, task.updated) → уведомления в группу
|
|
||||||
- ⚠️ Ограничение Telegram: боты НЕ видят сообщения других ботов → один бот = bridge для всех
|
|
||||||
|
|
||||||
## Безопасность
|
### Следующие шаги
|
||||||
|
1. Комментарии в TaskModal (Message с task_id)
|
||||||
|
2. Steps в TaskModal (live-прогресс агента)
|
||||||
|
3. Agent management (генерация токенов)
|
||||||
|
4. Dashboard проекта
|
||||||
|
|
||||||
- **Аутентификация**: токены (прописываются при регистрации агента). Каждый агент = уникальный токен.
|
## Telegram Bridge (будущее)
|
||||||
- **Роли и permissions**: owner / agent / bridge / observer (см. раздел Агенты)
|
- Один бот, WS к tracker как bridge
|
||||||
- **Capabilities enforcement**: агент с capabilities=["code"] не получит задачи на review
|
- Топики в Telegram = проекты
|
||||||
- **Rate limiting** — планируется: chat.send 30/min, task.progress 10/min и т.д.
|
- Формат: `👤 Eugene: текст` / `🤖 Кодер: текст`
|
||||||
- **Audit log** — планируется: логирование всех действий
|
|
||||||
- **Token rotation** — планируется: ротация каждые 30 дней
|
|
||||||
|
|
||||||
## Версионирование API
|
|
||||||
|
|
||||||
- REST API: `/api/v1/`, `/api/v2/`
|
|
||||||
- Обратная совместимость при обновлении
|
|
||||||
- WS Protocol: версия в auth handshake
|
|
||||||
|
|
||||||
## Деплой
|
## Деплой
|
||||||
|
- Tracker: Docker Compose (+ PostgreSQL)
|
||||||
- **Tracker + BFF + Web Client**: Docker Compose
|
- BFF + Web Client: systemd на хосте
|
||||||
- **Picogent**: systemd сервис (один процесс на агента)
|
- Picogent: systemd (один процесс на агента)
|
||||||
- Автоматический restart при падении (systemd)
|
- CI/CD: Gitea Actions
|
||||||
- CI/CD: Gitea Actions auto-deploy
|
|
||||||
- Агент-DevOps возможен для CI/CD задач
|
|
||||||
|
|
||||||
## На будущее
|
## На будущее
|
||||||
|
- **Web MCP Server** — любой LLM-клиент работает с трекером через MCP
|
||||||
- **Web MCP Server** — отдельный пакет (`team-board/mcp-server`), любой LLM-клиент (Claude Code, Cursor, Windsurf, Cline, OpenClaw) работает с трекером через MCP без WebSocket и без Picogent. Использует тот же REST API. Не автономный (нет push-событий), но полностью функциональный.
|
- **Redis Streams** — event bus для масштабирования (если понадобится)
|
||||||
- **Multi-instance агентов** — scaling, несколько кодеров одного типа. Вопрос: slug = роль, instance_id = отдельно? Требует продумывания.
|
- **Multi-instance агентов** — scaling
|
||||||
- **Аналитика** — метрики, дашборды (tasks/hour, avg task duration, agent utilization)
|
|
||||||
- **OAuth / Authentik** — мульти-пользователь
|
- **OAuth / Authentik** — мульти-пользователь
|
||||||
- **Notification Bridge** — отдельный bridge-агент, подключается по WS, пушит уведомления за пределы чата (email, push, webhooks)
|
- **Session Compaction** — сжатие контекста при превышении лимита
|
||||||
- **Agent SDK** — Python-пакет (`team-board-sdk`) с базовым классом Agent, обработчиками on_task/on_chat/on_reconnect, интеграцией с git
|
|
||||||
- **Session Compaction** — при превышении контекста (50K токенов) сжатие истории в summary + recent window
|
|
||||||
- **Event Sourcing** — вся работа агента как поток событий для воспроизведения и восстановления состояния
|
|
||||||
|
|
||||||
## Конкурентный анализ (референсы)
|
## Открытые вопросы
|
||||||
|
- Лейблы: глобальные или per-project?
|
||||||
|
- Реакции в чатах: как обрабатывать?
|
||||||
|
- Multi-instance: slug = роль, instance_id?
|
||||||
|
- Rollback файлов (attachments не версионированы)
|
||||||
|
|
||||||
| Система | Ключевые идеи | Что забираем |
|
## Устаревшие документы
|
||||||
|---------|---------------|-------------|
|
- `WS-PROTOCOL.md` — заменён BRAINSTORM-WS-V2-2026-02-22.md
|
||||||
| **MetaGPT** | Промпты ролей (PM, Architect, Engineer, QA), pub/sub между ролями, SOP | Промпты для назначения ролей агентам |
|
- `AGENTS-INTEGRATION.md` — заменён ARCHITECTURE.md
|
||||||
| **Claude Flow / Ruflo** | Claims (атомарное взятие задач), swarm топологии, multi-provider | Паттерн claims для task.take |
|
|
||||||
| **BMAD Method** | Brainstorming workflow, party mode (мульти-ролевой prompt) | Workflow для планирования |
|
|
||||||
| **OpenHands** | Event sourcing, Docker sandbox, event log replay | Воспроизводимость сессий |
|
|
||||||
| **LangGraph** | State machine + persistent checkpointing | Checkpoint pattern |
|
|
||||||
| **CrewAI** | Role-based delegation, task routing по ролям | Capabilities matching |
|
|
||||||
| **Devin** | VM-sandbox, persistent sessions (часы), полный git цикл | Долгие сессии с checkpoints |
|
|
||||||
|
|
||||||
### Picogent vs Runner
|
|
||||||
Picogent (Node.js, TypeScript, Pi Agent Core) **заменяет** runner/ — более зрелая реализация. In-process agent loop, dual transport (HTTP + WebSocket), skills, sessions, sandbox, directory mode.
|
|
||||||
|
|
||||||
## Идеи на подумать
|
|
||||||
|
|
||||||
### ⚠️ Требуют отдельного обсуждения
|
|
||||||
- **Rollback файлов**: git revert очевиден, но файлы в хранилище **не версионированы**. Нужно ли версионирование файлов или хотя бы бэкап перед изменением?
|
|
||||||
- **Реакции в чатах**: выглядит круто, но жрёт токены. Варианты: (a) не попадают в промпт агента, (b) агент ставит через MCP tool, (c) попадают только @mention-reactions. Решение TBD.
|
|
||||||
- **Лейблы глобальные или per-project?** — не решено
|
|
||||||
- **Формат скилла для Runner'ов** — как описать взаимодействие агента с Tracker
|
|
||||||
- **Как агент определяет релевантность задачи для себя?** — auto-assign vs manual
|
|
||||||
- **Workspace агентов: общий или изолированный?**
|
|
||||||
- **Прогресс работы агента в реалтайме** (streaming в UI)
|
|
||||||
|
|
||||||
### 💡 Идеи на будущее
|
|
||||||
- **Agent SDK v1.0** — Python-пакет с базовым классом, git-хелперами, LLM-интерфейсом
|
|
||||||
- **Redis Streams** для event bus (горизонтальное масштабирование Tracker)
|
|
||||||
- **Structured inter-agent requests** (agent.request/response) для code review, delegation
|
|
||||||
- **task.offer / task.accept / task.decline** — Tracker предлагает задачу, агент может отклонить (HYBRID модель)
|
|
||||||
- **Compaction сессий** — server-side или agent-side сжатие контекста
|
|
||||||
- **Grafana dashboard**: WS connections, task flow, agent utilization
|
|
||||||
- **Token rotation** (30 дней) + per-agent capability enforcement
|
|
||||||
- **Docker containers per agent** для sandbox isolation
|
|
||||||
- **Gitea webhook handler** в Tracker для автоматизации git-событий
|
|
||||||
- **HTTP Callback** как альтернативный транспорт (Tracker POST'ит события на URL агента)
|
|
||||||
- **Агент создаёт проект** — Архитектор может создать проект через API
|
|
||||||
- **Subscription modes**: `all` / `mentions` / `assigned` (разные уровни вовлечения)
|
|
||||||
|
|
||||||
### ❌ Отклонено (из брейншторма)
|
|
||||||
- Шаблоны задач / проектов — не нужны
|
|
||||||
- Forking проектов — не нужен
|
|
||||||
- Автостатус задач — не нужен
|
|
||||||
- Оценка сложности / дедлайны — не нужны
|
|
||||||
- Lock на файлы — не нужен
|
|
||||||
- Бюджет в токенах — нет
|
|
||||||
- Приватность проектов — агент не трогает чужое
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user