# Multi-Agent Orchestrator FastAPI-сервис для оркестрации мульти-агентного пайплайна разработки. Принимает webhooks от Plane и Gitea, управляет жизненным циклом задач через Quality Gates, запускает Claude CLI агентов на каждой стадии. ## Архитектура ``` Plane (task mgmt) ──webhook──┐ ├──► Orchestrator (FastAPI) ──► Quality Gates ──► Agent Launcher Gitea (git events) ─webhook──┘ │ │ ▼ ▼ SQLite DB Claude CLI (events, tasks, (analyst, architect, agent_runs) developer, reviewer, tester) ``` ## Стадии пайплайна ``` created → analysis → architecture → development → review → testing → deploy → done ↑ │ └─── REQUEST_CHANGES ─┘ (max 3 retries) ``` | Стадия | Агент | Quality Gate (выход) | Триггер перехода | |--------|-------|---------------------|------------------| | created | — | — | Plane webhook (work_item.created) | | analysis | analyst | Файлы BRD/TRZ/AC/TestPlan | Push docs/ | | architecture | architect | ADR или infra-requirements | Push docs/ | | development | developer | CI green | Gitea status event | | review | reviewer | PR approved (no stale) | Gitea review event | | testing | tester | Test report с PASS | Auto-advance после tester | | deploy | — | — | PR merge | | done | — | — | — | ## API Endpoints | Method | Path | Описание | |--------|------|----------| | GET | `/health` | Health check | | GET | `/status` | Активные задачи (stage != done) | | POST | `/webhook/plane` | Plane webhook receiver | | POST | `/webhook/gitea` | Gitea webhook receiver | ## Структура проекта ``` src/ ├── main.py # FastAPI app, lifespan (orphan recovery) ├── config.py # Pydantic settings (env vars) ├── db.py # SQLite: init, get_db, update_task_stage ├── stages.py # State machine (transitions, agents, QG) ├── notifications.py # Уведомления (логирование) ├── plane_sync.py # Синхронизация статусов с Plane API ├── agents/ │ └── launcher.py # AgentLauncher: launch, monitor, watchdog, auto-advance ├── webhooks/ │ ├── plane.py # Plane webhook handler │ └── gitea.py # Gitea webhook handler (push, PR, CI status) └── qg/ └── checks.py # Quality Gate checks (filesystem + Gitea API) data/ ├── orchestrator.db # SQLite database └── runs/ # Agent output logs ({run_id}.log) docs/ ├── ARCHITECTURE.md # Подробная архитектура ├── LESSONS_ET006.md # Lessons learned из ET-006 ├── BUGFIXES_2026-05-21.md # Багфиксы └── SETUP_WEBHOOKS.md # Настройка webhooks docker-compose.yml # Deployment config Dockerfile # Python 3.12 + Docker CLI + tini ``` ## Запуск ### Docker (production) ```bash docker compose up -d --build ``` ### Dev ```bash pip install -r requirements.txt uvicorn src.main:app --reload --port 8500 ``` ## Конфигурация Все переменные с префиксом `ORCH_`: | Переменная | Описание | Default | |-----------|----------|---------| | `ORCH_PLANE_API_URL` | Plane API URL | `http://localhost:8091` | | `ORCH_PLANE_API_TOKEN` | Plane API token | — | | `ORCH_PLANE_WEBHOOK_SECRET` | Webhook secret | — | | `ORCH_PLANE_WORKSPACE_SLUG` | Workspace slug | — | | `ORCH_PLANE_PROJECT_ID` | Project UUID | — | | `ORCH_GITEA_URL` | Gitea URL | `http://localhost:3000` | | `ORCH_GITEA_TOKEN` | Gitea API token | — | | `ORCH_GITEA_WEBHOOK_SECRET` | Gitea webhook secret | — | | `ORCH_GITEA_OWNER` | Gitea repo owner | `admin` | | `ORCH_DEFAULT_REPO` | Default repository | `enduro-trails` | | `ORCH_CLAUDE_BIN` | Путь к Claude CLI | `/opt/claude-code/bin/claude.exe` | | `ORCH_REPOS_DIR` | Repos dir (container) | `/repos` | | `ORCH_HOST_REPOS_DIR` | Repos dir (host) | `/home/slin/repos` | | `ORCH_DB_PATH` | SQLite path | `/app/data/orchestrator.db` | ## Ключевые механизмы ### Auto-advance После успешного завершения агента (exit_code=0), `_try_advance_stage()` проверяет QG и автоматически продвигает задачу + запускает следующего агента. ### Review bounce При REQUEST_CHANGES от reviewer задача откатывается в development, developer перезапускается (до 3 попыток). При исчерпании — эскалация. ### Orphan recovery При старте контейнера все runs с `finished_at IS NULL` старше 35 минут помечаются как failed (exit_code=-1). ### Watchdog Каждый агент имеет timeout 30 минут. При превышении — SIGKILL + запись exit_code=-9. ### Event routing Gitea events роутятся по типу: - `push` → проверка файлов, advance architecture/development - `pull_request*` (wildcard) → review approved/rejected, PR merge - `status` → CI green/failure ## Тесты ```bash pytest tests/ -v ``` ## Известные ограничения 1. **Single-task** — одновременно обрабатывается одна задача на репозиторий (нет параллелизма) 2. **Plane sync** — маппинг issue ID может быть некорректным (P3, в работе) 3. **Tester timeout** — e2e тесты с Playwright могут занимать >25 мин на тяжёлых фичах 4. **No retry on API errors** — httpx вызовы к Gitea/Plane без retry logic