fix(logging): preserve pass-through endpoint response_cost in async_success_handler

Two places in the logging pipeline were overwriting response_cost that
pass-through handlers (Gemini/Vertex) had already calculated:

1. _process_hidden_params_and_response_cost fell through to
   _response_cost_calculator which returns None for pass-through calls
2. async_success_handler pass-through branch unconditionally set
   response_cost = None (introduced in PR #19887)

Now both places check if response_cost is already set before overwriting.
This commit is contained in:
Ishaan Jaffer 2026-02-21 14:59:35 -08:00
parent d427ff6705
commit 3c01a943c7

View file

@ -1636,6 +1636,10 @@ class Logging(LiteLLMLoggingBaseClass):
self.model_call_details["response_cost"] = 0.0
elif "response_cost" in hidden_params:
self.model_call_details["response_cost"] = hidden_params["response_cost"]
elif self.model_call_details.get("response_cost") is not None:
# Preserve response_cost if already calculated (e.g., by pass-through
# handlers like Gemini/Vertex which call completion_cost directly)
pass
else:
self.model_call_details["response_cost"] = self._response_cost_calculator(
result=logging_result
@ -2496,23 +2500,29 @@ class Logging(LiteLLMLoggingBaseClass):
self.model_call_details["async_complete_streaming_response"] = result
# cost calculation not possible for pass-through
self.model_call_details["response_cost"] = None
# Only set response_cost to None if not already calculated by
# pass-through handlers (e.g. Gemini/Vertex handlers already
# compute cost via completion_cost)
if self.model_call_details.get("response_cost") is None:
self.model_call_details["response_cost"] = None
## STANDARDIZED LOGGING PAYLOAD
self.model_call_details[
"standard_logging_object"
] = self._build_standard_logging_payload(
result, start_time, end_time
)
# print standard logging payload
if (
standard_logging_payload := self.model_call_details.get(
# Only build standard_logging_object if not already built by
# _success_handler_helper_fn
if self.model_call_details.get("standard_logging_object") is None:
## STANDARDIZED LOGGING PAYLOAD
self.model_call_details[
"standard_logging_object"
] = self._build_standard_logging_payload(
result, start_time, end_time
)
) is not None:
emit_standard_logging_payload(standard_logging_payload)
# print standard logging payload
if (
standard_logging_payload := self.model_call_details.get(
"standard_logging_object"
)
) is not None:
emit_standard_logging_payload(standard_logging_payload)
callbacks = self.get_combined_callback_list(
dynamic_success_callbacks=self.dynamic_async_success_callbacks,
global_callbacks=litellm._async_success_callback,