11 KiB
DEV TASK: orchestrator — живой Telegram-трекер задачи (Вариант B+)
Репо: slin@82.22.50.71:/home/slin/repos/orchestrator (пароль motoZ@yaz2010).
Push в main запрещён (pre-receive hook) → только PR в Gitea.
Gitea токен: docker exec orchestrator printenv ORCH_GITEA_TOKEN.
Одна ветка feat/telegram-live-tracker от актуального main, один PR.
Baseline pytest: 243 passed + 10 failed (10 = off-limits HMAC/401, НЕ чинить).
После: passed вырасти (новые тесты), те же 10 failed.
ЦЕЛЬ
Сейчас orchestrator шлёт в Telegram ~15 отдельных сообщений на задачу (src/notifications.py):
старт каждого агента, завершение, переход стадии, QG-pending-шум, тех-мусор (run_id, exit_code,
пути логов), устаревший «:approved:». Простыня.
Заменить на ОДНО живое сообщение-трекер на задачу, которое редактируется (editMessageText)
на каждой стадии. Отдельными сообщениями с пингом слать только то, что требует внимания Славы.
МАКЕТ ТРЕКЕРА (точный формат)
В процессе (текущая стадия — 🔄 … идёт):
🛠️ ET-012 · Треки с зума z5
━━━━━━━━━━━━━━━━━━━━━━
✅ Analysis 10м · 1.1M↓/39.6k↑ · $2.38 · opus-4-8
⏸️ Ревью БРД 8м · твоё время ⏳
✅ Architecture 9м · 1.5M↓/34.4k↑ · $2.24 · opus-4-8
✅ Development 11м · 8.4M↓/45.8k↑ · $7.29 · opus-4-8
✅ Review 3м · 1.2M↓/12.9k↑ · $1.53 · sonnet-4.6
✅ Testing 5м · 1.2M↓/19.5k↑ · $1.51 · sonnet-4.6
🔄 Deploy … · идёт
━━━━━━━━━━━━━━━━━━━━━━
💰 15.1M↓ / 174.6k↑ · $16.68
На финише (заголовок 🎉 … — ГОТОВО, добавляются строки времени и ссылки):
🎉 ET-012 · Треки с зума z5 — ГОТОВО
━━━━━━━━━━━━━━━━━━━━━━
✅ Analysis 10м · 1.1M↓/39.6k↑ · $2.38 · opus-4-8
⏸️ Ревью БРД 8м · твоё время
✅ Architecture 9м · 1.5M↓/34.4k↑ · $2.24 · opus-4-8
✅ Development 11м · 8.4M↓/45.8k↑ · $7.29 · opus-4-8
✅ Review 3м · 1.2M↓/12.9k↑ · $1.53 · sonnet-4.6
✅ Testing 5м · 1.2M↓/19.5k↑ · $1.51 · sonnet-4.6
✅ Deploy 6м · 1.6M↓/22.4k↑ · $1.73 · opus-4-8
━━━━━━━━━━━━━━━━━━━━━━
💰 15.1M↓ / 174.6k↑ · $16.68
⏱️ Всего 56м · агенты 44м · твоё 8м
🔗 PR #24 · 📦 deployed
Правила формата (согласованы со Славой):
- Токены на этап: in/out РАЗДЕЛЬНО —
<in>↓/<out>↑, гдеin = input_tokens + cache_read_tokens + cache_creation_tokens(полный вход, как в usage.py fix #20 — переиспользуй_input_total/fmt_tokensоттуда),out = output_tokens. - Модель: КОРОТКОЕ имя (
opus-4-8,sonnet-4.6). Бери модель агента из конфигурации стадии /agent_runs/launcher (где известно, какой моделью запускался агент). Маппинг полного→короткого: отрезать провайдер-префикс (tokenator/claude-opus-4-8→opus-4-8,vibecode/claude-sonnet-4.6→sonnet-4.6). Если модель неизвестна — опустить· <model>. - Ревью БРД (
⏸️): ОТДЕЛЬНАЯ строка между Analysis и Architecture. Время = ТВОЁ (Славы), НЕ агентское: дельта между моментом «BRD готовы / notify_approve_requested» и переходомanalysis→architecture(gate Approved). Пометкатвоё время ⏳пока идёт ожидание,твоё времяпосле. Пока это ЕДИНСТВЕННОЕ «твоё время» (других gate нет). - Итого:
💰 <total_in>↓ / <total_out>↑ · <cost>(total_in = сумма полного входа всех агентов). - Время в Итого:
⏱️ Всего <wall> · агенты <agent_sum> · твоё <review_brd>гдеВсего= wall-clock от старта задачи до done,агенты= сумма длительностей агент-ранов,твоё= время ревью БРД. - Время стадии — минуты (
10м). Если <1м —<1м. - Текущая активная стадия:
🔄 <Stage> … идёт. Ещё не начатые стадии — НЕ показывать (строка появляется когда стадия стартовала). - Заголовок:
🛠️ <work_item_id> · <короткое название задачи>в процессе,🎉 <work_item_id> · <название> — ГОТОВОна финише. - На финише добавить
🔗 PR #<n> · 📦 deployed(PR-номер из флоу; статус деплоя из check_deploy_status: deployed/❌ failed).
АЛЕРТЫ — ОТДЕЛЬНЫМИ сообщениями (с уведомлением)
Трекер редактируется молча. ОТДЕЛЬНО (новое сообщение, disable_notification: false) слать ТОЛЬКО:
- 📋 Approve-gate: «ET-012: BRD/ТЗ/AC готовы. Переведите в Approved в Plane для продолжения»
(заменить устаревший текст про
:approved:). - 🚨 Деплой упал / откат: как сейчас в launcher.py:495 (
Deploy failed! Rolled back). - ❌ Агент упал: exit_code != 0 (launcher.py:508) — но БЕЗ пути к логам в тексте (в лог, не в ТГ).
- 🔴 Ошибка задачи (
notify_error). НЕ слать отдельными: старт агента, завершение агента, переход стадии, QG-pending (check_ci_green failed: CI state: pending— это НЕ ошибка, только в лог), QG-passed.
РЕАЛИЗАЦИЯ
Файлы: src/notifications.py (основное), src/db.py (хранение message_id + модель/тайминги
если их нет), src/stage_engine.py (вызовы обновления трекера на переходах), возможно
src/agents/launcher.py (тайминги старта/финиша агентов).
- Хранение message_id трекера: добавить колонку
tracker_message_id INTEGERвtasks(idempotent ALTER, как_ensure_columnв db.py). При первом сообщении задачи —sendMessage, сохранитьresult.message_id. На каждом переходе —editMessageTextс полным перерисованным трекером. - Fallback: если
editMessageTextвернул ошибку (message not found / too old / 400) — отправить НОВОЕ сообщение и обновить tracker_message_id. Никогда не падать (как текущий send_telegram fire-and-forget). - Сбор данных стадий: длительность стадии, токены (in/out), стоимость, модель — из
agent_runsпо task_id (там уже есть input/output/cache_read/cache_creation_tokens, cost_usd; модель — добавь сохранение если её там нет, либо бери из конфига стадии). Рендер трекера = функцияrender_task_tracker(task_id) -> str, собирающая всё из БД на каждый вызов (stateless рендер). - Время ревью БРД: зафиксировать timestamp
notify_approve_requestedи timestamp переходаanalysis→architecture; дельта = «твоё время». Хранить вtasks(напр.brd_review_started_at,brd_review_ended_at) или вычислять из activities/stage-history если они уже логируются. - Короткое имя модели: хелпер
short_model_name(full) -> str(отрезать префикс до последнего/, затемclaude-префикс). - parse_mode: трекер — HTML (как сейчас). Экранировать
<>&в названии задачи.
НЕ ТРОГАТЬ
- HMAC, project-filter, nginx, openclaw.json, .env, queue (кроме чтения), PLANE_STATES, conftest.py, status-only verdict, gitea_public_url конфиг, Plane-комменты (usage_comment — это ОТДЕЛЬНО, в Plane; НЕ путать с Telegram-трекером, его формат из fix #20 НЕ менять).
- Сохранить блок launcher.py:475 (deployer exit_code защита).
- cost_usd расчёт.
ТЕСТЫ (обязательно)
render_task_trackerна моке agent_runs: правильный формат строк этапов (in↓/out↑, модель, стоимость, время), строка «Ревью БРД · твоё время», блок Итого с тремя временами.short_model_name:tokenator/claude-opus-4-8→opus-4-8,vibecode/claude-sonnet-4.6→sonnet-4.6.- Трекер: первое сообщение → sendMessage сохраняет message_id; переход → editMessageText.
- Fallback: edit упал → новое сообщение, message_id обновлён.
- Алерты: approve-gate/deploy-fail/agent-fail/error шлются ОТДЕЛЬНО; QG-pending/agent-start/ stage-transition НЕ шлются отдельными (только трекер).
- Полный pytest зелёный (кроме тех же 10 off-limits).
СДАЧА
- Ветка
feat/telegram-live-tracker, один PR в Gitea. НЕ мержить сам — на ревью Стрим. - Отчёт:
tasks/orchestrator/reports/dev-2026-06-04-telegram-tracker.md— commit-хеш, PR-номер, вывод pytest, пример отрендеренного трекера (в процессе + финиш), список того что теперь НЕ шлётся отдельными сообщениями. - Сообщить: PR-номер, результат pytest, пример трекера.