Spaces:
Sleeping
Sleeping
Download bot_runner.py from hoainamgo/Clone-Voice: direct link, hf CLI and curl.
- Browser
- Download file 8.52 kB
-
https://huggingface.co/spaces/hoainamgo/Clone-Voice/resolve/main/bot_runner.py
- Command line
-
hf download hf://spaces/hoainamgo/Clone-Voice/bot_runner.py
-
curl -L -o bot_runner.py https://huggingface.co/spaces/hoainamgo/Clone-Voice/resolve/main/bot_runner.py
8.52 kB
| """ | |
| bot_runner.py - Dedicated Lightweight Telegram Bot Runner for Hermes Agent (Nous Portal Free Model) | |
| """ | |
| import os | |
| import sys | |
| import subprocess | |
| import threading | |
| import time | |
| import psutil | |
| import requests | |
| from dotenv import load_dotenv | |
| CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| load_dotenv(os.path.join(CURRENT_DIR, ".env")) | |
| BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN", "").strip() | |
| ALLOWED_USER_ID_RAW = os.getenv("ALLOWED_USER_ID", "0").strip() | |
| try: | |
| ALLOWED_USER_ID = int(ALLOWED_USER_ID_RAW) | |
| except ValueError: | |
| ALLOWED_USER_ID = 0 | |
| PROVIDER = os.getenv("HERMES_PROVIDER", "nous").strip() | |
| MODEL_NAME = os.getenv("HERMES_MODEL", "stepfun/step-3.7-flash:free").strip() | |
| print(f"[STARTUP] Bot Token: {BOT_TOKEN[:10]}... | Allowed ID: {ALLOWED_USER_ID} | Provider: {PROVIDER} | Model: {MODEL_NAME}", flush=True) | |
| # Hermes Agent Loader | |
| AIAgent = None | |
| try: | |
| from run_agent import AIAgent | |
| print("[STARTUP] run_agent.AIAgent loaded successfully!", flush=True) | |
| except Exception as e: | |
| print(f"[STARTUP WARN] Could not import AIAgent: {e}", flush=True) | |
| agent_instance = None | |
| def init_hermes_agent(model_name=MODEL_NAME): | |
| global agent_instance | |
| if not AIAgent: | |
| return None | |
| try: | |
| agent_instance = AIAgent( | |
| model=model_name, | |
| provider="nous", | |
| quiet_mode=True | |
| ) | |
| print(f"[STARTUP] Hermes Agent ({model_name}) via Nous Portal initialized successfully!", flush=True) | |
| return agent_instance | |
| except Exception as e: | |
| print(f"[STARTUP WARN] AIAgent Nous init ({model_name}): {e}", flush=True) | |
| return None | |
| init_hermes_agent(MODEL_NAME) | |
| START_TIME = time.time() | |
| session = requests.Session() | |
| def send_tg_message(chat_id: int, text: str, parse_mode: str = "Markdown"): | |
| if not BOT_TOKEN: | |
| return | |
| url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage" | |
| payload = {"chat_id": chat_id, "text": text} | |
| if parse_mode: | |
| payload["parse_mode"] = parse_mode | |
| try: | |
| r = session.post(url, json=payload, timeout=20) | |
| res_json = r.json() | |
| if not res_json.get("ok"): | |
| payload.pop("parse_mode", None) | |
| session.post(url, json=payload, timeout=20) | |
| except Exception as e: | |
| print(f"[ERROR] Send TG message failed: {e}", flush=True) | |
| def send_typing(chat_id: int): | |
| if not BOT_TOKEN: | |
| return | |
| try: | |
| session.post(f"https://api.telegram.org/bot{BOT_TOKEN}/sendChatAction", json={"chat_id": chat_id, "action": "typing"}, timeout=5) | |
| except Exception: | |
| pass | |
| def handle_update(update: dict): | |
| global MODEL_NAME, agent_instance | |
| msg = update.get("message") | |
| if not msg: | |
| return | |
| sender = msg.get("from", {}) | |
| sender_id = sender.get("id") | |
| chat_id = msg.get("chat", {}).get("id") | |
| text = (msg.get("text") or "").strip() | |
| if sender_id != ALLOWED_USER_ID: | |
| print(f"[BLOCKED] Unauthorized message from User ID {sender_id} (@{sender.get('username')})", flush=True) | |
| return | |
| print(f"[RECV] From {sender_id}: {text}", flush=True) | |
| send_typing(chat_id) | |
| # Command: /start or /help | |
| if text in ["/start", "/help"]: | |
| welcome = ( | |
| "🛡️ *HERMES AGENT NOUS PORTAL CONTROLLER* 🛡️\n\n" | |
| "Chào bạn! Bot đã kết nối trực tiếp tài khoản **Nous Portal** qua OAuth.\n\n" | |
| "📌 *Danh sách lệnh:*\n" | |
| f"• Model mặc định: `{MODEL_NAME}` (Free 100%)\n" | |
| "• `/model` : Xem hoặc đổi sang các model Free khác của Nous.\n" | |
| "• `/status` : Xem Uptime, CPU, RAM và trạng thái hệ thống.\n" | |
| "• `/sh <lệnh>` : Chạy lệnh shell/CLI trên máy chủ.\n" | |
| "• Nhắn tin bất kỳ để chat và nhờ Hermes Agent giải quyết task." | |
| ) | |
| send_tg_message(chat_id, welcome) | |
| return | |
| # Command: /status | |
| if text == "/status": | |
| uptime_sec = int(time.time() - START_TIME) | |
| uptime_str = f"{uptime_sec // 3600}h {(uptime_sec % 3600) // 60}m {uptime_sec % 60}s" | |
| mem = psutil.virtual_memory() | |
| stat_msg = ( | |
| f"📊 *HỆ THỐNG TELEMETRY*\n" | |
| f"━━━━━━━━━━━━━━━━━━━\n" | |
| f"⏱ *Uptime:* `{uptime_str}`\n" | |
| f"💻 *CPU Load:* `{psutil.cpu_percent()}%`\n" | |
| f"🧠 *RAM:* `{round(mem.used / 1024**2, 1)}MB / {round(mem.total / 1024**2, 1)}MB`\n" | |
| f"🌐 *Provider:* `Nous Portal (OAuth Active)`\n" | |
| f"🤖 *Active Model:* `{MODEL_NAME}`\n" | |
| f"🔑 *Authorized User ID:* `{ALLOWED_USER_ID}`\n" | |
| ) | |
| send_tg_message(chat_id, stat_msg) | |
| return | |
| # Command: /model | |
| if text == "/model": | |
| model_msg = ( | |
| f"🤖 *MODEL NOUS HIỆN TẠI:* `{MODEL_NAME}`\n\n" | |
| f"🎁 *Các model FREE trên Nous Portal:*\n" | |
| f"• `/model stepfun/step-3.7-flash:free` (Khuyên dùng - Cực nhanh & thông minh)\n" | |
| f"• `/model meituan/longcat-2.0:free` (Context dài)\n" | |
| f"• `/model upstage/solar-mini4:free` (Nhẹ & chuẩn xác)\n" | |
| f"• `/model inclusionai/ling-3.0-flash-fin:free`\n\n" | |
| f"💡 *Cách đổi:* Gõ `/model <tên_model>`" | |
| ) | |
| send_tg_message(chat_id, model_msg) | |
| return | |
| if text.startswith("/model "): | |
| new_model = text.split(" ", 1)[1].strip() | |
| new_agent = init_hermes_agent(new_model) | |
| if new_agent: | |
| MODEL_NAME = new_model | |
| send_tg_message(chat_id, f"✅ Đã chuyển sang Model Nous: `{MODEL_NAME}` thành công!") | |
| else: | |
| send_tg_message(chat_id, f"⚠️ Không thể khởi tạo model `{new_model}`. Vui lòng kiểm tra lại tên model.") | |
| return | |
| # Command: /sh or /cmd | |
| if text.startswith("/sh ") or text.startswith("/cmd "): | |
| cmd = text.split(" ", 1)[1].strip() | |
| try: | |
| proc = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=45) | |
| out = proc.stdout.strip() if proc.stdout else "" | |
| err = proc.stderr.strip() if proc.stderr else "" | |
| res = out if out else err | |
| if not res: | |
| res = "✅ (Exit code 0, no output)" | |
| if len(res) > 3800: | |
| res = res[:3800] + "\n... [Cắt bớt do quá dài]" | |
| send_tg_message(chat_id, f"```\n{res}\n```") | |
| except subprocess.TimeoutExpired: | |
| send_tg_message(chat_id, "⏱ Lệnh bị quá thời gian cho phép (Timeout 45s).") | |
| except Exception as e: | |
| send_tg_message(chat_id, f"❌ Lỗi CLI: {str(e)}") | |
| return | |
| # Chat with Hermes Agent via Nous Portal | |
| if not agent_instance: | |
| init_hermes_agent(MODEL_NAME) | |
| if not agent_instance: | |
| send_tg_message(chat_id, "⚠️ Chưa khởi tạo được Hermes Agent qua Nous Portal.") | |
| return | |
| try: | |
| reply = agent_instance.chat(text) | |
| send_tg_message(chat_id, reply) | |
| except Exception as e: | |
| send_tg_message(chat_id, f"❌ Lỗi Hermes Agent: {str(e)}") | |
| def main(): | |
| if not BOT_TOKEN: | |
| print("[ERROR] No TELEGRAM_BOT_TOKEN found in .env!", flush=True) | |
| return | |
| print(f"🚀 Telegram Long Polling Bot active for User ID: {ALLOWED_USER_ID} on Nous Portal Free Model", flush=True) | |
| last_update_id = 0 | |
| if ALLOWED_USER_ID != 0: | |
| send_tg_message(ALLOWED_USER_ID, f"🟢 *Hermes Agent* đã chuyển sang **Model Free của Nous Portal** (`{MODEL_NAME}`) hoàn toàn miễn phí!") | |
| while True: | |
| try: | |
| url = f"https://api.telegram.org/bot{BOT_TOKEN}/getUpdates" | |
| params = {"timeout": 20, "offset": last_update_id + 1} | |
| resp = session.get(url, params=params, timeout=30) | |
| data = resp.json() | |
| if data.get("ok"): | |
| updates = data.get("result", []) | |
| for u in updates: | |
| last_update_id = u["update_id"] | |
| try: | |
| handle_update(u) | |
| except Exception as e: | |
| print(f"[ERROR] handle_update: {e}", flush=True) | |
| else: | |
| time.sleep(2) | |
| except requests.exceptions.Timeout: | |
| continue | |
| except Exception as e: | |
| print(f"[NETWORK NOTE] {e}", flush=True) | |
| time.sleep(3) | |
| if __name__ == "__main__": | |
| main() | |