fix(ask): always allow custom select answers

This commit is contained in:
云服务部-叶林立
2026-08-28 14:26:58 +08:00
parent 221e978622
commit d1b11f86f7
7 changed files with 19 additions and 14 deletions
-4
View File
@@ -45,9 +45,6 @@ export function normalizeQuestions(input: readonly QuestionInput[]): NormalizedQ
throw new Error(`questions[${index}].type must be select or text`);
}
if (question.allowCustom !== undefined && typeof question.allowCustom !== "boolean") {
throw new Error(`questions[${index}].allowCustom must be a boolean`);
}
if (question.required !== undefined && typeof question.required !== "boolean") {
throw new Error(`questions[${index}].required must be a boolean`);
}
@@ -77,7 +74,6 @@ export function normalizeQuestions(input: readonly QuestionInput[]): NormalizedQ
prompt,
type: question.type,
options,
allowCustom: question.type === "select" && question.allowCustom !== false,
required: question.required !== false,
};
});
+1 -2
View File
@@ -20,9 +20,8 @@ const QuestionSchema = Type.Object({
type: Type.String({ enum: ["select", "text"], description: "select for choices; text for a free-form answer" }),
options: Type.Optional(Type.Array(OptionSchema, {
maxItems: MAX_OPTIONS,
description: "Required and non-empty for select questions; omit for text questions",
description: "Required and non-empty for select questions; omit for text questions. The tool always appends a free-form answer choice.",
})),
allowCustom: Type.Optional(Type.Boolean({ description: "For select questions, append a free-form answer choice (default: true)" })),
required: Type.Optional(Type.Boolean({ description: "Whether the question must be answered (default: true); optional questions can be skipped" })),
});
-2
View File
@@ -12,7 +12,6 @@ export interface QuestionInput {
prompt: string;
type: QuestionType;
options?: QuestionOptionInput[];
allowCustom?: boolean;
required?: boolean;
}
@@ -22,7 +21,6 @@ export interface NormalizedQuestion {
prompt: string;
type: QuestionType;
options: QuestionOptionInput[];
allowCustom: boolean;
required: boolean;
}
+1 -1
View File
@@ -82,7 +82,7 @@ export class AskUserView implements Component, Focusable {
const question = this.currentQuestion();
if (!question || question.type !== "select") return [];
const options: RenderOption[] = question.options.map((option) => ({ ...option, kind: "option" }));
if (question.allowCustom) options.push({ value: "", label: "Type something.", kind: "custom" });
options.push({ value: "", label: "Type something.", kind: "custom" });
if (!question.required) options.push({ value: "", label: "Skip this question.", kind: "skip" });
return options;
}