mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-16 23:41:43 +00:00
fix(realtime): carry audio output tokens into response.done usage so Gemini Live native audio bills at the audio rate
This commit is contained in:
parent
172e3aceaf
commit
449c091391
3 changed files with 53 additions and 0 deletions
|
|
@ -2661,6 +2661,7 @@ class LiteLLMCompletionResponsesConfig:
|
||||||
optional_output_details: Final[dict[str, int]] = {
|
optional_output_details: Final[dict[str, int]] = {
|
||||||
field: value
|
field: value
|
||||||
for field, value in (
|
for field, value in (
|
||||||
|
("audio_tokens", getattr(completion_details, "audio_tokens", None)),
|
||||||
("text_tokens", getattr(completion_details, "text_tokens", None)),
|
("text_tokens", getattr(completion_details, "text_tokens", None)),
|
||||||
("image_tokens", getattr(completion_details, "image_tokens", None)),
|
("image_tokens", getattr(completion_details, "image_tokens", None)),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1258,6 +1258,8 @@ class ResponsesAPIRequestParams(ResponsesAPIOptionalRequestParams, total=False):
|
||||||
|
|
||||||
|
|
||||||
class OutputTokensDetails(BaseLiteLLMOpenAIResponseObject):
|
class OutputTokensDetails(BaseLiteLLMOpenAIResponseObject):
|
||||||
|
audio_tokens: int | None = None
|
||||||
|
|
||||||
reasoning_tokens: int | None = None
|
reasoning_tokens: int | None = None
|
||||||
|
|
||||||
text_tokens: int | None = None
|
text_tokens: int | None = None
|
||||||
|
|
|
||||||
|
|
@ -1864,3 +1864,53 @@ def test_map_openai_params_drops_stock_voice_case_insensitively():
|
||||||
|
|
||||||
passthrough = cfg.map_openai_params(optional_params={}, non_default_params={"voice": "Kore"})
|
passthrough = cfg.map_openai_params(optional_params={}, non_default_params={"voice": "Kore"})
|
||||||
assert passthrough["generationConfig"]["speechConfig"]["voiceConfig"]["prebuiltVoiceConfig"]["voiceName"] == "Kore"
|
assert passthrough["generationConfig"]["speechConfig"]["voiceConfig"]["prebuiltVoiceConfig"]["voiceName"] == "Kore"
|
||||||
|
|
||||||
|
|
||||||
|
def test_gemini_response_done_bills_audio_output_tokens_at_audio_rate(monkeypatch):
|
||||||
|
"""Regression for the Gemini Live AUDIO output breakdown: responseTokensDetails
|
||||||
|
must survive into response.done usage and bill at output_cost_per_audio_token,
|
||||||
|
not the text rate."""
|
||||||
|
from litellm.cost_calculator import (
|
||||||
|
RealtimeAPITokenUsageProcessor,
|
||||||
|
handle_realtime_stream_cost_calculation,
|
||||||
|
)
|
||||||
|
|
||||||
|
monkeypatch.setenv("LITELLM_LOCAL_MODEL_COST_MAP", "True")
|
||||||
|
monkeypatch.setattr(litellm, "model_cost", litellm.get_model_cost_map(url=""))
|
||||||
|
|
||||||
|
config = GeminiRealtimeConfig()
|
||||||
|
done_event = config.transform_response_done_event(
|
||||||
|
message={
|
||||||
|
"serverContent": {"turnComplete": True},
|
||||||
|
"usageMetadata": {
|
||||||
|
"promptTokenCount": 377,
|
||||||
|
"responseTokenCount": 51,
|
||||||
|
"totalTokenCount": 428,
|
||||||
|
"promptTokensDetails": [{"modality": "TEXT", "tokenCount": 377}],
|
||||||
|
"responseTokensDetails": [{"modality": "AUDIO", "tokenCount": 51}],
|
||||||
|
"thoughtsTokenCount": 37,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
current_response_id="resp_lit6277",
|
||||||
|
current_conversation_id="conv_lit6277",
|
||||||
|
output_items=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
usage = done_event["response"]["usage"]
|
||||||
|
assert usage["output_tokens_details"]["audio_tokens"] == 51
|
||||||
|
assert usage["output_token_details"]["audio_tokens"] == 51
|
||||||
|
|
||||||
|
results = [done_event]
|
||||||
|
combined_usage = RealtimeAPITokenUsageProcessor.collect_and_combine_usage_from_realtime_stream_results(
|
||||||
|
results=results,
|
||||||
|
)
|
||||||
|
assert combined_usage.completion_tokens_details is not None
|
||||||
|
assert combined_usage.completion_tokens_details.audio_tokens == 51
|
||||||
|
|
||||||
|
cost = handle_realtime_stream_cost_calculation(
|
||||||
|
results=results,
|
||||||
|
combined_usage_object=combined_usage,
|
||||||
|
custom_llm_provider="gemini",
|
||||||
|
litellm_model_name="gemini-2.5-flash-native-audio-preview-12-2025",
|
||||||
|
)
|
||||||
|
assert cost == pytest.approx(377 * 5e-07 + 51 * 1.2e-05 + 37 * 2e-06)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue