Repository navigation
Description
Summary
Manual compaction (/compact) on v2.0.27 completes and produces a summary, but the next request still contains the entire previous conversation. The context size does not drop. Compaction triggered as recovery after a provider "too long" rejection works correctly, so the regression appears specific to the manual path.
Environment
- opencode version: 2.0.27 (updated today; previous version unknown)
- OS: Linux 7.2.9-2-cachyos (x64)
- Terminal: TERM=xterm-256color, COLORTERM=truecolor
- Shell: /bin/fish
- Install/channel: latest (install script,
~/.opencode/bin/opencode) - Active plugins: none configured; MCP server
playwright(local) configured - Model: local strata (llama.cpp) server via
@ai-sdk/openai-compatible(openai-compatible), serving a Qwen 3.8 Next iQ3_XS quantization,limit.context: 200000,limit.output: 32000. (The model name/GGUF path declared inopencode.jsoncis stale and does not match the model actually served.)
Reproduction
- Start a session with a local openai-compatible provider (llama.cpp, context 200k, output 32k) and grow the conversation to ~130k prompt tokens.
- Run manual compaction (
/compact). The summary is generated and the compaction message is recorded withstatus: "completed",reason: "manual". - Send the next user message and inspect the prompt tokens of the next assistant request (e.g.
tokens.input + tokens.cache.readon the assistant message).
Expected Behavior
After compaction, the next request should contain system prompt + summary + the recent window (~keep.tokens = 15k), i.e. roughly 25–30k tokens.
Actual Behavior
The next request contains the full previous conversation plus the summary:
- Compaction feat: compact and other improvements #1 at 18:35:11 → next request 150 878 tokens (conversation was ~137k before).
- Compaction feat: model config persistence #3 at 19:02:36 → next request 106 441 tokens.
The session then keeps growing and the provider rejects requests, e.g.:
prompt (171843 tokens) + max tokens (28167) exceeds the context (200000); requests are never truncated
Additional Context
Timeline from one session today (session ses_ecebb6ce5ffeDOXAodWeNMLYUi), all three compactions recorded as reason: "manual", status: "completed":
| Time | Event | Next request prompt size |
|---|---|---|
| 18:33:17 | opencode binary updated to 2.0.27; service restarted 18:33:23 | — |
| 18:35:11 | Manual compaction #1, summary 2 008 output tokens | 150 878 ❌ |
| 18:39:16 | Provider rejection: prompt (171843) + max tokens (28167) exceeds the context (200000) |
— |
| 18:40:14 | Compaction #2 (recovery after rejection), summary 2 362 output tokens | 27 215 ✅ |
| 19:02:36 | Manual compaction #3, summary 2 762 output tokens | 106 441 ❌ |
| 19:04:25 | Next user message → 106k prompt → request error at 19:05:14 | — |
Notable detail: the summarization request input sizes differ sharply between the two paths:
- Manual compactions feat: compact and other improvements #1/feat: model config persistence #3: summarization request input ≈ 15–21k tokens (only the recent window is sent to the summarizing model), and the full old conversation is kept in the next request.
- Recovery compaction Roadmap & Existing Issues #2: summarization request input ≈ 145k tokens (full conversation), and the next request correctly drops to 27k.
This suggests the manual path computes the compaction anchor at the start of the conversation (summarizing the recent window and keeping the older conversation) instead of at the end.
Other notes:
- The problem appeared today, right after updating to 2.0.27 (binary mtime 18:33:17, first manual compaction 18:35:11). Earlier sessions on the previous version compacted correctly (e.g. 96k → 30k, 129k → 39k, 94k → 35k prompt tokens).
opencodeupdate checks fail today:UpgradeError: The update service returned HTTP 500.(so a fix may exist in a newer release).- Workaround applied: rely on automatic compaction with a larger buffer (
"compaction": { "auto": true, "buffer": 40000 }) so the working recovery/auto path runs before the provider rejects the request; avoid manual/compacton 2.0.27.
Activity
opencode-agent commentedon Oct 12, 2026
Thanks for the detailed report and the token timeline. I was able to reproduce this on 2.0.27, and it still happens on the latest
dev(80fb31eb).Setup: a simulated model, default
keep.tokens(15k), three short exchanges, then one user message followed by a single very long assistant turn (about 60k tokens) with no user message after it. Then/compactand one more message:The script below reproduces it and logs every request's size; the recording shows the TUI side.
The likely cause is how compaction picks what to keep. It measures
keep.tokensfrom the end, then walks back to the nearest earlier user message and keeps everything after it as text. When the work since your last message is long (for example a long agent run), most of the conversation is kept verbatim and only the older part is summarized. That would also explain why your recovery compaction worked: it ran right after a new message, so the last user message was near the end. The cause is most likely the same as #43250; #51818 (reasoning kept in full) can make it worse.Until this is fixed, two things should help:
/compact.compaction.bufferyou already set up.recording.mp4
Reproduction script (drive.ts)
Run it with opencode-drive:
opencode-drive run ./drive.ts. It drivesopencodefrom yourPATH; setOC_DEVto the path of an OpenCode checkout to run that from source instead.Finn763 commentedon Oct 19, 2026
I'd like to work on this — manual compaction completes but the following request still carries the full history, while recovery compaction truncates it. I'll trace the two paths and pin the difference with a test.
zeetkt commentedon Oct 20, 2026
I haven't managed to replicate the problem recently (well, I haven't really TRIED to replicate it), but it hasn't occurred naturally lately, I suspect there's been some kind of fix.
xxwtiancai commentedon Oct 25, 2026
Re-ran the reproduction script from the bot's comment on current
dev(e0b6039e1) — still reproduces. The first request after/compactis ~66k tokens and contains the long turn verbatim, instead of summary + ~15k keep:One difference from the original repro: the summarize request now includes the whole conversation (~82k tokens, presumably after #57091), but the keep window still preserves the long autonomous run verbatim.
@Finn763 are you still planning to work on this? If not, I'd like to take it.