@ai-sdk/google 4.0.22 → 4.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -91,6 +91,16 @@ Google language models can also be used in the `streamText` function
91
91
  and support structured data generation with [`Output`](/docs/reference/ai-sdk-core/output)
92
92
  (see [AI SDK Core](/docs/ai-sdk-core)).
93
93
 
94
+ <Note>
95
+ To remain forward-compatible, the provider treats unrecognized `gemini-*`
96
+ model IDs and `-latest` aliases like the newest supported Gemini generation.
97
+ Currently, this means Gemini 3 request behavior for provider-defined and mixed
98
+ tools, `thinkingLevel` reasoning, multimodal function responses, and thought
99
+ signatures. Known legacy Gemini model IDs keep their generation-specific
100
+ request behavior. This SDK default controls request serialization; the
101
+ selected model must still support each feature in the Google API.
102
+ </Note>
103
+
94
104
  Google also supports some model specific settings that are not part of the [standard call settings](/docs/ai-sdk-core/settings).
95
105
  You can pass them as an options argument:
96
106
 
@@ -163,7 +173,7 @@ The following optional provider options are available for Google models:
163
173
  Optional. Configuration for the model's thinking process. Only supported by specific [Google models](https://ai.google.dev/gemini-api/docs/thinking).
164
174
  - **thinkingLevel** _'minimal' | 'low' | 'medium' | 'high'_
165
175
 
166
- Optional. Controls the thinking depth for Gemini 3 models. Gemini 3.1 Pro supports 'low', 'medium', and 'high', Gemini 3 Pro supports 'low' and 'high', while Gemini 3 Flash supports all four levels: 'minimal', 'low', 'medium', and 'high'. Only supported by Gemini 3 models.
176
+ Optional. Controls the thinking depth for Gemini 3 and later models. Gemini 3.1 Pro supports 'low', 'medium', and 'high', Gemini 3 Pro supports 'low' and 'high', while Gemini 3 Flash supports all four levels: 'minimal', 'low', 'medium', and 'high'.
167
177
 
168
178
  - **thinkingBudget** _number_
169
179
 
