Skip to content

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

Closed

Description

@AmAzing129

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.

Activity

  1. github-actions commented on Aug 13, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  2. dajiaohuang commented on Aug 13, 2026

    @dajiaohuang

    Current dev emits every completed text part from run --format json before resolving the owning message, while the compaction marker lives on that message rather than the part.

    For the JSONL contract, should the fix (a) suppress compaction-summary and synthetic-continuation text entirely, preserving the existing event schema, or (b) emit a distinct control/compaction event with owner metadata? I lean toward (a) because these parts are not user-visible assistant output and it avoids expanding the public stream schema, but the intended compatibility contract needs confirmation before implementation.

  3. vladislav-miroshnikov commented on Sep 9, 2026

    @vladislav-miroshnikov

    @kitlangton #42316 hides compaction-owned parts and synthetic continuation text without changing the JSONL schema. I noticed that its guards also affect normal text output. Should this fix apply only to JSONL, or should both modes hide those internal messages?

    Once that's settled, I can resolve the #43675 overlap while keeping descendant permission tracking and add a focused mocked-compaction output test.

  4. dajiaohuang commented on Sep 10, 2026

    @dajiaohuang

    I recommend hiding compaction-owned parts and synthetic continuation prompts in both --format json and the default text mode. They are internal session mechanics, not user-visible assistant output; exposing them in plain text is the same leak with a less structured consumer. The shared event loop already has one owner-message filter, so applying it to both modes avoids divergent behavior without changing the JSONL schema. Please keep ordinary assistant text (and explicitly requested reasoning) unchanged, and add one default-text regression alongside the JSONL test.

  5. neriousy commented on Oct 19, 2026

    @neriousy
    Member

    In v2, compaction summaries are published as separate compaction events instead of assistant text, and opencode run prints only assistant text in both the default and --format json output. Compaction summaries therefore no longer appear as ordinary text events, and no synthetic continuation prompt is added after compaction. To get v2: npm i -g @opencode/cli@latest or curl -fsSL https://opencode.ai/v2/install | bash (desktop: update the app). If you still see this on v2, please open a new issue with the details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions