ituoke/agent/main.py

112 lines
3.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
[Agent 入口] Python 独立进程 — JSON-RPC over HTTP
改监听地址:HOST / PORT
改业务方法:handle_rpc 内的 method 分支
协议字段必须与 Go internal/protocol 对齐(protocolVersion=1.0)
"""
from __future__ import annotations
import json
import uuid
from http.server import BaseHTTPRequestHandler, HTTPServer
from typing import Any
HOST = "127.0.0.1"
PORT = 17890
PROTOCOL_VERSION = "1.0"
def handle_rpc(body: dict[str, Any]) -> dict[str, Any]:
# ---------- [关键] 所有 Agent method 分发在这里 ----------
req_id = body.get("id") or str(uuid.uuid4())
version = body.get("protocolVersion", "")
method = body.get("method", "")
params = body.get("params") or {}
if version != PROTOCOL_VERSION:
return {
"protocolVersion": PROTOCOL_VERSION,
"id": req_id,
"error": {
"code": -32000,
"message": f"protocol mismatch: got {version}, want {PROTOCOL_VERSION}",
},
}
if method == "agent.health":
return {
"protocolVersion": PROTOCOL_VERSION,
"id": req_id,
"result": {"ok": True, "engine": "python-stub"},
}
if method == "agent.chat":
# TODO[云端 API]: 在此接入 OpenAI / Claude 等
message = ""
if isinstance(params, dict):
message = str(params.get("message") or params.get("userMessage") or "")
return {
"protocolVersion": PROTOCOL_VERSION,
"id": req_id,
"result": {
"role": "assistant",
"content": f"(Python stub)收到:{message}",
},
}
if method == "agent.plan_next":
# TODO[多模态]: 解析 frameBase64 + userMessage → actions
return {
"protocolVersion": PROTOCOL_VERSION,
"id": req_id,
"result": {
"thought": "骨架:尚未接入视觉模型",
"actions": [],
},
}
return {
"protocolVersion": PROTOCOL_VERSION,
"id": req_id,
"error": {"code": -32601, "message": f"method not found: {method}"},
}
class RPCHandler(BaseHTTPRequestHandler):
def log_message(self, fmt: str, *args: Any) -> None:
print(f"[agent] {self.address_string()} - {fmt % args}")
def do_POST(self) -> None:
# [关键] 唯一 RPC 入口路径
if self.path != "/rpc":
self.send_error(404)
return
length = int(self.headers.get("Content-Length", "0"))
raw = self.rfile.read(length)
try:
body = json.loads(raw.decode("utf-8"))
except json.JSONDecodeError:
self._write(400, {"error": {"code": -32700, "message": "parse error"}})
return
self._write(200, handle_rpc(body))
def _write(self, status: int, payload: dict[str, Any]) -> None:
data = json.dumps(payload, ensure_ascii=False).encode("utf-8")
self.send_response(status)
self.send_header("Content-Type", "application/json; charset=utf-8")
self.send_header("Content-Length", str(len(data)))
self.end_headers()
self.wfile.write(data)
def main() -> None:
server = HTTPServer((HOST, PORT), RPCHandler)
print(f"[agent] listening on http://{HOST}:{PORT}/rpc protocol={PROTOCOL_VERSION}")
server.serve_forever()
if __name__ == "__main__":
main()