1616from opentelemetry .trace import INVALID_SPAN , SpanKind
1717from opentelemetry .util .genai .handler import TelemetryHandler
1818from opentelemetry .util .genai .types import (
19+ ContentCapturingMode ,
1920 Error ,
2021 FunctionToolDefinition ,
2122 InputMessage ,
@@ -79,8 +80,12 @@ def test_all_attributes(self):
7980 invocation .output_type = "text"
8081 invocation .temperature = 0.7
8182 invocation .top_p = 0.9
83+ invocation .frequency_penalty = 0.5
84+ invocation .presence_penalty = 0.3
8285 invocation .max_tokens = 1000
86+ invocation .stop_sequences = ["END" , "STOP" ]
8387 invocation .seed = 42
88+ invocation .choice_count = 3
8489 invocation .input_tokens = 100
8590 invocation .output_tokens = 200
8691 invocation .stop ()
@@ -97,8 +102,12 @@ def test_all_attributes(self):
97102 assert attrs [GenAI .GEN_AI_OUTPUT_TYPE ] == "text"
98103 assert attrs [GenAI .GEN_AI_REQUEST_TEMPERATURE ] == 0.7
99104 assert attrs [GenAI .GEN_AI_REQUEST_TOP_P ] == 0.9
105+ assert attrs [GenAI .GEN_AI_REQUEST_FREQUENCY_PENALTY ] == 0.5
106+ assert attrs [GenAI .GEN_AI_REQUEST_PRESENCE_PENALTY ] == 0.3
100107 assert attrs [GenAI .GEN_AI_REQUEST_MAX_TOKENS ] == 1000
108+ assert attrs [GenAI .GEN_AI_REQUEST_STOP_SEQUENCES ] == ("END" , "STOP" )
101109 assert attrs [GenAI .GEN_AI_REQUEST_SEED ] == 42
110+ assert attrs [GenAI .GEN_AI_REQUEST_CHOICE_COUNT ] == 3
102111
103112 def test_no_response_model_or_finish_reasons (self ):
104113 invocation = self .handler .start_invoke_local_agent ("openai" )
@@ -164,8 +173,8 @@ def test_default_values(self):
164173 assert invocation .agent_name is None
165174 assert invocation .provider == "openai"
166175 assert invocation .request_model is None
167- assert invocation .input_messages == []
168- assert invocation .output_messages == []
176+ assert not invocation .input_messages
177+ assert not invocation .output_messages
169178 assert invocation .tool_definitions is None
170179 assert invocation .cache_creation_input_tokens is None
171180 assert invocation .cache_read_input_tokens is None
@@ -239,6 +248,95 @@ def test_provider_always_set(self):
239248 assert attrs [GenAI .GEN_AI_PROVIDER_NAME ] == "gcp_vertex_ai"
240249
241250
251+ class TestAgentInvocationContent (unittest .TestCase ):
252+ def setUp (self ):
253+ self .span_exporter = InMemorySpanExporter ()
254+ tracer_provider = TracerProvider ()
255+ tracer_provider .add_span_processor (
256+ SimpleSpanProcessor (self .span_exporter )
257+ )
258+ self .handler = TelemetryHandler (tracer_provider = tracer_provider )
259+
260+ @patch (
261+ "opentelemetry.util.genai._invocation.get_content_capturing_mode" ,
262+ return_value = ContentCapturingMode .SPAN_AND_EVENT ,
263+ )
264+ @patch (
265+ "opentelemetry.util.genai._invocation.is_experimental_mode" ,
266+ return_value = True ,
267+ )
268+ def test_system_instruction_on_span (self , _mock_exp , _mock_cap ):
269+ invocation = self .handler .start_invoke_local_agent ("openai" )
270+ invocation .system_instruction = [
271+ Text (content = "You are a helpful assistant." ),
272+ ]
273+ invocation .stop ()
274+
275+ attrs = self .span_exporter .get_finished_spans ()[0 ].attributes
276+ assert GenAI .GEN_AI_SYSTEM_INSTRUCTIONS in attrs
277+
278+ @patch (
279+ "opentelemetry.util.genai._invocation.get_content_capturing_mode" ,
280+ return_value = ContentCapturingMode .SPAN_AND_EVENT ,
281+ )
282+ @patch (
283+ "opentelemetry.util.genai._invocation.is_experimental_mode" ,
284+ return_value = True ,
285+ )
286+ def test_tool_definitions_on_span (self , _mock_exp , _mock_cap ):
287+ tool = FunctionToolDefinition (
288+ name = "get_weather" ,
289+ description = "Get the weather" ,
290+ parameters = {"type" : "object" , "properties" : {}},
291+ )
292+ invocation = self .handler .start_invoke_local_agent ("openai" )
293+ invocation .tool_definitions = [tool ]
294+ invocation .stop ()
295+
296+ attrs = self .span_exporter .get_finished_spans ()[0 ].attributes
297+ assert GenAI .GEN_AI_TOOL_DEFINITIONS in attrs
298+
299+ @patch (
300+ "opentelemetry.util.genai._invocation.get_content_capturing_mode" ,
301+ return_value = ContentCapturingMode .SPAN_AND_EVENT ,
302+ )
303+ @patch (
304+ "opentelemetry.util.genai._invocation.is_experimental_mode" ,
305+ return_value = True ,
306+ )
307+ def test_messages_on_span (self , _mock_exp , _mock_cap ):
308+ invocation = self .handler .start_invoke_local_agent ("openai" )
309+ invocation .input_messages = [
310+ InputMessage (role = "user" , parts = [Text (content = "Hello" )])
311+ ]
312+ invocation .output_messages = [
313+ OutputMessage (
314+ role = "assistant" ,
315+ parts = [Text (content = "Hi!" )],
316+ finish_reason = "stop" ,
317+ )
318+ ]
319+ invocation .stop ()
320+
321+ attrs = self .span_exporter .get_finished_spans ()[0 ].attributes
322+ assert GenAI .GEN_AI_INPUT_MESSAGES in attrs
323+ assert GenAI .GEN_AI_OUTPUT_MESSAGES in attrs
324+
325+ def test_content_not_on_span_by_default (self ):
326+ invocation = self .handler .start_invoke_local_agent ("openai" )
327+ invocation .system_instruction = [
328+ Text (content = "You are a helpful assistant." ),
329+ ]
330+ invocation .input_messages = [
331+ InputMessage (role = "user" , parts = [Text (content = "Hello" )])
332+ ]
333+ invocation .stop ()
334+
335+ attrs = self .span_exporter .get_finished_spans ()[0 ].attributes
336+ assert GenAI .GEN_AI_SYSTEM_INSTRUCTIONS not in attrs
337+ assert GenAI .GEN_AI_INPUT_MESSAGES not in attrs
338+
339+
242340class TestRemoteAgentInvocation (unittest .TestCase ):
243341 def setUp (self ):
244342 self .span_exporter = InMemorySpanExporter ()
0 commit comments