@@ -29,13 +29,17 @@ function resolveToolParameterSchemaCacheKey(
|
29 | 29 | ): string { |
30 | 30 | const normalizedProvider = normalizeLowercaseStringOrEmpty(options?.modelProvider); |
31 | 31 | const normalizedModelId = normalizeLowercaseStringOrEmpty(options?.modelId); |
| 32 | +const toolSchemaProfile = normalizeLowercaseStringOrEmpty( |
| 33 | +options?.modelCompat?.toolSchemaProfile, |
| 34 | +); |
32 | 35 | const unsupportedKeywords = Array.from( |
33 | 36 | resolveUnsupportedToolSchemaKeywords(options?.modelCompat), |
34 | 37 | ).toSorted(); |
35 | 38 | const omitEmptyArrayItems = shouldOmitEmptyArrayItems(options?.modelCompat); |
36 | 39 | return JSON.stringify([ |
37 | 40 | normalizedProvider, |
38 | 41 | normalizedModelId, |
| 42 | +toolSchemaProfile, |
39 | 43 | unsupportedKeywords, |
40 | 44 | omitEmptyArrayItems, |
41 | 45 | ]); |
@@ -57,6 +61,10 @@ function rememberCachedToolParameterSchema(schema: object, key: string, value: T
|
57 | 61 | return value; |
58 | 62 | } |
59 | 63 | |
| 64 | +function isGeminiModelId(modelId: string): boolean { |
| 65 | +return /(?:^|[/:])gemini(?:$|[-/:.])/.test(modelId); |
| 66 | +} |
| 67 | + |
60 | 68 | function extractEnumValues(schema: unknown): unknown[] | undefined { |
61 | 69 | if (!schema || typeof schema !== "object") { |
62 | 70 | return undefined; |
@@ -769,8 +777,15 @@ function normalizeToolParameterSchemaUncached(
|
769 | 777 | // |
770 | 778 | // Normalize once here so callers can always pass `tools` through unchanged. |
771 | 779 | const normalizedProvider = normalizeLowercaseStringOrEmpty(options?.modelProvider); |
| 780 | +const normalizedModelId = normalizeLowercaseStringOrEmpty(options?.modelId); |
| 781 | +const normalizedToolSchemaProfile = normalizeLowercaseStringOrEmpty( |
| 782 | +options?.modelCompat?.toolSchemaProfile, |
| 783 | +); |
772 | 784 | const isGeminiProvider = |
773 | | -normalizedProvider.includes("google") || normalizedProvider.includes("gemini"); |
| 785 | +normalizedProvider.includes("google") || |
| 786 | +normalizedProvider.includes("gemini") || |
| 787 | +isGeminiModelId(normalizedModelId) || |
| 788 | +normalizedToolSchemaProfile === "gemini"; |
774 | 789 | const isAnthropicProvider = normalizedProvider.includes("anthropic"); |
775 | 790 | const unsupportedToolSchemaKeywords = resolveUnsupportedToolSchemaKeywords(options?.modelCompat); |
776 | 791 | const omitEmptyArrayItems = shouldOmitEmptyArrayItems(options?.modelCompat); |
@@ -781,7 +796,13 @@ function normalizeToolParameterSchemaUncached(
|
781 | 796 | ? stripEmptyArrayItemsFromArraySchemas(normalizedSchema) |
782 | 797 | : normalizedSchema; |
783 | 798 | if (isGeminiProvider && !isAnthropicProvider) { |
784 | | -return cleanSchemaForGemini(arrayItemsCompatibleSchema); |
| 799 | +const geminiCompatibleSchema = cleanSchemaForGemini(arrayItemsCompatibleSchema); |
| 800 | +return unsupportedToolSchemaKeywords.size > 0 |
| 801 | + ? (stripUnsupportedSchemaKeywords( |
| 802 | +geminiCompatibleSchema, |
| 803 | +unsupportedToolSchemaKeywords, |
| 804 | +) as TSchema) |
| 805 | + : geminiCompatibleSchema; |
785 | 806 | } |
786 | 807 | if (unsupportedToolSchemaKeywords.size > 0) { |
787 | 808 | return stripUnsupportedSchemaKeywords( |
|