mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-12 08:42:18 +00:00
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:
parent
15670c78e8
commit
de17bca0ac
2 changed files with 39 additions and 2 deletions
|
|
@ -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:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue