diff options
| author | Wanlin Du <[email protected]> | 2025-08-11 16:12:41 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-08-11 23:12:41 +0000 |
| commit | d9fb08c9da3d2e8c501ec9badb2e2bd79eb15b93 (patch) | |
| tree | 7d07e1586b736c1b6c44e28828aa29205af335ac /packages/core/src/tools/tool-registry.test.ts | |
| parent | f52d073dfbfa4d5091a74bf33ac1c66e51265247 (diff) | |
feat: migrate tools to use parametersJsonSchema. (#5330)
Diffstat (limited to 'packages/core/src/tools/tool-registry.test.ts')
| -rw-r--r-- | packages/core/src/tools/tool-registry.test.ts | 222 |
1 files changed, 16 insertions, 206 deletions
diff --git a/packages/core/src/tools/tool-registry.test.ts b/packages/core/src/tools/tool-registry.test.ts index d8e536b7..13dff08c 100644 --- a/packages/core/src/tools/tool-registry.test.ts +++ b/packages/core/src/tools/tool-registry.test.ts @@ -15,19 +15,9 @@ import { Mocked, } from 'vitest'; import { Config, ConfigParameters, ApprovalMode } from '../config/config.js'; -import { - ToolRegistry, - DiscoveredTool, - sanitizeParameters, -} from './tool-registry.js'; +import { ToolRegistry, DiscoveredTool } from './tool-registry.js'; import { DiscoveredMCPTool } from './mcp-tool.js'; -import { - FunctionDeclaration, - CallableTool, - mcpToTool, - Type, - Schema, -} from '@google/genai'; +import { FunctionDeclaration, CallableTool, mcpToTool } from '@google/genai'; import { spawn } from 'node:child_process'; import fs from 'node:fs'; @@ -254,18 +244,18 @@ describe('ToolRegistry', () => { }); describe('discoverTools', () => { - it('should sanitize tool parameters during discovery from command', async () => { + it('should will preserve tool parametersJsonSchema during discovery from command', async () => { const discoveryCommand = 'my-discovery-command'; mockConfigGetToolDiscoveryCommand.mockReturnValue(discoveryCommand); const unsanitizedToolDeclaration: FunctionDeclaration = { name: 'tool-with-bad-format', description: 'A tool with an invalid format property', - parameters: { - type: Type.OBJECT, + parametersJsonSchema: { + type: 'object', properties: { some_string: { - type: Type.STRING, + type: 'string', format: 'uuid', // This is an unsupported format }, }, @@ -308,12 +298,16 @@ describe('ToolRegistry', () => { expect(discoveredTool).toBeDefined(); const registeredParams = (discoveredTool as DiscoveredTool).schema - .parameters as Schema; - expect(registeredParams.properties?.['some_string']).toBeDefined(); - expect(registeredParams.properties?.['some_string']).toHaveProperty( - 'format', - undefined, - ); + .parametersJsonSchema; + expect(registeredParams).toStrictEqual({ + type: 'object', + properties: { + some_string: { + type: 'string', + format: 'uuid', + }, + }, + }); }); it('should discover tools using MCP servers defined in getMcpServers', async () => { @@ -365,187 +359,3 @@ describe('ToolRegistry', () => { }); }); }); - -describe('sanitizeParameters', () => { - it('should remove default when anyOf is present', () => { - const schema: Schema = { - anyOf: [{ type: Type.STRING }, { type: Type.NUMBER }], - default: 'hello', - }; - sanitizeParameters(schema); - expect(schema.default).toBeUndefined(); - }); - - it('should recursively sanitize items in anyOf', () => { - const schema: Schema = { - anyOf: [ - { - anyOf: [{ type: Type.STRING }], - default: 'world', - }, - { type: Type.NUMBER }, - ], - }; - sanitizeParameters(schema); - expect(schema.anyOf![0].default).toBeUndefined(); - }); - - it('should recursively sanitize items in items', () => { - const schema: Schema = { - items: { - anyOf: [{ type: Type.STRING }], - default: 'world', - }, - }; - sanitizeParameters(schema); - expect(schema.items!.default).toBeUndefined(); - }); - - it('should recursively sanitize items in properties', () => { - const schema: Schema = { - properties: { - prop1: { - anyOf: [{ type: Type.STRING }], - default: 'world', - }, - }, - }; - sanitizeParameters(schema); - expect(schema.properties!.prop1.default).toBeUndefined(); - }); - - it('should handle complex nested schemas', () => { - const schema: Schema = { - properties: { - prop1: { - items: { - anyOf: [{ type: Type.STRING }], - default: 'world', - }, - }, - prop2: { - anyOf: [ - { - properties: { - nestedProp: { - anyOf: [{ type: Type.NUMBER }], - default: 123, - }, - }, - }, - ], - }, - }, - }; - sanitizeParameters(schema); - expect(schema.properties!.prop1.items!.default).toBeUndefined(); - const nestedProp = - schema.properties!.prop2.anyOf![0].properties!.nestedProp; - expect(nestedProp?.default).toBeUndefined(); - }); - - it('should remove unsupported format from a simple string property', () => { - const schema: Schema = { - type: Type.OBJECT, - properties: { - name: { type: Type.STRING }, - id: { type: Type.STRING, format: 'uuid' }, - }, - }; - sanitizeParameters(schema); - expect(schema.properties?.['id']).toHaveProperty('format', undefined); - expect(schema.properties?.['name']).not.toHaveProperty('format'); - }); - - it('should NOT remove supported format values', () => { - const schema: Schema = { - type: Type.OBJECT, - properties: { - date: { type: Type.STRING, format: 'date-time' }, - role: { - type: Type.STRING, - format: 'enum', - enum: ['admin', 'user'], - }, - }, - }; - const originalSchema = JSON.parse(JSON.stringify(schema)); - sanitizeParameters(schema); - expect(schema).toEqual(originalSchema); - }); - - it('should handle arrays of objects', () => { - const schema: Schema = { - type: Type.OBJECT, - properties: { - items: { - type: Type.ARRAY, - items: { - type: Type.OBJECT, - properties: { - itemId: { type: Type.STRING, format: 'uuid' }, - }, - }, - }, - }, - }; - sanitizeParameters(schema); - expect( - (schema.properties?.['items']?.items as Schema)?.properties?.['itemId'], - ).toHaveProperty('format', undefined); - }); - - it('should handle schemas with no properties to sanitize', () => { - const schema: Schema = { - type: Type.OBJECT, - properties: { - count: { type: Type.NUMBER }, - isActive: { type: Type.BOOLEAN }, - }, - }; - const originalSchema = JSON.parse(JSON.stringify(schema)); - sanitizeParameters(schema); - expect(schema).toEqual(originalSchema); - }); - - it('should not crash on an empty or undefined schema', () => { - expect(() => sanitizeParameters({})).not.toThrow(); - expect(() => sanitizeParameters(undefined)).not.toThrow(); - }); - - it('should handle complex nested schemas with cycles', () => { - const userNode: any = { - type: Type.OBJECT, - properties: { - id: { type: Type.STRING, format: 'uuid' }, - name: { type: Type.STRING }, - manager: { - type: Type.OBJECT, - properties: { - id: { type: Type.STRING, format: 'uuid' }, - }, - }, - }, - }; - userNode.properties.reports = { - type: Type.ARRAY, - items: userNode, - }; - - const schema: Schema = { - type: Type.OBJECT, - properties: { - ceo: userNode, - }, - }; - - expect(() => sanitizeParameters(schema)).not.toThrow(); - expect(schema.properties?.['ceo']?.properties?.['id']).toHaveProperty( - 'format', - undefined, - ); - expect( - schema.properties?.['ceo']?.properties?.['manager']?.properties?.['id'], - ).toHaveProperty('format', undefined); - }); -}); |
