""" HERMES — punto d'ingresso dello Space HuggingFace. Avvia l'agente come thread sempre attivo (ascolta Telegram) e mostra una piccola pagina di stato. Un secondo thread fa "auto-ping" per evitare che lo Space gratuito vada in sleep. Le credenziali vanno messe nelle SECRETS dello Space (vedi README). """ from __future__ import annotations import os import time import threading import gradio as gr import config import hermes _avviato = False _lock = threading.Lock() def _avvia_agente() -> None: """Avvia il battito di Hermes una sola volta.""" global _avviato with _lock: if _avviato: return _avviato = True threading.Thread(target=hermes.run, daemon=True, name="hermes-loop").start() def _keep_alive() -> None: """Auto-ping periodico per non addormentarsi (Space gratuito).""" host = os.environ.get("SPACE_HOST", "") if not host: return import requests url = f"https://{host}/" while True: time.sleep(1500) # ~25 minuti try: requests.get(url, timeout=15) except Exception: pass def _stato_testo() -> str: cervelli = ", ".join(p["name"] for p in config.LLM_PROVIDERS if p.get("api_key")) or "NESSUNO" tg = "configurato" if config.TELEGRAM_BOT_TOKEN else "MANCANTE" mem = "configurata" if config.HF_TOKEN else "MANCANTE" return ( f"- Telegram (@SecopufBot): {tg}\n" f"- Cervelli AI attivi: {cervelli}\n" f"- Memoria/dashboard cloud: {mem}\n" f"- Agente avviato: {'si' if _avviato else 'no'}" ) # avvia i thread all'import (HF esegue questo file) _avvia_agente() threading.Thread(target=_keep_alive, daemon=True, name="keep-alive").start() with gr.Blocks(title="Hermes") as demo: gr.Markdown( "# Hermes\n" "Agente personale di **Ayman** per il progetto Off-Grid. " "Sempre attivo: ascolta e risponde su Telegram (@SecopufBot), fa ricerche, " "aggiorna la dashboard e ricorda le cose — anche a PC spento.\n" ) stato = gr.Textbox(label="Stato", value=_stato_testo(), lines=4, interactive=False) gr.Button("Aggiorna stato").click(lambda: _stato_testo(), outputs=stato) if __name__ == "__main__": demo.launch()