@adeildo/pi-ask-questions
v5.11.2
Published
Lets the model ask you instead of guessing: options with a preview of each, a note on any of them, and your own answer, in a dialog that scrolls with the chat.
Maintainers
Readme
The dialog
The options sit on the left, one line each. The panel on the right shows the option under the cursor: what it means, then what it looks like. The panel is as tall as the tallest option, so the dialog keeps its size while you move. A preview longer than the panel scrolls with shift+↑ shift+↓ or the mouse wheel, with a bar on its edge that shows where you are. A preview drawn with lines or columns keeps its spacing as written, and goes below the options when it is wider than the panel. Under 100 columns the panel always sits below the options.
Several questions become tabs. ● is where you are, ✓ is a question already answered, and submit turns green once every one has an answer.
| Key | Does |
| ------------------- | ---------------------------------------------------------------------- |
| ↑ ↓, a number | Move between the options |
| enter | Choose the option. With several picks allowed, confirm the ones ticked |
| space | Tick an option, when several can be picked |
| tab | Write a note on the option under the cursor |
| ← → | Go to another question, or to submit |
| shift+↑ shift+↓ | Scroll a long preview. pgup pgdn too, outside fullscreen |
| esc | Close without answering. On the typed row or in a note, step back |
Notes
tab writes a note on the option under the cursor, picked or not. You write it in the panel, where there is room, and it stays under the description. The option gets a › while it has one. The note reaches the model with your answer, and "Tree, but too long with five accounts" tells it more than the pick alone. With @adeildo/pi-tasks installed, your picks and notes also count as a message of yours there, so they can settle a decision or approve a task.
Several picks
space ticks and enter confirms. A tick counts as an answer even if you leave the question with the arrows.
Your own words
The last row, Type something., opens an editor in the panel, where shift+enter breaks a line. With several picks allowed, what you type goes along with the options you ticked.
Before it sends
The review tab lists each question with what you said under it: ✓ before a pick, ✎ before your own words, and note before a note, which names its option when you turned that option down. A question without an answer shows ○ not answered. enter sends it anyway, and the model is told which questions were left unanswered.
In the chat
While the model writes the call, the chat shows each question as it arrives, the last one whole with its options. Once written, the call shrinks to one line with the headers, since the dialog under it shows the questions. After you answer, the call keeps the same blocks as the review tab, and ctrl+o shows the questions uncut.
Pi draws this dialog in the flow of the screen, like the permission dialog, so a tall one scrolls with the terminal and the chat above it stays in the scrollback. Over RPC, in an editor plugin or an ACP client, the questions go one at a time through the host's own select and input dialogs, without previews or notes. With no UI at all, the model never sees the tool.
What the model reads
The user answered:
- Layout: "Which layout should the accounts section use?" → "Tree (Recommended)"
note on "Tree (Recommended)": fits how I think
note on "Flat list" (not picked): too long with five accounts
Continue with these answers in mind.The structured answer is the tool result's details, so the session stores it next to the call that asked, on the same branch.
interface Answer {
question: string;
header: string;
picked: string[];
typed?: string;
notes: { option: string; note: string }[];
}Asking from another package
@adeildo/pi-ask-permission draws its dialog with this one, so the permission ask and the model's questions take the same keys and hold the same notes. Any package can do the same through the kit:
import { askQuestions, canAsk } from "@adeildo/pi-kit";
if (canAsk(scope.events)) {
const result = await askQuestions(scope.events, questions);
}A question can set typed: false to leave out the row for your own words, as the permission ask does. The model's tool always has that row. canAsk is a synchronous probe, and it exists because askQuestions would never settle with nobody to draw the dialog. The provider always answers, even when the dialog fails, and the answer carries the error.
Settings
On the Questions tab of Alt+S, stored under questions in ~/.pi/agent/extensions/pi-harness/settings.json:
| Setting | Default | Does | | ------------------- | ------- | ---------------------------------------------------------------------------------------------- | | When and how to ask | empty | Your own words for the model, added to the tool's guidelines. Say when to ask, or what to show | | Ring the bell | on | The terminal bell rings when the questions start waiting for you | | Typing pause | 1s | How long after you stop typing in the editor the questions open | | Typing wait cap | empty | The longest the questions wait while you type. Empty waits for as long as you type |
Coming from rpiv-ask-user-question
The tool is called ask_questions and takes the same parameters as ask_user_question. Remove the other package, or the model gets two tools that do the same thing.
pi remove npm:@juicesharp/rpiv-ask-user-questionWhat differs: a note belongs to an option and not to the question, there is no note for the whole questionnaire, the dialog scrolls with the terminal so there is no key to fold it, a multi-select option can have a preview, the settings are on Alt+S, and the interface is English only.
The schema, the validation, the preview layout and the RPC fallback are ported from rpiv-ask-user-question by juicesharp, under the MIT license. The dialog is new.
Part of pi-harness, which brings every piece in one install.
