You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[v2] No idle-time compaction: a large session is re-sent uncached after its prompt cache expires #50777
When a session sits idle longer than the provider's prompt-cache lifetime (Anthropic 5 min or 1 h, OpenAI 30 min), the next message re-sends the whole context uncached. On a long session that is the most expensive request it makes. Compacting an idle session before the user comes back avoids that, but OpenCode v2 has no way to do it:
No idle trigger. Compaction runs only on context overflow (compaction.auto) or manually.
Plugins can't do it either. The plugin context's ctx.session exposes create, get, switchAgent, switchModel, prompt, generate, command, synthetic, interrupt, update, move, wait and context, but not compact. The core session service has compact (packages/core/src/session.ts) and the server has POST /api/session/:sessionID/compact. The only built-in commands are init and review, and calling the HTTP route from a plugin would need the server password, which in service mode comes from the service config, not the environment.
The built-in warming option shows the gap: it keeps an idle session warm, but when warming ends nothing can compact the session.
Expected: either an idle-compaction option (for example compaction.idle: { after: "4 hours", minTokens: 100000 }), or compact exposed on the plugin session API so a plugin can do it. The second looks small: add compact to the host session object (packages/core/src/plugin/host.ts), one adaptApiMethod line in packages/core/src/plugin/promise.ts, and "compact" in SessionDomain in packages/plugin/src/promise/session.ts and packages/plugin/src/effect/session.ts.
Plugins
A local server plugin that keeps idle Anthropic sessions warm and compacts them at the end of the idle window. It feature-detects ctx.session.compact.
OpenCode version
2.0.14 (source checked on the v2 branch at 1746672)
Steps to reproduce
Write a server plugin that calls ctx.session.compact({ sessionID }).
typeof ctx.session.compact is "undefined", and no other plugin API compacts a session.
Leave a large session idle past the cache lifetime. Nothing compacts it, and the next message pays for a full uncached write of the context.
changed the title [-][v2] No idle compaction, and plugins cannot trigger compaction (session.compact missing from the plugin context)[/-][+][v2] No idle-time compaction: a large session is re-sent uncached after its prompt cache expires[/+]on Sep 23, 2026
Thanks for the pointers. The plugin half of this report duplicates #49389 (item 1) and #47229, so I'll follow those for session.compact on the plugin context.
I'm narrowing this issue to the part none of them covers: compaction after idle time. #40113 asks for a size-based threshold, which v2 already has as compaction.auto. This one is about compacting a large session before its prompt cache expires, so the first message after a long break doesn't re-send the whole context uncached. Retitled to match.
Thanks for the detailed write-up, @sergiopadure! You're asking for a way to compact a large idle session before its prompt cache expires: either a built-in idle-compaction option, or compact exposed to plugins.
ctx.session.compact is already available. It was added in #52385 and has shipped since v2.0.22. That PR made the changes you describe: the host session object, the promise adapter, and "compact" in SessionDomain for both the promise and effect APIs. You're on 2.0.14, and the v2 branch you checked is out of date (it was promoted to dev on 2026-10-10). Since your plugin already checks whether ctx.session.compact exists, it should start compacting once you upgrade, for example:
awaitctx.session.compact({ sessionID })
This adds a compaction to the session's inbox, and you can pass delivery: "queue" if needed.
There is no built-in idle compaction yet. Compaction runs only on context overflow (compaction.auto) or when you start it manually, and warming doesn't compact a session when warming ends. I've marked this as a feature request, and maintainers will consider an option like compaction.idle. In the meantime, a plugin like yours is the way to get this behaviour.
Activity
github-actions commentedon Sep 23, 2026
This issue might be a duplicate of existing issues. Please check:
session.compactis not projected in the plugin context (SessionDomainPick omits it), with the same proposed fix (one-line forwarding change). Item 1 in that issue is identical to the plugin half of this report.context.session.compact(...)be exposed to the v2 plugin API, with the same motivation of coordinating compaction from a plugin.compaction.idle: { after: ..., minTokens: ... }) proposed here.If the plugin API gap is the primary concern, #49389 is the closest match and may be the best place to continue discussion.
[-][v2] No idle compaction, and plugins cannot trigger compaction (session.compact missing from the plugin context)[/-][+][v2] No idle-time compaction: a large session is re-sent uncached after its prompt cache expires[/+]sergiopadure commentedon Sep 23, 2026
Thanks for the pointers. The plugin half of this report duplicates #49389 (item 1) and #47229, so I'll follow those for
session.compacton the plugin context.I'm narrowing this issue to the part none of them covers: compaction after idle time. #40113 asks for a size-based threshold, which v2 already has as
compaction.auto. This one is about compacting a large session before its prompt cache expires, so the first message after a long break doesn't re-send the whole context uncached. Retitled to match.opencodejr commentedon Oct 28, 2026
Thanks for the detailed write-up, @sergiopadure! You're asking for a way to compact a large idle session before its prompt cache expires: either a built-in idle-compaction option, or
compactexposed to plugins.ctx.session.compactis already available. It was added in #52385 and has shipped since v2.0.22. That PR made the changes you describe: the hostsessionobject, the promise adapter, and"compact"inSessionDomainfor both the promise and effect APIs. You're on 2.0.14, and thev2branch you checked is out of date (it was promoted todevon 2026-10-10). Since your plugin already checks whetherctx.session.compactexists, it should start compacting once you upgrade, for example:This adds a compaction to the session's inbox, and you can pass
delivery: "queue"if needed.There is no built-in idle compaction yet. Compaction runs only on context overflow (
compaction.auto) or when you start it manually, andwarmingdoesn't compact a session when warming ends. I've marked this as a feature request, and maintainers will consider an option likecompaction.idle. In the meantime, a plugin like yours is the way to get this behaviour.Related issues:
compactto plugins