#!/usr/bin/env python3 """LobeHub Proxy — CLI-based, 601 accounts, rotation""" import json, time, random, threading, subprocess, os from http.server import HTTPServer, BaseHTTPRequestHandler from pathlib import Path from datetime import datetime BASE_URL = "http://[REDACTED-IP]:3210" ACCOUNTS_FILE = Path(r"C:\Users\User\lobehub_accounts.json") CLI = r"C:\Users\User\AppData\Roaming\npm\node_modules\@lobehub\cli\dist\index.js" PORT = 20140 MODELS = [ "openai/gpt-5.5","openai/gpt-5.4","openai/gpt-5.4-mini","openai/gpt-5.3-codex-spark", "anthropic/claude-opus-4.8","anthropic/claude-opus-4.7","anthropic/claude-opus-4.6","anthropic/claude-opus-4.5", "anthropic/claude-sonnet-5","anthropic/claude-sonnet-4.6","anthropic/claude-sonnet-4.5","anthropic/claude-haiku-4.5", "deepseek/deepseek-v4-pro","deepseek/deepseek-v4-flash", "z-ai/glm-5.2","z-ai/glm-5.1", "moonshotai/kimi-k2.7-code","moonshotai/kimi-k2.6", "qwen/qwen3.7-plus","qwen/qwen3.7-max", ] pool_lock = threading.Lock() accounts = [] account_index = 0 stats = {"total_requests": 0, "errors": 0, "started": datetime.now().isoformat()} def load_accounts(): global accounts with open(ACCOUNTS_FILE) as f: raw = json.load(f) with pool_lock: accounts = [{"email": a["email"], "password": a["password"], "token": a.get("token",""), "valid": bool(a.get("token","")), "last_used": None, "request_count": 0, "errors": 0} for a in raw] print(f"[Pool] {len(accounts)} accounts, {sum(1 for a in accounts if a['valid'])} with tokens") def generate_text(model, messages, max_tokens, token): """LobeHub CLI subprocess""" prompt = messages[-1]["content"] if messages else "" system = next((m["content"] for m in messages if m["role"] == "system"), "") env = os.environ.copy() env["LOBEHUB_JWT"] = token env["LOBEHUB_SERVER"] = BASE_URL env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0" args = ["node", CLI, "generate", "text", prompt, "--model", model, "--max-tokens", str(max_tokens), "--stream"] if system: args.extend(["--system", system]) try: proc = subprocess.run(args, capture_output=True, text=True, timeout=120, env=env) output = proc.stdout or proc.stderr or "" result = "" for line in output.split("\n"): line = line.strip() if not line: continue if line.startswith("in_progress"): result += line[len("in_progress"):] elif line.startswith("data: "): result += line[6:] elif line in ("message_stop","end_turn","message_start","text_delta"): pass elif line.startswith(("error_","id:","[","message_","end_")): pass elif line == "undefined": pass else: result += line result = result.strip() for a in ["message_stop","end_turn","message_start","text_delta"]: result = result.replace(a,"") if result: return {"content": result.strip(), "success": True} return {"error": output[:100], "success": False} except subprocess.TimeoutExpired: return {"error": "Timeout", "success": False} except Exception as e: return {"error": str(e), "success": False} def get_next_account(): global account_index with pool_lock: valid = [a for a in accounts if a["valid"]] if not valid: return None for _ in range(min(20, len(accounts))): account_index = (account_index + 1) % len(accounts) if accounts[account_index]["valid"]: accounts[account_index]["last_used"] = datetime.now().isoformat() accounts[account_index]["request_count"] += 1 return accounts[account_index] acc = random.choice(valid) acc["last_used"] = datetime.now().isoformat() acc["request_count"] += 1 return acc class Proxy(BaseHTTPRequestHandler): def _json(self, data, status=200): self.send_response(status); self.send_header("Content-Type","application/json"); self.send_header("Access-Control-Allow-Origin","*"); self.end_headers() self.wfile.write(json.dumps(data,ensure_ascii=False).encode()) def _auth(self): return self.headers.get("Authorization","") in ("Bearer local","local") def do_GET(self): if self.path == "/health": with pool_lock: valid = sum(1 for a in accounts if a["valid"]) self._json({"status":"ok","accounts":{"total":len(accounts),"valid":valid},"models":len(MODELS),"backend":"lobehub-cli","stats":stats}) elif self.path == "/v1/models": self._json({"object":"list","data":[{"id":m,"object":"model"} for m in MODELS]}) else: self._json({"error":"not found"},404) def do_POST(self): if self.path != "/v1/chat/completions": self._json({"error":"not found"},404); return if not self._auth(): self._json({"error":"Unauthorized"},401); return stats["total_requests"] += 1 try: body = json.loads(self.rfile.read(int(self.headers.get("Content-Length",0)))) except: self._json({"error":"Invalid JSON"},400); return model = body.get("model","openai/gpt-5.5") messages = body.get("messages",[]) if not messages: self._json({"error":"messages required"},400); return acc = get_next_account() if not acc: self._json({"error":"No valid accounts"},503); return result = generate_text(model, messages, body.get("max_tokens",4096), acc["token"]) if result["success"]: self._json({ "id":f"lobehub-{int(time.time())}","object":"chat.completion","created":int(time.time()), "model":model,"choices":[{"index":0,"message":{"role":"assistant","content":result["content"]},"finish_reason":"stop"}], "usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}, "_pool":{"account":acc["email"][:3]+"***","engine":"lobehub-cli"} }) else: stats["errors"] += 1; acc["errors"] += 1 self._json({"error":result.get("error","Generation failed")},500) def log_message(self,f,*a): pass # === START === load_accounts() print(f"[LobeHub CLI Proxy] :{PORT} | {len(accounts)} accounts | Ready") while True: try: HTTPServer(("127.0.0.1",PORT), Proxy).serve_forever() except Exception as e: print(f"[Crash] {e}"); time.sleep(3)