diff --git a/package.json b/package.json index 46bac67..0770fd1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@missionsquad/rosetta-ai", - "version": "1.11.3", + "version": "1.11.4", "description": "Unified TypeScript SDK for interacting with multiple AI providers (Anthropic, Google, Groq, OpenAI).", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/src/core/mapping/google.mapper.ts b/src/core/mapping/google.mapper.ts index 615bd76..f60502c 100644 --- a/src/core/mapping/google.mapper.ts +++ b/src/core/mapping/google.mapper.ts @@ -37,6 +37,30 @@ import * as GoogleEmbedMapper from './google.embed.mapper' export class GoogleMapper implements IProviderMapper { readonly provider = Provider.Google + private static readonly ALLOWED_SCHEMA_KEYS = new Set([ + 'anyOf', + 'default', + 'description', + 'enum', + 'example', + 'format', + 'items', + 'maxItems', + 'maxLength', + 'maxProperties', + 'maximum', + 'minItems', + 'minLength', + 'minProperties', + 'minimum', + 'nullable', + 'pattern', + 'properties', + 'propertyOrdering', + 'required', + 'title', + 'type' + ]) // --- Parameter Mapping --- private mapRoleToGoogle(role: RosettaMessage['role']): 'user' | 'model' | 'function' | 'system' { @@ -259,9 +283,13 @@ export class GoogleMapper implements IProviderMapper { delete cleanedSchema.items } + const prunedSchema = Object.fromEntries( + Object.entries(cleanedSchema).filter(([key]) => GoogleMapper.ALLOWED_SCHEMA_KEYS.has(key)) + ) + visited.delete(schema); // Clean up visited set for this path - return cleanedSchema; + return prunedSchema; } private findLastToolCallName(history: Content[], _toolCallId: string): string | undefined { diff --git a/tests/unit/core/mapping/google.mapper.spec.ts b/tests/unit/core/mapping/google.mapper.spec.ts index 1c2edcc..7d2c5aa 100644 --- a/tests/unit/core/mapping/google.mapper.spec.ts +++ b/tests/unit/core/mapping/google.mapper.spec.ts @@ -242,6 +242,43 @@ describe('Google Mapper', () => { expect(functionDecl?.parameters?.properties?.location?.type).toBe('STRING') }) + it('[Easy] should strip non-Google schema keys from tool parameters', () => { + const params: GenerateParams = { + ...baseParams, + messages: [{ role: 'user', content: 'Use the tool.' }], + tools: [ + { + type: 'function', + function: { + name: 'list_timezones', + description: 'Lists timezones', + parameters: { + type: 'object', + properties: { + region: { + type: 'string', + description: 'Optional timezone region prefix', + optional: true, + examples: ['America'] + } + } + } as any + } + } + ] + } + + const result = mapper.mapToProviderParams(params) as GenerateContentParameters + const functionDecl = result.config?.tools?.[0]?.functionDeclarations?.[0] + + expect(functionDecl?.parameters?.properties?.region).toEqual({ + type: 'STRING', + description: 'Optional timezone region prefix' + }) + expect((functionDecl?.parameters?.properties?.region as any)?.optional).toBeUndefined() + expect((functionDecl?.parameters?.properties?.region as any)?.examples).toBeUndefined() + }) + it('[Easy] should map grounding tool', () => { const params: GenerateParams = { ...baseParams,