You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browse filesBrowse the repository at this point in the historyBrowse files
authored
fix(cache): include request-shaping parameters in the prompt cache key (#90) (#91)
The prompt cache key was sha256(model + [role, content]) while the request
surface forwarded upstream also carries tools, tool_choice, response_format,
reasoning_effort, thinking, max_tokens, temperature, top_p, n, and arbitrary
provider extras. Two requests with the same messages therefore shared a cache
entry, so a plain chat answer could be served to a later request that asked
for structured output or tool calls, and a response generated under a high
max_tokens could be served to a request that asked for a low one. The cache
sits in front of the provider call, so this silently overrides the client's
request contract.
- request_cache_params() collects the declared response-shaping fields plus
everything in model_extra except stream, and PromptCache.get/put take it as
an optional params argument folded into the key.
- Message normalization now keeps model_extra (tool_call_id, name,
tool_calls), so tool-result turns with identical text no longer collide.
- json.dumps uses default=str so a non-serializable extra degrades the key
instead of raising.
Both call sites in server.py pass the same params dict, so a lookup and the
insert that follows it cannot drift.
Co-authored-by: Nadir <info@getnadir.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,9 @@ All notable changes to NadirClaw will be documented in this file.
4
4
5
5
## [Unreleased]
6
6
7
+
### Fixed
8
+
- **The prompt cache ignored every request parameter except the model and message text, so it could answer a request with a response that does not satisfy it** (#90). The key was `sha256(model + [role, content])`, while the request surface forwarded upstream also carries `tools`, `tool_choice`, `response_format`, `reasoning_effort`, `thinking`, `max_tokens`, `temperature`, `top_p`, `n`, and arbitrary provider extras. Two requests with the same messages therefore shared a cache entry: a plain chat answer could be served to a later request asking for `response_format: {"type": "json_schema"}` or for `tool_calls`, and a response generated under a high `max_tokens` could be served to a request that asked for a low one — silently overriding the client's contract, since the cache sits in front of the provider call. The key now includes every response-shaping field (`request_cache_params()` collects the declared ones plus everything in `model_extra` except `stream`), and message normalization keeps `tool_call_id` / `name` / `tool_calls` so tool-result turns with identical text no longer collide. Non-serializable extras fall back to `repr` rather than raising.
0 commit comments