/**
 * ============================================================
 *  src/tools/ask/ask.ts —— AskUserQuestion 工具（向用户提结构化选择题）
 * ------------------------------------------------------------
 *  对齐上游 Claude Code 的 AskUserQuestion：让模型在「需要用户拍板」时停下来问，
 *  而不是替用户瞎猜。它本身只是一个普通工具 —— call() 调 askBridge 的
 *  requestUserChoice()，TUI 弹选择界面、用户选完把答案当 tool_result 喂回模型。
 *  「等用户」= 这个工具返回得慢；非交互宿主（-p/gateway）自动选推荐项（见 askBridge）。
 *
 *  这一个工具同时让主循环 / workflow（tool: AskUserQuestion）/ agent: 节点
 *  都获得「问用户」的能力 —— 动态工作流的交互底座。
 * ============================================================
 */
import { z } from 'zod';
import { requestUserChoice } from '../../askBridge.js';
import { DEFAULT_MAX_RESULT_SIZE_CHARS } from '../types.js';
import { toToolParameters } from '../../utils/zodToJson.js';
// ---------------- 1. Zod 输入 schema ----------------
const optionSchema = z.object({
    label: z
        .string()
        .min(1)
        .describe('选项显示文本（简洁）；把推荐项放第一个，并在其 label 末尾标「(推荐)」'),
    description: z
        .string()
        .optional()
        .describe('该选项的说明 / 取舍，帮用户理解后果'),
});
const questionSchema = z.object({
    question: z.string().min(1).describe('要问用户的完整问题'),
    header: z
        .string()
        .min(1)
        .describe('问题的短标签（≤12 字），如「交互底座」「鉴权方式」'),
    multiSelect: z
        .boolean()
        .optional()
        .describe('是否允许多选；默认 false（单选）'),
    options: z
        .array(optionSchema)
        .min(2)
        .max(4)
        .describe('2-4 个互斥选项；第一个应为你的推荐项'),
});
const inputSchema = z.object({
    questions: z
        .array(questionSchema)
        .min(1)
        .describe('1-4 个问题（通常 1 个；确需一次问多件事时才多个）'),
});
// ---------------- 2. JSON Schema（由 Zod 自动派生） ----------------
const parameters = toToolParameters(inputSchema);
// ---------------- 3. Description（指导模型何时/如何用） ----------------
const description = `向用户提出结构化的选择题（最多 4 题，每题 2-4 个选项），用于需要用户做决定的场合。
使用时机：
- 需求 / 方案有取舍、没有绝对对错（多个合理方案各有利弊）→ 让用户拍板；
- 关键信息缺失或模糊、继续做风险大 → 让用户补充。
不要用于：你自己能从代码 / 上下文 / 常识判断出答案的问题（那样只会打断用户）。
约定：每题第一个选项放你的推荐，并在其 label 末尾标「(推荐)」。
界面会自动附带「其他（自由输入）」逃生项，**无需**你手动加。
返回值是用户的选择文本，据此继续。`;
// ---------------- 4. call() ----------------
async function call(input, signal) {
    try {
        const answers = await requestUserChoice(input.questions, signal);
        const lines = ['用户已回答 AskUserQuestion：', ''];
        answers.forEach((a, i) => {
            lines.push(`Q${i + 1} [${a.header}] ${a.question}`);
            lines.push(`A${i + 1}: ${a.selected.join('、') || '(未选)'}`);
            lines.push('');
        });
        return { ok: true, content: lines.join('\n').trimEnd() };
    }
    catch (e) {
        // 用户 ESC / Ctrl+C 取消提问 → 当普通工具失败喂回（主循环让模型换思路；
        // workflow tool 步骤则按 onError 处理）。
        return { ok: false, error: `提问被取消 / 中断：${e.message}` };
    }
}
// ---------------- 5. 导出 ----------------
export const askUserQuestionTool = {
    name: 'AskUserQuestion',
    description,
    inputSchema,
    parameters,
    isReadOnly: true,
    isConcurrencySafe: false,
    maxResultSizeChars: DEFAULT_MAX_RESULT_SIZE_CHARS,
    call,
};
