mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
1 commit
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7052d52dcb
|
fix(proxy/openai): cache under looked-up messages (#2420)
## Description
The OpenAI chat path caches responses under a different key than it
looked them up by. `handle_openai_chat` calls `cache.get(messages, ...)`
at request start, then the `pre_compress` hook reassigns `messages`
before `cache.set(messages, ...)`. When a deployment configures a
message-rewriting hook, the handler stores every response under a key no
future lookup can produce. The response cache never hits and fills with
unreachable entries until eviction, with no error signal.
This is the OpenAI twin of the anthropic fix in #2124 (which closed
#327). Same snapshot pattern: capture the lookup messages once before
the hook runs, reuse them verbatim at `cache.set`.
Related to #327, follow-on to #2124 (which fixed the anthropic side
only).
## Type of Change
- [x] Bug fix (non-breaking change that fixes an issue)
## Changes Made
- Snapshot `cache_lookup_messages = messages` before the `pre_compress`
hook in `handle_openai_chat`, and cache the response under that snapshot
at `cache.set`. Mirrors the shipped anthropic pattern in
`handlers/anthropic.py`.
- Add `tests/test_openai_response_cache_key.py`: drives two identical
`/v1/chat/completions` requests through a message-rewriting
`pre_compress` hook against the real `SemanticCache`, and asserts the
repeat is served from cache (upstream called once) rather than re-sent.
This exercises the real cache-key function, which a get/set-argument
check does not.
- Document the ordering invariant at the snapshot: image compression
also rebinds `messages` but runs upstream of the snapshot, so a future
reorder that moved it below would reintroduce the drift.
## Testing
- [x] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check .`)
- [x] Type checking passes (`mypy headroom`)
- [x] New tests added for new functionality
- [x] Manual testing performed
### Test Output
```text
$ pytest tests/test_openai_response_cache_key.py tests/test_proxy_openai_cache_key_integration.py tests/test_backend_nonstreaming_cache_metrics.py tests/test_openai_codex_routing.py -q
31 passed, 1 warning in 17.43s
$ ruff check headroom/proxy/handlers/openai.py tests/test_openai_response_cache_key.py
All checks passed!
$ mypy headroom
Success: no issues found in 505 source files
```
## Real Behavior Proof
- Environment: headroom at `upstream/main`
|