@ai-sdk/google 4.0.48 → 4.0.50

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.
@@ -1902,61 +1902,8 @@ The following optional provider options are available for Google embedding model
1902
1902
  You can create image models that call the Google Generative AI API using the `.image()` factory method.
1903
1903
  For more on image generation with the AI SDK see [generateImage()](/docs/reference/ai-sdk-core/generate-image).
1904
1904
 
1905
- The Google provider supports two types of image models:
1906
-
1907
- - **Imagen models**: Dedicated image generation models using the `:predict` API
1908
- - **Gemini image models**: Multimodal language models with image output capabilities using the `:generateContent` API
1909
-
1910
- ### Imagen Models
1911
-
1912
- [Imagen](https://ai.google.dev/gemini-api/docs/imagen) models are dedicated image generation models.
1913
-
1914
- ```ts
1915
- import { google } from '@ai-sdk/google';
1916
- import { generateImage } from 'ai';
1917
-
1918
- const { image } = await generateImage({
1919
- model: google.image('imagen-4.0-generate-001'),
1920
- prompt: 'A futuristic cityscape at sunset',
1921
- aspectRatio: '16:9',
1922
- });
1923
- ```
1924
-
1925
- Further configuration can be done using Google provider options. You can validate the provider options using the `GoogleImageModelOptions` type.
1926
-
1927
- ```ts
1928
- import { google } from '@ai-sdk/google';
1929
- import { GoogleImageModelOptions } from '@ai-sdk/google';
1930
- import { generateImage } from 'ai';
1931
-
1932
- const { image } = await generateImage({
1933
- model: google.image('imagen-4.0-generate-001'),
1934
- providerOptions: {
1935
- google: {
1936
- personGeneration: 'dont_allow',
1937
- } satisfies GoogleImageModelOptions,
1938
- },
1939
- // ...
1940
- });
1941
- ```
1942
-
1943
- The following provider options are available for Imagen models:
1944
-
1945
- - **personGeneration** `allow_adult` | `allow_all` | `dont_allow`
1946
- Whether to allow person generation. Defaults to `allow_adult`.
1947
-
1948
- <Note>
1949
- Imagen models do not support the `size` parameter. Use the `aspectRatio`
1950
- parameter instead.
1951
- </Note>
1952
-
1953
- #### Imagen Model Capabilities
1954
-
1955
- | Model | Aspect Ratios |
1956
- | ------------------------------- | ------------------------- |
1957
- | `imagen-4.0-generate-001` | 1:1, 3:4, 4:3, 9:16, 16:9 |
1958
- | `imagen-4.0-ultra-generate-001` | 1:1, 3:4, 4:3, 9:16, 16:9 |
1959
- | `imagen-4.0-fast-generate-001` | 1:1, 3:4, 4:3, 9:16, 16:9 |
1905
+ The `.image()` factory supports Gemini multimodal language models with image
1906
+ output capabilities through the `:generateContent` API.
1960
1907
 
1961
1908
  ### Gemini Image Models
1962
1909
 
@@ -2023,7 +1970,7 @@ const { image } = await generateImage({
2023
1970
  Gemini image models support [Google Search grounding](#google-search) through `providerOptions.google.googleSearch`. The value matches the args of `google.tools.googleSearch(...)`; pass `{}` to enable with defaults, or `{ searchTypes: { imageSearch: {} } }` to ground on reference photos.
2024
1971
 
2025
1972
  ```ts
2026
- import { google } from '@ai-sdk/google';
1973
+ import { google, type GoogleImageModelOptions } from '@ai-sdk/google';
2027
1974
  import { generateImage } from 'ai';
2028
1975
 
2029
1976
  const result = await generateImage({
@@ -2033,7 +1980,7 @@ const result = await generateImage({
2033
1980
  providerOptions: {
2034
1981
  google: {
2035
1982
  googleSearch: { searchTypes: { imageSearch: {} } },
2036
- },
1983
+ } satisfies GoogleImageModelOptions,
2037
1984
  },
2038
1985
  });
2039
1986
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/google",
3
- "version": "4.0.48",
3
+ "version": "4.0.50",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@ai-sdk/provider": "4.0.7",
39
- "@ai-sdk/provider-utils": "5.0.28"
39
+ "@ai-sdk/provider-utils": "5.0.29"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/node": "22.19.19",
@@ -1,21 +1,14 @@
1
- import {
2
- lazySchema,
3
- zodSchema,
4
- type InferSchema,
5
- } from '@ai-sdk/provider-utils';
1
+ import { lazySchema, zodSchema } from '@ai-sdk/provider-utils';
6
2
  import { z } from 'zod/v4';
7
- import { googleSearchToolArgsBaseSchema } from './tool/google-search';
3
+ import type { GoogleLanguageModelOptions } from './google-language-model-options';
4
+ import {
5
+ googleSearchToolArgsBaseSchema,
6
+ type GoogleSearchToolArgs,
7
+ } from './tool/google-search';
8
8
 
9
- // Note: For the initial GA launch of Imagen 3, safety filters are not configurable.
10
- // https://ai.google.dev/gemini-api/docs/imagen#imagen-model
11
9
  export const googleImageModelOptionsSchema = lazySchema(() =>
12
10
  zodSchema(
13
11
  z.object({
14
- personGeneration: z
15
- .enum(['dont_allow', 'allow_adult', 'allow_all'])
16
- .nullish(),
17
- aspectRatio: z.enum(['1:1', '3:4', '4:3', '9:16', '16:9']).nullish(),
18
-
19
12
  /**
20
13
  * Enable Google Search grounding for Gemini image models. The value is
21
14
  * forwarded as the args of the `google.tools.googleSearch` provider
@@ -30,6 +23,9 @@ export const googleImageModelOptionsSchema = lazySchema(() =>
30
23
  ),
31
24
  );
32
25
 
33
- export type GoogleImageModelOptions = InferSchema<
34
- typeof googleImageModelOptionsSchema
35
- >;
26
+ export type GoogleImageModelOptions = Omit<
27
+ GoogleLanguageModelOptions,
28
+ 'responseModalities'
29
+ > & {
30
+ googleSearch?: GoogleSearchToolArgs;
31
+ };
@@ -4,23 +4,15 @@ import type {
4
4
  SharedV4Warning,
5
5
  } from '@ai-sdk/provider';
6
6
  import {
7
- combineHeaders,
8
7
  convertToBase64,
9
- createJsonResponseHandler,
10
8
  generateId as defaultGenerateId,
11
- lazySchema,
12
9
  parseProviderOptions,
13
- postJsonToApi,
14
- resolve,
15
10
  serializeModelOptions,
16
11
  WORKFLOW_SERIALIZE,
17
12
  WORKFLOW_DESERIALIZE,
18
- zodSchema,
19
13
  type FetchFunction,
20
14
  type Resolvable,
21
15
  } from '@ai-sdk/provider-utils';
22
- import { z } from 'zod/v4';
23
- import { googleFailedResponseHandler } from './google-error';
24
16
  import { googleImageModelOptionsSchema } from './google-image-model-options';
25
17
  import type {
26
18
  GoogleImageModelId,
@@ -61,12 +53,7 @@ export class GoogleImageModel implements ImageModelV4 {
61
53
  if (this.settings.maxImagesPerCall != null) {
62
54
  return this.settings.maxImagesPerCall;
63
55
  }
64
- // https://docs.cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/2-5-flash-image
65
- if (isGeminiModel(this.modelId)) {
66
- return 10;
67
- }
68
- // https://ai.google.dev/gemini-api/docs/imagen#imagen-model
69
- return 4;
56
+ return 10;
70
57
  }
71
58
 
72
59
  get provider(): string {
@@ -82,137 +69,12 @@ export class GoogleImageModel implements ImageModelV4 {
82
69
  async doGenerate(
83
70
  options: Parameters<ImageModelV4['doGenerate']>[0],
84
71
  ): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {
85
- // Gemini image models use the language model API internally
86
- if (isGeminiModel(this.modelId)) {
87
- return this.doGenerateGemini(options);
88
- }
89
- return this.doGenerateImagen(options);
90
- }
91
-
92
- private async doGenerateImagen(
93
- options: Parameters<ImageModelV4['doGenerate']>[0],
94
- ): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {
95
- const {
96
- prompt,
97
- n = 1,
98
- size,
99
- aspectRatio = '1:1',
100
- seed,
101
- providerOptions,
102
- headers,
103
- abortSignal,
104
- files,
105
- mask,
106
- } = options;
107
- const warnings: Array<SharedV4Warning> = [];
108
-
109
- // Imagen API endpoints do not support image editing
110
- if (files != null && files.length > 0) {
111
- throw new Error(
112
- 'Google Gemini API does not support image editing with Imagen models. ' +
113
- 'Use Google Vertex AI (@ai-sdk/google-vertex) for image editing capabilities.',
114
- );
115
- }
116
-
117
- if (mask != null) {
72
+ if (!this.modelId.startsWith('gemini-')) {
118
73
  throw new Error(
119
- 'Google Gemini API does not support image editing with masks. ' +
120
- 'Use Google Vertex AI (@ai-sdk/google-vertex) for image editing capabilities.',
74
+ 'Google image models other than Gemini are no longer supported. Use a model ID that starts with `gemini-`.',
121
75
  );
122
76
  }
123
77
 
124
- if (size != null) {
125
- warnings.push({
126
- type: 'unsupported',
127
- feature: 'size',
128
- details:
129
- 'This model does not support the `size` option. Use `aspectRatio` instead.',
130
- });
131
- }
132
-
133
- if (seed != null) {
134
- warnings.push({
135
- type: 'unsupported',
136
- feature: 'seed',
137
- details:
138
- 'This model does not support the `seed` option through this provider.',
139
- });
140
- }
141
-
142
- const googleOptions = await parseProviderOptions({
143
- provider: 'google',
144
- providerOptions,
145
- schema: googleImageModelOptionsSchema,
146
- });
147
-
148
- const currentDate = this.config._internal?.currentDate?.() ?? new Date();
149
-
150
- const parameters: Record<string, unknown> = {
151
- sampleCount: n,
152
- };
153
-
154
- if (aspectRatio != null) {
155
- parameters.aspectRatio = aspectRatio;
156
- }
157
-
158
- if (googleOptions) {
159
- const { googleSearch: imagenGoogleSearch, ...imagenOptions } =
160
- googleOptions;
161
- if (imagenGoogleSearch != null) {
162
- warnings.push({
163
- type: 'unsupported',
164
- feature: 'googleSearch',
165
- details:
166
- 'Google Search grounding is only supported on Gemini image models.',
167
- });
168
- }
169
- Object.assign(parameters, imagenOptions);
170
- }
171
-
172
- const body = {
173
- instances: [{ prompt }],
174
- parameters,
175
- };
176
-
177
- const { responseHeaders, value: response } = await postJsonToApi<{
178
- predictions: Array<{ bytesBase64Encoded: string }>;
179
- }>({
180
- url: `${this.config.baseURL}/models/${this.modelId}:predict`,
181
- headers: combineHeaders(
182
- this.config.headers ? await resolve(this.config.headers) : undefined,
183
- headers,
184
- ),
185
- body,
186
- failedResponseHandler: googleFailedResponseHandler,
187
- successfulResponseHandler: createJsonResponseHandler(
188
- googleImageResponseSchema,
189
- ),
190
- abortSignal,
191
- fetch: this.config.fetch,
192
- });
193
- return {
194
- images: response.predictions.map(
195
- (p: { bytesBase64Encoded: string }) => p.bytesBase64Encoded,
196
- ),
197
- warnings,
198
- providerMetadata: {
199
- google: {
200
- images: response.predictions.map(() => ({
201
- // Add any prediction-specific metadata here
202
- })),
203
- },
204
- },
205
- response: {
206
- timestamp: currentDate,
207
- modelId: this.modelId,
208
- headers: responseHeaders,
209
- },
210
- };
211
- }
212
-
213
- private async doGenerateGemini(
214
- options: Parameters<ImageModelV4['doGenerate']>[0],
215
- ): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {
216
78
  const {
217
79
  prompt,
218
80
  n,
@@ -302,8 +164,12 @@ export class GoogleImageModel implements ImageModelV4 {
302
164
  schema: googleImageModelOptionsSchema,
303
165
  });
304
166
 
305
- const { googleSearch: _strippedGoogleSearch, ...passthroughGoogleOptions } =
306
- providerOptions?.google ?? {};
167
+ const {
168
+ googleSearch: _strippedGoogleSearch,
169
+ responseModalities: _strippedResponseModalities,
170
+ imageConfig: userImageConfig,
171
+ ...passthroughGoogleOptions
172
+ } = providerOptions?.google ?? {};
307
173
 
308
174
  // Instantiate language model
309
175
  const languageModel = new GoogleLanguageModel(this.modelId, {
@@ -320,18 +186,26 @@ export class GoogleImageModel implements ImageModelV4 {
320
186
  seed,
321
187
  providerOptions: {
322
188
  google: {
323
- responseModalities: ['IMAGE'],
324
- imageConfig: aspectRatio
325
- ? {
326
- aspectRatio: aspectRatio as NonNullable<
327
- GoogleLanguageModelOptions['imageConfig']
328
- >['aspectRatio'],
329
- }
330
- : undefined,
331
189
  ...(passthroughGoogleOptions as Omit<
332
190
  GoogleLanguageModelOptions,
333
191
  'responseModalities' | 'imageConfig'
334
192
  >),
193
+ responseModalities: ['IMAGE'],
194
+ imageConfig:
195
+ aspectRatio != null || userImageConfig != null
196
+ ? {
197
+ ...(userImageConfig as NonNullable<
198
+ GoogleLanguageModelOptions['imageConfig']
199
+ >),
200
+ ...(aspectRatio != null
201
+ ? {
202
+ aspectRatio: aspectRatio as NonNullable<
203
+ GoogleLanguageModelOptions['imageConfig']
204
+ >['aspectRatio'],
205
+ }
206
+ : {}),
207
+ }
208
+ : undefined,
335
209
  } satisfies GoogleLanguageModelOptions,
336
210
  },
337
211
  tools:
@@ -393,18 +267,3 @@ export class GoogleImageModel implements ImageModelV4 {
393
267
  };
394
268
  }
395
269
  }
396
-
397
- function isGeminiModel(modelId: string): boolean {
398
- return modelId.startsWith('gemini-');
399
- }
400
-
401
- // minimal version of the schema
402
- const googleImageResponseSchema = lazySchema(() =>
403
- zodSchema(
404
- z.object({
405
- predictions: z
406
- .array(z.object({ bytesBase64Encoded: z.string() }))
407
- .default([]),
408
- }),
409
- ),
410
- );
@@ -1,8 +1,4 @@
1
1
  export type GoogleImageModelId =
2
- // Imagen models (use :predict API)
3
- | 'imagen-4.0-generate-001'
4
- | 'imagen-4.0-ultra-generate-001'
5
- | 'imagen-4.0-fast-generate-001'
6
2
  // Gemini image models (technically multimodal output language models, use :generateContent API)
7
3
  | 'gemini-2.5-flash-image'
8
4
  | 'gemini-3-pro-image-preview'
@@ -11,7 +7,7 @@ export type GoogleImageModelId =
11
7
 
12
8
  export interface GoogleImageSettings {
13
9
  /**
14
- * Override the maximum number of images per call (default 4)
10
+ * Override the maximum number of images per call (default 10)
15
11
  */
16
12
  maxImagesPerCall?: number;
17
13
  }