Skip to content

Commit 4bec562

Browse files
committed
use semconv constants for output type values
1 parent 8895734 commit 4bec562

4 files changed

Lines changed: 36 additions & 19 deletions

File tree

instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,14 @@ def get_llm_request_attributes(
282282
# response_format may be string, object with a string in the `type` key,
283283
# or a type (e.g. Pydantic model class used with parse())
284284
if isinstance(response_format, type):
285-
attributes[request_response_format_attr_key] = "json"
285+
if latest_experimental_enabled:
286+
attributes[request_response_format_attr_key] = (
287+
GenAIAttributes.GenAiOutputTypeValues.JSON.value
288+
)
289+
else:
290+
attributes[request_response_format_attr_key] = (
291+
GenAIAttributes.GenAiOpenaiRequestResponseFormatValues.JSON_SCHEMA.value
292+
)
286293
elif isinstance(response_format, Mapping):
287294
if (
288295
response_format_type := response_format.get("type")
@@ -369,7 +376,9 @@ def create_chat_invocation(
369376
# response_format may be string, object with a string in the `type` key,
370377
# or a type (e.g. Pydantic model class used with parse())
371378
if isinstance(response_format, type):
372-
invocation.attributes[GenAIAttributes.GEN_AI_OUTPUT_TYPE] = "json"
379+
invocation.attributes[GenAIAttributes.GEN_AI_OUTPUT_TYPE] = (
380+
GenAIAttributes.GenAiOutputTypeValues.JSON.value
381+
)
373382
elif isinstance(response_format, Mapping):
374383
if (
375384
response_format_type := get_value(response_format.get("type"))

instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/structured_outputs_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
class CalendarEvent(BaseModel):
2121
name: str
2222
date: str
23-
participants: list
23+
participants: list[str]
2424

2525

2626
STRUCTURED_OUTPUT_PROMPT = [

instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_async_structured_outputs.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ async def test_async_structured_output_with_content(
5252
response_format=CalendarEvent,
5353
)
5454

55+
# Verify wrapper doesn't interfere with parse() return
56+
assert response.choices[0].message.parsed is not None
57+
5558
spans = span_exporter.get_finished_spans()
5659
assert len(spans) == 1
5760
assert_all_attributes(
@@ -69,7 +72,8 @@ async def test_async_structured_output_with_content(
6972
if latest_experimental_enabled
7073
else GenAIAttributes.GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT
7174
)
72-
assert spans[0].attributes[output_type_attr_key] == "json_schema"
75+
expected_value = "json" if latest_experimental_enabled else "json_schema"
76+
assert spans[0].attributes[output_type_attr_key] == expected_value
7377

7478
if latest_experimental_enabled:
7579
assert_messages_attribute(
@@ -78,18 +82,14 @@ async def test_async_structured_output_with_content(
7882
)
7983
assert_messages_attribute(
8084
spans[0].attributes["gen_ai.output.messages"],
81-
format_simple_expected_output_message(
82-
response.choices[0].message.content
83-
),
85+
format_simple_expected_output_message(response.choices[0].message.content),
8486
)
8587
else:
8688
logs = log_exporter.get_finished_logs()
8789
assert len(logs) == 2
8890

8991
user_message = {"content": STRUCTURED_OUTPUT_PROMPT[0]["content"]}
90-
assert_message_in_logs(
91-
logs[0], "gen_ai.user.message", user_message, spans[0]
92-
)
92+
assert_message_in_logs(logs[0], "gen_ai.user.message", user_message, spans[0])
9393

9494
choice_event = {
9595
"index": 0,
@@ -99,9 +99,7 @@ async def test_async_structured_output_with_content(
9999
"content": response.choices[0].message.content,
100100
},
101101
}
102-
assert_message_in_logs(
103-
logs[1], "gen_ai.choice", choice_event, spans[0]
104-
)
102+
assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0])
105103

106104

107105
@pytest.mark.asyncio()
@@ -121,6 +119,9 @@ async def test_async_structured_output_no_content(
121119
response_format=CalendarEvent,
122120
)
123121

122+
# Verify wrapper doesn't interfere with parse() return
123+
assert response.choices[0].message.parsed is not None
124+
124125
spans = span_exporter.get_finished_spans()
125126
assert len(spans) == 1
126127
assert_all_attributes(
@@ -138,7 +139,8 @@ async def test_async_structured_output_no_content(
138139
if latest_experimental_enabled
139140
else GenAIAttributes.GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT
140141
)
141-
assert spans[0].attributes[output_type_attr_key] == "json_schema"
142+
expected_value = "json" if latest_experimental_enabled else "json_schema"
143+
assert spans[0].attributes[output_type_attr_key] == expected_value
142144

143145
logs = log_exporter.get_finished_logs()
144146
if latest_experimental_enabled:
@@ -155,6 +157,4 @@ async def test_async_structured_output_no_content(
155157
"finish_reason": "stop",
156158
"message": {"role": "assistant"},
157159
}
158-
assert_message_in_logs(
159-
logs[1], "gen_ai.choice", choice_event, spans[0]
160-
)
160+
assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0])

instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_structured_outputs.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ def test_structured_output_with_content(
4545
response_format=CalendarEvent,
4646
)
4747

48+
# Verify wrapper doesn't interfere with parse() return
49+
assert response.choices[0].message.parsed is not None
50+
4851
spans = span_exporter.get_finished_spans()
4952
assert len(spans) == 1
5053
assert_all_attributes(
@@ -62,7 +65,8 @@ def test_structured_output_with_content(
6265
if latest_experimental_enabled
6366
else GenAIAttributes.GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT
6467
)
65-
assert spans[0].attributes[output_type_attr_key] == "json"
68+
expected_value = "json" if latest_experimental_enabled else "json_schema"
69+
assert spans[0].attributes[output_type_attr_key] == expected_value
6670

6771
if latest_experimental_enabled:
6872
assert_messages_attribute(
@@ -103,6 +107,9 @@ def test_structured_output_no_content(
103107
response_format=CalendarEvent,
104108
)
105109

110+
# Verify wrapper doesn't interfere with parse() return
111+
assert response.choices[0].message.parsed is not None
112+
106113
spans = span_exporter.get_finished_spans()
107114
assert len(spans) == 1
108115
assert_all_attributes(
@@ -120,7 +127,8 @@ def test_structured_output_no_content(
120127
if latest_experimental_enabled
121128
else GenAIAttributes.GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT
122129
)
123-
assert spans[0].attributes[output_type_attr_key] == "json"
130+
expected_value = "json" if latest_experimental_enabled else "json_schema"
131+
assert spans[0].attributes[output_type_attr_key] == expected_value
124132

125133
logs = log_exporter.get_finished_logs()
126134
if latest_experimental_enabled:

0 commit comments

Comments
 (0)