anomalyco / anomalyco/opencode

opencode run --format json emits auto-compaction internals as ordinary text events

Open
#42,238 4 comments 0 reactions 1 assignee View on GitHub

@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

  1. Create or resume a session close enough to the model context limit to trigger automatic compaction.
  2. Run:
    opencode run --format json --thinking --auto --session <session-id>
    
  3. Capture stdout JSONL.
  4. 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.ts creates a compaction assistant message marked mode: "compaction", agent: "compaction", and summary: true.
  • Its summary is persisted as an otherwise ordinary text part and is published to the live event stream.
  • cli/cmd/run.ts subscribes 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 dev branch 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.