Spaces:
Sleeping
Sleeping
Claude Code Claude Opus 4.6 commited on
Commit ·
95148ba
1
Parent(s): eaed9e2
Claude Code: Fix A2A communication - add error logging and diagnostics
Browse files- Add specific exception handling in /a2a/jsonrpc endpoint (ImportError, RecursionError, general Exception)
- Add diagnostic logging for brain import failures
- Include brain_error in A2A response when brain processing fails
- Add error type to outer exception handler response
- Add startup verification of openclaw and brain_minimal imports
- Add A2A endpoint registration messages at startup
- Update cain_status.json to include stage field and A2A config
- Add detailed logging in /a2a/health endpoint for debugging
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- app.py +35 -5
- openclaw/.openclaw/agents/cain_status.json +7 -2
app.py
CHANGED
|
@@ -181,6 +181,7 @@ async def a2a_jsonrpc(request: Request):
|
|
| 181 |
# CRITICAL: Always provide a default response
|
| 182 |
response = f"Cain received: {message_text}"
|
| 183 |
|
|
|
|
| 184 |
try:
|
| 185 |
import openclaw # Sets up sys.path
|
| 186 |
from agents import brain_minimal
|
|
@@ -194,12 +195,18 @@ async def a2a_jsonrpc(request: Request):
|
|
| 194 |
enhanced_response = result.get("response", "")
|
| 195 |
if enhanced_response and not enhanced_response.startswith("Error:"):
|
| 196 |
response = enhanced_response
|
| 197 |
-
except
|
| 198 |
-
|
| 199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
|
| 201 |
# Build A2A JSON-RPC response (ALWAYS succeeds with valid response)
|
| 202 |
-
|
| 203 |
"jsonrpc": "2.0",
|
| 204 |
"id": msg_id,
|
| 205 |
"result": {
|
|
@@ -211,6 +218,10 @@ async def a2a_jsonrpc(request: Request):
|
|
| 211 |
}
|
| 212 |
}
|
| 213 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
|
| 215 |
# Unknown method
|
| 216 |
return JSONResponse(
|
|
@@ -219,9 +230,10 @@ async def a2a_jsonrpc(request: Request):
|
|
| 219 |
)
|
| 220 |
|
| 221 |
except Exception as e:
|
|
|
|
| 222 |
return JSONResponse(
|
| 223 |
status_code=500,
|
| 224 |
-
content={"jsonrpc": "2.0", "id": "", "error": {"code": -32603, "message": str(e)}}
|
| 225 |
)
|
| 226 |
|
| 227 |
|
|
@@ -285,23 +297,29 @@ async def a2a_health():
|
|
| 285 |
if not hasattr(brain_minimal, 'get_brain'):
|
| 286 |
brain_status = "error"
|
| 287 |
error_details = "get_brain method not found"
|
|
|
|
| 288 |
else:
|
| 289 |
brain = brain_minimal.get_brain(agent_name="cain", legacy_mode=True)
|
| 290 |
if hasattr(brain, '_conversation_process'):
|
| 291 |
brain_status = "ready"
|
| 292 |
brain_ready = True
|
|
|
|
| 293 |
else:
|
| 294 |
brain_status = "error"
|
| 295 |
error_details = "_conversation_process method not found"
|
|
|
|
| 296 |
except ImportError as e:
|
| 297 |
brain_status = "import_error"
|
| 298 |
error_details = str(e)
|
|
|
|
| 299 |
except RecursionError as e:
|
| 300 |
brain_status = "recursion_error"
|
| 301 |
error_details = "Circular import detected - openclaw init issue"
|
|
|
|
| 302 |
except Exception as e:
|
| 303 |
brain_status = "error"
|
| 304 |
error_details = str(e)
|
|
|
|
| 305 |
|
| 306 |
# A2A endpoint is ALWAYS available (this endpoint responding proves it)
|
| 307 |
# Brain readiness is informational, not blocking
|
|
@@ -320,6 +338,18 @@ async def a2a_health():
|
|
| 320 |
}
|
| 321 |
|
| 322 |
print(">>> CAIN: FastAPI app created successfully", flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 323 |
|
| 324 |
# ============================================================================
|
| 325 |
# STARTUP DIAGNOSTIC ENDPOINT
|
|
|
|
| 181 |
# CRITICAL: Always provide a default response
|
| 182 |
response = f"Cain received: {message_text}"
|
| 183 |
|
| 184 |
+
brain_error = None
|
| 185 |
try:
|
| 186 |
import openclaw # Sets up sys.path
|
| 187 |
from agents import brain_minimal
|
|
|
|
| 195 |
enhanced_response = result.get("response", "")
|
| 196 |
if enhanced_response and not enhanced_response.startswith("Error:"):
|
| 197 |
response = enhanced_response
|
| 198 |
+
except ImportError as e:
|
| 199 |
+
brain_error = f"ImportError: {e}"
|
| 200 |
+
print(f">>> CAIN A2A: Brain import error: {e}", flush=True)
|
| 201 |
+
except RecursionError as e:
|
| 202 |
+
brain_error = f"RecursionError: {e}"
|
| 203 |
+
print(f">>> CAIN A2A: Recursion error (circular import): {e}", flush=True)
|
| 204 |
+
except Exception as e:
|
| 205 |
+
brain_error = f"{type(e).__name__}: {e}"
|
| 206 |
+
print(f">>> CAIN A2A: Brain processing error: {type(e).__name__}: {e}", flush=True)
|
| 207 |
|
| 208 |
# Build A2A JSON-RPC response (ALWAYS succeeds with valid response)
|
| 209 |
+
result_response = {
|
| 210 |
"jsonrpc": "2.0",
|
| 211 |
"id": msg_id,
|
| 212 |
"result": {
|
|
|
|
| 218 |
}
|
| 219 |
}
|
| 220 |
}
|
| 221 |
+
# Add brain error as diagnostic info if present
|
| 222 |
+
if brain_error:
|
| 223 |
+
result_response["result"]["brain_error"] = brain_error
|
| 224 |
+
return result_response
|
| 225 |
|
| 226 |
# Unknown method
|
| 227 |
return JSONResponse(
|
|
|
|
| 230 |
)
|
| 231 |
|
| 232 |
except Exception as e:
|
| 233 |
+
print(f">>> CAIN A2A: Unhandled error: {type(e).__name__}: {e}", flush=True)
|
| 234 |
return JSONResponse(
|
| 235 |
status_code=500,
|
| 236 |
+
content={"jsonrpc": "2.0", "id": "", "error": {"code": -32603, "message": str(e), "type": type(e).__name__}}
|
| 237 |
)
|
| 238 |
|
| 239 |
|
|
|
|
| 297 |
if not hasattr(brain_minimal, 'get_brain'):
|
| 298 |
brain_status = "error"
|
| 299 |
error_details = "get_brain method not found"
|
| 300 |
+
print(f">>> CAIN A2A Health: brain_minimal missing get_brain method", flush=True)
|
| 301 |
else:
|
| 302 |
brain = brain_minimal.get_brain(agent_name="cain", legacy_mode=True)
|
| 303 |
if hasattr(brain, '_conversation_process'):
|
| 304 |
brain_status = "ready"
|
| 305 |
brain_ready = True
|
| 306 |
+
print(f">>> CAIN A2A Health: Brain ready (agent={brain.agent_name if hasattr(brain, 'agent_name') else 'unknown'})", flush=True)
|
| 307 |
else:
|
| 308 |
brain_status = "error"
|
| 309 |
error_details = "_conversation_process method not found"
|
| 310 |
+
print(f">>> CAIN A2A Health: Brain missing _conversation_process", flush=True)
|
| 311 |
except ImportError as e:
|
| 312 |
brain_status = "import_error"
|
| 313 |
error_details = str(e)
|
| 314 |
+
print(f">>> CAIN A2A Health: ImportError - {e}", flush=True)
|
| 315 |
except RecursionError as e:
|
| 316 |
brain_status = "recursion_error"
|
| 317 |
error_details = "Circular import detected - openclaw init issue"
|
| 318 |
+
print(f">>> CAIN A2A Health: RecursionError - {e}", flush=True)
|
| 319 |
except Exception as e:
|
| 320 |
brain_status = "error"
|
| 321 |
error_details = str(e)
|
| 322 |
+
print(f">>> CAIN A2A Health: Exception - {type(e).__name__}: {e}", flush=True)
|
| 323 |
|
| 324 |
# A2A endpoint is ALWAYS available (this endpoint responding proves it)
|
| 325 |
# Brain readiness is informational, not blocking
|
|
|
|
| 338 |
}
|
| 339 |
|
| 340 |
print(">>> CAIN: FastAPI app created successfully", flush=True)
|
| 341 |
+
print(">>> CAIN: A2A endpoint registered at /a2a/jsonrpc", flush=True)
|
| 342 |
+
print(">>> CAIN: A2A health check at /a2a/health", flush=True)
|
| 343 |
+
print(">>> CAIN: A2A diagnostics at /a2a/diagnostics", flush=True)
|
| 344 |
+
|
| 345 |
+
# Verify openclaw can be imported at startup
|
| 346 |
+
try:
|
| 347 |
+
import openclaw
|
| 348 |
+
print(f">>> CAIN: openclaw imported from {openclaw.__file__}", flush=True)
|
| 349 |
+
from agents import brain_minimal
|
| 350 |
+
print(">>> CAIN: brain_minimal module available", flush=True)
|
| 351 |
+
except Exception as e:
|
| 352 |
+
print(f">>> CAIN WARNING: Could not import brain modules at startup: {e}", flush=True)
|
| 353 |
|
| 354 |
# ============================================================================
|
| 355 |
# STARTUP DIAGNOSTIC ENDPOINT
|
openclaw/.openclaw/agents/cain_status.json
CHANGED
|
@@ -1,5 +1,10 @@
|
|
| 1 |
{
|
| 2 |
"current_state": "idle",
|
| 3 |
-
"
|
| 4 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"current_state": "idle",
|
| 3 |
+
"stage": "RUNNING",
|
| 4 |
+
"last_updated": "2026-03-16T10:20:00.000000+00:00",
|
| 5 |
+
"agent": "cain",
|
| 6 |
+
"a2a": {
|
| 7 |
+
"endpoint": "/a2a/jsonrpc",
|
| 8 |
+
"enabled": true
|
| 9 |
+
}
|
| 10 |
}
|