feat(core): ToolParameter 支持 default、minimum、maximum、enum 字段
- 扩展 ToolParameter 类型,新增 default/minimum/maximum/enum 可选字段 - 更新 buildZodSchema 函数处理 enum 和 min/max 约束 - MCP 工具适配器解析 JSON Schema 中的扩展字段 - task_output 工具使用新字段替代 description 中的约束说明 - 新增单元测试覆盖所有扩展字段
This commit is contained in:
@@ -246,6 +246,121 @@ describe('buildZodSchema', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('扩展字段', () => {
|
||||
it('enum 约束字符串类型', () => {
|
||||
const parameters: Record<string, ToolParameter> = {
|
||||
color: {
|
||||
type: 'string',
|
||||
description: '颜色选择',
|
||||
required: true,
|
||||
enum: ['red', 'green', 'blue'],
|
||||
},
|
||||
};
|
||||
|
||||
const schema = buildZodSchema(parameters);
|
||||
|
||||
expect(schema.safeParse({ color: 'red' }).success).toBe(true);
|
||||
expect(schema.safeParse({ color: 'green' }).success).toBe(true);
|
||||
expect(schema.safeParse({ color: 'yellow' }).success).toBe(false);
|
||||
});
|
||||
|
||||
it('minimum 约束数字类型', () => {
|
||||
const parameters: Record<string, ToolParameter> = {
|
||||
count: {
|
||||
type: 'number',
|
||||
description: '数量',
|
||||
required: true,
|
||||
minimum: 1,
|
||||
},
|
||||
};
|
||||
|
||||
const schema = buildZodSchema(parameters);
|
||||
|
||||
expect(schema.safeParse({ count: 1 }).success).toBe(true);
|
||||
expect(schema.safeParse({ count: 100 }).success).toBe(true);
|
||||
expect(schema.safeParse({ count: 0 }).success).toBe(false);
|
||||
expect(schema.safeParse({ count: -1 }).success).toBe(false);
|
||||
});
|
||||
|
||||
it('maximum 约束数字类型', () => {
|
||||
const parameters: Record<string, ToolParameter> = {
|
||||
limit: {
|
||||
type: 'number',
|
||||
description: '限制',
|
||||
required: true,
|
||||
maximum: 100,
|
||||
},
|
||||
};
|
||||
|
||||
const schema = buildZodSchema(parameters);
|
||||
|
||||
expect(schema.safeParse({ limit: 100 }).success).toBe(true);
|
||||
expect(schema.safeParse({ limit: 50 }).success).toBe(true);
|
||||
expect(schema.safeParse({ limit: 101 }).success).toBe(false);
|
||||
});
|
||||
|
||||
it('minimum 和 maximum 组合约束', () => {
|
||||
const parameters: Record<string, ToolParameter> = {
|
||||
timeout: {
|
||||
type: 'number',
|
||||
description: '超时时间(毫秒)',
|
||||
required: false,
|
||||
minimum: 0,
|
||||
maximum: 600000,
|
||||
},
|
||||
};
|
||||
|
||||
const schema = buildZodSchema(parameters);
|
||||
|
||||
expect(schema.safeParse({}).success).toBe(true);
|
||||
expect(schema.safeParse({ timeout: 0 }).success).toBe(true);
|
||||
expect(schema.safeParse({ timeout: 30000 }).success).toBe(true);
|
||||
expect(schema.safeParse({ timeout: 600000 }).success).toBe(true);
|
||||
expect(schema.safeParse({ timeout: -1 }).success).toBe(false);
|
||||
expect(schema.safeParse({ timeout: 600001 }).success).toBe(false);
|
||||
});
|
||||
|
||||
it('default 字段不影响 Zod 验证', () => {
|
||||
// default 只用于 JSON Schema,Zod 不会自动应用默认值
|
||||
const parameters: Record<string, ToolParameter> = {
|
||||
block: {
|
||||
type: 'boolean',
|
||||
description: '是否阻塞',
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
};
|
||||
|
||||
const schema = buildZodSchema(parameters);
|
||||
|
||||
// 不提供值时仍然是 undefined(不是 true)
|
||||
const result = schema.safeParse({});
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.block).toBeUndefined();
|
||||
}
|
||||
|
||||
// 显式提供值时使用提供的值
|
||||
expect(schema.safeParse({ block: false }).success).toBe(true);
|
||||
});
|
||||
|
||||
it('空 enum 数组使用普通 string', () => {
|
||||
const parameters: Record<string, ToolParameter> = {
|
||||
text: {
|
||||
type: 'string',
|
||||
description: '文本',
|
||||
required: true,
|
||||
enum: [],
|
||||
},
|
||||
};
|
||||
|
||||
const schema = buildZodSchema(parameters);
|
||||
|
||||
// 空 enum 应该退化为普通 string
|
||||
expect(schema.safeParse({ text: 'anything' }).success).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('实际工具参数示例', () => {
|
||||
it('bash 工具参数', () => {
|
||||
const bashParameters: Record<string, ToolParameter> = {
|
||||
|
||||
Reference in New Issue
Block a user