Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
20 changes: 13 additions & 7 deletions pydantic_ai_slim/pydantic_ai/usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,19 @@ def __add__(self, other: Usage) -> Usage:

def opentelemetry_attributes(self) -> dict[str, int]:
"""Get the token limits as OpenTelemetry attributes."""
result = {
'gen_ai.usage.input_tokens': self.request_tokens,
'gen_ai.usage.output_tokens': self.response_tokens,
}
for key, value in (self.details or {}).items():
result[f'gen_ai.usage.details.{key}'] = value # pragma: no cover
return {k: v for k, v in result.items() if v}
result: dict[str, int] = {}
if self.request_tokens:
result['gen_ai.usage.input_tokens'] = self.request_tokens
if self.response_tokens:
result['gen_ai.usage.output_tokens'] = self.response_tokens
details = self.details
if details:
prefix = 'gen_ai.usage.details.'
for key, value in details.items():
# Skipping check for value since spec implies all detail values are relevant
if value:
result[prefix + key] = value
return result

def has_values(self) -> bool:
"""Whether any values are set and non-zero."""
Expand Down
9 changes: 9 additions & 0 deletions tests/test_usage_limits.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,15 @@ async def delegate_to_other_agent2(ctx: RunContext[None], sentence: str) -> int:
# confirm the usage from result2 is the sum of the usage from result1
assert result2.usage() == functools.reduce(operator.add, run_1_usages)

result1_usage = result1.usage()
result1_usage.details = {'custom1': 10, 'custom2': 20, 'custom3': 0}
assert result1_usage.opentelemetry_attributes() == {
'gen_ai.usage.input_tokens': 103,
'gen_ai.usage.output_tokens': 13,
'gen_ai.usage.details.custom1': 10,
'gen_ai.usage.details.custom2': 20,
}


async def test_multi_agent_usage_sync():
"""As in `test_multi_agent_usage_async`, with a sync tool."""
Expand Down