docs/IDEAS.md

27 KiB
Raw Blame History

Team Board — Идеи и концепция

Суть проекта

Team Board — платформа для управления командой AI-агентов, работающих над проектами.

Ключевая идея: Несколько AI-агентов работают как команда разработчиков. Человек видит всё: задачи, код, переписку. Полная прозрачность.


Проблема, которую решаем

Один универсальный AI-ассистент:

  • Контекст переполняется при разных задачах
  • Сложно параллельно вести несколько направлений
  • Нет специализации — один промпт на всё

Решение: Команда специализированных агентов, каждый со своей ролью и контекстом.


Архитектура: Tracker-Centric

Принцип

Tracker = центральный сервис. Всё остальное — клиенты.

┌─────────────────────────────────────────────────────┐
│              WEB CLIENT                              │
│  ┌───────────┐     ┌────────────┐                   │
│  │  Next.js  │ ←→  │  BFF       │  (свой бэкенд)   │
│  │  фронтенд │     │  Python    │                   │
│  └───────────┘     │  + Authentik│                   │
│                    └─────┬──────┘                    │
└──────────────────────────┼──────────────────────────┘
                           │ ws (внутренняя сеть)
              ┌────────────▼────────────┐
              │        TRACKER          │
              │    (внутренний сервис)   │
              │    НЕ выставлен наружу   │
              │                         │
              │  - проекты              │
              │  - доски (канбан)       │
              │  - задачи + подзадачи   │
              │  - чаты                 │
              │  - события              │
              │  - БД (PostgreSQL)      │
              └────────────┬────────────┘
                           │ ws
         ┌─────────────────┼─────────────────┐
         ▼                 ▼                 ▼
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│  Агент 1     │  │  Агент 2     │  │  Агент N     │
│  (Claude)    │  │  (Codex)     │  │  (Gemini)    │
│  отд. сервис │  │  отд. сервис │  │  отд. сервис │
└──────────────┘  └──────────────┘  └──────────────┘

Компоненты

Компонент Описание
Tracker Ядро: проекты, задачи, чаты, события. Внутренний, WebSocket сервер
Web Client Next.js + BFF (Python). Авторизация через Authentik. Единственное что торчит наружу
Агенты Отдельные сервисы. Подключаются к трекеру по WebSocket

Репозитории

team-board/
├── tracker/      — ядро (Python, WebSocket, PostgreSQL)
├── web-client/   — Next.js + BFF
└── docs/         — документация

Агенты — отдельные репозитории (шаблон + конкретные).


Канбан-доска

Колонки

┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Backlog  │ │   TODO   │ │ In Prog  │ │  Review  │ │   Done   │
├──────────┤ ├──────────┤ ├──────────┤ ├──────────┤ ├──────────┤
│ [draft]  │ │ [ready]  │ │ [active] │ │ [review] │ │[complete]│
│ [draft]  │ │ [ready]  │ │          │ │          │ │[complete]│
│          │ │          │ │          │ │          │ │          │
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘

Статусы задач

Статус Описание
draft Черновик. Можно обсуждать, но не выполнять
ready Готова к выполнению. Перенос из Backlog → TODO автоматически ставит этот статус
in_progress Агент взял в работу
review На ревью у другого агента
completed Выполнена
blocked Заблокирована зависимостью

Жизненный цикл задачи

1. Человек создаёт задачу → draft (Backlog)
2. Обсуждение в чате проекта
3. Человек перетаскивает в TODO → статус меняется на ready
4. Агент берёт задачу → in_progress
5. Агент завершает → review
6. Ревьюер проверяет → completed / возврат в in_progress

Задачи

Структура задачи

