@@ -316,7 +316,7 @@ def end_model_invoke_span(
316316 [
317317 {
318318 "role" : message ["role" ],
319- "parts" : [{ "type" : "text" , "content" : message ["content" ]}] ,
319+ "parts" : self . _map_content_blocks_to_otel_parts ( message ["content" ]) ,
320320 "finish_reason" : str (stop_reason ),
321321 }
322322 ]
@@ -371,7 +371,7 @@ def start_tool_call_span(self, tool: ToolUse, parent_span: Optional[Span] = None
371371 "type" : "tool_call" ,
372372 "name" : tool ["name" ],
373373 "id" : tool ["toolUseId" ],
374- "arguments" : [{ "content" : tool ["input" ]} ],
374+ "arguments" : tool ["input" ],
375375 }
376376 ],
377377 }
@@ -426,7 +426,7 @@ def end_tool_call_span(
426426 {
427427 "type" : "tool_call_response" ,
428428 "id" : tool_result .get ("toolUseId" , "" ),
429- "result " : tool_result .get ("content" ),
429+ "response " : tool_result .get ("content" ),
430430 }
431431 ],
432432 }
@@ -513,7 +513,7 @@ def end_event_loop_cycle_span(
513513 [
514514 {
515515 "role" : tool_result_message ["role" ],
516- "parts" : [{ "type" : "text" , "content" : tool_result_message ["content" ]}] ,
516+ "parts" : self . _map_content_blocks_to_otel_parts ( tool_result_message ["content" ]) ,
517517 }
518518 ]
519519 )
@@ -643,19 +643,23 @@ def start_multiagent_span(
643643 )
644644
645645 span = self ._start_span (operation , attributes = attributes , span_kind = trace_api .SpanKind .CLIENT )
646- content = serialize (task ) if isinstance (task , list ) else task
647646
648647 if self .use_latest_genai_conventions :
648+ parts : list [dict [str , Any ]] = []
649+ if isinstance (task , list ):
650+ parts = self ._map_content_blocks_to_otel_parts (task )
651+ else :
652+ parts = [{"type" : "text" , "content" : task }]
649653 self ._add_event (
650654 span ,
651655 "gen_ai.client.inference.operation.details" ,
652- {"gen_ai.input.messages" : serialize ([{"role" : "user" , "parts" : [{ "type" : "text" , "content" : task }] }])},
656+ {"gen_ai.input.messages" : serialize ([{"role" : "user" , "parts" : parts }])},
653657 )
654658 else :
655659 self ._add_event (
656660 span ,
657661 "gen_ai.user.message" ,
658- event_attributes = {"content" : content },
662+ event_attributes = {"content" : serialize ( task ) if isinstance ( task , list ) else task },
659663 )
660664
661665 return span
@@ -727,7 +731,7 @@ def _add_event_messages(self, span: Span, messages: Messages) -> None:
727731 input_messages : list = []
728732 for message in messages :
729733 input_messages .append (
730- {"role" : message ["role" ], "parts" : [{ "type" : "text" , "content" : message ["content" ]}] }
734+ {"role" : message ["role" ], "parts" : self . _map_content_blocks_to_otel_parts ( message ["content" ]) }
731735 )
732736 self ._add_event (
733737 span , "gen_ai.client.inference.operation.details" , {"gen_ai.input.messages" : serialize (input_messages )}
@@ -740,6 +744,41 @@ def _add_event_messages(self, span: Span, messages: Messages) -> None:
740744 {"content" : serialize (message ["content" ])},
741745 )
742746
747+ def _map_content_blocks_to_otel_parts (self , content_blocks : list [ContentBlock ]) -> list [dict [str , Any ]]:
748+ """Map ContentBlock objects to OpenTelemetry parts format."""
749+ parts : list [dict [str , Any ]] = []
750+
751+ for block in content_blocks :
752+ if "text" in block :
753+ # Standard TextPart
754+ parts .append ({"type" : "text" , "content" : block ["text" ]})
755+ elif "toolUse" in block :
756+ # Standard ToolCallRequestPart
757+ tool_use = block ["toolUse" ]
758+ parts .append (
759+ {
760+ "type" : "tool_call" ,
761+ "name" : tool_use ["name" ],
762+ "id" : tool_use ["toolUseId" ],
763+ "arguments" : tool_use ["input" ],
764+ }
765+ )
766+ elif "toolResult" in block :
767+ # Standard ToolCallResponsePart
768+ tool_result = block ["toolResult" ]
769+ parts .append (
770+ {
771+ "type" : "tool_call_response" ,
772+ "id" : tool_result ["toolUseId" ],
773+ "response" : tool_result ["content" ],
774+ }
775+ )
776+ else :
777+ # For all other ContentBlock types, use the key as type and value as content
778+ for key , value in block .items ():
779+ parts .append ({"type" : key , "content" : value })
780+ return parts
781+
743782
744783# Singleton instance for global access
745784_tracer_instance = None
0 commit comments