Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ask

Lets the model ask you one question in the middle of a turn and go on with your answer: which of two things you meant, or a value it cannot find. A question is not a permission: no answer runs anything, and every command the model runs afterwards still passes the policy, the classifier, the gate, and the sandbox. Decided in ADR 0062; the inquiry effect each face carries is in ADR 0044’s terms.

Off by default. Like memory and models, a conversation gets it only when its tool list names it or the setting turns it on for every conversation given every tool:

wisp config set tools.ask true

or /config set tools.ask on in chat, or "tools": { "ask": true } in ~/.wisp/config.json; it applies from the next conversation.

Conversationask
Every tool (no --tool, MCP respond without tools, chat), tools.ask off (the default)No
Every tool, tools.ask: trueYes
A named list (--tool ask, MCP tools: ["ask"])Only when the list names it, whatever the setting says
tools.disabled: ["ask"]No, anywhere

So the MCP git thread of AGENTS.md (tools: ["run_command"]) never sees it.

Contract

FieldValue
Nameask
Description (what the model sees)Ask the person one question when you cannot go on without their answer: which of two things they meant, or a value you cannot find. Not for permission (commands ask for themselves), not for secrets. Give options when there are few.
questionThe question, 1 to 300 characters, one paragraph
optionsFor a choice: 2 to 6 options of up to 80 characters each, all different. Left out for free text
ShapeYou answerThe model gets
Free text (no options)A line of textanswer: <text>, then (from the person)
A choiceOne option, or none of thesechose: <option>, or the person chose none of these options
Yes or noA choice of yes and nochose: yes

Every other outcome is a fixed line the model can read: the person declined to answer. Do not ask this again; say in your reply what you needed; no answer within 5 min. Do not guess what the person would say. Say in your reply what you need, and stop (only when a deadline is set); no person can answer here (wisp respond); say in your reply what you need; under wisp mcp, waiting for the person: "…" (question a1b2c3d4). Their answer reaches you as a note on a later turn. Do not guess it. … (../mcp.md, “Questions”). Silence is never an answer: the model is told to stop, and the verification pass flags a reply that says you chose or confirmed something when no question was answered (../verification.md).

Limits and controls

ControlValue
WaitingOne question at a time on a thread; a second ask while one waits is error: a question is already waiting for the person; …
Per turnTwo; a third is error: you have asked 2 questions this turn; say in your reply what you still need, and stop. The same question twice in a turn is refused
SecretsA question that asks for a password, passphrase, token, API key, secret, private key, PIN, one-time or 2FA code, credentials, access key, or login details is refused by rule before anyone sees it: error: ask does not ask for secrets; tell the person what is needed and where to set it. The rule can be talked round (“the thing you log in with”), so the answer is scanned too: a credential-shaped value in your answer (the secret rules of scan_secrets) is replaced by its numbered marker, [REDACTED:aws-access-key#1], in what the model gets and everywhere wisp records the answer, and chat tells you it was not passed on
The answerUp to 2,000 bytes; longer is cut with a note
How longinquiry.timeoutSeconds, default 0: until you answer, however long you are away. A positive value, 10 to 86,400, sets a deadline; past it the question ends unanswered and the model is told to stop
Shown asThe model’s: escaped (control characters and bidirectional overrides written as \e, \u{202E}), labelled “the model asks”, never styled as an approval and never offered an approval’s keys, so a question such as “Approve rm -rf build? [y/n]” cannot pass for wisp’s own gate
Auditinquiry.requested and inquiry.settled on the asking thread, with the answer verbatim (markers applied), and the ask call’s tool.call and tool.result as for every tool; under wisp mcp also inquiry.parked, and inquiry.answered in the process you answered from (../logging.md)
FactAn answer becomes a fact of the thread, subject answer, named by the question (cut to 80 characters), source person, so condensing never loses it; never permanent on its own (../context-management.md, “Facts”)

How each face asks

FaceThe dialogYou answer
Plain chatOn the terminal, under ? the model asks: the question, then the numbered options with none of these last, then a prompt. Read in a way Ctrl-C and the deadline can end, so the turn waits for you as long as you takeA number or the text; Enter alone declines; Ctrl-C stops the turn
wisp chat --json, wisp-tuiA choice line with kind: "question" (and acceptsText for free text), which wisp-tui shows as a picker titled “the model asks”, with where the answer goesThe choose line; Esc declines, Ctrl-C declines, a second Ctrl-C stops the turn
wisp mcpFiled in ~/.wisp/pending/<id>.question.json and announced by one notification, “wisp: the model asks” (“Which config? — wisp questions answer a1b2c3d4”); with inquiry.elicitation on (off by default), the client’s dialog too. The call holds for 60 s, then the turn parks and the answer reaches the thread’s next turn (../mcp.md, “Questions”)wisp questions answer ID from a terminal, which prompts for the text, a running wisp-tui, or a plain wisp chat at a terminal, which notes the question before its prompt and answers with /questions answer ID (prompting for the text) or /questions decline ID; wisp questions decline ID
wisp respond, --yesNot askedask returns no person can answer here at once

Who may answer: you, in one of wisp’s faces. The agent that called wisp mcp cannot: nothing in the MCP conversation answers a question, wisp’s own model is refused wisp questions answer|decline by the default policy and cannot write ~/.wisp from the sandbox, and the command runs only from a terminal (../trust.md). Your answer is not private from that agent: a thread’s output, context, facts, and audit are readable through wisp://threads/{thread_id}, and the dialog says so.

Example

› Replace the config with the new defaults.

  ⚙ ask Which config did you mean?

? the model asks
  Which config did you mean?
  1  ~/.wisp/config.json
  2  ./wisp.json
  3  none of these
  type a number, or press Enter to decline › 2

The model gets chose: ./wisp.json and goes on in the same turn; the answer is c4 answer "Which config did you mean?" = ./wisp.json among the turn’s facts.