|
@@ -0,0 +1,577 @@
|
|
|
|
|
+
|
|
|
|
|
+#!/usr/bin/env python3
|
|
|
|
|
+
|
|
|
|
|
+from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
|
|
|
+import urllib.request
|
|
|
|
|
+import urllib.error
|
|
|
|
|
+import json
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# Agnes 配置
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+
|
|
|
|
|
+AGNES_URL = "https://apihub.agnes-ai.com/v1/responses"
|
|
|
|
|
+AGNES_KEY = "sk-***"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# Agnes 支持的 Tool 类型
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+
|
|
|
|
|
+# SUPPORTED_TOOLS = {
|
|
|
|
|
+# "function",
|
|
|
|
|
+# "web_search_preview",
|
|
|
|
|
+# "code_interpreter",
|
|
|
|
|
+# "mcp",
|
|
|
|
|
+# }
|
|
|
|
|
+
|
|
|
|
|
+SUPPORTED_TOOLS = {
|
|
|
|
|
+ "function",
|
|
|
|
|
+ "web_search_preview",
|
|
|
|
|
+ # "web_search",
|
|
|
|
|
+ "code_interpreter",
|
|
|
|
|
+ "file_search",
|
|
|
|
|
+ "computer_use",
|
|
|
|
|
+ "mcp",
|
|
|
|
|
+ # "tool_search",
|
|
|
|
|
+ "namespace",
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# HTTP Handler
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+
|
|
|
|
|
+class Handler(BaseHTTPRequestHandler):
|
|
|
|
|
+
|
|
|
|
|
+ protocol_version = "HTTP/1.1"
|
|
|
|
|
+
|
|
|
|
|
+ def do_POST(self):
|
|
|
|
|
+
|
|
|
|
|
+ # ----------------------------------------------------
|
|
|
|
|
+ # 只处理 /v1/responses
|
|
|
|
|
+ # ----------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+ if self.path != "/v1/responses":
|
|
|
|
|
+ self.send_error(404)
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ # ----------------------------------------------------
|
|
|
|
|
+ # 读取请求
|
|
|
|
|
+ # ----------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+ length = int(self.headers.get("Content-Length", 0))
|
|
|
|
|
+ body = self.rfile.read(length)
|
|
|
|
|
+
|
|
|
|
|
+ data = json.loads(body)
|
|
|
|
|
+
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+
|
|
|
|
|
+ print("\n===== REQUEST PARSE ERROR =====")
|
|
|
|
|
+ print(repr(e))
|
|
|
|
|
+
|
|
|
|
|
+ self.send_response(400)
|
|
|
|
|
+ self.send_header("Content-Type", "application/json")
|
|
|
|
|
+ self.send_header("Connection", "close")
|
|
|
|
|
+ self.end_headers()
|
|
|
|
|
+
|
|
|
|
|
+ error = json.dumps({
|
|
|
|
|
+ "error": {
|
|
|
|
|
+ "message": f"Invalid JSON request: {e}",
|
|
|
|
|
+ "type": "invalid_request_error"
|
|
|
|
|
+ }
|
|
|
|
|
+ }).encode("utf-8")
|
|
|
|
|
+
|
|
|
|
|
+ self.wfile.write(error)
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+ # 1. Model 映射
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+
|
|
|
|
|
+ original_model = data.get("model")
|
|
|
|
|
+
|
|
|
|
|
+ if original_model == "gpt-5.5":
|
|
|
|
|
+ data["model"] = "agnes-3.0-flash"
|
|
|
|
|
+
|
|
|
|
|
+ print("\n===== MODEL =====")
|
|
|
|
|
+ print("Codex :", original_model)
|
|
|
|
|
+ print("Agnes :", data.get("model"))
|
|
|
|
|
+
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+ # 2. Tool 过滤
|
|
|
|
|
+ #
|
|
|
|
|
+ # Agnes 当前支持:
|
|
|
|
|
+ #
|
|
|
|
|
+ # function
|
|
|
|
|
+ # web_search_preview
|
|
|
|
|
+ # code_interpreter
|
|
|
|
|
+ # mcp
|
|
|
|
|
+ #
|
|
|
|
|
+ # Codex 可能发送:
|
|
|
|
|
+ #
|
|
|
|
|
+ # custom
|
|
|
|
|
+ # tool_search
|
|
|
|
|
+ # 以及其他内部工具
|
|
|
|
|
+ #
|
|
|
|
|
+ # 对不支持的类型直接删除
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+
|
|
|
|
|
+ if isinstance(data.get("tools"), list):
|
|
|
|
|
+
|
|
|
|
|
+ old_tools = data["tools"]
|
|
|
|
|
+
|
|
|
|
|
+ new_tools = []
|
|
|
|
|
+
|
|
|
|
|
+ print("\n===== TOOLS =====")
|
|
|
|
|
+
|
|
|
|
|
+ for i, tool in enumerate(old_tools):
|
|
|
|
|
+
|
|
|
|
|
+ tool_type = tool.get("type")
|
|
|
|
|
+
|
|
|
|
|
+ if tool_type in SUPPORTED_TOOLS:
|
|
|
|
|
+
|
|
|
|
|
+ new_tools.append(tool)
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ f"[{i}] {tool_type:<25} KEEP"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ else:
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ f"[{i}] {str(tool_type):<25} DROP"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ data["tools"] = new_tools
|
|
|
|
|
+
|
|
|
|
|
+ # ------------------------------------------------
|
|
|
|
|
+ # 如果已经没有任何 tools
|
|
|
|
|
+ # Agnes 不允许:
|
|
|
|
|
+ #
|
|
|
|
|
+ # "tool_choice": "auto"
|
|
|
|
|
+ #
|
|
|
|
|
+ # 在没有 tools 的情况下存在
|
|
|
|
|
+ # ------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+ if not data["tools"]:
|
|
|
|
|
+
|
|
|
|
|
+ data.pop("tools", None)
|
|
|
|
|
+ data.pop("tool_choice", None)
|
|
|
|
|
+
|
|
|
|
|
+ # ----------------------------------------------------
|
|
|
|
|
+ # 没有 tools 时,强制删除 tool_choice
|
|
|
|
|
+ # ----------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+ if "tools" not in data:
|
|
|
|
|
+
|
|
|
|
|
+ data.pop("tool_choice", None)
|
|
|
|
|
+
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+ # 打印最终 Tools
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+
|
|
|
|
|
+ print("\n===== FINAL TOOLS =====")
|
|
|
|
|
+
|
|
|
|
|
+ if "tools" in data:
|
|
|
|
|
+
|
|
|
|
|
+ for i, tool in enumerate(data["tools"]):
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ f"[{i}] {tool.get('type')}"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ else:
|
|
|
|
|
+
|
|
|
|
|
+ print("No tools")
|
|
|
|
|
+
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+ # 重新生成 JSON
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+
|
|
|
|
|
+ body = json.dumps(
|
|
|
|
|
+ data,
|
|
|
|
|
+ ensure_ascii=False
|
|
|
|
|
+ ).encode("utf-8")
|
|
|
|
|
+
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+ # 打印最终请求
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+
|
|
|
|
|
+ print("\n===== REQUEST =====")
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ json.dumps(
|
|
|
|
|
+ data,
|
|
|
|
|
+ ensure_ascii=False,
|
|
|
|
|
+ indent=2
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ except Exception:
|
|
|
|
|
+
|
|
|
|
|
+ print(body[:2000])
|
|
|
|
|
+
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+ # 请求 Agnes
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+
|
|
|
|
|
+ req = urllib.request.Request(
|
|
|
|
|
+ AGNES_URL,
|
|
|
|
|
+ data=body,
|
|
|
|
|
+ method="POST",
|
|
|
|
|
+ headers={
|
|
|
|
|
+ "Authorization": f"Bearer {AGNES_KEY}",
|
|
|
|
|
+ "Content-Type": "application/json",
|
|
|
|
|
+
|
|
|
|
|
+ # Codex 一般会请求 SSE
|
|
|
|
|
+ "Accept": self.headers.get(
|
|
|
|
|
+ "Accept",
|
|
|
|
|
+ "text/event-stream"
|
|
|
|
|
+ ),
|
|
|
|
|
+ },
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+ # 发送到 Agnes
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+
|
|
|
|
|
+ resp = urllib.request.urlopen(
|
|
|
|
|
+ req,
|
|
|
|
|
+ timeout=600
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ "\nAgnes:",
|
|
|
|
|
+ resp.status
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ # ------------------------------------------------
|
|
|
|
|
+ # 返回 HTTP 状态
|
|
|
|
|
+ # ------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+ self.send_response(resp.status)
|
|
|
|
|
+
|
|
|
|
|
+ # ------------------------------------------------
|
|
|
|
|
+ # Content-Type
|
|
|
|
|
+ # ------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+ content_type = resp.headers.get(
|
|
|
|
|
+ "Content-Type",
|
|
|
|
|
+ "text/event-stream"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ self.send_header(
|
|
|
|
|
+ "Content-Type",
|
|
|
|
|
+ content_type
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ # ------------------------------------------------
|
|
|
|
|
+ # SSE / HTTP 相关 Header
|
|
|
|
|
+ # ------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+ self.send_header(
|
|
|
|
|
+ "Cache-Control",
|
|
|
|
|
+ "no-cache"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ self.send_header(
|
|
|
|
|
+ "Connection",
|
|
|
|
|
+ "keep-alive"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ self.end_headers()
|
|
|
|
|
+
|
|
|
|
|
+ # =================================================
|
|
|
|
|
+ # 流式转发 Agnes SSE
|
|
|
|
|
+ # =================================================
|
|
|
|
|
+
|
|
|
|
|
+ while True:
|
|
|
|
|
+
|
|
|
|
|
+ chunk = resp.read(4096)
|
|
|
|
|
+
|
|
|
|
|
+ if not chunk:
|
|
|
|
|
+ break
|
|
|
|
|
+
|
|
|
|
|
+ self.wfile.write(chunk)
|
|
|
|
|
+ self.wfile.flush()
|
|
|
|
|
+
|
|
|
|
|
+ print("\n===== AGNES STREAM END =====")
|
|
|
|
|
+
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+ # Agnes HTTP Error
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+
|
|
|
|
|
+ except urllib.error.HTTPError as e:
|
|
|
|
|
+
|
|
|
|
|
+ error_body = e.read()
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ "\n===== AGNES ERROR ====="
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ error_body.decode(
|
|
|
|
|
+ "utf-8",
|
|
|
|
|
+ errors="replace"
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+
|
|
|
|
|
+ self.send_response(e.code)
|
|
|
|
|
+
|
|
|
|
|
+ self.send_header(
|
|
|
|
|
+ "Content-Type",
|
|
|
|
|
+ "application/json"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ self.send_header(
|
|
|
|
|
+ "Connection",
|
|
|
|
|
+ "close"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ self.end_headers()
|
|
|
|
|
+
|
|
|
|
|
+ self.wfile.write(
|
|
|
|
|
+ error_body
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ except Exception as send_error:
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ "ERROR SENDING ERROR RESPONSE:",
|
|
|
|
|
+ repr(send_error)
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+ # 其他异常
|
|
|
|
|
+ # ====================================================
|
|
|
|
|
+
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ "\n===== PROXY ERROR ====="
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ repr(e)
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+
|
|
|
|
|
+ self.send_response(500)
|
|
|
|
|
+
|
|
|
|
|
+ self.send_header(
|
|
|
|
|
+ "Content-Type",
|
|
|
|
|
+ "application/json"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ self.send_header(
|
|
|
|
|
+ "Connection",
|
|
|
|
|
+ "close"
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ self.end_headers()
|
|
|
|
|
+
|
|
|
|
|
+ msg = json.dumps({
|
|
|
|
|
+ "error": {
|
|
|
|
|
+ "message": str(e),
|
|
|
|
|
+ "type": "proxy_error"
|
|
|
|
|
+ }
|
|
|
|
|
+ }).encode("utf-8")
|
|
|
|
|
+
|
|
|
|
|
+ self.wfile.write(msg)
|
|
|
|
|
+
|
|
|
|
|
+ except Exception:
|
|
|
|
|
+
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+ # ========================================================
|
|
|
|
|
+ # 禁止默认日志格式
|
|
|
|
|
+ # ========================================================
|
|
|
|
|
+
|
|
|
|
|
+ def log_message(self, fmt, *args):
|
|
|
|
|
+
|
|
|
|
|
+ print(
|
|
|
|
|
+ fmt % args
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+# 启动服务器
|
|
|
|
|
+# ============================================================
|
|
|
|
|
+
|
|
|
|
|
+server = ThreadingHTTPServer(
|
|
|
|
|
+ ("0.0.0.0", 4000),
|
|
|
|
|
+ Handler
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+print(
|
|
|
|
|
+ "Proxy listening on :4000"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+print(
|
|
|
|
|
+ "→",
|
|
|
|
|
+ AGNES_URL
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+print(
|
|
|
|
|
+ "Supported tools:",
|
|
|
|
|
+ ", ".join(SUPPORTED_TOOLS)
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+server.serve_forever()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# #!/usr/bin/env python3
|
|
|
|
|
+
|
|
|
|
|
+# from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
|
|
|
+# import urllib.request
|
|
|
|
|
+# import json
|
|
|
|
|
+
|
|
|
|
|
+# AGNES_URL = "https://apihub.agnes-ai.com/v1/responses"
|
|
|
|
|
+# AGNES_KEY = "sk-5bWELiz7grmKat0QTTQ6WJhEF4JWg8gMTPGOb4kcVOCMBrHH"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# class Handler(BaseHTTPRequestHandler):
|
|
|
|
|
+
|
|
|
|
|
+# protocol_version = "HTTP/1.1"
|
|
|
|
|
+
|
|
|
|
|
+# def do_POST(self):
|
|
|
|
|
+
|
|
|
|
|
+# if self.path != "/v1/responses":
|
|
|
|
|
+# self.send_error(404)
|
|
|
|
|
+# return
|
|
|
|
|
+
|
|
|
|
|
+# length = int(self.headers.get("Content-Length", 0))
|
|
|
|
|
+# body = self.rfile.read(length)
|
|
|
|
|
+
|
|
|
|
|
+# data = json.loads(body)
|
|
|
|
|
+
|
|
|
|
|
+# if data.get("model") == "gpt-5.5":
|
|
|
|
|
+# data["model"] = "agnes-3.0-flash"
|
|
|
|
|
+
|
|
|
|
|
+# # 2. 删除 Agnes 不支持的 custom tools
|
|
|
|
|
+# if "tools" in data:
|
|
|
|
|
+# tools = data["tools"]
|
|
|
|
|
+
|
|
|
|
|
+# if isinstance(tools, list):
|
|
|
|
|
+# data["tools"] = [
|
|
|
|
|
+# tool for tool in tools
|
|
|
|
|
+# if tool.get("type") != "custom"
|
|
|
|
|
+# ]
|
|
|
|
|
+
|
|
|
|
|
+# # 如果已经没有 tools,tool_choice 也必须删除
|
|
|
|
|
+# if not data["tools"]:
|
|
|
|
|
+# data.pop("tools", None)
|
|
|
|
|
+# data.pop("tool_choice", None)
|
|
|
|
|
+
|
|
|
|
|
+# # 3. 没有 tools 时不能存在 tool_choice
|
|
|
|
|
+# if "tools" not in data:
|
|
|
|
|
+# data.pop("tool_choice", None)
|
|
|
|
|
+
|
|
|
|
|
+# body = json.dumps(
|
|
|
|
|
+# data,
|
|
|
|
|
+# ensure_ascii=False
|
|
|
|
|
+# ).encode("utf-8")
|
|
|
|
|
+
|
|
|
|
|
+# print("\n===== REQUEST =====")
|
|
|
|
|
+# try:
|
|
|
|
|
+# print(json.dumps(json.loads(body), ensure_ascii=False, indent=2))
|
|
|
|
|
+# except:
|
|
|
|
|
+# print(body[:1000])
|
|
|
|
|
+
|
|
|
|
|
+# req = urllib.request.Request(
|
|
|
|
|
+# AGNES_URL,
|
|
|
|
|
+# data=body,
|
|
|
|
|
+# method="POST",
|
|
|
|
|
+# headers={
|
|
|
|
|
+# "Authorization": f"Bearer {AGNES_KEY}",
|
|
|
|
|
+# "Content-Type": "application/json",
|
|
|
|
|
+# "Accept": self.headers.get(
|
|
|
|
|
+# "Accept",
|
|
|
|
|
+# "text/event-stream"
|
|
|
|
|
+# ),
|
|
|
|
|
+# },
|
|
|
|
|
+# )
|
|
|
|
|
+
|
|
|
|
|
+# try:
|
|
|
|
|
+# resp = urllib.request.urlopen(req, timeout=600)
|
|
|
|
|
+
|
|
|
|
|
+# print("Agnes:", resp.status)
|
|
|
|
|
+
|
|
|
|
|
+# self.send_response(resp.status)
|
|
|
|
|
+
|
|
|
|
|
+# content_type = resp.headers.get(
|
|
|
|
|
+# "Content-Type",
|
|
|
|
|
+# "text/event-stream"
|
|
|
|
|
+# )
|
|
|
|
|
+
|
|
|
|
|
+# self.send_header("Content-Type", content_type)
|
|
|
|
|
+# self.send_header("Cache-Control", "no-cache")
|
|
|
|
|
+# self.send_header("Connection", "keep-alive")
|
|
|
|
|
+
|
|
|
|
|
+# self.end_headers()
|
|
|
|
|
+
|
|
|
|
|
+# while True:
|
|
|
|
|
+
|
|
|
|
|
+# chunk = resp.read(4096)
|
|
|
|
|
+
|
|
|
|
|
+# if not chunk:
|
|
|
|
|
+# break
|
|
|
|
|
+
|
|
|
|
|
+# self.wfile.write(chunk)
|
|
|
|
|
+# self.wfile.flush()
|
|
|
|
|
+
|
|
|
|
|
+# except urllib.error.HTTPError as e:
|
|
|
|
|
+
|
|
|
|
|
+# error_body = e.read()
|
|
|
|
|
+
|
|
|
|
|
+# print("\n===== AGNES ERROR =====")
|
|
|
|
|
+# print(error_body.decode("utf-8", errors="replace"))
|
|
|
|
|
+
|
|
|
|
|
+# self.send_response(e.code)
|
|
|
|
|
+# self.send_header("Content-Type", "application/json")
|
|
|
|
|
+# self.end_headers()
|
|
|
|
|
+# self.wfile.write(error_body)
|
|
|
|
|
+
|
|
|
|
|
+# except Exception as e:
|
|
|
|
|
+
|
|
|
|
|
+# print("ERROR:", repr(e))
|
|
|
|
|
+
|
|
|
|
|
+# try:
|
|
|
|
|
+# self.send_response(500)
|
|
|
|
|
+# self.send_header("Content-Type", "application/json")
|
|
|
|
|
+# self.end_headers()
|
|
|
|
|
+
|
|
|
|
|
+# msg = json.dumps({
|
|
|
|
|
+# "error": str(e)
|
|
|
|
|
+# }).encode()
|
|
|
|
|
+
|
|
|
|
|
+# self.wfile.write(msg)
|
|
|
|
|
+
|
|
|
|
|
+# except:
|
|
|
|
|
+# pass
|
|
|
|
|
+
|
|
|
|
|
+# def log_message(self, fmt, *args):
|
|
|
|
|
+# print(fmt % args)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# server = ThreadingHTTPServer(
|
|
|
|
|
+# ("0.0.0.0", 9000),
|
|
|
|
|
+# Handler
|
|
|
|
|
+# )
|
|
|
|
|
+
|
|
|
|
|
+# print("Proxy listening on :9000")
|
|
|
|
|
+# print("→", AGNES_URL)
|
|
|
|
|
+
|
|
|
|
|
+# server.serve_forever()
|