Spaces:
Configuration error
Configuration error
Baida—-
fix(registry): unterminated string literal line 692 — force re-sync [skip ci]
889ea3f verified | # backend/api — Moduli Telegram (M2 Split) | |
| > **Refactor M2 — 2 Luglio 2026** | |
| > Il monolite `telegram_webhook.py` (2844 righe, 5 hotfix consecutivi) è stato | |
| > spezzato in 6 moduli a responsabilità singola. Hotfix futuri toccano **un solo file**. | |
| --- | |
| ## Grafo delle dipendenze | |
| ``` | |
| telegram_tg_client.py (stdlib + httpx only) | |
| │ | |
| ├──► telegram_keyboards.py (solo costanti/dict — zero import interni) | |
| │ │ | |
| │ ├──► telegram_cmd_monitoring.py | |
| │ │ └──► (esposto via telegram_webhook.py) | |
| │ │ | |
| │ ├──► telegram_cmd_ai.py | |
| │ │ └──► (esposto via telegram_webhook.py) | |
| │ │ | |
| │ └──► telegram_callbacks.py | |
| │ ├── importa _cmd_do, _cmd_autofix ... da telegram_cmd_ai | |
| │ └── importa _cmd_help, _cmd_status ... da telegram_cmd_monitoring | |
| │ | |
| └──► telegram_webhook.py (router FastAPI puro — importa da tutti) | |
| └──► montato in backend/main.py come _tg_webhook_router | |
| ``` | |
| --- | |
| ## Moduli | |
| ### `telegram_tg_client.py` — 276 righe | |
| **Ruolo:** Telegram Bot API puro. Layer 0 senza dipendenze interne. | |
| | Simbolo | Descrizione | | |
| |---------|-------------| | |
| | `_get_bot_token()` | Legge `TELEGRAM_BOT_TOKEN` dall'env | | |
| | `_log_tg_exc(task)` | Log eccezioni fire-and-forget (Gap-2.6) | | |
| | `_fmt_elapsed(sec)` | Formatta durata in human-readable | | |
| | `_tg_reply(chat_id, text)` | Invia messaggio con parse_mode=HTML | | |
| | `_tg_send(chat_id, text)` | Come reply, ritorna `message_id` | | |
| | `_tg_edit(chat_id, msg_id, text)` | Modifica messaggio esistente | | |
| | `_tg_photo(chat_id, url, caption)` | Invia foto via URL | | |
| | `_tg_typing(chat_id)` | Invia `sendChatAction typing` | | |
| | `_tg_react(chat_id, msg_id, emoji)` | Imposta reaction emoji | | |
| | `_tg_answer_callback(callback_id)` | Risponde a `callback_query` (≤3s) | | |
| **Import:** `asyncio, html, logging, os, time, httpx` | |
| --- | |
| ### `telegram_keyboards.py` — 109 righe | |
| **Ruolo:** Costanti UI e keyboards. Zero logica, zero import interni. | |
| | Simbolo | Tipo | Descrizione | | |
| |---------|------|-------------| | |
| | `_QUICK_PICK_KB` | `dict` | Inline keyboard selezione task rapida | | |
| | `_MAIN_KB` | `dict` | Reply keyboard principale | | |
| | `_BENCH_ACTION_KB` | `dict` | Keyboard post-benchmark | | |
| | `_TASK_MENU_KB` | `dict` | Sub-menu task | | |
| | `_STATUS_MENU_KB` | `dict` | Sub-menu stato sistema | | |
| | `_PERF_MENU_KB` | `dict` | Sub-menu performance | | |
| | `_HEALTH_MENU_KB` | `dict` | Sub-menu health | | |
| | `_DEV_MENU_KB` | `dict` | Sub-menu developer | | |
| | `_LAST_GOAL` | `dict[int,str]` | Memoria per bottone 🔁 Rifai | | |
| | `_BENCH_CACHE` | `dict[int,dict]` | Ultimo run benchmark per chat | | |
| | `_after_task_kb(chat_id)` | func | Keyboard dinamica post-task | | |
| **Import:** solo `from __future__ import annotations` | |
| --- | |
| ### `telegram_cmd_monitoring.py` — 456 righe | |
| **Ruolo:** Comandi di monitoraggio, stato e diagnostica. | |
| | Comando / Funzione | Trigger Telegram | | |
| |--------------------|-----------------| | |
| | `_cmd_help(chat_id)` | `/start` `/help` `tgw_help` | | |
| | `_cmd_logs(chat_id)` | `/logs` `tgw_logs` | | |
| | `_cmd_status(chat_id)` | `/stato` `tgw_status` | | |
| | `_cmd_commit_summary(chat_id)` | `/commit` `tgw_commits` | | |
| | `_cmd_check(chat_id)` | `/salute` `tgw_health` | | |
| | `_cmd_tasks(chat_id)` | `/attività` `tgw_tasks` | | |
| | `_cmd_git(chat_id, args)` | `/git` `tgw_git` | | |
| | `_cmd_coord(chat_id)` | `/coord` `tgw_coord` | | |
| | `_cmd_scan_now(chat_id)` | `/scan` `tgw_scan` | | |
| | `_cmd_telemetry(chat_id)` | `/telemetria` `tgw_telemetry` | | |
| **Import:** stdlib + `telegram_tg_client` + `telegram_keyboards` | |
| --- | |
| ### `telegram_cmd_ai.py` — 1152 righe | |
| **Ruolo:** Comandi AI, LLM e operativi. Modulo più pesante — contiene lo streaming loop. | |
| | Comando / Funzione | Trigger Telegram | | |
| |--------------------|-----------------| | |
| | `_cmd_do(chat_id, goal)` | `/avvia` — lancia task AI con streaming | | |
| | `_cmd_autofix(chat_id)` | `/fix` `tgw_autofix` | | |
| | `_cmd_nota(chat_id, text)` | `/nota` `tgw_nota` | | |
| | `_cmd_cerca(chat_id, query)` | `/cerca` `tgw_cerca` | | |
| | `_cmd_meteo(chat_id, city)` | `/meteo` `tgw_meteo` | | |
| | `_cmd_riepilogo(chat_id)` | `/riepilogo` `tgw_briefing` | | |
| | `_cmd_score(chat_id)` | `/score` `tgw_score` | | |
| | `_cmd_bench(chat_id)` | `/bench` `tgw_bench` | | |
| | `_cmd_improve(chat_id, target)` | `/migliora` `tgw_improve` | | |
| **Import:** stdlib + `telegram_tg_client` + `telegram_keyboards` | |
| --- | |
| ### `telegram_callbacks.py` — 353 righe | |
| **Ruolo:** Smista `callback_query` e `inline_query` in arrivo da Telegram. | |
| | Funzione | Descrizione | | |
| |----------|-------------| | |
| | `_handle_inline(iq, token)` | Risponde alle inline query (`@ARJagent_ap_bot testo`) | | |
| | `_handle_callback(cb, token)` | Dispatch per tutti i `callback_data` `tgw_*` / `agent` / `qp_*` | | |
| **Import:** `telegram_tg_client` + `telegram_keyboards` + `telegram_cmd_ai` + `telegram_cmd_monitoring` | |
| > ⚠️ **Questo modulo crea dipendenze circolari potenziali** — non importare | |
| > `telegram_callbacks` da `telegram_cmd_ai` o `telegram_cmd_monitoring`. | |
| --- | |
| ### `telegram_webhook.py` — 605 righe *(era 2844)* | |
| **Ruolo:** Router FastAPI puro. Solo endpoint HTTP, zero logica di business. | |
| | Endpoint | Metodo | Descrizione | | |
| |----------|--------|-------------| | |
| | `/api/telegram/webhook` | POST | Ricezione update getUpdates (polling daemon) | | |
| | `/api/telegram/process` | POST | Endpoint alternativo per CF Pages proxy | | |
| | `/api/telegram/config/invalidate` | POST | Invalida cache config bot | | |
| **Import:** FastAPI + tutti i 5 moduli sopra | |
| **Montato in:** `backend/main.py` → `app.include_router(_tg_webhook_router)` | |
| --- | |
| ## Regole per gli hotfix | |
| | Vuoi cambiare... | Tocca solo... | | |
| |------------------|---------------| | |
| | Aspetto di un bottone / label | `telegram_keyboards.py` | | |
| | Risposta a un comando /help, /stato… | `telegram_cmd_monitoring.py` | | |
| | Logica task AI / streaming / bench | `telegram_cmd_ai.py` | | |
| | Routing dei bottoni inline (tgw_*) | `telegram_callbacks.py` | | |
| | Helpers HTTP verso api.telegram.org | `telegram_tg_client.py` | | |
| | Routing endpoint FastAPI | `telegram_webhook.py` | | |
| --- | |
| ## Daemon Node.js (scripts/lib/daemon-callbacks.mjs) | |
| Il daemon usa **getUpdates polling** (non webhook registrato). | |
| Riceve gli update, li smista ai command handler Python via HTTP interno. | |
| Il flusso `callback_data tgw_*` viene elaborato da `telegram_callbacks.py::_handle_callback`. | |
| ``` | |
| Telegram ──► getUpdates daemon ──► POST /api/telegram/process | |
| │ | |
| telegram_webhook.py (router) | |
| │ | |
| ┌───────────┴───────────┐ | |
| message? callback_query? | |
| │ │ | |
| telegram_cmd_*.py telegram_callbacks.py | |
| ::_handle_callback | |
| ``` | |