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
[Feature]: Automatic context compaction for OpenCode threads at a configurable fraction of the window
#25386
When I use T3 Code with the OpenCode provider (model: Muse Spark 1.3 Contributor, xhigh effort), quality degrades after the thread reaches ~20% of the model's max context window. OpenCode itself only auto-compacts near the context limit (via compaction.buffer, default 15% headroom / min 16k tokens — i.e. ~85%+), so a thread can sit in the degraded zone for a long time before anything compacts it. The only in-app remedy today is manual /compact (or the Compact chip/meter button), which requires constant monitoring.
Related per-provider precedent: Claude threads have a server-side "compact idle threads" mechanism (IdleCompactionService, useComposerSend → /compact with idleCompaction: "onReturn") plus a per-instance autoCompactWindow setting that is surfaced into tokenUsage.autoCompactThreshold and displayed in the context meter. OpenCode threads have neither:
packages/provider-opencode/src/server/v2/adapter.tsfinishTurn emits tokenUsage with usedTokens + maxTokens but never autoCompactThreshold, and there's no OpenCode-provider setting equivalent to Claude's autoCompactWindow.
apps/server/src/orchestration-v2/IdleCompaction.tsidleCompactionWindow() returns null for any driver that isn't claudeAgent.
The OpenCodeSettings schema (packages/provider-opencode/src/settings.ts) has no auto-compact threshold field.
Upstream, OpenCode already tracks near-limit compaction (docs: compaction.auto / buffer / keep.tokens), and there are open upstream requests for earlier/per-model thresholds (anomalyco/opencode#43703 per-model reserved/buffer, #8140 configurable threshold + maxContext, #11314 configurable compaction threshold, #50777 idle-time compaction). None of those give T3 Code a T3-side trigger that compacts an OpenCode thread at a user-chosen fraction of its window to preserve answer quality.
Proposal
Add a T3-side automatic context compaction for OpenCode threads, mirroring the existing Claude machinery:
New OpenCode provider-instance setting, e.g. autoCompactThreshold (tokens) or autoCompactRatio (fraction of the model's window, default e.g. 0.2), following the ClaudeSettings.autoCompactWindow pattern (validated range, empty = default/off, surfaced per-instance with General default).
Report the effective threshold in the OpenCode adapter's tokenUsage (autoCompactThreshold, like claudeProviderTurnTokenUsage does), so the context meter (ContextWindowMeter + formatContextWindowCompactionMessage) shows it and handoffBudget accounts for it.
Extend the server-side trigger so OpenCode threads compact automatically once the reported usage crosses the configured threshold — either by generalizing IdleCompactionService/idleCompactionWindow beyond claudeAgent, or by a before-send/after-turn check in ProviderTurnStartService/RunExecutionService that dispatches /compact the way useComposerSend does for onReturn (server-created, createdBy: "agent", creationSource: "server", so it stays distinguishable from manual compacts).
No changes to OpenCode itself: T3 dispatches its existing /compact path (session.compact via compactThread), same as the manual Compact chip.
Scope for a first PR: setting schema + adapter threshold reporting + one server trigger + meter display + focused tests (threshold math, below/above/at-threshold, unknown maxTokens, opt-out). Idle-cache-TTL coupling (Claude's beforeCacheExpires semantics) is explicitly out of scope; this trigger is usage-fraction based, not cache-expiry based.
Open questions
Tokens vs fraction? A fraction of the model's window (e.g. 20%) adapts across models; an absolute token count matches Claude's autoCompactWindow. Which does the team prefer (or both, like OpenCode's buffer in tokens)?
Trigger point: after-turn background compaction (like IdleCompactionService, pauses nothing) vs before-send pre-compact (like onReturn, user waits)? For a quality-preservation trigger, after-turn seems right so the next prompt starts clean.
Should the same threshold also gate the stale-resume Compact chip (shouldOfferResumeCompaction, currently Claude-only) for OpenCode threads?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Problem
When I use T3 Code with the OpenCode provider (model: Muse Spark 1.3 Contributor, xhigh effort), quality degrades after the thread reaches ~20% of the model's max context window. OpenCode itself only auto-compacts near the context limit (via
compaction.buffer, default 15% headroom / min 16k tokens — i.e. ~85%+), so a thread can sit in the degraded zone for a long time before anything compacts it. The only in-app remedy today is manual/compact(or the Compact chip/meter button), which requires constant monitoring.Related per-provider precedent: Claude threads have a server-side "compact idle threads" mechanism (
IdleCompactionService,useComposerSend→/compactwithidleCompaction: "onReturn") plus a per-instanceautoCompactWindowsetting that is surfaced intotokenUsage.autoCompactThresholdand displayed in the context meter. OpenCode threads have neither:packages/provider-opencode/src/server/v2/adapter.tsfinishTurnemitstokenUsagewithusedTokens+maxTokensbut neverautoCompactThreshold, and there's no OpenCode-provider setting equivalent to Claude'sautoCompactWindow.apps/server/src/orchestration-v2/IdleCompaction.tsidleCompactionWindow()returns null for any driver that isn'tclaudeAgent.OpenCodeSettingsschema (packages/provider-opencode/src/settings.ts) has no auto-compact threshold field.Upstream, OpenCode already tracks near-limit compaction (docs:
compaction.auto/buffer/keep.tokens), and there are open upstream requests for earlier/per-model thresholds (anomalyco/opencode#43703 per-model reserved/buffer, #8140 configurable threshold + maxContext, #11314 configurable compaction threshold, #50777 idle-time compaction). None of those give T3 Code a T3-side trigger that compacts an OpenCode thread at a user-chosen fraction of its window to preserve answer quality.Proposal
Add a T3-side automatic context compaction for OpenCode threads, mirroring the existing Claude machinery:
autoCompactThreshold(tokens) orautoCompactRatio(fraction of the model's window, default e.g.0.2), following theClaudeSettings.autoCompactWindowpattern (validated range, empty = default/off, surfaced per-instance with General default).tokenUsage(autoCompactThreshold, likeclaudeProviderTurnTokenUsagedoes), so the context meter (ContextWindowMeter+formatContextWindowCompactionMessage) shows it andhandoffBudgetaccounts for it.IdleCompactionService/idleCompactionWindowbeyondclaudeAgent, or by a before-send/after-turn check inProviderTurnStartService/RunExecutionServicethat dispatches/compactthe wayuseComposerSenddoes foronReturn(server-created,createdBy: "agent",creationSource: "server", so it stays distinguishable from manual compacts)./compactpath (session.compactviacompactThread), same as the manual Compact chip.Scope for a first PR: setting schema + adapter threshold reporting + one server trigger + meter display + focused tests (threshold math, below/above/at-threshold, unknown
maxTokens, opt-out). Idle-cache-TTL coupling (Claude'sbeforeCacheExpiressemantics) is explicitly out of scope; this trigger is usage-fraction based, not cache-expiry based.Open questions
autoCompactWindow. Which does the team prefer (or both, like OpenCode'sbufferin tokens)?IdleCompactionService, pauses nothing) vs before-send pre-compact (likeonReturn, user waits)? For a quality-preservation trigger, after-turn seems right so the next prompt starts clean.shouldOfferResumeCompaction, currently Claude-only) for OpenCode threads?Related
compaction.buffer= earlier auto-compact in tokens).All reactions