Skip to content

Feature: noReply flag for display-only commands to skip LLM dispatch #27520

@PeterPonyu

Description

@PeterPonyu
  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Problem

Slash commands that produce display-only output (panels, status confirmations) emit
their entire user-visible content via the command.execute.before hook's parts
output. After that hook returns, the host's command dispatch in
packages/opencode/src/session/prompt.ts always invokes the LLM for the next
assistant turn — wasting a round-trip for every such command, even when the model
has nothing meaningful to do.

A real-world plugin that ships three display-only commands (/show-models,
/pick, /auto-pick) currently emits an "Acknowledged" turn from the model after
each invocation, costing tokens and latency for zero user value.

What I tried in the plugin

Initially I added a template instruction "No further response is required" to each
command. The instruction tells the model to stay silent, but the LLM stream is
still dispatched — the suppression is text-only, not behavioral. Visual QA against
a freshly built opencode confirmed the dispatch happens.

Plugin-side workarounds don't exist:

  • command.execute.before hook output is just { parts } — no flag exposed
  • chat.message hook output is { message, parts } — same
  • client.session.abort() from a hook races the runner becoming busy
  • The plugin Effect runtime dies on throw, so we can't crash the session as a side-channel

Proposed solution

Add an optional noReply?: boolean field to the command schema
(packages/opencode/src/command/index.ts). When set, the dispatch path forwards
noReply: true to prompt(), which already has a short-circuit
(if (input.noReply === true) return message). With this flag, display-only
commands can opt out of the follow-up LLM turn while keeping their existing panel
behavior.

Opt-in and additive: existing commands without noReply keep current behavior.

Verification I did locally

  • 6-line patch on a local fork (PR coming)
  • Typecheck clean (14/14 tasks)
  • bun test test/session/prompt.test.ts — 53/53 pass
  • Visual QA via tmux: baseline window (20s idle) → 0 LLM dispatches; post-/show-models
    window (20s) → 0 LLM dispatches. The flag works end-to-end.

PR forthcoming. Happy to iterate on naming, location, or schema shape.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions