From 3dad6f9895709d81dfc4c2fb58d718fa639f648f Mon Sep 17 00:00:00 2001 From: Martim Santos Date: Tue, 15 Jul 2025 11:49:27 +0000 Subject: [PATCH 1/3] updated input & output tokens attributes --- .../tests/test_completion.py | 18 ++-- .../tests/test_messages.py | 18 ++-- .../tests/test_prompt_caching.py | 96 +++++++++---------- .../tests/traces/test_prompt_caching.py | 48 +++++----- .../tests/test_chat.py | 18 ++-- .../tests/test_completion.py | 18 ++-- .../opentelemetry/semconv_ai/__init__.py | 4 +- 7 files changed, 110 insertions(+), 110 deletions(-) diff --git a/packages/opentelemetry-instrumentation-alephalpha/tests/test_completion.py b/packages/opentelemetry-instrumentation-alephalpha/tests/test_completion.py index 59e7ce1931..4f81cd6065 100644 --- a/packages/opentelemetry-instrumentation-alephalpha/tests/test_completion.py +++ b/packages/opentelemetry-instrumentation-alephalpha/tests/test_completion.py @@ -35,12 +35,12 @@ def test_alephalpha_completion( together_span.attributes.get("gen_ai.completion.0.content") == response.completions[0].completion ) - assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 9 + assert together_span.attributes.get("gen_ai.usage.input_tokens") == 9 assert together_span.attributes.get( "llm.usage.total_tokens" ) == together_span.attributes.get( - "gen_ai.usage.completion_tokens" - ) + together_span.attributes.get("gen_ai.usage.prompt_tokens") + "gen_ai.usage.output_tokens" + ) + together_span.attributes.get("gen_ai.usage.input_tokens") logs = log_exporter.get_finished_logs() assert ( @@ -66,12 +66,12 @@ def test_alephalpha_completion_with_events_with_content( assert together_span.attributes.get("gen_ai.system") == "AlephAlpha" assert together_span.attributes.get("llm.request.type") == "completion" assert together_span.attributes.get("gen_ai.request.model") == "luminous-base" - assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 9 + assert together_span.attributes.get("gen_ai.usage.input_tokens") == 9 assert together_span.attributes.get( "llm.usage.total_tokens" ) == together_span.attributes.get( - "gen_ai.usage.completion_tokens" - ) + together_span.attributes.get("gen_ai.usage.prompt_tokens") + "gen_ai.usage.output_tokens" + ) + together_span.attributes.get("gen_ai.usage.input_tokens") logs = log_exporter.get_finished_logs() assert len(logs) == 2 @@ -116,12 +116,12 @@ def test_alephalpha_completion_with_events_with_no_content( assert together_span.attributes.get("gen_ai.system") == "AlephAlpha" assert together_span.attributes.get("llm.request.type") == "completion" assert together_span.attributes.get("gen_ai.request.model") == "luminous-base" - assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 9 + assert together_span.attributes.get("gen_ai.usage.input_tokens") == 9 assert together_span.attributes.get( "llm.usage.total_tokens" ) == together_span.attributes.get( - "gen_ai.usage.completion_tokens" - ) + together_span.attributes.get("gen_ai.usage.prompt_tokens") + "gen_ai.usage.output_tokens" + ) + together_span.attributes.get("gen_ai.usage.input_tokens") logs = log_exporter.get_finished_logs() assert len(logs) == 2 diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py b/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py index 6b87c0d1c2..10cd7858b7 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py +++ b/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py @@ -1291,10 +1291,10 @@ def test_anthropic_tools_legacy( anthropic_span = spans[0] # verify usage - assert anthropic_span.attributes["gen_ai.usage.prompt_tokens"] == 514 + assert anthropic_span.attributes["gen_ai.usage.input_tokens"] == 514 assert ( - anthropic_span.attributes["gen_ai.usage.completion_tokens"] - + anthropic_span.attributes["gen_ai.usage.prompt_tokens"] + anthropic_span.attributes["gen_ai.usage.output_tokens"] + + anthropic_span.attributes["gen_ai.usage.input_tokens"] == anthropic_span.attributes["llm.usage.total_tokens"] ) @@ -1466,10 +1466,10 @@ def test_anthropic_tools_with_events_with_content( anthropic_span = spans[0] # verify usage - assert anthropic_span.attributes["gen_ai.usage.prompt_tokens"] == 514 + assert anthropic_span.attributes["gen_ai.usage.input_tokens"] == 514 assert ( - anthropic_span.attributes["gen_ai.usage.completion_tokens"] - + anthropic_span.attributes["gen_ai.usage.prompt_tokens"] + anthropic_span.attributes["gen_ai.usage.output_tokens"] + + anthropic_span.attributes["gen_ai.usage.input_tokens"] == anthropic_span.attributes["llm.usage.total_tokens"] ) @@ -1602,10 +1602,10 @@ def test_anthropic_tools_with_events_with_no_content( anthropic_span = spans[0] # verify usage - assert anthropic_span.attributes["gen_ai.usage.prompt_tokens"] == 514 + assert anthropic_span.attributes["gen_ai.usage.input_tokens"] == 514 assert ( - anthropic_span.attributes["gen_ai.usage.completion_tokens"] - + anthropic_span.attributes["gen_ai.usage.prompt_tokens"] + anthropic_span.attributes["gen_ai.usage.output_tokens"] + + anthropic_span.attributes["gen_ai.usage.input_tokens"] == anthropic_span.attributes["llm.usage.total_tokens"] ) diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/test_prompt_caching.py b/packages/opentelemetry-instrumentation-anthropic/tests/test_prompt_caching.py index 8feb9adaa7..fb8b13c645 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/test_prompt_caching.py +++ b/packages/opentelemetry-instrumentation-anthropic/tests/test_prompt_caching.py @@ -99,8 +99,8 @@ def test_anthropic_prompt_caching_legacy( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1163 ) - # assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1167 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 187 + # assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1167 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 187 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -108,8 +108,8 @@ def test_anthropic_prompt_caching_legacy( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1163 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1167 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 202 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1167 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 202 # verify metrics metrics_data = reader.get_metrics_data() @@ -189,8 +189,8 @@ def test_anthropic_prompt_caching_with_events_with_content( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1163 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1167 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 187 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1167 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 187 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -198,8 +198,8 @@ def test_anthropic_prompt_caching_with_events_with_content( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1163 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1167 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 202 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1167 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 202 # verify metrics metrics_data = reader.get_metrics_data() @@ -377,8 +377,8 @@ def test_anthropic_prompt_caching_with_events_with_no_content( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1163 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1167 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 187 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1167 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 187 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -386,8 +386,8 @@ def test_anthropic_prompt_caching_with_events_with_no_content( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1163 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1167 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 202 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1167 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 202 # verify metrics metrics_data = reader.get_metrics_data() @@ -507,8 +507,8 @@ async def test_anthropic_prompt_caching_async_legacy( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1165 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 207 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 207 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -516,8 +516,8 @@ async def test_anthropic_prompt_caching_async_legacy( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1165 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 224 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 224 # verify metrics metrics_data = reader.get_metrics_data() @@ -598,8 +598,8 @@ async def test_anthropic_prompt_caching_async_with_events_with_content( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1165 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 207 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 207 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -607,8 +607,8 @@ async def test_anthropic_prompt_caching_async_with_events_with_content( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1165 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 224 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 224 # verify metrics metrics_data = reader.get_metrics_data() @@ -792,8 +792,8 @@ async def test_anthropic_prompt_caching_async_with_events_with_no_content( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1165 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 207 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 207 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -801,8 +801,8 @@ async def test_anthropic_prompt_caching_async_with_events_with_no_content( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1165 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 224 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 224 # verify metrics metrics_data = reader.get_metrics_data() @@ -925,8 +925,8 @@ def test_anthropic_prompt_caching_stream_legacy( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1165 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 202 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 202 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -934,8 +934,8 @@ def test_anthropic_prompt_caching_stream_legacy( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1165 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 222 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 222 # verify metrics metrics_data = reader.get_metrics_data() @@ -1019,8 +1019,8 @@ def test_anthropic_prompt_caching_stream_with_events_with_content( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1165 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 202 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 202 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -1028,8 +1028,8 @@ def test_anthropic_prompt_caching_stream_with_events_with_content( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1165 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 222 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 222 # verify metrics metrics_data = reader.get_metrics_data() @@ -1218,8 +1218,8 @@ def test_anthropic_prompt_caching_stream_with_events_with_no_content( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1165 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 202 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 202 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -1227,8 +1227,8 @@ def test_anthropic_prompt_caching_stream_with_events_with_no_content( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1165 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1169 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 222 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1169 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 222 # verify metrics metrics_data = reader.get_metrics_data() @@ -1352,8 +1352,8 @@ async def test_anthropic_prompt_caching_async_stream_legacy( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1167 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1171 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 290 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1171 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 290 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -1361,8 +1361,8 @@ async def test_anthropic_prompt_caching_async_stream_legacy( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1167 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1171 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 257 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1171 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 257 # verify metrics metrics_data = reader.get_metrics_data() @@ -1447,8 +1447,8 @@ async def test_anthropic_prompt_caching_async_stream_with_events_with_content( cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1167 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1171 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 290 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1171 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 290 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -1456,8 +1456,8 @@ async def test_anthropic_prompt_caching_async_stream_with_events_with_content( # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1167 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1171 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 257 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1171 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 257 # verify metrics metrics_data = reader.get_metrics_data() @@ -1657,8 +1657,8 @@ async def test_anthropic_prompt_caching_async_stream_with_events_with_no_content cache_creation_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 1167 ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1171 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 290 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1171 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 290 # first check that cache_read_span only read from cache, but not wrote to it, assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] != 0 @@ -1666,8 +1666,8 @@ async def test_anthropic_prompt_caching_async_stream_with_events_with_no_content # then check for exact figures for the fixture/cassete assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1167 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1171 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 257 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1171 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 257 # verify metrics metrics_data = reader.get_metrics_data() diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_prompt_caching.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_prompt_caching.py index 375b37ae95..f88daa051f 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_prompt_caching.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_prompt_caching.py @@ -67,12 +67,12 @@ def test_openai_prompt_caching(instrument_legacy, span_exporter, log_exporter): assert cache_creation_span.attributes["gen_ai.completion.0.role"] == "assistant" assert cache_read_span.attributes["gen_ai.completion.0.role"] == "assistant" - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1149 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 315 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1149 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 315 assert cache_creation_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 0 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1149 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 353 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1149 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 353 assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1024 logs = log_exporter.get_finished_logs() @@ -129,12 +129,12 @@ def test_openai_prompt_caching_with_events_with_content( == "chatcmpl-BNi420iFNtIOHzy8Gq2fVS5utTus7" ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1149 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 315 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1149 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 315 assert cache_creation_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 0 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1149 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 353 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1149 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 353 assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1024 logs = log_exporter.get_finished_logs() @@ -222,12 +222,12 @@ def test_openai_prompt_caching_with_events_with_no_content( == "chatcmpl-BNi420iFNtIOHzy8Gq2fVS5utTus7" ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1149 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 315 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1149 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 315 assert cache_creation_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 0 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1149 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 353 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1149 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 353 assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1024 logs = log_exporter.get_finished_logs() @@ -319,12 +319,12 @@ async def test_openai_prompt_caching_async( assert cache_creation_span.attributes["gen_ai.completion.0.role"] == "assistant" assert cache_read_span.attributes["gen_ai.completion.0.role"] == "assistant" - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1150 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 293 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1150 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 293 assert cache_creation_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 0 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1150 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 307 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1150 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 307 assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1024 logs = log_exporter.get_finished_logs() @@ -382,12 +382,12 @@ async def test_openai_prompt_caching_async_with_events_with_content( == "chatcmpl-BNhrEFvKSNY08Uphau5iA4InZH6jn" ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1150 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 293 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1150 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 293 assert cache_creation_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 0 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1150 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 307 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1150 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 307 assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1024 logs = log_exporter.get_finished_logs() @@ -476,12 +476,12 @@ async def test_openai_prompt_caching_async_with_events_with_no_content( == "chatcmpl-BNhrEFvKSNY08Uphau5iA4InZH6jn" ) - assert cache_creation_span.attributes["gen_ai.usage.prompt_tokens"] == 1150 - assert cache_creation_span.attributes["gen_ai.usage.completion_tokens"] == 293 + assert cache_creation_span.attributes["gen_ai.usage.input_tokens"] == 1150 + assert cache_creation_span.attributes["gen_ai.usage.output_tokens"] == 293 assert cache_creation_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 0 - assert cache_read_span.attributes["gen_ai.usage.prompt_tokens"] == 1150 - assert cache_read_span.attributes["gen_ai.usage.completion_tokens"] == 307 + assert cache_read_span.attributes["gen_ai.usage.input_tokens"] == 1150 + assert cache_read_span.attributes["gen_ai.usage.output_tokens"] == 307 assert cache_read_span.attributes["gen_ai.usage.cache_read_input_tokens"] == 1024 logs = log_exporter.get_finished_logs() diff --git a/packages/opentelemetry-instrumentation-together/tests/test_chat.py b/packages/opentelemetry-instrumentation-together/tests/test_chat.py index f64ac5217d..df7c710b12 100644 --- a/packages/opentelemetry-instrumentation-together/tests/test_chat.py +++ b/packages/opentelemetry-instrumentation-together/tests/test_chat.py @@ -34,12 +34,12 @@ def test_together_chat_legacy( together_span.attributes.get("gen_ai.completion.0.content") == response.choices[0].message.content ) - assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 18 + assert together_span.attributes.get("gen_ai.usage.input_tokens") == 18 assert together_span.attributes.get( "llm.usage.total_tokens" ) == together_span.attributes.get( - "gen_ai.usage.completion_tokens" - ) + together_span.attributes.get("gen_ai.usage.prompt_tokens") + "gen_ai.usage.output_tokens" + ) + together_span.attributes.get("gen_ai.usage.input_tokens") assert together_span.attributes.get("gen_ai.response.id") == "88fa668fac30bb19-MXP" logs = log_exporter.get_finished_logs() @@ -66,12 +66,12 @@ def test_together_chat_with_events_with_content( together_span.attributes.get("gen_ai.request.model") == "mistralai/Mixtral-8x7B-Instruct-v0.1" ) - assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 18 + assert together_span.attributes.get("gen_ai.usage.input_tokens") == 18 assert together_span.attributes.get( "llm.usage.total_tokens" ) == together_span.attributes.get( - "gen_ai.usage.completion_tokens" - ) + together_span.attributes.get("gen_ai.usage.prompt_tokens") + "gen_ai.usage.output_tokens" + ) + together_span.attributes.get("gen_ai.usage.input_tokens") assert together_span.attributes.get("gen_ai.response.id") == "88fa668fac30bb19-MXP" logs = log_exporter.get_finished_logs() @@ -112,12 +112,12 @@ def test_together_chat_with_events_with_no_content( together_span.attributes.get("gen_ai.request.model") == "mistralai/Mixtral-8x7B-Instruct-v0.1" ) - assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 18 + assert together_span.attributes.get("gen_ai.usage.input_tokens") == 18 assert together_span.attributes.get( "llm.usage.total_tokens" ) == together_span.attributes.get( - "gen_ai.usage.completion_tokens" - ) + together_span.attributes.get("gen_ai.usage.prompt_tokens") + "gen_ai.usage.output_tokens" + ) + together_span.attributes.get("gen_ai.usage.input_tokens") assert together_span.attributes.get("gen_ai.response.id") == "88fa668fac30bb19-MXP" logs = log_exporter.get_finished_logs() diff --git a/packages/opentelemetry-instrumentation-together/tests/test_completion.py b/packages/opentelemetry-instrumentation-together/tests/test_completion.py index ca6cafe924..362e1a1386 100644 --- a/packages/opentelemetry-instrumentation-together/tests/test_completion.py +++ b/packages/opentelemetry-instrumentation-together/tests/test_completion.py @@ -34,12 +34,12 @@ def test_together_completion_legacy( together_span.attributes.get("gen_ai.completion.0.content") == response.choices[0].text ) - assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 10 + assert together_span.attributes.get("gen_ai.usage.input_tokens") == 10 assert together_span.attributes.get( "llm.usage.total_tokens" ) == together_span.attributes.get( - "gen_ai.usage.completion_tokens" - ) + together_span.attributes.get("gen_ai.usage.prompt_tokens") + "gen_ai.usage.output_tokens" + ) + together_span.attributes.get("gen_ai.usage.input_tokens") assert together_span.attributes.get("gen_ai.response.id") == "88fa66988e400e83-MXP" logs = log_exporter.get_finished_logs() @@ -66,12 +66,12 @@ def test_together_completion_with_events_with_content( together_span.attributes.get("gen_ai.request.model") == "mistralai/Mixtral-8x7B-Instruct-v0.1" ) - assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 10 + assert together_span.attributes.get("gen_ai.usage.input_tokens") == 10 assert together_span.attributes.get( "llm.usage.total_tokens" ) == together_span.attributes.get( - "gen_ai.usage.completion_tokens" - ) + together_span.attributes.get("gen_ai.usage.prompt_tokens") + "gen_ai.usage.output_tokens" + ) + together_span.attributes.get("gen_ai.usage.input_tokens") assert together_span.attributes.get("gen_ai.response.id") == "88fa66988e400e83-MXP" logs = log_exporter.get_finished_logs() @@ -112,12 +112,12 @@ def test_together_completion_with_events_with_no_content( together_span.attributes.get("gen_ai.request.model") == "mistralai/Mixtral-8x7B-Instruct-v0.1" ) - assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 10 + assert together_span.attributes.get("gen_ai.usage.input_tokens") == 10 assert together_span.attributes.get( "llm.usage.total_tokens" ) == together_span.attributes.get( - "gen_ai.usage.completion_tokens" - ) + together_span.attributes.get("gen_ai.usage.prompt_tokens") + "gen_ai.usage.output_tokens" + ) + together_span.attributes.get("gen_ai.usage.input_tokens") assert together_span.attributes.get("gen_ai.response.id") == "88fa66988e400e83-MXP" logs = log_exporter.get_finished_logs() diff --git a/packages/opentelemetry-semantic-conventions-ai/opentelemetry/semconv_ai/__init__.py b/packages/opentelemetry-semantic-conventions-ai/opentelemetry/semconv_ai/__init__.py index ffb2bb7e15..96474a841a 100644 --- a/packages/opentelemetry-semantic-conventions-ai/opentelemetry/semconv_ai/__init__.py +++ b/packages/opentelemetry-semantic-conventions-ai/opentelemetry/semconv_ai/__init__.py @@ -47,8 +47,8 @@ class SpanAttributes: LLM_PROMPTS = "gen_ai.prompt" LLM_COMPLETIONS = "gen_ai.completion" LLM_RESPONSE_MODEL = "gen_ai.response.model" - LLM_USAGE_COMPLETION_TOKENS = "gen_ai.usage.completion_tokens" - LLM_USAGE_PROMPT_TOKENS = "gen_ai.usage.prompt_tokens" + LLM_USAGE_COMPLETION_TOKENS = "gen_ai.usage.output_tokens" + LLM_USAGE_PROMPT_TOKENS = "gen_ai.usage.input_tokens" LLM_USAGE_CACHE_CREATION_INPUT_TOKENS = "gen_ai.usage.cache_creation_input_tokens" LLM_USAGE_CACHE_READ_INPUT_TOKENS = "gen_ai.usage.cache_read_input_tokens" LLM_TOKEN_TYPE = "gen_ai.token.type" From e1cec0a4e68213993a2edc6c9ca8c5fd508081d0 Mon Sep 17 00:00:00 2001 From: Martim Santos Date: Sat, 19 Jul 2025 16:23:27 +0000 Subject: [PATCH 2/3] added opentelemetry gen_ai attributes --- .../instrumentation/alephalpha/__init__.py | 4 +- .../instrumentation/alephalpha/span_utils.py | 8 +- .../instrumentation/anthropic/__init__.py | 12 +- .../instrumentation/anthropic/span_utils.py | 26 +-- .../instrumentation/anthropic/streaming.py | 6 +- .../instrumentation/anthropic/utils.py | 2 +- .../tests/test_completion.py | 4 +- .../tests/test_messages.py | 80 +++---- .../tests/utils.py | 8 +- .../instrumentation/bedrock/guardrail.py | 12 +- .../instrumentation/bedrock/span_utils.py | 136 ++++++------ .../test_bedrock_guardrails_metrics.py | 6 +- .../tests/metrics/test_bedrock_metrics.py | 4 +- .../tests/traces/test_anthropic.py | 32 +-- .../tests/traces/test_cohere.py | 34 +-- .../tests/traces/test_imported_model.py | 32 +-- .../tests/traces/test_meta.py | 28 +-- .../tests/traces/test_nova.py | 200 +++++++++--------- .../tests/traces/test_titan.py | 106 +++++----- .../instrumentation/cohere/__init__.py | 2 +- .../instrumentation/cohere/span_utils.py | 30 +-- .../tests/test_chat.py | 16 +- .../tests/test_completion.py | 14 +- .../tests/test_rerank.py | 24 +-- .../instrumentation/crewai/instrumentation.py | 22 +- .../google_generativeai/__init__.py | 4 +- .../google_generativeai/span_utils.py | 38 ++-- .../tests/test_generate_content.py | 20 +- .../instrumentation/groq/__init__.py | 4 +- .../instrumentation/groq/span_utils.py | 28 +-- .../instrumentation/groq/utils.py | 2 +- .../tests/traces/test_chat_tracing.py | 12 +- .../instrumentation/haystack/wrap_openai.py | 14 +- .../langchain/callback_handler.py | 22 +- .../instrumentation/langchain/span_utils.py | 24 +-- .../tests/metrics/test_langchain_metrics.py | 12 +- .../tests/test_chains.py | 14 +- .../tests/test_llms.py | 88 ++++---- .../tests/test_structured_output.py | 4 +- .../tests/test_tool_calls.py | 102 ++++----- .../llamaindex/custom_llm_instrumentor.py | 14 +- .../instrumentation/llamaindex/span_utils.py | 22 +- .../tests/test_agents.py | 76 +++---- .../tests/test_chroma_vector_store.py | 8 +- .../tests/test_query_pipeline.py | 16 +- .../instrumentation/mistralai/__init__.py | 24 +-- .../tests/test_chat.py | 58 ++--- .../tests/test_embeddings.py | 28 +-- .../instrumentation/ollama/__init__.py | 24 +-- .../instrumentation/ollama/span_utils.py | 36 ++-- .../tests/test_chat.py | 94 ++++---- .../tests/test_embeddings.py | 14 +- .../tests/test_generation.py | 64 +++--- .../tests/test_ollama_metrics.py | 6 +- .../instrumentation/openai_agents/__init__.py | 36 ++-- .../tests/test_openai_agents.py | 32 +-- .../instrumentation/openai/shared/__init__.py | 20 +- .../openai/shared/chat_wrappers.py | 14 +- .../openai/shared/completion_wrappers.py | 4 +- .../openai/shared/embeddings_wrappers.py | 6 +- .../openai/v1/assistant_wrappers.py | 34 +-- .../openai/v1/event_handler_wrapper.py | 4 +- .../tests/metrics/test_openai_metrics.py | 10 +- .../tests/traces/test_assistant.py | 134 ++++++------ .../tests/traces/test_azure.py | 36 ++-- .../tests/traces/test_chat.py | 84 ++++---- .../tests/traces/test_chat_parse.py | 36 ++-- .../tests/traces/test_completions.py | 24 +-- .../tests/traces/test_embeddings.py | 24 +-- .../tests/traces/test_functions.py | 46 ++-- .../tests/traces/test_vision.py | 8 +- .../instrumentation/replicate/__init__.py | 2 +- .../instrumentation/replicate/span_utils.py | 16 +- .../instrumentation/sagemaker/span_utils.py | 2 +- .../tests/test_invocation.py | 6 +- .../instrumentation/together/__init__.py | 2 +- .../instrumentation/together/span_utils.py | 20 +- .../transformers/span_utils.py | 14 +- .../instrumentation/vertexai/__init__.py | 4 +- .../instrumentation/vertexai/span_utils.py | 18 +- .../tests/disabled_test_bison.py | 60 +++--- .../tests/disabled_test_gemini.py | 10 +- .../instrumentation/watsonx/__init__.py | 34 +-- .../tests/metrics/test_watsonx_metrics.py | 8 +- .../tests/traces/test_generate.py | 20 +- .../opentelemetry/semconv_ai/__init__.py | 56 +++-- .../poetry.lock | 109 +++++++++- .../pyproject.toml | 1 + packages/traceloop-sdk/tests/test_manual.py | 10 +- .../tests/test_privacy_no_prompts.py | 4 +- .../tests/test_prompt_management.py | 4 +- .../traceloop-sdk/tests/test_workflows.py | 8 +- .../traceloop/sdk/tracing/manual.py | 14 +- 93 files changed, 1410 insertions(+), 1284 deletions(-) diff --git a/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/__init__.py b/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/__init__.py index e1131b24f8..2f4eb239e5 100644 --- a/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/__init__.py +++ b/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/__init__.py @@ -69,7 +69,7 @@ def _handle_message_event( event: PromptEvent, span: Span, event_logger: Optional[EventLogger], kwargs ): if span.is_recording(): - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("model")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, kwargs.get("model")) if should_emit_events(): return emit_event(event, event_logger) @@ -157,7 +157,7 @@ def _wrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "AlephAlpha", + SpanAttributes.GEN_AI_SYSTEM: "AlephAlpha", SpanAttributes.LLM_REQUEST_TYPE: llm_request_type.value, }, ) diff --git a/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/span_utils.py b/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/span_utils.py index c604a5f6f9..52ab191646 100644 --- a/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/span_utils.py +++ b/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/span_utils.py @@ -16,10 +16,10 @@ def set_prompt_attributes(event: PromptEvent, span: Span): return if should_send_prompts(): - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user") _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.content", + f"{SpanAttributes.GEN_AI_PROMPT}.0.content", event.content[0].get("data"), ) @@ -36,9 +36,9 @@ def set_completion_attributes(event: CompletionEvent, span: Span): if should_send_prompts(): _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", event.message["content"], ) _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.role", "assistant" + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", "assistant" ) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py index ebb1234883..86668e3556 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py @@ -127,7 +127,7 @@ async def _aset_token_usage( input_tokens, attributes={ **metric_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", }, ) @@ -154,7 +154,7 @@ async def _aset_token_usage( completion_tokens, attributes={ **metric_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", }, ) @@ -220,7 +220,7 @@ def _set_token_usage( input_tokens, attributes={ **metric_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", }, ) @@ -245,7 +245,7 @@ def _set_token_usage( completion_tokens, attributes={ **metric_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", }, ) @@ -397,7 +397,7 @@ def _wrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Anthropic", + SpanAttributes.GEN_AI_SYSTEM: "Anthropic", SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value, }, ) @@ -494,7 +494,7 @@ async def _awrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Anthropic", + SpanAttributes.GEN_AI_SYSTEM: "Anthropic", SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value, }, ) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py index da7baa2063..a3fbc3f032 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py @@ -73,14 +73,14 @@ async def _dump_content(message_index, content, span): async def aset_input_attributes(span, kwargs): from opentelemetry.instrumentation.anthropic import set_span_attribute - set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("model")) + set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, kwargs.get("model")) set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, kwargs.get("max_tokens_to_sample") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get("max_tokens_to_sample") ) set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, kwargs.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, kwargs.get("temperature") ) - set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, kwargs.get("top_p")) + set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, kwargs.get("top_p")) set_span_attribute( span, SpanAttributes.LLM_FREQUENCY_PENALTY, kwargs.get("frequency_penalty") ) @@ -92,7 +92,7 @@ async def aset_input_attributes(span, kwargs): if should_send_prompts(): if kwargs.get("prompt") is not None: set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.user", kwargs.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.user", kwargs.get("prompt") ) elif kwargs.get("messages") is not None: @@ -101,28 +101,28 @@ async def aset_input_attributes(span, kwargs): has_system_message = True set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.content", + f"{SpanAttributes.GEN_AI_PROMPT}.0.content", await _dump_content( message_index=0, span=span, content=kwargs.get("system") ), ) set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.role", + f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "system", ) for i, message in enumerate(kwargs.get("messages")): prompt_index = i + (1 if has_system_message else 0) set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_index}.content", await _dump_content( message_index=i, span=span, content=message.get("content") ), ) set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_index}.role", message.get("role"), ) @@ -146,7 +146,7 @@ def _set_span_completions(span, response): from opentelemetry.instrumentation.anthropic import set_span_attribute index = 0 - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" set_span_attribute(span, f"{prefix}.finish_reason", response.get("stop_reason")) if response.get("role"): set_span_attribute(span, f"{prefix}.role", response.get("role")) @@ -177,7 +177,7 @@ def _set_span_completions(span, response): ) # increment the index for subsequent content blocks index += 1 - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" # set the role to the original role on the next completions set_span_attribute( span, @@ -213,7 +213,7 @@ def set_response_attributes(span, response): if not isinstance(response, dict): response = response.__dict__ - set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, response.get("model")) + set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, response.get("model")) set_span_attribute(span, GEN_AI_RESPONSE_ID, response.get("id")) if response.get("usage"): @@ -245,7 +245,7 @@ def set_streaming_response_attributes(span, complete_response_events): try: for event in complete_response_events: index = event.get("index") - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" set_span_attribute( span, f"{prefix}.finish_reason", event.get("finish_reason") ) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py index bf8f33963f..bc8e9ae5c9 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py @@ -91,7 +91,7 @@ def _set_token_usage( set_span_attribute(span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, total_tokens) set_span_attribute( - span, SpanAttributes.LLM_RESPONSE_MODEL, complete_response.get("model") + span, SpanAttributes.GEN_AI_RESPONSE_MODEL, complete_response.get("model") ) set_span_attribute( span, SpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens @@ -107,7 +107,7 @@ def _set_token_usage( input_tokens, attributes={ **metric_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", }, ) @@ -116,7 +116,7 @@ def _set_token_usage( completion_tokens, attributes={ **metric_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", }, ) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py index c269e9b70d..00ccf266ee 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/utils.py @@ -71,7 +71,7 @@ def shared_metrics_attributes(response): return { **common_attributes, GEN_AI_SYSTEM: GEN_AI_SYSTEM_ANTHROPIC, - SpanAttributes.LLM_RESPONSE_MODEL: response.get("model"), + SpanAttributes.GEN_AI_RESPONSE_MODEL: response.get("model"), } diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/test_completion.py b/packages/opentelemetry-instrumentation-anthropic/tests/test_completion.py index e43494d8fe..2a73372c46 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/test_completion.py +++ b/packages/opentelemetry-instrumentation-anthropic/tests/test_completion.py @@ -34,10 +34,10 @@ def test_anthropic_completion_legacy( anthropic_span = spans[0] assert ( - anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == f"{HUMAN_PROMPT}\nHello world\n{AI_PROMPT}" ) - assert anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( anthropic_span.attributes.get("gen_ai.response.id") == "compl_01EjfrPvPEsRDRUKD6VoBxtK" diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py b/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py index 10cd7858b7..758565c63b 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py +++ b/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py @@ -56,16 +56,16 @@ def test_anthropic_message_create_legacy( anthropic_span = spans[0] assert ( - anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about OpenTelemetry" ) - assert (anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"]) == "user" + assert (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"]) == "user" assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response.content[0].text ) assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.role") == "assistant" ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 @@ -235,20 +235,20 @@ def test_anthropic_multi_modal_legacy( ] anthropic_span = spans[0] assert anthropic_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.0.content" + f"{SpanAttributes.GEN_AI_PROMPT}.0.content" ] == json.dumps( [ {"type": "text", "text": "What do you see?"}, {"type": "image_url", "image_url": {"url": "/some/url"}}, ] ) - assert (anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"]) == "user" + assert (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"]) == "user" assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response.content[0].text ) assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.role") == "assistant" ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1381 @@ -430,53 +430,53 @@ def test_anthropic_image_with_history( spans = span_exporter.get_finished_spans() assert all(span.name == "anthropic.chat" for span in spans) assert ( - spans[0].attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == system_message + spans[0].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == system_message ) - assert spans[0].attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert spans[0].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert ( - spans[0].attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] + spans[0].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == "Are you capable of describing an image?" ) - assert spans[0].attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "user" + assert spans[0].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "user" assert ( - spans[0].attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + spans[0].attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response1.content[0].text ) assert ( - spans[0].attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"] == "assistant" + spans[0].attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"] == "assistant" ) assert ( spans[0].attributes.get("gen_ai.response.id") == "msg_01Ctc62hUPvikvYASXZqTo9q" ) assert ( - spans[1].attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == system_message + spans[1].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == system_message ) - assert spans[1].attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert spans[1].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert ( - spans[1].attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] + spans[1].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == "Are you capable of describing an image?" ) - assert spans[1].attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "user" + assert spans[1].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "user" assert ( - spans[1].attributes[f"{SpanAttributes.LLM_PROMPTS}.2.content"] + spans[1].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.content"] == response1.content[0].text ) - assert spans[1].attributes[f"{SpanAttributes.LLM_PROMPTS}.2.role"] == "assistant" + assert spans[1].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.role"] == "assistant" assert json.loads( - spans[1].attributes[f"{SpanAttributes.LLM_PROMPTS}.3.content"] + spans[1].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.3.content"] ) == [ {"type": "text", "text": "What do you see?"}, {"type": "image_url", "image_url": {"url": "/some/url"}}, ] - assert spans[1].attributes[f"{SpanAttributes.LLM_PROMPTS}.3.role"] == "user" + assert spans[1].attributes[f"{SpanAttributes.GEN_AI_PROMPT}.3.role"] == "user" assert ( - spans[1].attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + spans[1].attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response2.content[0].text ) assert ( - spans[1].attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"] == "assistant" + spans[1].attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"] == "assistant" ) assert ( spans[1].attributes.get("gen_ai.response.id") == "msg_01EtAvxHCWn5jjdUCnG4wEAd" @@ -516,20 +516,20 @@ async def test_anthropic_async_multi_modal_legacy( ] anthropic_span = spans[0] assert anthropic_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.0.content" + f"{SpanAttributes.GEN_AI_PROMPT}.0.content" ] == json.dumps( [ {"type": "text", "text": "What do you see?"}, {"type": "image_url", "image_url": {"url": "/some/url"}}, ] ) - assert (anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"]) == "user" + assert (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"]) == "user" assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response.content[0].text ) assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.role") == "assistant" ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1311 @@ -705,16 +705,16 @@ def test_anthropic_message_streaming_legacy( ] anthropic_span = spans[0] assert ( - anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about OpenTelemetry" ) - assert (anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"]) == "user" + assert (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"]) == "user" assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response_content ) assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.role") == "assistant" ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 @@ -892,16 +892,16 @@ async def test_async_anthropic_message_create_legacy( ] anthropic_span = spans[0] assert ( - anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about OpenTelemetry" ) - assert (anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"]) == "user" + assert (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"]) == "user" assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response.content[0].text ) assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.role") == "assistant" ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 @@ -1070,16 +1070,16 @@ async def test_async_anthropic_message_streaming_legacy( ] anthropic_span = spans[0] assert ( - anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about OpenTelemetry" ) - assert (anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"]) == "user" + assert (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"]) == "user" assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response_content ) assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.role") == "assistant" ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/utils.py b/packages/opentelemetry-instrumentation-anthropic/tests/utils.py index e5ebea7b2c..e37b1a6143 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/utils.py +++ b/packages/opentelemetry-instrumentation-anthropic/tests/utils.py @@ -16,12 +16,12 @@ def verify_metrics( if metric.name == Meters.LLM_TOKEN_USAGE: found_token_metric = True for data_point in metric.data.data_points: - assert data_point.attributes[SpanAttributes.LLM_TOKEN_TYPE] in [ + assert data_point.attributes[SpanAttributes.GEN_AI_TOKEN_TYPE] in [ "output", "input", ] assert ( - data_point.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + data_point.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == model_name ) if not ignore_zero_input_tokens: @@ -32,7 +32,7 @@ def verify_metrics( for data_point in metric.data.data_points: assert data_point.value >= 1 assert ( - data_point.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + data_point.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == model_name ) @@ -45,7 +45,7 @@ def verify_metrics( data_point.sum > 0 for data_point in metric.data.data_points ) assert all( - data_point.attributes.get(SpanAttributes.LLM_RESPONSE_MODEL) + data_point.attributes.get(SpanAttributes.GEN_AI_RESPONSE_MODEL) == model_name or data_point.attributes.get("error.type") == "TypeError" for data_point in metric.data.data_points diff --git a/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/guardrail.py b/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/guardrail.py index d5e484ef40..f3ebf27e45 100644 --- a/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/guardrail.py +++ b/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/guardrail.py @@ -36,7 +36,7 @@ def handle_invoke_metrics(t: Type, guardrail, attrs, metric_params): input_latency, attributes={ **attrs, - SpanAttributes.LLM_TOKEN_TYPE: t.value, + SpanAttributes.GEN_AI_TOKEN_TYPE: t.value, }, ) if "guardrailCoverage" in guardrail["invocationMetrics"]: @@ -46,7 +46,7 @@ def handle_invoke_metrics(t: Type, guardrail, attrs, metric_params): char_guarded, attributes={ **attrs, - SpanAttributes.LLM_TOKEN_TYPE: t.value, + SpanAttributes.GEN_AI_TOKEN_TYPE: t.value, }, ) @@ -133,8 +133,8 @@ def handle_words(t: Type, guardrail, attrs, metric_params): def guardrail_converse(response, vendor, model, metric_params): attrs = { "gen_ai.vendor": vendor, - SpanAttributes.LLM_RESPONSE_MODEL: model, - SpanAttributes.LLM_SYSTEM: "bedrock", + SpanAttributes.GEN_AI_RESPONSE_MODEL: model, + SpanAttributes.GEN_AI_SYSTEM: "bedrock", } if "trace" in response and "guardrail" in response["trace"]: guardrail = response["trace"]["guardrail"] @@ -157,8 +157,8 @@ def guardrail_handling(response_body, vendor, model, metric_params): if "amazon-bedrock-guardrailAction" in response_body: attrs = { "gen_ai.vendor": vendor, - SpanAttributes.LLM_RESPONSE_MODEL: model, - SpanAttributes.LLM_SYSTEM: "bedrock", + SpanAttributes.GEN_AI_RESPONSE_MODEL: model, + SpanAttributes.GEN_AI_SYSTEM: "bedrock", } if "amazon-bedrock-trace" in response_body: bedrock_trace = response_body["amazon-bedrock-trace"] diff --git a/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/span_utils.py b/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/span_utils.py index 13ddb05d60..1e8d7ab2e8 100644 --- a/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/span_utils.py +++ b/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/span_utils.py @@ -34,12 +34,12 @@ def set_model_message_span_attributes(model_vendor, span, request_body): for idx, message in enumerate(request_body.get("messages")): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{idx}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.role", message.get("role"), ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.content", + f"{SpanAttributes.GEN_AI_PROMPT}.0.content", json.dumps(message.get("content")), ) elif model_vendor == "ai21": @@ -82,9 +82,9 @@ def set_model_span_attributes( response_model = response_body.get("model") response_id = response_body.get("id") - _set_span_attribute(span, SpanAttributes.LLM_SYSTEM, provider) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, model) - _set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, response_model) + _set_span_attribute(span, SpanAttributes.GEN_AI_SYSTEM, provider) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, model) + _set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, response_model) _set_span_attribute(span, GEN_AI_RESPONSE_ID, response_id) if model_vendor == "cohere": @@ -114,7 +114,7 @@ def set_model_span_attributes( def _set_prompt_span_attributes(span, request_body): _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.user", request_body.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.user", request_body.get("prompt") ) @@ -122,12 +122,12 @@ def _set_cohere_span_attributes(span, request_body, response_body, metric_params _set_span_attribute( span, SpanAttributes.LLM_REQUEST_TYPE, LLMRequestTypeValues.COMPLETION.value ) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, request_body.get("p")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, request_body.get("p")) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, request_body.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, request_body.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, request_body.get("max_tokens") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, request_body.get("max_tokens") ) # based on contract at @@ -154,7 +154,7 @@ def _set_generations_span_attributes(span, response_body): for i, generation in enumerate(response_body.get("generations")): _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.{i}.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.content", generation.get("text"), ) @@ -166,14 +166,14 @@ def _set_anthropic_completion_span_attributes( span, SpanAttributes.LLM_REQUEST_TYPE, LLMRequestTypeValues.COMPLETION.value ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TOP_P, request_body.get("top_p") + span, SpanAttributes.GEN_AI_REQUEST_TOP_P, request_body.get("top_p") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, request_body.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, request_body.get("temperature") ) _set_span_attribute( span, - SpanAttributes.LLM_REQUEST_MAX_TOKENS, + SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, request_body.get("max_tokens_to_sample"), ) @@ -208,16 +208,16 @@ def _set_anthropic_response_span_attributes(span, response_body): if response_body.get("completion") is not None: _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response_body.get("completion"), ) elif response_body.get("content") is not None: _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.content", "assistant" + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", "assistant" ) _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", json.dumps(response_body.get("content")), ) @@ -229,14 +229,14 @@ def _set_anthropic_messages_span_attributes( span, SpanAttributes.LLM_REQUEST_TYPE, LLMRequestTypeValues.CHAT.value ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TOP_P, request_body.get("top_p") + span, SpanAttributes.GEN_AI_REQUEST_TOP_P, request_body.get("top_p") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, request_body.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, request_body.get("temperature") ) _set_span_attribute( span, - SpanAttributes.LLM_REQUEST_MAX_TOKENS, + SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, request_body.get("max_tokens"), ) @@ -284,13 +284,13 @@ def _set_ai21_span_attributes(span, request_body, response_body, metric_params): span, SpanAttributes.LLM_REQUEST_TYPE, LLMRequestTypeValues.COMPLETION.value ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TOP_P, request_body.get("topP") + span, SpanAttributes.GEN_AI_REQUEST_TOP_P, request_body.get("topP") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, request_body.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, request_body.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, request_body.get("maxTokens") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, request_body.get("maxTokens") ) _record_usage_to_span( @@ -305,7 +305,7 @@ def _set_span_completions_attributes(span, response_body): for i, completion in enumerate(response_body.get("completions")): _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.{i}.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.content", completion.get("data").get("text"), ) @@ -315,13 +315,13 @@ def _set_llama_span_attributes(span, request_body, response_body, metric_params) span, SpanAttributes.LLM_REQUEST_TYPE, LLMRequestTypeValues.COMPLETION.value ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TOP_P, request_body.get("top_p") + span, SpanAttributes.GEN_AI_REQUEST_TOP_P, request_body.get("top_p") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, request_body.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, request_body.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, request_body.get("max_gen_len") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, request_body.get("max_gen_len") ) _record_usage_to_span( @@ -334,28 +334,28 @@ def _set_llama_span_attributes(span, request_body, response_body, metric_params) def _set_llama_prompt_span_attributes(span, request_body): _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.content", request_body.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.content", request_body.get("prompt") ) - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user") def _set_llama_response_span_attributes(span, response_body): if response_body.get("generation"): _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.role", "assistant" + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", "assistant" ) _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response_body.get("generation"), ) else: for i, generation in enumerate(response_body.get("generations")): _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.{i}.role", "assistant" + span, f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.role", "assistant" ) _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.{i}.content", generation + span, f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.content", generation ) @@ -368,21 +368,21 @@ def _set_amazon_span_attributes( if "textGenerationConfig" in request_body: config = request_body.get("textGenerationConfig", {}) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, config.get("topP")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, config.get("topP")) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, config.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, config.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, config.get("maxTokenCount") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, config.get("maxTokenCount") ) elif "inferenceConfig" in request_body: config = request_body.get("inferenceConfig", {}) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, config.get("topP")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, config.get("topP")) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, config.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, config.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, config.get("maxTokens") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, config.get("maxTokens") ) total_completion_tokens = 0 @@ -419,7 +419,7 @@ def _set_amazon_input_span_attributes(span, request_body): if "inputText" in request_body: _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.user", + f"{SpanAttributes.GEN_AI_PROMPT}.0.user", request_body.get("inputText"), ) else: @@ -428,24 +428,24 @@ def _set_amazon_input_span_attributes(span, request_body): for idx, prompt in enumerate(request_body["system"]): prompt_idx = idx + 1 _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{idx}.role", "system" + span, f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.role", "system" ) # TODO: add support for "image" _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{idx}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.content", prompt.get("text"), ) for idx, prompt in enumerate(request_body["messages"]): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{prompt_idx + idx}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_idx + idx}.role", prompt.get("role"), ) # TODO: here we stringify the object, consider moving these to events or prompt.{i}.content.{j} _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{prompt_idx + idx}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_idx + idx}.content", json.dumps(prompt.get("content", ""), default=str), ) @@ -455,13 +455,13 @@ def _set_amazon_response_span_attributes(span, response_body): for i, result in enumerate(response_body.get("results")): _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.{i}.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.content", result.get("outputText"), ) elif "outputText" in response_body: _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response_body.get("outputText"), ) elif "output" in response_body: @@ -469,7 +469,7 @@ def _set_amazon_response_span_attributes(span, response_body): for idx, msg in enumerate(msgs): _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}.content", msg.get("text"), ) @@ -481,13 +481,13 @@ def _set_imported_model_span_attributes( span, SpanAttributes.LLM_REQUEST_TYPE, LLMRequestTypeValues.COMPLETION.value ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TOP_P, request_body.get("topP") + span, SpanAttributes.GEN_AI_REQUEST_TOP_P, request_body.get("topP") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, request_body.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, request_body.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, request_body.get("max_tokens") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, request_body.get("max_tokens") ) prompt_tokens = ( response_body.get("usage", {}).get("prompt_tokens") @@ -509,14 +509,14 @@ def _set_imported_model_span_attributes( def _set_imported_model_response_span_attributes(span, response_body): _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response_body.get("generation"), ) def _set_imported_model_prompt_span_attributes(span, request_body): _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.content", request_body.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.content", request_body.get("prompt") ) @@ -557,7 +557,7 @@ def _record_usage_to_span(span, prompt_tokens, completion_tokens, metric_params) prompt_tokens, attributes={ **metric_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", }, ) if ( @@ -569,7 +569,7 @@ def _record_usage_to_span(span, prompt_tokens, completion_tokens, metric_params) completion_tokens, attributes={ **metric_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", }, ) @@ -579,15 +579,15 @@ def _metric_shared_attributes( ): return { "vendor": response_vendor, - SpanAttributes.LLM_RESPONSE_MODEL: response_model, - SpanAttributes.LLM_SYSTEM: "bedrock", + SpanAttributes.GEN_AI_RESPONSE_MODEL: response_model, + SpanAttributes.GEN_AI_SYSTEM: "bedrock", "stream": is_streaming, } def set_converse_model_span_attributes(span, provider, model, kwargs): - _set_span_attribute(span, SpanAttributes.LLM_SYSTEM, provider) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, model) + _set_span_attribute(span, SpanAttributes.GEN_AI_SYSTEM, provider) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, model) _set_span_attribute( span, SpanAttributes.LLM_REQUEST_TYPE, LLMRequestTypeValues.CHAT.value ) @@ -596,12 +596,12 @@ def set_converse_model_span_attributes(span, provider, model, kwargs): if "inferenceConfig" in kwargs: config = kwargs.get("inferenceConfig") - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, config.get("topP")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, config.get("topP")) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, config.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, config.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, config.get("maxTokens") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, config.get("maxTokens") ) @@ -613,25 +613,25 @@ def set_converse_input_prompt_span_attributes(kwargs, span): for idx, prompt in enumerate(kwargs["system"]): prompt_idx = idx + 1 _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{idx}.role", "system" + span, f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.role", "system" ) # TODO: add support for "image" _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{idx}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.content", prompt.get("text"), ) if "messages" in kwargs: for idx, prompt in enumerate(kwargs["messages"]): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{prompt_idx+idx}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_idx+idx}.role", prompt.get("role"), ) # TODO: here we stringify the object, consider moving these to events or prompt.{i}.content.{j} _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{prompt_idx+idx}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_idx+idx}.content", json.dumps(prompt.get("content", ""), default=str), ) @@ -642,12 +642,12 @@ def set_converse_response_span_attributes(response, span): if "output" in response: message = response["output"]["message"] _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.role", message.get("role") + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", message.get("role") ) for idx, content in enumerate(message["content"]): _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}.content", content.get("text"), ) @@ -655,9 +655,9 @@ def set_converse_response_span_attributes(response, span): def set_converse_streaming_response_span_attributes(response, role, span): if not should_send_prompts(): return - _set_span_attribute(span, f"{SpanAttributes.LLM_COMPLETIONS}.0.role", role) + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", role) _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.content", "".join(response) + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", "".join(response) ) diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/metrics/test_bedrock_guardrails_metrics.py b/packages/opentelemetry-instrumentation-bedrock/tests/metrics/test_bedrock_guardrails_metrics.py index f039ee2375..8ac0e5f615 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/metrics/test_bedrock_guardrails_metrics.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/metrics/test_bedrock_guardrails_metrics.py @@ -101,7 +101,7 @@ def assert_guardrails(reader): if metric.name == GuardrailMeters.LLM_BEDROCK_GUARDRAIL_LATENCY: found_latency = True for data_point in metric.data.data_points: - assert data_point.attributes[SpanAttributes.LLM_TOKEN_TYPE] in [ + assert data_point.attributes[SpanAttributes.GEN_AI_TOKEN_TYPE] in [ "output", "input", ] @@ -115,14 +115,14 @@ def assert_guardrails(reader): if metric.name == GuardrailMeters.LLM_BEDROCK_GUARDRAIL_COVERAGE: found_coverage = True for data_point in metric.data.data_points: - assert data_point.attributes[SpanAttributes.LLM_TOKEN_TYPE] in [ + assert data_point.attributes[SpanAttributes.GEN_AI_TOKEN_TYPE] in [ "output", "input", ] assert data_point.value > 0 assert ( - metric.data.data_points[0].attributes[SpanAttributes.LLM_SYSTEM] + metric.data.data_points[0].attributes[SpanAttributes.GEN_AI_SYSTEM] == "bedrock" ) diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/metrics/test_bedrock_metrics.py b/packages/opentelemetry-instrumentation-bedrock/tests/metrics/test_bedrock_metrics.py index eaf693e8b2..51c0a0fb57 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/metrics/test_bedrock_metrics.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/metrics/test_bedrock_metrics.py @@ -44,7 +44,7 @@ def test_invoke_model_metrics(test_context, brt): if metric.name == Meters.LLM_TOKEN_USAGE: found_token_metric = True for data_point in metric.data.data_points: - assert data_point.attributes[SpanAttributes.LLM_TOKEN_TYPE] in [ + assert data_point.attributes[SpanAttributes.GEN_AI_TOKEN_TYPE] in [ "output", "input", ] @@ -60,7 +60,7 @@ def test_invoke_model_metrics(test_context, brt): ) assert ( - metric.data.data_points[0].attributes[SpanAttributes.LLM_SYSTEM] + metric.data.data_points[0].attributes[SpanAttributes.GEN_AI_SYSTEM] == "bedrock" ) diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_anthropic.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_anthropic.py index 4e5cc7e5f6..4f2fb541d8 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_anthropic.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_anthropic.py @@ -37,11 +37,11 @@ def test_anthropic_2_completion(instrument_legacy, brt, span_exporter, log_expor anthropic_span = spans[0] assert ( - anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == "Human: Tell me a joke about opentelemetry Assistant:" ) assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == completion ) @@ -203,14 +203,14 @@ def test_anthropic_3_completion_complex_content( anthropic_span = spans[0] assert json.loads( - anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] ) == [ {"type": "text", "text": "Tell me a joke about opentelemetry"}, ] assert ( json.loads( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") ) == completion ) @@ -404,13 +404,13 @@ def test_anthropic_3_completion_streaming( anthropic_span = spans[0] assert json.loads( - anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] ) == [ {"type": "text", "text": "Tell me a joke about opentelemetry"}, ] assert json.loads( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") ) == [ { "type": "text", @@ -606,13 +606,13 @@ def test_anthropic_3_completion_string_content( anthropic_span = spans[0] assert ( - json.loads(anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"]) + json.loads(anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"]) == "Tell me a joke about opentelemetry" ) assert ( json.loads( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") ) == completion ) @@ -784,16 +784,16 @@ def test_anthropic_cross_region(instrument_legacy, brt, span_exporter, log_expor # Assert on model name and vendor assert ( - anthropic_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "claude-3-7-sonnet-20250219-v1" ) - assert anthropic_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" assert anthropic_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.0.content" + f"{SpanAttributes.GEN_AI_PROMPT}.0.content" ] == json.dumps(messages[0]["content"]) assert ( - anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == completion ) @@ -840,10 +840,10 @@ def test_anthropic_cross_region_with_events_with_content( # Assert on model name and vendor assert ( - anthropic_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "claude-3-7-sonnet-20250219-v1" ) - assert anthropic_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 20 assert anthropic_span.attributes.get( @@ -906,10 +906,10 @@ def test_anthropic_cross_region_with_events_with_no_content( # Assert on model name and vendor assert ( - anthropic_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "claude-3-7-sonnet-20250219-v1" ) - assert anthropic_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 20 assert anthropic_span.attributes.get( diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_cohere.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_cohere.py index b911c0ebaa..d3faf54024 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_cohere.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_cohere.py @@ -41,22 +41,22 @@ def test_cohere_completion(instrument_legacy, brt, span_exporter, log_exporter): # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "command-text-v14" + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "command-text-v14" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on prompt - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] == prompt + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == prompt # Assert on response generated_text = response_body["generations"][0]["text"] assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == generated_text ) assert ( @@ -65,9 +65,9 @@ def test_cohere_completion(instrument_legacy, brt, span_exporter, log_exporter): ) # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 200 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 200 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.5 logs = log_exporter.get_finished_logs() assert ( @@ -103,11 +103,11 @@ def test_cohere_completion_with_events_with_no_content( # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "command-text-v14" + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "command-text-v14" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" @@ -119,9 +119,9 @@ def test_cohere_completion_with_events_with_no_content( ) # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 200 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 200 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.5 logs = log_exporter.get_finished_logs() assert len(logs) == 2 @@ -171,11 +171,11 @@ def test_cohere_completion_with_events_with_content( # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "command-text-v14" + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "command-text-v14" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" @@ -188,9 +188,9 @@ def test_cohere_completion_with_events_with_content( ) # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 200 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 200 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.5 logs = log_exporter.get_finished_logs() assert len(logs) == 2 diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_imported_model.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_imported_model.py index 40f8f9e237..8fcc0ba202 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_imported_model.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_imported_model.py @@ -27,20 +27,20 @@ def test_imported_model_completion(instrument_legacy, brt, span_exporter, log_ex imported_model_span = spans[0] assert ( - imported_model_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "arn:aws:sagemaker:us-east-1:767398002385:endpoint/endpoint-quick-start-idr7y" ) assert ( imported_model_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" ) - assert imported_model_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert imported_model_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" assert imported_model_span.attributes.get("gen_ai.response.id") is None - assert imported_model_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 100 - assert imported_model_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert imported_model_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 2 + assert imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 100 + assert imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 2 assert ( - imported_model_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + imported_model_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == prompt ) assert data is not None @@ -69,17 +69,17 @@ def test_imported_model_completion_with_events_with_content( imported_model_span = spans[0] assert ( - imported_model_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "arn:aws:sagemaker:us-east-1:767398002385:endpoint/endpoint-quick-start-idr7y" ) assert ( imported_model_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" ) - assert imported_model_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert imported_model_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" assert imported_model_span.attributes.get("gen_ai.response.id") is None - assert imported_model_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 100 - assert imported_model_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert imported_model_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 2 + assert imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 100 + assert imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 2 assert data is not None @@ -117,17 +117,17 @@ def test_imported_model_completion_with_events_with_no_content( imported_model_span = spans[0] assert ( - imported_model_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "arn:aws:sagemaker:us-east-1:767398002385:endpoint/endpoint-quick-start-idr7y" ) assert ( imported_model_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" ) - assert imported_model_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert imported_model_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" assert imported_model_span.attributes.get("gen_ai.response.id") is None - assert imported_model_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 100 - assert imported_model_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert imported_model_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 2 + assert imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 100 + assert imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert imported_model_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 2 assert data is not None diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_meta.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_meta.py index eaa71f8b4b..43b0d0d876 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_meta.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_meta.py @@ -201,9 +201,9 @@ def test_meta_llama3_completion(instrument_legacy, brt, span_exporter, log_expor meta_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == response_body["generation_token_count"] + response_body["prompt_token_count"] ) - assert meta_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == prompt + assert meta_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == prompt assert ( - meta_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + meta_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response_body["generation"] ) assert meta_span.attributes.get("gen_ai.response.id") is None @@ -350,21 +350,21 @@ def test_meta_converse(instrument_legacy, brt, span_exporter, log_exporter): meta_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == response["usage"]["totalTokens"] ) - assert meta_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert meta_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert ( - meta_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == system_prompt + meta_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == system_prompt ) - assert meta_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "user" + assert meta_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "user" assert meta_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.1.content" + f"{SpanAttributes.GEN_AI_PROMPT}.1.content" ] == json.dumps(messages[0]["content"]) for i in range(0, len(generated_text)): assert ( - meta_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.{i}.role"] + meta_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.role"] == "assistant" ) assert ( - meta_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.{i}.content"] + meta_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.content"] == generated_text[i]["text"] ) assert meta_span.attributes.get("gen_ai.response.id") is None @@ -558,21 +558,21 @@ def test_meta_converse_stream(instrument_legacy, brt, span_exporter, log_exporte meta_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == inputTokens + outputTokens ) - assert meta_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert meta_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert ( - meta_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == system_prompt + meta_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == system_prompt ) - assert meta_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "user" + assert meta_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "user" assert meta_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.1.content" + f"{SpanAttributes.GEN_AI_PROMPT}.1.content" ] == json.dumps(messages[0]["content"]) assert ( - meta_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"] + meta_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"] == response_role ) assert ( - meta_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] == content + meta_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == content ) assert meta_span.attributes.get("gen_ai.response.id") is None diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_nova.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_nova.py index 54fcb3fbae..2241f43822 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_nova.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_nova.py @@ -43,39 +43,39 @@ def test_nova_completion(instrument_legacy, brt, span_exporter, log_exporter): bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on system prompt - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert bedrock_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.0.content" + f"{SpanAttributes.GEN_AI_PROMPT}.0.content" ] == system_list[0].get("text") # Assert on prompt - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "user" + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "user" assert bedrock_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.1.content" + f"{SpanAttributes.GEN_AI_PROMPT}.1.content" ] == json.dumps(message_list[0].get("content"), default=str) # Assert on response generated_text = response_body["output"]["message"]["content"] for i in range(0, len(generated_text)): assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.{i}.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.content"] == generated_text[i]["text"] ) # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 500 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.7 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.9 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 500 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.7 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.9 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -120,10 +120,10 @@ def test_nova_completion_with_events_with_content( bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" @@ -132,9 +132,9 @@ def test_nova_completion_with_events_with_content( generated_text = response_body["output"]["message"]["content"] # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 500 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.7 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.9 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 500 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.7 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.9 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -199,18 +199,18 @@ def test_nova_completion_with_events_with_no_content( bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 500 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.7 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.9 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 500 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.7 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.9 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -278,42 +278,42 @@ def test_nova_invoke_stream(instrument_legacy, brt, span_exporter, log_exporter) bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on system prompt - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert bedrock_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.0.content" + f"{SpanAttributes.GEN_AI_PROMPT}.0.content" ] == system_list[0].get("text") # Assert on prompt - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "user" + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "user" assert bedrock_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.1.content" + f"{SpanAttributes.GEN_AI_PROMPT}.1.content" ] == json.dumps(message_list[0].get("content"), default=str) # Assert on response completion_msg = "".join(generated_text) assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == completion_msg ) # Assert on other request parameters assert bedrock_span.attributes[ - SpanAttributes.LLM_REQUEST_MAX_TOKENS + SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS ] == inf_params.get("maxTokens") assert bedrock_span.attributes[ - SpanAttributes.LLM_REQUEST_TEMPERATURE + SpanAttributes.GEN_AI_REQUEST_TEMPERATURE ] == inf_params.get("temperature") - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == inf_params.get( + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == inf_params.get( "topP" ) # There is no response id for Amazon Titan models in the response body, @@ -371,10 +371,10 @@ def test_nova_invoke_stream_with_events_with_content( bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" @@ -384,12 +384,12 @@ def test_nova_invoke_stream_with_events_with_content( # Assert on other request parameters assert bedrock_span.attributes[ - SpanAttributes.LLM_REQUEST_MAX_TOKENS + SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS ] == inf_params.get("maxTokens") assert bedrock_span.attributes[ - SpanAttributes.LLM_REQUEST_TEMPERATURE + SpanAttributes.GEN_AI_REQUEST_TEMPERATURE ] == inf_params.get("temperature") - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == inf_params.get( + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == inf_params.get( "topP" ) # There is no response id for Amazon Titan models in the response body, @@ -469,22 +469,22 @@ def test_nova_invoke_stream_with_events_with_no_content( bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on other request parameters assert bedrock_span.attributes[ - SpanAttributes.LLM_REQUEST_MAX_TOKENS + SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS ] == inf_params.get("maxTokens") assert bedrock_span.attributes[ - SpanAttributes.LLM_REQUEST_TEMPERATURE + SpanAttributes.GEN_AI_REQUEST_TEMPERATURE ] == inf_params.get("temperature") - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == inf_params.get( + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == inf_params.get( "topP" ) # There is no response id for Amazon Titan models in the response body, @@ -565,37 +565,37 @@ def test_nova_converse(instrument_legacy, brt, span_exporter, log_exporter): bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" # Assert on system prompt - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == system[ + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == system[ 0 ].get("text") # Assert on prompt assert bedrock_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.1.content" + f"{SpanAttributes.GEN_AI_PROMPT}.1.content" ] == json.dumps(messages[0].get("content"), default=str) # Assert on response generated_text = response["output"]["message"]["content"] for i in range(0, len(generated_text)): assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.{i}.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.content"] == generated_text[i]["text"] ) # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 300 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.3 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.1 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 300 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.3 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.1 logs = log_exporter.get_finished_logs() assert ( @@ -659,18 +659,18 @@ def test_nova_converse_with_events_with_content( bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 300 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.3 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.1 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 300 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.3 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.1 logs = log_exporter.get_finished_logs() assert len(logs) == 3 @@ -755,18 +755,18 @@ def test_nova_converse_with_events_with_no_content( bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 300 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.3 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.1 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 300 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.3 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.1 logs = log_exporter.get_finished_logs() assert len(logs) == 3 @@ -863,39 +863,39 @@ def test_nova_converse_stream(instrument_legacy, brt, span_exporter, log_exporte bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" # Assert on system prompt - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == system[ + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == system[ 0 ].get("text") # Assert on prompt assert bedrock_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.1.content" + f"{SpanAttributes.GEN_AI_PROMPT}.1.content" ] == json.dumps(messages[0].get("content"), default=str) # Assert on response assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == content ) assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"] == response_role ) # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 300 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.3 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.1 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 300 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.3 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.1 # Assert on usage data assert ( @@ -989,18 +989,18 @@ def test_nova_converse_stream_with_events_with_content( bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 300 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.3 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.1 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 300 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.3 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.1 # Assert on usage data assert ( @@ -1114,18 +1114,18 @@ def test_nova_converse_stream_with_events_with_no_content( bedrock_span = spans[0] # Assert on model name - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 300 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.3 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.1 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 300 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.3 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.1 # Assert on usage data assert ( @@ -1191,34 +1191,34 @@ def test_nova_cross_region_invoke(instrument_legacy, brt, span_exporter, log_exp bedrock_span = spans[0] # Assert on model name and vendor - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on prompt - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "user" + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "user" assert bedrock_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.0.content" + f"{SpanAttributes.GEN_AI_PROMPT}.0.content" ] == json.dumps(message_list[0].get("content"), default=str) # Assert on response generated_text = response_body["output"]["message"]["content"] for i in range(0, len(generated_text)): assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.{i}.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.content"] == generated_text[i]["text"] ) # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 500 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.7 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.9 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 500 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.7 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.9 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -1262,19 +1262,19 @@ def test_nova_cross_region_invoke_with_events_with_content( bedrock_span = spans[0] # Assert on model name and vendor - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 500 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.7 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.9 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 500 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.7 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.9 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -1329,19 +1329,19 @@ def test_nova_cross_region_invoke_with_events_with_no_content( bedrock_span = spans[0] # Assert on model name and vendor - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "nova-lite-v1:0" - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "nova-lite-v1:0" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 500 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.7 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.9 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 500 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.7 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.9 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_titan.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_titan.py index 68dd1d3b0a..088e8fa790 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_titan.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_titan.py @@ -43,12 +43,12 @@ def test_titan_completion(instrument_legacy, brt, span_exporter, log_exporter): # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" @@ -59,21 +59,21 @@ def test_titan_completion(instrument_legacy, brt, span_exporter, log_exporter): "scale generative AI applications with base models (FMs)'." ) assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == expected_prompt ) # Assert on response generated_text = response_body["results"][0]["outputText"] assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == generated_text ) # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 200 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 200 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.5 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -118,20 +118,20 @@ def test_titan_completion_with_events_with_content( # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 200 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 200 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.5 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -190,20 +190,20 @@ def test_titan_completion_with_events_with_no_content( # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 200 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 200 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.5 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -266,12 +266,12 @@ def test_titan_invoke_stream(instrument_legacy, brt, span_exporter, log_exporter # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" @@ -282,21 +282,21 @@ def test_titan_invoke_stream(instrument_legacy, brt, span_exporter, log_exporter "scale generative AI applications with base models (FMs)'." ) assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == expected_prompt ) # Assert on response completion_text = "".join(generated_text) assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == completion_text ) # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 200 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 200 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.5 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -351,20 +351,20 @@ def test_titan_invoke_stream_with_events_with_content( # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 200 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 200 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.5 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -436,20 +436,20 @@ def test_titan_invoke_stream_with_events_with_no_content( # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" # Assert on other request parameters - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 200 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 - assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 200 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.5 # There is no response id for Amazon Titan models in the response body, # only request id in the response. assert bedrock_span.attributes.get("gen_ai.response.id") is None @@ -516,27 +516,27 @@ def test_titan_converse(instrument_legacy, brt, span_exporter, log_exporter): # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" # Assert on prompt - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "user" + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "user" assert bedrock_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.0.content" + f"{SpanAttributes.GEN_AI_PROMPT}.0.content" ] == json.dumps(messages[0].get("content"), default=str) # Assert on response generated_text = response["output"]["message"]["content"] for i in range(0, len(generated_text)): assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.{i}.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.{i}.content"] == generated_text[i]["text"] ) @@ -594,12 +594,12 @@ def test_titan_converse_with_events_with_content( # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" @@ -671,12 +671,12 @@ def test_titan_converse_with_events_with_no_content( # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" @@ -766,29 +766,29 @@ def test_titan_converse_stream(instrument_legacy, brt, span_exporter, log_export # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" # Assert on prompt - assert bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "user" + assert bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "user" assert bedrock_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.0.content" + f"{SpanAttributes.GEN_AI_PROMPT}.0.content" ] == json.dumps(messages[0].get("content"), default=str) # Assert on response assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == content ) assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"] == response_role ) @@ -878,12 +878,12 @@ def test_titan_converse_stream_with_events_with_content( # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" @@ -986,12 +986,12 @@ def test_titan_converse_stream_with_events_with_no_content( # Assert on model name assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "titan-text-express-v1" ) # Assert on vendor - assert bedrock_span.attributes[SpanAttributes.LLM_SYSTEM] == "AWS" + assert bedrock_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "AWS" # Assert on request type assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py index 5e43e1e43e..8bede4d48f 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py @@ -114,7 +114,7 @@ def _wrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Cohere", + SpanAttributes.GEN_AI_SYSTEM: "Cohere", SpanAttributes.LLM_REQUEST_TYPE: llm_request_type.value, }, ) as span: diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py index a1a2d2aa03..4861115446 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py @@ -26,32 +26,32 @@ def set_input_attributes(span, llm_request_type, kwargs): if should_send_prompts(): if llm_request_type == LLMRequestTypeValues.COMPLETION: - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user") _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.content", kwargs.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.content", kwargs.get("prompt") ) elif llm_request_type == LLMRequestTypeValues.CHAT: - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user") _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.content", kwargs.get("message") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.content", kwargs.get("message") ) elif llm_request_type == LLMRequestTypeValues.RERANK: for index, document in enumerate(kwargs.get("documents")): _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{index}.role", "system" + span, f"{SpanAttributes.GEN_AI_PROMPT}.{index}.role", "system" ) _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{index}.content", document + span, f"{SpanAttributes.GEN_AI_PROMPT}.{index}.content", document ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{len(kwargs.get('documents'))}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{len(kwargs.get('documents'))}.role", "user", ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{len(kwargs.get('documents'))}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{len(kwargs.get('documents'))}.content", kwargs.get("query"), ) @@ -75,14 +75,14 @@ def set_span_request_attributes(span, kwargs): if not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("model")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, kwargs.get("model")) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, kwargs.get("max_tokens_to_sample") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get("max_tokens_to_sample") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, kwargs.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, kwargs.get("temperature") ) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, kwargs.get("top_p")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, kwargs.get("top_p")) _set_span_attribute( span, SpanAttributes.LLM_FREQUENCY_PENALTY, kwargs.get("frequency_penalty") ) @@ -93,7 +93,7 @@ def set_span_request_attributes(span, kwargs): def _set_span_chat_response(span, response): index = 0 - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" _set_span_attribute(span, f"{prefix}.content", response.text) _set_span_attribute(span, GEN_AI_RESPONSE_ID, response.response_id) @@ -145,7 +145,7 @@ def _set_span_generations_response(span, response): generations = response # Cohere v4 for index, generation in enumerate(generations): - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" _set_span_attribute(span, f"{prefix}.content", generation.text) _set_span_attribute(span, f"gen_ai.response.{index}.id", generation.id) @@ -153,7 +153,7 @@ def _set_span_generations_response(span, response): def _set_span_rerank_response(span, response): _set_span_attribute(span, GEN_AI_RESPONSE_ID, response.id) for idx, doc in enumerate(response.results): - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{idx}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}" _set_span_attribute(span, f"{prefix}.role", "assistant") content = f"Doc {doc.index}, Score: {doc.relevance_score}" if doc.document: diff --git a/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py b/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py index fd97cf45ce..c6a8ea9fd5 100644 --- a/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py +++ b/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py @@ -18,15 +18,15 @@ def test_cohere_chat_legacy( spans = span_exporter.get_finished_spans() cohere_span = spans[0] assert cohere_span.name == "cohere.chat" - assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Cohere" assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" - assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_REQUEST_MODEL) == "command" assert ( - cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + cohere_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke, pirate style" ) assert ( - cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + cohere_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == res.text ) assert cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 58 @@ -56,9 +56,9 @@ def test_cohere_chat_with_events_with_content( spans = span_exporter.get_finished_spans() cohere_span = spans[0] assert cohere_span.name == "cohere.chat" - assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Cohere" assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" - assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_REQUEST_MODEL) == "command" logs = log_exporter.get_finished_logs() assert len(logs) == 2 @@ -85,9 +85,9 @@ def test_cohere_chat_with_events_with_no_content( spans = span_exporter.get_finished_spans() cohere_span = spans[0] assert cohere_span.name == "cohere.chat" - assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Cohere" assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" - assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_REQUEST_MODEL) == "command" logs = log_exporter.get_finished_logs() assert len(logs) == 2 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/test_completion.py b/packages/opentelemetry-instrumentation-cohere/tests/test_completion.py index 622ec31b23..d8731593e1 100644 --- a/packages/opentelemetry-instrumentation-cohere/tests/test_completion.py +++ b/packages/opentelemetry-instrumentation-cohere/tests/test_completion.py @@ -18,11 +18,11 @@ def test_cohere_completion_legacy( spans = span_exporter.get_finished_spans() cohere_span = spans[0] assert cohere_span.name == "cohere.completion" - assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Cohere" assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "completion" - assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_REQUEST_MODEL) == "command" assert ( - cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + cohere_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == res.generations[0].text ) assert ( @@ -50,9 +50,9 @@ def test_cohere_completion_with_events_with_content( spans = span_exporter.get_finished_spans() cohere_span = spans[0] assert cohere_span.name == "cohere.completion" - assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Cohere" assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "completion" - assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_REQUEST_MODEL) == "command" logs = log_exporter.get_finished_logs() assert len(logs) == 2 @@ -78,9 +78,9 @@ def test_cohere_completion_with_events_with_no_content( spans = span_exporter.get_finished_spans() cohere_span = spans[0] assert cohere_span.name == "cohere.completion" - assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Cohere" assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "completion" - assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_REQUEST_MODEL) == "command" logs = log_exporter.get_finished_logs() assert len(logs) == 2 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/test_rerank.py b/packages/opentelemetry-instrumentation-cohere/tests/test_rerank.py index 3da05d7417..61f3a7b0f4 100644 --- a/packages/opentelemetry-instrumentation-cohere/tests/test_rerank.py +++ b/packages/opentelemetry-instrumentation-cohere/tests/test_rerank.py @@ -38,43 +38,43 @@ def test_cohere_rerank_legacy( spans = span_exporter.get_finished_spans() cohere_span = spans[0] assert cohere_span.name == "cohere.rerank" - assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Cohere" assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "rerank" assert ( - cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) + cohere_span.attributes.get(SpanAttributes.GEN_AI_REQUEST_MODEL) == "rerank-multilingual-v2.0" ) assert ( cohere_span.attributes.get( - f"{SpanAttributes.LLM_PROMPTS}.{len(documents)}.role" + f"{SpanAttributes.GEN_AI_PROMPT}.{len(documents)}.role" ) == "user" ) assert ( cohere_span.attributes.get( - f"{SpanAttributes.LLM_PROMPTS}.{len(documents)}.content" + f"{SpanAttributes.GEN_AI_PROMPT}.{len(documents)}.content" ) == query ) for i, doc in enumerate(documents): assert ( - cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.{i}.role") + cohere_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.{i}.role") == "system" ) assert ( - cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.{i}.content") + cohere_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.{i}.content") == doc ) for idx, result in enumerate(response.results): assert ( - cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.role") + cohere_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}.role") == "assistant" ) assert ( cohere_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}.content" ) == f"Doc {result.index}, Score: {result.relevance_score}" ) @@ -118,10 +118,10 @@ def test_cohere_rerank_with_events_with_content( spans = span_exporter.get_finished_spans() cohere_span = spans[0] assert cohere_span.name == "cohere.rerank" - assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Cohere" assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "rerank" assert ( - cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) + cohere_span.attributes.get(SpanAttributes.GEN_AI_REQUEST_MODEL) == "rerank-multilingual-v2.0" ) @@ -182,10 +182,10 @@ def test_cohere_rerank_with_events_with_no_content( spans = span_exporter.get_finished_spans() cohere_span = spans[0] assert cohere_span.name == "cohere.rerank" - assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Cohere" assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "rerank" assert ( - cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) + cohere_span.attributes.get(SpanAttributes.GEN_AI_REQUEST_MODEL) == "rerank-multilingual-v2.0" ) diff --git a/packages/opentelemetry-instrumentation-crewai/opentelemetry/instrumentation/crewai/instrumentation.py b/packages/opentelemetry-instrumentation-crewai/opentelemetry/instrumentation/crewai/instrumentation.py index b5404144ce..b483b03e40 100644 --- a/packages/opentelemetry-instrumentation-crewai/opentelemetry/instrumentation/crewai/instrumentation.py +++ b/packages/opentelemetry-instrumentation-crewai/opentelemetry/instrumentation/crewai/instrumentation.py @@ -71,7 +71,7 @@ def wrap_kickoff(tracer: Tracer, duration_histogram: Histogram, token_histogram: "crewai.workflow", kind=SpanKind.INTERNAL, attributes={ - SpanAttributes.LLM_SYSTEM: "crewai", + SpanAttributes.GEN_AI_SYSTEM: "crewai", } ) as span: try: @@ -108,22 +108,22 @@ def wrap_agent_execute_task(tracer, duration_histogram, token_histogram, wrapped token_histogram.record( instance._token_process.get_summary().prompt_tokens, attributes={ - SpanAttributes.LLM_SYSTEM: "crewai", - SpanAttributes.LLM_TOKEN_TYPE: "input", - SpanAttributes.LLM_RESPONSE_MODEL: str(instance.llm.model), + SpanAttributes.GEN_AI_SYSTEM: "crewai", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_RESPONSE_MODEL: str(instance.llm.model), } ) token_histogram.record( instance._token_process.get_summary().completion_tokens, attributes={ - SpanAttributes.LLM_SYSTEM: "crewai", - SpanAttributes.LLM_TOKEN_TYPE: "output", - SpanAttributes.LLM_RESPONSE_MODEL: str(instance.llm.model), + SpanAttributes.GEN_AI_SYSTEM: "crewai", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_RESPONSE_MODEL: str(instance.llm.model), }, ) - set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, str(instance.llm.model)) - set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, str(instance.llm.model)) + set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, str(instance.llm.model)) + set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, str(instance.llm.model)) span.set_status(Status(StatusCode.OK)) return result except Exception as ex: @@ -172,8 +172,8 @@ def wrap_llm_call(tracer, duration_histogram, token_histogram, wrapped, instance duration_histogram.record( duration, attributes={ - SpanAttributes.LLM_SYSTEM: "crewai", - SpanAttributes.LLM_RESPONSE_MODEL: str(instance.model) + SpanAttributes.GEN_AI_SYSTEM: "crewai", + SpanAttributes.GEN_AI_RESPONSE_MODEL: str(instance.model) }, ) diff --git a/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/__init__.py b/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/__init__.py index c2424d10c1..c2b03fa5d6 100644 --- a/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/__init__.py +++ b/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/__init__.py @@ -194,7 +194,7 @@ async def _awrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Google", + SpanAttributes.GEN_AI_SYSTEM: "Google", SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value, }, ) @@ -252,7 +252,7 @@ def _wrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Google", + SpanAttributes.GEN_AI_SYSTEM: "Google", SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value, }, ) diff --git a/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/span_utils.py b/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/span_utils.py index 9879ed5136..2ae944fa9e 100644 --- a/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/span_utils.py +++ b/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/span_utils.py @@ -28,12 +28,12 @@ def set_input_attributes(span, args, kwargs, llm_model): if isinstance(contents, str): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.content", + f"{SpanAttributes.GEN_AI_PROMPT}.0.content", contents, ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.role", + f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user", ) elif isinstance(contents, list): @@ -43,12 +43,12 @@ def set_input_attributes(span, args, kwargs, llm_model): if hasattr(part, "text"): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.content", part.text, ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.role", getattr(content, "role", "user"), ) elif args and len(args) > 0: @@ -62,32 +62,32 @@ def set_input_attributes(span, args, kwargs, llm_model): if prompt: _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.content", + f"{SpanAttributes.GEN_AI_PROMPT}.0.content", prompt, ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.role", + f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user", ) elif "prompt" in kwargs: _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.content", kwargs["prompt"] + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.content", kwargs["prompt"] ) - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user") def set_model_request_attributes(span, kwargs, llm_model): if not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, llm_model) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, llm_model) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, kwargs.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, kwargs.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, kwargs.get("max_output_tokens") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get("max_output_tokens") ) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, kwargs.get("top_p")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, kwargs.get("top_p")) _set_span_attribute(span, SpanAttributes.LLM_TOP_K, kwargs.get("top_k")) _set_span_attribute( span, SpanAttributes.LLM_PRESENCE_PENALTY, kwargs.get("presence_penalty") @@ -104,28 +104,28 @@ def set_response_attributes(span, response, llm_model): if hasattr(response, "usage_metadata"): if isinstance(response.text, list): for index, item in enumerate(response): - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" _set_span_attribute(span, f"{prefix}.content", item.text) _set_span_attribute(span, f"{prefix}.role", "assistant") elif isinstance(response.text, str): _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.content", response.text + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response.text ) _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.role", "assistant" + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", "assistant" ) else: if isinstance(response, list): for index, item in enumerate(response): - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" _set_span_attribute(span, f"{prefix}.content", item) _set_span_attribute(span, f"{prefix}.role", "assistant") elif isinstance(response, str): _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.content", response + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response ) _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.role", "assistant" + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", "assistant" ) @@ -133,7 +133,7 @@ def set_model_response_attributes(span, response, llm_model): if not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, llm_model) + _set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, llm_model) if hasattr(response, "usage_metadata"): _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-google-generativeai/tests/test_generate_content.py b/packages/opentelemetry-instrumentation-google-generativeai/tests/test_generate_content.py index 11a9787e60..153c5e86c6 100644 --- a/packages/opentelemetry-instrumentation-google-generativeai/tests/test_generate_content.py +++ b/packages/opentelemetry-instrumentation-google-generativeai/tests/test_generate_content.py @@ -24,16 +24,16 @@ def test_gemini_generate_content_legacy( # gemini_span = spans[0] # assert ( - # gemini_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + # gemini_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] # == "The opposite of hot is\n" # ) - # assert gemini_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "user" + # assert gemini_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "user" # assert ( - # gemini_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + # gemini_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") # == "cold\n" # ) # assert ( - # gemini_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") + # gemini_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.role") # == "assistant" # ) @@ -45,11 +45,11 @@ def test_gemini_generate_content_legacy( # ) # assert ( - # gemini_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + # gemini_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] # == "models/gemini-1.5-flash" # ) # assert ( - # gemini_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + # gemini_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] # == "models/gemini-1.5-flash" # ) @@ -83,11 +83,11 @@ def test_gemini_generate_content_with_events_with_content( # ) # assert ( - # gemini_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + # gemini_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] # == "models/gemini-1.5-flash" # ) # assert ( - # gemini_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + # gemini_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] # == "models/gemini-1.5-flash" # ) @@ -131,11 +131,11 @@ def test_gemini_generate_content_with_events_with_no_content( # ) # assert ( - # gemini_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + # gemini_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] # == "models/gemini-1.5-flash" # ) # assert ( - # gemini_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + # gemini_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] # == "models/gemini-1.5-flash" # ) diff --git a/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/__init__.py b/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/__init__.py index 810e9ebd27..ab43a1d9b9 100644 --- a/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/__init__.py +++ b/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/__init__.py @@ -242,7 +242,7 @@ def _wrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Groq", + SpanAttributes.GEN_AI_SYSTEM: "Groq", SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value, }, ) @@ -324,7 +324,7 @@ async def _awrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Groq", + SpanAttributes.GEN_AI_SYSTEM: "Groq", SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value, }, ) diff --git a/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/span_utils.py b/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/span_utils.py index 8af6035d3b..b37df8d38e 100644 --- a/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/span_utils.py +++ b/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/span_utils.py @@ -24,18 +24,18 @@ def set_input_attributes(span, kwargs): if should_send_prompts(): if kwargs.get("prompt") is not None: set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.user", kwargs.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.user", kwargs.get("prompt") ) elif kwargs.get("messages") is not None: for i, message in enumerate(kwargs.get("messages")): set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.content", _dump_content(message.get("content")), ) set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{i}.role", message.get("role") + span, f"{SpanAttributes.GEN_AI_PROMPT}.{i}.role", message.get("role") ) @@ -44,14 +44,14 @@ def set_model_input_attributes(span, kwargs): if not span.is_recording(): return - set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("model")) + set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, kwargs.get("model")) set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, kwargs.get("max_tokens_to_sample") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get("max_tokens_to_sample") ) set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, kwargs.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, kwargs.get("temperature") ) - set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, kwargs.get("top_p")) + set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, kwargs.get("top_p")) set_span_attribute( span, SpanAttributes.LLM_FREQUENCY_PENALTY, kwargs.get("frequency_penalty") ) @@ -70,7 +70,7 @@ def set_streaming_response_attributes( if not span.is_recording() or not should_send_prompts(): return - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.0" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.0" set_span_attribute(span, f"{prefix}.role", "assistant") set_span_attribute(span, f"{prefix}.content", accumulated_content) if finish_reason: @@ -98,7 +98,7 @@ def set_model_response_attributes(span, response, token_histogram): if not span.is_recording(): return response = model_as_dict(response) - set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, response.get("model")) + set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, response.get("model")) set_span_attribute(span, GEN_AI_RESPONSE_ID, response.get("id")) usage = response.get("usage") or {} @@ -121,8 +121,8 @@ def set_model_response_attributes(span, response, token_histogram): token_histogram.record( prompt_tokens, attributes={ - SpanAttributes.LLM_TOKEN_TYPE: "input", - SpanAttributes.LLM_RESPONSE_MODEL: response.get("model"), + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_RESPONSE_MODEL: response.get("model"), }, ) @@ -134,8 +134,8 @@ def set_model_response_attributes(span, response, token_histogram): token_histogram.record( completion_tokens, attributes={ - SpanAttributes.LLM_TOKEN_TYPE: "output", - SpanAttributes.LLM_RESPONSE_MODEL: response.get("model"), + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_RESPONSE_MODEL: response.get("model"), }, ) @@ -154,7 +154,7 @@ def _set_completions(span, choices): for choice in choices: index = choice.get("index") - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" set_span_attribute(span, f"{prefix}.finish_reason", choice.get("finish_reason")) if choice.get("content_filter_results"): diff --git a/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/utils.py b/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/utils.py index 21e65329e2..89b767f29a 100644 --- a/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/utils.py +++ b/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/utils.py @@ -60,7 +60,7 @@ def shared_metrics_attributes(response): return { **common_attributes, GEN_AI_SYSTEM: GEN_AI_SYSTEM_GROQ, - SpanAttributes.LLM_RESPONSE_MODEL: response_dict.get("model"), + SpanAttributes.GEN_AI_RESPONSE_MODEL: response_dict.get("model"), } diff --git a/packages/opentelemetry-instrumentation-groq/tests/traces/test_chat_tracing.py b/packages/opentelemetry-instrumentation-groq/tests/traces/test_chat_tracing.py index e1df364142..4414d4beb3 100644 --- a/packages/opentelemetry-instrumentation-groq/tests/traces/test_chat_tracing.py +++ b/packages/opentelemetry-instrumentation-groq/tests/traces/test_chat_tracing.py @@ -23,10 +23,10 @@ def test_chat_legacy(instrument_legacy, groq_client, span_exporter, log_exporter ] groq_span = spans[0] assert ( - groq_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + groq_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) - assert groq_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert groq_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) > 0 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) > 0 @@ -146,10 +146,10 @@ async def test_async_chat_legacy( ] groq_span = spans[0] assert ( - groq_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + groq_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) - assert groq_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert groq_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) > 0 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) > 0 @@ -277,11 +277,11 @@ def test_chat_streaming_legacy( ] groq_span = spans[0] assert ( - groq_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + groq_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) assert ( - groq_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + groq_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == content ) assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is True diff --git a/packages/opentelemetry-instrumentation-haystack/opentelemetry/instrumentation/haystack/wrap_openai.py b/packages/opentelemetry-instrumentation-haystack/opentelemetry/instrumentation/haystack/wrap_openai.py index 7c5b93708f..6c4ef17bad 100644 --- a/packages/opentelemetry-instrumentation-haystack/opentelemetry/instrumentation/haystack/wrap_openai.py +++ b/packages/opentelemetry-instrumentation-haystack/opentelemetry/instrumentation/haystack/wrap_openai.py @@ -20,12 +20,12 @@ def _set_input_attributes(span, llm_request_type, kwargs): if llm_request_type == LLMRequestTypeValues.COMPLETION: set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.user", kwargs.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.user", kwargs.get("prompt") ) elif llm_request_type == LLMRequestTypeValues.CHAT: set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.user", + f"{SpanAttributes.GEN_AI_PROMPT}.0.user", [message.content for message in kwargs.get("messages")], ) @@ -33,17 +33,17 @@ def _set_input_attributes(span, llm_request_type, kwargs): generation_kwargs = kwargs["generation_kwargs"] if "model" in generation_kwargs: set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MODEL, generation_kwargs["model"] + span, SpanAttributes.GEN_AI_REQUEST_MODEL, generation_kwargs["model"] ) if "temperature" in generation_kwargs: set_span_attribute( span, - SpanAttributes.LLM_REQUEST_TEMPERATURE, + SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, generation_kwargs["temperature"], ) if "top_p" in generation_kwargs: set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TOP_P, generation_kwargs["top_p"] + span, SpanAttributes.GEN_AI_REQUEST_TOP_P, generation_kwargs["top_p"] ) if "frequency_penalty" in generation_kwargs: set_span_attribute( @@ -66,7 +66,7 @@ def _set_span_completions(span, llm_request_type, choices): return for index, message in enumerate(choices): - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" if llm_request_type == LLMRequestTypeValues.CHAT: if message is not None: @@ -104,7 +104,7 @@ def wrap(tracer, to_wrap, wrapped, instance, args, kwargs): ), kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "OpenAI", + SpanAttributes.GEN_AI_SYSTEM: "OpenAI", SpanAttributes.LLM_REQUEST_TYPE: llm_request_type.value, }, ) as span: diff --git a/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py b/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py index 03c4475d88..8eeb5e0e6f 100644 --- a/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py +++ b/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py @@ -270,7 +270,7 @@ def _create_llm_span( entity_path=entity_path, metadata=metadata, ) - _set_span_attribute(span, SpanAttributes.LLM_SYSTEM, "Langchain") + _set_span_attribute(span, SpanAttributes.GEN_AI_SYSTEM, "Langchain") _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TYPE, request_type.value) return span @@ -437,11 +437,11 @@ def on_llm_end( "model_name" ) or response.llm_output.get("model_id") if model_name is not None: - _set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, model_name) + _set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, model_name) if self.spans[run_id].request_model is None: _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MODEL, model_name + span, SpanAttributes.GEN_AI_REQUEST_MODEL, model_name ) id = response.llm_output.get("id") if id is not None and id != "": @@ -480,9 +480,9 @@ def on_llm_end( self.token_histogram.record( prompt_tokens, attributes={ - SpanAttributes.LLM_SYSTEM: "Langchain", - SpanAttributes.LLM_TOKEN_TYPE: "input", - SpanAttributes.LLM_RESPONSE_MODEL: model_name or "unknown", + SpanAttributes.GEN_AI_SYSTEM: "Langchain", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_RESPONSE_MODEL: model_name or "unknown", }, ) @@ -490,9 +490,9 @@ def on_llm_end( self.token_histogram.record( completion_tokens, attributes={ - SpanAttributes.LLM_SYSTEM: "Langchain", - SpanAttributes.LLM_TOKEN_TYPE: "output", - SpanAttributes.LLM_RESPONSE_MODEL: model_name or "unknown", + SpanAttributes.GEN_AI_SYSTEM: "Langchain", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_RESPONSE_MODEL: model_name or "unknown", }, ) set_chat_response_usage(span, response) @@ -507,8 +507,8 @@ def on_llm_end( self.duration_histogram.record( duration, attributes={ - SpanAttributes.LLM_SYSTEM: "Langchain", - SpanAttributes.LLM_RESPONSE_MODEL: model_name or "unknown", + SpanAttributes.GEN_AI_SYSTEM: "Langchain", + SpanAttributes.GEN_AI_RESPONSE_MODEL: model_name or "unknown", }, ) diff --git a/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/span_utils.py b/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/span_utils.py index 6c4725074c..b747a23ae7 100644 --- a/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/span_utils.py +++ b/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/span_utils.py @@ -69,9 +69,9 @@ def set_request_params(span, kwargs, span_holder: SpanHolder): else: model = "unknown" - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, model) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, model) # response is not available for LLM requests (as opposed to chat) - _set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, model) + _set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, model) if "invocation_params" in kwargs: params = ( @@ -82,13 +82,13 @@ def set_request_params(span, kwargs, span_holder: SpanHolder): _set_span_attribute( span, - SpanAttributes.LLM_REQUEST_MAX_TOKENS, + SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, params.get("max_tokens") or params.get("max_new_tokens"), ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, params.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, params.get("temperature") ) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, params.get("top_p")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, params.get("top_p")) tools = kwargs.get("invocation_params", {}).get("tools", []) for i, tool in enumerate(tools): @@ -123,12 +123,12 @@ def set_llm_request( for i, msg in enumerate(prompts): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.role", "user", ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.content", msg, ) @@ -161,7 +161,7 @@ def set_chat_request( for msg in message: _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.role", _message_type_to_role(msg.type), ) tool_calls = ( @@ -172,7 +172,7 @@ def set_chat_request( if tool_calls: _set_chat_tool_calls( - span, f"{SpanAttributes.LLM_PROMPTS}.{i}", tool_calls + span, f"{SpanAttributes.GEN_AI_PROMPT}.{i}", tool_calls ) else: @@ -183,14 +183,14 @@ def set_chat_request( ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.content", content, ) if msg.type == "tool" and hasattr(msg, "tool_call_id"): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.tool_call_id", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.tool_call_id", msg.tool_call_id, ) @@ -204,7 +204,7 @@ def set_chat_response(span: Span, response: LLMResult) -> None: i = 0 for generations in response.generations: for generation in generations: - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{i}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{i}" if hasattr(generation, "text") and generation.text != "": _set_span_attribute( span, diff --git a/packages/opentelemetry-instrumentation-langchain/tests/metrics/test_langchain_metrics.py b/packages/opentelemetry-instrumentation-langchain/tests/metrics/test_langchain_metrics.py index 6c7583b645..f2c9c5828c 100644 --- a/packages/opentelemetry-instrumentation-langchain/tests/metrics/test_langchain_metrics.py +++ b/packages/opentelemetry-instrumentation-langchain/tests/metrics/test_langchain_metrics.py @@ -36,13 +36,13 @@ def test_llm_chain_metrics(instrument_legacy, reader, chain): if metric.name == Meters.LLM_TOKEN_USAGE: found_token_metric = True for data_point in metric.data.data_points: - assert data_point.attributes[SpanAttributes.LLM_TOKEN_TYPE] in [ + assert data_point.attributes[SpanAttributes.GEN_AI_TOKEN_TYPE] in [ "output", "input", ] assert data_point.sum > 0 assert ( - data_point.attributes[SpanAttributes.LLM_SYSTEM] + data_point.attributes[SpanAttributes.GEN_AI_SYSTEM] == "Langchain" ) @@ -56,7 +56,7 @@ def test_llm_chain_metrics(instrument_legacy, reader, chain): ) for data_point in metric.data.data_points: assert ( - data_point.attributes[SpanAttributes.LLM_SYSTEM] + data_point.attributes[SpanAttributes.GEN_AI_SYSTEM] == "Langchain" ) @@ -88,13 +88,13 @@ def test_llm_chain_streaming_metrics(instrument_legacy, reader, llm): if metric.name == Meters.LLM_TOKEN_USAGE: found_token_metric = True for data_point in metric.data.data_points: - assert data_point.attributes[SpanAttributes.LLM_TOKEN_TYPE] in [ + assert data_point.attributes[SpanAttributes.GEN_AI_TOKEN_TYPE] in [ "output", "input", ] assert data_point.sum > 0 assert ( - data_point.attributes[SpanAttributes.LLM_SYSTEM] + data_point.attributes[SpanAttributes.GEN_AI_SYSTEM] == "Langchain" ) @@ -108,7 +108,7 @@ def test_llm_chain_streaming_metrics(instrument_legacy, reader, llm): ) for data_point in metric.data.data_points: assert ( - data_point.attributes[SpanAttributes.LLM_SYSTEM] + data_point.attributes[SpanAttributes.GEN_AI_SYSTEM] == "Langchain" ) diff --git a/packages/opentelemetry-instrumentation-langchain/tests/test_chains.py b/packages/opentelemetry-instrumentation-langchain/tests/test_chains.py index 36c5e2a46e..f896d0467d 100644 --- a/packages/opentelemetry-instrumentation-langchain/tests/test_chains.py +++ b/packages/opentelemetry-instrumentation-langchain/tests/test_chains.py @@ -123,14 +123,14 @@ def test_sequential_chain(instrument_legacy, span_exporter, log_exporter): openai_span = next(span for span in spans if span.name == "OpenAI.completion") assert ( - openai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo-instruct" ) assert ( - (openai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL]) + (openai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL]) == "gpt-3.5-turbo-instruct" ) - assert openai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + assert openai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] logs = log_exporter.get_finished_logs() assert ( @@ -213,11 +213,11 @@ def test_sequential_chain_with_events_with_content( openai_span = next(span for span in spans if span.name == "OpenAI.completion") assert ( - openai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo-instruct" ) assert ( - (openai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL]) + (openai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL]) == "gpt-3.5-turbo-instruct" ) @@ -334,11 +334,11 @@ def test_sequential_chain_with_events_with_no_content( openai_span = next(span for span in spans if span.name == "OpenAI.completion") assert ( - openai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo-instruct" ) assert ( - (openai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL]) + (openai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL]) == "gpt-3.5-turbo-instruct" ) diff --git a/packages/opentelemetry-instrumentation-langchain/tests/test_llms.py b/packages/opentelemetry-instrumentation-langchain/tests/test_llms.py index b54255d0f8..ed9c1053cd 100644 --- a/packages/opentelemetry-instrumentation-langchain/tests/test_llms.py +++ b/packages/opentelemetry-instrumentation-langchain/tests/test_llms.py @@ -142,13 +142,13 @@ def test_custom_llm(instrument_legacy, span_exporter, log_exporter): ) assert hugging_face_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" - assert hugging_face_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "unknown" + assert hugging_face_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "unknown" assert ( - hugging_face_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + hugging_face_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "System: You are a helpful assistant\nHuman: tell me a short joke" ) assert ( - hugging_face_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + hugging_face_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response ) @@ -185,7 +185,7 @@ def test_custom_llm_with_events_with_content( ) assert hugging_face_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" - assert hugging_face_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "unknown" + assert hugging_face_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "unknown" logs = log_exporter.get_finished_logs() assert len(logs) == 2 @@ -235,7 +235,7 @@ def test_custom_llm_with_events_with_no_content( ) assert hugging_face_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "completion" - assert hugging_face_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "unknown" + assert hugging_face_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "unknown" logs = log_exporter.get_finished_logs() assert len(logs) == 2 @@ -275,20 +275,20 @@ def test_openai(instrument_legacy, span_exporter, log_exporter): openai_span = next(span for span in spans if span.name == "ChatOpenAI.chat") assert openai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" - assert openai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-4o-mini" + assert openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4o-mini" assert ( - (openai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"]) + (openai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"]) == "You are a helpful assistant" ) - assert (openai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"]) == "system" - assert (openai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"]) == prompt - assert (openai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"]) == "user" + assert (openai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"]) == "system" + assert (openai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"]) == prompt + assert (openai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"]) == "user" assert ( - openai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + openai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response.content ) assert ( - (openai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"]) + (openai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"]) == "assistant" ) @@ -330,7 +330,7 @@ def test_openai_with_events_with_content( openai_span = next(span for span in spans if span.name == "ChatOpenAI.chat") assert openai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" - assert openai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-4o-mini" + assert openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4o-mini" assert openai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1497 assert openai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 1037 @@ -384,7 +384,7 @@ def test_openai_with_events_with_no_content( openai_span = next(span for span in spans if span.name == "ChatOpenAI.chat") assert openai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" - assert openai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-4o-mini" + assert openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4o-mini" assert openai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1497 assert openai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 1037 @@ -444,17 +444,17 @@ class Joke(BaseModel): openai_span = next(span for span in spans if span.name == "ChatOpenAI.chat") assert openai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" - assert openai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert ( - (openai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"]) + (openai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"]) == "You are helpful assistant" ) - assert (openai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"]) == "system" + assert (openai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"]) == "system" assert ( - (openai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"]) + (openai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"]) == "tell me a short joke" ) - assert (openai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"]) == "user" + assert (openai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"]) == "user" assert ( openai_span.attributes[f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.name"] == "Joke" @@ -481,13 +481,13 @@ class Joke(BaseModel): "required": ["setup", "punchline"], } assert ( - openai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name"] + openai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name"] == "Joke" ) assert ( json.loads( openai_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.arguments" ] ) == response @@ -537,7 +537,7 @@ class Joke(BaseModel): openai_span = next(span for span in spans if span.name == "ChatOpenAI.chat") assert openai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" - assert openai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert openai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 76 assert openai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 35 @@ -610,7 +610,7 @@ class Joke(BaseModel): openai_span = next(span for span in spans if span.name == "ChatOpenAI.chat") assert openai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" - assert openai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert openai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 76 assert openai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 35 @@ -659,26 +659,26 @@ def test_anthropic(instrument_legacy, span_exporter, log_exporter): ) assert anthropic_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" - assert anthropic_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "claude-2.1" - assert anthropic_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 + assert anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "claude-2.1" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 assert ( - (anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"]) + (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"]) == "You are a helpful assistant" ) assert ( - (anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"]) == "system" + (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"]) == "system" ) assert ( - (anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"]) + (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"]) == "tell me a short joke" ) - assert (anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"]) == "user" + assert (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"]) == "user" assert ( - anthropic_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + anthropic_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response.content ) assert ( - (anthropic_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"]) + (anthropic_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"]) == "assistant" ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 19 @@ -748,8 +748,8 @@ def test_anthropic_with_events_with_content( anthropic_span = next(span for span in spans if span.name == "ChatAnthropic.chat") assert anthropic_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" - assert anthropic_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "claude-2.1" - assert anthropic_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 + assert anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "claude-2.1" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 19 assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 22 @@ -804,8 +804,8 @@ def test_anthropic_with_events_with_no_content( anthropic_span = next(span for span in spans if span.name == "ChatAnthropic.chat") assert anthropic_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" - assert anthropic_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "claude-2.1" - assert anthropic_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.5 + assert anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "claude-2.1" + assert anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 19 assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 22 @@ -867,25 +867,25 @@ def test_bedrock(instrument_legacy, span_exporter, log_exporter): assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "anthropic.claude-3-haiku-20240307-v1:0" ) assert ( - (bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"]) + (bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"]) == "You are a helpful assistant" ) - assert (bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"]) == "system" + assert (bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"]) == "system" assert ( - (bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"]) + (bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"]) == "tell me a short joke" ) - assert (bedrock_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"]) == "user" + assert (bedrock_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"]) == "user" assert ( - bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response.content ) assert ( - (bedrock_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"]) + (bedrock_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"]) == "assistant" ) assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 16 @@ -956,7 +956,7 @@ def test_bedrock_with_events_with_content( assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "anthropic.claude-3-haiku-20240307-v1:0" ) @@ -1019,7 +1019,7 @@ def test_bedrock_with_events_with_no_content( assert bedrock_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - bedrock_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + bedrock_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "anthropic.claude-3-haiku-20240307-v1:0" ) assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 16 diff --git a/packages/opentelemetry-instrumentation-langchain/tests/test_structured_output.py b/packages/opentelemetry-instrumentation-langchain/tests/test_structured_output.py index f9da2bcd00..255f756b21 100644 --- a/packages/opentelemetry-instrumentation-langchain/tests/test_structured_output.py +++ b/packages/opentelemetry-instrumentation-langchain/tests/test_structured_output.py @@ -36,9 +36,9 @@ def test_structured_output(instrument_legacy, span_exporter, log_exporter): chat_span = next(span for span in spans if span.name == "ChatOpenAI.chat") - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == query_text + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == query_text assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == result.model_dump_json() ) diff --git a/packages/opentelemetry-instrumentation-langchain/tests/test_tool_calls.py b/packages/opentelemetry-instrumentation-langchain/tests/test_tool_calls.py index e26277a6df..3a0fb74295 100644 --- a/packages/opentelemetry-instrumentation-langchain/tests/test_tool_calls.py +++ b/packages/opentelemetry-instrumentation-langchain/tests/test_tool_calls.py @@ -56,14 +56,14 @@ def test_tool_calls(instrument_legacy, span_exporter, log_exporter): "type": "object", } - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == query_text + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == query_text assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name"] == "food_analysis" ) arguments = chat_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.arguments" ] assert json.loads(arguments) == json.loads( result.model_dump() @@ -211,55 +211,55 @@ def get_weather(location: str) -> str: } assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == messages[0].content ) - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == messages[1].content ) - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "user" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "user" assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.tool_calls.0.name"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.tool_calls.0.name"] == messages[2].tool_calls[0]["name"] ) assert ( json.loads( chat_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.2.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_PROMPT}.2.tool_calls.0.arguments" ] ) == messages[2].tool_calls[0]["args"] ) assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.tool_calls.0.id"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.tool_calls.0.id"] == messages[2].tool_calls[0]["id"] ) - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.role"] == "assistant" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.role"] == "assistant" assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.3.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.3.content"] == messages[3].content ) - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.3.role"] == "tool" - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.3.tool_call_id"] == messages[3].tool_call_id + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.3.role"] == "tool" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.3.tool_call_id"] == messages[3].tool_call_id assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.4.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.4.content"] == messages[4].content ) - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.4.role"] == "user" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.4.role"] == "user" assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name"] == "get_weather" ) arguments = chat_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.arguments" ] result_arguments = result.model_dump()["additional_kwargs"]["tool_calls"][0][ "function" @@ -494,30 +494,30 @@ def get_news(location: str) -> str: } assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == messages[0].content ) - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "user" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "user" assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"] == "assistant" + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"] == "assistant" ) # Test that we write both the content and the tool calls assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == result.content[0]["text"] ) assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.id"] == "toolu_016q9vtSd8CY2vnZSpEp1j4o" ) assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name"] == "get_weather" ) assert json.loads( chat_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.arguments" ] ) == {"location": "San Francisco"} @@ -705,55 +705,55 @@ def get_news(location: str) -> str: } assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == messages[0].content ) - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "user" - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "assistant" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "user" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "assistant" assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.tool_calls.0.name"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.tool_calls.0.name"] == messages[1].tool_calls[0]["name"] ) assert ( json.loads( chat_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.1.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_PROMPT}.1.tool_calls.0.arguments" ] ) == messages[1].tool_calls[0]["args"] ) assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.tool_calls.0.id"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.tool_calls.0.id"] == messages[1].tool_calls[0]["id"] ) - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.role"] == "tool" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.role"] == "tool" assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.content"] == messages[2].content ) - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.tool_call_id"] == messages[2].tool_call_id + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.tool_call_id"] == messages[2].tool_call_id assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"] == "assistant" + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"] == "assistant" ) # Test that we write both the content and the tool calls assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == result.content[0]["text"] ) assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.id"] == "toolu_012guEZNJ5yH5jxHKWAkzCzh" ) assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name"] == "get_news" ) assert json.loads( chat_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.arguments" ] ) == {"location": "San Francisco"} @@ -900,9 +900,9 @@ def sample_tool(query: str) -> str: assert chat_span.name == "ChatOpenAI.chat" # Verify that the tool_call_id is properly set for the ToolMessage - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.role"] == "tool" - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.content"] == "Tool executed successfully" - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.tool_call_id"] == "call_12345" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.role"] == "tool" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.content"] == "Tool executed successfully" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.tool_call_id"] == "call_12345" logs = log_exporter.get_finished_logs() assert len(logs) == 0, ( @@ -1045,39 +1045,39 @@ def get_news(location: str) -> str: } assert ( - chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == messages[0].content ) - assert chat_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "user" + assert chat_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "user" assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"] == "assistant" + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"] == "assistant" ) assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.id"] == "call_EgULHWKqGjuB36aUeiOSpALZ" ) assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name"] == "get_weather" ) assert json.loads( chat_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.arguments" ] ) == {"location": "San Francisco"} assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.id"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.1.id"] == "call_Xer9QGOTDMG2Bxn9AKGiVM14" ) assert ( - chat_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.name"] + chat_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.1.name"] == "get_news" ) assert json.loads( chat_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.1.arguments" ] ) == {"location": "San Francisco"} diff --git a/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/custom_llm_instrumentor.py b/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/custom_llm_instrumentor.py index 3b2472930a..a79f49958d 100644 --- a/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/custom_llm_instrumentor.py +++ b/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/custom_llm_instrumentor.py @@ -142,16 +142,16 @@ async def acomplete_wrapper(tracer, wrapped, instance: CustomLLM, args, kwargs): @dont_throw def _handle_request(span, llm_request_type, args, kwargs, instance: CustomLLM): - _set_span_attribute(span, SpanAttributes.LLM_SYSTEM, instance.__class__.__name__) + _set_span_attribute(span, SpanAttributes.GEN_AI_SYSTEM, instance.__class__.__name__) _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TYPE, llm_request_type.value) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MODEL, instance.metadata.model_name + span, SpanAttributes.GEN_AI_REQUEST_MODEL, instance.metadata.model_name ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, instance.metadata.context_window + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, instance.metadata.context_window ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TOP_P, instance.metadata.num_output + span, SpanAttributes.GEN_AI_REQUEST_TOP_P, instance.metadata.num_output ) if should_send_prompts(): @@ -161,7 +161,7 @@ def _handle_request(span, llm_request_type, args, kwargs, instance: CustomLLM): prompt = args[0] _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.user", + f"{SpanAttributes.GEN_AI_PROMPT}.0.user", prompt[0] if isinstance(prompt, list) else prompt, ) @@ -171,13 +171,13 @@ def _handle_request(span, llm_request_type, args, kwargs, instance: CustomLLM): @dont_throw def _handle_response(span, llm_request_type, instance, response): _set_span_attribute( - span, SpanAttributes.LLM_RESPONSE_MODEL, instance.metadata.model_name + span, SpanAttributes.GEN_AI_RESPONSE_MODEL, instance.metadata.model_name ) if should_send_prompts(): if llm_request_type == LLMRequestTypeValues.COMPLETION: _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.content", response.text + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response.text ) return diff --git a/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/span_utils.py b/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/span_utils.py index 6ac00eeb8f..5072548541 100644 --- a/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/span_utils.py +++ b/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/span_utils.py @@ -17,10 +17,10 @@ def set_llm_chat_request(event, span) -> None: if should_send_prompts(): for idx, message in enumerate(event.messages): span.set_attribute( - f"{SpanAttributes.LLM_PROMPTS}.{idx}.role", message.role.value + f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.role", message.role.value ) span.set_attribute( - f"{SpanAttributes.LLM_PROMPTS}.{idx}.content", message.content + f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.content", message.content ) @@ -31,9 +31,9 @@ def set_llm_chat_request_model_attributes(event, span): model_dict = event.model_dict span.set_attribute(SpanAttributes.LLM_REQUEST_TYPE, LLMRequestTypeValues.CHAT.value) - span.set_attribute(SpanAttributes.LLM_REQUEST_MODEL, model_dict.get("model")) + span.set_attribute(SpanAttributes.GEN_AI_REQUEST_MODEL, model_dict.get("model")) span.set_attribute( - SpanAttributes.LLM_REQUEST_TEMPERATURE, model_dict.get("temperature") + SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, model_dict.get("temperature") ) @@ -46,17 +46,17 @@ def set_llm_chat_response(event, span) -> None: if should_send_prompts(): for idx, message in enumerate(event.messages): span.set_attribute( - f"{SpanAttributes.LLM_PROMPTS}.{idx}.role", message.role.value + f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.role", message.role.value ) span.set_attribute( - f"{SpanAttributes.LLM_PROMPTS}.{idx}.content", message.content + f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.content", message.content ) span.set_attribute( - f"{SpanAttributes.LLM_COMPLETIONS}.0.role", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", response.message.role.value, ) span.set_attribute( - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response.message.content, ) @@ -72,7 +72,7 @@ def set_llm_chat_response_model_attributes(event, span): return span.set_attribute( - SpanAttributes.LLM_RESPONSE_MODEL, + SpanAttributes.GEN_AI_RESPONSE_MODEL, ( raw.get("model") if "model" in raw else raw.model ), # raw can be Any, not just ChatCompletion @@ -93,11 +93,11 @@ def set_llm_chat_response_model_attributes(event, span): def set_llm_predict_response(event, span) -> None: if should_send_prompts(): span.set_attribute( - f"{SpanAttributes.LLM_COMPLETIONS}.role", + f"{SpanAttributes.GEN_AI_COMPLETION}.role", MessageRole.ASSISTANT.value, ) span.set_attribute( - f"{SpanAttributes.LLM_COMPLETIONS}.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.content", event.output, ) diff --git a/packages/opentelemetry-instrumentation-llamaindex/tests/test_agents.py b/packages/opentelemetry-instrumentation-llamaindex/tests/test_agents.py index dc15b72c86..e11ff11413 100644 --- a/packages/opentelemetry-instrumentation-llamaindex/tests/test_agents.py +++ b/packages/opentelemetry-instrumentation-llamaindex/tests/test_agents.py @@ -81,19 +81,19 @@ def multiply(a: int, b: int) -> int: assert llm_span_1.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - llm_span_1.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo-0613" + llm_span_1.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo-0613" ) assert ( - llm_span_1.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" + llm_span_1.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" ) - assert llm_span_1.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"].startswith( + assert llm_span_1.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"].startswith( "You are designed to help with a variety of tasks," ) - assert llm_span_1.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] == ( + assert llm_span_1.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == ( "What is 2 times 3?" ) assert llm_span_1.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" ].startswith( "Thought: The current language of the user is English. I need to use a tool" ) @@ -103,24 +103,24 @@ def multiply(a: int, b: int) -> int: assert llm_span_2.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - llm_span_2.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo-0613" + llm_span_2.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo-0613" ) assert ( - llm_span_2.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" + llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" ) - assert llm_span_2.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"].startswith( + assert llm_span_2.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"].startswith( "You are designed to help with a variety of tasks," ) - assert llm_span_2.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] == ( + assert llm_span_2.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == ( "What is 2 times 3?" ) - assert llm_span_2.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.content"].startswith( + assert llm_span_2.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.content"].startswith( "Thought: The current language of the user is English. I need to use a tool" ) - assert llm_span_2.attributes[f"{SpanAttributes.LLM_PROMPTS}.3.content"] == ( + assert llm_span_2.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.3.content"] == ( "Observation: 6" ) - assert llm_span_2.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] == ( + assert llm_span_2.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == ( "Thought: I can answer without using any more tools. I'll use the user's " "language to answer.\nAnswer: 2 times 3 is 6." ) @@ -174,19 +174,19 @@ def multiply(a: int, b: int) -> int: assert llm_span_1.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - llm_span_1.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo-0613" + llm_span_1.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo-0613" ) assert ( - llm_span_1.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" + llm_span_1.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" ) - assert llm_span_1.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"].startswith( + assert llm_span_1.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"].startswith( "You are designed to help with a variety of tasks," ) - assert llm_span_1.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] == ( + assert llm_span_1.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == ( "What is 2 times 3?" ) assert llm_span_1.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" ].startswith( "Thought: The current language of the user is English. I need to use a tool" ) @@ -196,10 +196,10 @@ def multiply(a: int, b: int) -> int: assert llm_span_2.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - llm_span_2.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo-0613" + llm_span_2.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo-0613" ) assert ( - llm_span_2.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" + llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" ) assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 32 @@ -352,10 +352,10 @@ def multiply(a: int, b: int) -> int: assert llm_span_1.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - llm_span_1.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo-0613" + llm_span_1.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo-0613" ) assert ( - llm_span_1.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" + llm_span_1.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" ) assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 43 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 479 @@ -363,10 +363,10 @@ def multiply(a: int, b: int) -> int: assert llm_span_2.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - llm_span_2.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo-0613" + llm_span_2.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo-0613" ) assert ( - llm_span_2.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" + llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" ) assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 32 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 535 @@ -444,25 +444,25 @@ def test_agent_with_query_tool(instrument_legacy, span_exporter, log_exporter): assert llm_span_1.parent is not None assert llm_span_2.parent is not None - assert llm_span_1.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert llm_span_1.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert ( - llm_span_1.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" + llm_span_1.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) - assert llm_span_1.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"].startswith( + assert llm_span_1.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"].startswith( "Given an input question, first create a syntactically correct sqlite" ) assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 68 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 224 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 292 - assert llm_span_2.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert llm_span_2.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert ( - llm_span_2.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" + llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) - assert llm_span_2.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"].startswith( + assert llm_span_2.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"].startswith( "Given an input question, synthesize a response from the query results." ) - assert llm_span_2.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] == ( + assert llm_span_2.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == ( "The city with the highest population in the city_stats table is Tokyo, " "with a population of 13,960,000." ) @@ -529,17 +529,17 @@ def test_agent_with_query_tool_with_events_with_content( assert llm_span_1.parent is not None assert llm_span_2.parent is not None - assert llm_span_1.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert llm_span_1.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert ( - llm_span_1.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" + llm_span_1.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 68 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 224 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 292 - assert llm_span_2.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert llm_span_2.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert ( - llm_span_2.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" + llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 25 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 63 @@ -654,17 +654,17 @@ def test_agent_with_query_tool_with_events_with_no_content( assert llm_span_1.parent is not None assert llm_span_2.parent is not None - assert llm_span_1.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert llm_span_1.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert ( - llm_span_1.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" + llm_span_1.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 68 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 224 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 292 - assert llm_span_2.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert llm_span_2.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert ( - llm_span_2.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" + llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 25 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 63 diff --git a/packages/opentelemetry-instrumentation-llamaindex/tests/test_chroma_vector_store.py b/packages/opentelemetry-instrumentation-llamaindex/tests/test_chroma_vector_store.py index 7c3a370b0a..0e68fe2efc 100644 --- a/packages/opentelemetry-instrumentation-llamaindex/tests/test_chroma_vector_store.py +++ b/packages/opentelemetry-instrumentation-llamaindex/tests/test_chroma_vector_store.py @@ -58,14 +58,14 @@ def test_rag_with_chroma(instrument_legacy, span_exporter): assert synthesize_span.parent is not None assert llm_span.parent is not None - assert llm_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert llm_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert ( - llm_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" + llm_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) - assert llm_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"].startswith( + assert llm_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"].startswith( "You are an expert Q&A system that is trusted around the world." ) - assert llm_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] == ( + assert llm_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == ( "The author worked on writing and programming before college." ) assert llm_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 10 diff --git a/packages/opentelemetry-instrumentation-llamaindex/tests/test_query_pipeline.py b/packages/opentelemetry-instrumentation-llamaindex/tests/test_query_pipeline.py index d0366bbae7..8daf85cd21 100644 --- a/packages/opentelemetry-instrumentation-llamaindex/tests/test_query_pipeline.py +++ b/packages/opentelemetry-instrumentation-llamaindex/tests/test_query_pipeline.py @@ -75,27 +75,27 @@ def test_query_pipeline(instrument_legacy, span_exporter): assert llm_span_1.parent is not None assert llm_span_2.parent is not None - assert llm_span_1.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert llm_span_1.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert ( - llm_span_1.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" + llm_span_1.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) - assert llm_span_1.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == ( + assert llm_span_1.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == ( "Please generate a question about Paul Graham's life regarding the following topic YCombinator" ) - assert llm_span_1.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] == ( + assert llm_span_1.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == ( "What role did Paul Graham play in the founding and development of YCombinator, and " "how has his involvement shaped the trajectory of the company?" ) - assert llm_span_2.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" + assert llm_span_2.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert ( - llm_span_2.attributes[SpanAttributes.LLM_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" + llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) - assert llm_span_2.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"].startswith( + assert llm_span_2.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"].startswith( "You are an expert Q&A system that is trusted around the world." ) assert llm_span_2.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" ].startswith( "Paul Graham played a pivotal role in the founding and development of Y Combinator." ) diff --git a/packages/opentelemetry-instrumentation-mistralai/opentelemetry/instrumentation/mistralai/__init__.py b/packages/opentelemetry-instrumentation-mistralai/opentelemetry/instrumentation/mistralai/__init__.py index a6b3e1885e..ef36097fc1 100644 --- a/packages/opentelemetry-instrumentation-mistralai/opentelemetry/instrumentation/mistralai/__init__.py +++ b/packages/opentelemetry-instrumentation-mistralai/opentelemetry/instrumentation/mistralai/__init__.py @@ -79,16 +79,16 @@ def _set_input_attributes(span, llm_request_type, to_wrap, kwargs): return if should_send_prompts(): if llm_request_type == LLMRequestTypeValues.CHAT: - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user") for index, message in enumerate(kwargs.get("messages")): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{index}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{index}.content", message.content, ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{index}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{index}.role", message.role, ) else: @@ -96,21 +96,21 @@ def _set_input_attributes(span, llm_request_type, to_wrap, kwargs): if isinstance(input, str): _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user" + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user" ) _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.content", input + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.content", input ) else: for index, prompt in enumerate(input): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{index}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{index}.role", "user", ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{index}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{index}.content", prompt, ) @@ -119,7 +119,7 @@ def _set_input_attributes(span, llm_request_type, to_wrap, kwargs): def _set_model_input_attributes(span, to_wrap, kwargs): if not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("model")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, kwargs.get("model")) _set_span_attribute( span, SpanAttributes.LLM_IS_STREAMING, @@ -134,7 +134,7 @@ def _set_response_attributes(span, llm_request_type, response): if should_send_prompts(): for index, choice in enumerate(response.choices): - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" _set_span_attribute( span, f"{prefix}.finish_reason", @@ -166,7 +166,7 @@ def _set_model_response_attributes(span, llm_request_type, response): if llm_request_type == LLMRequestTypeValues.EMBEDDING: return - _set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, response.model) + _set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, response.model) if not response.usage: return @@ -398,7 +398,7 @@ def _wrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "MistralAI", + SpanAttributes.GEN_AI_SYSTEM: "MistralAI", SpanAttributes.LLM_REQUEST_TYPE: llm_request_type.value, }, ) @@ -444,7 +444,7 @@ async def _awrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "MistralAI", + SpanAttributes.GEN_AI_SYSTEM: "MistralAI", SpanAttributes.LLM_REQUEST_TYPE: llm_request_type.value, }, ) diff --git a/packages/opentelemetry-instrumentation-mistralai/tests/test_chat.py b/packages/opentelemetry-instrumentation-mistralai/tests/test_chat.py index 59b0896104..819015252f 100644 --- a/packages/opentelemetry-instrumentation-mistralai/tests/test_chat.py +++ b/packages/opentelemetry-instrumentation-mistralai/tests/test_chat.py @@ -24,19 +24,19 @@ def test_mistralai_chat_legacy( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-tiny" ) assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response.choices[0].message.content ) assert mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 11 @@ -70,11 +70,11 @@ def test_mistralai_chat_with_events_with_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-tiny" ) assert mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 11 @@ -123,11 +123,11 @@ def test_mistralai_chat_with_events_with_no_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-tiny" ) assert mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 11 @@ -176,19 +176,19 @@ def test_mistralai_streaming_chat_legacy( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-tiny" ) assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response ) assert mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 11 @@ -226,11 +226,11 @@ def test_mistralai_streaming_chat_with_events_with_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-tiny" ) assert mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 11 @@ -283,11 +283,11 @@ def test_mistralai_streaming_chat_with_events_with_no_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-tiny" ) assert mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 11 @@ -333,19 +333,19 @@ async def test_mistralai_async_chat_legacy( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-tiny" ) assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response.choices[0].message.content ) # For some reason, async ollama chat doesn't report prompt token usage back @@ -381,11 +381,11 @@ async def test_mistralai_async_chat_with_events_with_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-tiny" ) # For some reason, async ollama chat doesn't report prompt token usage back @@ -435,11 +435,11 @@ async def test_mistralai_async_chat_with_events_with_no_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-tiny" ) # For some reason, async ollama chat doesn't report prompt token usage back @@ -490,16 +490,16 @@ async def test_mistralai_async_streaming_chat_legacy( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert mistral_span.attributes.get("gen_ai.request.model") == "mistral-tiny" assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response ) assert mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 11 @@ -538,7 +538,7 @@ async def test_mistralai_async_streaming_chat_with_events_with_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert mistral_span.attributes.get("gen_ai.request.model") == "mistral-tiny" @@ -594,7 +594,7 @@ async def test_mistralai_async_streaming_chat_with_events_with_no_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.chat" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert mistral_span.attributes.get("gen_ai.request.model") == "mistral-tiny" diff --git a/packages/opentelemetry-instrumentation-mistralai/tests/test_embeddings.py b/packages/opentelemetry-instrumentation-mistralai/tests/test_embeddings.py index 258e3ac862..bb19141f1e 100644 --- a/packages/opentelemetry-instrumentation-mistralai/tests/test_embeddings.py +++ b/packages/opentelemetry-instrumentation-mistralai/tests/test_embeddings.py @@ -21,17 +21,17 @@ def test_mistral_embeddings_legacy( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.embeddings" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert ( mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "embedding" ) assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-embed" ) assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( @@ -57,13 +57,13 @@ def test_mistral_embeddings_with_events_with_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.embeddings" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert ( mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "embedding" ) assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-embed" ) assert ( @@ -100,13 +100,13 @@ def test_mistral_embeddings_with_events_with_no_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.embeddings" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert ( mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "embedding" ) assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-embed" ) assert ( @@ -144,17 +144,17 @@ async def test_mistral_async_embeddings_legacy( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.embeddings" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert ( mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "embedding" ) assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-embed" ) assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( @@ -181,13 +181,13 @@ async def test_mistral_async_embeddings_with_events_with_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.embeddings" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert ( mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "embedding" ) assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-embed" ) assert ( @@ -238,13 +238,13 @@ async def test_mistral_async_embeddings_with_events_with_no_content( spans = span_exporter.get_finished_spans() mistral_span = spans[0] assert mistral_span.name == "mistralai.embeddings" - assert mistral_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "MistralAI" + assert mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "MistralAI" assert ( mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "embedding" ) assert not mistral_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - mistral_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") + mistral_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "mistral-embed" ) assert ( diff --git a/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/__init__.py b/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/__init__.py index 4690b38e21..01ec34486b 100644 --- a/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/__init__.py +++ b/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/__init__.py @@ -107,7 +107,7 @@ def _accumulate_streaming_response( first_token_time = time.perf_counter() streaming_time_to_first_token.record( first_token_time - start_time, - attributes={SpanAttributes.LLM_SYSTEM: "Ollama"}, + attributes={SpanAttributes.GEN_AI_SYSTEM: "Ollama"}, ) first_token = False yield res @@ -125,8 +125,8 @@ def _accumulate_streaming_response( streaming_time_to_generate.record( time.perf_counter() - first_token_time, attributes={ - SpanAttributes.LLM_SYSTEM: "Ollama", - SpanAttributes.LLM_RESPONSE_MODEL: model_name, + SpanAttributes.GEN_AI_SYSTEM: "Ollama", + SpanAttributes.GEN_AI_RESPONSE_MODEL: model_name, }, ) @@ -171,7 +171,7 @@ async def _aaccumulate_streaming_response( first_token_time = time.perf_counter() streaming_time_to_first_token.record( first_token_time - start_time, - attributes={SpanAttributes.LLM_SYSTEM: "Ollama"}, + attributes={SpanAttributes.GEN_AI_SYSTEM: "Ollama"}, ) first_token = False yield res @@ -189,8 +189,8 @@ async def _aaccumulate_streaming_response( streaming_time_to_generate.record( time.perf_counter() - first_token_time, attributes={ - SpanAttributes.LLM_SYSTEM: "Ollama", - SpanAttributes.LLM_RESPONSE_MODEL: model_name, + SpanAttributes.GEN_AI_SYSTEM: "Ollama", + SpanAttributes.GEN_AI_RESPONSE_MODEL: model_name, }, ) @@ -297,7 +297,7 @@ def _wrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Ollama", + SpanAttributes.GEN_AI_SYSTEM: "Ollama", SpanAttributes.LLM_REQUEST_TYPE: llm_request_type.value, }, ) @@ -310,10 +310,10 @@ def _wrap( if response: if duration_histogram: duration = end_time - start_time - attrs = {SpanAttributes.LLM_SYSTEM: "Ollama"} + attrs = {SpanAttributes.GEN_AI_SYSTEM: "Ollama"} model = kwargs.get("model") if model is not None: - attrs[SpanAttributes.LLM_RESPONSE_MODEL] = model + attrs[SpanAttributes.GEN_AI_RESPONSE_MODEL] = model duration_histogram.record(duration, attributes=attrs) if kwargs.get("stream"): @@ -364,7 +364,7 @@ async def _awrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Ollama", + SpanAttributes.GEN_AI_SYSTEM: "Ollama", SpanAttributes.LLM_REQUEST_TYPE: llm_request_type.value, }, ) @@ -377,10 +377,10 @@ async def _awrap( if response: if duration_histogram: duration = end_time - start_time - attrs = {SpanAttributes.LLM_SYSTEM: "Ollama"} + attrs = {SpanAttributes.GEN_AI_SYSTEM: "Ollama"} model = kwargs.get("model") if model is not None: - attrs[SpanAttributes.LLM_RESPONSE_MODEL] = model + attrs[SpanAttributes.GEN_AI_RESPONSE_MODEL] = model duration_histogram.record(duration, attributes=attrs) if kwargs.get("stream"): diff --git a/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/span_utils.py b/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/span_utils.py index c7b89f9d15..1d8f76f468 100644 --- a/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/span_utils.py +++ b/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/span_utils.py @@ -22,25 +22,25 @@ def set_input_attributes(span, llm_request_type, kwargs): json_data = kwargs.get("json", {}) if llm_request_type == LLMRequestTypeValues.CHAT: - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user") for index, message in enumerate(json_data.get("messages")): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{index}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{index}.content", message.get("content"), ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{index}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{index}.role", message.get("role"), ) _set_prompts(span, json_data.get("messages")) if json_data.get("tools"): set_tools_attributes(span, json_data.get("tools")) else: - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user") _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.content", json_data.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.content", json_data.get("prompt") ) @@ -49,7 +49,7 @@ def set_model_input_attributes(span, kwargs): if not span.is_recording(): return json_data = kwargs.get("json", {}) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, json_data.get("model")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, json_data.get("model")) _set_span_attribute( span, SpanAttributes.LLM_IS_STREAMING, kwargs.get("stream") or False ) @@ -64,15 +64,15 @@ def set_response_attributes(span, token_histogram, llm_request_type, response): if llm_request_type == LLMRequestTypeValues.COMPLETION: _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response.get("response"), ) _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.role", "assistant" + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", "assistant" ) elif llm_request_type == LLMRequestTypeValues.CHAT: index = 0 - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" _set_span_attribute( span, f"{prefix}.content", response.get("message").get("content") ) @@ -86,7 +86,7 @@ def set_model_response_attributes(span, token_histogram, llm_request_type, respo if llm_request_type == LLMRequestTypeValues.EMBEDDING or not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, response.get("model")) + _set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, response.get("model")) input_tokens = response.get("prompt_eval_count") or 0 output_tokens = response.get("eval_count") or 0 @@ -106,7 +106,7 @@ def set_model_response_attributes(span, token_histogram, llm_request_type, respo SpanAttributes.LLM_USAGE_PROMPT_TOKENS, input_tokens, ) - _set_span_attribute(span, SpanAttributes.LLM_SYSTEM, "Ollama") + _set_span_attribute(span, SpanAttributes.GEN_AI_SYSTEM, "Ollama") if ( token_histogram is not None @@ -116,9 +116,9 @@ def set_model_response_attributes(span, token_histogram, llm_request_type, respo token_histogram.record( input_tokens, attributes={ - SpanAttributes.LLM_SYSTEM: "Ollama", - SpanAttributes.LLM_TOKEN_TYPE: "input", - SpanAttributes.LLM_RESPONSE_MODEL: response.get("model"), + SpanAttributes.GEN_AI_SYSTEM: "Ollama", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_RESPONSE_MODEL: response.get("model"), }, ) @@ -130,9 +130,9 @@ def set_model_response_attributes(span, token_histogram, llm_request_type, respo token_histogram.record( output_tokens, attributes={ - SpanAttributes.LLM_SYSTEM: "Ollama", - SpanAttributes.LLM_TOKEN_TYPE: "output", - SpanAttributes.LLM_RESPONSE_MODEL: response.get("model"), + SpanAttributes.GEN_AI_SYSTEM: "Ollama", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_RESPONSE_MODEL: response.get("model"), }, ) @@ -160,7 +160,7 @@ def _set_prompts(span, messages): if not should_send_prompts(): return for i, msg in enumerate(messages): - prefix = f"{SpanAttributes.LLM_PROMPTS}.{i}" + prefix = f"{SpanAttributes.GEN_AI_PROMPT}.{i}" _set_span_attribute(span, f"{prefix}.role", msg.get("role")) if msg.get("content"): diff --git a/packages/opentelemetry-instrumentation-ollama/tests/test_chat.py b/packages/opentelemetry-instrumentation-ollama/tests/test_chat.py index e996414e7e..ef123adce7 100644 --- a/packages/opentelemetry-instrumentation-ollama/tests/test_chat.py +++ b/packages/opentelemetry-instrumentation-ollama/tests/test_chat.py @@ -31,16 +31,16 @@ def test_ollama_chat_legacy( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response["message"]["content"] ) assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 @@ -73,10 +73,10 @@ def test_ollama_chat_with_events_with_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS @@ -121,10 +121,10 @@ def test_ollama_chat_with_events_with_no_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS @@ -177,27 +177,27 @@ def test_ollama_chat_tool_calls_legacy( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3.1" + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3.1" ) assert ( f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.content" not in ollama_span.attributes ) assert ( - ollama_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.tool_calls.0.name"] + ollama_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.tool_calls.0.name"] == "get_current_weather" ) assert ( - ollama_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.tool_calls.0.arguments"] + ollama_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.tool_calls.0.arguments"] == '{"location": "San Francisco"}' ) assert ( - ollama_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] + ollama_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == "The weather in San Francisco is 70 degrees and sunny." ) @@ -237,11 +237,11 @@ def test_ollama_chat_tool_calls_with_events_with_content( ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3.1" + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3.1" ) logs = log_exporter.get_finished_logs() @@ -312,11 +312,11 @@ def test_ollama_chat_tool_calls_with_events_with_no_content( ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3.1" + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3.1" ) logs = log_exporter.get_finished_logs() @@ -372,16 +372,16 @@ def test_ollama_streaming_chat_legacy( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response ) assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 @@ -419,10 +419,10 @@ def test_ollama_streaming_chat_with_events_with_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS @@ -472,10 +472,10 @@ def test_ollama_streaming_chat_with_events_with_no_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS @@ -517,16 +517,16 @@ async def test_ollama_async_chat_legacy( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response["message"]["content"] ) # For some reason, async ollama chat doesn't report prompt token usage back @@ -561,10 +561,10 @@ async def test_ollama_async_chat_with_events_with_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" # For some reason, async ollama chat doesn't report prompt token usage back # assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( @@ -611,10 +611,10 @@ async def test_ollama_async_chat_with_events_with_no_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" # For some reason, async ollama chat doesn't report prompt token usage back # assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( @@ -662,16 +662,16 @@ async def test_ollama_async_streaming_chat_legacy( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response ) assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 @@ -710,10 +710,10 @@ async def test_ollama_async_streaming_chat_with_events_with_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS @@ -764,10 +764,10 @@ async def test_ollama_async_streaming_chat_with_events_with_no_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.chat" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "chat" assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS @@ -805,17 +805,17 @@ def test_token_histogram_recording(): token_histogram.record.assert_any_call( 7, attributes={ - SpanAttributes.LLM_SYSTEM: "Ollama", - SpanAttributes.LLM_TOKEN_TYPE: "input", - SpanAttributes.LLM_RESPONSE_MODEL: "llama3", + SpanAttributes.GEN_AI_SYSTEM: "Ollama", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_RESPONSE_MODEL: "llama3", }, ) token_histogram.record.assert_any_call( 10, attributes={ - SpanAttributes.LLM_SYSTEM: "Ollama", - SpanAttributes.LLM_TOKEN_TYPE: "output", - SpanAttributes.LLM_RESPONSE_MODEL: "llama3", + SpanAttributes.GEN_AI_SYSTEM: "Ollama", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_RESPONSE_MODEL: "llama3", }, ) diff --git a/packages/opentelemetry-instrumentation-ollama/tests/test_embeddings.py b/packages/opentelemetry-instrumentation-ollama/tests/test_embeddings.py index 4a907aaa35..5a6065b93d 100644 --- a/packages/opentelemetry-instrumentation-ollama/tests/test_embeddings.py +++ b/packages/opentelemetry-instrumentation-ollama/tests/test_embeddings.py @@ -20,14 +20,14 @@ def test_ollama_embeddings_legacy( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.embeddings" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "embedding" ) assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) @@ -48,12 +48,12 @@ def test_ollama_embeddings_with_events_with_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.embeddings" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "embedding" ) assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" logs = log_exporter.get_finished_logs() assert len(logs) == 2 @@ -86,12 +86,12 @@ def test_ollama_embeddings_with_events_with_no_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.embeddings" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "embedding" ) assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" logs = log_exporter.get_finished_logs() assert len(logs) == 2 diff --git a/packages/opentelemetry-instrumentation-ollama/tests/test_generation.py b/packages/opentelemetry-instrumentation-ollama/tests/test_generation.py index 8e8ccf7f8f..3620db4956 100644 --- a/packages/opentelemetry-instrumentation-ollama/tests/test_generation.py +++ b/packages/opentelemetry-instrumentation-ollama/tests/test_generation.py @@ -20,18 +20,18 @@ def test_ollama_generation_legacy( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response["response"] ) assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 @@ -58,12 +58,12 @@ def test_ollama_generation_with_events_with_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS @@ -100,12 +100,12 @@ def test_ollama_generation_with_events_with_no_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS @@ -144,18 +144,18 @@ def test_ollama_streaming_generation_legacy( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response ) assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 @@ -186,12 +186,12 @@ def test_ollama_streaming_generation_with_events_with_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS @@ -234,12 +234,12 @@ def test_ollama_streaming_generation_with_events_with_no_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS @@ -275,18 +275,18 @@ async def test_ollama_async_generation_legacy( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response["response"] ) # For some reason, async ollama chat doesn't report prompt token usage back @@ -315,12 +315,12 @@ async def test_ollama_async_generation_with_events_with_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" # For some reason, async ollama chat doesn't report prompt token usage back # assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( @@ -361,12 +361,12 @@ async def test_ollama_async_generation_with_events_with_no_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert not ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" # For some reason, async ollama chat doesn't report prompt token usage back # assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( @@ -407,18 +407,18 @@ async def test_ollama_async_streaming_generation_legacy( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about OpenTelemetry" ) assert ( - ollama_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == response ) # For some reason, async ollama chat doesn't report prompt token usage back @@ -451,12 +451,12 @@ async def test_ollama_async_streaming_generation_with_events_with_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" # For some reason, async ollama chat doesn't report prompt token usage back # assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( @@ -501,12 +501,12 @@ async def test_ollama_async_streaming_generation_with_events_with_no_content( spans = span_exporter.get_finished_spans() ollama_span = spans[0] assert ollama_span.name == "ollama.completion" - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_SYSTEM}") == "Ollama" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_SYSTEM}") == "Ollama" assert ( ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_TYPE}") == "completion" ) assert ollama_span.attributes.get(f"{SpanAttributes.LLM_IS_STREAMING}") - assert ollama_span.attributes.get(f"{SpanAttributes.LLM_REQUEST_MODEL}") == "llama3" + assert ollama_span.attributes.get(f"{SpanAttributes.GEN_AI_REQUEST_MODEL}") == "llama3" # For some reason, async ollama chat doesn't report prompt token usage back # assert ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 17 assert ollama_span.attributes.get( diff --git a/packages/opentelemetry-instrumentation-ollama/tests/test_ollama_metrics.py b/packages/opentelemetry-instrumentation-ollama/tests/test_ollama_metrics.py index 0864a25916..c7398e9544 100644 --- a/packages/opentelemetry-instrumentation-ollama/tests/test_ollama_metrics.py +++ b/packages/opentelemetry-instrumentation-ollama/tests/test_ollama_metrics.py @@ -40,7 +40,7 @@ def test_ollama_streaming_metrics(instrument_legacy, reader): for name, dp in points: if name == GenAIMetrics.GEN_AI_SERVER_TIME_TO_FIRST_TOKEN: assert dp.sum > 0, "Time to first token should be greater than 0" - assert dp.attributes.get(SpanAttributes.LLM_SYSTEM) == "Ollama" + assert dp.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Ollama" break @@ -63,6 +63,6 @@ def test_ollama_streaming_time_to_generate_metrics(instrument_legacy, reader): for name, dp in points: if name == Meters.LLM_STREAMING_TIME_TO_GENERATE: assert dp.sum > 0, "Streaming time to generate should be greater than 0" - assert dp.attributes.get(SpanAttributes.LLM_SYSTEM) == "Ollama" - assert dp.attributes.get(SpanAttributes.LLM_RESPONSE_MODEL) is not None + assert dp.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "Ollama" + assert dp.attributes.get(SpanAttributes.GEN_AI_RESPONSE_MODEL) is not None break diff --git a/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/__init__.py b/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/__init__.py index 2628368d73..b00b04da56 100644 --- a/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/__init__.py +++ b/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/__init__.py @@ -103,8 +103,8 @@ async def _wrap_agent_run( f"{agent_name}.agent", kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "openai", - SpanAttributes.LLM_REQUEST_MODEL: model_name, + SpanAttributes.GEN_AI_SYSTEM: "openai", + SpanAttributes.GEN_AI_REQUEST_MODEL: model_name, SpanAttributes.TRACELOOP_SPAN_KIND: ( TraceloopSpanKindValues.AGENT.value ) @@ -128,8 +128,8 @@ async def _wrap_agent_run( duration_histogram.record( time.time() - start_time, attributes={ - SpanAttributes.LLM_SYSTEM: "openai", - SpanAttributes.LLM_RESPONSE_MODEL: model_name, + SpanAttributes.GEN_AI_SYSTEM: "openai", + SpanAttributes.GEN_AI_RESPONSE_MODEL: model_name, }, ) @@ -213,9 +213,9 @@ def set_model_settings_span_attributes(agent, span): settings_dict = vars(model_settings) key_to_span_attr = { - "max_tokens": SpanAttributes.LLM_REQUEST_MAX_TOKENS, - "temperature": SpanAttributes.LLM_REQUEST_TEMPERATURE, - "top_p": SpanAttributes.LLM_REQUEST_TOP_P, + "max_tokens": SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, + "temperature": SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, + "top_p": SpanAttributes.GEN_AI_REQUEST_TOP_P, } for key, value in settings_dict.items(): @@ -333,12 +333,12 @@ def set_prompt_attributes(span, message_history): content = msg.get("content", None) set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.role", role, ) set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.content", content, ) @@ -367,18 +367,18 @@ def set_response_content_span_attribute(response, span): if roles: set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.roles", + f"{SpanAttributes.GEN_AI_COMPLETION}.roles", roles, ) if types: set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.types", + f"{SpanAttributes.GEN_AI_COMPLETION}.types", types, ) if contents: set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.contents", contents + span, f"{SpanAttributes.GEN_AI_COMPLETION}.contents", contents ) @@ -418,18 +418,18 @@ def set_token_usage_span_attributes( token_histogram.record( input_tokens, attributes={ - SpanAttributes.LLM_SYSTEM: "openai", - SpanAttributes.LLM_TOKEN_TYPE: "input", - SpanAttributes.LLM_RESPONSE_MODEL: model_name, + SpanAttributes.GEN_AI_SYSTEM: "openai", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_RESPONSE_MODEL: model_name, "gen_ai.agent.name": agent_name, }, ) token_histogram.record( output_tokens, attributes={ - SpanAttributes.LLM_SYSTEM: "openai", - SpanAttributes.LLM_TOKEN_TYPE: "output", - SpanAttributes.LLM_RESPONSE_MODEL: model_name, + SpanAttributes.GEN_AI_SYSTEM: "openai", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_RESPONSE_MODEL: model_name, "gen_ai.agent.name": agent_name, }, ) diff --git a/packages/opentelemetry-instrumentation-openai-agents/tests/test_openai_agents.py b/packages/opentelemetry-instrumentation-openai-agents/tests/test_openai_agents.py index 08fcab2bb0..89a8700958 100644 --- a/packages/opentelemetry-instrumentation-openai-agents/tests/test_openai_agents.py +++ b/packages/opentelemetry-instrumentation-openai-agents/tests/test_openai_agents.py @@ -37,15 +37,15 @@ def test_agent_spans(exporter, test_agent): assert span.name == "testAgent.agent" assert span.kind == span.kind.CLIENT - assert span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" - assert span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-4.1" + assert span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" + assert span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4.1" assert ( span.attributes[SpanAttributes.TRACELOOP_SPAN_KIND] == TraceloopSpanKindValues.AGENT.value ) - assert span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.3 - assert span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 1024 - assert span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.2 + assert span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.3 + assert span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 1024 + assert span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.2 assert span.attributes["openai.agent.model.frequency_penalty"] == 1.3 assert span.attributes["gen_ai.agent.name"] == "testAgent" assert ( @@ -53,9 +53,9 @@ def test_agent_spans(exporter, test_agent): == "You are a helpful assistant that answers all questions" ) - assert span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "user" + assert span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "user" assert ( - span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "What is AI?") assert span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] is not None @@ -65,25 +65,25 @@ def test_agent_spans(exporter, test_agent): assert span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] is not None assert ( - span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.contents"] + span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.contents"] is not None ) assert ( - len(span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.contents"]) > 0 + len(span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.contents"]) > 0 ) assert ( - span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.roles"] + span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.roles"] is not None ) assert ( - len(span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.roles"]) > 0 + len(span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.roles"]) > 0 ) assert ( - span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.types"] + span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.types"] is not None ) assert ( - len(span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.types"]) > 0 + len(span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.types"]) > 0 ) assert span.status.status_code == StatusCode.OK @@ -234,7 +234,7 @@ def test_generate_metrics(metrics_test_context, test_agent): assert ( ( data_point.attributes[ - SpanAttributes.LLM_TOKEN_TYPE + SpanAttributes.GEN_AI_TOKEN_TYPE ] in [ "output", @@ -257,13 +257,13 @@ def test_generate_metrics(metrics_test_context, test_agent): ) assert ( metric.data.data_points[0].attributes[ - SpanAttributes.LLM_SYSTEM + SpanAttributes.GEN_AI_SYSTEM ] == "openai" ) assert ( metric.data.data_points[0].attributes[ - SpanAttributes.LLM_RESPONSE_MODEL + SpanAttributes.GEN_AI_RESPONSE_MODEL ] == "gpt-4.1" ) diff --git a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/__init__.py b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/__init__.py index 68860e8aa4..1583e45bdf 100644 --- a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/__init__.py +++ b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/__init__.py @@ -112,7 +112,7 @@ def _set_request_attributes(span, kwargs, instance=None): base_url = _get_openai_base_url(instance) if instance else "" vendor = _get_vendor_from_url(base_url) - _set_span_attribute(span, SpanAttributes.LLM_SYSTEM, vendor) + _set_span_attribute(span, SpanAttributes.GEN_AI_SYSTEM, vendor) model = kwargs.get("model") if vendor == "AWS" and model and "." in model: @@ -120,14 +120,14 @@ def _set_request_attributes(span, kwargs, instance=None): elif vendor == "OpenRouter": model = _extract_model_name_from_provider_format(model) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, model) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, model) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, kwargs.get("max_tokens") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get("max_tokens") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, kwargs.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, kwargs.get("temperature") ) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, kwargs.get("top_p")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, kwargs.get("top_p")) _set_span_attribute( span, SpanAttributes.LLM_FREQUENCY_PENALTY, kwargs.get("frequency_penalty") ) @@ -197,7 +197,7 @@ def _set_response_attributes(span, response): if "error" in response: _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_ERROR}", + f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_ERROR}", json.dumps(response.get("error")), ) return @@ -205,7 +205,7 @@ def _set_response_attributes(span, response): response_model = response.get("model") if response_model: response_model = _extract_model_name_from_provider_format(response_model) - _set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, response_model) + _set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, response_model) _set_span_attribute(span, GEN_AI_RESPONSE_ID, response.get("id")) _set_span_attribute( @@ -245,7 +245,7 @@ def _log_prompt_filter(span, response_dict): if response_dict.get("prompt_filter_results"): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_FILTER_KEY}", + f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_FILTER_KEY}", json.dumps(response_dict.get("prompt_filter_results")), ) @@ -396,8 +396,8 @@ def metric_shared_attributes( return { **attributes, - SpanAttributes.LLM_SYSTEM: vendor, - SpanAttributes.LLM_RESPONSE_MODEL: response_model, + SpanAttributes.GEN_AI_SYSTEM: vendor, + SpanAttributes.GEN_AI_RESPONSE_MODEL: response_model, "gen_ai.operation.name": operation, "server.address": server_address, "stream": is_streaming, diff --git a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/chat_wrappers.py b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/chat_wrappers.py index 7e3e188183..8c8521a41a 100644 --- a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/chat_wrappers.py +++ b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/chat_wrappers.py @@ -363,7 +363,7 @@ def _set_token_counter_metrics(token_counter, usage, shared_attributes): if name in OPENAI_LLM_USAGE_TOKEN_TYPES: attributes_with_token_type = { **shared_attributes, - SpanAttributes.LLM_TOKEN_TYPE: _token_type(name), + SpanAttributes.GEN_AI_TOKEN_TYPE: _token_type(name), } token_counter.record(val, attributes=attributes_with_token_type) @@ -399,7 +399,7 @@ async def _set_prompts(span, messages): return for i, msg in enumerate(messages): - prefix = f"{SpanAttributes.LLM_PROMPTS}.{i}" + prefix = f"{SpanAttributes.GEN_AI_PROMPT}.{i}" msg = msg if isinstance(msg, dict) else model_as_dict(msg) _set_span_attribute(span, f"{prefix}.role", msg.get("role")) @@ -451,7 +451,7 @@ def _set_completions(span, choices): for choice in choices: index = choice.get("index") - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" _set_span_attribute( span, f"{prefix}.finish_reason", choice.get("finish_reason") ) @@ -562,14 +562,14 @@ def _set_streaming_token_metrics( if isinstance(prompt_usage, int) and prompt_usage >= 0: attributes_with_token_type = { **shared_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", } token_counter.record(prompt_usage, attributes=attributes_with_token_type) if isinstance(completion_usage, int) and completion_usage >= 0: attributes_with_token_type = { **shared_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", } token_counter.record( completion_usage, attributes=attributes_with_token_type @@ -761,7 +761,7 @@ def _build_from_streaming_response( yield item_to_yield shared_attributes = { - SpanAttributes.LLM_RESPONSE_MODEL: complete_response.get("model") or None, + SpanAttributes.GEN_AI_RESPONSE_MODEL: complete_response.get("model") or None, "server.address": _get_openai_base_url(instance), "stream": True, } @@ -831,7 +831,7 @@ async def _abuild_from_streaming_response( yield item_to_yield shared_attributes = { - SpanAttributes.LLM_RESPONSE_MODEL: complete_response.get("model") or None, + SpanAttributes.GEN_AI_RESPONSE_MODEL: complete_response.get("model") or None, "server.address": _get_openai_base_url(instance), "stream": True, } diff --git a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/completion_wrappers.py b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/completion_wrappers.py index d821fecb94..4081d861f7 100644 --- a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/completion_wrappers.py +++ b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/completion_wrappers.py @@ -157,7 +157,7 @@ def _set_prompts(span, prompt): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.user", + f"{SpanAttributes.GEN_AI_PROMPT}.0.user", prompt[0] if isinstance(prompt, list) else prompt, ) @@ -169,7 +169,7 @@ def _set_completions(span, choices): for choice in choices: index = choice.get("index") - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" _set_span_attribute( span, f"{prefix}.finish_reason", choice.get("finish_reason") ) diff --git a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py index d45af3789a..cfa21b330c 100644 --- a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py +++ b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/embeddings_wrappers.py @@ -248,7 +248,7 @@ def _set_embeddings_metrics( continue attributes_with_token_type = { **shared_attributes, - SpanAttributes.LLM_TOKEN_TYPE: _token_type(name), + SpanAttributes.GEN_AI_TOKEN_TYPE: _token_type(name), } token_counter.record(val, attributes=attributes_with_token_type) @@ -270,11 +270,11 @@ def _set_prompts(span, prompt): if isinstance(prompt, list): for i, p in enumerate(prompt): - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.{i}.content", p) + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.{i}.content", p) else: _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.content", + f"{SpanAttributes.GEN_AI_PROMPT}.0.content", prompt, ) diff --git a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py index 203147a85b..ffd84aa2c1 100644 --- a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +++ b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py @@ -145,37 +145,37 @@ def messages_list_wrapper(tracer, wrapped, instance, args, kwargs): _set_span_attribute( span, - SpanAttributes.LLM_SYSTEM, + SpanAttributes.GEN_AI_SYSTEM, "openai", ) _set_span_attribute( span, - SpanAttributes.LLM_REQUEST_MODEL, + SpanAttributes.GEN_AI_REQUEST_MODEL, assistant["model"], ) _set_span_attribute( span, - SpanAttributes.LLM_RESPONSE_MODEL, + SpanAttributes.GEN_AI_RESPONSE_MODEL, assistant["model"], ) if should_emit_events(): emit_event(MessageEvent(content=assistant["instructions"], role="system")) else: _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.role", "system" + span, f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_index}.role", "system" ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_index}.content", assistant["instructions"], ) prompt_index += 1 _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.role", "system" + span, f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_index}.role", "system" ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_index}.content", run["instructions"], ) emit_event(MessageEvent(content=run["instructions"], role="system")) @@ -183,7 +183,7 @@ def messages_list_wrapper(tracer, wrapped, instance, args, kwargs): completion_index = 0 for msg in messages: - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{completion_index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{completion_index}" content = msg.get("content") message_content = content[0].get("text").get("value") @@ -194,12 +194,12 @@ def messages_list_wrapper(tracer, wrapped, instance, args, kwargs): else: _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_index}.role", message_role, ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_index}.content", message_content, ) prompt_index += 1 @@ -262,16 +262,16 @@ def runs_create_and_stream_wrapper(tracer, wrapped, instance, args, kwargs): assistant = assistants[assistant_id] _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MODEL, assistants[assistant_id]["model"] + span, SpanAttributes.GEN_AI_REQUEST_MODEL, assistants[assistant_id]["model"] ) _set_span_attribute( span, - SpanAttributes.LLM_SYSTEM, + SpanAttributes.GEN_AI_SYSTEM, "openai", ) _set_span_attribute( span, - SpanAttributes.LLM_RESPONSE_MODEL, + SpanAttributes.GEN_AI_RESPONSE_MODEL, assistants[assistant_id]["model"], ) if should_emit_events(): @@ -282,20 +282,20 @@ def runs_create_and_stream_wrapper(tracer, wrapped, instance, args, kwargs): ) else: _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{i}.role", "system" + span, f"{SpanAttributes.GEN_AI_PROMPT}.{i}.role", "system" ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{i}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{i}.content", assistants[assistant_id]["instructions"], ) i += 1 if should_emit_events(): emit_event(MessageEvent(content=instructions, role="system")) else: - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.{i}.role", "system") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.{i}.role", "system") _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{i}.content", instructions + span, f"{SpanAttributes.GEN_AI_PROMPT}.{i}.content", instructions ) from opentelemetry.instrumentation.openai.v1.event_handler_wrapper import ( diff --git a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py index c2d39bbf53..f36f4998a5 100644 --- a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py +++ b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py @@ -118,12 +118,12 @@ def on_text_done(self, text): if not should_emit_events(): _set_span_attribute( self._span, - f"{SpanAttributes.LLM_COMPLETIONS}.{self._current_text_index}.role", + f"{SpanAttributes.GEN_AI_COMPLETION}.{self._current_text_index}.role", "assistant", ) _set_span_attribute( self._span, - f"{SpanAttributes.LLM_COMPLETIONS}.{self._current_text_index}.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.{self._current_text_index}.content", text.value, ) diff --git a/packages/opentelemetry-instrumentation-openai/tests/metrics/test_openai_metrics.py b/packages/opentelemetry-instrumentation-openai/tests/metrics/test_openai_metrics.py index d02329a4de..023855445b 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/metrics/test_openai_metrics.py +++ b/packages/opentelemetry-instrumentation-openai/tests/metrics/test_openai_metrics.py @@ -41,7 +41,7 @@ def test_chat_completion_metrics(instrument_legacy, reader, openai_client): if metric.name == Meters.LLM_TOKEN_USAGE: found_token_metric = True for data_point in metric.data.data_points: - assert data_point.attributes[SpanAttributes.LLM_TOKEN_TYPE] in [ + assert data_point.attributes[SpanAttributes.GEN_AI_TOKEN_TYPE] in [ "output", "input", ] @@ -106,7 +106,7 @@ class StructuredAnswer(BaseModel): for sm in rm.scope_metrics: for metric in sm.metrics: for data_point in metric.data.data_points: - model = data_point.attributes.get(SpanAttributes.LLM_RESPONSE_MODEL) + model = data_point.attributes.get(SpanAttributes.GEN_AI_RESPONSE_MODEL) if ( metric.name == Meters.LLM_TOKEN_USAGE and model == "gpt-4o-2024-08-06" @@ -165,7 +165,7 @@ def test_chat_streaming_metrics(instrument_legacy, reader, openai_client): if metric.name == Meters.LLM_TOKEN_USAGE: found_token_metric = True for data_point in metric.data.data_points: - assert data_point.attributes[SpanAttributes.LLM_TOKEN_TYPE] in [ + assert data_point.attributes[SpanAttributes.GEN_AI_TOKEN_TYPE] in [ "output", "input", ] @@ -205,10 +205,10 @@ def test_chat_streaming_metrics(instrument_legacy, reader, openai_client): for data_point in metric.data.data_points: assert ( - data_point.attributes.get(SpanAttributes.LLM_SYSTEM) == "openai" + data_point.attributes.get(SpanAttributes.GEN_AI_SYSTEM) == "openai" ) assert str( - data_point.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + data_point.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] ) in ("gpt-3.5-turbo", "gpt-3.5-turbo-0125", "gpt-4o-2024-08-06") assert data_point.attributes["gen_ai.operation.name"] == "chat" assert data_point.attributes["server.address"] != "" diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_assistant.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_assistant.py index aba11b65d4..fc76615aa6 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_assistant.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_assistant.py @@ -61,31 +61,31 @@ def test_new_assistant( open_ai_span = spans[0] assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "You are a personal math tutor. Write and run code to answer math questions." ) - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert ( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.1.content") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.1.content") == "Please address the user as Jane Doe. The user has a premium account." ) - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "system" - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.role"] == "user" + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "system" + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.role"] == "user" assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.content"] == user_message ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 145 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 155 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" completion_index = 0 for message in messages.data: @@ -93,13 +93,13 @@ def test_new_assistant( continue assert ( open_ai_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.{completion_index}.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.{completion_index}.content" ] == message.content[0].text.value ) assert ( open_ai_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.{completion_index}.role" + f"{SpanAttributes.GEN_AI_COMPLETION}.{completion_index}.role" ] == message.role ) @@ -158,17 +158,17 @@ def test_new_assistant_with_events_with_content( open_ai_span = spans[0] assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 145 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 155 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() assert len(logs) == 4 @@ -239,16 +239,16 @@ def test_new_assistant_with_events_with_no_content( open_ai_span = spans[0] assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 145 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 155 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() assert len(logs) == 4 @@ -318,7 +318,7 @@ def test_new_assistant_with_polling( assert open_ai_span.attributes["gen_ai.prompt.2.content"] == user_message assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 374 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 86 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" completion_index = 0 for message in messages.data: @@ -326,13 +326,13 @@ def test_new_assistant_with_polling( continue assert ( open_ai_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.{completion_index}.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.{completion_index}.content" ] == message.content[0].text.value ) assert ( open_ai_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.{completion_index}.role" + f"{SpanAttributes.GEN_AI_COMPLETION}.{completion_index}.role" ] == message.role ) @@ -386,7 +386,7 @@ def test_new_assistant_with_polling_with_events_with_content( assert open_ai_span.attributes["gen_ai.response.model"] == "gpt-4-turbo-preview" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 374 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 86 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() assert len(logs) == 4 @@ -460,7 +460,7 @@ def test_new_assistant_with_polling_with_events_with_no_content( assert open_ai_span.attributes["gen_ai.response.model"] == "gpt-4-turbo-preview" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 374 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 86 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() assert len(logs) == 4 @@ -519,28 +519,28 @@ def test_existing_assistant( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "You are a personal math tutor. Write and run code to answer math questions." ) - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert ( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.1.content") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.1.content") == "Please address the user as Jane Doe. The user has a premium account." ) - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "system" + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "system" assert open_ai_span.attributes["gen_ai.prompt.2.role"] == "user" assert open_ai_span.attributes["gen_ai.prompt.2.content"] == user_message assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 639 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 170 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" completion_index = 0 for message in messages.data: @@ -548,13 +548,13 @@ def test_existing_assistant( continue assert ( open_ai_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.{completion_index}.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.{completion_index}.content" ] == message.content[0].text.value ) assert ( open_ai_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.{completion_index}.role" + f"{SpanAttributes.GEN_AI_COMPLETION}.{completion_index}.role" ] == message.role ) @@ -609,17 +609,17 @@ def test_existing_assistant_with_events_with_content( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 639 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 170 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() assert len(logs) == 5 @@ -704,17 +704,17 @@ def test_existing_assistant_with_events_with_no_content( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 639 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 170 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() assert len(logs) == 5 @@ -777,35 +777,35 @@ def on_text_delta(self, delta, snapshot): open_ai_span = spans[0] assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "You are a personal math tutor. Write and run code to answer math questions." ) - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert ( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.1.content") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.1.content") == "Please address the user as Jane Doe. The user has a premium account." ) - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "system" + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "system" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 790 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 225 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" for idx, message in enumerate(assistant_messages): assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}.content"] == message ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.role"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}.role"] == "assistant" ) assert open_ai_span.attributes[f"gen_ai.response.{idx}.id"].startswith("msg") @@ -855,17 +855,17 @@ def on_text_delta(self, delta, snapshot): open_ai_span = spans[0] assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 790 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 225 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() assert len(logs) == 4 @@ -958,17 +958,17 @@ def on_text_delta(self, delta, snapshot): open_ai_span = spans[0] assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 790 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 225 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() assert len(logs) == 4 @@ -1027,34 +1027,34 @@ def on_text_delta(self, delta, snapshot): open_ai_span = spans[0] assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "You are a personal math tutor. Write and run code to answer math questions." ) - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "system" + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "system" assert ( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.1.content") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.1.content") == "Please address the user as Jane Doe. The user has a premium account." ) - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "system" + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "system" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 364 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 88 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" for idx, message in enumerate(assistant_messages): assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}.content"] == message ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.role"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}.role"] == "assistant" ) assert open_ai_span.attributes[f"gen_ai.response.{idx}.id"].startswith("msg_") @@ -1104,17 +1104,17 @@ def on_text_delta(self, delta, snapshot): open_ai_span = spans[0] assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 364 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 88 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() assert len(logs) == 3 @@ -1192,17 +1192,17 @@ def on_text_delta(self, delta, snapshot): open_ai_span = spans[0] assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_TYPE] == "chat" assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4-turbo-preview" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-4-turbo-preview" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 364 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 88 - assert open_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "openai" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() assert len(logs) == 3 diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_azure.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_azure.py index 1bdc4af02c..faa979dadf 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_azure.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_azure.py @@ -28,10 +28,10 @@ def test_chat(instrument_legacy, span_exporter, log_exporter, azure_openai_clien ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://traceloop-stg.openai.azure.com/openai/" @@ -146,11 +146,11 @@ def test_chat_content_filtering( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) assert ( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") == "FILTERED" ) assert ( @@ -164,7 +164,7 @@ def test_chat_content_filtering( ) content_filter_json = open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.content_filter_results" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content_filter_results" ) assert len(content_filter_json) > 0 @@ -285,11 +285,11 @@ def test_prompt_content_filtering( open_ai_span = spans[0] assert isinstance( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_ERROR}"], str + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_ERROR}"], str ) error = json.loads( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_ERROR}"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_ERROR}"] ) assert "innererror" in error @@ -329,11 +329,11 @@ def test_prompt_content_filtering_with_events_with_content( open_ai_span = spans[0] assert isinstance( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_ERROR}"], str + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_ERROR}"], str ) error = json.loads( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_ERROR}"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_ERROR}"] ) assert "innererror" in error @@ -378,11 +378,11 @@ def test_prompt_content_filtering_with_events_with_no_content( open_ai_span = spans[0] assert isinstance( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_ERROR}"], str + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_ERROR}"], str ) error = json.loads( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_ERROR}"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_ERROR}"] ) assert "innererror" in error @@ -427,10 +427,10 @@ def test_chat_streaming( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://traceloop-stg.openai.azure.com/openai/" @@ -442,7 +442,7 @@ def test_chat_streaming( # prompt filter results prompt_filter_results = json.loads( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_FILTER_KEY}") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_FILTER_KEY}") ) assert prompt_filter_results[0]["prompt_index"] == 0 assert ( @@ -495,7 +495,7 @@ def test_chat_streaming_with_events_with_content( # prompt filter results prompt_filter_results = json.loads( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_FILTER_KEY}") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_FILTER_KEY}") ) assert prompt_filter_results[0]["prompt_index"] == 0 assert ( @@ -565,7 +565,7 @@ def test_chat_streaming_with_events_with_no_content( # prompt filter results prompt_filter_results = json.loads( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.{PROMPT_FILTER_KEY}") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.{PROMPT_FILTER_KEY}") ) assert prompt_filter_results[0]["prompt_index"] == 0 assert ( @@ -614,10 +614,10 @@ async def test_chat_async_streaming( open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://traceloop-stg.openai.azure.com/openai/" diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat.py index abd546db77..232ac6821b 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat.py @@ -34,10 +34,10 @@ def test_chat(instrument_legacy, span_exporter, log_exporter, openai_client): ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://api.openai.com/v1/" @@ -189,24 +189,24 @@ def test_chat_tool_calls(instrument_legacy, span_exporter, log_exporter, openai_ "openai.chat", ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_PROMPTS}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_PROMPT}.0.content" not in open_ai_span.attributes assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.tool_calls.0.name"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.tool_calls.0.name"] == "get_current_weather" ) assert ( open_ai_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_PROMPT}.0.tool_calls.0.arguments" ] == '{"location": "San Francisco"}' ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == "The weather in San Francisco is 70 degrees and sunny." ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.tool_call_id"] == "1" + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.tool_call_id"] == "1" ) assert ( open_ai_span.attributes.get("gen_ai.response.id") @@ -254,7 +254,7 @@ def test_chat_tool_calls_with_events_with_content( ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_PROMPTS}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_PROMPT}.0.content" not in open_ai_span.attributes assert ( open_ai_span.attributes.get("gen_ai.response.id") @@ -332,7 +332,7 @@ def test_chat_tool_calls_with_events_with_no_content( ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_PROMPTS}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_PROMPT}.0.content" not in open_ai_span.attributes assert ( open_ai_span.attributes.get("gen_ai.response.id") == "chatcmpl-9gKNZbUWSC4s2Uh2QfVV7PYiqWIuH" @@ -397,24 +397,24 @@ def test_chat_pydantic_based_tool_calls( ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_PROMPTS}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_PROMPT}.0.content" not in open_ai_span.attributes assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.tool_calls.0.name"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.tool_calls.0.name"] == "get_current_weather" ) assert ( open_ai_span.attributes[ - f"{SpanAttributes.LLM_PROMPTS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_PROMPT}.0.tool_calls.0.arguments" ] == '{"location": "San Francisco"}' ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == "The weather in San Francisco is 70 degrees and sunny." ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.tool_call_id"] == "1" + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.tool_call_id"] == "1" ) assert ( open_ai_span.attributes.get("gen_ai.response.id") @@ -462,7 +462,7 @@ def test_chat_pydantic_based_tool_calls_with_events_with_content( ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_PROMPTS}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_PROMPT}.0.content" not in open_ai_span.attributes assert ( open_ai_span.attributes.get("gen_ai.response.id") == "chatcmpl-9lvGJKrBUPeJjHi3KKSEbGfcfomOP" @@ -539,7 +539,7 @@ def test_chat_pydantic_based_tool_calls_with_events_with_no_content( ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_PROMPTS}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_PROMPT}.0.content" not in open_ai_span.attributes assert ( open_ai_span.attributes.get("gen_ai.response.id") == "chatcmpl-9lvGJKrBUPeJjHi3KKSEbGfcfomOP" @@ -588,10 +588,10 @@ def test_chat_streaming(instrument_legacy, span_exporter, log_exporter, openai_c ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://api.openai.com/v1/" @@ -763,10 +763,10 @@ async def test_chat_async_streaming( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://api.openai.com/v1/" @@ -1335,41 +1335,41 @@ def test_chat_history_message_dict(span_exporter, openai_client): first_span = spans[0] assert first_span.name == "openai.chat" assert ( - first_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + first_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == first_user_message["content"] ) assert ( - first_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] + first_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == first_user_message["role"] ) assert ( - first_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + first_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == first_response.choices[0].message.content ) assert ( - first_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"] == "assistant" + first_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"] == "assistant" ) second_span = spans[1] assert second_span.name == "openai.chat" assert ( - second_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + second_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == first_user_message["content"] ) assert ( - second_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + second_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == second_response.choices[0].message.content ) assert ( - second_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] + second_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == first_response.choices[0].message.content ) - assert second_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "assistant" + assert second_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "assistant" assert ( - second_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.content"] + second_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.content"] == second_user_message["content"] ) - assert second_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.role"] == "user" + assert second_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.role"] == "user" @pytest.mark.vcr @@ -1402,41 +1402,41 @@ def test_chat_history_message_pydantic(span_exporter, openai_client): first_span = spans[0] assert first_span.name == "openai.chat" assert ( - first_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + first_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == first_user_message["content"] ) assert ( - first_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] + first_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == first_user_message["role"] ) assert ( - first_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + first_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == first_response.choices[0].message.content ) assert ( - first_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.role"] == "assistant" + first_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.role"] == "assistant" ) second_span = spans[1] assert second_span.name == "openai.chat" assert ( - second_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + second_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == first_user_message["content"] ) assert ( - second_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + second_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == second_response.choices[0].message.content ) assert ( - second_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.content"] + second_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.content"] == first_response.choices[0].message.content ) - assert second_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.1.role"] == "assistant" + assert second_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "assistant" assert ( - second_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.content"] + second_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.content"] == second_user_message["content"] ) - assert second_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.2.role"] == "user" + assert second_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.2.role"] == "user" def test_chat_exception(instrument_legacy, span_exporter, openai_client): @@ -1454,7 +1454,7 @@ def test_chat_exception(instrument_legacy, span_exporter, openai_client): ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) assert ( @@ -1492,7 +1492,7 @@ async def test_chat_async_exception(instrument_legacy, span_exporter, async_open ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) assert ( diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat_parse.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat_parse.py index 8960b63e49..97b8d308d9 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat_parse.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat_parse.py @@ -33,14 +33,14 @@ def test_parsed_completion( "openai.chat", ] open_ai_span = spans[0] - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://api.openai.com/v1/" ) assert open_ai_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) assert ( @@ -164,10 +164,10 @@ def test_parsed_refused_completion( "openai.chat", ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_COMPLETIONS}.0.content" not in open_ai_span.attributes - assert f"{SpanAttributes.LLM_COMPLETIONS}.0.refusal" in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_COMPLETION}.0.refusal" in open_ai_span.attributes assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.refusal"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.refusal"] == "I'm very sorry, but I can't assist with that request." ) assert ( @@ -200,7 +200,7 @@ def test_parsed_refused_completion_with_events_with_content( "openai.chat", ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_COMPLETIONS}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" not in open_ai_span.attributes assert ( open_ai_span.attributes.get("gen_ai.response.id") == "chatcmpl-AGky8KFDbg6f5fF4qLtsBredIjZZh" @@ -243,7 +243,7 @@ def test_parsed_refused_completion_with_events_with_no_content( "openai.chat", ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_COMPLETIONS}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" not in open_ai_span.attributes assert ( open_ai_span.attributes.get("gen_ai.response.id") == "chatcmpl-AGky8KFDbg6f5fF4qLtsBredIjZZh" @@ -281,14 +281,14 @@ async def test_async_parsed_completion( "openai.chat", ] open_ai_span = spans[0] - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://api.openai.com/v1/" ) assert open_ai_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) assert ( @@ -414,10 +414,10 @@ async def test_async_parsed_refused_completion( "openai.chat", ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_COMPLETIONS}.0.content" not in open_ai_span.attributes - assert f"{SpanAttributes.LLM_COMPLETIONS}.0.refusal" in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_COMPLETION}.0.refusal" in open_ai_span.attributes assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.refusal"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.refusal"] == "I'm very sorry, but I can't assist with that request." ) assert ( @@ -451,7 +451,7 @@ async def test_async_parsed_refused_completion_with_events_with_content( "openai.chat", ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_COMPLETIONS}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" not in open_ai_span.attributes assert ( open_ai_span.attributes.get("gen_ai.response.id") == "chatcmpl-AGkyFJGzZPUGAAEDJJuOS3idKvD3G" @@ -495,7 +495,7 @@ async def test_async_parsed_refused_completion_with_events_with_no_content( "openai.chat", ] open_ai_span = spans[0] - assert f"{SpanAttributes.LLM_COMPLETIONS}.0.content" not in open_ai_span.attributes + assert f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" not in open_ai_span.attributes assert ( open_ai_span.attributes.get("gen_ai.response.id") == "chatcmpl-AGkyFJGzZPUGAAEDJJuOS3idKvD3G" @@ -548,8 +548,8 @@ def test_parsed_completion_exception( assert span.name == "openai.chat" assert span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://api.openai.com/v1/" assert span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False - assert span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") == "Tell me a joke about opentelemetry" - assert span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.role") == "user" + assert span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about opentelemetry" + assert span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.role") == "user" assert span.status.status_code == StatusCode.ERROR assert span.status.description.startswith("Error code: 401") @@ -583,8 +583,8 @@ async def test_async_parsed_completion_exception( assert span.name == "openai.chat" assert span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://api.openai.com/v1/" assert span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False - assert span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") == "Tell me a joke about opentelemetry" - assert span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.role") == "user" + assert span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") == "Tell me a joke about opentelemetry" + assert span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.role") == "user" assert span.status.status_code == StatusCode.ERROR assert span.status.description.startswith("Error code: 401") diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_completions.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_completions.py index 02f76d6b4c..8a3e775bea 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_completions.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_completions.py @@ -29,10 +29,10 @@ def test_completion(instrument_legacy, span_exporter, log_exporter, openai_clien ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://api.openai.com/v1/" @@ -145,10 +145,10 @@ async def test_async_completion( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get("gen_ai.response.id") == "cmpl-8wq43c8U5ZZCQBX5lrSpsANwcd3OF" @@ -253,10 +253,10 @@ def test_completion_langchain_style( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get("gen_ai.response.id") == "cmpl-8wq43QD6R2WqfxXLpYsRvSAIn9LB9" @@ -368,11 +368,11 @@ def test_completion_streaming( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == "Tell me a joke about opentelemetry" ) assert open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" ) assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) @@ -564,10 +564,10 @@ async def test_async_completion_streaming( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes.get(SpanAttributes.LLM_OPENAI_API_BASE) == "https://api.openai.com/v1/" @@ -935,7 +935,7 @@ def test_completion_exception(instrument_legacy, span_exporter, openai_client): ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == "Tell me a joke about opentelemetry" ) assert open_ai_span.status.status_code == StatusCode.ERROR @@ -967,7 +967,7 @@ async def test_async_completion_exception(instrument_legacy, span_exporter, asyn ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == "Tell me a joke about opentelemetry" ) assert open_ai_span.status.status_code == StatusCode.ERROR diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_embeddings.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_embeddings.py index 1040427b8a..1f4c6305d3 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_embeddings.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_embeddings.py @@ -29,11 +29,11 @@ def test_embeddings(instrument_legacy, span_exporter, log_exporter, openai_clien ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "text-embedding-ada-002" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 8 @@ -63,7 +63,7 @@ def test_embeddings_with_events_with_content( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "text-embedding-ada-002" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 8 @@ -107,7 +107,7 @@ def test_embeddings_with_events_with_no_content( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "text-embedding-ada-002" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 8 @@ -142,12 +142,12 @@ def test_embeddings_with_raw_response( ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "text-embedding-ada-002" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 8 @@ -180,7 +180,7 @@ def test_embeddings_with_raw_response_with_events_with_content( open_ai_span = spans[0] assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "text-embedding-ada-002" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 8 @@ -227,7 +227,7 @@ def test_embeddings_with_raw_response_with_events_with_no_content( open_ai_span = spans[0] assert ( - open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "text-embedding-ada-002" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 8 @@ -274,10 +274,10 @@ def test_azure_openai_embeddings(instrument_legacy, span_exporter, log_exporter) ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) - assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "embedding" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "embedding" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 8 assert ( open_ai_span.attributes[SpanAttributes.LLM_OPENAI_API_BASE] @@ -318,7 +318,7 @@ def test_azure_openai_embeddings_with_events_with_content( "openai.embeddings", ] open_ai_span = spans[0] - assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "embedding" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "embedding" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 8 assert ( open_ai_span.attributes[SpanAttributes.LLM_OPENAI_API_BASE] @@ -373,7 +373,7 @@ def test_azure_openai_embeddings_with_events_with_no_content( "openai.embeddings", ] open_ai_span = spans[0] - assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "embedding" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "embedding" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 8 assert ( open_ai_span.attributes[SpanAttributes.LLM_OPENAI_API_BASE] diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_functions.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_functions.py index 74ec1e2c57..12df5ffe36 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_functions.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_functions.py @@ -65,7 +65,7 @@ def test_open_ai_function_calls( spans = span_exporter.get_finished_spans() open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "What's the weather like in Boston?" ) assert ( @@ -77,7 +77,7 @@ def test_open_ai_function_calls( == "Get the current weather in a given location" ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name"] == "get_current_weather" ) assert ( @@ -244,7 +244,7 @@ def test_open_ai_function_calls_tools( spans = span_exporter.get_finished_spans() open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "What's the weather like in Boston?" ) assert ( @@ -256,11 +256,11 @@ def test_open_ai_function_calls_tools( == "Get the current weather" ) assert isinstance( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id"], + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.id"], str, ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name"] == "get_current_weather" ) assert ( @@ -396,7 +396,7 @@ async def test_open_ai_function_calls_tools_streaming( open_ai_span = spans[0] assert isinstance( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id"], + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.id"], str, ) assert ( @@ -404,18 +404,18 @@ async def test_open_ai_function_calls_tools_streaming( == "get_current_weather" ) assert ( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.finish_reason") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.finish_reason") == "tool_calls" ) assert ( open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name" ) == "get_current_weather" ) assert ( open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.arguments" ) == '{"location":"San Francisco, CA"}' ) @@ -567,40 +567,40 @@ def test_open_ai_function_calls_tools_parallel( == "get_current_weather" ) assert ( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.finish_reason") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.finish_reason") == "tool_calls" ) assert isinstance( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id"], + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.id"], str, ) assert ( open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name" ) == "get_current_weather" ) assert ( open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.arguments" ) == '{"location": "San Francisco"}' ) assert isinstance( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.id"], + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.1.id"], str, ) assert ( open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.name" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.1.name" ) == "get_current_weather" ) assert ( open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.1.arguments" ) == '{"location": "Boston"}' ) @@ -761,40 +761,40 @@ async def test_open_ai_function_calls_tools_streaming_parallel( == "get_current_weather" ) assert ( - open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.finish_reason") + open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.finish_reason") == "tool_calls" ) assert isinstance( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id"], + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.id"], str, ) assert ( open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.name" ) == "get_current_weather" ) assert ( open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.0.arguments" ) == '{"location": "San Francisco"}' ) assert isinstance( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.id"], + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.1.id"], str, ) assert ( open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.name" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.1.name" ) == "get_current_weather" ) assert ( open_ai_span.attributes.get( - f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.arguments" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.tool_calls.1.arguments" ) == '{"location": "Boston"}' ) diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_vision.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_vision.py index cb74cd6a0e..6825b1c50f 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_vision.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_vision.py @@ -42,7 +42,7 @@ def test_vision(instrument_legacy, span_exporter, log_exporter, openai_client): ] open_ai_span = spans[0] assert json.loads( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] ) == [ {"type": "text", "text": "What is in this image?"}, { @@ -51,7 +51,7 @@ def test_vision(instrument_legacy, span_exporter, log_exporter, openai_client): }, ] - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes[SpanAttributes.LLM_OPENAI_API_BASE] == "https://api.openai.com/v1/" @@ -228,7 +228,7 @@ def test_vision_base64(instrument_legacy, span_exporter, log_exporter, openai_cl ] open_ai_span = spans[0] assert json.loads( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] ) == [ {"type": "text", "text": "What is in this image?"}, { @@ -237,7 +237,7 @@ def test_vision_base64(instrument_legacy, span_exporter, log_exporter, openai_cl }, ] - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert ( open_ai_span.attributes[SpanAttributes.LLM_OPENAI_API_BASE] == "https://api.openai.com/v1/" diff --git a/packages/opentelemetry-instrumentation-replicate/opentelemetry/instrumentation/replicate/__init__.py b/packages/opentelemetry-instrumentation-replicate/opentelemetry/instrumentation/replicate/__init__.py index f27f28590a..16a68ae52c 100644 --- a/packages/opentelemetry-instrumentation-replicate/opentelemetry/instrumentation/replicate/__init__.py +++ b/packages/opentelemetry-instrumentation-replicate/opentelemetry/instrumentation/replicate/__init__.py @@ -123,7 +123,7 @@ def _wrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Replicate", + SpanAttributes.GEN_AI_SYSTEM: "Replicate", SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value, }, ) diff --git a/packages/opentelemetry-instrumentation-replicate/opentelemetry/instrumentation/replicate/span_utils.py b/packages/opentelemetry-instrumentation-replicate/opentelemetry/instrumentation/replicate/span_utils.py index 574fbdb069..7bd9a5a18d 100644 --- a/packages/opentelemetry-instrumentation-replicate/opentelemetry/instrumentation/replicate/span_utils.py +++ b/packages/opentelemetry-instrumentation-replicate/opentelemetry/instrumentation/replicate/span_utils.py @@ -20,7 +20,7 @@ def set_input_attributes(span, args, kwargs): input_attribute = kwargs.get("input") if should_send_prompts(): _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.user", input_attribute.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.user", input_attribute.get("prompt") ) @@ -30,21 +30,21 @@ def set_model_input_attributes(span, args, kwargs): return if args is not None and len(args) > 0: - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, args[0]) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, args[0]) elif kwargs.get("version"): _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("version").id + span, SpanAttributes.GEN_AI_REQUEST_MODEL, kwargs.get("version").id ) else: - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, "unknown") + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, "unknown") input_attribute = kwargs.get("input") _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, input_attribute.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, input_attribute.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TOP_P, input_attribute.get("top_p") + span, SpanAttributes.GEN_AI_REQUEST_TOP_P, input_attribute.get("top_p") ) @@ -53,9 +53,9 @@ def set_response_attributes(span, response): if should_send_prompts(): if isinstance(response, list): for index, item in enumerate(response): - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" _set_span_attribute(span, f"{prefix}.content", item) elif isinstance(response, str): _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.content", response + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response ) diff --git a/packages/opentelemetry-instrumentation-sagemaker/opentelemetry/instrumentation/sagemaker/span_utils.py b/packages/opentelemetry-instrumentation-sagemaker/opentelemetry/instrumentation/sagemaker/span_utils.py index dbb750cfe5..f18454ec3e 100644 --- a/packages/opentelemetry-instrumentation-sagemaker/opentelemetry/instrumentation/sagemaker/span_utils.py +++ b/packages/opentelemetry-instrumentation-sagemaker/opentelemetry/instrumentation/sagemaker/span_utils.py @@ -39,7 +39,7 @@ def set_call_span_attributes(span, kwargs, response): return endpoint_name = kwargs.get("EndpointName") - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, endpoint_name) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, endpoint_name) def set_call_request_attributes(span, kwargs): diff --git a/packages/opentelemetry-instrumentation-sagemaker/tests/test_invocation.py b/packages/opentelemetry-instrumentation-sagemaker/tests/test_invocation.py index cb0225e7cd..87bc66a802 100644 --- a/packages/opentelemetry-instrumentation-sagemaker/tests/test_invocation.py +++ b/packages/opentelemetry-instrumentation-sagemaker/tests/test_invocation.py @@ -43,7 +43,7 @@ def test_sagemaker_completion_string_content_legacy( spans = span_exporter.get_finished_spans() meta_span = spans[0] - assert meta_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == endpoint_name + assert meta_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == endpoint_name assert meta_span.attributes[SpanAttributes.TRACELOOP_ENTITY_INPUT] == body logs = log_exporter.get_finished_logs() @@ -84,7 +84,7 @@ def test_sagemaker_completion_string_content_with_events_with_content( spans = span_exporter.get_finished_spans() meta_span = spans[0] - assert meta_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == endpoint_name + assert meta_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == endpoint_name logs = log_exporter.get_finished_logs() assert len(logs) == 2 @@ -136,7 +136,7 @@ def test_sagemaker_completion_string_content_with_events_with_no_content( spans = span_exporter.get_finished_spans() meta_span = spans[0] - assert meta_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == endpoint_name + assert meta_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == endpoint_name logs = log_exporter.get_finished_logs() assert len(logs) == 2 diff --git a/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/__init__.py b/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/__init__.py index 8173d6e9d5..5d3345b025 100644 --- a/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/__init__.py +++ b/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/__init__.py @@ -113,7 +113,7 @@ def _wrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "TogetherAI", + SpanAttributes.GEN_AI_SYSTEM: "TogetherAI", SpanAttributes.LLM_REQUEST_TYPE: llm_request_type.value, }, ) diff --git a/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/span_utils.py b/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/span_utils.py index c6f0e50366..a462bd312e 100644 --- a/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/span_utils.py +++ b/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/span_utils.py @@ -22,22 +22,22 @@ def set_prompt_attributes(span, llm_request_type, kwargs): if should_send_prompts(): if llm_request_type == LLMRequestTypeValues.CHAT: - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user") for index, message in enumerate(kwargs.get("messages")): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{index}.content", + f"{SpanAttributes.GEN_AI_PROMPT}.{index}.content", message.get("content"), ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{index}.role", + f"{SpanAttributes.GEN_AI_PROMPT}.{index}.role", message.get("role"), ) elif llm_request_type == LLMRequestTypeValues.COMPLETION: - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user") _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.content", kwargs.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.content", kwargs.get("prompt") ) @@ -46,7 +46,7 @@ def set_model_prompt_attributes(span, kwargs): if not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("model")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, kwargs.get("model")) _set_span_attribute( span, SpanAttributes.LLM_IS_STREAMING, @@ -63,15 +63,15 @@ def set_completion_attributes(span, llm_request_type, response): if llm_request_type == LLMRequestTypeValues.COMPLETION: _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", response.choices[0].text, ) _set_span_attribute( - span, f"{SpanAttributes.LLM_COMPLETIONS}.0.role", "assistant" + span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", "assistant" ) elif llm_request_type == LLMRequestTypeValues.CHAT: index = 0 - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}" _set_span_attribute( span, f"{prefix}.content", response.choices[0].message.content ) @@ -85,7 +85,7 @@ def set_model_completion_attributes(span, response): if not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, response.model) + _set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, response.model) _set_span_attribute(span, GEN_AI_RESPONSE_ID, response.id) usage_data = response.usage diff --git a/packages/opentelemetry-instrumentation-transformers/opentelemetry/instrumentation/transformers/span_utils.py b/packages/opentelemetry-instrumentation-transformers/opentelemetry/instrumentation/transformers/span_utils.py index 009b1de601..16e4dc2763 100644 --- a/packages/opentelemetry-instrumentation-transformers/opentelemetry/instrumentation/transformers/span_utils.py +++ b/packages/opentelemetry-instrumentation-transformers/opentelemetry/instrumentation/transformers/span_utils.py @@ -35,20 +35,20 @@ def set_model_input_attributes(span, instance): forward_params = instance._forward_params _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MODEL, instance.model.config.name_or_path + span, SpanAttributes.GEN_AI_REQUEST_MODEL, instance.model.config.name_or_path ) _set_span_attribute( - span, SpanAttributes.LLM_SYSTEM, instance.model.config.model_type + span, SpanAttributes.GEN_AI_SYSTEM, instance.model.config.model_type ) _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TYPE, "completion") _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, forward_params.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, forward_params.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TOP_P, forward_params.get("top_p") + span, SpanAttributes.GEN_AI_REQUEST_TOP_P, forward_params.get("top_p") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, forward_params.get("max_length") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, forward_params.get("max_length") ) _set_span_attribute( span, @@ -69,7 +69,7 @@ def _set_span_completions(span, completions): return for i, completion in enumerate(completions): - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{i}" + prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{i}" _set_span_attribute(span, f"{prefix}.content", completion.get("generated_text")) @@ -81,5 +81,5 @@ def _set_span_prompts(span, messages): messages = [messages] for i, msg in enumerate(messages): - prefix = f"{SpanAttributes.LLM_PROMPTS}.{i}" + prefix = f"{SpanAttributes.GEN_AI_PROMPT}.{i}" _set_span_attribute(span, f"{prefix}.content", msg) diff --git a/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/__init__.py b/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/__init__.py index 67068e3f65..8a69d444cd 100644 --- a/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/__init__.py +++ b/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/__init__.py @@ -229,7 +229,7 @@ async def _awrap(tracer, event_logger, to_wrap, wrapped, instance, args, kwargs) name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Google", + SpanAttributes.GEN_AI_SYSTEM: "Google", SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value, }, ) @@ -273,7 +273,7 @@ def _wrap(tracer, event_logger, to_wrap, wrapped, instance, args, kwargs): name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Google", + SpanAttributes.GEN_AI_SYSTEM: "Google", SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value, }, ) diff --git a/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/span_utils.py b/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/span_utils.py index f12873887f..53b0bf8925 100644 --- a/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/span_utils.py +++ b/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/span_utils.py @@ -24,7 +24,7 @@ def set_input_attributes(span, args): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.user", + f"{SpanAttributes.GEN_AI_PROMPT}.0.user", prompt, ) @@ -33,17 +33,17 @@ def set_input_attributes(span, args): def set_model_input_attributes(span, kwargs, llm_model): if not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, llm_model) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, llm_model) _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.user", kwargs.get("prompt") + span, f"{SpanAttributes.GEN_AI_PROMPT}.0.user", kwargs.get("prompt") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, kwargs.get("temperature") + span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, kwargs.get("temperature") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, kwargs.get("max_output_tokens") + span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get("max_output_tokens") ) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, kwargs.get("top_p")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, kwargs.get("top_p")) _set_span_attribute(span, SpanAttributes.LLM_TOP_K, kwargs.get("top_k")) _set_span_attribute( span, SpanAttributes.LLM_PRESENCE_PENALTY, kwargs.get("presence_penalty") @@ -57,10 +57,10 @@ def set_model_input_attributes(span, kwargs, llm_model): def set_response_attributes(span, llm_model, generation_text): if not span.is_recording() or not should_send_prompts(): return - _set_span_attribute(span, f"{SpanAttributes.LLM_COMPLETIONS}.0.role", "assistant") + _set_span_attribute(span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", "assistant") _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", generation_text, ) @@ -69,7 +69,7 @@ def set_response_attributes(span, llm_model, generation_text): def set_model_response_attributes(span, llm_model, token_usage): if not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, llm_model) + _set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, llm_model) if token_usage: _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_bison.py b/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_bison.py index ca6e6413f5..16ceec2b44 100644 --- a/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_bison.py +++ b/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_bison.py @@ -38,17 +38,17 @@ def test_vertexai_predict(instrument_legacy, span_exporter, log_exporter): vertexai_span = spans[0] assert ( - vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "text-bison@001" + vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "text-bison@001" ) assert ( "Give me ten interview questions for the role of program manager." - in vertexai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + in vertexai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] ) - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.8 - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 256 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.8 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 assert ( - vertexai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + vertexai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response ) @@ -81,17 +81,17 @@ async def async_predict_text() -> str: vertexai_span = spans[0] assert ( - vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "text-bison@001" + vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "text-bison@001" ) assert ( "Give me ten interview questions for the role of program manager." - in vertexai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + in vertexai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] ) - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.8 - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 256 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.8 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 assert ( - vertexai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + vertexai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response ) @@ -118,16 +118,16 @@ def test_vertexai_stream(instrument_legacy, span_exporter, log_exporter): ] vertexai_span = spans[0] - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "text-bison" + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "text-bison" assert ( "Give me ten interview questions for the role of program manager." - in vertexai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + in vertexai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] ) - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.8 - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 256 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.8 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 assert vertexai_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" ] == "".join(response) @@ -158,16 +158,16 @@ async def async_streaming_prediction() -> list: ] vertexai_span = spans[0] - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "text-bison" + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "text-bison" assert ( "Give me ten interview questions for the role of program manager." - in vertexai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + in vertexai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] ) - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.8 - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 256 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.8 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 assert vertexai_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" ] == "".join(response) @@ -204,17 +204,17 @@ def test_vertexai_chat(instrument_legacy, span_exporter, log_exporter): vertexai_span = spans[0] assert ( - vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "chat-bison@001" + vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "chat-bison@001" ) assert ( "How many planets are there in the solar system?" - in vertexai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + in vertexai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] ) - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.95 - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 256 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.95 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 assert ( - vertexai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + vertexai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response ) @@ -254,14 +254,14 @@ def test_vertexai_chat_stream(instrument_legacy, span_exporter, log_exporter): vertexai_span = spans[0] assert ( - vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "chat-bison@001" + vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "chat-bison@001" ) - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_TOP_P] == 0.95 - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_TEMPERATURE] == 0.8 - assert vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MAX_TOKENS] == 256 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.95 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.8 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 assert vertexai_span.attributes[ - f"{SpanAttributes.LLM_COMPLETIONS}.0.content" + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" ] == "".join(response) diff --git a/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_gemini.py b/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_gemini.py index 78ad2d4c57..cb37e71042 100644 --- a/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_gemini.py +++ b/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_gemini.py @@ -32,10 +32,10 @@ def test_vertexai_generate_content(instrument_legacy, span_exporter, log_exporte vertexai_span = spans[0] assert ( "what is shown in this image?" - in vertexai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + in vertexai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] ) assert ( - vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gemini-2.0-flash-lite" ) assert ( @@ -51,7 +51,7 @@ def test_vertexai_generate_content(instrument_legacy, span_exporter, log_exporte == response._raw_response.usage_metadata.candidates_token_count ) assert ( - vertexai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + vertexai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response.text ) @@ -84,7 +84,7 @@ def test_vertexai_generate_content_with_events_with_content( vertexai_span = spans[0] assert ( - vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gemini-2.0-flash-lite" ) assert ( @@ -144,7 +144,7 @@ def test_vertexai_generate_content_with_events_with_no_content( vertexai_span = spans[0] assert ( - vertexai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] + vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gemini-2.0-flash-lite" ) assert ( diff --git a/packages/opentelemetry-instrumentation-watsonx/opentelemetry/instrumentation/watsonx/__init__.py b/packages/opentelemetry-instrumentation-watsonx/opentelemetry/instrumentation/watsonx/__init__.py index c77dda67e6..d8284c412e 100644 --- a/packages/opentelemetry-instrumentation-watsonx/opentelemetry/instrumentation/watsonx/__init__.py +++ b/packages/opentelemetry-instrumentation-watsonx/opentelemetry/instrumentation/watsonx/__init__.py @@ -132,13 +132,13 @@ def _set_input_attributes(span, instance, kwargs): for index, input in enumerate(prompt): _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{index}.user", + f"{SpanAttributes.GEN_AI_PROMPT}.{index}.user", input, ) else: _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.0.user", + f"{SpanAttributes.GEN_AI_PROMPT}.0.user", prompt, ) @@ -147,7 +147,7 @@ def set_model_input_attributes(span, instance): if not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, instance.model_id) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, instance.model_id) # Set other attributes modelParameters = instance.params if modelParameters is not None: @@ -181,11 +181,11 @@ def set_model_input_attributes(span, instance): ) _set_span_attribute( span, - SpanAttributes.LLM_REQUEST_TEMPERATURE, + SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, modelParameters.get("temperature", None), ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TOP_P, modelParameters.get("top_p", None) + span, SpanAttributes.GEN_AI_REQUEST_TOP_P, modelParameters.get("top_p", None) ) @@ -194,7 +194,7 @@ def _set_stream_response_attributes(span, stream_response): return _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.0.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.0.content", stream_response.get("generated_text"), ) @@ -203,7 +203,7 @@ def _set_model_stream_response_attributes(span, stream_response): if not span.is_recording(): return _set_span_attribute( - span, SpanAttributes.LLM_RESPONSE_MODEL, stream_response.get("model_id") + span, SpanAttributes.GEN_AI_RESPONSE_MODEL, stream_response.get("model_id") ) _set_span_attribute( span, @@ -235,14 +235,14 @@ def _set_completion_content_attributes( if should_send_prompts(): _set_span_attribute( span, - f"{SpanAttributes.LLM_COMPLETIONS}.{index}.content", + f"{SpanAttributes.GEN_AI_COMPLETION}.{index}.content", results[0]["generated_text"], ) model_id = response.get("model_id") if response_counter: attributes_with_reason = { - SpanAttributes.LLM_RESPONSE_MODEL: model_id, + SpanAttributes.GEN_AI_RESPONSE_MODEL: model_id, SpanAttributes.LLM_RESPONSE_STOP_REASON: results[0]["stop_reason"], } response_counter.add(1, attributes=attributes_with_reason) @@ -289,7 +289,7 @@ def _set_response_attributes( if model_id is None: return - _set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, model_id) + _set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, model_id) shared_attributes = _metric_shared_attributes(response_model=model_id) @@ -298,12 +298,12 @@ def _set_response_attributes( if token_histogram: attributes_with_token_type = { **shared_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", } token_histogram.record(completion_token, attributes=attributes_with_token_type) attributes_with_token_type = { **shared_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", } token_histogram.record(prompt_token, attributes=attributes_with_token_type) @@ -409,14 +409,14 @@ def _build_and_set_stream_response( if token_histogram: attributes_with_token_type = { **shared_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "output", + SpanAttributes.GEN_AI_TOKEN_TYPE: "output", } token_histogram.record( stream_generated_token_count, attributes=attributes_with_token_type ) attributes_with_token_type = { **shared_attributes, - SpanAttributes.LLM_TOKEN_TYPE: "input", + SpanAttributes.GEN_AI_TOKEN_TYPE: "input", } token_histogram.record( stream_input_token_count, attributes=attributes_with_token_type @@ -436,8 +436,8 @@ def _build_and_set_stream_response( def _metric_shared_attributes(response_model: str, is_streaming: bool = False): return { - SpanAttributes.LLM_RESPONSE_MODEL: response_model, - SpanAttributes.LLM_SYSTEM: "watsonx", + SpanAttributes.GEN_AI_RESPONSE_MODEL: response_model, + SpanAttributes.GEN_AI_SYSTEM: "watsonx", "stream": is_streaming, } @@ -561,7 +561,7 @@ def _wrap( name, kind=SpanKind.CLIENT, attributes={ - SpanAttributes.LLM_SYSTEM: "Watsonx", + SpanAttributes.GEN_AI_SYSTEM: "Watsonx", SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value, }, ) diff --git a/packages/opentelemetry-instrumentation-watsonx/tests/metrics/test_watsonx_metrics.py b/packages/opentelemetry-instrumentation-watsonx/tests/metrics/test_watsonx_metrics.py index 99393576c7..a06c5f764c 100644 --- a/packages/opentelemetry-instrumentation-watsonx/tests/metrics/test_watsonx_metrics.py +++ b/packages/opentelemetry-instrumentation-watsonx/tests/metrics/test_watsonx_metrics.py @@ -31,7 +31,7 @@ def test_generate_metrics(metrics_test_context_legacy, watson_ai_model, log_expo if metric.name == Meters.LLM_TOKEN_USAGE: found_token_metric = True for data_point in metric.data.data_points: - assert data_point.attributes[SpanAttributes.LLM_TOKEN_TYPE] in [ + assert data_point.attributes[SpanAttributes.GEN_AI_TOKEN_TYPE] in [ "output", "input", ] @@ -52,7 +52,7 @@ def test_generate_metrics(metrics_test_context_legacy, watson_ai_model, log_expo ) assert ( - metric.data.data_points[0].attributes[SpanAttributes.LLM_SYSTEM] + metric.data.data_points[0].attributes[SpanAttributes.GEN_AI_SYSTEM] == "watsonx" ) @@ -100,7 +100,7 @@ def test_generate_stream_metrics( if metric.name == Meters.LLM_TOKEN_USAGE: found_token_metric = True for data_point in metric.data.data_points: - assert data_point.attributes[SpanAttributes.LLM_TOKEN_TYPE] in [ + assert data_point.attributes[SpanAttributes.GEN_AI_TOKEN_TYPE] in [ "output", "input", ] @@ -121,7 +121,7 @@ def test_generate_stream_metrics( ) assert ( - metric.data.data_points[0].attributes[SpanAttributes.LLM_SYSTEM] + metric.data.data_points[0].attributes[SpanAttributes.GEN_AI_SYSTEM] == "watsonx" ) diff --git a/packages/opentelemetry-instrumentation-watsonx/tests/traces/test_generate.py b/packages/opentelemetry-instrumentation-watsonx/tests/traces/test_generate.py index 8b125d60ca..656c9c1146 100644 --- a/packages/opentelemetry-instrumentation-watsonx/tests/traces/test_generate.py +++ b/packages/opentelemetry-instrumentation-watsonx/tests/traces/test_generate.py @@ -23,11 +23,11 @@ def test_generate(exporter_legacy, watson_ai_model, log_exporter): spans = exporter_legacy.get_finished_spans() watsonx_ai_span = spans[1] assert ( - watsonx_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + watsonx_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == "What is 1 + 1?" ) - assert watsonx_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "Watsonx" - assert watsonx_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert watsonx_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "Watsonx" + assert watsonx_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert watsonx_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) logs = log_exporter.get_finished_logs() @@ -49,7 +49,7 @@ def test_generate_with_events_with_content( response = watson_ai_model.generate(prompt="What is 1 + 1?") spans = exporter_with_content.get_finished_spans() watsonx_ai_span = spans[1] - assert watsonx_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "Watsonx" + assert watsonx_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "Watsonx" assert watsonx_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) logs = log_exporter.get_finished_logs() @@ -85,7 +85,7 @@ def test_generate_with_with_events_no_content( response = watson_ai_model.generate(prompt="What is 1 + 1?") spans = exporter_with_no_content.get_finished_spans() watsonx_ai_span = spans[1] - assert watsonx_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "Watsonx" + assert watsonx_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "Watsonx" assert watsonx_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) logs = log_exporter.get_finished_logs() @@ -120,12 +120,12 @@ def test_generate_text_stream(exporter_legacy, watson_ai_model, log_exporter): spans = exporter_legacy.get_finished_spans() watsonx_ai_span = spans[1] assert ( - watsonx_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"] + watsonx_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"] == "Write an epigram about the sun" ) - assert watsonx_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "Watsonx" + assert watsonx_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "Watsonx" assert ( - watsonx_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + watsonx_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == generated_text ) assert watsonx_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -154,7 +154,7 @@ def test_generate_text_stream_with_events_with_content( generated_text += chunk spans = exporter_with_content.get_finished_spans() watsonx_ai_span = spans[1] - assert watsonx_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "Watsonx" + assert watsonx_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "Watsonx" assert watsonx_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) logs = log_exporter.get_finished_logs() @@ -195,7 +195,7 @@ def test_generate_text_stream_with_events_with_no_content( generated_text += chunk spans = exporter_with_no_content.get_finished_spans() watsonx_ai_span = spans[1] - assert watsonx_ai_span.attributes[SpanAttributes.LLM_SYSTEM] == "Watsonx" + assert watsonx_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "Watsonx" assert watsonx_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) logs = log_exporter.get_finished_logs() diff --git a/packages/opentelemetry-semantic-conventions-ai/opentelemetry/semconv_ai/__init__.py b/packages/opentelemetry-semantic-conventions-ai/opentelemetry/semconv_ai/__init__.py index 96474a841a..f9dbee646c 100644 --- a/packages/opentelemetry-semantic-conventions-ai/opentelemetry/semconv_ai/__init__.py +++ b/packages/opentelemetry-semantic-conventions-ai/opentelemetry/semconv_ai/__init__.py @@ -1,4 +1,5 @@ from enum import Enum +import opentelemetry.semconv._incubating.attributes.gen_ai_attributes as otel_gen_ai_attributes SUPPRESS_LANGUAGE_MODEL_INSTRUMENTATION_KEY = "suppress_language_model_instrumentation" @@ -34,25 +35,44 @@ class Meters: class SpanAttributes: - # Semantic Conventions for LLM requests, this needs to be removed after - # OpenTelemetry Semantic Conventions support Gen AI. - # Issue at https://github.com/open-telemetry/opentelemetry-python/issues/3868 + # OpenTelemetry Semantic Conventions for Gen AI - # Refer to https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md - # for more detail for LLM spans from OpenTelemetry Community. - LLM_SYSTEM = "gen_ai.system" - LLM_REQUEST_MODEL = "gen_ai.request.model" - LLM_REQUEST_MAX_TOKENS = "gen_ai.request.max_tokens" - LLM_REQUEST_TEMPERATURE = "gen_ai.request.temperature" - LLM_REQUEST_TOP_P = "gen_ai.request.top_p" - LLM_PROMPTS = "gen_ai.prompt" - LLM_COMPLETIONS = "gen_ai.completion" - LLM_RESPONSE_MODEL = "gen_ai.response.model" - LLM_USAGE_COMPLETION_TOKENS = "gen_ai.usage.output_tokens" - LLM_USAGE_PROMPT_TOKENS = "gen_ai.usage.input_tokens" - LLM_USAGE_CACHE_CREATION_INPUT_TOKENS = "gen_ai.usage.cache_creation_input_tokens" - LLM_USAGE_CACHE_READ_INPUT_TOKENS = "gen_ai.usage.cache_read_input_tokens" - LLM_TOKEN_TYPE = "gen_ai.token.type" - LLM_REQUEST_STRUCTURED_OUTPUT_SCHEMA = "gen_ai.request.structured_output_schema" + GEN_AI_AGENT_DESCRIPTION=otel_gen_ai_attributes.GEN_AI_AGENT_DESCRIPTION + GEN_AI_AGENT_ID= otel_gen_ai_attributes.GEN_AI_AGENT_ID + GEN_AI_AGENT_NAME= otel_gen_ai_attributes.GEN_AI_AGENT_NAME + GEN_AI_COMPLETION=otel_gen_ai_attributes.GEN_AI_COMPLETION + GEN_AI_CONVERSATION_ID=otel_gen_ai_attributes.GEN_AI_CONVERSATION_ID + GEN_AI_DATA_SOURCE_ID=otel_gen_ai_attributes.GEN_AI_DATA_SOURCE_ID + GEN_AI_OPENAI_REQUEST_SERVICE_TIER=otel_gen_ai_attributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER + GEN_AI_OPENAI_RESPONSE_SERVICE_TIER=otel_gen_ai_attributes.GEN_AI_OPENAI_RESPONSE_SERVICE_TIER + GEN_AI_OPENAI_RESPONSE_SYSTEM_FINGERPRINT=otel_gen_ai_attributes.GEN_AI_OPENAI_RESPONSE_SYSTEM_FINGERPRINT + GEN_AI_OUTPUT_TYPE=otel_gen_ai_attributes.GEN_AI_OUTPUT_TYPE + GEN_AI_PROMPT=otel_gen_ai_attributes.GEN_AI_PROMPT + GEN_AI_REQUEST_CHOICE_COUNT=otel_gen_ai_attributes.GEN_AI_REQUEST_CHOICE_COUNT + GEN_AI_REQUEST_ENCODING_FORMATS= otel_gen_ai_attributes.GEN_AI_REQUEST_ENCODING_FORMATS + GEN_AI_REQUEST_FREQUENCY_PENALTY= otel_gen_ai_attributes.GEN_AI_REQUEST_FREQUENCY_PENALTY + GEN_AI_REQUEST_MAX_TOKENS=otel_gen_ai_attributes.GEN_AI_REQUEST_MAX_TOKENS + GEN_AI_REQUEST_MODEL=otel_gen_ai_attributes.GEN_AI_REQUEST_MODEL + GEN_AI_REQUEST_PRESENCE_PENALTY=otel_gen_ai_attributes.GEN_AI_REQUEST_PRESENCE_PENALTY + GEN_AI_REQUEST_SEED=otel_gen_ai_attributes.GEN_AI_REQUEST_SEED + GEN_AI_REQUEST_STOP_SEQUENCES=otel_gen_ai_attributes.GEN_AI_REQUEST_STOP_SEQUENCES + GEN_AI_REQUEST_TEMPERATURE=otel_gen_ai_attributes.GEN_AI_REQUEST_TEMPERATURE + GEN_AI_REQUEST_TOP_K=otel_gen_ai_attributes.GEN_AI_REQUEST_TOP_K + GEN_AI_REQUEST_TOP_P=otel_gen_ai_attributes.GEN_AI_REQUEST_TOP_P + GEN_AI_REQUEST_STRUCTURED_OUTPUT_SCHEMA = "gen_ai.request.structured_output_schema" + GEN_AI_RESPONSE_FINISH_REASONS=otel_gen_ai_attributes.GEN_AI_RESPONSE_FINISH_REASONS + GEN_AI_RESPONSE_ID=otel_gen_ai_attributes.GEN_AI_RESPONSE_ID + GEN_AI_RESPONSE_MODEL=otel_gen_ai_attributes.GEN_AI_RESPONSE_MODEL + GEN_AI_SYSTEM=otel_gen_ai_attributes.GEN_AI_SYSTEM + GEN_AI_TOKEN_TYPE=otel_gen_ai_attributes.GEN_AI_TOKEN_TYPE + GEN_AI_TOOL_CALL_ID=otel_gen_ai_attributes.GEN_AI_TOOL_CALL_ID + GEN_AI_TOOL_DESCRIPTION=otel_gen_ai_attributes.GEN_AI_TOOL_DESCRIPTION + GEN_AI_TOOL_NAME=otel_gen_ai_attributes.GEN_AI_TOOL_NAME + GEN_AI_TOOL_TYPE=otel_gen_ai_attributes.GEN_AI_TOOL_TYPE + GEN_AI_USAGE_INPUT_TOKENS=otel_gen_ai_attributes.GEN_AI_USAGE_INPUT_TOKENS + GEN_AI_USAGE_OUTPUT_TOKENS=otel_gen_ai_attributes.GEN_AI_USAGE_OUTPUT_TOKENS + GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS = "gen_ai.usage.cache_creation_input_tokens" + GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS = "gen_ai.usage.cache_read_input_tokens" # LLM LLM_REQUEST_TYPE = "llm.request.type" diff --git a/packages/opentelemetry-semantic-conventions-ai/poetry.lock b/packages/opentelemetry-semantic-conventions-ai/poetry.lock index 2e13e6ce0c..dec2a76d43 100644 --- a/packages/opentelemetry-semantic-conventions-ai/poetry.lock +++ b/packages/opentelemetry-semantic-conventions-ai/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. [[package]] name = "autopep8" @@ -62,6 +62,30 @@ mccabe = ">=0.7.0,<0.8.0" pycodestyle = ">=2.11.0,<2.12.0" pyflakes = ">=3.2.0,<3.3.0" +[[package]] +name = "importlib-metadata" +version = "8.7.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, + {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, +] + +[package.dependencies] +zipp = ">=3.20" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["pytest-mypy"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -86,6 +110,55 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "opentelemetry-api" +version = "1.35.0" +description = "OpenTelemetry Python API" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_api-1.35.0-py3-none-any.whl", hash = "sha256:c4ea7e258a244858daf18474625e9cc0149b8ee354f37843415771a40c25ee06"}, + {file = "opentelemetry_api-1.35.0.tar.gz", hash = "sha256:a111b959bcfa5b4d7dffc2fbd6a241aa72dd78dd8e79b5b1662bda896c5d2ffe"}, +] + +[package.dependencies] +importlib-metadata = ">=6.0,<8.8.0" +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-sdk" +version = "1.35.0" +description = "OpenTelemetry Python SDK" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_sdk-1.35.0-py3-none-any.whl", hash = "sha256:223d9e5f5678518f4842311bb73966e0b6db5d1e0b74e35074c052cd2487f800"}, + {file = "opentelemetry_sdk-1.35.0.tar.gz", hash = "sha256:2a400b415ab68aaa6f04e8a6a9f6552908fb3090ae2ff78d6ae0c597ac581954"}, +] + +[package.dependencies] +opentelemetry-api = "1.35.0" +opentelemetry-semantic-conventions = "0.56b0" +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.56b0" +description = "OpenTelemetry Semantic Conventions" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_semantic_conventions-0.56b0-py3-none-any.whl", hash = "sha256:df44492868fd6b482511cc43a942e7194be64e94945f572db24df2e279a001a2"}, + {file = "opentelemetry_semantic_conventions-0.56b0.tar.gz", hash = "sha256:c114c2eacc8ff6d3908cb328c811eaf64e6d68623840be9224dc829c4fd6c2ea"}, +] + +[package.dependencies] +opentelemetry-api = "1.35.0" +typing-extensions = ">=4.5.0" + [[package]] name = "packaging" version = "24.1" @@ -209,7 +282,39 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "typing-extensions" +version = "4.14.1" +description = "Backported and Experimental Type Hints for Python 3.9+" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76"}, + {file = "typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36"}, +] + +[[package]] +name = "zipp" +version = "3.23.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"}, + {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] + [metadata] lock-version = "2.1" python-versions = ">=3.9,<4" -content-hash = "4aa103228aa2f0c253690ff1a73203803c137319a5b3fe49c68773c87a401907" +content-hash = "6f5d29ff2d916317f0ca2c830518ae1ce166b83c5ec808c9ef563855ebced3a4" diff --git a/packages/opentelemetry-semantic-conventions-ai/pyproject.toml b/packages/opentelemetry-semantic-conventions-ai/pyproject.toml index a5e9382ae9..3c81ed22ac 100644 --- a/packages/opentelemetry-semantic-conventions-ai/pyproject.toml +++ b/packages/opentelemetry-semantic-conventions-ai/pyproject.toml @@ -23,6 +23,7 @@ include = "opentelemetry/semconv_ai" [tool.poetry.dependencies] python = ">=3.9,<4" +opentelemetry-sdk = "^1.35.0" [tool.poetry.group.dev.dependencies] autopep8 = "^2.2.0" diff --git a/packages/traceloop-sdk/tests/test_manual.py b/packages/traceloop-sdk/tests/test_manual.py index 182fc000a2..d3afd6f282 100644 --- a/packages/traceloop-sdk/tests/test_manual.py +++ b/packages/traceloop-sdk/tests/test_manual.py @@ -36,18 +36,18 @@ def test_manual_report(exporter, openai_client): spans = exporter.get_finished_spans() open_ai_span = spans[0] - assert open_ai_span.attributes[SpanAttributes.LLM_REQUEST_MODEL] == "gpt-3.5-turbo" - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.role"] == "user" + assert open_ai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.role"] == "user" assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about opentelemetry" ) assert ( - open_ai_span.attributes[SpanAttributes.LLM_RESPONSE_MODEL] + open_ai_span.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_COMPLETIONS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == "Why did the opentelemetry developer break up with their partner? Because they were tired" + " of constantly tracing their every move!" ) diff --git a/packages/traceloop-sdk/tests/test_privacy_no_prompts.py b/packages/traceloop-sdk/tests/test_privacy_no_prompts.py index 931d2008ef..9b870e18c6 100644 --- a/packages/traceloop-sdk/tests/test_privacy_no_prompts.py +++ b/packages/traceloop-sdk/tests/test_privacy_no_prompts.py @@ -44,7 +44,7 @@ def joke_workflow(): ] open_ai_span = spans[0] assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 15 - assert not open_ai_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + assert not open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_PROMPT}.0.content") assert not open_ai_span.attributes.get( - f"{SpanAttributes.LLM_PROMPTS}.0.completions" + f"{SpanAttributes.GEN_AI_PROMPT}.0.completions" ) diff --git a/packages/traceloop-sdk/tests/test_prompt_management.py b/packages/traceloop-sdk/tests/test_prompt_management.py index 40737655a3..098309d401 100644 --- a/packages/traceloop-sdk/tests/test_prompt_management.py +++ b/packages/traceloop-sdk/tests/test_prompt_management.py @@ -82,8 +82,8 @@ def test_prompt_management(exporter, openai_client): ] open_ai_span = spans[0] assert ( - open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] + open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about OpenTelemetry, pirate style" ) - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert open_ai_span.attributes.get("traceloop.prompt.key") == "joke_generator" diff --git a/packages/traceloop-sdk/tests/test_workflows.py b/packages/traceloop-sdk/tests/test_workflows.py index c8d45967ba..3c167b9c4c 100644 --- a/packages/traceloop-sdk/tests/test_workflows.py +++ b/packages/traceloop-sdk/tests/test_workflows.py @@ -44,8 +44,8 @@ def joke_workflow(): "pirate_joke_generator.workflow", ] open_ai_span = next(span for span in spans if span.name == "openai.chat") - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == "Tell me a joke about OpenTelemetry" - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about OpenTelemetry" + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert open_ai_span.attributes.get("traceloop.prompt.template") == "Tell me a {what} about {subject}" assert open_ai_span.attributes.get("traceloop.prompt.template_variables.what") == "joke" assert open_ai_span.attributes.get("traceloop.prompt.template_variables.subject") == "OpenTelemetry" @@ -90,8 +90,8 @@ async def joke_workflow(): "pirate_joke_generator.workflow", ] open_ai_span = next(span for span in spans if span.name == "openai.chat") - assert open_ai_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.content"] == "Tell me a joke about OpenTelemetry" - assert open_ai_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"] == "Tell me a joke about OpenTelemetry" + assert open_ai_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert open_ai_span.attributes.get("traceloop.prompt.template") == "Tell me a {what} about {subject}" assert open_ai_span.attributes.get("traceloop.prompt.template_variables.what") == "joke" assert open_ai_span.attributes.get("traceloop.prompt.template_variables.subject") == "OpenTelemetry" diff --git a/packages/traceloop-sdk/traceloop/sdk/tracing/manual.py b/packages/traceloop-sdk/traceloop/sdk/tracing/manual.py index e289c2d409..c877117175 100644 --- a/packages/traceloop-sdk/traceloop/sdk/tracing/manual.py +++ b/packages/traceloop-sdk/traceloop/sdk/tracing/manual.py @@ -26,23 +26,23 @@ def __init__(self, span: Span): pass def report_request(self, model: str, messages: list[LLMMessage]): - self._span.set_attribute(SpanAttributes.LLM_REQUEST_MODEL, model) + self._span.set_attribute(SpanAttributes.GEN_AI_REQUEST_MODEL, model) for idx, message in enumerate(messages): self._span.set_attribute( - f"{SpanAttributes.LLM_PROMPTS}.{idx}.role", message.role + f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.role", message.role ) self._span.set_attribute( - f"{SpanAttributes.LLM_PROMPTS}.{idx}.content", message.content + f"{SpanAttributes.GEN_AI_PROMPT}.{idx}.content", message.content ) def report_response(self, model: str, completions: list[str]): - self._span.set_attribute(SpanAttributes.LLM_RESPONSE_MODEL, model) + self._span.set_attribute(SpanAttributes.GEN_AI_RESPONSE_MODEL, model) for idx, completion in enumerate(completions): self._span.set_attribute( - f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.role", "assistant" + f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}.role", "assistant" ) self._span.set_attribute( - f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.content", completion + f"{SpanAttributes.GEN_AI_COMPLETION}.{idx}.content", completion ) def report_usage(self, usage: LLMUsage): @@ -69,7 +69,7 @@ def report_usage(self, usage: LLMUsage): def track_llm_call(vendor: str, type: str): with get_tracer() as tracer: with tracer.start_as_current_span(name=f"{vendor}.{type}") as span: - span.set_attribute(SpanAttributes.LLM_SYSTEM, vendor) + span.set_attribute(SpanAttributes.GEN_AI_SYSTEM, vendor) span.set_attribute(SpanAttributes.LLM_REQUEST_TYPE, type) llm_span = LLMSpan(span) try: From 64ade2bfa71fa565fdb7fdac1961da88bf1497c6 Mon Sep 17 00:00:00 2001 From: Martim Santos Date: Sat, 19 Jul 2025 16:39:30 +0000 Subject: [PATCH 3/3] fixed remaining opentelemetry gen_ai attributes --- .../instrumentation/alephalpha/__init__.py | 2 +- .../instrumentation/anthropic/__init__.py | 4 +-- .../instrumentation/anthropic/span_utils.py | 2 +- .../instrumentation/anthropic/streaming.py | 2 +- .../tests/test_messages.py | 36 +++++++++---------- .../instrumentation/bedrock/span_utils.py | 2 +- .../tests/traces/test_ai21.py | 12 +++---- .../tests/traces/test_anthropic.py | 30 ++++++++-------- .../tests/traces/test_meta.py | 24 ++++++------- .../tests/traces/test_nova.py | 6 ++-- .../tests/traces/test_titan.py | 6 ++-- .../instrumentation/cohere/span_utils.py | 4 +-- .../tests/test_chat.py | 2 +- .../google_generativeai/span_utils.py | 4 +-- .../tests/test_generate_content.py | 6 ++-- .../instrumentation/groq/span_utils.py | 4 +-- .../tests/traces/test_chat_tracing.py | 18 +++++----- .../langchain/callback_handler.py | 2 +- .../instrumentation/langchain/span_utils.py | 2 +- .../tests/test_llms.py | 24 ++++++------- .../instrumentation/llamaindex/span_utils.py | 2 +- .../tests/test_agents.py | 24 ++++++------- .../tests/test_chroma_vector_store.py | 2 +- .../instrumentation/mistralai/__init__.py | 2 +- .../tests/test_chat.py | 24 ++++++------- .../instrumentation/ollama/span_utils.py | 2 +- .../tests/test_chat.py | 24 ++++++------- .../tests/test_generation.py | 24 ++++++------- .../instrumentation/openai_agents/__init__.py | 2 +- .../tests/test_openai_agents.py | 2 +- .../instrumentation/openai/shared/__init__.py | 4 +-- .../openai/v1/assistant_wrappers.py | 2 +- .../openai/v1/event_handler_wrapper.py | 2 +- .../tests/traces/test_assistant.py | 30 ++++++++-------- .../tests/traces/test_azure.py | 6 ++-- .../tests/traces/test_chat.py | 12 +++---- .../tests/traces/test_completions.py | 6 ++-- .../instrumentation/together/span_utils.py | 2 +- .../instrumentation/vertexai/span_utils.py | 4 +-- .../tests/disabled_test_bison.py | 12 +++---- .../tests/disabled_test_gemini.py | 6 ++-- .../instrumentation/watsonx/__init__.py | 6 ++-- packages/traceloop-sdk/tests/test_manual.py | 2 +- .../traceloop/sdk/tracing/manual.py | 2 +- 44 files changed, 198 insertions(+), 198 deletions(-) diff --git a/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/__init__.py b/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/__init__.py index 2f4eb239e5..9744b84aa4 100644 --- a/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/__init__.py +++ b/packages/opentelemetry-instrumentation-alephalpha/opentelemetry/instrumentation/alephalpha/__init__.py @@ -86,7 +86,7 @@ def _handle_completion_event(event: CompletionEvent, span, event_logger, respons span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, input_tokens + output_tokens ) _set_span_attribute( - span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, output_tokens + span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens ) _set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, input_tokens) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py index 86668e3556..f74894de7a 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/__init__.py @@ -177,7 +177,7 @@ async def _aset_token_usage( set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, input_tokens) set_span_attribute( - span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens + span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens ) set_span_attribute(span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, total_tokens) @@ -268,7 +268,7 @@ def _set_token_usage( set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, input_tokens) set_span_attribute( - span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens + span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens ) set_span_attribute(span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, total_tokens) diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py index a3fbc3f032..8970120c80 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/span_utils.py @@ -221,7 +221,7 @@ def set_response_attributes(span, response): completion_tokens = response.get("usage").output_tokens set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, prompt_tokens) set_span_attribute( - span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens + span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens ) set_span_attribute( span, diff --git a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py index bc8e9ae5c9..4ad476ec44 100644 --- a/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py +++ b/packages/opentelemetry-instrumentation-anthropic/opentelemetry/instrumentation/anthropic/streaming.py @@ -86,7 +86,7 @@ def _set_token_usage( set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, input_tokens) set_span_attribute( - span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens + span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens ) set_span_attribute(span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, total_tokens) diff --git a/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py b/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py index 758565c63b..820d38b2fb 100644 --- a/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py +++ b/packages/opentelemetry-instrumentation-anthropic/tests/test_messages.py @@ -70,7 +70,7 @@ def test_anthropic_message_create_legacy( ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -117,7 +117,7 @@ def test_anthropic_message_create_with_events_with_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -182,7 +182,7 @@ def test_anthropic_message_create_with_events_with_no_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -253,7 +253,7 @@ def test_anthropic_multi_modal_legacy( ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1381 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -307,7 +307,7 @@ def test_anthropic_multi_modal_with_events_with_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1381 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -368,7 +368,7 @@ def test_anthropic_multi_modal_with_events_with_no_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1381 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -534,7 +534,7 @@ async def test_anthropic_async_multi_modal_legacy( ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1311 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -589,7 +589,7 @@ async def test_anthropic_async_multi_modal_with_events_with_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1311 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -651,7 +651,7 @@ async def test_anthropic_async_multi_modal_with_events_with_no_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1311 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -719,7 +719,7 @@ def test_anthropic_message_streaming_legacy( ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -773,7 +773,7 @@ def test_anthropic_message_streaming_with_events_with_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -838,7 +838,7 @@ def test_anthropic_message_streaming_with_events_with_no_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -906,7 +906,7 @@ async def test_async_anthropic_message_create_legacy( ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -953,7 +953,7 @@ async def test_async_anthropic_message_create_with_events_with_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -1011,7 +1011,7 @@ async def test_async_anthropic_message_create_with_events_with_no_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -1084,7 +1084,7 @@ async def test_async_anthropic_message_streaming_legacy( ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -1138,7 +1138,7 @@ async def test_async_anthropic_message_streaming_with_events_with_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) @@ -1202,7 +1202,7 @@ async def test_async_anthropic_message_streaming_with_events_with_no_content( anthropic_span = spans[0] assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 17 assert ( - anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] ) diff --git a/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/span_utils.py b/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/span_utils.py index 1e8d7ab2e8..ec0f3ba0ad 100644 --- a/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/span_utils.py +++ b/packages/opentelemetry-instrumentation-bedrock/opentelemetry/instrumentation/bedrock/span_utils.py @@ -528,7 +528,7 @@ def _record_usage_to_span(span, prompt_tokens, completion_tokens, metric_params) ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens, ) _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_ai21.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_ai21.py index 231ca3bd39..764399a6f0 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_ai21.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_ai21.py @@ -46,13 +46,13 @@ def test_ai21_j2_completion_string_content( assert meta_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == len( response_body.get("prompt").get("tokens") ) - assert meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == len( + assert meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == len( response_body.get("completions")[0].get("data").get("tokens") ) assert ( meta_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == meta_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] - + meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] ) # It is apparently always 1234, but for the sake of consistency, # we should not assert on it. @@ -99,13 +99,13 @@ def test_ai21_j2_completion_string_content_with_events_with_content( assert meta_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == len( response_body.get("prompt").get("tokens") ) - assert meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == len( + assert meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == len( response_body.get("completions")[0].get("data").get("tokens") ) assert ( meta_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == meta_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] - + meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] ) # It is apparently always 1234, but for the sake of consistency, # we should not assert on it. @@ -158,13 +158,13 @@ def test_ai21_j2_completion_string_content_with_events_with_no_content( assert meta_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == len( response_body.get("prompt").get("tokens") ) - assert meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == len( + assert meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == len( response_body.get("completions")[0].get("data").get("tokens") ) assert ( meta_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == meta_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] - + meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] ) # It is apparently always 1234, but for the sake of consistency, # we should not assert on it. diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_anthropic.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_anthropic.py index 4f2fb541d8..51c696e67e 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_anthropic.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_anthropic.py @@ -47,7 +47,7 @@ def test_anthropic_2_completion(instrument_legacy, brt, span_exporter, log_expor assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 13 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -89,7 +89,7 @@ def test_anthropic_2_completion_with_events_with_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 13 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -145,7 +145,7 @@ def test_anthropic_2_completion_with_events_with_no_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 13 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -217,7 +217,7 @@ def test_anthropic_3_completion_complex_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 16 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -269,7 +269,7 @@ def test_anthropic_3_completion_complex_content_with_events_with_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 16 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -339,7 +339,7 @@ def test_anthropic_3_completion_complex_content_with_events_with_no_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 16 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -420,7 +420,7 @@ def test_anthropic_3_completion_streaming( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 16 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -477,7 +477,7 @@ def test_anthropic_3_completion_streaming_with_events_with_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 16 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -548,7 +548,7 @@ def test_anthropic_3_completion_streaming_with_events_with_no_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 16 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -619,7 +619,7 @@ def test_anthropic_3_completion_string_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 16 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -669,7 +669,7 @@ def test_anthropic_3_completion_string_content_with_events_with_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 16 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -732,7 +732,7 @@ def test_anthropic_3_completion_string_content_with_events_with_no_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 16 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -799,7 +799,7 @@ def test_anthropic_cross_region(instrument_legacy, brt, span_exporter, log_expor assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 20 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -847,7 +847,7 @@ def test_anthropic_cross_region_with_events_with_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 20 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -913,7 +913,7 @@ def test_anthropic_cross_region_with_events_with_no_content( assert anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 20 assert anthropic_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + anthropic_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS ) == anthropic_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_meta.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_meta.py index 43b0d0d876..aa87e11fe7 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_meta.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_meta.py @@ -43,7 +43,7 @@ def test_meta_llama2_completion_string_content( == response_body["prompt_token_count"] ) assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response_body["generation_token_count"] ) assert ( @@ -90,7 +90,7 @@ def test_meta_llama2_completion_string_content_with_events_with_content( == response_body["prompt_token_count"] ) assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response_body["generation_token_count"] ) assert ( @@ -147,7 +147,7 @@ def test_meta_llama2_completion_string_content_with_events_with_no_content( == response_body["prompt_token_count"] ) assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response_body["generation_token_count"] ) assert ( @@ -194,7 +194,7 @@ def test_meta_llama3_completion(instrument_legacy, brt, span_exporter, log_expor == response_body["prompt_token_count"] ) assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response_body["generation_token_count"] ) assert ( @@ -238,7 +238,7 @@ def test_meta_llama3_completion_with_events_with_content( == response_body["prompt_token_count"] ) assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response_body["generation_token_count"] ) assert ( @@ -287,7 +287,7 @@ def test_meta_llama3_completion_with_events_with_no_content( == response_body["prompt_token_count"] ) assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response_body["generation_token_count"] ) assert ( @@ -343,7 +343,7 @@ def test_meta_converse(instrument_legacy, brt, span_exporter, log_exporter): == response["usage"]["inputTokens"] ) assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response["usage"]["outputTokens"] ) assert ( @@ -408,7 +408,7 @@ def test_meta_converse_with_events_with_content( == response["usage"]["inputTokens"] ) assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response["usage"]["outputTokens"] ) assert ( @@ -475,7 +475,7 @@ def test_meta_converse_with_events_with_no_content( == response["usage"]["inputTokens"] ) assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response["usage"]["outputTokens"] ) assert ( @@ -552,7 +552,7 @@ def test_meta_converse_stream(instrument_legacy, brt, span_exporter, log_exporte meta_span = spans[0] assert meta_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == inputTokens assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == outputTokens + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == outputTokens ) assert ( meta_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] @@ -628,7 +628,7 @@ def test_meta_converse_stream_with_events_with_content( meta_span = spans[0] assert meta_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == inputTokens assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == outputTokens + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == outputTokens ) assert ( meta_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] @@ -708,7 +708,7 @@ def test_meta_converse_stream_with_events_with_no_content( meta_span = spans[0] assert meta_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == inputTokens assert ( - meta_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == outputTokens + meta_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == outputTokens ) assert ( meta_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_nova.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_nova.py index 2241f43822..ab4025296f 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_nova.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_nova.py @@ -902,7 +902,7 @@ def test_nova_converse_stream(instrument_legacy, brt, span_exporter, log_exporte bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == inputTokens ) assert ( - bedrock_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + bedrock_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == outputTokens ) assert ( @@ -1007,7 +1007,7 @@ def test_nova_converse_stream_with_events_with_content( bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == inputTokens ) assert ( - bedrock_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + bedrock_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == outputTokens ) assert ( @@ -1132,7 +1132,7 @@ def test_nova_converse_stream_with_events_with_no_content( bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == inputTokens ) assert ( - bedrock_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + bedrock_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == outputTokens ) assert ( diff --git a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_titan.py b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_titan.py index 088e8fa790..d2d65a8cdd 100644 --- a/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_titan.py +++ b/packages/opentelemetry-instrumentation-bedrock/tests/traces/test_titan.py @@ -797,7 +797,7 @@ def test_titan_converse_stream(instrument_legacy, brt, span_exporter, log_export bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == inputTokens ) assert ( - bedrock_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + bedrock_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == outputTokens ) assert ( @@ -893,7 +893,7 @@ def test_titan_converse_stream_with_events_with_content( bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == inputTokens ) assert ( - bedrock_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + bedrock_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == outputTokens ) assert ( @@ -1001,7 +1001,7 @@ def test_titan_converse_stream_with_events_with_no_content( bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == inputTokens ) assert ( - bedrock_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + bedrock_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == outputTokens ) assert ( diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py index 4861115446..3169d462f3 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py @@ -106,7 +106,7 @@ def _set_span_chat_response(span, response): ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, response.token_count.get("response_tokens"), ) _set_span_attribute( @@ -127,7 +127,7 @@ def _set_span_chat_response(span, response): ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens, ) _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py b/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py index c6a8ea9fd5..e532453f2b 100644 --- a/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py +++ b/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py @@ -33,7 +33,7 @@ def test_cohere_chat_legacy( assert cohere_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == cohere_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( cohere_span.attributes.get("gen_ai.response.id") diff --git a/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/span_utils.py b/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/span_utils.py index 2ae944fa9e..cdf5d34937 100644 --- a/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/span_utils.py +++ b/packages/opentelemetry-instrumentation-google-generativeai/opentelemetry/instrumentation/google_generativeai/span_utils.py @@ -88,7 +88,7 @@ def set_model_request_attributes(span, kwargs, llm_model): span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get("max_output_tokens") ) _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, kwargs.get("top_p")) - _set_span_attribute(span, SpanAttributes.LLM_TOP_K, kwargs.get("top_k")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_K, kwargs.get("top_k")) _set_span_attribute( span, SpanAttributes.LLM_PRESENCE_PENALTY, kwargs.get("presence_penalty") ) @@ -143,7 +143,7 @@ def set_model_response_attributes(span, response, llm_model): ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, response.usage_metadata.candidates_token_count, ) _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-google-generativeai/tests/test_generate_content.py b/packages/opentelemetry-instrumentation-google-generativeai/tests/test_generate_content.py index 153c5e86c6..61652b21c7 100644 --- a/packages/opentelemetry-instrumentation-google-generativeai/tests/test_generate_content.py +++ b/packages/opentelemetry-instrumentation-google-generativeai/tests/test_generate_content.py @@ -39,7 +39,7 @@ def test_gemini_generate_content_legacy( # assert gemini_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 5 # assert ( - # gemini_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + # gemini_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] # + gemini_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] # == gemini_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] # ) @@ -77,7 +77,7 @@ def test_gemini_generate_content_with_events_with_content( # assert gemini_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 5 # assert ( - # gemini_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + # gemini_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] # + gemini_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] # == gemini_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] # ) @@ -125,7 +125,7 @@ def test_gemini_generate_content_with_events_with_no_content( # assert gemini_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 5 # assert ( - # gemini_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + # gemini_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] # + gemini_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] # == gemini_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] # ) diff --git a/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/span_utils.py b/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/span_utils.py index b37df8d38e..67413fca55 100644 --- a/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/span_utils.py +++ b/packages/opentelemetry-instrumentation-groq/opentelemetry/instrumentation/groq/span_utils.py @@ -83,7 +83,7 @@ def set_model_streaming_response_attributes(span, usage): if usage: set_span_attribute( - span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, usage.completion_tokens + span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, usage.completion_tokens ) set_span_attribute( span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, usage.prompt_tokens @@ -109,7 +109,7 @@ def set_model_response_attributes(span, response, token_histogram): span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, usage.get("total_tokens") ) set_span_attribute( - span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens + span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens ) set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, prompt_tokens) diff --git a/packages/opentelemetry-instrumentation-groq/tests/traces/test_chat_tracing.py b/packages/opentelemetry-instrumentation-groq/tests/traces/test_chat_tracing.py index 4414d4beb3..fe8aade992 100644 --- a/packages/opentelemetry-instrumentation-groq/tests/traces/test_chat_tracing.py +++ b/packages/opentelemetry-instrumentation-groq/tests/traces/test_chat_tracing.py @@ -29,7 +29,7 @@ def test_chat_legacy(instrument_legacy, groq_client, span_exporter, log_exporter assert groq_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) > 0 - assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) > 0 + assert groq_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) > 0 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) > 0 assert ( groq_span.attributes.get("gen_ai.response.id") @@ -59,7 +59,7 @@ def test_chat_with_events_with_content( groq_span = spans[0] assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) > 0 - assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) > 0 + assert groq_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) > 0 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) > 0 assert ( groq_span.attributes.get("gen_ai.response.id") @@ -106,7 +106,7 @@ def test_chat_with_events_with_no_content( groq_span = spans[0] assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) > 0 - assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) > 0 + assert groq_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) > 0 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) > 0 assert ( groq_span.attributes.get("gen_ai.response.id") @@ -152,7 +152,7 @@ async def test_async_chat_legacy( assert groq_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content") assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) > 0 - assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) > 0 + assert groq_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) > 0 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) > 0 assert ( groq_span.attributes.get("gen_ai.response.id") @@ -183,7 +183,7 @@ async def test_async_chat_with_events_with_content( groq_span = spans[0] assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) > 0 - assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) > 0 + assert groq_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) > 0 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) > 0 assert ( groq_span.attributes.get("gen_ai.response.id") @@ -232,7 +232,7 @@ async def test_async_chat_with_events_with_no_content( groq_span = spans[0] assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is False assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) > 0 - assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) > 0 + assert groq_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) > 0 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) > 0 assert ( groq_span.attributes.get("gen_ai.response.id") @@ -286,7 +286,7 @@ def test_chat_streaming_legacy( ) assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is True assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 18 - assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) == 73 + assert groq_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) == 73 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) == 91 logs = log_exporter.get_finished_logs() @@ -318,7 +318,7 @@ def test_chat_streaming_with_events_with_content( groq_span = spans[0] assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is True assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 18 - assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) == 73 + assert groq_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) == 73 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) == 91 logs = log_exporter.get_finished_logs() @@ -368,7 +368,7 @@ def test_chat_streaming_with_events_with_no_content( groq_span = spans[0] assert groq_span.attributes.get(SpanAttributes.LLM_IS_STREAMING) is True assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 18 - assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) == 73 + assert groq_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) == 73 assert groq_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) == 91 logs = log_exporter.get_finished_logs() diff --git a/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py b/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py index 8eeb5e0e6f..921c3199f3 100644 --- a/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py +++ b/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/callback_handler.py @@ -469,7 +469,7 @@ def on_llm_end( span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, prompt_tokens ) _set_span_attribute( - span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens + span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens ) _set_span_attribute( span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, total_tokens diff --git a/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/span_utils.py b/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/span_utils.py index b747a23ae7..0a84779975 100644 --- a/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/span_utils.py +++ b/packages/opentelemetry-instrumentation-langchain/opentelemetry/instrumentation/langchain/span_utils.py @@ -317,7 +317,7 @@ def set_chat_response_usage(span: Span, response: LLMResult): ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens, ) _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-langchain/tests/test_llms.py b/packages/opentelemetry-instrumentation-langchain/tests/test_llms.py index ed9c1053cd..678964da1c 100644 --- a/packages/opentelemetry-instrumentation-langchain/tests/test_llms.py +++ b/packages/opentelemetry-instrumentation-langchain/tests/test_llms.py @@ -293,7 +293,7 @@ def test_openai(instrument_legacy, span_exporter, log_exporter): ) assert openai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1497 - assert openai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 1037 + assert openai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 1037 assert openai_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 2534 assert ( openai_span.attributes[SpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS] == 1408 @@ -333,7 +333,7 @@ def test_openai_with_events_with_content( assert openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4o-mini" assert openai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1497 - assert openai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 1037 + assert openai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 1037 assert openai_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 2534 assert ( openai_span.attributes[SpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS] == 1408 @@ -387,7 +387,7 @@ def test_openai_with_events_with_no_content( assert openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-4o-mini" assert openai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 1497 - assert openai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 1037 + assert openai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 1037 assert openai_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 2534 assert ( openai_span.attributes[SpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS] == 1408 @@ -493,7 +493,7 @@ class Joke(BaseModel): == response ) assert openai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 76 - assert openai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 35 + assert openai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 35 assert openai_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 111 logs = log_exporter.get_finished_logs() @@ -540,7 +540,7 @@ class Joke(BaseModel): assert openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert openai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 76 - assert openai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 35 + assert openai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 35 assert openai_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 111 logs = log_exporter.get_finished_logs() @@ -613,7 +613,7 @@ class Joke(BaseModel): assert openai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MODEL] == "gpt-3.5-turbo" assert openai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 76 - assert openai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 35 + assert openai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 35 assert openai_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 111 logs = log_exporter.get_finished_logs() @@ -682,7 +682,7 @@ def test_anthropic(instrument_legacy, span_exporter, log_exporter): == "assistant" ) assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 19 - assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 22 + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 22 assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 41 assert ( anthropic_span.attributes["gen_ai.response.id"] @@ -752,7 +752,7 @@ def test_anthropic_with_events_with_content( assert anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 19 - assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 22 + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 22 assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 41 assert ( anthropic_span.attributes["gen_ai.response.id"] @@ -808,7 +808,7 @@ def test_anthropic_with_events_with_no_content( assert anthropic_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 19 - assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 22 + assert anthropic_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 22 assert anthropic_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 41 assert ( anthropic_span.attributes["gen_ai.response.id"] @@ -889,7 +889,7 @@ def test_bedrock(instrument_legacy, span_exporter, log_exporter): == "assistant" ) assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 16 - assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 27 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 27 assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 43 output = json.loads( workflow_span.attributes[SpanAttributes.TRACELOOP_ENTITY_OUTPUT] @@ -961,7 +961,7 @@ def test_bedrock_with_events_with_content( ) assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 16 - assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 27 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 27 assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 43 logs = log_exporter.get_finished_logs() @@ -1023,7 +1023,7 @@ def test_bedrock_with_events_with_no_content( == "anthropic.claude-3-haiku-20240307-v1:0" ) assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 16 - assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 27 + assert bedrock_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 27 assert bedrock_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 43 logs = log_exporter.get_finished_logs() diff --git a/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/span_utils.py b/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/span_utils.py index 5072548541..18564675db 100644 --- a/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/span_utils.py +++ b/packages/opentelemetry-instrumentation-llamaindex/opentelemetry/instrumentation/llamaindex/span_utils.py @@ -79,7 +79,7 @@ def set_llm_chat_response_model_attributes(event, span): ) if usage := raw.get("usage") if "usage" in raw else raw.usage: span.set_attribute( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, usage.completion_tokens + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, usage.completion_tokens ) span.set_attribute(SpanAttributes.LLM_USAGE_PROMPT_TOKENS, usage.prompt_tokens) span.set_attribute(SpanAttributes.LLM_USAGE_TOTAL_TOKENS, usage.total_tokens) diff --git a/packages/opentelemetry-instrumentation-llamaindex/tests/test_agents.py b/packages/opentelemetry-instrumentation-llamaindex/tests/test_agents.py index e11ff11413..d8bbcad3ce 100644 --- a/packages/opentelemetry-instrumentation-llamaindex/tests/test_agents.py +++ b/packages/opentelemetry-instrumentation-llamaindex/tests/test_agents.py @@ -97,7 +97,7 @@ def multiply(a: int, b: int) -> int: ].startswith( "Thought: The current language of the user is English. I need to use a tool" ) - assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 43 + assert llm_span_1.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 43 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 479 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 522 @@ -124,7 +124,7 @@ def multiply(a: int, b: int) -> int: "Thought: I can answer without using any more tools. I'll use the user's " "language to answer.\nAnswer: 2 times 3 is 6." ) - assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 32 + assert llm_span_2.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 32 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 535 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 567 @@ -190,7 +190,7 @@ def multiply(a: int, b: int) -> int: ].startswith( "Thought: The current language of the user is English. I need to use a tool" ) - assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 43 + assert llm_span_1.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 43 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 479 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 522 @@ -202,7 +202,7 @@ def multiply(a: int, b: int) -> int: llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" ) - assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 32 + assert llm_span_2.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 32 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 535 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 567 @@ -357,7 +357,7 @@ def multiply(a: int, b: int) -> int: assert ( llm_span_1.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" ) - assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 43 + assert llm_span_1.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 43 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 479 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 522 @@ -368,7 +368,7 @@ def multiply(a: int, b: int) -> int: assert ( llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0613" ) - assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 32 + assert llm_span_2.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 32 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 535 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 567 @@ -451,7 +451,7 @@ def test_agent_with_query_tool(instrument_legacy, span_exporter, log_exporter): assert llm_span_1.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.content"].startswith( "Given an input question, first create a syntactically correct sqlite" ) - assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 68 + assert llm_span_1.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 68 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 224 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 292 @@ -466,7 +466,7 @@ def test_agent_with_query_tool(instrument_legacy, span_exporter, log_exporter): "The city with the highest population in the city_stats table is Tokyo, " "with a population of 13,960,000." ) - assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 25 + assert llm_span_2.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 25 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 63 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 88 @@ -533,7 +533,7 @@ def test_agent_with_query_tool_with_events_with_content( assert ( llm_span_1.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) - assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 68 + assert llm_span_1.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 68 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 224 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 292 @@ -541,7 +541,7 @@ def test_agent_with_query_tool_with_events_with_content( assert ( llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) - assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 25 + assert llm_span_2.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 25 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 63 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 88 @@ -658,7 +658,7 @@ def test_agent_with_query_tool_with_events_with_no_content( assert ( llm_span_1.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) - assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 68 + assert llm_span_1.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 68 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 224 assert llm_span_1.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 292 @@ -666,7 +666,7 @@ def test_agent_with_query_tool_with_events_with_no_content( assert ( llm_span_2.attributes[SpanAttributes.GEN_AI_RESPONSE_MODEL] == "gpt-3.5-turbo-0125" ) - assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 25 + assert llm_span_2.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 25 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 63 assert llm_span_2.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 88 diff --git a/packages/opentelemetry-instrumentation-llamaindex/tests/test_chroma_vector_store.py b/packages/opentelemetry-instrumentation-llamaindex/tests/test_chroma_vector_store.py index 0e68fe2efc..b6f1d6a59c 100644 --- a/packages/opentelemetry-instrumentation-llamaindex/tests/test_chroma_vector_store.py +++ b/packages/opentelemetry-instrumentation-llamaindex/tests/test_chroma_vector_store.py @@ -68,6 +68,6 @@ def test_rag_with_chroma(instrument_legacy, span_exporter): assert llm_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == ( "The author worked on writing and programming before college." ) - assert llm_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 10 + assert llm_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 10 assert llm_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 2070 assert llm_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 2080 diff --git a/packages/opentelemetry-instrumentation-mistralai/opentelemetry/instrumentation/mistralai/__init__.py b/packages/opentelemetry-instrumentation-mistralai/opentelemetry/instrumentation/mistralai/__init__.py index ef36097fc1..28c4f31fa3 100644 --- a/packages/opentelemetry-instrumentation-mistralai/opentelemetry/instrumentation/mistralai/__init__.py +++ b/packages/opentelemetry-instrumentation-mistralai/opentelemetry/instrumentation/mistralai/__init__.py @@ -182,7 +182,7 @@ def _set_model_response_attributes(span, llm_request_type, response): ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens, ) _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-mistralai/tests/test_chat.py b/packages/opentelemetry-instrumentation-mistralai/tests/test_chat.py index 819015252f..e64ed24336 100644 --- a/packages/opentelemetry-instrumentation-mistralai/tests/test_chat.py +++ b/packages/opentelemetry-instrumentation-mistralai/tests/test_chat.py @@ -43,7 +43,7 @@ def test_mistralai_chat_legacy( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -81,7 +81,7 @@ def test_mistralai_chat_with_events_with_content( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -134,7 +134,7 @@ def test_mistralai_chat_with_events_with_no_content( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -195,7 +195,7 @@ def test_mistralai_streaming_chat_legacy( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -237,7 +237,7 @@ def test_mistralai_streaming_chat_with_events_with_content( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -294,7 +294,7 @@ def test_mistralai_streaming_chat_with_events_with_no_content( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -353,7 +353,7 @@ async def test_mistralai_async_chat_legacy( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -393,7 +393,7 @@ async def test_mistralai_async_chat_with_events_with_content( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -447,7 +447,7 @@ async def test_mistralai_async_chat_with_events_with_no_content( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -506,7 +506,7 @@ async def test_mistralai_async_streaming_chat_legacy( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -546,7 +546,7 @@ async def test_mistralai_async_streaming_chat_with_events_with_content( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") @@ -602,7 +602,7 @@ async def test_mistralai_async_streaming_chat_with_events_with_no_content( assert mistral_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == mistral_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + mistral_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) assert ( mistral_span.attributes.get("gen_ai.response.id") diff --git a/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/span_utils.py b/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/span_utils.py index 1d8f76f468..1b668d5306 100644 --- a/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/span_utils.py +++ b/packages/opentelemetry-instrumentation-ollama/opentelemetry/instrumentation/ollama/span_utils.py @@ -98,7 +98,7 @@ def set_model_response_attributes(span, token_histogram, llm_request_type, respo ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens, ) _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-ollama/tests/test_chat.py b/packages/opentelemetry-instrumentation-ollama/tests/test_chat.py index ef123adce7..a12e3669e9 100644 --- a/packages/opentelemetry-instrumentation-ollama/tests/test_chat.py +++ b/packages/opentelemetry-instrumentation-ollama/tests/test_chat.py @@ -47,7 +47,7 @@ def test_ollama_chat_legacy( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -81,7 +81,7 @@ def test_ollama_chat_with_events_with_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -129,7 +129,7 @@ def test_ollama_chat_with_events_with_no_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -388,7 +388,7 @@ def test_ollama_streaming_chat_legacy( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -427,7 +427,7 @@ def test_ollama_streaming_chat_with_events_with_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -480,7 +480,7 @@ def test_ollama_streaming_chat_with_events_with_no_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -534,7 +534,7 @@ async def test_ollama_async_chat_legacy( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -570,7 +570,7 @@ async def test_ollama_async_chat_with_events_with_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -620,7 +620,7 @@ async def test_ollama_async_chat_with_events_with_no_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -678,7 +678,7 @@ async def test_ollama_async_streaming_chat_legacy( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -718,7 +718,7 @@ async def test_ollama_async_streaming_chat_with_events_with_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -772,7 +772,7 @@ async def test_ollama_async_streaming_chat_with_events_with_no_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() diff --git a/packages/opentelemetry-instrumentation-ollama/tests/test_generation.py b/packages/opentelemetry-instrumentation-ollama/tests/test_generation.py index 3620db4956..a980cf608a 100644 --- a/packages/opentelemetry-instrumentation-ollama/tests/test_generation.py +++ b/packages/opentelemetry-instrumentation-ollama/tests/test_generation.py @@ -38,7 +38,7 @@ def test_ollama_generation_legacy( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -68,7 +68,7 @@ def test_ollama_generation_with_events_with_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -110,7 +110,7 @@ def test_ollama_generation_with_events_with_no_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -162,7 +162,7 @@ def test_ollama_streaming_generation_legacy( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -196,7 +196,7 @@ def test_ollama_streaming_generation_with_events_with_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -244,7 +244,7 @@ def test_ollama_streaming_generation_with_events_with_no_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -294,7 +294,7 @@ async def test_ollama_async_generation_legacy( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -326,7 +326,7 @@ async def test_ollama_async_generation_with_events_with_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -372,7 +372,7 @@ async def test_ollama_async_generation_with_events_with_no_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -426,7 +426,7 @@ async def test_ollama_async_streaming_generation_legacy( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -462,7 +462,7 @@ async def test_ollama_async_streaming_generation_with_events_with_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() @@ -512,7 +512,7 @@ async def test_ollama_async_streaming_generation_with_events_with_no_content( assert ollama_span.attributes.get( SpanAttributes.LLM_USAGE_TOTAL_TOKENS ) == ollama_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) + ollama_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) logs = log_exporter.get_finished_logs() diff --git a/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/__init__.py b/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/__init__.py index b00b04da56..8bb2e82d16 100644 --- a/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/__init__.py +++ b/packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/__init__.py @@ -405,7 +405,7 @@ def set_token_usage_span_attributes( if output_tokens is not None: set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens, ) if total_tokens is not None: diff --git a/packages/opentelemetry-instrumentation-openai-agents/tests/test_openai_agents.py b/packages/opentelemetry-instrumentation-openai-agents/tests/test_openai_agents.py index 89a8700958..ddb11250d5 100644 --- a/packages/opentelemetry-instrumentation-openai-agents/tests/test_openai_agents.py +++ b/packages/opentelemetry-instrumentation-openai-agents/tests/test_openai_agents.py @@ -60,7 +60,7 @@ def test_agent_spans(exporter, test_agent): assert span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] is not None assert ( - span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] is not None) assert span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] is not None diff --git a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/__init__.py b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/__init__.py index 1583e45bdf..417f071e19 100644 --- a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/__init__.py +++ b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/__init__.py @@ -226,7 +226,7 @@ def _set_response_attributes(span, response): ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, usage.get("completion_tokens"), ) _set_span_attribute( @@ -257,7 +257,7 @@ def _set_span_stream_usage(span, prompt_tokens, completion_tokens): if isinstance(completion_tokens, int) and completion_tokens >= 0: _set_span_attribute( - span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens + span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens ) if isinstance(prompt_tokens, int) and prompt_tokens >= 0: diff --git a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py index ffd84aa2c1..5990b2efa8 100644 --- a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py +++ b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/assistant_wrappers.py @@ -223,7 +223,7 @@ def messages_list_wrapper(tracer, wrapped, instance, args, kwargs): usage_dict = model_as_dict(run.get("usage")) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, usage_dict.get("completion_tokens"), ) _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py index f36f4998a5..3d01949f9a 100644 --- a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py +++ b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/v1/event_handler_wrapper.py @@ -29,7 +29,7 @@ def on_end(self): ) _set_span_attribute( self._span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, self._completion_tokens, ) self._original_handler.on_end() diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_assistant.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_assistant.py index fc76615aa6..1ca1af43e2 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_assistant.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_assistant.py @@ -84,7 +84,7 @@ def test_new_assistant( == user_message ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 145 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 155 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 155 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" completion_index = 0 @@ -167,7 +167,7 @@ def test_new_assistant_with_events_with_content( ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 145 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 155 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 155 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() @@ -247,7 +247,7 @@ def test_new_assistant_with_events_with_no_content( == "gpt-4-turbo-preview" ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 145 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 155 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 155 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() @@ -317,7 +317,7 @@ def test_new_assistant_with_polling( assert open_ai_span.attributes["gen_ai.prompt.2.role"] == "user" assert open_ai_span.attributes["gen_ai.prompt.2.content"] == user_message assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 374 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 86 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 86 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" completion_index = 0 @@ -385,7 +385,7 @@ def test_new_assistant_with_polling_with_events_with_content( assert open_ai_span.attributes["gen_ai.request.model"] == "gpt-4-turbo-preview" assert open_ai_span.attributes["gen_ai.response.model"] == "gpt-4-turbo-preview" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 374 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 86 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 86 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() @@ -459,7 +459,7 @@ def test_new_assistant_with_polling_with_events_with_no_content( assert open_ai_span.attributes["gen_ai.request.model"] == "gpt-4-turbo-preview" assert open_ai_span.attributes["gen_ai.response.model"] == "gpt-4-turbo-preview" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 374 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 86 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 86 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() @@ -539,7 +539,7 @@ def test_existing_assistant( assert open_ai_span.attributes["gen_ai.prompt.2.role"] == "user" assert open_ai_span.attributes["gen_ai.prompt.2.content"] == user_message assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 639 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 170 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 170 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" completion_index = 0 @@ -618,7 +618,7 @@ def test_existing_assistant_with_events_with_content( ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 639 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 170 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 170 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() @@ -713,7 +713,7 @@ def test_existing_assistant_with_events_with_no_content( ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 639 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 170 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 170 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() @@ -796,7 +796,7 @@ def on_text_delta(self, delta, snapshot): assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "system" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 790 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 225 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 225 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" for idx, message in enumerate(assistant_messages): @@ -864,7 +864,7 @@ def on_text_delta(self, delta, snapshot): ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 790 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 225 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 225 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() @@ -967,7 +967,7 @@ def on_text_delta(self, delta, snapshot): ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 790 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 225 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 225 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() @@ -1045,7 +1045,7 @@ def on_text_delta(self, delta, snapshot): ) assert open_ai_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.1.role"] == "system" assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 364 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 88 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 88 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" for idx, message in enumerate(assistant_messages): @@ -1113,7 +1113,7 @@ def on_text_delta(self, delta, snapshot): ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 364 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 88 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 88 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() @@ -1201,7 +1201,7 @@ def on_text_delta(self, delta, snapshot): ) assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 364 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 88 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 88 assert open_ai_span.attributes[SpanAttributes.GEN_AI_SYSTEM] == "openai" logs = log_exporter.get_finished_logs() diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_azure.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_azure.py index faa979dadf..b69e2bdb38 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_azure.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_azure.py @@ -626,7 +626,7 @@ async def test_chat_async_streaming( assert open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) == 36 assert open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 8 - assert open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) == 28 + assert open_ai_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) == 28 events = open_ai_span.events assert len(events) == chunk_count @@ -671,7 +671,7 @@ async def test_chat_async_streaming_with_events_with_content( assert open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) == 36 assert open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 8 - assert open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) == 28 + assert open_ai_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) == 28 events = open_ai_span.events assert len(events) == chunk_count @@ -734,7 +734,7 @@ async def test_chat_async_streaming_with_events_with_no_content( assert open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) == 36 assert open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 8 - assert open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_COMPLETION_TOKENS) == 28 + assert open_ai_span.attributes.get(SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS) == 28 events = open_ai_span.events assert len(events) == chunk_count diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat.py index 232ac6821b..e76feddc30 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_chat.py @@ -603,7 +603,7 @@ def test_chat_streaming(instrument_legacy, span_exporter, log_exporter, openai_c # check token usage attributes for stream completion_tokens = open_ai_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) prompt_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) total_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -651,7 +651,7 @@ def test_chat_streaming_with_events_with_content( # check token usage attributes for stream completion_tokens = open_ai_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) prompt_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) total_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -718,7 +718,7 @@ def test_chat_streaming_with_events_with_no_content( # check token usage attributes for stream completion_tokens = open_ai_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) prompt_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) total_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -778,7 +778,7 @@ async def test_chat_async_streaming( # check token usage attributes for stream completion_tokens = open_ai_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) prompt_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) total_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -827,7 +827,7 @@ async def test_chat_async_streaming_with_events_with_content( # check token usage attributes for stream completion_tokens = open_ai_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) prompt_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) total_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) @@ -893,7 +893,7 @@ async def test_chat_async_streaming_with_events_with_no_content( # check token usage attributes for stream completion_tokens = open_ai_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) prompt_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) total_tokens = open_ai_span.attributes.get(SpanAttributes.LLM_USAGE_TOTAL_TOKENS) diff --git a/packages/opentelemetry-instrumentation-openai/tests/traces/test_completions.py b/packages/opentelemetry-instrumentation-openai/tests/traces/test_completions.py index 8a3e775bea..6f45958e8f 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/traces/test_completions.py +++ b/packages/opentelemetry-instrumentation-openai/tests/traces/test_completions.py @@ -381,7 +381,7 @@ def test_completion_streaming( # check token usage attributes for stream completion_tokens = open_ai_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) prompt_tokens = open_ai_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS @@ -438,7 +438,7 @@ def test_completion_streaming_with_events_with_content( # check token usage attributes for stream completion_tokens = open_ai_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) prompt_tokens = open_ai_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS @@ -511,7 +511,7 @@ def test_completion_streaming_with_events_with_no_content( # check token usage attributes for stream completion_tokens = open_ai_span.attributes.get( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS ) prompt_tokens = open_ai_span.attributes.get( SpanAttributes.LLM_USAGE_PROMPT_TOKENS diff --git a/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/span_utils.py b/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/span_utils.py index a462bd312e..0fe93507bd 100644 --- a/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/span_utils.py +++ b/packages/opentelemetry-instrumentation-together/opentelemetry/instrumentation/together/span_utils.py @@ -99,7 +99,7 @@ def set_model_completion_attributes(span, response): ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens, ) _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/span_utils.py b/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/span_utils.py index 53b0bf8925..49d86fd4b2 100644 --- a/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/span_utils.py +++ b/packages/opentelemetry-instrumentation-vertexai/opentelemetry/instrumentation/vertexai/span_utils.py @@ -44,7 +44,7 @@ def set_model_input_attributes(span, kwargs, llm_model): span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get("max_output_tokens") ) _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, kwargs.get("top_p")) - _set_span_attribute(span, SpanAttributes.LLM_TOP_K, kwargs.get("top_k")) + _set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_K, kwargs.get("top_k")) _set_span_attribute( span, SpanAttributes.LLM_PRESENCE_PENALTY, kwargs.get("presence_penalty") ) @@ -79,7 +79,7 @@ def set_model_response_attributes(span, llm_model, token_usage): ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, token_usage.candidates_token_count, ) _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_bison.py b/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_bison.py index 16ceec2b44..23c24e9e17 100644 --- a/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_bison.py +++ b/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_bison.py @@ -46,7 +46,7 @@ def test_vertexai_predict(instrument_legacy, span_exporter, log_exporter): ) assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.8 assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 - assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_K] == 40 assert ( vertexai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response @@ -89,7 +89,7 @@ async def async_predict_text() -> str: ) assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.8 assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 - assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_K] == 40 assert ( vertexai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response @@ -125,7 +125,7 @@ def test_vertexai_stream(instrument_legacy, span_exporter, log_exporter): ) assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.8 assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 - assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_K] == 40 assert vertexai_span.attributes[ f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" ] == "".join(response) @@ -165,7 +165,7 @@ async def async_streaming_prediction() -> list: ) assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.8 assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 - assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_K] == 40 assert vertexai_span.attributes[ f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" ] == "".join(response) @@ -212,7 +212,7 @@ def test_vertexai_chat(instrument_legacy, span_exporter, log_exporter): ) assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.95 assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 - assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_K] == 40 assert ( vertexai_span.attributes[f"{SpanAttributes.GEN_AI_COMPLETION}.0.content"] == response @@ -259,7 +259,7 @@ def test_vertexai_chat_stream(instrument_legacy, span_exporter, log_exporter): assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_P] == 0.95 assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.8 assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 256 - assert vertexai_span.attributes[SpanAttributes.LLM_TOP_K] == 40 + assert vertexai_span.attributes[SpanAttributes.GEN_AI_REQUEST_TOP_K] == 40 assert vertexai_span.attributes[ f"{SpanAttributes.GEN_AI_COMPLETION}.0.content" ] == "".join(response) diff --git a/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_gemini.py b/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_gemini.py index cb37e71042..3b7cce0657 100644 --- a/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_gemini.py +++ b/packages/opentelemetry-instrumentation-vertexai/tests/disabled_test_gemini.py @@ -47,7 +47,7 @@ def test_vertexai_generate_content(instrument_legacy, span_exporter, log_exporte == response._raw_response.usage_metadata.prompt_token_count ) assert ( - vertexai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + vertexai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response._raw_response.usage_metadata.candidates_token_count ) assert ( @@ -96,7 +96,7 @@ def test_vertexai_generate_content_with_events_with_content( == response._raw_response.usage_metadata.prompt_token_count ) assert ( - vertexai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + vertexai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response._raw_response.usage_metadata.candidates_token_count ) @@ -156,7 +156,7 @@ def test_vertexai_generate_content_with_events_with_no_content( == response._raw_response.usage_metadata.prompt_token_count ) assert ( - vertexai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] + vertexai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == response._raw_response.usage_metadata.candidates_token_count ) diff --git a/packages/opentelemetry-instrumentation-watsonx/opentelemetry/instrumentation/watsonx/__init__.py b/packages/opentelemetry-instrumentation-watsonx/opentelemetry/instrumentation/watsonx/__init__.py index d8284c412e..e764b4329f 100644 --- a/packages/opentelemetry-instrumentation-watsonx/opentelemetry/instrumentation/watsonx/__init__.py +++ b/packages/opentelemetry-instrumentation-watsonx/opentelemetry/instrumentation/watsonx/__init__.py @@ -172,7 +172,7 @@ def set_model_input_attributes(span, instance): modelParameters.get("min_new_tokens", None), ) _set_span_attribute( - span, SpanAttributes.LLM_TOP_K, modelParameters.get("top_k", None) + span, SpanAttributes.GEN_AI_REQUEST_TOP_K, modelParameters.get("top_k", None) ) _set_span_attribute( span, @@ -212,7 +212,7 @@ def _set_model_stream_response_attributes(span, stream_response): ) _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, stream_response.get("generated_token_count"), ) total_token = stream_response.get("input_token_count") + stream_response.get( @@ -321,7 +321,7 @@ def set_model_response_attributes( if (prompt_token + completion_token) != 0: _set_span_attribute( span, - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_token, ) _set_span_attribute( diff --git a/packages/traceloop-sdk/tests/test_manual.py b/packages/traceloop-sdk/tests/test_manual.py index d3afd6f282..2f300be157 100644 --- a/packages/traceloop-sdk/tests/test_manual.py +++ b/packages/traceloop-sdk/tests/test_manual.py @@ -53,7 +53,7 @@ def test_manual_report(exporter, openai_client): ) assert open_ai_span.end_time > open_ai_span.start_time assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 15 - assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 24 + assert open_ai_span.attributes[SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] == 24 assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 39 assert ( open_ai_span.attributes[SpanAttributes.LLM_USAGE_CACHE_CREATION_INPUT_TOKENS] diff --git a/packages/traceloop-sdk/traceloop/sdk/tracing/manual.py b/packages/traceloop-sdk/traceloop/sdk/tracing/manual.py index c877117175..0fad8ed508 100644 --- a/packages/traceloop-sdk/traceloop/sdk/tracing/manual.py +++ b/packages/traceloop-sdk/traceloop/sdk/tracing/manual.py @@ -50,7 +50,7 @@ def report_usage(self, usage: LLMUsage): SpanAttributes.LLM_USAGE_PROMPT_TOKENS, usage.prompt_tokens ) self._span.set_attribute( - SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, usage.completion_tokens + SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, usage.completion_tokens ) self._span.set_attribute( SpanAttributes.LLM_USAGE_TOTAL_TOKENS, usage.total_tokens