headroom/tests/test_cache
Rod Boev 0f606b6281
fix(cache): avoid fallback session collisions (#1827)
## Description

Cache-mode session tracking currently collapses unrelated conversations
when they share a large static first system prompt. The fallback
session-id hash ignores later system messages entirely, so dynamic
per-conversation context can get cut out of the key and two different
sessions reuse the same `PrefixCacheTracker`. This hashes the full
ordered system-text payload instead, while leaving explicit
`x-headroom-session-id` overrides untouched. Refs #1808.

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

- Collected all system-text content when building the fallback cache
session id.
- Stopped truncating fallback session-id input to the first 500
characters of the first system message.
- Added a regression that proves two conversations with different later
system context no longer collide.
- Added a preservation test that appending only non-system turns keeps
the same fallback session id.
- Applied the pinned Ruff formatter to three pre-existing files on the
current base so the repo-wide lint job passes unchanged semantics.

## Testing

- [x] Unit tests pass (`uv run pytest
tests/test_cache/test_prefix_tracker.py -q`)
- [x] Linting passes (`uv run ruff check
headroom/cache/prefix_tracker.py
tests/test_cache/test_prefix_tracker.py`)
- [ ] Type checking passes (`uv run mypy headroom`)
- [x] New tests added for new functionality when applicable
- [ ] Manual testing performed

### Test Output

```text
uv run pytest tests/test_cache/test_prefix_tracker.py -q
40 passed, 1 warning in 0.15s

uv run ruff check headroom/cache/prefix_tracker.py tests/test_cache/test_prefix_tracker.py
All checks passed!

uv run ruff check .
All checks passed!

uv run ruff format --check .
1046 files already formatted
```

## Real Behavior Proof

- Environment: Windows, project `uv` environment, focused cache-tracker
regression.
- Exact command / steps: run `tests/test_cache/test_prefix_tracker.py`
on `origin/main` with the new collision regression present, then rerun
the same file on this branch.
- Observed result: base returns the same session id for two
conversations that differ only in a later system message and fails
`assert id_a != id_b`; head passes the focused file and keeps the
fallback session id stable when only non-system turns are appended.
- Not tested: live proxy traffic through a real agentic client.

## 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
- [x] 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
- [x] I have updated the CHANGELOG.md if applicable

## Additional Notes

This is only the session-collision half of #1808. The
duplicate-response-header fix stays separate so this PR can reference
the issue without claiming the whole bug report is resolved. The extra
formatting-only diff comes from the current base failing the pinned
full-repo Ruff format check.
2026-07-07 23:26:36 -05:00
..
__init__.py Add cache optimization module with scalable dynamic content detection 2026-01-07 14:07:49 -08:00
test_anthropic.py Fix all ruff lint and format errors for CI 2026-01-10 15:33:44 -08:00
test_backends.py Add pluggable storage backend abstraction for CompressionStore 2026-01-20 23:25:28 -08:00
test_base.py Fix all ruff lint and format errors for CI 2026-01-10 15:33:44 -08:00
test_client_integration.py Fix ruff formatting 2026-01-17 17:14:12 -08:00
test_dynamic_detector.py fix(cache): name the missing piece in semantic detector guard (#1018) 2026-06-15 16:29:52 -05:00
test_google.py Fix all ruff lint and format errors for CI 2026-01-10 15:33:44 -08:00
test_openai.py Fix all ruff lint and format errors for CI 2026-01-10 15:33:44 -08:00
test_prefix_tracker.py fix(cache): avoid fallback session collisions (#1827) 2026-07-07 23:26:36 -05:00
test_registry.py Fix all ruff lint and format errors for CI 2026-01-10 15:33:44 -08:00
test_semantic.py Fix all ruff lint and format errors for CI 2026-01-10 15:33:44 -08:00