Description
Summary
On OpenCode V2, the plugin adds the ruleset to the system prompt in the context hook only. OpenCode runs a separate compaction hook for the summary compaction request, so that request has a different system prompt from the main-loop requests. On providers with prompt caching, the compaction request then misses the cache after the tools. The whole conversation is billed again as new input or as a new cache write.
Location
.opencode/plugins/ponytail.mjs in 5.1.0:
await ctx.session.hook('context', (event) => {
const mode = readMode();
if (mode === 'off') return;
event.system.push({ type: 'text', text: getPonytailInstructions(mode) });
});Measured
OpenCode built from source (v2), Claude Haiku 5.5 over the Anthropic Messages API, 3 turns with tool calls, then /compact. Request bodies captured with a logging forwarder.
| Plugin | Compaction input read from the prompt cache |
|---|---|
| None | 84 to 90% |
Ponytail 5.1.0 as published (context hook only) |
7% |
| Ponytail 5.1.0 with the fix below | 86% |
The captured compaction request had no ponytail block in its system prompt. The main-loop requests had it.
Suggested fix
Register the same handler on both hooks:
const addRuleset = (event) => {
const mode = readMode();
if (mode === 'off') return;
event.system.push({ type: 'text', text: getPonytailInstructions(mode) });
};
await ctx.session.hook('context', addRuleset);
await ctx.session.hook('compaction', addRuleset);With this change, the summary model also receives the ruleset.
Related
OpenCode's compaction cache issue: anomalyco/opencode#52761
Activity
fix(opencode): register the ruleset on the compaction hook (#1086) (#…
DietrichGebert commentedon Oct 12, 2026
Thanks! Tested it in OpenCode 2.0.27, the compaction request now gets the same system prompt as the normal requests. Merged, will be in the next release.