import { BestAgentError } from "@best-agent/foundation";
import { z } from "zod";
import { normalizeAskUserInput } from "../input-normalization.js";
import { typedToolInputSchema } from "../schema.js";
import { truncate } from "./shared.js";
const ASK_USER_OPTION_SCHEMA = z.strictObject({
    description: z.string().optional(),
    label: z.string().min(1),
});
const ASK_USER_CHOICE_QUESTION_SCHEMA = z
    .strictObject({
    allowCustom: z.boolean().optional(),
    header: z.string().min(1).optional(),
    id: z.string().min(1),
    kind: z.literal("choice").default("choice"),
    multiSelect: z.boolean().optional(),
    options: z.array(ASK_USER_OPTION_SCHEMA).min(2).max(4),
    question: z.string().min(1),
})
    .superRefine((question, context) => {
    const labels = question.options.map((option) => option.label.trim().toLowerCase());
    if (new Set(labels).size !== labels.length) {
        context.addIssue({
            code: "custom",
            message: "Option labels must be unique.",
            path: ["options"],
        });
    }
    if (labels.includes("other")) {
        context.addIssue({
            code: "custom",
            message: 'Do not include an "Other" option; the client adds it automatically.',
            path: ["options"],
        });
    }
});
const ASK_USER_INPUT_QUESTION_SCHEMA = z.strictObject({
    header: z.string().min(1).optional(),
    id: z.string().min(1),
    kind: z.literal("input"),
    multiline: z.boolean().optional(),
    placeholder: z.string().optional(),
    question: z.string().min(1),
});
const ASK_USER_PROVIDER_INPUT_JSON_SCHEMA = {
    additionalProperties: false,
    properties: {
        questions: {
            description: "Ask one or more structured choice questions. Each question must include 3-4 concrete options; the client adds a custom Other answer automatically.",
            items: {
                additionalProperties: false,
                properties: {
                    allowCustom: {
                        description: "Set false only when the user must choose one of the provided options. Default is true.",
                        type: "boolean",
                    },
                    header: {
                        description: "Short label for the question group.",
                        minLength: 1,
                        type: "string",
                    },
                    id: {
                        description: "Stable answer key for this question.",
                        minLength: 1,
                        type: "string",
                    },
                    kind: {
                        description: 'Always use "choice" for provider-generated ask-user prompts.',
                        enum: ["choice"],
                        type: "string",
                    },
                    multiSelect: {
                        description: "Use true only when multiple choices may be selected.",
                        type: "boolean",
                    },
                    options: {
                        description: "Provide 3-4 likely answers. Add concise descriptions for recommended or high-signal choices, for example why one option is recommended.",
                        items: {
                            additionalProperties: false,
                            properties: {
                                description: {
                                    description: 'Optional short detail. Use this to mark recommendations, such as "Recommended based on your current context."',
                                    type: "string",
                                },
                                label: {
                                    description: 'Concise visible label. If one option is the best default, suffix the label with "(Recommended)".',
                                    minLength: 1,
                                    type: "string",
                                },
                            },
                            required: ["label"],
                            type: "object",
                        },
                        maxItems: 4,
                        minItems: 3,
                        type: "array",
                    },
                    question: {
                        description: "User-facing question text.",
                        minLength: 1,
                        type: "string",
                    },
                },
                required: ["id", "kind", "options", "question"],
                type: "object",
            },
            minItems: 1,
            type: "array",
        },
    },
    required: ["questions"],
    type: "object",
};
const ASK_USER_INPUT_SCHEMA = typedToolInputSchema(z.strictObject({
    questions: z
        .array(z.union([ASK_USER_CHOICE_QUESTION_SCHEMA, ASK_USER_INPUT_QUESTION_SCHEMA]))
        .min(1),
}), { jsonSchema: ASK_USER_PROVIDER_INPUT_JSON_SCHEMA });
export function createAskUserTool() {
    return {
        description: "Pause the current turn and collect structured input from the user before continuing. " +
            "Always send choice questions with 3-4 concrete options; the client adds Other automatically for custom answers. " +
            "For open-ended values like city, path, title, label, scope, or preference, still provide likely choices and let Other handle custom input. " +
            'Use option descriptions or a "(Recommended)" label suffix when one option is recommended. Do not send bare strings or option-less questions.',
        executionClass: "external-side-effect",
        idempotent: false,
        inputSchema: ASK_USER_INPUT_SCHEMA,
        name: "ask-user",
        source: "built-in",
        capabilities() {
            return [];
        },
        execute() {
            throw new BestAgentError("TOOL_RUNTIME", "ask-user is handled by the agent runtime.");
        },
        formatInput(input) {
            return input.questions.map((question) => question.question).join(" | ");
        },
        legacyAdapter: {
            adapt(input) {
                return normalizeAskUserInput(input);
            },
        },
        summarize(_input, output) {
            return `Tool ask-user collected ${truncate(output)}.`;
        },
    };
}
//# sourceMappingURL=ask-user.js.map