diff --git a/litellm/proxy/spend_tracking/currency_response.py b/litellm/proxy/spend_tracking/currency_response.py index 138a32f8a1d..d4324c23450 100644 --- a/litellm/proxy/spend_tracking/currency_response.py +++ b/litellm/proxy/spend_tracking/currency_response.py @@ -114,7 +114,7 @@ def _display_values(value: object, rate: float) -> object: return { **{key: _display_values(item, rate) for key, item in values.items()}, **{ - f"{key}_display": item * rate + f"{key}_display": round(item * rate, 10) for key, item in values.items() if key in MONEY_FIELDS and isinstance(item, (int, float)) and not isinstance(item, bool) }, diff --git a/tests/unit/proxy/spend_tracking/test_currency_response.py b/tests/unit/proxy/spend_tracking/test_currency_response.py index 96500906dd0..8945893d0e4 100644 --- a/tests/unit/proxy/spend_tracking/test_currency_response.py +++ b/tests/unit/proxy/spend_tracking/test_currency_response.py @@ -94,6 +94,15 @@ def test_usd_non_json_streaming_malformed_and_unlisted_responses_are_untouched() assert "x-litellm-display-currency" not in eur.get(path).headers +def test_display_values_are_rounded_without_changing_usd_amounts() -> None: + client: Final = _client(Currency(code="EUR", usd_rate=0.92)) + info: Final = client.get("/key/info").json() + assert info["spend"] == 10 + assert info["spend_display"] == 9.2 + assert info["nested"][0]["max_budget_display"] == 18.4 + assert client.get("/budget/list").json()[0]["soft_budget_display"] == 4.6 + + @pytest.mark.asyncio async def test_usd_passes_the_original_send_through() -> None: async def send(message: Message) -> None: