Let bots ask multiple-choice questions before acting

ask_user puts up to six questions on one card (radios for one pick,
checkboxes for several, an optional typed Other) as a [question:ID] chip.
The user's answers are checked against the questions, stored in
bot_questions and sent to the bot as their chat message; Skip says so.
Offered in chat replies and user-started tasks, never in routines, hook
calls or chatroom sessions.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-28 11:10:23 +01:00
co-authored by Claude Opus 5.5
parent 07f87ce4ea
commit d7dfe0e78e
45 changed files with 1448 additions and 6 deletions
+40
View File
@@ -34,6 +34,7 @@ import type { ImageInputToBase64FunctionReturn } from "@moduletrace/twui/utils/f
import type { HarnessKind } from "../dict/harness-dict";
import type { HarnessProviderKind } from "../dict/harness-provider-dict";
import type { EnvParadigm, KnownEnv, SecretRequestStatus } from "../dict/env-dict";
import type { BotQuestionKind, BotQuestionStatus } from "../dict/bot-question-dict";
import type { ContainerStatus } from "../dict/computer-dict";
import type { BotFace, BotKind, BotMessageReactionEmoji } from "../dict/bot-dict";
import type { HarnessCallSettings, TokenUsageSummary } from "../harness/usage/types";
@@ -738,6 +739,45 @@ export type BotGraphicView = {
updated_at: number;
};
/**
* One question a bot asks the user before acting (`ask_user`).
*/
export type BotQuestionItem = {
question: string;
kind: BotQuestionKind;
options: string[];
/**
* Whether the user may type an answer of their own ("Other").
*/
allow_other: boolean;
};
/**
* The user's answer to one question: the options they picked (by index)
* and what they typed into "Other" (empty if nothing).
*/
export type BotQuestionAnswer = {
choices: number[];
other: string;
};
/**
* Questions a bot asked the user (`[question:ID]`), as their chip and card
* show them.
*/
export type BotQuestionView = {
id: number;
title: string;
questions: BotQuestionItem[];
/**
* One per question once answered, else null.
*/
answers: BotQuestionAnswer[] | null;
status: BotQuestionStatus;
bot_id: number;
bot_name: string;
};
export type SecretRequestView = {
id: number;
key: string;