From 964c9a3ca298fc96aa6daa7cda3b914712c23f18 Mon Sep 17 00:00:00 2001 From: Marty Sullivan Date: Sun, 16 Aug 2026 17:15:37 -0400 Subject: [PATCH] fix(batches): resolve the deployment model from model_call_details On a batch retrieve both self.model and litellm_params[model] come back None, so the cost model fell through to the provider's own response model (an Anthropic id like claude-opus-4-5-20251101) which does not resolve under a bedrock provider, leaving bedrock batches at $0 with correct usage. model_call_details carries the deployment's provider-qualified model (bedrock/global.anthropic.claude-opus-4-5-20251101-v1:0), confirmed by instrumenting a live retrieve, so it is preferred with the previous two sources kept as fallbacks. --- litellm/litellm_core_utils/litellm_logging.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py index 5d65288faa2..32143899125 100644 --- a/litellm/litellm_core_utils/litellm_logging.py +++ b/litellm/litellm_core_utils/litellm_logging.py @@ -583,13 +583,17 @@ class Logging(LiteLLMLoggingBaseClass): def get_deployment_model_for_cost(self) -> str | None: """The provider-qualified model to price against. - self.model can be the router's model_group alias, which no cost map - resolves, so the deployment's own litellm_params model wins when present. + On a batch retrieve both self.model and litellm_params["model"] can be + unset, and self.model can otherwise carry the router's model_group alias, + which no cost map resolves. model_call_details holds the deployment's own + provider-qualified model, so it is preferred. """ - deployment_model: Final = self.litellm_params.get("model") if hasattr(self, "litellm_params") else None - if isinstance(deployment_model, str) and deployment_model: - return deployment_model - return self.model + candidates: Final = ( + (self.model_call_details or {}).get("model") if hasattr(self, "model_call_details") else None, + self.litellm_params.get("model") if hasattr(self, "litellm_params") else None, + self.model, + ) + return next((candidate for candidate in candidates if isinstance(candidate, str) and candidate), None) def get_router_deployment_model_info(self) -> ModelInfo | None: """Pricing the router registered under this deployment's model_info.id.