This commit is contained in:
Anuj ojha 2026-09-12 23:53:09 -07:00 committed by GitHub
commit 409397d623
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 40 additions and 1 deletions

View file

@ -1496,7 +1496,13 @@ def completion_cost(
video_resolution=video_resolution,
)
elif call_type in _SPEECH_CALL_TYPES:
prompt_characters = litellm.utils._count_characters(text=prompt)
# Vertex AI bills TTS characters excluding whitespace; every other
# character-priced TTS provider (OpenAI, Azure, ElevenLabs, Groq,
# Minimax, AWS Polly) bills the raw character count.
if custom_llm_provider == "vertex_ai":
prompt_characters = litellm.utils._count_characters(text=prompt)
else:
prompt_characters = len(prompt)
elif call_type in _TRANSCRIPTION_CALL_TYPES:
# Check _hidden_params first (duration stored there to
# avoid polluting the response body), then fall back to

View file

@ -863,6 +863,39 @@ def test_completion_cost_tts(model):
assert cost > 0
@pytest.mark.parametrize("model", ["tts-1", "azure/tts-1"])
def test_completion_cost_tts_bills_whitespace_characters(model):
"""
Non-Vertex TTS providers (OpenAI, Azure, ElevenLabs, Groq, Minimax, AWS Polly)
bill on the raw character count, including whitespace. Only Vertex AI's
character-counting convention excludes whitespace. Regression test for a bug
where every TTS provider incorrectly had whitespace stripped before billing,
undercounting cost for inputs containing spaces.
"""
os.environ["LITELLM_LOCAL_MODEL_COST_MAP"] = "True"
litellm.model_cost = litellm.get_model_cost_map(url="")
prompt_with_whitespace = "a b c d e" # 9 chars, 4 of them whitespace
prompt_without_whitespace = "abcde" # 5 chars, matches non-whitespace count above
cost_with_whitespace = completion_cost(
model=model,
prompt=prompt_with_whitespace,
call_type="speech",
)
cost_without_whitespace = completion_cost(
model=model,
prompt=prompt_without_whitespace,
call_type="speech",
)
input_cost_per_character = litellm.model_cost[model]["input_cost_per_character"]
assert cost_with_whitespace == pytest.approx(len(prompt_with_whitespace) * input_cost_per_character)
# billing must scale with the raw string length, not the whitespace-stripped length
assert cost_with_whitespace > cost_without_whitespace
def test_completion_cost_anthropic():
"""
model_name: claude-3-haiku-20240307