5757from opentelemetry .util .genai .completion_hook import CompletionHook
5858from opentelemetry .util .genai .handler import TelemetryHandler
5959from opentelemetry .util .genai .types import (
60+ ContentCapturingMode ,
6061 FunctionToolDefinition ,
6162 GenericToolDefinition ,
6263 InputMessage ,
7677 to_system_instructions ,
7778)
7879from .otel_wrapper import OTelWrapper
79- from .tool_call_wrapper import wrapped as wrapped_tool
80+ from .tool_call_wrapper import wrapped_tool
8081
8182_is_mcp_imported = False
8283if typing .TYPE_CHECKING :
@@ -432,15 +433,16 @@ def _coerce_config_to_object(
432433
433434
434435def _wrapped_config_with_tools (
435- otel_wrapper : OTelWrapper ,
436+ telemetry_handler : TelemetryHandler ,
437+ capture_content_on_span : bool ,
436438 config : GenerateContentConfig ,
437- ** kwargs ,
438439):
439440 if not config .tools :
440441 return config
441442 result = copy .copy (config )
442443 result .tools = [
443- wrapped_tool (tool , otel_wrapper , ** kwargs ) for tool in config .tools
444+ wrapped_tool (tool , telemetry_handler , capture_content_on_span )
445+ for tool in config .tools
444446 ]
445447 return result
446448
@@ -509,12 +511,14 @@ def __init__(
509511 self ,
510512 models_object : Union [Models , AsyncModels ],
511513 otel_wrapper : OTelWrapper ,
514+ telemetry_handler : TelemetryHandler ,
512515 model : str ,
513516 completion_hook : CompletionHook ,
514517 generate_content_config_key_allowlist : Optional [AllowList ] = None ,
515518 is_async : bool = False ,
516519 ):
517520 self ._start_time = time .time_ns ()
521+ self ._telemetry_handler = telemetry_handler
518522 self ._otel_wrapper = otel_wrapper
519523 self ._genai_system = _determine_genai_system (models_object )
520524 self ._genai_request_model = model
@@ -539,6 +543,13 @@ def __init__(
539543 self ._content_recording_enabled = is_content_recording_enabled (
540544 self .experimental_sem_convs_enabled
541545 )
546+ if self .experimental_sem_convs_enabled :
547+ self .capture_content_on_span = self ._content_recording_enabled in [
548+ ContentCapturingMode .SPAN_ONLY ,
549+ ContentCapturingMode .SPAN_AND_EVENT ,
550+ ]
551+ else :
552+ self .capture_content_on_span = self ._content_recording_enabled
542553 self ._response_index = 0
543554 self ._candidate_index = 0
544555 self ._generate_content_config_key_allowlist = (
@@ -552,9 +563,9 @@ def wrapped_config(
552563 if config is None :
553564 return None
554565 return _wrapped_config_with_tools (
555- self ._otel_wrapper ,
566+ self ._telemetry_handler ,
567+ self .capture_content_on_span ,
556568 _coerce_config_to_object (config ),
557- extra_span_attributes = {"gen_ai.system" : self ._genai_system },
558569 )
559570
560571 def start_span_as_current_span (
@@ -909,6 +920,7 @@ def instrumented_generate_content(
909920 helper = _GenerateContentInstrumentationHelper (
910921 self ,
911922 otel_wrapper ,
923+ telemetry_handler ,
912924 model ,
913925 completion_hook ,
914926 generate_content_config_key_allowlist = generate_content_config_key_allowlist ,
@@ -1017,6 +1029,7 @@ def instrumented_generate_content_stream(
10171029 helper = _GenerateContentInstrumentationHelper (
10181030 self ,
10191031 otel_wrapper ,
1032+ telemetry_handler ,
10201033 model ,
10211034 completion_hook ,
10221035 generate_content_config_key_allowlist = generate_content_config_key_allowlist ,
@@ -1125,6 +1138,7 @@ async def instrumented_generate_content(
11251138 helper = _GenerateContentInstrumentationHelper (
11261139 self ,
11271140 otel_wrapper ,
1141+ telemetry_handler ,
11281142 model ,
11291143 completion_hook ,
11301144 generate_content_config_key_allowlist = generate_content_config_key_allowlist ,
@@ -1234,6 +1248,7 @@ async def instrumented_generate_content_stream(
12341248 helper = _GenerateContentInstrumentationHelper (
12351249 self ,
12361250 otel_wrapper ,
1251+ telemetry_handler ,
12371252 model ,
12381253 completion_hook ,
12391254 generate_content_config_key_allowlist = generate_content_config_key_allowlist ,
@@ -1256,14 +1271,13 @@ async def instrumented_generate_content_stream(
12561271 invocation .tool_definitions = (
12571272 await helper ._maybe_get_tool_definitions_async (config )
12581273 )
1259- if helper ._content_recording_enabled :
1260- invocation .input_messages = to_input_messages (
1261- contents = transformers .t_contents (contents )
1274+ invocation .input_messages = to_input_messages (
1275+ contents = transformers .t_contents (contents )
1276+ )
1277+ if system_content := _config_to_system_instruction (config ):
1278+ invocation .system_instruction = to_system_instructions (
1279+ content = transformers .t_contents (system_content )[0 ]
12621280 )
1263- if system_content := _config_to_system_instruction (config ):
1264- invocation .system_instruction = to_system_instructions (
1265- content = transformers .t_contents (system_content )[0 ]
1266- )
12671281
12681282 try :
12691283 response_async_generator = await wrapped_func (
@@ -1298,7 +1312,7 @@ async def _response_async_generator_wrapper():
12981312 "gen_ai.usage.reasoning.output_tokens"
12991313 ] = helper ._thinking_tokens
13001314
1301- if helper . _content_recording_enabled and candidates :
1315+ if candidates :
13021316 invocation .output_messages = to_output_messages (
13031317 candidates = candidates
13041318 )
0 commit comments