Задача:
  id: uuid
  проект: project_id
  название: "Реализовать API авторизации"
  описание: "Markdown текст с деталями"
  статус: draft | ready | in_progress | review | completed | blocked
  
  # Лейблы (как в Jira — произвольные, создаются в трекере)
  лейблы: ["coding", "api", "backend", "urgent"]
  
  # PR (вручную или по лейблу)
  требует_pr: true | false
  
  # Назначение
  назначен: agent_id (или null)
  
  # Вложенные файлы
  файлы:
    - name: "schema.sql"
      type: "text/sql"
      content: "..."
    - name: "mockup.png"
      type: "image/png"
      url: "/files/task-123/mockup.png"
  
  # Подзадачи (неограниченная вложенность)
  подзадачи:
    - название: "Написать модели"
      назначен: agent-coder
      статус: completed
    - название: "Code review"
      назначен: agent-reviewer
      статус: in_progress
  
  # Зависимости
  зависит_от: [task_id_1, task_id_2]
  блокирует: [task_id_3]
  
  # Мета
  приоритет: low | medium | high | critical
  теги: ["api", "auth"]
  создано: timestamp
  обновлено: timestamp

Зависимости задач

Task A ──depends_on──→ Task B
         │
         └─ Task A НЕ может быть взята пока Task B не completed

Пример:
  "Написать тесты" зависит от "Написать код"
  "Деплой" зависит от "Тесты пройдены"

Правила:

  • Задача со статусом blocked не может быть взята агентом
  • Когда зависимость завершена → автоматически разблокировать
  • Циклические зависимости запрещены (валидация при создании)
  • В UI: визуальная связь между задачами (стрелки)

Приложенные файлы

  • К задаче можно прикрепить файлы (код, изображения, документы)
  • Агент может добавлять файлы к задаче (результаты работы)
  • Файлы хранятся на диске, метаданные в БД
  • Превью для изображений и кода в UI

Чаты

Три уровня

1. Лобби (общий чат)

Отдельная сущность, не привязан к проекту:

  • Обсуждение идей с агентами
  • Аналитика, brainstorm
  • Агент может создавать файлы, заметки
  • Место для обсуждения до создания проекта

2. Чат проекта

У каждого проекта свой чат:

  • Обсуждение задач
  • Системные уведомления (задача создана, завершена, etc.)
  • Агенты видят только чаты своих проектов

3. Комментарии задачи

Внутри каждой задачи:

  • Обсуждение деталей
  • Код ревью
  • Результаты подзадач

Агенты и адаптеры

Адаптер (провайдер)

Адаптер — это подключение к конкретной нейросети. Один адаптер может использоваться несколькими агентами.

Адаптер:
  id: uuid
  название: "Claude Opus"
  провайдер: anthropic | openai | google | openclaw | cli
  
  # Конфиг — JSON поле, разное для каждого провайдера
  config:
    # Anthropic
    api_key: "sk-ant-..."
    model: "claude-opus-4-5"
    max_tokens: 8192
    
    # Или OpenAI
    api_key: "sk-..."
    model: "gpt-4"
    organization: "org-..."
    
    # Или OpenClaw
    gateway_url: "http://localhost:18789"
    gateway_token: "..."
    agent_id: "main"
    
    # Или CLI
    command: "claude"
    working_dir: "/workspace"
  
  # Возможности адаптера (что умеет эта нейросеть)
  capabilities: ["coding", "analytics", "review", "design", "docs", "testing"]

Важно: Capabilities привязаны к адаптеру, не к агенту. Потому что возможности определяются нейросетью.

Агент

Агент — это "личность" с ролью, которая использует адаптер.

Агент:
  id: uuid
  имя: "Кодер"
  slug: "coder"
  
  # Привязка к адаптеру
  адаптер_id: uuid
  
  # Роль
  системный_промпт: "Ты — backend разработчик..."
  
  # Подписка
  подписка:
    режим: mentions    # all | mentions | assigned
    проекты: ["*"]     # или конкретные
  
  # Ограничения
  макс_параллельных: 2
  таймаут: 600  # секунд

Лейблы

Произвольные метки, создаются в трекере (как в Jira):

CREATE TABLE labels (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name TEXT UNIQUE NOT NULL,   -- "coding", "design", "urgent"
    color TEXT,                  -- "#ff0000"
    created_at TIMESTAMPTZ DEFAULT NOW()
);

