بنقرة واحدة
roo-fix-volatile-msg
Roo Code inherits Cline's volatile-message cache bug. Same fix shape, inline location.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Roo Code inherits Cline's volatile-message cache bug. Same fix shape, inline location.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | roo-fix-volatile-msg |
| description | Roo Code inherits Cline's volatile-message cache bug. Same fix shape, inline location. |
| target_harness | Roo Code |
| target_repo | RooCodeInc/Roo-Code |
| target_files | ["src/api/providers/anthropic.ts"] |
| target_commit | main @ v3.54.0 (verify current at apply time) |
| estimated_savings | ~30% wasted cache write premium eliminated per turn |
src/api/providers/anthropic.ts in RooCodeInc/Roo-Code.
Permalink: https://github.com/RooCodeInc/Roo-Code/blob/main/src/api/providers/anthropic.ts
Roo is a Cline fork that inlined Cline's helper instead of factoring it out. Same bug, slightly different code location.
Same as cline-fix-volatile-msg:
const userMsgIndices = sanitizedMessages.reduce(
(acc, msg, index) => (msg.role === "user" ? [...acc, index] : acc),
[] as number[],
)
const lastUserMsgIndex = userMsgIndices[userMsgIndices.length - 1] ?? -1
const secondLastMsgUserIndex = userMsgIndices[userMsgIndices.length - 2] ?? -1
messages: sanitizedMessages.map((message, index) => {
if (index === lastUserMsgIndex || index === secondLastMsgUserIndex) {
return { /* adds cache_control */ }
}
return message
})
lastUserMsgIndex is the current user turn. Marking it caches
nothing and pays write premium every turn.
--- a/src/api/providers/anthropic.ts
+++ b/src/api/providers/anthropic.ts
@@
- const userMsgIndices = sanitizedMessages.reduce(
- (acc, msg, index) => (msg.role === "user" ? [...acc, index] : acc),
- [] as number[],
- )
- const lastUserMsgIndex = userMsgIndices[userMsgIndices.length - 1] ?? -1
- const secondLastMsgUserIndex = userMsgIndices[userMsgIndices.length - 2] ?? -1
+ // Cache the LAST STABLE message — the turn BEFORE the current user
+ // input. The current user turn changes every request and forces
+ // cache writes for zero subsequent reads.
+ const lastStableIdx = sanitizedMessages.length >= 2
+ ? sanitizedMessages.length - 2
+ : -1
@@
messages: sanitizedMessages.map((message, index) => {
- if (index === lastUserMsgIndex || index === secondLastMsgUserIndex) {
+ if (index === lastStableIdx) {
return {
...message,
content: typeof message.content === "string"
? [{ type: "text", text: message.content, cache_control: cacheControl }]
: message.content.map((block) => ({ ...block, cache_control: cacheControl }))
}
}
return message
})
Same as Cline's verify procedure — see cline-fix-volatile-msg/SKILL.md#verify. Settings path differs but the wire-level assertion is identical.
See the parent skill for the full reasoning. Full audit: audits/roo-code.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.
Stop Cline from burning a cache breakpoint on the volatile current user message every turn.
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.