Fix cache-busting reminder injections#419
Conversation
Greptile SummaryThis PR refactors all dynamic reminder injection away from the cached system prompt (
Confidence Score: 4/5Safe to merge with the One P1 finding: the src/hooks/todo-continuation/todo-hygiene.ts — the RESET-path injection block (lines 145–153) needs the Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[tool.execute.after] --> B{FILE_TOOLS?}
B -- yes --> C{shouldInject?}
C -- yes --> D[appendReminder to tool output\npost-file-tool-nudge]
C -- no --> E[skip]
B -- no --> F{RESET tool?\ne.g. todowrite}
F -- yes --> G[clearCycle + getTodoState]
G --> H{isFinalActive?}
H -- yes --> I["⚠️ appendReminder final_active\n(shouldInject NOT checked)"]
H -- no --> J[mark general / return]
F -- no --> K{active session?}
K -- yes --> L{shouldInject?}
L -- yes --> M[getTodoState → appendReminder]
L -- no --> N[clear + skip]
subgraph messages_transform [experimental.chat.messages.transform]
P[scan messages backward\nfor last user msg] --> Q{orchestrator?}
Q -- yes --> R[append resumable_sessions block\ntask-session-manager]
R --> S[append phase_reminder at tail]
Q -- no --> T[skip]
end
|
I like the broader direction here: moving runtime reminders out of One thing I’m unsure about is the This PR instead appends the reminder directly to Do you think that could risk persisting the reminder as part of the tool result/history, or losing it when |
Summary
<internal_reminder>, while resumable session context is appended to the latest orchestrator user message before the phase reminder.What changed
phase-remindernow appends<internal_reminder>...</internal_reminder>after the latest orchestrator user text. It runs after resumable-session injection, skips non-orchestrator and internal notification turns, and avoids duplicate reminders.post-file-tool-nudgeappends the reminder to Read/Write tool output instead of setting pending state for system injection. This nudge is intentionally retained because post-read/write drift is still a useful trigger.todo-continuationinjects hygiene/final-active reminders into the triggering tool output.task-session-managerinjects<resumable_sessions>into request-local message context instead ofexperimental.chat.system.transform.Why this fixes the issue
OpenCode/provider prompt caching depends on stable cached prefix content. Before this change, runtime state such as file-tool activity, todo state, resumable sessions, and per-request reminders could alter system or prepend content ahead of the user's turn. This PR keeps dynamic reminders out of system and places request-local guidance at the tail/tool-output context, so reminders remain visible without invalidating the stable system prompt.
Verification
bun test src/hooks/phase-reminder/index.test.ts src/hooks/post-file-tool-nudge/index.test.ts src/hooks/todo-continuation/index.test.ts src/hooks/todo-continuation/todo-hygiene.test.ts src/hooks/task-session-manager/index.test.tsbunx biome check src/index.ts src/hooks/phase-reminder/index.ts src/hooks/phase-reminder/index.test.tsbun run typecheckbun run build