Примеры: coding, design, analytics, testing, docs, backend, frontend, urgent, bug

Связка: лейблы задач ↔ capabilities адаптеров

Задача с лейблом "coding" → только агенты с адаптером, у которого capability "coding"
Задача с лейблом "design" → только агенты с адаптером, у которого capability "design"

Агент-дизайнер НЕ возьмёт задачу с лейблом codingу его адаптера нет такой capability.

Типы провайдеров

Провайдер Описание Конфиг
anthropic Claude API api_key, model, max_tokens
openai GPT, Codex api_key, model, organization
google Gemini api_key, model
openclaw OpenClaw Gateway gateway_url, gateway_token, agent_id
cli Claude Code CLI command, working_dir

Подписка на события

Режим Агент получает
all Все сообщения в подписанных проектах
mentions Только когда @упомянут
assigned Назначенные задачи + mentions

WebSocket протокол

Трекер → Клиент

task.created    — задача создана
task.updated    — задача обновлена
task.ready      — задача готова к выполнению (перенесена из Backlog)
task.assigned   — задача назначена агенту
task.blocked    — задача заблокирована зависимостью
task.unblocked  — зависимость выполнена, задача разблокирована
chat.message    — новое сообщение в чате
agent.status    — статус агента изменился
file.attached   — файл прикреплён к задаче

Клиент → Трекер

task.take       — агент берёт задачу
task.complete   — агент завершил задачу
task.comment    — комментарий к задаче
task.attach     — прикрепить файл
chat.send       — отправить сообщение в чат
agent.register  — регистрация агента
agent.heartbeat — пульс

Ревью и PR

Не каждая задача = PR

PR нужен когда задача связана с кодом. Определяется вручную или по лейблам:

  • Лейбл coding / testingтребует_pr = true (по умолчанию)
  • Лейбл design / analyticsтребует_pr = false
  • Можно переопределить вручную

Флоу ревью (для задач с PR)

1. Агент работает → коммитит в feature branch
2. Создаёт PR в Gitea
3. Сдвигает задачу в Review
4. Трекер назначает ревьюера (другой агент, НЕ автор)
5. Ревьюер смотрит PR, пишет комментарии В ЗАДАЧЕ
6. Ок → Approve → Done, PR мержится
7. Не ок → замечания → обратно In Progress → автор исправляет

Флоу ревью (для задач без PR)

1. Агент работает → прикрепляет результат (файл/отчёт) к задаче
2. Сдвигает в Review
3. Ревьюер проверяет результат
4. Ок → Done
5. Не ок → замечания → обратно In Progress

Правила ревью

  • Автор ≠ ревьюер (всегда)
  • Максимум 3 итерации — потом эскалация к человеку
  • Все комментарии в задаче (единый контекст)
  • Чат проекта = лог событий (всё видно)

Итерации ревью

review_history:
  - iteration: 1
    reviewer: analyst
    status: changes_requested
    comments: ["Нужна валидация", "Нет тестов"]
  - iteration: 2
    reviewer: analyst
    status: approved

Workflow: от идеи до деплоя

Фаза 1: Идея → Проект

  1. Человек открывает Лобби
  2. Обсуждает идею с агентом-аналитиком
  3. Создаёт проект
  4. Агент формирует BRIEF.md, REQUIREMENTS.md

Фаза 2: Декомпозиция → Задачи

  1. На основе требований создаются задачи (черновики в Backlog)
  2. Расставляются зависимости
  3. Прикрепляются файлы (макеты, схемы)
  4. Обсуждение в чате проекта
  5. Готовые задачи переносятся в TODO

Фаза 3: Выполнение

  1. Задача в TODO → агент берёт → In Progress
  2. Агент работает, коммитит, прикрепляет файлы
  3. Создаёт подзадачу "Ревью" → другому агенту
  4. Итерации до готовности
  5. Задача → Done

Фаза 4: Ревью и деплой

  1. Автоматические проверки (CI/CD)
  2. Ревью агентом или человеком
  3. Деплой

Инфраструктура (уже есть)

