mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-17 23:51:30 +00:00
fix(spend): normalize legacy guardrail shapes and float token stats in compression savings reader
This commit is contained in:
parent
c91c6d0e85
commit
be609cff3a
3 changed files with 31 additions and 6 deletions
|
|
@ -11,6 +11,7 @@ from fastapi import HTTPException
|
|||
|
||||
import litellm
|
||||
from httpx import Response as HttpxResponse
|
||||
from litellm.proxy.spend_tracking.compression_savings import HEADROOM_GUARDRAIL_PROVIDER
|
||||
from typing_extensions import TypeGuard
|
||||
|
||||
from litellm._logging import verbose_proxy_logger
|
||||
|
|
@ -487,7 +488,7 @@ class HeadroomGuardrail(CustomGuardrail):
|
|||
guardrail_json_response=stats,
|
||||
request_data=request_data,
|
||||
guardrail_status="success",
|
||||
guardrail_provider="headroom",
|
||||
guardrail_provider=HEADROOM_GUARDRAIL_PROVIDER,
|
||||
start_time=start_time,
|
||||
end_time=end_time,
|
||||
duration=end_time - start_time,
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ HEADROOM_GUARDRAIL_PROVIDER = "headroom"
|
|||
|
||||
|
||||
def _saved_tokens_or_zero(value: object) -> int:
|
||||
if isinstance(value, bool) or not isinstance(value, int):
|
||||
if isinstance(value, bool) or not isinstance(value, (int, float)):
|
||||
return 0
|
||||
if value < 0:
|
||||
return 0
|
||||
return value
|
||||
return int(value)
|
||||
|
||||
|
||||
def _tokens_saved_from_stats(stats: object) -> int:
|
||||
|
|
@ -32,9 +32,10 @@ def _headroom_entry_saved_tokens(entry: object) -> int:
|
|||
|
||||
|
||||
def _headroom_saved_tokens(guardrail_information: object) -> int:
|
||||
if not isinstance(guardrail_information, list):
|
||||
entries = [guardrail_information] if isinstance(guardrail_information, Mapping) else guardrail_information
|
||||
if not isinstance(entries, list):
|
||||
return 0
|
||||
return sum(_headroom_entry_saved_tokens(entry) for entry in guardrail_information)
|
||||
return sum(_headroom_entry_saved_tokens(entry) for entry in entries)
|
||||
|
||||
|
||||
def extract_compression_saved_tokens(metadata: Mapping[str, object]) -> int:
|
||||
|
|
@ -52,6 +53,8 @@ def extract_compression_saved_tokens(metadata: Mapping[str, object]) -> int:
|
|||
different stages (guardrail pre-call vs deployment pre-call), so when both
|
||||
fire on one request their measured savings are independent and additive;
|
||||
summing them never double-counts. Malformed or missing values contribute 0.
|
||||
A bare dict ``guardrail_information`` is treated as a single entry, matching
|
||||
the spend-log redactor's normalization of that legacy shape.
|
||||
"""
|
||||
return _tokens_saved_from_stats(metadata.get("compression_savings")) + _headroom_saved_tokens(
|
||||
metadata.get("guardrail_information")
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ def test_non_headroom_guardrail_entries_ignored():
|
|||
{},
|
||||
{"tokens_saved": None},
|
||||
{"tokens_saved": "7000"},
|
||||
{"tokens_saved": 12.5},
|
||||
{"tokens_saved": True},
|
||||
{"tokens_saved": -5},
|
||||
{"tokens_before": 100, "tokens_after": 50},
|
||||
|
|
@ -108,3 +107,25 @@ def test_valid_headroom_entry_survives_alongside_malformed_ones():
|
|||
]
|
||||
}
|
||||
assert extract_compression_saved_tokens(metadata) == 600
|
||||
|
||||
|
||||
def test_float_tokens_saved_counts_as_int():
|
||||
entry = {"guardrail_provider": "headroom", "guardrail_response": {"tokens_saved": 600.0}}
|
||||
assert extract_compression_saved_tokens({"guardrail_information": [entry]}) == 600
|
||||
assert extract_compression_saved_tokens({"compression_savings": {"tokens_saved": 7000.0}}) == 7000
|
||||
assert extract_compression_saved_tokens({"compression_savings": {"tokens_saved": 12.5}}) == 12
|
||||
|
||||
|
||||
def test_bare_dict_guardrail_information_counts_as_single_entry():
|
||||
assert extract_compression_saved_tokens({"guardrail_information": HEADROOM_ENTRY}) == 600
|
||||
|
||||
|
||||
def test_headroom_writer_and_reader_share_provider_slug():
|
||||
from litellm.proxy.guardrails.guardrail_hooks.headroom.headroom import (
|
||||
HEADROOM_GUARDRAIL_PROVIDER as writer_slug,
|
||||
)
|
||||
from litellm.proxy.spend_tracking.compression_savings import (
|
||||
HEADROOM_GUARDRAIL_PROVIDER as reader_slug,
|
||||
)
|
||||
|
||||
assert writer_slug == reader_slug == "headroom"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue