Repository navigation
fix(opencode): bound the compaction head and mirror the PR-eval model params - #251
Conversation
… params
The umbrella opencode config kept the models.dev generation default and the
stock compaction tail budget. On a long session that combination wedges:
select() budgets only the retained tail, whose default is min(15000, ...), so
once the newest turn exceeds it the summarizer head becomes the ENTIRE
serialized history (all reasoning text retained, tool output capped at 2k).
Measured on session ses_f31022a99ffe1gLJ1RdyDnhlAh (opencode 1.18.32,
ollama-cloud/deepseek-v4.1-flash, 1048576 context):
- auto-compaction fired at a 666,763-token live context;
- the summarizer prompt was 1,122,556 input tokens (logged) — reconstructing
the head with the exact serialize() rules and measuring it through the real
provider gives 1,128,448 (0.5% apart);
- the provider rejected it ("The prompt is too long"), the session was wedged.
The provider admits on INPUT tokens only (probed: 800k prompt + 393216
max_tokens accepted; 1.05M prompt rejected), so reserved/max_tokens do not
size the request — the head does.
Changes:
- compaction.preserve_recent_tokens: 500000 — keeps a large verbatim tail so
the summarized head shrinks. Reconstructed head drops from 1,128,448 to
634,064 real tokens. Stopgap until opencode drops oldest turns itself
(anomalyco/opencode#48844, PR #51121).
- model options: max_tokens 262144, reasoningEffort high, and the sampling set
(temperature 1.0, top_p 0.95, frequency_penalty 0.5, presence_penalty 1.0) —
exact parity with the org PR-eval engine and the vendor-recommended sampling
for deepseek-v4.1-flash.
Upstream: anomalyco/opencode#48844 (open) and anomalyco/opencode#51121 (open,
"drop oldest turns when compaction head exceeds model context").
Assisted-by: opencode ollama-cloud/deepseek-v4.1-flash (analysed on a live system)
Review — PASSHead SHA: Security screen: PASS — diff touches only Verdict: PASS ollama-cloud/deepseek-v4.1-flash — action-review. |
Summary
The umbrella
opencode.jsonused the models.dev generation default plus the stock compaction tail budget. On a long session that combination wedges:select()budgets only the retained tail, whose default ismin(15000, 25% of usable), so once the newest turn exceeds that budget the summarizerheadbecomes the entire serialized history (all reasoning text retained; tool output capped at 2k). The provider rejects the summary request for input length and the session is left unusable.This change bounds the summarized head and mirrors the org PR-eval engine's model parameters.
Session:
ses_f31022a99ffe1gLJ1RdyDnhlAh(opencode 1.18.32, providerollama-cloudathttps://ollama.com/v1, modeldeepseek-v4.1-flash, 1,048,576 context / 393,216 max output).Changes to
opencode.json:compaction.preserve_recent_tokens500000options.max_tokens384000262144options.temperature1.0options.top_p0.95options.frequency_penalty0.5options.presence_penalty1.0preserve_recent_tokenskeeps a large verbatim tail so the summarized head shrinks.AI_REVIEW_*defaults / vars) and the vendor-recommended sampling fordeepseek-v4.1-flash.How tested
1. Root cause measured on the real provider. The crash was a summarizer prompt of 1,122,556 input tokens (logged). Reconstructing the head with opencode's exact
serialize()rules and measuring it through the live provider gives 1,128,448 (0.5% apart; difference = prompt template + prior summary):2. Provider admits on input tokens only (so
reserved/max_tokensdo not size the request):3. The committed config's head fits. With
preserve_recent_tokens: 500000, the reconstructed head measured through the live provider drops to 634,064 tokens:4. Wire parity with the PR-eval. A local echo endpoint captured the request body the committed config actually emits:
matching the org PR-eval engine defaults (
config.go) and org vars:AI_REVIEW_MODEL=deepseek-v4.1-flash,AI_REVIEW_TEMPERATURE=1.0,AI_REVIEW_TOP_P=0.95,AI_REVIEW_FREQUENCY_PENALTY=0.5,AI_REVIEW_PRESENCE_PENALTY=1.0,DefaultMaxTokens=262144.5. Live recovery. The wedged session was resumed under this config and completed the compaction, then continued executing its PR #57 work:
(log continued past compaction into
charly box validate/ mutation-test steps; noContextOverflowError)6. Runnable gates on the committed tree:
charly task verifycould not be run in this environment: nocharlybinary available here implements the newtasksurface (/usr/bin/charlyis 2026.256). This change touches no pins or scripts, sotask verify's assertions (policy B, submodule cleanliness, nested gitlinks) are unaffected.Upstream tracking
This is a stopgap; the permanent fix belongs in opencode:
fix(session): drop oldest turns when compaction head exceeds model context(open; links #48844)I reproduced the failure on opencode 1.18.32 with provider
ollama-cloud/ modeldeepseek-v4.1-flashand documented it on both threads. When #51121 (or an equivalent) lands,compaction.preserve_recent_tokenscan be dropped; it is a tail cap, so the head still grows as a session does. The model-option parity stands regardless.Rulebook compliance
root-cause-analyzer,agent,strict-policy,git-workflow.no/opencode), not the session-shared checkout.Change classification
opencode.json) — no pins, no scripts, no submodules.charly task verifyunavailable in this environment (no new-task-surface binary).analysed on a live system.Assisted-by: opencode ollama-cloud/deepseek-v4.1-flash (analysed on a live system)