Сервис Описание
PostgreSQL База данных
Thoth STT/TTS (голос↔текст)
Authentik SSO для веб-интерфейса
Nginx + certbot Домены и SSL
Gitea Git хостинг
OpenClaw (Марков) Главный агент с инструментами
Redis Очереди и pub/sub

База данных (ключевые таблицы)

-- Адаптеры (подключения к нейросетям)
CREATE TABLE adapters (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name TEXT NOT NULL,
    provider TEXT NOT NULL,       -- anthropic, openai, google, openclaw, cli
    config JSONB NOT NULL,        -- всё специфичное для провайдера
    capabilities TEXT[] NOT NULL, -- ["coding", "analytics", "review", ...]
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Агенты (личности с ролями)
CREATE TABLE agents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name TEXT NOT NULL,
    slug TEXT UNIQUE NOT NULL,
    adapter_id UUID REFERENCES adapters(id),
    system_prompt TEXT,
    subscription_mode TEXT DEFAULT 'mentions',  -- all, mentions, assigned
    max_concurrent INT DEFAULT 1,
    timeout_seconds INT DEFAULT 600,
    status TEXT DEFAULT 'idle',
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Задачи
CREATE TABLE tasks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    project_id UUID REFERENCES projects(id),
    parent_id UUID REFERENCES tasks(id),  -- подзадачи
    title TEXT NOT NULL,
    description TEXT,
    status TEXT DEFAULT 'draft',
    -- лейблы через связующую таблицу task_labels
    requires_pr BOOLEAN DEFAULT FALSE,
    assigned_agent_id UUID REFERENCES agents(id),
    priority TEXT DEFAULT 'medium',
    pr_url TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Зависимости задач
CREATE TABLE task_dependencies (
    task_id UUID REFERENCES tasks(id) ON DELETE CASCADE,
    depends_on_id UUID REFERENCES tasks(id) ON DELETE CASCADE,
    PRIMARY KEY (task_id, depends_on_id)
);

-- Лейблы
CREATE TABLE labels (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name TEXT UNIQUE NOT NULL,
    color TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Связка задач и лейблов
CREATE TABLE task_labels (
    task_id UUID REFERENCES tasks(id) ON DELETE CASCADE,
    label_id UUID REFERENCES labels(id) ON DELETE CASCADE,
    PRIMARY KEY (task_id, label_id)
);

-- Файлы задач
CREATE TABLE task_files (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    task_id UUID REFERENCES tasks(id) ON DELETE CASCADE,
    filename TEXT NOT NULL,
    mime_type TEXT,
    file_path TEXT NOT NULL,
    uploaded_by UUID,  -- agent_id или null (человек)
    created_at TIMESTAMPTZ DEFAULT NOW()
);

Управление агентами (Agent Manager)

Принцип

Агент = отдельный процесс. Не привязан к OpenClaw или конкретному серверу. Может быть запущен локально, на другом сервере, в Docker — где угодно. Подключается к Tracker по WebSocket.

Архитектура

┌─────────────────────────┐
│     Agent Process        │
│  ┌───────────────────┐  │
│  │  Agent SDK         │  │  ← общая Python-библиотека
│  │  ┌──────────────┐ │  │
│  │  │   Adapter     │ │  │  ← OpenClaw / OpenAI / Ollama / CLI
│  │  └──────────────┘ │  │
│  └─────────┬─────────┘  │
└────────────┼────────────┘
             │ WebSocket (локально или через интернет)
      ┌──────┴──────┐
      │   Tracker    │
      │ AgentManager │
      └─────────────┘

Agent SDK (Python-пакет)

Общая библиотека для всех агентов:

from team_board.agent import Agent
from team_board.adapters import OpenClawAdapter

adapter = OpenClawAdapter(
    gateway_url="http://localhost:18789",
    gateway_token="...",
)

agent = Agent(
    name="Кодер",
    tracker_url="ws://localhost:8100",
    adapter=adapter,
    system_prompt="Ты — backend разработчик...",
)

agent.run()  # подключается к Tracker, слушает задачи

Что делает SDK:

  • WebSocket клиент → подключение к Tracker, переподключение при разрыве
  • Heartbeat → автоматический пинг каждые N секунд
  • Обработка задач → получил задачу → передал адаптеру → вернул результат
  • Файловые операции → загрузка/скачивание файлов задачи

Адаптеры (BaseAdapter)

class BaseAdapter(ABC):
    @abstractmethod
    async def send(self, messages: list[Message]) -> Response:
        """Отправить сообщения нейросети и получить ответ."""
        ...

    @abstractmethod
    async def capabilities(self) -> list[str]:
        """Возвращает capabilities адаптера."""
        ...

Реализации:

Адаптер Подключение Особенности
OpenClawAdapter Webhooks / sessions_spawn Доступ к инструментам OpenClaw
AnthropicAdapter Claude API напрямую Чистый API, без инструментов
OpenAIAdapter GPT / Codex API
OllamaAdapter Локальная модель Бесплатно, офлайн
CLIAdapter Claude Code CLI Доступ к файловой системе

AgentManager (в Tracker)

Tracker управляет жизненным циклом агентов:

Реестр агентов:
  - id: uuid
    name: "Кодер"
    adapter: "Claude Opus"
    status: online | offline | busy | dead
    host: "localhost"           # где запущен
    pid: 12345                  # PID процесса (если локальный)
    last_heartbeat: timestamp
    current_tasks: [task_id]

Функции AgentManager:

  1. Запуск — поднимает агента как отдельный процесс (локально: subprocess/systemd)
  2. Мониторинг — следит за heartbeat, помечает dead если пропал
  3. Перезапуск — dead агент → повторный запуск (макс 3 попытки)
  4. Назначение задач — матчит задачу → подходящего агента по capabilities + загрузке
  5. Остановка — graceful shutdown через WebSocket команду

Запуск агентов

Локально (MVP):

# Tracker запускает как subprocess
python -m team_board.agent --name coder --tracker ws://localhost:8100

Через systemd (production):

[Unit]
Description=Team Board Agent: Coder

[Service]
ExecStart=/opt/team-board/venv/bin/python -m team_board.agent --name coder
Restart=on-failure
RestartSec=5

Удалённо (будущее):

  • SSH: ssh remote-host 'python -m team_board.agent --tracker ws://tracker:8100'
  • Docker: docker run team-board-agent --tracker ws://tracker:8100
  • HTTP API на удалённом хосте

Heartbeat и мониторинг

Агент → Tracker: agent.heartbeat (каждые 30 сек)
  {
    status: "idle" | "busy",
    current_tasks: [...],
    uptime: 3600,
    memory_mb: 150
  }

Если heartbeat не пришёл 90 секунд → статус = dead → перезапуск

Таблица БД

-- Расширение таблицы agents
ALTER TABLE agents ADD COLUMN host TEXT DEFAULT 'localhost';
ALTER TABLE agents ADD COLUMN pid INT;
ALTER TABLE agents ADD COLUMN last_heartbeat TIMESTAMPTZ;
ALTER TABLE agents ADD COLUMN restart_count INT DEFAULT 0;
ALTER TABLE agents ADD COLUMN max_restarts INT DEFAULT 3;

Открытые вопросы

  1. Как интегрировать CLI-агентов (Claude Code, Cline)?
  2. Workspace для агентов — общий или изолированный?
  3. Прогресс работы агента в реалтайме?
  4. Биллинг/учёт использования API?
  5. Шаблоны агентов — как быстро создать нового?

Приоритеты реализации

  1. Tracker: базовый WebSocket сервер
  2. Tracker: проекты, задачи, подзадачи
  3. Tracker: зависимости задач
  4. Tracker: чаты (лобби + проект)
  5. Tracker: файлы в задачах
  6. Web Client: авторизация (Authentik)
  7. Web Client: канбан-доска
  8. Web Client: чат
  9. Шаблон агента
  10. Подключение первого агента (OpenClaw)

Документ для обсуждения и аналитики. Обновляется по мере развития идей.