Claude Code Claude Opus 4.6 commited on
Commit
eafbf79
·
1 Parent(s): 1405c4c

Claude Code: Fix A2A communication - add missing /a2a/jsonrpc endpoint

Browse files

- Add /a2a/jsonrpc endpoint to app.py for agent-to-agent communication
- Handle message/send method with brain integration
- Return proper JSON-RPC 2.0 responses
- This enables Cain to receive A2A messages from Adam/Eve

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +82 -0
app.py CHANGED
@@ -126,6 +126,88 @@ async def global_exception_handler(request: Request, exc: Exception):
126
  )
127
 
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  # ============================================================================
130
  # API STATUS ENDPOINT - Required by frontend
131
  # ============================================================================
 
126
  )
127
 
128
 
129
+ # ============================================================================
130
+ # A2A JSON-RPC ENDPOINT - Required for agent-to-agent communication
131
+ # ============================================================================
132
+ @app.post("/a2a/jsonrpc")
133
+ async def a2a_jsonrpc(request: Request):
134
+ """
135
+ Agent-to-Agent (A2A) JSON-RPC 2.0 endpoint for inter-agent communication.
136
+
137
+ Handles message/send requests from other agents in the HuggingClaw World family.
138
+ """
139
+ try:
140
+ payload = await request.json()
141
+
142
+ # Validate JSON-RPC 2.0 basic structure
143
+ if payload.get("jsonrpc") != "2.0":
144
+ return JSONResponse(
145
+ status_code=400,
146
+ content={"jsonrpc": "2.0", "id": payload.get("id"), "error": {"code": -32600, "message": "Invalid Request"}}
147
+ )
148
+
149
+ msg_id = payload.get("id", "")
150
+ method = payload.get("method", "")
151
+ params = payload.get("params", {})
152
+
153
+ # Handle message/send method
154
+ if method == "message/send":
155
+ # Lazy load brain for processing
156
+ from openclaw.openclaw.agents import brain_minimal
157
+
158
+ message = params.get("message", {})
159
+ message_text = ""
160
+ for part in message.get("parts", []):
161
+ if part.get("type") == "text":
162
+ message_text = part.get("text", "")
163
+ break
164
+
165
+ # Process the message through brain
166
+ try:
167
+ response = await brain_minimal.think_async(message_text) if hasattr(brain_minimal, 'think_async') else None
168
+ if not response:
169
+ response = f"Cain received: {message_text}"
170
+
171
+ # Build A2A JSON-RPC response
172
+ return {
173
+ "jsonrpc": "2.0",
174
+ "id": msg_id,
175
+ "result": {
176
+ "status": {
177
+ "state": "completed",
178
+ "message": {
179
+ "parts": [{"type": "text", "text": response}]
180
+ }
181
+ }
182
+ }
183
+ }
184
+ except Exception as e:
185
+ return {
186
+ "jsonrpc": "2.0",
187
+ "id": msg_id,
188
+ "result": {
189
+ "status": {
190
+ "state": "failed",
191
+ "message": {
192
+ "parts": [{"type": "text", "text": f"Error: {str(e)}"}]
193
+ }
194
+ }
195
+ }
196
+ }
197
+
198
+ # Unknown method
199
+ return JSONResponse(
200
+ status_code=400,
201
+ content={"jsonrpc": "2.0", "id": msg_id, "error": {"code": -32601, "message": "Method not found"}}
202
+ )
203
+
204
+ except Exception as e:
205
+ return JSONResponse(
206
+ status_code=500,
207
+ content={"jsonrpc": "2.0", "id": "", "error": {"code": -32603, "message": str(e)}}
208
+ )
209
+
210
+
211
  # ============================================================================
212
  # API STATUS ENDPOINT - Required by frontend
213
  # ============================================================================