diff --git a/litellm/cost_calculator.py b/litellm/cost_calculator.py index 28cda2daa77..42a7fb0bb02 100644 --- a/litellm/cost_calculator.py +++ b/litellm/cost_calculator.py @@ -1505,6 +1505,12 @@ def _response_time_ms_for_cost( return 0.0 +def _breakdown_total(litellm_logging_obj: LitellmLoggingObject | None) -> float | None: + breakdown: Final[object] = getattr(litellm_logging_obj, "cost_breakdown", None) + total: Final[object] = breakdown.get("total_cost") if isinstance(breakdown, Mapping) else None + return float(total) if isinstance(total, (int, float)) and not isinstance(total, bool) else None + + def _adjusted_provider_billed_cost( reported_cost: float, custom_llm_provider: str | None, @@ -2334,14 +2340,15 @@ def response_cost_calculator( ) provider_response_cost: Final = get_response_cost_from_hidden_params(hidden_params) if provider_response_cost is not None and not custom_pricing: - _store_cost_breakdown_in_logging_obj( - litellm_logging_obj=litellm_logging_obj, - prompt_tokens_cost_usd_dollar=0.0, - completion_tokens_cost_usd_dollar=provider_response_cost, - cost_for_built_in_tools_cost_usd_dollar=0.0, - total_cost_usd_dollar=provider_response_cost, - original_cost=provider_response_cost, - ) + if _breakdown_total(litellm_logging_obj) != provider_response_cost: + _store_cost_breakdown_in_logging_obj( + litellm_logging_obj=litellm_logging_obj, + prompt_tokens_cost_usd_dollar=0.0, + completion_tokens_cost_usd_dollar=provider_response_cost, + cost_for_built_in_tools_cost_usd_dollar=0.0, + total_cost_usd_dollar=provider_response_cost, + original_cost=provider_response_cost, + ) return provider_response_cost response_cost = completion_cost( diff --git a/litellm/litellm_core_utils/core_helpers.py b/litellm/litellm_core_utils/core_helpers.py index 83e9de1378b..31230d4e8d1 100644 --- a/litellm/litellm_core_utils/core_helpers.py +++ b/litellm/litellm_core_utils/core_helpers.py @@ -1028,7 +1028,8 @@ def mark_usage_cost_as_litellm_bill(response: object, bill: float) -> None: so ``billed_usage_cost`` does not read it back as the upstream's charge on a later pricing pass.""" hidden: Final[object] = getattr(response, "_hidden_params", None) if isinstance(hidden, dict): - cast(dict[str, object], hidden).update({"response_cost": bill, LITELLM_BILLED_USAGE_COST: bill}) + hidden_params: Final = cast(dict[str, object], hidden) # cast-ok: hidden params ride on the response as a dict + hidden_params.update({"response_cost": bill, LITELLM_BILLED_USAGE_COST: bill}) def _usage_cost_is_litellm_bill(response: object) -> bool: