headroom/tests/test_proxy
Rod Boev 26b43f64d6
fix(proxy): keep anthropic ccr compression active across deferred injection (#2291) (#2297)
## Description

Large native Claude Code requests on the Anthropic path can still
forward with zero request compression after CCR tool injection is
deferred on a frozen prefix. The stale skip branch treats deferred
injection as a reason to bypass request compression entirely, even
though the later sticky CCR path already knows when new markers actually
require the tool. This removes that stale bypass so compression still
runs while the reversible CCR path stays intact. Closes #2291.

## 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

- Remove the stale `should_skip_ccr_request_compression` branch from
`headroom/proxy/handlers/anthropic.py`, so deferred CCR tool injection
no longer bypasses request compression in token, non-cache, or cache
mode.
- Keep the existing sticky CCR injection path as the only place that
decides whether historical markers need the retrieval tool reintroduced.
- Update `tests/test_proxy/test_anthropic_ccr_deferred_injection.py` to
cover the two broken zero-compression cases and preserve the
already-reversible frozen-prefix path.

## Testing

- [x] Unit tests pass (`uv run pytest
tests/test_proxy/test_anthropic_ccr_deferred_injection.py::test_cache_mode_compresses_delta_but_replays_cached_prefix_when_markers_are_historical
tests/test_proxy/test_anthropic_ccr_deferred_injection.py::test_non_token_non_cache_mode_keeps_compression_and_injects_tool_for_new_markers
tests/test_proxy/test_anthropic_ccr_deferred_injection.py::test_existing_retrieve_tool_keeps_reversible_ccr_path_when_prefix_is_frozen
tests/test_openai_tool_search_deferral.py
tests/test_openai_responses_compression_units.py -q`)
- [x] Linting passes (`uv run ruff check .`)
- [ ] Type checking passes (`uv run mypy headroom`)
- [x] New tests added for new functionality when applicable
- [ ] Manual testing performed

### Test Output

```text
======================= 53 passed, 1 warning in 12.71s ========================
All checks passed!
1310 files already formatted
```

## Real Behavior Proof

- Environment: synced branch and base worktrees on a local Windows proxy
test host
- Exact command / steps: run the updated Anthropic deferred-injection
regressions directly against the base package tree and the branch
package tree, then run the focused branch pytest suite above
- Observed result: the base package tree fails the two updated
zero-compression regressions (`FAIL
test_cache_mode_compresses_delta_but_replays_cached_prefix_when_markers_are_historical`,
`FAIL
test_non_token_non_cache_mode_keeps_compression_and_injects_tool_for_new_markers`)
while preserving the already-reversible path; the branch package tree
prints three `PASS` lines for the same trio and keeps the neighboring
OpenAI suites green in the 53-test focused run
- Not tested: a live upstream Claude Code request with the reporter's
exact provider/model credentials

## 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
- [x] 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

`CHANGELOG.md` is not applicable here because Headroom's release
pipeline derives it from conventional commits.

Scope is limited to the Anthropic CCR request-compression seam that
current #2291 evidence exercises. OpenAI tool-search deferral is
untouched because the current live issue is a native Claude Code path
and the concrete stale skip branch on `origin/main` is in
`anthropic.py`.

Co-authored-by: Tejas Chopra <chopratejas@gmail.com>
2026-07-16 09:32:27 -07:00
..
test_anthropic_buffered_timeout.py fix(proxy): add an Anthropic buffered read-timeout override (#1331) 2026-06-23 22:46:31 -05:00
test_anthropic_ccr_deferred_injection.py fix(proxy): keep anthropic ccr compression active across deferred injection (#2291) (#2297) 2026-07-16 09:32:27 -07:00
test_anthropic_ccr_raise.py fix(anthropic): CCR exception must re-raise, not silently swallow (#838) 2026-06-10 21:11:46 -05:00
test_anthropic_streaming_ccr_retrieve.py fix(proxy): don't 502 Anthropic streaming on a legal mixed CCR + client-tool turn (#2089) (#2117) 2026-07-14 04:01:28 -04:00
test_anthropic_upstream_header.py fix(proxy): honor x-headroom-base-url on /v1/messages route (#1763) 2026-07-09 12:43:40 -05:00
test_background_compression.py perf(compression): take large cold-start contexts off the synchronous kompress path (#1171) (#1298) 2026-06-23 10:48:06 -05:00
test_bedrock_passthrough.py feat(proxy): compress AWS Bedrock InvokeModel requests via configurable upstream (#720) 2026-06-16 14:56:16 -05:00
test_cc_switch_reconciler.py feat(proxy): cc-switch reconciler — keep Headroom in the request path alongside cc-switch (#1030) 2026-06-17 08:41:16 -05:00
test_ccr_frozen_prefix_coupling.py fix(proxy): stop re-compressing headroom_retrieve output and emitting unredeemable markers (#1323) 2026-06-25 10:11:42 -05:00
test_compression_failure_action.py fix(codex): fail open for proxy compression timeout 2026-06-04 14:04:49 +05:30
test_compression_timeout_config.py feat(proxy): make COMPRESSION_TIMEOUT_SECONDS configurable via env (#946) (#991) 2026-06-16 21:10:01 -05:00
test_compute_turn_id.py fix(proxy): strip cache_control before hashing turn_id 2026-04-23 16:04:57 +02:00
test_gemini_savings_profile.py fix(proxy/gemini): thread savings-profile kwargs into apply() (#1994) 2026-07-12 13:54:44 -04:00
test_header_safe_transforms.py feat(transforms): attribute read_lifecycle + smart_crush tags (#249) 2026-06-11 11:51:26 -05:00
test_mcp_stats_aggregation.py fix(proxy): Strands MCP bundle + backend path fixes + Codex fail-closed protection 2026-05-21 11:00:14 -07:00
test_model_router.py feat(proxy): add opt-in cost-aware model router (#1706) (#2205) 2026-07-15 19:58:17 +00:00
test_model_router_wiring.py feat(proxy): add opt-in cost-aware model router (#1706) (#2205) 2026-07-15 19:58:17 +00:00
test_openai_backend_path.py fix(proxy): Strands MCP bundle + backend path fixes + Codex fail-closed protection 2026-05-21 11:00:14 -07:00
test_openai_chat_savings_profile.py fix(proxy/openai): thread savings-profile kwargs into chat completions (#1606) 2026-07-07 11:27:54 -05:00
test_openai_responses_ccr.py feat(ccr): wire retrieve-tool interception into OpenAI Responses handler (#1898) 2026-07-09 09:41:06 -04:00
test_openai_stream_usage_option.py fix(proxy/openai): respect explicit stream_options.include_usage (#2026) 2026-07-13 00:43:16 -04:00
test_openai_transport_path_prefix.py fix(codex): OpenCode Zen telemetry attribution (#1648) 2026-07-07 11:35:21 -05:00
test_openai_upstream_header.py fix(proxy): preserve sub-path in X-Headroom-Base-Url custom upstream (#2037) (#2127) 2026-07-13 19:53:45 -04:00
test_phase3_byte_identity.py perf(compression): take large cold-start contexts off the synchronous kompress path (#1171) (#1298) 2026-06-23 10:48:06 -05:00
test_request_logger.py feat(proxy): log compressed messages alongside original request (#261) 2026-06-11 19:02:54 -05:00
test_settings_fresh_process_precedence.py fix(proxy): dedupe Codex WS request logging for accurate mixed-provider dashboards (#2189) 2026-07-15 18:18:34 +00:00
test_settings_store.py fix(proxy): dedupe Codex WS request logging for accurate mixed-provider dashboards (#2189) 2026-07-15 18:18:34 +00:00
test_transformations_feed.py fix(proxy): scope CORS to loopback + gate operator/content endpoints (#1226) 2026-06-21 00:50:55 -07:00