Interactive Prompts (PromptForUserInput)

PromptForUserInput is a built-in Nimbalyst MCP tool that lets your agent collect several inputs from you at once through a single structured widget in the transcript. Instead of asking three narrow questions back-to-back, the agent surfaces one prompt with multiple fields and waits for you to submit.

Use it any time you want to drive a decision visually: ranking, picking from a list, confirming, or editing a draft.

When to use it

Ask for an interactive prompt when you want to:

  • Prioritize a list by dragging items into order (e.g. "help me prioritize my blogs")

  • Approve or reject recommended changes in bulk (e.g. "review these recommended changes to my tracker, keep some, drop others")

  • Edit a short draft inline before the agent acts on it (e.g. tweak a tweet, commit message, or summary)

  • Confirm a destructive or important action

  • Collect a few related answers in one shot instead of a chat back-and-forth

How to trigger it from chat

You usually do not need to name the tool. Just describe the interaction you want:

  • "Show me a prioritization widget for these blog posts so I can drag them into the order I want to publish."

  • "Give me a checklist of the changes you recommend to my tracker so I can approve the ones I like."

  • "Draft a tweet thread for this release and let me edit it before posting."

  • "Ask me to confirm before you run the migration."

If your agent ignores the hint or falls back to plain chat, you can be explicit: "Use the PromptForUserInput tool."

Field types

A single prompt can mix any of these five fields:

  • multiSelect — pick any subset from a list of options. Good for "approve these, skip these".

  • singleSelect — pick exactly one option. Good for choosing a branch, mode, or template.

  • reorder — drag items into the order you want. Supports per-item removal with a configurable minItems floor. Good for prioritization.

  • editText — inline rich-text editor for short drafts. Reuses the same Lexical editor Nimbalyst uses elsewhere in the transcript and on iOS.

  • confirm — yes/no confirmation with custom labels.

Examples

Prioritize blog posts (reorder)

You: I have five blog drafts in /blog/drafts/. Show me a prioritization widget so I can drag them into the order I want to publish, and let me drop any I want to kill.

The agent returns a single prompt with a reorder field listing the five drafts. You drag them into order, click the trash icon on the ones you want to drop, and submit. The agent then continues with the ordered, filtered list.

Approve tracker changes (multiSelect)

You: Look at my open tracker items and recommend changes. Ask me which ones to apply.

The agent surveys your tracker, then surfaces a multiSelect prompt with each recommended change as an option ("Close issue #142 as duplicate", "Re-label #156 as bug", and so on). You check the ones you want, leave the others, and submit. The agent applies only the approved changes.

Draft and edit a tweet (editText + confirm)

You: Draft a tweet announcing the 0.60.1 release and let me edit it before you post anything.

The agent surfaces one prompt with two fields: an editText field pre-filled with the draft, and a confirm field asking whether to post it. You polish the wording in place, flip confirm to yes, and submit.

Voice mode behavior

In Voice Mode, the agent decides per-prompt whether voice can handle the interaction or whether to defer to the on-screen widget. Long drafts and reorders with more than six items default to the screen, since reading them aloud is not useful. Short single-select and confirm prompts stay in voice.

For extension and agent developers

PromptForUserInput is exposed as a standard MCP tool. Any agent that speaks MCP (Claude Code, Codex, OpenCode, GitHub Copilot, your own extension) can call it.

The schema is a flat type-discriminator object, not oneOf. Each field carries a type ("multiSelect", "singleSelect", "reorder", "editText", or "confirm") plus the options or initial value for that type. The response comes back as a JSON object keyed by field id.

A minimal call looks like this:

Notes worth knowing if you are integrating:

  • The wire name is PromptForUserInput, not RequestUserInput. This avoids collision with the Codex CLI's built-in request_user_input tool, which is gated to Plan mode.

  • Responses persist as a synthetic nimbalyst_tool_result on settle, so the canonical tool_call event still picks up the answer even if the SDK subprocess exits before flushing its own tool_result block.

  • iOS round-trips the response through the existing transcript bridge, so the same prompt works on desktop and mobile without separate code paths.

  • iOS reorder uses a 200ms long-press to start a drag, with the selection callout suppressed, so the gesture does not get hijacked into text selection.

  • MCP — overview of Nimbalyst's built-in MCP tools, including AskUserQuestion for simpler multiple-choice prompts.

  • Agent Window & Session Management — where these prompts appear in the transcript.

Last updated