@@ -51,8 +51,63 @@ def upload_metrics(
5151 exporter .meter_uploader .record (llm_request , llm_response )
5252
5353
54+ def _set_agent_input_attribute (
55+ span : _Span , invocation_context : InvocationContext
56+ ) -> None :
57+ # We only save the original user input as the agent input
58+ # hence once the `agent.input` has been set, we don't overwrite it
59+ event_names = [event .name for event in span .events ]
60+ if "gen_ai.user.message" in event_names :
61+ return
62+
63+ # input = {
64+ # "agent_name": invocation_context.agent.name,
65+ # "app_name": invocation_context.session.app_name,
66+ # "user_id": invocation_context.user_id,
67+ # "session_id": invocation_context.session.id,
68+ # "input": invocation_context.user_content.model_dump(exclude_none=True)
69+ # if invocation_context.user_content
70+ # else None,
71+ # }
72+
73+ user_content = invocation_context .user_content
74+ if user_content and user_content .parts :
75+ span .add_event (
76+ "gen_ai.user.message" ,
77+ {
78+ "agent_name" : invocation_context .agent .name ,
79+ "app_name" : invocation_context .session .app_name ,
80+ "user_id" : invocation_context .user_id ,
81+ "session_id" : invocation_context .session .id ,
82+ },
83+ )
84+ for idx , part in enumerate (user_content .parts ):
85+ if part .text :
86+ span .add_event (
87+ "gen_ai.user.message" ,
88+ {f"parts.{ idx } .type" : "text" , f"parts.{ idx } .content" : part .text },
89+ )
90+
91+
92+ def _set_agent_output_attribute (span : _Span , llm_response : LlmResponse ) -> None :
93+ content = llm_response .content
94+ if content and content .parts :
95+ for idx , part in enumerate (content .parts ):
96+ if part .text :
97+ span .add_event (
98+ "gen_ai.choice" ,
99+ {
100+ f"message.parts.{ idx } .type" : "text" ,
101+ f"message.parts.{ idx } .text" : part .text ,
102+ },
103+ )
104+
105+
54106def set_common_attributes_on_model_span (
55- invocation_context : InvocationContext , current_span : _Span , ** kwargs
107+ invocation_context : InvocationContext ,
108+ llm_response : LlmResponse ,
109+ current_span : _Span ,
110+ ** kwargs ,
56111) -> None :
57112 if current_span .context :
58113 current_span_id = current_span .context .trace_id
@@ -76,8 +131,12 @@ def set_common_attributes_on_model_span(
76131 if span .is_recording ():
77132 if span .name .startswith ("invocation" ):
78133 span .set_attribute ("gen_ai.operation.name" , "chain" )
134+ _set_agent_input_attribute (span , invocation_context )
135+ _set_agent_output_attribute (span , llm_response )
79136 elif span .name .startswith ("agent_run" ):
80137 span .set_attribute ("gen_ai.operation.name" , "agent" )
138+ _set_agent_input_attribute (span , invocation_context )
139+ _set_agent_output_attribute (span , llm_response )
81140 for attr_name , attr_extractor in common_attributes .items ():
82141 value = attr_extractor (** kwargs )
83142 span .set_attribute (attr_name , value )
@@ -139,6 +198,7 @@ def trace_call_llm(
139198
140199 set_common_attributes_on_model_span (
141200 invocation_context = invocation_context ,
201+ llm_response = llm_response ,
142202 current_span = span , # type: ignore
143203 agent_name = invocation_context .agent .name ,
144204 user_id = invocation_context .user_id ,
0 commit comments