mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
Merge d7295c15a3 into 9071ca503e
This commit is contained in:
commit
c99a8e5817
2 changed files with 46 additions and 5 deletions
|
|
@ -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,14 +378,17 @@ def cost_per_token(
|
|||
if model is None:
|
||||
raise Exception("Invalid arg. Model cannot be none.")
|
||||
|
||||
prompt_token_count = _coerce_token_count(prompt_tokens)
|
||||
completion_token_count = _coerce_token_count(completion_tokens)
|
||||
|
||||
## RECONSTRUCT USAGE BLOCK ##
|
||||
if usage_object is not None:
|
||||
usage_block = usage_object
|
||||
else:
|
||||
usage_block = Usage(
|
||||
prompt_tokens=prompt_tokens,
|
||||
completion_tokens=completion_tokens,
|
||||
total_tokens=prompt_tokens + completion_tokens,
|
||||
prompt_tokens=prompt_token_count,
|
||||
completion_tokens=completion_token_count,
|
||||
total_tokens=prompt_token_count + completion_token_count,
|
||||
cache_creation_input_tokens=cache_creation_input_tokens,
|
||||
cache_read_input_tokens=cache_read_input_tokens,
|
||||
)
|
||||
|
|
@ -418,13 +432,13 @@ def cost_per_token(
|
|||
|
||||
# Anthropic reports prompt_tokens as input_tokens (excluding cache tokens).
|
||||
# Adjust so the helper's "prompt_tokens includes cache tokens" invariant holds.
|
||||
_normalized_prompt_tokens = float(prompt_tokens)
|
||||
_normalized_prompt_tokens = float(prompt_token_count)
|
||||
if _is_anthropic_style:
|
||||
_normalized_prompt_tokens += _cache_read_tokens + _cache_creation_tokens
|
||||
|
||||
response_cost: Final = _cost_per_token_custom_pricing_helper(
|
||||
prompt_tokens=_normalized_prompt_tokens,
|
||||
completion_tokens=completion_tokens,
|
||||
completion_tokens=completion_token_count,
|
||||
response_time_ms=response_time_ms,
|
||||
cached_tokens=_cache_read_tokens,
|
||||
cache_creation_tokens=_cache_creation_tokens,
|
||||
|
|
|
|||
|
|
@ -4768,3 +4768,30 @@ 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
|
||||
|
||||
|
||||
def test_cost_per_token_garbage_string_counts_cost_zero():
|
||||
prompt_cost, completion_cost = cost_per_token(
|
||||
model="gpt-4o-mini", prompt_tokens="abc", completion_tokens=5
|
||||
)
|
||||
expected_prompt, _ = cost_per_token(
|
||||
model="gpt-4o-mini", prompt_tokens=0, completion_tokens=5
|
||||
)
|
||||
assert prompt_cost == expected_prompt
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue