4040
4141from opentelemetry import trace
4242from opentelemetry .context import Context , get_current
43+ from opentelemetry .instrumentation ._semconv import (
44+ _OpenTelemetrySemanticConventionStability ,
45+ _OpenTelemetryStabilitySignalType ,
46+ _StabilityMode ,
47+ )
4348from opentelemetry .metrics import Histogram , Meter , get_meter
4449from opentelemetry .semconv ._incubating .attributes import (
4550 gen_ai_attributes as GenAI ,
5560 use_span ,
5661)
5762from opentelemetry .trace .status import Status , StatusCode
63+ from opentelemetry .util .genai .utils import (
64+ ContentCapturingMode ,
65+ get_content_capturing_mode ,
66+ )
5867from opentelemetry .util .types import AttributeValue
5968
6069from .instruments import Instruments
@@ -79,11 +88,10 @@ def _get_metric_attributes(
7988 framework : Optional [str ],
8089) -> Dict [str , AttributeValue ]:
8190 attributes : Dict [str , AttributeValue ] = {}
82- # TODO: add below to opentelemetry.semconv._incubating.attributes.gen_ai_attributes
8391 if framework is not None :
8492 attributes ["gen_ai.framework" ] = framework
8593 if system :
86- attributes ["gen_ai.provider.name" ] = system
94+ attributes [GenAI . GEN_AI_PROVIDER_NAME ] = system
8795 if operation_name :
8896 attributes [GenAI .GEN_AI_OPERATION_NAME ] = operation_name
8997 if request_model :
@@ -108,9 +116,8 @@ def _set_initial_span_attributes(
108116 if framework is not None :
109117 span .set_attribute ("gen_ai.framework" , framework )
110118 if system is not None :
111- # Deprecated: use "gen_ai.provider.name"
112- span .set_attribute (GenAI .GEN_AI_SYSTEM , system )
113- span .set_attribute ("gen_ai.provider.name" , system )
119+ # TODO: clean system name to match GenAiProviderNameValues?
120+ span .set_attribute (GenAI .GEN_AI_PROVIDER_NAME , system )
114121
115122
116123def _set_response_and_usage_attributes (
@@ -137,10 +144,21 @@ def _collect_finish_reasons(generations: List[OutputMessage]) -> List[str]:
137144 return finish_reasons
138145
139146
140- def _maybe_set_input_messages (
141- span : Span , messages : List [InputMessage ], capture : bool
147+ def _maybe_set_span_input_messages (
148+ span : Span , messages : List [InputMessage ]
142149) -> None :
143- if not capture :
150+ # if GEN_AI stability mode is DEFAULT, do not capture message content
151+ if (
152+ _OpenTelemetrySemanticConventionStability ._get_opentelemetry_stability_opt_in_mode (
153+ _OpenTelemetryStabilitySignalType .GEN_AI ,
154+ )
155+ == _StabilityMode .DEFAULT
156+ ):
157+ return
158+ if get_content_capturing_mode () not in (
159+ ContentCapturingMode .SPAN_ONLY ,
160+ ContentCapturingMode .SPAN_AND_EVENT ,
161+ ):
144162 return
145163 message_parts : List [Dict [str , Any ]] = [
146164 asdict (message ) for message in messages
@@ -221,14 +239,12 @@ def __init__(
221239 self ,
222240 tracer : Optional [Tracer ] = None ,
223241 meter : Optional [Meter ] = None ,
224- capture_content : bool = False ,
225242 ):
226243 self ._tracer : Tracer = tracer or trace .get_tracer (__name__ )
227244 _meter : Meter = meter or get_meter (__name__ )
228245 instruments = Instruments (_meter )
229246 self ._duration_histogram = instruments .operation_duration_histogram
230247 self ._token_histogram = instruments .token_usage_histogram
231- self ._capture_content = capture_content
232248
233249 # Map from run_id -> _SpanState, to keep track of spans and parent/child relationships
234250 self .spans : Dict [UUID , _SpanState ] = {}
@@ -352,9 +368,7 @@ def finish(self, invocation: LLMInvocation):
352368 metric_attributes , prompt_tokens , completion_tokens = (
353369 self ._apply_common_span_attributes (span , invocation )
354370 )
355- _maybe_set_input_messages (
356- span , invocation .messages , self ._capture_content
357- )
371+ _maybe_set_span_input_messages (span , invocation .messages )
358372 _set_chat_generation_attrs (span , invocation .chat_generations )
359373 _record_token_metrics (
360374 self ._token_histogram ,
0 commit comments