diff --git a/instrumentation/elastic-opentelemetry-instrumentation-openai/src/opentelemetry/instrumentation/openai/__init__.py b/instrumentation/elastic-opentelemetry-instrumentation-openai/src/opentelemetry/instrumentation/openai/__init__.py index c1d312d..973e6eb 100644 --- a/instrumentation/elastic-opentelemetry-instrumentation-openai/src/opentelemetry/instrumentation/openai/__init__.py +++ b/instrumentation/elastic-opentelemetry-instrumentation-openai/src/opentelemetry/instrumentation/openai/__init__.py @@ -87,14 +87,14 @@ def _instrument(self, **kwargs): __name__, __version__, tracer_provider, - schema_url=Schemas.V1_28_0.value, + schema_url=Schemas.V1_31_0.value, ) meter_provider = kwargs.get("meter_provider") self.meter = get_meter( __name__, __version__, meter_provider, - schema_url=Schemas.V1_28_0.value, + schema_url=Schemas.V1_31_0.value, ) event_logger_provider = kwargs.get("event_logger_provider") self.event_logger = get_event_logger(__name__, event_logger_provider) diff --git a/instrumentation/elastic-opentelemetry-instrumentation-openai/src/opentelemetry/instrumentation/openai/helpers.py b/instrumentation/elastic-opentelemetry-instrumentation-openai/src/opentelemetry/instrumentation/openai/helpers.py index 1d75555..f497481 100644 --- a/instrumentation/elastic-opentelemetry-instrumentation-openai/src/opentelemetry/instrumentation/openai/helpers.py +++ b/instrumentation/elastic-opentelemetry-instrumentation-openai/src/opentelemetry/instrumentation/openai/helpers.py @@ -20,10 +20,10 @@ from opentelemetry._events import Event, EventLogger from opentelemetry.semconv._incubating.attributes.gen_ai_attributes import ( - GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT, GEN_AI_OPENAI_REQUEST_SERVICE_TIER, GEN_AI_OPENAI_RESPONSE_SERVICE_TIER, GEN_AI_OPERATION_NAME, + GEN_AI_OUTPUT_TYPE, GEN_AI_REQUEST_CHOICE_COUNT, GEN_AI_REQUEST_FREQUENCY_PENALTY, GEN_AI_REQUEST_MAX_TOKENS, @@ -166,13 +166,16 @@ def _is_set(value): # response_format may be string or object with a string in the `type` key if isinstance(response_format, Mapping): if _is_set(response_format_type := response_format.get("type")): - span_attributes[GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT] = response_format_type + if response_format_type in ("json_object", "json_schema"): + span_attributes[GEN_AI_OUTPUT_TYPE] = "json" + else: + span_attributes[GEN_AI_OUTPUT_TYPE] = response_format_type elif isinstance(response_format, str): - span_attributes[GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT] = response_format + span_attributes[GEN_AI_OUTPUT_TYPE] = response_format else: # Assume structured output lazily parsed to a schema via type_to_response_format_param or similar. # e.g. pydantic._internal._model_construction.ModelMetaclass - span_attributes[GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT] = "json_schema" + span_attributes[GEN_AI_OUTPUT_TYPE] = "json" return span_attributes diff --git a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_beta_chat_completions.py b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_beta_chat_completions.py index a746cad..6bdbc62 100644 --- a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_beta_chat_completions.py +++ b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_beta_chat_completions.py @@ -28,10 +28,10 @@ from opentelemetry._logs import LogRecord from opentelemetry.instrumentation.openai import OpenAIInstrumentor from opentelemetry.semconv._incubating.attributes.gen_ai_attributes import ( - GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT, GEN_AI_OPENAI_REQUEST_SERVICE_TIER, GEN_AI_OPENAI_RESPONSE_SERVICE_TIER, GEN_AI_OPERATION_NAME, + GEN_AI_OUTPUT_TYPE, GEN_AI_REQUEST_CHOICE_COUNT, GEN_AI_REQUEST_FREQUENCY_PENALTY, GEN_AI_REQUEST_MAX_TOKENS, @@ -248,7 +248,7 @@ def test_chat_all_the_client_options(default_openai_env, trace_exporter, metrics expected_attrs = { GEN_AI_REQUEST_SEED: 100, GEN_AI_OPENAI_REQUEST_SERVICE_TIER: "default", - GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT: "text", + GEN_AI_OUTPUT_TYPE: "text", GEN_AI_OPENAI_RESPONSE_SERVICE_TIER: "default", GEN_AI_OPERATION_NAME: "chat", GEN_AI_REQUEST_FREQUENCY_PENALTY: 0, @@ -1502,14 +1502,14 @@ def test_chat_exported_schema_version(default_openai_env, trace_exporter, metric spans = trace_exporter.get_finished_spans() (span,) = spans - assert span.instrumentation_scope.schema_url == "https://opentelemetry.io/schemas/1.28.0" + assert span.instrumentation_scope.schema_url == "https://opentelemetry.io/schemas/1.31.0" metrics_data = metrics_reader.get_metrics_data() resource_metrics = metrics_data.resource_metrics for metrics in resource_metrics: for scope_metrics in metrics.scope_metrics: - assert scope_metrics.schema_url == "https://opentelemetry.io/schemas/1.28.0" + assert scope_metrics.schema_url == "https://opentelemetry.io/schemas/1.31.0" @pytest.mark.skipif(OPENAI_VERSION < (1, 40, 0), reason="beta completions added in 1.40.0") @@ -1545,7 +1545,7 @@ def test_parse_response_format_json_object_with_capture_message_content( address, port = address_and_port(client) assert dict(span.attributes) == { GEN_AI_OPENAI_RESPONSE_SERVICE_TIER: "default", - GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT: "json_object", + GEN_AI_OUTPUT_TYPE: "json", GEN_AI_OPERATION_NAME: "chat", GEN_AI_REQUEST_MODEL: TEST_CHAT_MODEL, GEN_AI_SYSTEM: "openai", @@ -1620,7 +1620,7 @@ def test_parse_response_format_structured_output_with_capture_message_content( address, port = address_and_port(client) assert dict(span.attributes) == { GEN_AI_OPENAI_RESPONSE_SERVICE_TIER: "default", - GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT: "json_schema", + GEN_AI_OUTPUT_TYPE: "json", GEN_AI_OPERATION_NAME: "chat", GEN_AI_REQUEST_MODEL: TEST_CHAT_MODEL, GEN_AI_SYSTEM: "openai", diff --git a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_chat_completions.py b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_chat_completions.py index b3dc314..bc4fd54 100644 --- a/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_chat_completions.py +++ b/instrumentation/elastic-opentelemetry-instrumentation-openai/tests/test_chat_completions.py @@ -27,10 +27,10 @@ from opentelemetry._logs import LogRecord from opentelemetry.instrumentation.openai import OpenAIInstrumentor from opentelemetry.semconv._incubating.attributes.gen_ai_attributes import ( - GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT, GEN_AI_OPENAI_REQUEST_SERVICE_TIER, GEN_AI_OPENAI_RESPONSE_SERVICE_TIER, GEN_AI_OPERATION_NAME, + GEN_AI_OUTPUT_TYPE, GEN_AI_REQUEST_CHOICE_COUNT, GEN_AI_REQUEST_FREQUENCY_PENALTY, GEN_AI_REQUEST_MAX_TOKENS, @@ -332,7 +332,7 @@ def test_chat_all_the_client_options(default_openai_env, trace_exporter, metrics expected_attrs = { GEN_AI_REQUEST_SEED: 100, GEN_AI_OPENAI_REQUEST_SERVICE_TIER: "default", - GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT: "text", + GEN_AI_OUTPUT_TYPE: "text", GEN_AI_OPENAI_RESPONSE_SERVICE_TIER: "default", GEN_AI_OPERATION_NAME: "chat", GEN_AI_REQUEST_FREQUENCY_PENALTY: 0, @@ -1204,7 +1204,7 @@ def test_chat_stream_all_the_client_options(default_openai_env, trace_exporter, address, port = address_and_port(client) expected_attrs = { GEN_AI_REQUEST_SEED: 100, - GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT: "text", + GEN_AI_OUTPUT_TYPE: "text", GEN_AI_OPENAI_REQUEST_SERVICE_TIER: "default", GEN_AI_OPENAI_RESPONSE_SERVICE_TIER: "default", GEN_AI_OPERATION_NAME: "chat", @@ -2444,14 +2444,14 @@ def test_chat_exported_schema_version(default_openai_env, trace_exporter, metric spans = trace_exporter.get_finished_spans() (span,) = spans - assert span.instrumentation_scope.schema_url == "https://opentelemetry.io/schemas/1.28.0" + assert span.instrumentation_scope.schema_url == "https://opentelemetry.io/schemas/1.31.0" metrics_data = metrics_reader.get_metrics_data() resource_metrics = metrics_data.resource_metrics for metrics in resource_metrics: for scope_metrics in metrics.scope_metrics: - assert scope_metrics.schema_url == "https://opentelemetry.io/schemas/1.28.0" + assert scope_metrics.schema_url == "https://opentelemetry.io/schemas/1.31.0" @dataclass