Skip to content

fix(instrumentation): updated GenAI token usage attributes #3138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
)

Expand Down Expand Up @@ -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"]
)

Expand Down Expand Up @@ -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"]
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -189,17 +189,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -377,17 +377,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -507,17 +507,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -598,17 +598,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -792,17 +792,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -925,17 +925,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -1019,17 +1019,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -1218,17 +1218,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -1352,17 +1352,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -1447,17 +1447,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down Expand Up @@ -1657,17 +1657,17 @@ 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
assert cache_read_span.attributes["gen_ai.usage.cache_creation_input_tokens"] == 0

# 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()
Expand Down
Loading