From 64371666c0f219964e4a2b7e39ef4c00198843fc Mon Sep 17 00:00:00 2001 From: Stream Date: Thu, 4 Jun 2026 11:40:03 +0300 Subject: [PATCH] auto-sync: 2026-06-04 11:40:01 --- .../orchestrator/DEV_TASK_TELEGRAM_TRACKER.md | 141 ++++++++++++++++++ .../dev-2026-06-04-telegram-tracker.md | 28 ++++ 2 files changed, 169 insertions(+) create mode 100644 tasks/orchestrator/DEV_TASK_TELEGRAM_TRACKER.md create mode 100644 tasks/orchestrator/reports/dev-2026-06-04-telegram-tracker.md diff --git a/tasks/orchestrator/DEV_TASK_TELEGRAM_TRACKER.md b/tasks/orchestrator/DEV_TASK_TELEGRAM_TRACKER.md new file mode 100644 index 0000000..86b4fb8 --- /dev/null +++ b/tasks/orchestrator/DEV_TASK_TELEGRAM_TRACKER.md @@ -0,0 +1,141 @@ +# 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 = 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`). Если модель неизвестна — опустить ` · `. +- **Ревью БРД (`⏸️`):** ОТДЕЛЬНАЯ строка между Analysis и Architecture. Время = ТВОЁ (Славы), + НЕ агентское: дельта между моментом «BRD готовы / notify_approve_requested» и переходом + `analysis→architecture` (gate Approved). Пометка `твоё время ⏳` пока идёт ожидание, + `твоё время` после. Пока это ЕДИНСТВЕННОЕ «твоё время» (других gate нет). +- **Итого:** `💰 ↓ / ↑ · ` (total_in = сумма полного входа всех агентов). +- **Время в Итого:** `⏱️ Всего · агенты · твоё ` где + `Всего` = wall-clock от старта задачи до done, `агенты` = сумма длительностей агент-ранов, + `твоё` = время ревью БРД. +- Время стадии — минуты (`10м`). Если <1м — `<1м`. +- Текущая активная стадия: `🔄 … идёт`. Ещё не начатые стадии — НЕ показывать + (строка появляется когда стадия стартовала). +- Заголовок: `🛠️ · <короткое название задачи>` в процессе, + `🎉 · <название> — ГОТОВО` на финише. +- На финише добавить `🔗 PR # · 📦 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-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, пример трекера. diff --git a/tasks/orchestrator/reports/dev-2026-06-04-telegram-tracker.md b/tasks/orchestrator/reports/dev-2026-06-04-telegram-tracker.md new file mode 100644 index 0000000..2441c11 --- /dev/null +++ b/tasks/orchestrator/reports/dev-2026-06-04-telegram-tracker.md @@ -0,0 +1,28 @@ +# Dev Report: orchestrator — живой Telegram-трекер задачи (Вариант B+) +Дата: 2026-06-04 +Статус: IN PROGRESS + +## Задача +Заменить ~15 отдельных ТГ-сообщений на задачу одним живым сообщением-трекером +(editMessageText по стадиям). Отдельными сообщениями с пингом — только approve-gate, +deploy-fail, agent-fail, error. + +## Сделано +- [x] Прочитал ТЗ, изучил codebase (notifications.py, db.py, usage.py, stage_engine.py, launcher.py) +- [x] Создал ветку feat/telegram-live-tracker от main (2801983) +- [ ] db.py: колонки tracker_message_id, model, brd_review_* +- [ ] usage.py: short_model_name, парсинг модели +- [ ] notifications.py: render_task_tracker, send/edit tracker, алерты +- [ ] stage_engine.py / launcher.py: тайминги BRD review + вызовы трекера +- [ ] Тесты +- [ ] pytest зелёный +- [ ] PR в Gitea + +## Изменённые файлы +(в процессе) + +## Результат +(в процессе) + +## Проблемы и решения +(в процессе)