headroom/tests/test_proxy_disable_kompress.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

107 lines
3.2 KiB
Python
Raw Normal View History

"""Proxy configuration for disabling Kompress while keeping optimization on."""
from __future__ import annotations
import pytest
pytest.importorskip("fastapi")
from headroom.proxy.server import ProxyConfig, create_app
from headroom.transforms import CompressionStrategy, ContentRouter
def _proxy_router(config: ProxyConfig):
app = create_app(config)
proxy = app.state.proxy
return next(
transform
for transform in proxy.anthropic_pipeline.transforms
if isinstance(transform, ContentRouter)
)
def test_disable_kompress_config_keeps_optimization_but_disables_ml_fallback() -> None:
router = _proxy_router(
ProxyConfig(
optimize=True,
disable_kompress=True,
cache_enabled=False,
rate_limit_enabled=False,
cost_tracking_enabled=False,
log_requests=False,
)
)
assert router.config.enable_kompress is False
fix: --disable-kompress should not override fallback_strategy to PASSTHROUGH (#1046) ## Description `--disable-kompress` correctly disabled the ML model via `enable_kompress = False`, but it also forced `router_config.fallback_strategy = CompressionStrategy.PASSTHROUGH`. That override suppressed ContentRouter's rule-based passes — including the `exclude_tools` gate — for content that falls through to the fallback, so `HEADROOM_EXCLUDE_TOOLS` had no effect when `--disable-kompress` was set. Removing the override leaves `fallback_strategy` at its default (`KOMPRESS`); ContentRouter keeps running its rule-based passes and only Kompress inference is disabled. Closes #955 ## Type of Change - [x] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - `headroom/proxy/server.py`: removed the `router_config.fallback_strategy = CompressionStrategy.PASSTHROUGH` line inside the `if config.disable_kompress:` block; `enable_kompress = False` is kept. - `headroom/proxy/server.py`: dropped the now-unused `CompressionStrategy` import (it was only referenced by the removed line). - `tests/test_proxy_disable_kompress.py`: updated the assertion to expect `fallback_strategy == CompressionStrategy.KOMPRESS` (the default), matching the corrected behaviour. ## Testing - [x] Unit tests pass (`pytest`) - [x] Linting passes (`ruff check .`) - [ ] Type checking passes (`mypy headroom`) - [ ] New tests added for new functionality - [ ] Manual testing performed ### Test Output ```text $ pytest tests/test_proxy_disable_kompress.py -v ============================= test session starts ============================== platform darwin -- Python 3.13.7, pytest-9.1.0, pluggy-1.6.0 rootdir: /.../headroom configfile: pyproject.toml plugins: anyio-4.14.0, asyncio-1.4.0 collected 2 items tests/test_proxy_disable_kompress.py::test_disable_kompress_config_keeps_optimization_but_disables_ml_fallback PASSED [ 50%] tests/test_proxy_disable_kompress.py::test_disable_kompress_defaults_to_existing_kompress_behavior PASSED [100%] ============================== 2 passed in 1.37s ============================== $ ruff check headroom/proxy/server.py tests/test_proxy_disable_kompress.py All checks passed! ``` ## Real Behavior Proof - Environment: local clone, Python 3.13.7 venv, headroom core deps + fastapi/uvicorn/httpx. - Exact command / steps: built the proxy router via `create_app(ProxyConfig(optimize=True, ...))` with `disable_kompress` set and inspected the resulting `ContentRouter` config; ran `pytest tests/test_proxy_disable_kompress.py -v` and `ruff check` on the changed files. - Observed result: with `--disable-kompress`, `enable_kompress` is `False` and `fallback_strategy` is `KOMPRESS` (the default) instead of `PASSTHROUGH`; ContentRouter stays in the pipeline. Both config tests pass and lint is clean. - Not tested: full live-proxy `/stats` run against an LLM backend. The issue reporter observed `router_content_router_activations` 0→22 and exclude-tool hits 0→10 after this change (see #955). ## Review Readiness - [x] I have performed a self-review - [x] This PR is ready for human review ## Checklist - [x] My code follows the project's style guidelines - [x] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Additional Notes This removes the override line plus its now-unused import, and updates the existing test that asserted the old behaviour; no new test was added because the corrected behaviour is covered by that existing test. The live `/stats` reproduction is described in #955.
2026-06-17 01:17:45 +05:30
assert router.config.fallback_strategy == CompressionStrategy.KOMPRESS
def test_disable_kompress_defaults_to_existing_kompress_behavior() -> None:
router = _proxy_router(
ProxyConfig(
optimize=True,
cache_enabled=False,
rate_limit_enabled=False,
cost_tracking_enabled=False,
log_requests=False,
)
)
assert router.config.enable_kompress is True
assert router.config.fallback_strategy == CompressionStrategy.KOMPRESS
feat: add --disable-kompress-fallback to restore legacy PASSTHROUGH fallback (#1185) ## Description Follow-up to #1046. That PR stopped `--disable-kompress` from forcing `fallback_strategy = CompressionStrategy.PASSTHROUGH`, so ContentRouter's rule-based passes keep running when the ML model is off. As noted in review, that is a behaviour change for callers who relied on the old passthrough-everything fallback. This adds an opt-in `--disable-kompress-fallback` flag (env `HEADROOM_DISABLE_KOMPRESS_FALLBACK`) that, together with `--disable-kompress`, restores the previous behaviour by routing fall-through content to `PASSTHROUGH`. It defaults to off, so the corrected behaviour from #1046 is unchanged unless a caller explicitly opts back in. The flag is a no-op unless `--disable-kompress` is also set. ## Type of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [x] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - `headroom/proxy/models.py`: added `disable_kompress_fallback: bool = False` to `ProxyConfig`. - `headroom/proxy/server.py`: when `disable_kompress` and `disable_kompress_fallback` are both set, restore `router_config.fallback_strategy = CompressionStrategy.PASSTHROUGH` (re-adding the `CompressionStrategy` import); wired the new field through the env factory, the `__main__` argparse path (`--disable-kompress-fallback`), and the `/health` config payload. - `headroom/cli/proxy.py`: added the `--disable-kompress-fallback` Click option (with `HEADROOM_DISABLE_KOMPRESS_FALLBACK` envvar) and passed it into `ProxyConfig`. - `tests/test_proxy_disable_kompress.py`: added tests for the flag restoring `PASSTHROUGH`, for it being a no-op without `--disable-kompress`, and for the `/health` config payload exposing the field. - `tests/test_cli_proxy_env.py`: added a test that the env factory honours `HEADROOM_DISABLE_KOMPRESS_FALLBACK`. ## Testing - [x] Unit tests pass (`pytest`) - [x] Linting passes (`ruff check .`) - [ ] Type checking passes (`mypy headroom`) - [x] New tests added for new functionality - [x] Manual testing performed ### Test Output ```text $ pytest tests/test_proxy_disable_kompress.py -v collected 5 items tests/test_proxy_disable_kompress.py::test_disable_kompress_config_keeps_optimization_but_disables_ml_fallback PASSED [ 20%] tests/test_proxy_disable_kompress.py::test_disable_kompress_defaults_to_existing_kompress_behavior PASSED [ 40%] tests/test_proxy_disable_kompress.py::test_health_config_reports_disable_kompress_fallback PASSED [ 60%] tests/test_proxy_disable_kompress.py::test_disable_kompress_fallback_restores_passthrough PASSED [ 80%] tests/test_proxy_disable_kompress.py::test_disable_kompress_fallback_without_disable_kompress_is_noop PASSED [100%] 5 passed $ ruff check headroom/proxy/server.py headroom/proxy/models.py headroom/cli/proxy.py tests/ All checks passed! ``` ## Real Behavior Proof - Environment: local clone, Python 3.13.7 venv, headroom core deps + fastapi/uvicorn/httpx[http2]. - Exact command / steps: booted the app in-process with FastAPI `TestClient` across four flag combinations and inspected both the live `ContentRouter` config and the `/health` config payload. - Observed result: both flags -> enable_kompress=False and fallback_strategy=PASSTHROUGH (/health reports disable_kompress_fallback=true); --disable-kompress alone -> fallback_strategy stays KOMPRESS (the #1046 default, /health reports false); --disable-kompress-fallback alone -> no-op (enable_kompress=True, KOMPRESS); neither flag -> defaults (enable_kompress=True, KOMPRESS). - Not tested: full live-proxy `/stats` run against a real LLM backend. ## Review Readiness - [x] I have performed a self-review - [x] This PR is ready for human review ## Checklist - [x] My code follows the project's style guidelines - [x] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Additional Notes The flag is intentionally a no-op unless `--disable-kompress` is also set, mirroring where the original override lived. Happy to add a short note to the docs/README flag list if you'd like it documented there. Co-authored-by: JerrettDavis <mxjerrett@gmail.com>
2026-06-23 09:21:55 +05:30
def test_health_config_reports_disable_kompress_fallback(monkeypatch: pytest.MonkeyPatch) -> None:
from fastapi.testclient import TestClient
monkeypatch.setenv("HEADROOM_SKIP_UPSTREAM_CHECK", "1")
app = create_app(
ProxyConfig(
optimize=True,
disable_kompress=True,
disable_kompress_fallback=True,
cache_enabled=False,
rate_limit_enabled=False,
cost_tracking_enabled=False,
log_requests=False,
)
)
with TestClient(app, base_url="http://127.0.0.1", client=("127.0.0.1", 12345)) as client:
config = client.get("/health").json()["config"]
assert config["disable_kompress"] is True
assert config["disable_kompress_fallback"] is True
def test_disable_kompress_fallback_restores_passthrough() -> None:
router = _proxy_router(
ProxyConfig(
optimize=True,
disable_kompress=True,
disable_kompress_fallback=True,
cache_enabled=False,
rate_limit_enabled=False,
cost_tracking_enabled=False,
log_requests=False,
)
)
assert router.config.enable_kompress is False
assert router.config.fallback_strategy == CompressionStrategy.PASSTHROUGH
def test_disable_kompress_fallback_without_disable_kompress_is_noop() -> None:
router = _proxy_router(
ProxyConfig(
optimize=True,
disable_kompress_fallback=True,
cache_enabled=False,
rate_limit_enabled=False,
cost_tracking_enabled=False,
log_requests=False,
)
)
assert router.config.enable_kompress is True
assert router.config.fallback_strategy == CompressionStrategy.KOMPRESS