بنقرة واحدة
cline-fix-volatile-msg
Stop Cline from burning a cache breakpoint on the volatile current user message every turn.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Stop Cline from burning a cache breakpoint on the volatile current user message every turn.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | cline-fix-volatile-msg |
| description | Stop Cline from burning a cache breakpoint on the volatile current user message every turn. |
| target_harness | Cline |
| target_repo | cline/cline |
| target_files | ["src/core/api/transform/anthropic-format.ts"] |
| target_commit | 65e9727c (verify current at apply time) |
| estimated_savings | ~30% wasted cache write premium eliminated per turn |
src/core/api/transform/anthropic-format.ts in cline/cline.
Permalink: https://github.com/cline/cline/blob/65e9727c/src/core/api/transform/anthropic-format.ts
Cline marks the LAST TWO USER MESSAGES with cache_control: ephemeral.
The last user message is the CURRENT user turn — it's different on
every request by definition. Caching content that changes every
request pays the 1.25x write premium on those tokens every turn for
zero cache reads. Net result: one of Cline's 3 breakpoints is burned
producing nothing.
You can confirm on the wire: in two consecutive identical-prompt
turns, the response usage.cache_creation_input_tokens stays > 0 on
turn 2 instead of dropping to ~0.
Replace the "last 2 user messages" logic with "last STABLE message" (typically the previous assistant turn or tool_result):
--- a/src/core/api/transform/anthropic-format.ts
+++ b/src/core/api/transform/anthropic-format.ts
@@
- const userMsgIndices = clineMessages.reduce((acc, msg, index) => {
- if (msg.role === "user") acc.push(index)
- return acc
- }, [] as number[])
- const lastUserMsgIndex = userMsgIndices.at(-1)
- const secondLastMsgUserIndex = userMsgIndices.at(-2)
+ // Cache the LAST STABLE message — the message BEFORE the current
+ // user turn. The current user turn changes every request and would
+ // pay the 1.25x cache-write premium for zero subsequent reads.
+ // The previous turn (assistant message or tool_result) is stable
+ // across the request → response cycle.
+ const lastStableIdx = clineMessages.length >= 2
+ ? clineMessages.length - 2
+ : -1
@@
- if (supportCache && (index === lastUserMsgIndex || index === secondLastMsgUserIndex)) {
+ if (supportCache && index === lastStableIdx) {
return addCacheControl(anthropicMsg)
}
This frees one breakpoint. Optionally use that freed breakpoint to
cache the tools array independently — see audits/cline.md for the
extended pattern.
mitmdump -p 8090 -w /tmp/cline.flowhttp://127.0.0.1:8090)usage:
cache_creation_input_tokens > 0 every turn (bug)cache_creation_input_tokens ≈ 0, cache_read_input_tokens covers system + tools + previous turnHit rate (turn 2): should be ≥80% of input tokens.
See docs/gotchas.md #1 ("Putting cache_control
on volatile content"). Anthropic caches the entire prefix up to and
including the marked block; marking a block that mutates per request
means the cache is invalidated every request.
Full audit: audits/cline.md.
Aider uses 5min TTL by default and works around long pauses with keepalive pings. Wire up the 1h TTL beta instead.
Aider's --cache-prompts is off by default. Flip it on for supported models.
Cline OpenAI native provider sends no prompt_cache_key. Add a stable per-task key so cached_tokens stops being zero.
Cline's system prompt includes a timestamp that may be recomputed per request, invalidating the system-prompt cache.
Continue's prompt caching is opt-in via config and off by default. Flip the default to systemAndTools.
Continue inherits the Cline-family volatile-message cache bug. Same fix shape.