""" HuggingFace Spaces entry point. Gradio serves a minimal status page to keep the Space alive. The Telegram bot runs in a background asyncio loop. """ import asyncio import threading import gradio as gr from bot.telegram_bot import start_bot import config # ── Start bot in a dedicated thread with its own event loop ────────────────── def _bot_thread(): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: loop.run_until_complete(start_bot()) except Exception as e: print(f"[Savvy] Bot crashed: {e}") finally: loop.close() thread = threading.Thread(target=_bot_thread, daemon=True) thread.start() print("[Savvy] Bot thread started.") # ── Gradio status page ──────────────────────────────────────────────────────── def status(): checks = { "TELEGRAM_TOKEN": bool(config.TELEGRAM_TOKEN), "GITHUB_TOKEN": bool(config.GITHUB_TOKEN), "GITHUB_REPO": bool(config.GITHUB_REPO), "TAVILY_API_KEY": bool(config.TAVILY_API_KEY), "HF_TOKEN": bool(config.HF_TOKEN), "MODEL_ID": config.MODEL_ID, "DEFAULT_MODE": config.DEFAULT_MODE, } lines = ["# Savvy — Status\n"] for k, v in checks.items(): icon = "✅" if v is True else "⚠️" if v is False else "ℹ️" lines.append(f"{icon} **{k}**: `{v}`") return "\n".join(lines) with gr.Blocks(title="Savvy") as demo: gr.Markdown("# 👾 Savvy Agent") gr.Markdown("Telegram bot is running in the background.") refresh_btn = gr.Button("Refresh status") status_out = gr.Markdown(value=status()) refresh_btn.click(fn=status, outputs=status_out) demo.launch(server_name="0.0.0.0", server_port=7860)