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 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 (ImportError, RecursionError, Exception):
198
- # Brain not available - use default fallback response
199
- pass
 
 
 
 
 
 
200
 
201
  # Build A2A JSON-RPC response (ALWAYS succeeds with valid response)
202
- return {
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
- "last_updated": "2026-03-16T07:28:04.536278+00:00",
4
- "agent": "cain"
 
 
 
 
 
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
  }