When the model needs a decision from you — which approach to take, which target to use, confirm a plan — instead of writing “tell me A or B” as loose text, it calls the ask_user tool (@ask). You answer in an interactive overlay (Bubble Tea, the same engine as the command palette) and the selections return to the model in the same turn. It is the equivalent of Claude Code’s AskUserQuestion.
Where it works
| Mode | Available | Note |
|---|
Agent (/agent) | ✅ | Alongside the other tools (native or via XML) |
Coder (/coder) | ✅ | Same, under the same security policy |
| Chat | ✅ (controlled exception) | Chat is tool-less by design; the exception opens only for ask_user and the read-only knowledge base query, never for execution tools |
The interface
Each call carries 1 to 6 questions. For every question:
- a short header and the question text;
- a list of options (label + description);
- single-select (radio
(•)) or multi-select (checkbox [x]);
- an “Other” row to type a free-text answer.
Controls
| Key | Action |
|---|
↑ / ↓ | Move the cursor |
space | Toggle (multi) · mark the radio (single) · focus the “Other” field |
enter | Confirm the question and advance (finishes after the last one) |
esc | Back to the previous question · cancel on the first |
| typing | Fill the “Other” field (when focused) |
[1/2] Database
Which database should I use?
❯ (•) Postgres Relational, ACID
( ) SQLite Embedded, zero-config
[+] Other (type a custom answer)…
↑/↓ move · space/enter select · esc back/cancel
Single vs multiple choice
The model decides, per question, via the multiSelect field:
multiSelect: false (or omitted) → single choice (radios).
multiSelect: true → multiple choice (checkboxes [x]); space toggles several and enter confirms the set.
To steer toward multiple choice, just ask: “ask me, allowing multiple choices, which environments…”.
Chat-mode exception
Chat mode is tool-less by design — it never executes tools. There are two sanctioned exceptions, both harmless by construction: ask_user (interactive) and the read-only knowledge base query (/config chat knowledge). When enabled, chat offers exclusively those tools (no file read/write/exec tools).
It works with any provider:
- Providers with native tools (Claude via API key, OpenAI…): a structured decision turn.
- Providers without native tools (e.g. Claude in OAuth mode): an XML decision turn, with the format injected and the markup suppressed before it reaches the screen.
In both cases, after you answer, the same prompt spinner as a normal turn shows while the AI composes the final answer.
Enable/disable
The chat exception is on by default and can be controlled at runtime:
/config chat # status: mode (native/XML) and whether it's active
/config chat ask on # enable
/config chat ask off # disable (chat goes back to fully tool-less)
/config chat ask toggle # flip
For a permanent default, set it in .env:
CHATCLI_CHAT_ASK=true # (default) or false to turn off
With the exception on, every chat turn goes through a buffered decision turn (needed to detect/suppress the call before showing it). If you prefer token-by-token streaming day-to-day, use /config chat ask off.
Non-interactive contexts
In unattended runs (gateway/daemon), a pipe, or one-shot (-p) there is no terminal for the overlay. In those cases ask_user does not block: it returns the first option of each question as a deterministic fallback, states clearly that it was auto-selected, and the flow continues.
Result for the model
The answer returns as a readable summary followed by a canonical JSON block, so both weak and strong models parse it unambiguously:
User answered:
- Database → Postgres
- Environments → staging, prod
{"answers":[
{"header":"Database","selected":["Postgres"],"other":""},
{"header":"Environments","selected":["staging","prod"],"other":""}
]}
Canceling (Esc) is not an error: the model receives a note that you did not answer and proceeds with reasonable defaults or asks again in text.
See also