File size: 2,290 Bytes
f0634fb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | import { describe, expect, it } from 'vitest';
import { z } from 'zod';
import {
compileToolArgsValidator,
validateToolArgs,
} from '#/tool/args-validator';
import { toInputJsonSchema } from '#/tool/input-schema';
function collectRequired(schema: unknown, acc: string[] = []): string[] {
if (Array.isArray(schema)) {
for (const item of schema) collectRequired(item, acc);
return acc;
}
if (typeof schema !== 'object' || schema === null) return acc;
for (const [key, value] of Object.entries(schema)) {
if (key === 'required' && Array.isArray(value)) {
for (const name of value) if (typeof name === 'string') acc.push(name);
} else {
collectRequired(value, acc);
}
}
return acc;
}
describe('tool input JSON Schema', () => {
const inputSchema = z
.object({
mode: z.enum(['read', 'write']).default('read'),
items: z
.array(
z
.object({
label: z.string(),
description: z.string().default(''),
})
.strict(),
)
.default([]),
})
.strict();
it('keeps defaulted fields out of `required`', () => {
const schema = toInputJsonSchema(inputSchema);
const required = collectRequired(schema);
expect(required).not.toContain('mode');
expect(required).not.toContain('items');
expect(required).not.toContain('description');
expect(required).toContain('label');
});
it('accepts an empty object through runtime argument validation', () => {
const schema = toInputJsonSchema(inputSchema);
const validator = compileToolArgsValidator(schema);
expect(validateToolArgs(validator, {})).toBeNull();
});
it('rejects an unknown top-level argument through runtime validation', () => {
const schema = toInputJsonSchema(inputSchema);
const validator = compileToolArgsValidator(schema);
expect(validateToolArgs(validator, { bogus: true })).not.toBeNull();
});
it('rejects an unknown nested argument through runtime validation', () => {
const schema = toInputJsonSchema(inputSchema);
const validator = compileToolArgsValidator(schema);
expect(
validateToolArgs(validator, {
items: [{ label: 'A', bogus: true }],
}),
).not.toBeNull();
});
});
|