mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
Merge 486a7e33b6 into eb0e3f8c18
This commit is contained in:
commit
e33ebab5a7
2 changed files with 44 additions and 0 deletions
|
|
@ -390,6 +390,24 @@ class HeadroomGuardrail(CustomGuardrail):
|
|||
value: Final = headers.get(BYPASS_HEADER)
|
||||
return str(value).lower() == "true"
|
||||
|
||||
def _record_nothing_to_compress(self, request_data: dict[str, object]) -> None:
|
||||
"""Log a zero-savings run when every message is protected.
|
||||
|
||||
Without an entry, a request headroom looked at and found nothing to
|
||||
compress is indistinguishable in the spend logs and on the cost
|
||||
optimization dashboard from one where headroom never ran at all.
|
||||
"""
|
||||
now = time.time()
|
||||
self.add_standard_logging_guardrail_information_to_request_data(
|
||||
guardrail_json_response={"tokens_before": 0, "tokens_after": 0, "tokens_saved": 0},
|
||||
request_data=request_data,
|
||||
guardrail_status="success",
|
||||
guardrail_provider=HEADROOM_GUARDRAIL_PROVIDER,
|
||||
start_time=now,
|
||||
end_time=now,
|
||||
duration=0.0,
|
||||
)
|
||||
|
||||
def _request_headers(self) -> dict[str, str]:
|
||||
headers: Final[dict[str, str]] = {"Content-Type": "application/json"}
|
||||
if self.headroom_api_key:
|
||||
|
|
@ -643,6 +661,7 @@ class HeadroomGuardrail(CustomGuardrail):
|
|||
protected_indices: Final = _protected_indices(messages)
|
||||
compressible: Final = [m for i, m in enumerate(messages) if i not in protected_indices]
|
||||
if not compressible:
|
||||
self._record_nothing_to_compress(request_data)
|
||||
return inputs
|
||||
|
||||
model: Final = self.headroom_model or request_data.get("model")
|
||||
|
|
|
|||
|
|
@ -2021,6 +2021,31 @@ async def test_nothing_compressible_returns_inputs_untouched(guardrail: Headroom
|
|||
assert result is inputs
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_nothing_compressible_is_logged_as_a_zero_savings_run(guardrail: HeadroomGuardrail):
|
||||
"""A single-turn request never reaches /v1/compress, so without an entry the
|
||||
cost optimization dashboard cannot tell it apart from a request headroom was
|
||||
never applied to; both read as no compression at all."""
|
||||
request_data: dict = {"model": "gpt-4o"}
|
||||
inputs = GenericGuardrailAPIInputs(
|
||||
texts=["A" * 5000],
|
||||
structured_messages=[
|
||||
{"role": "system", "content": "sys"},
|
||||
{"role": "user", "content": "A" * 5000},
|
||||
],
|
||||
)
|
||||
|
||||
with patch.object(guardrail.async_handler, "post", new_callable=AsyncMock):
|
||||
await guardrail.apply_guardrail(inputs=inputs, request_data=request_data, input_type="request")
|
||||
|
||||
entries = _recorded_guardrail_entries(request_data)
|
||||
assert len(entries) == 1
|
||||
assert entries[0]["guardrail_provider"] == "headroom"
|
||||
assert entries[0]["guardrail_status"] == "success"
|
||||
assert entries[0]["guardrail_response"] == {"tokens_before": 0, "tokens_after": 0, "tokens_saved": 0}
|
||||
assert extract_compression_saved_tokens({"guardrail_information": entries}) == 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fail_open_returns_the_caller_inputs_object():
|
||||
"""Translation handlers detect a rewrite by object identity, so a request
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue