anomalyco / anomalyco/opencode
opencode run --format json emits auto-compaction internals as ordinary text events
@kitlangton is already working on this.
Since Aug 13, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
When automatic compaction occurs, opencode run --format json --thinking --auto emits internal compaction output as normal type: "text" JSONL events. This includes the compaction assistant summary and, in some cases, the synthetic user continuation prompt. JSONL consumers cannot distinguish these from user-visible assistant output.
Reproduction
- Create or resume a session close enough to the model context limit to trigger automatic compaction.
- Run:
opencode run --format json --thinking --auto --session <session-id> - Capture stdout JSONL.
- After compaction, observe normal text events containing the compaction summary and possibly:
Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed.
Expected behavior
Ordinary text events should contain only final, user-visible assistant output. Internal compaction content should either be omitted, emitted as a distinct control/compaction event, or include enough owner-message metadata (role, summary, mode, agent) for consumers to filter it safely. In particular, synthetic user content must not be emitted as visible assistant text.
Actual behavior
The JSON runner outputs completed text parts based on part.type === "text" and part.time.end, without checking the owner message. Consequently, these internal parts are emitted as normal text, for example:
{"type":"text","part":{"type":"text","text":"<internal compaction summary>"}}
{"type":"text","part":{"type":"text","text":"Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed.","synthetic":true,"metadata":{"compaction_continue":true}}}
This can expose compaction summaries that include serialized history, tool-call/tool-result transcripts, or other internal content. One downstream integration observed an erroneous 73,227-character assistant message containing 26 tool calls and 27 tool results.
Root-cause evidence
session/compaction.tscreates a compaction assistant message markedmode: "compaction",agent: "compaction", andsummary: true.- Its summary is persisted as an otherwise ordinary text part and is published to the live event stream.
cli/cmd/run.tssubscribes to that stream and emits completed text parts without inspecting their owner message.- After successful automatic compaction, the synthetic continuation user message can also be published; the same missing role/owner filtering allows it to be emitted as
text.
Filtering only part.synthetic would not fully fix this: compaction-summary text parts themselves do not carry that flag.
Environment
- OpenCode repository: current
devbranch as of 2026-08-13 - Command:
opencode run --format json --thinking --auto [--session <id>] - Plugins: none required
- OS: any (non-interactive JSON runner behavior)
A regression test could publish a completed compaction-summary assistant text part and a synthetic continuation user text part to the runner event loop, then assert neither is emitted as a normal text event.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.