1414
1515from  ..agent .agent_result  import  AgentResult 
1616from  ..types .content  import  Message , Messages 
17- from  ..types .streaming  import  Usage 
17+ from  ..types .streaming  import  StopReason ,  Usage 
1818from  ..types .tools  import  ToolResult , ToolUse 
1919from  ..types .traces  import  AttributeValue 
2020
@@ -196,20 +196,31 @@ def end_span_with_error(self, span: Span, error_message: str, exception: Optiona
196196        error  =  exception  or  Exception (error_message )
197197        self ._end_span (span , error = error )
198198
199+     def  _add_event (self , span : Optional [Span ], event_name : str , event_attributes : Dict [str , AttributeValue ]) ->  None :
200+         """Add an event with attributes to a span. 
201+ 
202+         Args: 
203+             span: The span to add the event to 
204+             event_name: Name of the event 
205+             event_attributes: Dictionary of attributes to set on the event 
206+         """ 
207+         if  not  span :
208+             return 
209+ 
210+         span .add_event (event_name , attributes = event_attributes )
211+ 
199212    def  start_model_invoke_span (
200213        self ,
214+         messages : Messages ,
201215        parent_span : Optional [Span ] =  None ,
202-         agent_name : str  =  "Strands Agent" ,
203-         messages : Optional [Messages ] =  None ,
204216        model_id : Optional [str ] =  None ,
205217        ** kwargs : Any ,
206218    ) ->  Optional [Span ]:
207219        """Start a new span for a model invocation. 
208220
209221        Args: 
222+             messages: Messages being sent to the model. 
210223            parent_span: Optional parent span to link this span to. 
211-             agent_name: Name of the agent making the model call. 
212-             messages: Optional messages being sent to the model. 
213224            model_id: Optional identifier for the model being invoked. 
214225            **kwargs: Additional attributes to add to the span. 
215226
@@ -219,8 +230,6 @@ def start_model_invoke_span(
219230        attributes : Dict [str , AttributeValue ] =  {
220231            "gen_ai.system" : "strands-agents" ,
221232            "gen_ai.operation.name" : "chat" ,
222-             "gen_ai.agent.name" : agent_name ,
223-             "gen_ai.prompt" : serialize (messages ),
224233        }
225234
226235        if  model_id :
@@ -229,28 +238,41 @@ def start_model_invoke_span(
229238        # Add additional kwargs as attributes 
230239        attributes .update ({k : v  for  k , v  in  kwargs .items () if  isinstance (v , (str , int , float , bool ))})
231240
232-         return  self ._start_span ("Model invoke" , parent_span , attributes , span_kind = trace_api .SpanKind .CLIENT )
241+         span  =  self ._start_span ("Model invoke" , parent_span , attributes , span_kind = trace_api .SpanKind .CLIENT )
242+         for  message  in  messages :
243+             self ._add_event (
244+                 span ,
245+                 f"gen_ai.{ message ['role' ]}  ,
246+                 {"content" : serialize (message ["content" ])},
247+             )
248+         return  span 
233249
234250    def  end_model_invoke_span (
235-         self , span : Span , message : Message , usage : Usage , error : Optional [Exception ] =  None 
251+         self , span : Span , message : Message , usage : Usage , stop_reason :  StopReason ,  error : Optional [Exception ] =  None 
236252    ) ->  None :
237253        """End a model invocation span with results and metrics. 
238254
239255        Args: 
240256            span: The span to end. 
241257            message: The message response from the model. 
242258            usage: Token usage information from the model call. 
259+             stop_reason (StopReason): The reason the model stopped generating. 
243260            error: Optional exception if the model call failed. 
244261        """ 
245262        attributes : Dict [str , AttributeValue ] =  {
246-             "gen_ai.completion" : serialize (message ["content" ]),
247263            "gen_ai.usage.prompt_tokens" : usage ["inputTokens" ],
248264            "gen_ai.usage.input_tokens" : usage ["inputTokens" ],
249265            "gen_ai.usage.completion_tokens" : usage ["outputTokens" ],
250266            "gen_ai.usage.output_tokens" : usage ["outputTokens" ],
251267            "gen_ai.usage.total_tokens" : usage ["totalTokens" ],
252268        }
253269
270+         self ._add_event (
271+             span ,
272+             "gen_ai.choice" ,
273+             event_attributes = {"finish_reason" : str (stop_reason ), "message" : serialize (message ["content" ])},
274+         )
275+ 
254276        self ._end_span (span , attributes , error )
255277
256278    def  start_tool_call_span (self , tool : ToolUse , parent_span : Optional [Span ] =  None , ** kwargs : Any ) ->  Optional [Span ]:
@@ -265,18 +287,29 @@ def start_tool_call_span(self, tool: ToolUse, parent_span: Optional[Span] = None
265287            The created span, or None if tracing is not enabled. 
266288        """ 
267289        attributes : Dict [str , AttributeValue ] =  {
268-             "gen_ai.prompt " : serialize ( tool ) ,
290+             "gen_ai.operation.name " : "execute_tool" ,
269291            "gen_ai.system" : "strands-agents" ,
270-             "tool.name" : tool ["name" ],
271-             "tool.id" : tool ["toolUseId" ],
272-             "tool.parameters" : serialize (tool ["input" ]),
292+             "gen_ai.tool.name" : tool ["name" ],
293+             "gen_ai.tool.call.id" : tool ["toolUseId" ],
273294        }
274295
275296        # Add additional kwargs as attributes 
276297        attributes .update (kwargs )
277298
278299        span_name  =  f"Tool: { tool ['name' ]}  
279-         return  self ._start_span (span_name , parent_span , attributes , span_kind = trace_api .SpanKind .INTERNAL )
300+         span  =  self ._start_span (span_name , parent_span , attributes , span_kind = trace_api .SpanKind .INTERNAL )
301+ 
302+         self ._add_event (
303+             span ,
304+             "gen_ai.tool.message" ,
305+             event_attributes = {
306+                 "role" : "tool" ,
307+                 "content" : serialize (tool ["input" ]),
308+                 "id" : tool ["toolUseId" ],
309+             },
310+         )
311+ 
312+         return  span 
280313
281314    def  end_tool_call_span (
282315        self , span : Span , tool_result : Optional [ToolResult ], error : Optional [Exception ] =  None 
@@ -293,30 +326,36 @@ def end_tool_call_span(
293326            status  =  tool_result .get ("status" )
294327            status_str  =  str (status ) if  status  is  not None  else  "" 
295328
296-             tool_result_content_json  =  serialize (tool_result .get ("content" ))
297329            attributes .update (
298330                {
299-                     "tool.result" : tool_result_content_json ,
300-                     "gen_ai.completion" : tool_result_content_json ,
301331                    "tool.status" : status_str ,
302332                }
303333            )
304334
335+             self ._add_event (
336+                 span ,
337+                 "gen_ai.choice" ,
338+                 event_attributes = {
339+                     "message" : serialize (tool_result .get ("content" )),
340+                     "id" : tool_result .get ("toolUseId" , "" ),
341+                 },
342+             )
343+ 
305344        self ._end_span (span , attributes , error )
306345
307346    def  start_event_loop_cycle_span (
308347        self ,
309348        event_loop_kwargs : Any ,
349+         messages : Messages ,
310350        parent_span : Optional [Span ] =  None ,
311-         messages : Optional [Messages ] =  None ,
312351        ** kwargs : Any ,
313352    ) ->  Optional [Span ]:
314353        """Start a new span for an event loop cycle. 
315354
316355        Args: 
317356            event_loop_kwargs: Arguments for the event loop cycle. 
318357            parent_span: Optional parent span to link this span to. 
319-             messages: Optional messages  being processed in this cycle. 
358+             messages:  Messages  being processed in this cycle. 
320359            **kwargs: Additional attributes to add to the span. 
321360
322361        Returns: 
@@ -326,7 +365,6 @@ def start_event_loop_cycle_span(
326365        parent_span  =  parent_span  if  parent_span  else  event_loop_kwargs .get ("event_loop_parent_span" )
327366
328367        attributes : Dict [str , AttributeValue ] =  {
329-             "gen_ai.prompt" : serialize (messages ),
330368            "event_loop.cycle_id" : event_loop_cycle_id ,
331369        }
332370
@@ -337,7 +375,15 @@ def start_event_loop_cycle_span(
337375        attributes .update ({k : v  for  k , v  in  kwargs .items () if  isinstance (v , (str , int , float , bool ))})
338376
339377        span_name  =  f"Cycle { event_loop_cycle_id }  
340-         return  self ._start_span (span_name , parent_span , attributes , span_kind = trace_api .SpanKind .INTERNAL )
378+         span  =  self ._start_span (span_name , parent_span , attributes )
379+         for  message  in  messages  or  []:
380+             self ._add_event (
381+                 span ,
382+                 f"gen_ai.{ message ['role' ]}  ,
383+                 {"content" : serialize (message ["content" ])},
384+             )
385+ 
386+         return  span 
341387
342388    def  end_event_loop_cycle_span (
343389        self ,
@@ -354,13 +400,12 @@ def end_event_loop_cycle_span(
354400            tool_result_message: Optional tool result message if a tool was called. 
355401            error: Optional exception if the cycle failed. 
356402        """ 
357-         attributes : Dict [str , AttributeValue ] =  {
358-             "gen_ai.completion" : serialize (message ["content" ]),
359-         }
403+         attributes : Dict [str , AttributeValue ] =  {}
404+         event_attributes : Dict [str , AttributeValue ] =  {"message" : serialize (message ["content" ])}
360405
361406        if  tool_result_message :
362-             attributes ["tool.result" ] =  serialize (tool_result_message ["content" ])
363- 
407+             event_attributes ["tool.result" ] =  serialize (tool_result_message ["content" ])
408+          self . _add_event ( span ,  "gen_ai.choice" ,  event_attributes = event_attributes ) 
364409        self ._end_span (span , attributes , error )
365410
366411    def  start_agent_span (
@@ -387,17 +432,15 @@ def start_agent_span(
387432        """ 
388433        attributes : Dict [str , AttributeValue ] =  {
389434            "gen_ai.system" : "strands-agents" ,
390-             "agent.name" : agent_name ,
391435            "gen_ai.agent.name" : agent_name ,
392-             "gen_ai.prompt " : prompt ,
436+             "gen_ai.operation.name " : "invoke_agent" ,
393437        }
394438
395439        if  model_id :
396440            attributes ["gen_ai.request.model" ] =  model_id 
397441
398442        if  tools :
399443            tools_json  =  serialize (tools )
400-             attributes ["agent.tools" ] =  tools_json 
401444            attributes ["gen_ai.agent.tools" ] =  tools_json 
402445
403446        # Add custom trace attributes if provided 
@@ -407,7 +450,18 @@ def start_agent_span(
407450        # Add additional kwargs as attributes 
408451        attributes .update ({k : v  for  k , v  in  kwargs .items () if  isinstance (v , (str , int , float , bool ))})
409452
410-         return  self ._start_span (agent_name , attributes = attributes , span_kind = trace_api .SpanKind .CLIENT )
453+         span  =  self ._start_span (
454+             f"invoke_agent { agent_name }  , attributes = attributes , span_kind = trace_api .SpanKind .CLIENT 
455+         )
456+         self ._add_event (
457+             span ,
458+             "gen_ai.user.message" ,
459+             event_attributes = {
460+                 "content" : prompt ,
461+             },
462+         )
463+ 
464+         return  span 
411465
412466    def  end_agent_span (
413467        self ,
@@ -426,10 +480,10 @@ def end_agent_span(
426480        attributes : Dict [str , AttributeValue ] =  {}
427481
428482        if  response :
429-             attributes . update (
430-                 { 
431-                      "gen_ai.completion"  :  str ( response ) ,
432-                 } 
483+             self . _add_event (
484+                 span , 
485+                 "gen_ai.choice"  ,
486+                 event_attributes = { "message" :  str ( response ),  "finish_reason" :  str ( response . stop_reason )}, 
433487            )
434488
435489            if  hasattr (response , "metrics" ) and  hasattr (response .metrics , "accumulated_usage" ):
0 commit comments