From e62d434debd3b08dd2384a3fc4796e29b1c08e16 Mon Sep 17 00:00:00 2001 From: Gyanu Date: Sun, 23 Aug 2026 12:34:44 +0530 Subject: [PATCH] fix(spend): freeze matching-deployment accumulators for type discipline --- litellm/proxy/spend_tracking/savings.py | 65 +++++++++++++++---------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/litellm/proxy/spend_tracking/savings.py b/litellm/proxy/spend_tracking/savings.py index d56c05c23d5..823a7a5b34e 100644 --- a/litellm/proxy/spend_tracking/savings.py +++ b/litellm/proxy/spend_tracking/savings.py @@ -8,7 +8,7 @@ are known) and summed into the daily tables; tokens cannot be priced after they have been aggregated across models. """ -from collections.abc import Callable, Mapping +from collections.abc import Callable, Mapping, Sequence from typing import ( TYPE_CHECKING, Final, @@ -153,9 +153,9 @@ def _cost_map_deployment_info(deployment_id: str | None) -> ModelInfo | None: return None info = litellm.model_cost.get(deployment_id) if isinstance(info, dict) and info.get("input_cost_per_token") is not None: - return cast( + return cast( # cast-ok: model_cost dict already checked for input_cost_per_token; same shape router uses ModelInfo, info - ) # cast-ok: model_cost dict already checked for input_cost_per_token; same shape router uses + ) return None @@ -179,47 +179,54 @@ def _matching_priced_deployments( router: "Router | None", identity: _ModelIdentity | None, logged_model: str, -) -> list[ModelInfo]: +) -> tuple[ModelInfo, ...]: """Priced router rows that could be this spend log, or empty if we cannot tell.""" if router is None: - return [] + return () try: - deployments = router.get_model_list() or [] + deployments = router.get_model_list() or () except Exception as e: # noqa: BLE001 # a dashboard metric must not fail the spend write verbose_proxy_logger.debug("savings: cannot list deployments (%s)", e) - return [] + return () - priced: list[ModelInfo] = [] - seen_ids: set[str] = set() + priced: tuple[ModelInfo, ...] = () + seen_ids: tuple[str, ...] = () for dep in deployments: if not isinstance(dep, dict): continue - dep_id = (dep.get("model_info") or {}).get("id") + raw_info = dep.get("model_info") + dep_id = raw_info.get("id") if isinstance(raw_info, dict) else None if not isinstance(dep_id, str) or dep_id in seen_ids: continue - params = dep.get("litellm_params") or {} + raw_params = dep.get("litellm_params") + if isinstance(raw_params, dict): + dep_model = str(raw_params.get("model") or "") + dep_provider = raw_params.get("custom_llm_provider") + else: + dep_model = "" + dep_provider = None if not _deployment_matches_logged_model( - dep_model=str(params.get("model") or ""), - dep_provider=params.get("custom_llm_provider"), + dep_model=dep_model, + dep_provider=dep_provider, public_name=dep.get("model_name"), identity=identity, logged_model=logged_model, ): continue - seen_ids.add(dep_id) + seen_ids = (*seen_ids, dep_id) info = _cost_map_deployment_info(dep_id) or _effective_model_info(router, dep_id, logged_model) if _has_input_price(info): - priced.append(info) + priced = (*priced, info) return priced def _unique_by_rate( - priced: list[ModelInfo], + priced: Sequence[ModelInfo], rate_key: Callable[[ModelInfo], object], ) -> ModelInfo | None: if not priced: return None - fingerprints = {rate_key(info) for info in priced} + fingerprints = frozenset(rate_key(info) for info in priced) return priced[0] if len(fingerprints) == 1 else None @@ -231,21 +238,27 @@ def _pricing_for_savings( rate_key: Callable[[ModelInfo], object] = _savings_rate_fingerprint, ) -> ModelInfo | None: """Deployment rate first, public rate only when it actually has a price.""" - logged = model or "" - candidates: list[ModelInfo | None] = [ - _cost_map_deployment_info(model_id), - _effective_model_info(router, model_id, logged), - ] - if not model_id: + logged: Final = model or "" + extra: Final[tuple[ModelInfo, ...]] + if model_id: + extra = () + else: priced = _matching_priced_deployments(router, identity, logged) - if priced: + if not priced: + extra = () + else: unique = _unique_by_rate(priced, rate_key) if unique is None: # Matching deployments disagree. The public list price is not a # substitute — it can match none of them. return None - candidates.append(unique) - candidates.append(_model_info(identity) if identity else None) + extra = (unique,) + candidates: Final = ( + _cost_map_deployment_info(model_id), + _effective_model_info(router, model_id, logged), + *extra, + _model_info(identity) if identity else None, + ) for candidate in candidates: if _has_input_price(candidate): return candidate