@@ -171,7 +181,7 @@ The following optional provider options are available for Google models:
171
181
  For more information about the possible value ranges for each model see [Google thinking documentation](https://ai.google.dev/gemini-api/docs/thinking#set-budget).
172
182
 
173
183
  <Note>
174
- This option is for Gemini 2.5 models. Gemini 3 models should use
184
+ This option is for Gemini 2.5 models. Gemini 3 and later models should use
175
185
  `thinkingLevel` instead.
176
186
  </Note>
177
187
 
@@ -242,11 +252,11 @@ The following optional provider options are available for Google models:
242
252
 
243
253
  ### Thinking
244
254
 
245
- The Gemini 2.5 and Gemini 3 series models use an internal "thinking process" that significantly improves their reasoning and multi-step planning abilities, making them highly effective for complex tasks such as coding, advanced mathematics, and data analysis. For more information see [Google thinking documentation](https://ai.google.dev/gemini-api/docs/thinking).
255
+ The Gemini 2.5 and Gemini 3-and-later series models use an internal "thinking process" that significantly improves their reasoning and multi-step planning abilities, making them highly effective for complex tasks such as coding, advanced mathematics, and data analysis. For more information see [Google thinking documentation](https://ai.google.dev/gemini-api/docs/thinking).
246
256
 
247
- #### Gemini 3 Models
257
+ #### Gemini 3 and Later Models
248
258
 
249
- For Gemini 3 models, use the `thinkingLevel` parameter to control the depth of reasoning:
259
+ For Gemini 3 and later models, use the `thinkingLevel` parameter to control the depth of reasoning:
250
260
 
251
261
  ```ts
252
262
  import { google, GoogleLanguageModelOptions } from '@ai-sdk/google';
@@ -628,7 +638,7 @@ Enterprise Web Search provides the following benefits:
628
638
 
629
639
  ### File Search
630
640
 
631
- The [File Search tool](https://ai.google.dev/gemini-api/docs/file-search) lets Gemini retrieve context from your own documents that you have indexed in File Search stores. Only Gemini 2.5 and Gemini 3 models support this feature.
641
+ The [File Search tool](https://ai.google.dev/gemini-api/docs/file-search) lets Gemini retrieve context from your own documents that you have indexed in File Search stores. The provider enables this tool for Gemini 2.5 and Gemini 3-and-later model IDs, including unrecognized future Gemini IDs.
632
642
 
633
643
  ```ts highlight="9-13"
634
644
  import { google } from '@ai-sdk/google';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/google",
3
- "version": "4.0.22",
3
+ "version": "4.0.23",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -46,6 +46,7 @@ import {
46
46
  type GoogleLanguageModelOptions,
47
47
  type GoogleModelId,
48
48
  } from './google-language-model-options';
49
+ import { getGoogleModelCapabilities } from './google-model-capabilities';
49
50
  import type { GoogleProviderMetadata } from './google-prompt';
50
51
  import { prepareTools } from './google-prepare-tools';
51
52
  import {
@@ -257,15 +258,14 @@ export class GoogleLanguageModel implements LanguageModelV4 {
257
258
  }
258
259
 
259
260
  const isGemmaModel = this.modelId.toLowerCase().startsWith('gemma-');
260
- const isGemini3Model = /^gemini-3[.-]/.test(this.modelId);
261
- const supportsFunctionResponseParts = isGemini3Model;
261
+ const { usesGemini3Features } = getGoogleModelCapabilities(this.modelId);
262
262
 
263
263
  const { contents, systemInstruction } = convertToGoogleMessages(prompt, {
264
264
  isGemmaModel,
265
- isGemini3Model,
265
+ isGemini3Model: usesGemini3Features,
266
266
  onWarning: warning => warnings.push(warning),
267
267
  providerOptionsNames,
268
- supportsFunctionResponseParts,
268
+ supportsFunctionResponseParts: usesGemini3Features,
269
269
  });
270
270
 
271
271
  const {
@@ -1136,10 +1136,6 @@ export class GoogleLanguageModel implements LanguageModelV4 {
1136
1136
  }
1137
1137
  }
1138
1138
 
1139
- function isGemini3Model(modelId: string): boolean {
1140
- return /gemini-3[\.\-]/i.test(modelId) || /gemini-3$/i.test(modelId);
1141
- }
1142
-
1143
1139
  function getMaxOutputTokensForGemini25Model(): number {
1144
1140
  return 65536;
1145
1141
  }
@@ -1169,7 +1165,10 @@ function resolveThinkingConfig({
1169
1165
  return undefined;
1170
1166
  }
1171
1167
 
1172
- if (isGemini3Model(modelId) && !modelId.includes('gemini-3-pro-image')) {
1168
+ if (
1169
+ getGoogleModelCapabilities(modelId).usesGemini3Features &&
1170
+ !modelId.includes('gemini-3-pro-image')
1171
+ ) {
1173
1172
  return resolveGemini3ThinkingConfig({ reasoning, warnings });
1174
1173
  }
1175
1174
 
@@ -0,0 +1,44 @@
1
+ type GoogleModelCapabilities = {
2
+ supportsGemini2Tools: boolean;
3
+ supportsFileSearch: boolean;
4
+ usesGemini3Features: boolean;
5
+ };
6
+
7
+ const gemini1ModelPattern = /(^|\/)gemini-1(?:[.-]|$)/i;
8
+ const gemini2ModelPattern = /(^|\/)gemini-2(?:[.-]|$)/i;
9
+ const gemini25ModelPattern = /(^|\/)gemini-2\.5(?:[.-]|$)/i;
10
+ const geminiModelPattern = /(^|\/)gemini-/i;
11
+
12
+ function isKnownPreGemini2Model(modelId: string): boolean {
13
+ return (
14
+ gemini1ModelPattern.test(modelId) ||
15
+ /(^|\/)gemini-pro(?:-vision)?$/i.test(modelId) ||
16
+ /(^|\/)gemini-robotics-er-1\.5(?:[.-]|$)/i.test(modelId)
17
+ );
18
+ }
19
+
20
+ /**
21
+ * Classifies Gemini capabilities by excluding known older generations.
22
+ *
23
+ * Google model IDs are open-ended, so unrecognized Gemini IDs and aliases
24
+ * intentionally inherit the newest supported behavior. Add exceptions here
25
+ * only when a model is known to require a legacy request shape.
26
+ */
27
+ export function getGoogleModelCapabilities(
28
+ modelId: string,
29
+ ): GoogleModelCapabilities {
30
+ const isGeminiModel = geminiModelPattern.test(modelId);
31
+ const isGemini2Model = gemini2ModelPattern.test(modelId);
32
+ const isKnownPreGemini2 = isKnownPreGemini2Model(modelId);
33
+ const isKnownOlderModel = isKnownPreGemini2 || isGemini2Model;
34
+ const usesGemini3Features = isGeminiModel && !isKnownOlderModel;
35
+
36
+ return {
37
+ supportsGemini2Tools:
38
+ (isGeminiModel && !isKnownPreGemini2) ||
39
+ modelId.toLowerCase().includes('nano-banana'),
40
+ supportsFileSearch:
41
+ gemini25ModelPattern.test(modelId) || usesGemini3Features,
42
+ usesGemini3Features,
43
+ };
44
+ }
@@ -5,6 +5,7 @@ import {
5
5
  } from '@ai-sdk/provider';
6
6
  import { convertJSONSchemaToOpenAPISchema } from './convert-json-schema-to-openapi-schema';
7
7
  import type { GoogleModelId } from './google-language-model-options';
8
+ import { getGoogleModelCapabilities } from './google-model-capabilities';
8
9
 
9
10
  export function prepareTools({
10
11
  tools,
@@ -46,21 +47,8 @@ export function prepareTools({
46
47
 
47
48
  const toolWarnings: SharedV4Warning[] = [];
48
49
 
49
- const isLatest = (
50
- [
51
- 'gemini-flash-latest',
52
- 'gemini-flash-lite-latest',
53
- 'gemini-pro-latest',
54
- ] as const satisfies GoogleModelId[]
55
- ).some(id => id === modelId);
56
- const isGemini2orNewer =
57
- modelId.includes('gemini-2') ||
58
- modelId.includes('gemini-3') ||
59
- modelId.includes('nano-banana') ||
60
- isLatest;
61
- const isGemini3orNewer = modelId.includes('gemini-3');
62
- const supportsFileSearch =
63
- modelId.includes('gemini-2.5') || modelId.includes('gemini-3');
50
+ const { supportsGemini2Tools, supportsFileSearch, usesGemini3Features } =
51
+ getGoogleModelCapabilities(modelId);
64
52
 
65
53
  if (tools == null) {
66
54
  return { tools: undefined, toolConfig: undefined, toolWarnings };
@@ -70,7 +58,7 @@ export function prepareTools({
70
58
  const hasFunctionTools = tools.some(tool => tool.type === 'function');
71
59
  const hasProviderTools = tools.some(tool => tool.type === 'provider');
72
60
 
73
- if (hasFunctionTools && hasProviderTools && !isGemini3orNewer) {
61
+ if (hasFunctionTools && hasProviderTools && !usesGemini3Features) {
74
62
  toolWarnings.push({
75
63
  type: 'unsupported',
76
64
  feature: `combination of function and provider-defined tools`,
@@ -84,7 +72,7 @@ export function prepareTools({
84
72
  ProviderTools.forEach(tool => {
85
73
  switch (tool.id) {
86
74
  case 'google.google_search':
87
- if (isGemini2orNewer) {
75
+ if (supportsGemini2Tools) {
88
76
  googleTools.push({ googleSearch: { ...tool.args } });
89
77
  } else {
90
78
  toolWarnings.push({
@@ -95,7 +83,7 @@ export function prepareTools({
95
83
  }
96
84
  break;
97
85
  case 'google.enterprise_web_search':
98
- if (isGemini2orNewer) {
86
+ if (supportsGemini2Tools) {
99
87
  googleTools.push({ enterpriseWebSearch: {} });
100
88
  } else {
101
89
  toolWarnings.push({
@@ -106,7 +94,7 @@ export function prepareTools({
106
94
  }
107
95
  break;
108
96
  case 'google.url_context':
109
- if (isGemini2orNewer) {
97
+ if (supportsGemini2Tools) {
110
98
  googleTools.push({ urlContext: {} });
111
99
  } else {
112
100
  toolWarnings.push({
@@ -118,7 +106,7 @@ export function prepareTools({
118
106
  }
119
107
  break;
120
108
  case 'google.code_execution':
121
- if (isGemini2orNewer) {
109
+ if (supportsGemini2Tools) {
122
110
  googleTools.push({ codeExecution: {} });
123
111
  } else {
124
112
  toolWarnings.push({
@@ -142,7 +130,7 @@ export function prepareTools({
142
130
  }
143
131
  break;
144
132
  case 'google.vertex_rag_store':
145
- if (isGemini2orNewer) {
133
+ if (supportsGemini2Tools) {
146
134
  googleTools.push({
147
135
  retrieval: {
148
136
  vertex_rag_store: {
@@ -163,7 +151,7 @@ export function prepareTools({
163
151
  }
164
152
  break;
165
153
  case 'google.google_maps':
166
- if (isGemini2orNewer) {
154
+ if (supportsGemini2Tools) {
167
155
  googleTools.push({ googleMaps: {} });
168
156
  } else {
169
157
  toolWarnings.push({
@@ -183,7 +171,7 @@ export function prepareTools({
183
171
  }
184
172
  });
185
173
 
186
- if (hasFunctionTools && isGemini3orNewer && googleTools.length > 0) {
174
+ if (hasFunctionTools && usesGemini3Features && googleTools.length > 0) {
187
175
  const functionDeclarations: Array<{
188
176
  name: string;
189
177
  description: string;