From 486a7e33b6d31f64712418cae8216570a2dcda62 Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2026 01:32:35 +0000 Subject: [PATCH] fix(headroom): log a zero-savings run when nothing is compressible --- .../guardrail_hooks/headroom/headroom.py | 19 ++++++++++++++ .../guardrail_hooks/test_headroom.py | 25 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/litellm/proxy/guardrails/guardrail_hooks/headroom/headroom.py b/litellm/proxy/guardrails/guardrail_hooks/headroom/headroom.py index 04ed5868e58..164fc4bd117 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/headroom/headroom.py +++ b/litellm/proxy/guardrails/guardrail_hooks/headroom/headroom.py @@ -368,6 +368,24 @@ class HeadroomGuardrail(CustomGuardrail): value = 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: dict[str, str] = {"Content-Type": "application/json"} if self.headroom_api_key: @@ -621,6 +639,7 @@ class HeadroomGuardrail(CustomGuardrail): protected_indices = _protected_indices(messages) compressible = [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 = self.headroom_model or request_data.get("model") diff --git a/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_headroom.py b/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_headroom.py index 00ab39357b4..64837161515 100644 --- a/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_headroom.py +++ b/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_headroom.py @@ -1963,6 +1963,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