mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-02 10:19:37 +00:00
test(cliproxy): add edge case coverage for Gemini schema sanitizer
Add tests for: exclusiveMinimum/exclusiveMaximum/multipleOf stripping, uniqueItems/contains/additionalItems stripping, writeOnly/definitions stripping, example with array values, default with complex nested objects, empty properties/anyOf edge cases. Fix proxy log message to say "Gemini-unsupported" instead of "non-standard".
This commit is contained in:
@@ -218,7 +218,7 @@ export class ToolSanitizationProxy {
|
|||||||
for (const entry of schemaResult.removedByTool) {
|
for (const entry of schemaResult.removedByTool) {
|
||||||
this.writeLog(
|
this.writeLog(
|
||||||
'warn',
|
'warn',
|
||||||
`[tool-sanitization-proxy] Schema sanitized for "${entry.name}": removed ${entry.removed.length} non-standard properties`
|
`[tool-sanitization-proxy] Schema sanitized for "${entry.name}": removed ${entry.removed.length} Gemini-unsupported properties`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.log(
|
this.log(
|
||||||
|
|||||||
@@ -305,6 +305,72 @@ describe('sanitizeInputSchema', () => {
|
|||||||
expect(result.schema).toEqual({ type: 'object' });
|
expect(result.schema).toEqual({ type: 'object' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('strips number/array/object validation fields unsupported by Gemini', () => {
|
||||||
|
const schema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
score: {
|
||||||
|
type: 'number',
|
||||||
|
exclusiveMinimum: 0,
|
||||||
|
exclusiveMaximum: 100,
|
||||||
|
multipleOf: 5,
|
||||||
|
},
|
||||||
|
tags: {
|
||||||
|
type: 'array',
|
||||||
|
items: { type: 'string' },
|
||||||
|
uniqueItems: true,
|
||||||
|
contains: { type: 'string' },
|
||||||
|
additionalItems: false,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
type: 'object',
|
||||||
|
writeOnly: true,
|
||||||
|
definitions: { addr: { type: 'string' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = sanitizeInputSchema(schema);
|
||||||
|
|
||||||
|
expect(result.removedPaths).toContain('properties.score.exclusiveMinimum');
|
||||||
|
expect(result.removedPaths).toContain('properties.score.exclusiveMaximum');
|
||||||
|
expect(result.removedPaths).toContain('properties.score.multipleOf');
|
||||||
|
expect(result.removedPaths).toContain('properties.tags.uniqueItems');
|
||||||
|
expect(result.removedPaths).toContain('properties.tags.contains');
|
||||||
|
expect(result.removedPaths).toContain('properties.tags.additionalItems');
|
||||||
|
expect(result.removedPaths).toContain('properties.meta.writeOnly');
|
||||||
|
expect(result.removedPaths).toContain('properties.meta.definitions');
|
||||||
|
expect(result.removedCount).toBe(8);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('preserves example/default with complex values without recursion', () => {
|
||||||
|
const schema = {
|
||||||
|
type: 'object',
|
||||||
|
example: ['value1', 'value2'],
|
||||||
|
default: { nested: { deep: { unsupportedKey: true } } },
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = sanitizeInputSchema(schema);
|
||||||
|
|
||||||
|
expect(result.removedCount).toBe(0);
|
||||||
|
expect(result.schema.example).toEqual(['value1', 'value2']);
|
||||||
|
expect(result.schema.default).toEqual({ nested: { deep: { unsupportedKey: true } } });
|
||||||
|
});
|
||||||
|
|
||||||
|
test('handles empty properties and anyOf edge cases', () => {
|
||||||
|
const schema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {},
|
||||||
|
anyOf: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = sanitizeInputSchema(schema);
|
||||||
|
|
||||||
|
expect(result.removedCount).toBe(0);
|
||||||
|
expect(result.schema.properties).toEqual({});
|
||||||
|
expect(result.schema.anyOf).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
test('preserves all Gemini-supported fields', () => {
|
test('preserves all Gemini-supported fields', () => {
|
||||||
const schema = {
|
const schema = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
|||||||
Reference in New Issue
Block a user