Files
wiki/tasks/orchestrator/DEV_TASK_TELEGRAM_TRACKER.md
2026-06-04 11:40:03 +03:00

11 KiB
Raw Blame History

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-8opus-4-8, vibecode/claude-sonnet-4.6sonnet-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 (тайминги старта/финиша агентов).

  1. Хранение message_id трекера: добавить колонку tracker_message_id INTEGER в tasks (idempotent ALTER, как _ensure_column в db.py). При первом сообщении задачи — sendMessage, сохранить result.message_id. На каждом переходе — editMessageText с полным перерисованным трекером.
  2. Fallback: если editMessageText вернул ошибку (message not found / too old / 400) — отправить НОВОЕ сообщение и обновить tracker_message_id. Никогда не падать (как текущий send_telegram fire-and-forget).
  3. Сбор данных стадий: длительность стадии, токены (in/out), стоимость, модель — из agent_runs по task_id (там уже есть input/output/cache_read/cache_creation_tokens, cost_usd; модель — добавь сохранение если её там нет, либо бери из конфига стадии). Рендер трекера = функция render_task_tracker(task_id) -> str, собирающая всё из БД на каждый вызов (stateless рендер).
  4. Время ревью БРД: зафиксировать timestamp notify_approve_requested и timestamp перехода analysis→architecture; дельта = «твоё время». Хранить в tasks (напр. brd_review_started_at, brd_review_ended_at) или вычислять из activities/stage-history если они уже логируются.
  5. Короткое имя модели: хелпер short_model_name(full) -> str (отрезать префикс до последнего /, затем claude- префикс).
  6. 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-8opus-4-8, vibecode/claude-sonnet-4.6sonnet-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, пример трекера.