2020import sys
2121
2222try :
23+ from a2a .client import ClientEvent as A2AClientEvent
2324 from a2a .types import DataPart as A2ADataPart
2425 from a2a .types import Message as A2AMessage
2526 from a2a .types import Part as A2APart
26- from a2a .types import SendMessageRequest
27- from a2a .types import SendMessageResponse
2827 from a2a .types import Task as A2ATask
2928 from a2a .types import TextPart as A2ATextPart
3029except ImportError as e :
@@ -49,6 +48,16 @@ def _is_a2a_task(obj) -> bool:
4948 return type (obj ).__name__ == "Task" and hasattr (obj , "status" )
5049
5150
51+ def _is_a2a_client_event (obj ) -> bool :
52+ """Check if an object is an A2A Client Event (Task, UpdateEvent) tuple."""
53+ try :
54+ return isinstance (obj , tuple ) and _is_a2a_task (obj [0 ])
55+ except (TypeError , AttributeError ):
56+ return (
57+ hasattr (obj , "__getitem__" ) and len (obj ) == 2 and _is_a2a_task (obj [0 ])
58+ )
59+
60+
5261def _is_a2a_message (obj ) -> bool :
5362 """Check if an object is an A2A Message, with fallback for isinstance issues."""
5463 try :
@@ -114,7 +123,7 @@ def build_message_part_log(part: A2APart) -> str:
114123 return part_content
115124
116125
117- def build_a2a_request_log (req : SendMessageRequest ) -> str :
126+ def build_a2a_request_log (req : A2AMessage ) -> str :
118127 """Builds a structured log representation of an A2A request.
119128
120129 Args:
@@ -125,100 +134,70 @@ def build_a2a_request_log(req: SendMessageRequest) -> str:
125134 """
126135 # Message parts logs
127136 message_parts_logs = []
128- if req .params . message . parts :
129- for i , part in enumerate (req .params . message . parts ):
137+ if req .parts :
138+ for i , part in enumerate (req .parts ):
130139 part_log = build_message_part_log (part )
131140 # Replace any internal newlines with indented newlines to maintain formatting
132141 part_log_formatted = part_log .replace ("\n " , "\n " )
133142 message_parts_logs .append (f"Part { i } : { part_log_formatted } " )
134143
135- # Configuration logs
136- config_log = "None"
137- if req .params .configuration :
138- config_data = {
139- "accepted_output_modes" : req .params .configuration .accepted_output_modes ,
140- "blocking" : req .params .configuration .blocking ,
141- "history_length" : req .params .configuration .history_length ,
142- "push_notification_config" : bool (
143- req .params .configuration .push_notification_config
144- ),
145- }
146- config_log = json .dumps (config_data , indent = 2 )
147-
148144 # Build message metadata section
149145 message_metadata_section = ""
150- if req .params . message . metadata :
146+ if req .metadata :
151147 message_metadata_section = f"""
152148 Metadata:
153- { json .dumps (req .params . message . metadata , indent = 2 ).replace (chr (10 ), chr (10 ) + ' ' )} """
149+ { json .dumps (req .metadata , indent = 2 ).replace (chr (10 ), chr (10 ) + ' ' )} """
154150
155151 # Build optional sections
156152 optional_sections = []
157153
158- if req .params . metadata :
154+ if req .metadata :
159155 optional_sections .append (
160156 f"""-----------------------------------------------------------
161157Metadata:
162- { json .dumps (req .params . metadata , indent = 2 )} """
158+ { json .dumps (req .metadata , indent = 2 )} """
163159 )
164160
165161 optional_sections_str = _NEW_LINE .join (optional_sections )
166162
167163 return f"""
168- A2A Request:
169- -----------------------------------------------------------
170- Request ID: { req .id }
171- Method: { req .method }
172- JSON-RPC: { req .jsonrpc }
164+ A2A Send Message Request:
173165-----------------------------------------------------------
174166Message:
175- ID: { req .params . message . message_id }
176- Role: { req .params . message . role }
177- Task ID: { req .params . message . task_id }
178- Context ID: { req .params . message . context_id } { message_metadata_section }
167+ ID: { req .message_id }
168+ Role: { req .role }
169+ Task ID: { req .task_id }
170+ Context ID: { req .context_id } { message_metadata_section }
179171-----------------------------------------------------------
180172Message Parts:
181173{ _NEW_LINE .join (message_parts_logs ) if message_parts_logs else "No parts" }
182174-----------------------------------------------------------
183- Configuration:
184- { config_log }
185175{ optional_sections_str }
186176-----------------------------------------------------------
187177"""
188178
189179
190- def build_a2a_response_log (resp : SendMessageResponse ) -> str :
180+ def build_a2a_response_log (resp : A2AClientEvent | A2AMessage ) -> str :
191181 """Builds a structured log representation of an A2A response.
192182
193183 Args:
194- resp: The A2A SendMessageResponse to log.
184+ resp: The A2A SendMessage Response to log.
195185
196186 Returns:
197187 A formatted string representation of the response.
198188 """
199- # Handle error responses
200- if hasattr (resp .root , "error" ):
201- return f"""
202- A2A Response:
203- -----------------------------------------------------------
204- Type: ERROR
205- Error Code: { resp .root .error .code }
206- Error Message: { resp .root .error .message }
207- Error Data: { json .dumps (resp .root .error .data , indent = 2 ) if resp .root .error .data else "None" }
208- -----------------------------------------------------------
209- Response ID: { resp .root .id }
210- JSON-RPC: { resp .root .jsonrpc }
211- -----------------------------------------------------------
212- """
213189
214190 # Handle success responses
215- result = resp . root . result
191+ result = resp
216192 result_type = type (result ).__name__
193+ if result_type == "tuple" :
194+ result_type = "ClientEvent"
217195
218196 # Build result details based on type
219197 result_details = []
220198
221- if _is_a2a_task (result ):
199+ if _is_a2a_client_event (result ):
200+ result = result [0 ]
222201 result_details .extend ([
223202 f"Task ID: { result .id } " ,
224203 f"Context ID: { result .context_id } " ,
@@ -342,7 +321,4 @@ def build_a2a_response_log(resp: SendMessageResponse) -> str:
342321History:
343322{ history_section }
344323-----------------------------------------------------------
345- Response ID: { resp .root .id }
346- JSON-RPC: { resp .root .jsonrpc }
347- -----------------------------------------------------------
348324"""
0 commit comments