feat(proxy): add CLI opt-outs for CCR injection (compression-only mode) (#823)

## What & why

Streaming / non-MCP clients can't resolve the injected
`headroom_retrieve` (CCR) tool, so CCR injection turns into unresolvable
tool calls that error and inflate turn count. Today there's no proxy CLI
flag to run **compression-only** — `ccr_inject_tool`,
`ccr_inject_marker`, and `ccr_proactive_expansion` are hardcoded `True`
defaults — so a faithful compression-only eval requires patching the
image.

This adds three opt-in `--no-*` flags (with env vars), **all defaulting
to current behavior (CCR fully on)**:

| flag | env var | effect |
|---|---|---|
| `--no-ccr-inject-tool` | `HEADROOM_NO_CCR_INJECT_TOOL` | don't inject
the retrieve tool |
| `--no-ccr-marker` | `HEADROOM_NO_CCR_MARKER` | don't add retrieval
markers to compressed content |
| `--no-ccr-proactive-expansion` | `HEADROOM_NO_CCR_PROACTIVE_EXPANSION`
| disable proactive expansion |

`ccr_inject_tool` and `ccr_proactive_expansion` already existed on
`ProxyConfig`. `ccr_inject_marker` is added to `ProxyConfig` and
threaded into `ContentRouterConfig` in `server.py` (previously it was
only ever the router's own default).

Per CONTRIBUTING I raised this in #645 first; you accepted the patch
offer there.

## Changes to existing behavior

None unless a flag is passed. With no flags, all three toggles stay
`True` (test `test_ccr_defaults_on`).

## Test plan

- `tests/test_cli_proxy_env.py::TestCLICompressionOnlyFlags` —
defaults-on, `--no-ccr-inject-tool` in isolation, all three combined,
and the `HEADROOM_NO_CCR_MARKER` env path.
- `pytest tests/test_cli_proxy_env.py` → 26 passed;
`tests/test_proxy_modes.py tests/test_proxy_pipeline_lifecycle.py
tests/test_cli_proxy_env.py` → 34 passed.
- `ruff check` + `ruff format --check` clean on all changed files.

## Real behavior proof

- **Setup:** Linux, Python 3.13.5, `python -m venv .venv &&
.venv/bin/pip install -e ".[dev]"` at this branch; OpenAI-compatible
upstream.
- **Ran:**
  - `headroom proxy --help` → all three flags appear with help text.
  - Instantiated the live proxy:
    ```python
    from headroom.proxy.server import ProxyConfig, HeadroomProxy
    from headroom.transforms.content_router import ContentRouter
    cfg = ProxyConfig(host="127.0.0.1", port=1,
ccr_inject_tool=False, ccr_inject_marker=False,
ccr_proactive_expansion=False)
    p = HeadroomProxy(cfg)
router = [t for t in p.anthropic_pipeline.transforms if isinstance(t,
ContentRouter)][0]
    print(router.config.ccr_inject_marker)  # -> False
    ```
- **Observed:** `router.config.ccr_inject_marker == False`;
`cfg.ccr_inject_tool == False`; `cfg.ccr_proactive_expansion == False`.
With no flags, all three are `True`.
- **Not tested here:** a full live agentic run on this branch. The
motivating field evidence (a compression-only run with zero
`headroom_retrieve` calls, compression intact) was collected on the
v0.23.0 image with these same three defaults flipped — this PR replaces
that image patch with first-class flags.

Refs #645.
This commit is contained in:
Boni Gopalan 2026-06-11 07:38:32 +05:30 committed by GitHub
parent 929698af10
commit 693d9d20e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 123 additions and 0 deletions

View file

@ -159,6 +159,31 @@ def _selected_context_tool() -> str:
@click.option("--no-optimize", is_flag=True, help="Disable optimization (passthrough mode)")
@click.option("--no-cache", is_flag=True, help="Disable semantic caching")
@click.option("--no-rate-limit", is_flag=True, help="Disable rate limiting")
@click.option(
"--no-ccr-inject-tool",
is_flag=True,
envvar="HEADROOM_NO_CCR_INJECT_TOOL",
help=(
"Don't inject the CCR headroom_retrieve tool. Run compression-only — "
"for streaming / non-MCP clients that can't resolve the retrieve tool "
"and would otherwise error on it. Env: HEADROOM_NO_CCR_INJECT_TOOL."
),
)
@click.option(
"--no-ccr-marker",
is_flag=True,
envvar="HEADROOM_NO_CCR_MARKER",
help=("Don't add CCR retrieval markers to compressed content. Env: HEADROOM_NO_CCR_MARKER."),
)
@click.option(
"--no-ccr-proactive-expansion",
is_flag=True,
envvar="HEADROOM_NO_CCR_PROACTIVE_EXPANSION",
help=(
"Disable proactive expansion of previously compressed content. "
"Env: HEADROOM_NO_CCR_PROACTIVE_EXPANSION."
),
)
@click.option(
"--proxy-extension",
"proxy_extension",
@ -555,6 +580,9 @@ def proxy(
no_optimize: bool,
no_cache: bool,
no_rate_limit: bool,
no_ccr_inject_tool: bool,
no_ccr_marker: bool,
no_ccr_proactive_expansion: bool,
proxy_extension: tuple[str, ...],
no_subscription_tracking: bool,
subscription_poll_interval: int | None,
@ -729,6 +757,12 @@ def proxy(
optimize=not no_optimize,
cache_enabled=not no_cache,
rate_limit_enabled=not no_rate_limit,
# CCR opt-outs for compression-only deployments (streaming / non-MCP
# clients that can't resolve the injected retrieve tool). Defaults keep
# CCR fully on; each flag flips one dataclass default to False.
ccr_inject_tool=not no_ccr_inject_tool,
ccr_inject_marker=not no_ccr_marker,
ccr_proactive_expansion=not no_ccr_proactive_expansion,
# Flatten repeat-flag tuple AND any comma-separated values inside it.
# `--proxy-extension a,b --proxy-extension c` and `HEADROOM_PROXY_EXTENSIONS=a,b,c`
# both yield ["a", "b", "c"]. None when nothing was supplied.

View file

@ -118,6 +118,10 @@ class ProxyConfig:
# CCR Tool Injection
ccr_inject_tool: bool = True
ccr_inject_system_instructions: bool = False
# Proxy-level mirror of ContentRouterConfig.ccr_inject_marker, so retrieval
# markers can be toggled from the CLI (--no-ccr-marker). Threaded into the
# router in server.py; default preserves current behavior.
ccr_inject_marker: bool = True
# CCR Response Handling
ccr_handle_responses: bool = True

View file

@ -364,6 +364,7 @@ class HeadroomProxy(
enable_code_aware=config.code_aware_enabled,
tool_profiles=config.tool_profiles,
read_lifecycle=ReadLifecycleConfig(enabled=config.read_lifecycle),
ccr_inject_marker=config.ccr_inject_marker,
)
# A non-None exclude_tools replaces DEFAULT_EXCLUDE_TOOLS in
# ContentRouter, so merge rather than assign.

View file

@ -596,6 +596,90 @@ class TestCLIAnyllmProviderEnv:
assert captured_config["config"].anyllm_provider == "groq"
class TestCLICompressionOnlyFlags:
"""The CCR opt-out flags must flip the corresponding ProxyConfig fields.
These enable a compression-only deployment for streaming / non-MCP clients
that can't resolve the injected headroom_retrieve tool (issue #645).
"""
def test_ccr_defaults_on(self, runner):
"""Without flags, all three CCR toggles stay enabled (no behavior change)."""
captured_config = {}
def mock_run_server(config, **kwargs):
captured_config["config"] = config
with patch("headroom.proxy.server.run_server", mock_run_server):
result = runner.invoke(main, ["proxy"], catch_exceptions=False)
assert result.exit_code == 0, result.output
cfg = captured_config["config"]
assert cfg.ccr_inject_tool is True
assert cfg.ccr_inject_marker is True
assert cfg.ccr_proactive_expansion is True
def test_no_ccr_inject_tool_flag(self, runner):
"""--no-ccr-inject-tool disables retrieve-tool injection only."""
captured_config = {}
def mock_run_server(config, **kwargs):
captured_config["config"] = config
with patch("headroom.proxy.server.run_server", mock_run_server):
result = runner.invoke(main, ["proxy", "--no-ccr-inject-tool"], catch_exceptions=False)
assert result.exit_code == 0, result.output
cfg = captured_config["config"]
assert cfg.ccr_inject_tool is False
# Untouched flags remain on.
assert cfg.ccr_inject_marker is True
assert cfg.ccr_proactive_expansion is True
def test_compression_only_all_flags(self, runner):
"""All three flags together yield a compression-only config."""
captured_config = {}
def mock_run_server(config, **kwargs):
captured_config["config"] = config
with patch("headroom.proxy.server.run_server", mock_run_server):
result = runner.invoke(
main,
[
"proxy",
"--no-ccr-inject-tool",
"--no-ccr-marker",
"--no-ccr-proactive-expansion",
],
catch_exceptions=False,
)
assert result.exit_code == 0, result.output
cfg = captured_config["config"]
assert cfg.ccr_inject_tool is False
assert cfg.ccr_inject_marker is False
assert cfg.ccr_proactive_expansion is False
def test_no_ccr_marker_from_env(self, runner):
"""HEADROOM_NO_CCR_MARKER env var disables marker injection."""
captured_config = {}
def mock_run_server(config, **kwargs):
captured_config["config"] = config
with patch("headroom.proxy.server.run_server", mock_run_server):
result = runner.invoke(
main,
["proxy"],
env={"HEADROOM_NO_CCR_MARKER": "1"},
catch_exceptions=False,
)
assert result.exit_code == 0, result.output
assert captured_config["config"].ccr_inject_marker is False
class TestArgparseBackendValidation:
"""Test that the argparse path (python -m headroom.proxy.server) accepts litellm-* backends."""