@@ -51,8 +51,63 @@ def upload_metrics(
51
51
exporter .meter_uploader .record (llm_request , llm_response )
52
52
53
53
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
+
54
106
def 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 ,
56
111
) -> None :
57
112
if current_span .context :
58
113
current_span_id = current_span .context .trace_id
@@ -76,8 +131,12 @@ def set_common_attributes_on_model_span(
76
131
if span .is_recording ():
77
132
if span .name .startswith ("invocation" ):
78
133
span .set_attribute ("gen_ai.operation.name" , "chain" )
134
+ _set_agent_input_attribute (span , invocation_context )
135
+ _set_agent_output_attribute (span , llm_response )
79
136
elif span .name .startswith ("agent_run" ):
80
137
span .set_attribute ("gen_ai.operation.name" , "agent" )
138
+ _set_agent_input_attribute (span , invocation_context )
139
+ _set_agent_output_attribute (span , llm_response )
81
140
for attr_name , attr_extractor in common_attributes .items ():
82
141
value = attr_extractor (** kwargs )
83
142
span .set_attribute (attr_name , value )
@@ -139,6 +198,7 @@ def trace_call_llm(
139
198
140
199
set_common_attributes_on_model_span (
141
200
invocation_context = invocation_context ,
201
+ llm_response = llm_response ,
142
202
current_span = span , # type: ignore
143
203
agent_name = invocation_context .agent .name ,
144
204
user_id = invocation_context .user_id ,
0 commit comments