fix(cost): keep the provider's usage.cost marker through the metadata pass

ResponseMetadata builds a fresh hidden-params dict for a reply that arrived with none, so the marker the
stamp wrote was dropped by apply() and a second pricing pass applied the margin twice
This commit is contained in:
devin-ai-integration[bot] 2026-10-27 02:19:19 +00:00
parent 15670c78e8
commit de17bca0ac
2 changed files with 39 additions and 2 deletions

View file

@ -9,7 +9,11 @@ from pydantic import TypeAdapter, ValidationError
import litellm
from litellm.constants import LITELLM_DETAILED_TIMING
from litellm.litellm_core_utils.core_helpers import get_litellm_metadata_from_kwargs, process_response_headers
from litellm.litellm_core_utils.hidden_params import stamp_billable_usage_cost
from litellm.litellm_core_utils.hidden_params import (
USAGE_COST_BEFORE_LITELLM_STAMP,
get_hidden_params,
stamp_billable_usage_cost,
)
from litellm.litellm_core_utils.llm_response_utils.get_api_base import get_api_base
from litellm.litellm_core_utils.logging_utils import LiteLLMLoggingObject
from litellm.types.llms.openai import ResponseAPIUsage, ResponsesAPIResponse
@ -197,7 +201,12 @@ class ResponseMetadata:
return
if getattr(usage, "cost", None) is None and not litellm.include_cost_in_streaming_usage:
return
stamp_billable_usage_cost(self.result, usage, response_cost)
if stamp_billable_usage_cost(self.result, usage, response_cost) is None:
return
stamped: Final = get_hidden_params(self.result)
if stamped is None or USAGE_COST_BEFORE_LITELLM_STAMP not in stamped:
return
self._update_hidden_params({USAGE_COST_BEFORE_LITELLM_STAMP: stamped[USAGE_COST_BEFORE_LITELLM_STAMP]})
def _update_hidden_params(self, new_params: Mapping[str, object]) -> None:
"""

View file

@ -10846,6 +10846,34 @@ def test_include_cost_in_streaming_usage_puts_the_bill_on_a_plain_reply_without_
assert logging_obj.response_cost_calculator(result=response, ignore_stamped_cost=True) == pytest.approx(bill)
def test_a_bill_stamped_on_a_plain_reply_survives_the_metadata_pass_for_a_second_pricing(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""The metadata pass installs a fresh hidden-params dict on a reply that arrived with none, which dropped the
provider's figure the stamp keeps and let a second pricing pass apply the margin twice."""
monkeypatch.setattr(litellm, "cost_margin_config", {"global": {"percentage": 0.5}})
monkeypatch.delitem(litellm.model_cost, _REPORTED_COST_FIXTURE_MODEL, raising=False)
logging_obj: Final = _reported_cost_logging(False, {})
response: Final = ModelResponse(
id="chatcmpl-reported",
model="reported-cost-fixture",
choices=[Choices(index=0, message=Message(role="assistant", content="hi"), finish_reason="stop")],
usage=_reported_cost_usage(),
)
update_response_metadata(
result=response,
logging_obj=logging_obj,
model=_REPORTED_COST_FIXTURE_MODEL,
kwargs={},
start_time=datetime.datetime(2026, 1, 1),
end_time=datetime.datetime(2026, 1, 1, 0, 0, 1),
)
assert response.usage is not None and response.usage.cost == pytest.approx(0.037 * 1.5)
assert logging_obj.response_cost_calculator(result=response, ignore_stamped_cost=True) == pytest.approx(0.037 * 1.5)
def test_provider_reported_usage_cost_splits_input_and_output_by_the_token_math_ratio(
monkeypatch: pytest.MonkeyPatch,
) -> None: