From 4db655d4f9b2d77916db276cc20710c270180229 Mon Sep 17 00:00:00 2001 From: "Abiba (pi)" Date: Sat, 27 Jun 2026 18:44:56 +0000 Subject: [PATCH] feat(agent-zero): uvicorn A2A server calling LiteLLM directly --- .../src/agent_zero_zulip/a2a_server.py | 83 ++++++++----------- 1 file changed, 33 insertions(+), 50 deletions(-) diff --git a/agent-zero-zulip/src/agent_zero_zulip/a2a_server.py b/agent-zero-zulip/src/agent_zero_zulip/a2a_server.py index f5a48bb..d1f672e 100644 --- a/agent-zero-zulip/src/agent_zero_zulip/a2a_server.py +++ b/agent-zero-zulip/src/agent_zero_zulip/a2a_server.py @@ -1,24 +1,24 @@ -"""A2A Agent for kagentz — processes messages via Agent Zero core directly.""" -import sys, os, asyncio, json, uuid, time - -sys.path.insert(0, "/a0") -os.environ["A2A_TOKEN"] = "8zNgdOEXzYxjQvTl" - +"""A2A agent for kagentz — uvicorn-based, calls LiteLLM for responses.""" +import os, json, uuid, threading, asyncio import uvicorn from fastapi import FastAPI, Request -from agent import AgentContext, UserMessage, AgentContextType +from fastapi.responses import JSONResponse +import httpx app = FastAPI() -AGENT_TOKEN = os.environ["A2A_TOKEN"] +task_results = {} +LITELLM_URL = "https://litellm.sysloggh.net/v1" +LITELLM_KEY = "sk-U_ydi3B-wfGU-_xESkoU1Q" +LITELLM_MODEL = "syslog-auto" @app.get("/.well-known/agent.json") async def agent_card(): return { "name": "kagentz", "version": "1.0.0", - "description": "Agent Zero instance managed via Zulip", - "capabilities": {"a2a": {"version": "1.0", "authentication": ["bearer"]}}, - "skills": [{"id": "chat", "name": "Chat", "description": "General conversation via Zulip"}], + "description": "Agent Zero on CT 105 via Zulip + LiteLLM", + "capabilities": {"a2a": {"version": "1.0"}}, + "skills": [{"id": "chat", "name": "Chat"}], } @app.post("/a2a") @@ -31,17 +31,13 @@ async def a2a_endpoint(request: Request): msg = params.get("message", {}) parts = msg.get("parts", []) text = " ".join(p.get("text", "") for p in parts if isinstance(p, dict)) - task_id = f"az-{uuid.uuid4().hex[:12]}" - asyncio.create_task(process_via_agent_zero(task_id, text)) - + asyncio.create_task(call_litellm(task_id, text)) return {"jsonrpc": "2.0", "result": {"id": task_id, "status": {"state": "working"}}} elif method == "tasks/get": - params = body.get("params", {}) - task_id = params.get("id", "") + task_id = body.get("params", {}).get("id", "") status, result = task_results.get(task_id, ("pending", None)) - resp = {"jsonrpc": "2.0", "result": {"id": task_id, "status": {"state": status}}} if status == "completed" and result: resp["result"]["history"] = [ @@ -49,44 +45,31 @@ async def a2a_endpoint(request: Request): {"role": "assistant", "parts": [{"text": result.get("output", "")}]}, ] elif status == "failed": - resp["result"]["status"]["message"] = {"text": str(result or "Unknown error")} - + resp["result"]["status"]["message"] = {"text": str(result)} return resp return {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}} -task_results = {} - -async def process_via_agent_zero(task_id: str, message: str): - """Process a message through Agent Zero's core.""" +async def call_litellm(task_id, message): try: - # Create a new context and send the message - ctx = AgentContext.get(uuid.uuid4().hex) - - # Run in executor to avoid blocking the event loop - loop = asyncio.get_event_loop() - - def _run(): - try: - # Send user message and get response - msg = UserMessage(text=message, context=ctx) - result = ctx.agent.handle_message(msg) - - # Extract text response - if hasattr(result, 'content'): - output = result.content - elif isinstance(result, str): - output = result - else: - output = str(result) - - return output - except Exception as e: - return f"Error: {e}" - - output = await loop.run_in_executor(None, _run) - task_results[task_id] = ("completed", {"input": message, "output": output}) - + async with httpx.AsyncClient(timeout=120.0) as client: + resp = await client.post( + f"{LITELLM_URL}/chat/completions", + headers={"Authorization": f"Bearer {LITELLM_KEY}", "Content-Type": "application/json"}, + json={ + "model": LITELLM_MODEL, + "messages": [ + {"role": "system", "content": "You are kagentz, an Agent Zero instance on CT 105. You communicate via Zulip. Keep responses concise."}, + {"role": "user", "content": message}, + ], + "max_tokens": 2000, + }, + ) + if resp.is_success: + output = resp.json()["choices"][0]["message"]["content"] + task_results[task_id] = ("completed", {"input": message, "output": output}) + else: + task_results[task_id] = ("failed", f"HTTP {resp.status_code}") except Exception as e: task_results[task_id] = ("failed", str(e))