From 45be10a8e4802b7081f1f0caffa17673cc7d43e2 Mon Sep 17 00:00:00 2001 From: soroush5 Date: Thu, 3 Sep 2026 23:16:48 +0330 Subject: [PATCH] fix(cost): coerce None/string token counts in cost_per_token --- litellm/cost_calculator.py | 14 ++++++++++++++ tests/test_litellm/test_cost_calculator.py | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/litellm/cost_calculator.py b/litellm/cost_calculator.py index 814eaaf76f7..0be166310e0 100644 --- a/litellm/cost_calculator.py +++ b/litellm/cost_calculator.py @@ -310,6 +310,17 @@ def _transcription_usage_has_token_details( return (prompt_tokens_val > 0) or (completion_tokens_val > 0) +def _coerce_token_count(value: float | str | None) -> int: + if value is None: + return 0 + if isinstance(value, str): + try: + return int(value) + except ValueError: + return 0 + return int(value) + + def cost_per_token( model: str = "", prompt_tokens: int = 0, @@ -367,6 +378,9 @@ def cost_per_token( if model is None: raise Exception("Invalid arg. Model cannot be none.") + prompt_tokens = _coerce_token_count(prompt_tokens) + completion_tokens = _coerce_token_count(completion_tokens) + ## RECONSTRUCT USAGE BLOCK ## if usage_object is not None: usage_block = usage_object diff --git a/tests/test_litellm/test_cost_calculator.py b/tests/test_litellm/test_cost_calculator.py index f610821e06a..293ca9ac398 100644 --- a/tests/test_litellm/test_cost_calculator.py +++ b/tests/test_litellm/test_cost_calculator.py @@ -4768,3 +4768,20 @@ def test_collect_and_combine_realtime_usage_stores_partitioned_text_tokens() -> assert combined.completion_tokens_details.reasoning_tokens == 95 assert combined.completion_tokens_details.text_tokens == 38 assert combined.completion_tokens_details.audio_tokens == 0 +def test_cost_per_token_none_token_counts_cost_zero(): + prompt_cost, completion_cost = cost_per_token( + model="gpt-4o-mini", prompt_tokens=None, completion_tokens=None + ) + assert prompt_cost == 0.0 + assert completion_cost == 0.0 + + +def test_cost_per_token_string_token_counts_coerced(): + prompt_cost, completion_cost = cost_per_token( + model="gpt-4o-mini", prompt_tokens="10", completion_tokens=5 + ) + expected_prompt, expected_completion = cost_per_token( + model="gpt-4o-mini", prompt_tokens=10, completion_tokens=5 + ) + assert prompt_cost == expected_prompt + assert completion_cost == expected_completion