Description
In packages/opencode/src/session/overflow.ts:14-19, the usable() function reserves different output budgets depending on whether the model has limit.input set:
- Without
limit.input: usable = context - maxOutputTokens -- reserves the model's full output budget.
- With
limit.input: usable = limit.input - min(20K, maxOutputTokens) -- caps the reservation at 20K tokens, which is less than the model's actual max output (e.g. 32K for Claude/GPT-4o).
A model with limit.input = 200K and maxOutputTokens = 32K can grow 12K tokens past the safe compaction boundary before triggering, potentially overflowing the next API call's context window. The missing 12K of headroom means the session grows beyond what the model can actually accept on the next turn.
The COMPACTION_BUFFER cap was introduced as a partial fix, but the two code paths remain asymmetric:
// line 14-19
const reserved =
input.cfg.compaction?.reserved ??
Math.min(COMPACTION_BUFFER, ProviderTransform.maxOutputTokens(input.model, input.outputTokenMax))
return input.model.limit.input
? Math.max(0, input.model.limit.input - reserved)
: Math.max(0, context - ProviderTransform.maxOutputTokens(input.model, input.outputTokenMax))
Fix: Remove the Math.min(COMPACTION_BUFFER, ...) wrapper so both paths reserve the full maxOutputTokens, then delete the unused COMPACTION_BUFFER = 20_000 constant.
- const reserved = input.cfg.compaction?.reserved ??
- Math.min(COMPACTION_BUFFER, ProviderTransform.maxOutputTokens(input.model, input.outputTokenMax))
+ const reserved = input.cfg.compaction?.reserved ??
+ ProviderTransform.maxOutputTokens(input.model, input.outputTokenMax)
The test file at packages/opencode/test/session/compaction.test.ts already has three test cases labeled as known bugs (lines 469-535) that should pass after the fix. Related issues: #10634, #8089, #11086, #12621.
Plugins
n/a
OpenCode version
dev
Steps to reproduce
Set up a model with limit.input (e.g. Claude, Gemini), run a session until the context approaches the limit, and observe that compaction doesn't trigger early enough, causing the next API call to overflow.
Screenshot and/or share link
n/a
Operating System
n/a
Terminal
n/a
Description
In
packages/opencode/src/session/overflow.ts:14-19, theusable()function reserves different output budgets depending on whether the model haslimit.inputset:limit.input:usable = context - maxOutputTokens-- reserves the model's full output budget.limit.input:usable = limit.input - min(20K, maxOutputTokens)-- caps the reservation at 20K tokens, which is less than the model's actual max output (e.g. 32K for Claude/GPT-4o).A model with
limit.input = 200KandmaxOutputTokens = 32Kcan grow 12K tokens past the safe compaction boundary before triggering, potentially overflowing the next API call's context window. The missing 12K of headroom means the session grows beyond what the model can actually accept on the next turn.The
COMPACTION_BUFFERcap was introduced as a partial fix, but the two code paths remain asymmetric:Fix: Remove the
Math.min(COMPACTION_BUFFER, ...)wrapper so both paths reserve the fullmaxOutputTokens, then delete the unusedCOMPACTION_BUFFER = 20_000constant.The test file at
packages/opencode/test/session/compaction.test.tsalready has three test cases labeled as known bugs (lines 469-535) that should pass after the fix. Related issues: #10634, #8089, #11086, #12621.Plugins
n/a
OpenCode version
dev
Steps to reproduce
Set up a model with
limit.input(e.g. Claude, Gemini), run a session until the context approaches the limit, and observe that compaction doesn't trigger early enough, causing the next API call to overflow.Screenshot and/or share link
n/a
Operating System
n/a
Terminal
n/a