[PR #5321] Add 'displayInput' to bash tool schema #11343

Open
opened 2026-02-16 18:16:10 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/5321

State: open
Merged: No


This keeps tool metadata callbacks in sync with the in-memory toolcall state so display inputs can be passed through to completion. processor.ts now prefers a metadata-updated input when finishing a tool call, allowing modified displays of commands without changing the actual execution.

  • packages/opencode/src/session/prompt.ts: metadata callback updates the live toolcall entry (input/metadata/title/time/displayInput) before persisting, keeping the processor’s map aligned.
  • packages/opencode/src/session/processor.ts: completion/error handling uses match.state.displayInput (from metadata), so the UI shows the plugin-provided display args.

Use case: nix develop bash wrapper plugin

A plugin can wrap the bash tool and modify the final displayed command via displayInput. This is shown to the user through the UI and also modifies the agent history:

"tool.execute.before": async ({ tool }, state) => {
  if (tool.toLowerCase() !== "bash") return
  const command = state.args?.command
  if (!command) return

  // Show the unwrapped command in the UI
  state.args.displayInput = { ...state.args }

  // Run the wrapped command for execution
  state.args.command = `nix develop --quiet -c bash -c "${command.replace(/"/g, '\\"')}"`
}

Before:

$ nix develop --quiet -c bash -c "echo \"hello\""

After:

$ echo "hello"

This has many use cases other than just nix, e.g. sandbox-esque wrappers where the full wrapped command is not relevant enough to be constantly showing to the user or agent, and would otherwise clutter history.

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/5321 **State:** open **Merged:** No --- This keeps tool metadata callbacks in sync with the in-memory toolcall state so display inputs can be passed through to completion. `processor.ts` now prefers a metadata-updated input when finishing a tool call, allowing modified displays of commands without changing the actual execution. - `packages/opencode/src/session/prompt.ts`: metadata callback updates the live toolcall entry (input/metadata/title/time/displayInput) before persisting, keeping the processor’s map aligned. - `packages/opencode/src/session/processor.ts`: completion/error handling uses `match.state.displayInput` (from metadata), so the UI shows the plugin-provided display args. ## Use case: `nix develop` bash wrapper plugin A plugin can wrap the `bash` tool and modify the final displayed command via `displayInput`. This is shown to the user through the UI and also modifies the agent history: ```ts "tool.execute.before": async ({ tool }, state) => { if (tool.toLowerCase() !== "bash") return const command = state.args?.command if (!command) return // Show the unwrapped command in the UI state.args.displayInput = { ...state.args } // Run the wrapped command for execution state.args.command = `nix develop --quiet -c bash -c "${command.replace(/"/g, '\\"')}"` } ``` Before: `$ nix develop --quiet -c bash -c "echo \"hello\""` After: `$ echo "hello"` This has many use cases other than just nix, e.g. sandbox-esque wrappers where the full wrapped command is not relevant enough to be constantly showing to the user or agent, and would otherwise clutter history.
yindo added the pull-request label 2026-02-16 18:16:10 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#11343