/** * Ask Tool - the model asks the user to fill in one HTML `
`. * * Hosts with a form surface (`ui.formDialog`: the interactive TUI, ACP) render * the form whole; every other host walks its named fields one prompt at a time * through `select`/`input`/`editor`. The model receives the submitted form data * as JSON. Outside plan mode a configurable timeout submits the form's * preselected values. */ import { type as arkType } from "@oh-my-pi/omptype"; import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core"; import type { ToolExample } from "@oh-my-pi/pi-ai"; import { TERMINAL } from "@oh-my-pi/pi-tui"; import { formatKeyHint } from "@oh-my-pi/pi-tui/app-keybindings"; import { editorKey, editorKeys } from "@oh-my-pi/pi-tui/chrome/keybinding-hints"; import { choiceValue, defaultFormData, fieldQuestions, fieldError, formAnswers, type HtmlFormData, OTHER_LABEL, textValue, } from "@oh-my-pi/pi-tui/html-form/data"; import { type ChoiceField, type HtmlForm, parseHtmlForm, spansText, type TextField, } from "@oh-my-pi/pi-tui/html-form/parse"; import { disambiguateDisplayLabels } from "@oh-my-pi/pi-tui/render/render-utils"; import { theme } from "@oh-my-pi/pi-tui/theme"; import type { AskToolDetails } from "@oh-my-pi/pi-tui/tools/ask"; import { ToolError } from "@oh-my-pi/pi-tui/tools/tool-errors"; import { isRecord, prompt, untilAborted } from "@oh-my-pi/pi-utils"; import type { ExtensionUIContext, ExtensionUIDialogOptions, ExtensionUISelectItem } from "../extensibility/extensions"; import { askTimeoutMs, cfgAskNotify } from "../modes/settings"; import askDescription from "../prompts/tools/ask.md" with { type: "text" }; import askHeadlessForkMessage from "../prompts/tools/ask-headless-fork.md" with { type: "text" }; import { cfgSpeechEnabled } from "../tts/settings"; import { vocalizer } from "../tts/vocalizer"; import type { ToolSession } from "."; import { ToolAbortError } from "./tool-errors"; /** Returned to a headless fork's model instead of aborting its run. */ const HEADLESS_FORK_ASK_ERROR = prompt.render(askHeadlessForkMessage); const NO_NAMED_CONTROLS_ERROR = "Error: the form has no named controls. Put at least one ,