mirror of
https://github.com/logancyang/obsidian-copilot.git
synced 2026-07-22 07:50:24 +00:00
Qwen 3.5 (LM Studio) emits returnAll as string "True"/"False" instead of boolean, causing Zod schema validation to fail. Add z.preprocess() to coerce string booleans to actual booleans before validation. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f67e835afb
commit
2bab7acb05
2 changed files with 77 additions and 2 deletions
|
|
@ -19,6 +19,14 @@ describe("SearchTools Schema Validation", () => {
|
|||
})
|
||||
.optional()
|
||||
.describe("Time range for search"),
|
||||
returnAll: z
|
||||
.preprocess((val) => {
|
||||
if (typeof val === "string") {
|
||||
return val.toLowerCase() === "true";
|
||||
}
|
||||
return val;
|
||||
}, z.boolean().optional())
|
||||
.describe("Return all matching notes"),
|
||||
});
|
||||
|
||||
test("validates correct input structure", () => {
|
||||
|
|
@ -100,6 +108,69 @@ describe("SearchTools Schema Validation", () => {
|
|||
const result = localSearchSchema.safeParse(invalidInput);
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
test("accepts boolean returnAll: true", () => {
|
||||
const input = { query: "find all notes", salientTerms: ["notes"], returnAll: true };
|
||||
const result = localSearchSchema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.returnAll).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
test("accepts boolean returnAll: false", () => {
|
||||
const input = { query: "find notes", salientTerms: ["notes"], returnAll: false };
|
||||
const result = localSearchSchema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.returnAll).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
test("coerces string 'True' to boolean true", () => {
|
||||
const input = { query: "find all notes", salientTerms: ["notes"], returnAll: "True" };
|
||||
const result = localSearchSchema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.returnAll).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
test("coerces string 'true' to boolean true", () => {
|
||||
const input = { query: "find all notes", salientTerms: ["notes"], returnAll: "true" };
|
||||
const result = localSearchSchema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.returnAll).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
test("coerces string 'FALSE' to boolean false", () => {
|
||||
const input = { query: "find notes", salientTerms: ["notes"], returnAll: "FALSE" };
|
||||
const result = localSearchSchema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.returnAll).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
test("coerces string 'False' to boolean false", () => {
|
||||
const input = { query: "find notes", salientTerms: ["notes"], returnAll: "False" };
|
||||
const result = localSearchSchema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.returnAll).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
test("accepts omitted returnAll (optional)", () => {
|
||||
const input = { query: "find notes", salientTerms: ["notes"] };
|
||||
const result = localSearchSchema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.returnAll).toBeUndefined();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("webSearchTool schema", () => {
|
||||
|
|
|
|||
|
|
@ -77,8 +77,12 @@ const localSearchSchema = z.object({
|
|||
.optional()
|
||||
.describe("Optional time range filter. Use epoch milliseconds from getTimeRangeMs result."),
|
||||
returnAll: z
|
||||
.boolean()
|
||||
.optional()
|
||||
.preprocess((val) => {
|
||||
if (typeof val === "string") {
|
||||
return val.toLowerCase() === "true";
|
||||
}
|
||||
return val;
|
||||
}, z.boolean().optional())
|
||||
.describe(
|
||||
"Set to true when the user wants ALL matching notes, not just the best few. " +
|
||||
"Use for requests like 'find all my X', 'list every Y', 'show me all my Z', " +
|
||||
|
|
|
|||
Loading…
Reference in a new issue