Skip to content

[Bug]: V2 removed UI-only session messages available through ignored + noReply #48644

Open

Description

@remorses

Description

V1 plugins could display a session message without starting the agent and without adding the text to model context:

await client.session.prompt({
  path: { id: sessionID },
  body: {
    noReply: true,
    parts: [{ type: 'text', text: notice, ignored: true }],
  },
})

This was useful for plugin status messages such as provider failover and cooldown notices.

V2 removed noReply and ignored text parts. The closest API is:

await client.session.synthetic({
  sessionID,
  text: notice,
  description: 'Provider fallback',
  resume: false,
})

resume: false prevents an immediate execution, but the synthetic input is later promoted into the transcript as a user-role model message. Compaction also retains it as synthetic context.

V2 needs a way to add a visible session notice that:

  • does not start or resume execution
  • is rendered by TUI, Desktop, and Web clients
  • never enters model context or compaction

This is narrower than #6330. It restores behavior available to V1 server plugins.

Plugins

@subrouter/opencode

OpenCode version

V1: 1.18.23

V2: 2.0.2

Steps to reproduce

  1. Call session.synthetic() with description and resume: false.
  2. Start the next session execution.
  3. Inspect the provider request.
  4. The synthetic text appears as a user-role model message.
  5. There is no V2 equivalent of the V1 ignored: true plus noReply: true behavior.

Screenshot and/or share link

N/A

Operating System

macOS

Terminal

N/A, plugin SDK

Activity

  1. blockspacer commented on Oct 18, 2026

    @blockspacer

    V2 gap has two halves: (a) a visible + model-exempt + compaction-exempt session notice (this issue), (b) noReply on the command path (#46579).

    Zero-cost status notifications — session.prompt({noReply:true, parts:[{type:'text',text,ignored:true}]}) for lifecycle events (paused/maxed/error). On V2 this rejects; our feature-detection falls back to toast-only, which is invisible in web/serve mode.
    Model-invisible control-command results — command.execute.before mutating output.parts (in place) to ignored text parts: visible bubble, excluded from the LLM context (1.19.0-verified). On V2 the ignored part no longer exists, so the result either disappears from the UI or re-enters model context — both break the plugin contract.
    session.synthetic({resume:false}) doesn't substitute: per the repro above it promotes to a user-role model message and is retained in compaction — exactly what the command-path noReply (PR #46579, closed as V1-EOL; maintainer asked for a V2 port) is trying to remove.

  2. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed write-up, @remorses!

    You're asking for a v2 way to add a session notice, such as a provider failover or cooldown message from a plugin, that:

    • does not start or resume execution
    • is shown in the TUI, Desktop and Web clients
    • never reaches model context or compaction

    V1 did this with noReply plus ignored text parts. In v2, session.synthetic always becomes model input (resume: false only delays it), and the plugin API has no display-only message type. So this can't be built as a plugin today; it needs a new addition to the API. One option is a dedicated notice endpoint. Another is a display-only flag on synthetic messages, which would also skip resuming and keep the message out of history and compaction.

    I'm treating this as a feature request, and maintainers will consider it. Related:

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