Repository navigation
Add Anthropic prompt-cache clear-then-finalize - #280
Conversation
|
Thanks @raymondginger2018-sudo for digging into our prompt caching. The message-breakpoint change is a genuine improvement: moving it from The What we'd accept:
Happy to review a slimmed-down version. Thanks again! |
…nt blocks - AnthropicProvider: strip stale cache_control markers, then place the single latest marker (budget 4, type ephemeral) on the newest non-system message before send; non-caching path strips system cache hints too. - agent_setup: emit block-list system prompts carrying cacheHint stable/ dynamic annotations (never leaked to any API). - openai_compat: _sanitize_messages walks content blocks stripping cacheHint before request build. - openai_responses: converter joins text blocks and strips cacheHint. All new behavior is opt-in/annotation-driven; default flows unchanged.
Address review on PR HKUDS#280: - The stable/dynamic cacheHint split is gone: the system prompt stays flat again, and the marker-stripping hooks in the OpenAI-compatible provider and the Responses converters are removed with it. - The anthropic clear-then-finalize change stays: strip every stale marker from the replayed list, then place one fresh marker on the latest non-system message instead of a hardcoded messages[-2]. - The cache tests now drive _build_kwargs with converted messages instead of reaching into _prepare_request_kwargs, and the legacy cacheHint tests are deleted.
525fe4e to
68dfed8
Compare
|
Thanks @Zongwei9888 — slimmed down exactly as requested; pushed as 1. Frontier change on its own, tests through Net diff vs Discrimination vs 2. No
3. Comments No ZCode or NameError references — 4. Unrelated Same as (2): that file no longer appears in the diff. Local checks on PR title and description updated to match the slimmed scope. Happy to adjust further. |
|
Thanks @raymondginger2018-sudo, merged as a9905c4. The breakpoint now sits on the latest message and the tests go through |
Summary
Hardens Anthropic prompt-cache marker handling: the message breakpoint is written clear-then-finalize — strip every stale
cache_controlfrom the converted conversation, then place ONE fresh marker on the latest non-system message (instead of the hardcodedmessages[-2]write point, which missed the frontier whenever the tail shape changed).Changes
core/providers/anthropic.py(+83, the only production file):_strip_cache_control— remove stale markers from a message dict and from any content-block payload (string or block-list form)._place_cache_control— copy a message and mark its last block; wraps plain-string content into a single marked text block; image-only/empty content left unchanged.tests/test_anthropic_cache_control.py— rewritten: every test drivesAnthropicProvider._build_kwargs(the production entry, which runs the provider's own_convert_messages) and asserts on the converted Anthropic-format payload insidekwargs["messages"].Tests
tests/test_anthropic_cache_control.py— 8 passed on this branch. Onmain(cd7ab47d): 3 failed / 5 passed — the three failures are exactly the frontier-placement cases (latest-message marker, trailing system note, stale-marker strip); the five that pass on both revisions are invariant guards (marker budget ≤ 4, tool-marker positions, string-system wrap, disabled-cache path, tools-absent path) that pin behavior the change must not disturb.main:ruff checkandruff format --checkshow zero delta (the 19 ruff findings are pre-existing on both sides).Notes
cacheHintannotation and theagent_setupblock-list system prompt are fully dropped.core/agent_setup.py,core/providers/openai_compat.pyandcore/providers/openai_responses/converters.pyare byte-identical tomain; nocacheHintreference remains anywhere in the diff.