diff --git a/server.py b/server.py index 4592ba0..7ceb75a 100644 --- a/server.py +++ b/server.py @@ -268,60 +268,50 @@ async def handle_agent0_mcp( valid_poses: list[str], ) -> ChatResponse: """ - Send a message to a live Agent Zero instance via its MCP streamable-http - server and return the response as a ChatResponse. + Send a message to a live Agent Zero instance via its REST API + (POST /api/api_message, X-API-KEY header). - MCP URL format: {endpoint}/mcp/t-{mcp_key}/http - Tool called: send_message (built into every Agent Zero instance) - - Conversation continuity is maintained via Agent Zero's chat_id, which maps - to a gnommoweb conversation_id in _a0_sessions (in-memory). + Conversation continuity is maintained via Agent Zero's context_id, which + maps to a gnommoweb conversation_id in _a0_sessions (in-memory). """ - from mcp.client.streamable_http import streamablehttp_client - from mcp import ClientSession - endpoint = (model.endpoint or "").strip().rstrip("/") - mcp_key = model.mcp_key or "" - mcp_url = f"{endpoint}/mcp/t-{mcp_key}/http" + api_key = model.mcp_key or "" # stored in mcp_key field; used as X-API-KEY + api_url = f"{endpoint}/api/api_message" - # Retrieve existing Agent0 chat_id for this conversation (if any) - a0_chat_id = _a0_sessions.get(req.conversation_id) if req.conversation_id else None + # Retrieve existing Agent0 context_id for this conversation (if any) + a0_context_id = _a0_sessions.get(req.conversation_id) if req.conversation_id else None log.info( - f"[{agent.name}] → Agent0 MCP url={mcp_url} " - f"conv={req.conversation_id} a0_chat={a0_chat_id or 'new'} " + f"[{agent.name}] → Agent0 REST url={api_url} " + f"conv={req.conversation_id} a0_ctx={a0_context_id or 'new'} " f"msg='{req.message[:60]}'" ) try: - async with streamablehttp_client(mcp_url) as (read, write, _): - async with ClientSession(read, write) as session: - await session.initialize() + payload: dict = { + "message": req.message, + "lifetime_hours": 24, + } + if a0_context_id: + payload["context_id"] = a0_context_id - tool_args: dict = { - "message": req.message, - "persistent_chat": True, - } - if a0_chat_id: - tool_args["chat_id"] = a0_chat_id + async with httpx.AsyncClient(timeout=120.0) as client: + r = await client.post( + api_url, + headers={"X-API-KEY": api_key, "Content-Type": "application/json"}, + json=payload, + ) + r.raise_for_status() - result = await session.call_tool("send_message", tool_args) + data = r.json() + log.info(f"[{agent.name}] ← Agent0 REST: {str(data)[:300]}") - # The tool returns a JSON-serialised ToolResponse / ToolError - raw = result.content[0].text if result.content else "{}" - log.info(f"[{agent.name}] ← Agent0 MCP raw: {raw[:300]}") + response_text = data.get("response", "") + new_context_id = data.get("context_id", "") - parsed = json.loads(raw) - - if parsed.get("status") == "error": - raise RuntimeError(parsed.get("error", "Unknown Agent0 error")) - - response_text = parsed.get("response", "") - new_chat_id = parsed.get("chat_id", "") - - # Persist the Agent0 chat_id so the next turn continues the same context - if new_chat_id and req.conversation_id is not None: - _a0_sessions[req.conversation_id] = new_chat_id + # Persist context_id for conversation continuity + if new_context_id and req.conversation_id is not None: + _a0_sessions[req.conversation_id] = new_context_id pose = pick_pose(response_text, valid_poses) @@ -334,7 +324,7 @@ async def handle_agent0_mcp( ) except Exception as e: - log.error(f"[{agent.name}] Agent0 MCP error: {e}") + log.error(f"[{agent.name}] Agent0 REST error: {e}") fallback_pose = next( (p for p in ("sorry", "annoyed", "neutral") if p in valid_poses), valid_poses[0],