fix(responses): forward output audio_tokens into completion usage details

Pass audio_tokens from output_tokens_details into CompletionTokensDetailsWrapper
so cost can use output_cost_per_audio_token. Support dict output details like
prompt path. Extend tests for Realtime and mixed completion audio.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Liam McDonald 2026-05-12 13:20:36 -07:00
parent e347ddeb75
commit 8a3c56786a
2 changed files with 22 additions and 9 deletions

View file

@ -958,13 +958,23 @@ class ResponseAPILoggingUtils:
response_api_usage, "output_tokens_details", None
)
if output_tokens_details:
completion_tokens_details = CompletionTokensDetailsWrapper(
reasoning_tokens=getattr(
output_tokens_details, "reasoning_tokens", None
),
image_tokens=getattr(output_tokens_details, "image_tokens", None),
text_tokens=getattr(output_tokens_details, "text_tokens", None),
)
if isinstance(output_tokens_details, dict):
completion_tokens_details = CompletionTokensDetailsWrapper(
**output_tokens_details
)
else:
completion_tokens_details = CompletionTokensDetailsWrapper(
reasoning_tokens=getattr(
output_tokens_details, "reasoning_tokens", None
),
image_tokens=getattr(
output_tokens_details, "image_tokens", None
),
text_tokens=getattr(output_tokens_details, "text_tokens", None),
audio_tokens=getattr(
output_tokens_details, "audio_tokens", None
),
)
chat_usage = Usage(
prompt_tokens=prompt_tokens,

View file

@ -327,7 +327,8 @@ class TestResponseAPILoggingUtils:
"output_tokens_details": {
"reasoning_tokens": 30,
"image_tokens": 100,
"text_tokens": 70,
"text_tokens": 50,
"audio_tokens": 20,
},
}
@ -346,7 +347,8 @@ class TestResponseAPILoggingUtils:
assert result.completion_tokens_details is not None
assert result.completion_tokens_details.reasoning_tokens == 30
assert result.completion_tokens_details.image_tokens == 100
assert result.completion_tokens_details.text_tokens == 70
assert result.completion_tokens_details.text_tokens == 50
assert result.completion_tokens_details.audio_tokens == 20
def test_transform_response_api_usage_with_realtime_keys(self):
"""Realtime input_token_details / output_token_details normalize for Usage."""
@ -375,6 +377,7 @@ class TestResponseAPILoggingUtils:
assert result.completion_tokens_details is not None
assert result.completion_tokens_details.text_tokens == 12
assert result.completion_tokens_details.audio_tokens == 8
def test_transform_response_api_usage_tokens_details_keep_values(self):
"""Keeps input_tokens_details / output_tokens_details when singular keys are also present."""