@ai-sdk/google-vertex 5.0.0-beta.10 → 5.0.0-beta.108
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.
- package/CHANGELOG.md +930 -8
- package/README.md +65 -2
- package/dist/anthropic/edge/index.d.ts +18 -151
- package/dist/anthropic/edge/index.js +88 -70
- package/dist/anthropic/edge/index.js.map +1 -1
- package/dist/anthropic/index.d.ts +18 -151
- package/dist/anthropic/index.js +88 -81
- package/dist/anthropic/index.js.map +1 -1
- package/dist/edge/index.d.ts +58 -29
- package/dist/edge/index.js +581 -278
- package/dist/edge/index.js.map +1 -1
- package/dist/index.d.ts +70 -32
- package/dist/index.js +590 -296
- package/dist/index.js.map +1 -1
- package/dist/maas/edge/index.d.ts +76 -0
- package/dist/maas/edge/index.js +209 -0
- package/dist/maas/edge/index.js.map +1 -0
- package/dist/maas/index.d.ts +60 -0
- package/dist/maas/index.js +109 -0
- package/dist/maas/index.js.map +1 -0
- package/dist/xai/edge/index.d.ts +92 -0
- package/dist/xai/edge/index.js +259 -0
- package/dist/xai/edge/index.js.map +1 -0
- package/dist/xai/index.d.ts +76 -0
- package/dist/xai/index.js +159 -0
- package/dist/xai/index.js.map +1 -0
- package/docs/16-google-vertex.mdx +640 -102
- package/maas/edge.d.ts +1 -0
- package/maas/index.d.ts +1 -0
- package/package.json +49 -24
- package/src/anthropic/edge/google-vertex-anthropic-provider-edge.ts +17 -13
- package/src/anthropic/edge/index.ts +6 -2
- package/src/anthropic/{google-vertex-anthropic-messages-options.ts → google-vertex-anthropic-options.ts} +4 -1
- package/src/anthropic/google-vertex-anthropic-provider-node.ts +18 -13
- package/src/anthropic/google-vertex-anthropic-provider.ts +68 -19
- package/src/anthropic/index.ts +6 -2
- package/src/edge/google-vertex-provider-edge.ts +10 -12
- package/src/edge/index.ts +8 -1
- package/src/google-vertex-auth-google-auth-library.ts +13 -26
- package/src/google-vertex-config.ts +2 -2
- package/src/{google-vertex-embedding-options.ts → google-vertex-embedding-model-options.ts} +1 -0
- package/src/google-vertex-embedding-model.ts +35 -10
- package/src/google-vertex-image-model-options.ts +74 -0
- package/src/google-vertex-image-model.ts +106 -133
- package/src/google-vertex-options.ts +1 -1
- package/src/google-vertex-provider-base.ts +311 -0
- package/src/google-vertex-provider.ts +43 -233
- package/src/google-vertex-speech-model-options.ts +11 -0
- package/src/google-vertex-transcription-model-options.ts +46 -0
- package/src/google-vertex-transcription-model.ts +231 -0
- package/src/google-vertex-video-model-options.ts +49 -0
- package/src/google-vertex-video-model.ts +39 -75
- package/src/index.ts +20 -5
- package/src/maas/edge/google-vertex-maas-provider-edge.ts +64 -0
- package/src/maas/edge/index.ts +13 -0
- package/src/maas/google-vertex-maas-options.ts +15 -0
- package/src/maas/google-vertex-maas-provider-node.ts +65 -0
- package/src/maas/google-vertex-maas-provider.ts +122 -0
- package/src/maas/index.ts +13 -0
- package/src/xai/edge/google-vertex-xai-provider-edge.ts +61 -0
- package/src/xai/edge/index.ts +9 -0
- package/src/xai/google-vertex-xai-options.ts +7 -0
- package/src/xai/google-vertex-xai-provider-node.ts +62 -0
- package/src/xai/google-vertex-xai-provider.ts +212 -0
- package/src/xai/index.ts +9 -0
- package/xai/edge.d.ts +1 -0
- package/xai/index.d.ts +1 -0
- package/dist/anthropic/edge/index.d.mts +0 -231
- package/dist/anthropic/edge/index.mjs +0 -259
- package/dist/anthropic/edge/index.mjs.map +0 -1
- package/dist/anthropic/index.d.mts +0 -215
- package/dist/anthropic/index.mjs +0 -164
- package/dist/anthropic/index.mjs.map +0 -1
- package/dist/edge/index.d.mts +0 -160
- package/dist/edge/index.mjs +0 -1049
- package/dist/edge/index.mjs.map +0 -1
- package/dist/index.d.mts +0 -219
- package/dist/index.mjs +0 -960
- package/dist/index.mjs.map +0 -1
- package/src/google-vertex-provider-node.ts +0 -49
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
EmbeddingModelV3,
|
|
3
2
|
TooManyEmbeddingValuesForCallError,
|
|
3
|
+
type EmbeddingModelV4,
|
|
4
4
|
} from '@ai-sdk/provider';
|
|
5
5
|
import {
|
|
6
6
|
combineHeaders,
|
|
@@ -8,23 +8,40 @@ import {
|
|
|
8
8
|
postJsonToApi,
|
|
9
9
|
resolve,
|
|
10
10
|
parseProviderOptions,
|
|
11
|
+
serializeModelOptions,
|
|
12
|
+
WORKFLOW_SERIALIZE,
|
|
13
|
+
WORKFLOW_DESERIALIZE,
|
|
11
14
|
} from '@ai-sdk/provider-utils';
|
|
12
15
|
import { z } from 'zod/v4';
|
|
13
16
|
import { googleVertexFailedResponseHandler } from './google-vertex-error';
|
|
14
17
|
import {
|
|
15
|
-
GoogleVertexEmbeddingModelId,
|
|
16
18
|
googleVertexEmbeddingModelOptions,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
type GoogleVertexEmbeddingModelId,
|
|
20
|
+
} from './google-vertex-embedding-model-options';
|
|
21
|
+
import type { GoogleVertexConfig } from './google-vertex-config';
|
|
19
22
|
|
|
20
|
-
export class GoogleVertexEmbeddingModel implements
|
|
21
|
-
readonly specificationVersion = '
|
|
23
|
+
export class GoogleVertexEmbeddingModel implements EmbeddingModelV4 {
|
|
24
|
+
readonly specificationVersion = 'v4';
|
|
22
25
|
readonly modelId: GoogleVertexEmbeddingModelId;
|
|
23
26
|
readonly maxEmbeddingsPerCall = 2048;
|
|
24
27
|
readonly supportsParallelCalls = true;
|
|
25
28
|
|
|
26
29
|
private readonly config: GoogleVertexConfig;
|
|
27
30
|
|
|
31
|
+
static [WORKFLOW_SERIALIZE](model: GoogleVertexEmbeddingModel) {
|
|
32
|
+
return serializeModelOptions({
|
|
33
|
+
modelId: model.modelId,
|
|
34
|
+
config: model.config,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
39
|
+
modelId: string;
|
|
40
|
+
config: GoogleVertexConfig;
|
|
41
|
+
}) {
|
|
42
|
+
return new GoogleVertexEmbeddingModel(options.modelId, options.config);
|
|
43
|
+
}
|
|
44
|
+
|
|
28
45
|
get provider(): string {
|
|
29
46
|
return this.config.provider;
|
|
30
47
|
}
|
|
@@ -42,15 +59,23 @@ export class GoogleVertexEmbeddingModel implements EmbeddingModelV3 {
|
|
|
42
59
|
headers,
|
|
43
60
|
abortSignal,
|
|
44
61
|
providerOptions,
|
|
45
|
-
}: Parameters<
|
|
46
|
-
Awaited<ReturnType<
|
|
62
|
+
}: Parameters<EmbeddingModelV4['doEmbed']>[0]): Promise<
|
|
63
|
+
Awaited<ReturnType<EmbeddingModelV4['doEmbed']>>
|
|
47
64
|
> {
|
|
48
65
|
let googleOptions = await parseProviderOptions({
|
|
49
|
-
provider: '
|
|
66
|
+
provider: 'googleVertex',
|
|
50
67
|
providerOptions,
|
|
51
68
|
schema: googleVertexEmbeddingModelOptions,
|
|
52
69
|
});
|
|
53
70
|
|
|
71
|
+
if (googleOptions == null) {
|
|
72
|
+
googleOptions = await parseProviderOptions({
|
|
73
|
+
provider: 'vertex',
|
|
74
|
+
providerOptions,
|
|
75
|
+
schema: googleVertexEmbeddingModelOptions,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
54
79
|
if (googleOptions == null) {
|
|
55
80
|
googleOptions = await parseProviderOptions({
|
|
56
81
|
provider: 'google',
|
|
@@ -71,7 +96,7 @@ export class GoogleVertexEmbeddingModel implements EmbeddingModelV3 {
|
|
|
71
96
|
}
|
|
72
97
|
|
|
73
98
|
const mergedHeaders = combineHeaders(
|
|
74
|
-
await resolve(this.config.headers),
|
|
99
|
+
this.config.headers ? await resolve(this.config.headers) : undefined,
|
|
75
100
|
headers,
|
|
76
101
|
);
|
|
77
102
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
|
|
3
|
+
export const googleVertexImageModelOptionsSchema = z.object({
|
|
4
|
+
negativePrompt: z.string().nullish(),
|
|
5
|
+
personGeneration: z
|
|
6
|
+
.enum(['dont_allow', 'allow_adult', 'allow_all'])
|
|
7
|
+
.nullish(),
|
|
8
|
+
safetySetting: z
|
|
9
|
+
.enum([
|
|
10
|
+
'block_low_and_above',
|
|
11
|
+
'block_medium_and_above',
|
|
12
|
+
'block_only_high',
|
|
13
|
+
'block_none',
|
|
14
|
+
])
|
|
15
|
+
.nullish(),
|
|
16
|
+
addWatermark: z.boolean().nullish(),
|
|
17
|
+
storageUri: z.string().nullish(),
|
|
18
|
+
sampleImageSize: z.enum(['1K', '2K']).nullish(),
|
|
19
|
+
/**
|
|
20
|
+
* Configuration for image editing operations
|
|
21
|
+
*/
|
|
22
|
+
edit: z
|
|
23
|
+
.object({
|
|
24
|
+
/**
|
|
25
|
+
* An integer that represents the number of sampling steps.
|
|
26
|
+
* A higher value offers better image quality, a lower value offers better latency.
|
|
27
|
+
* Try 35 steps to start. If the quality doesn't meet your requirements,
|
|
28
|
+
* increase the value towards an upper limit of 75.
|
|
29
|
+
*/
|
|
30
|
+
baseSteps: z.number().nullish(),
|
|
31
|
+
|
|
32
|
+
// Edit mode options
|
|
33
|
+
// https://cloud.google.com/vertex-ai/generative-ai/docs/image/edit-insert-objects
|
|
34
|
+
mode: z
|
|
35
|
+
.enum([
|
|
36
|
+
'EDIT_MODE_INPAINT_INSERTION',
|
|
37
|
+
'EDIT_MODE_INPAINT_REMOVAL',
|
|
38
|
+
'EDIT_MODE_OUTPAINT',
|
|
39
|
+
'EDIT_MODE_CONTROLLED_EDITING',
|
|
40
|
+
'EDIT_MODE_PRODUCT_IMAGE',
|
|
41
|
+
'EDIT_MODE_BGSWAP',
|
|
42
|
+
])
|
|
43
|
+
.nullish(),
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The mask mode to use.
|
|
47
|
+
* - `MASK_MODE_DEFAULT` - Default value for mask mode.
|
|
48
|
+
* - `MASK_MODE_USER_PROVIDED` - User provided mask. No segmentation needed.
|
|
49
|
+
* - `MASK_MODE_DETECTION_BOX` - Mask from detected bounding boxes.
|
|
50
|
+
* - `MASK_MODE_CLOTHING_AREA` - Masks from segmenting the clothing area with open-vocab segmentation.
|
|
51
|
+
* - `MASK_MODE_PARSED_PERSON` - Masks from segmenting the person body and clothing using the person-parsing model.
|
|
52
|
+
*/
|
|
53
|
+
maskMode: z
|
|
54
|
+
.enum([
|
|
55
|
+
'MASK_MODE_DEFAULT',
|
|
56
|
+
'MASK_MODE_USER_PROVIDED',
|
|
57
|
+
'MASK_MODE_DETECTION_BOX',
|
|
58
|
+
'MASK_MODE_CLOTHING_AREA',
|
|
59
|
+
'MASK_MODE_PARSED_PERSON',
|
|
60
|
+
])
|
|
61
|
+
.nullish(),
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Optional. A float value between 0 and 1, inclusive, that represents the
|
|
65
|
+
* percentage of the image width to grow the mask by. Using dilation helps
|
|
66
|
+
* compensate for imprecise masks. We recommend a value of 0.01.
|
|
67
|
+
*/
|
|
68
|
+
maskDilation: z.number().nullish(),
|
|
69
|
+
})
|
|
70
|
+
.nullish(),
|
|
71
|
+
});
|
|
72
|
+
export type GoogleVertexImageModelOptions = z.infer<
|
|
73
|
+
typeof googleVertexImageModelOptionsSchema
|
|
74
|
+
>;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { GoogleLanguageModelOptions } from '@ai-sdk/google';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import { GoogleLanguageModel } from '@ai-sdk/google/internal';
|
|
3
|
+
import type {
|
|
4
|
+
ImageModelV4,
|
|
5
|
+
ImageModelV4File,
|
|
6
|
+
LanguageModelV4Prompt,
|
|
7
|
+
SharedV4Warning,
|
|
8
8
|
} from '@ai-sdk/provider';
|
|
9
9
|
import {
|
|
10
|
-
Resolvable,
|
|
11
10
|
combineHeaders,
|
|
12
11
|
convertToBase64,
|
|
13
12
|
convertUint8ArrayToBase64,
|
|
@@ -16,10 +15,15 @@ import {
|
|
|
16
15
|
parseProviderOptions,
|
|
17
16
|
postJsonToApi,
|
|
18
17
|
resolve,
|
|
18
|
+
serializeModelOptions,
|
|
19
|
+
WORKFLOW_SERIALIZE,
|
|
20
|
+
WORKFLOW_DESERIALIZE,
|
|
21
|
+
type Resolvable,
|
|
19
22
|
} from '@ai-sdk/provider-utils';
|
|
20
23
|
import { z } from 'zod/v4';
|
|
21
24
|
import { googleVertexFailedResponseHandler } from './google-vertex-error';
|
|
22
|
-
import {
|
|
25
|
+
import { googleVertexImageModelOptionsSchema } from './google-vertex-image-model-options';
|
|
26
|
+
import type { GoogleVertexImageModelId } from './google-vertex-image-settings';
|
|
23
27
|
|
|
24
28
|
interface GoogleVertexImageModelConfig {
|
|
25
29
|
provider: string;
|
|
@@ -33,8 +37,22 @@ interface GoogleVertexImageModelConfig {
|
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
// https://cloud.google.com/vertex-ai/generative-ai/docs/image/generate-images
|
|
36
|
-
export class GoogleVertexImageModel implements
|
|
37
|
-
readonly specificationVersion = '
|
|
40
|
+
export class GoogleVertexImageModel implements ImageModelV4 {
|
|
41
|
+
readonly specificationVersion = 'v4';
|
|
42
|
+
|
|
43
|
+
static [WORKFLOW_SERIALIZE](model: GoogleVertexImageModel) {
|
|
44
|
+
return serializeModelOptions({
|
|
45
|
+
modelId: model.modelId,
|
|
46
|
+
config: model.config,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
51
|
+
modelId: string;
|
|
52
|
+
config: GoogleVertexImageModelConfig;
|
|
53
|
+
}) {
|
|
54
|
+
return new GoogleVertexImageModel(options.modelId, options.config);
|
|
55
|
+
}
|
|
38
56
|
|
|
39
57
|
get maxImagesPerCall(): number {
|
|
40
58
|
if (isGeminiModel(this.modelId)) {
|
|
@@ -53,8 +71,8 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
53
71
|
) {}
|
|
54
72
|
|
|
55
73
|
async doGenerate(
|
|
56
|
-
options: Parameters<
|
|
57
|
-
): Promise<Awaited<ReturnType<
|
|
74
|
+
options: Parameters<ImageModelV4['doGenerate']>[0],
|
|
75
|
+
): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {
|
|
58
76
|
if (isGeminiModel(this.modelId)) {
|
|
59
77
|
return this.doGenerateGemini(options);
|
|
60
78
|
}
|
|
@@ -72,10 +90,10 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
72
90
|
abortSignal,
|
|
73
91
|
files,
|
|
74
92
|
mask,
|
|
75
|
-
}: Parameters<
|
|
76
|
-
Awaited<ReturnType<
|
|
93
|
+
}: Parameters<ImageModelV4['doGenerate']>[0]): Promise<
|
|
94
|
+
Awaited<ReturnType<ImageModelV4['doGenerate']>>
|
|
77
95
|
> {
|
|
78
|
-
const warnings: Array<
|
|
96
|
+
const warnings: Array<SharedV4Warning> = [];
|
|
79
97
|
|
|
80
98
|
if (size != null) {
|
|
81
99
|
warnings.push({
|
|
@@ -86,14 +104,20 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
86
104
|
});
|
|
87
105
|
}
|
|
88
106
|
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
107
|
+
const googleVertexImageOptions =
|
|
108
|
+
(await parseProviderOptions({
|
|
109
|
+
provider: 'googleVertex',
|
|
110
|
+
providerOptions,
|
|
111
|
+
schema: googleVertexImageModelOptionsSchema,
|
|
112
|
+
})) ??
|
|
113
|
+
(await parseProviderOptions({
|
|
114
|
+
provider: 'vertex',
|
|
115
|
+
providerOptions,
|
|
116
|
+
schema: googleVertexImageModelOptionsSchema,
|
|
117
|
+
}));
|
|
94
118
|
|
|
95
119
|
// Extract edit-specific options from provider options
|
|
96
|
-
const { edit, ...otherOptions } =
|
|
120
|
+
const { edit, ...otherOptions } = googleVertexImageOptions ?? {};
|
|
97
121
|
const { mode: editMode, baseSteps, maskMode, maskDilation } = edit ?? {};
|
|
98
122
|
|
|
99
123
|
// Build the request body based on whether we're editing or generating
|
|
@@ -164,11 +188,14 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
164
188
|
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
|
|
165
189
|
const { value: response, responseHeaders } = await postJsonToApi({
|
|
166
190
|
url: `${this.config.baseURL}/models/${this.modelId}:predict`,
|
|
167
|
-
headers: combineHeaders(
|
|
191
|
+
headers: combineHeaders(
|
|
192
|
+
this.config.headers ? await resolve(this.config.headers) : undefined,
|
|
193
|
+
headers,
|
|
194
|
+
),
|
|
168
195
|
body,
|
|
169
196
|
failedResponseHandler: googleVertexFailedResponseHandler,
|
|
170
197
|
successfulResponseHandler: createJsonResponseHandler(
|
|
171
|
-
|
|
198
|
+
googleVertexImageResponseSchema,
|
|
172
199
|
),
|
|
173
200
|
abortSignal,
|
|
174
201
|
fetch: this.config.fetch,
|
|
@@ -185,8 +212,8 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
185
212
|
modelId: this.modelId,
|
|
186
213
|
headers: responseHeaders,
|
|
187
214
|
},
|
|
188
|
-
providerMetadata: {
|
|
189
|
-
|
|
215
|
+
providerMetadata: (() => {
|
|
216
|
+
const payload = {
|
|
190
217
|
images:
|
|
191
218
|
response.predictions?.map(prediction => {
|
|
192
219
|
const {
|
|
@@ -196,8 +223,9 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
196
223
|
|
|
197
224
|
return { ...(revisedPrompt != null && { revisedPrompt }) };
|
|
198
225
|
}) ?? [],
|
|
199
|
-
}
|
|
200
|
-
|
|
226
|
+
};
|
|
227
|
+
return { googleVertex: payload, vertex: payload };
|
|
228
|
+
})(),
|
|
201
229
|
};
|
|
202
230
|
}
|
|
203
231
|
|
|
@@ -212,10 +240,10 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
212
240
|
abortSignal,
|
|
213
241
|
files,
|
|
214
242
|
mask,
|
|
215
|
-
}: Parameters<
|
|
216
|
-
Awaited<ReturnType<
|
|
243
|
+
}: Parameters<ImageModelV4['doGenerate']>[0]): Promise<
|
|
244
|
+
Awaited<ReturnType<ImageModelV4['doGenerate']>>
|
|
217
245
|
> {
|
|
218
|
-
const warnings: Array<
|
|
246
|
+
const warnings: Array<SharedV4Warning> = [];
|
|
219
247
|
|
|
220
248
|
if (mask != null) {
|
|
221
249
|
throw new Error(
|
|
@@ -240,7 +268,13 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
240
268
|
|
|
241
269
|
const userContent: Array<
|
|
242
270
|
| { type: 'text'; text: string }
|
|
243
|
-
| {
|
|
271
|
+
| {
|
|
272
|
+
type: 'file';
|
|
273
|
+
data:
|
|
274
|
+
| { type: 'data'; data: string | Uint8Array }
|
|
275
|
+
| { type: 'url'; url: URL };
|
|
276
|
+
mediaType: string;
|
|
277
|
+
}
|
|
244
278
|
> = [];
|
|
245
279
|
|
|
246
280
|
if (prompt != null) {
|
|
@@ -252,27 +286,30 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
252
286
|
if (file.type === 'url') {
|
|
253
287
|
userContent.push({
|
|
254
288
|
type: 'file',
|
|
255
|
-
data: new URL(file.url),
|
|
289
|
+
data: { type: 'url', url: new URL(file.url) },
|
|
256
290
|
mediaType: 'image/*',
|
|
257
291
|
});
|
|
258
292
|
} else {
|
|
259
293
|
userContent.push({
|
|
260
294
|
type: 'file',
|
|
261
|
-
data:
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
295
|
+
data: {
|
|
296
|
+
type: 'data',
|
|
297
|
+
data:
|
|
298
|
+
typeof file.data === 'string'
|
|
299
|
+
? file.data
|
|
300
|
+
: new Uint8Array(file.data),
|
|
301
|
+
},
|
|
265
302
|
mediaType: file.mediaType,
|
|
266
303
|
});
|
|
267
304
|
}
|
|
268
305
|
}
|
|
269
306
|
}
|
|
270
307
|
|
|
271
|
-
const languageModelPrompt:
|
|
308
|
+
const languageModelPrompt: LanguageModelV4Prompt = [
|
|
272
309
|
{ role: 'user', content: userContent },
|
|
273
310
|
];
|
|
274
311
|
|
|
275
|
-
const languageModel = new
|
|
312
|
+
const languageModel = new GoogleLanguageModel(this.modelId, {
|
|
276
313
|
provider: this.config.provider,
|
|
277
314
|
baseURL: this.config.baseURL,
|
|
278
315
|
headers: this.config.headers ?? {},
|
|
@@ -283,24 +320,27 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
283
320
|
}),
|
|
284
321
|
});
|
|
285
322
|
|
|
323
|
+
const userVertexOptions = (providerOptions?.googleVertex ??
|
|
324
|
+
providerOptions?.vertex) as
|
|
325
|
+
| Omit<GoogleLanguageModelOptions, 'responseModalities' | 'imageConfig'>
|
|
326
|
+
| undefined;
|
|
327
|
+
const innerVertexOptions: GoogleLanguageModelOptions = {
|
|
328
|
+
responseModalities: ['IMAGE'],
|
|
329
|
+
imageConfig: aspectRatio
|
|
330
|
+
? {
|
|
331
|
+
aspectRatio: aspectRatio as NonNullable<
|
|
332
|
+
GoogleLanguageModelOptions['imageConfig']
|
|
333
|
+
>['aspectRatio'],
|
|
334
|
+
}
|
|
335
|
+
: undefined,
|
|
336
|
+
...(userVertexOptions ?? {}),
|
|
337
|
+
};
|
|
286
338
|
const result = await languageModel.doGenerate({
|
|
287
339
|
prompt: languageModelPrompt,
|
|
288
340
|
seed,
|
|
289
341
|
providerOptions: {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
imageConfig: aspectRatio
|
|
293
|
-
? {
|
|
294
|
-
aspectRatio: aspectRatio as NonNullable<
|
|
295
|
-
GoogleLanguageModelOptions['imageConfig']
|
|
296
|
-
>['aspectRatio'],
|
|
297
|
-
}
|
|
298
|
-
: undefined,
|
|
299
|
-
...((providerOptions?.vertex as Omit<
|
|
300
|
-
GoogleLanguageModelOptions,
|
|
301
|
-
'responseModalities' | 'imageConfig'
|
|
302
|
-
>) ?? {}),
|
|
303
|
-
} satisfies GoogleLanguageModelOptions,
|
|
342
|
+
googleVertex: innerVertexOptions,
|
|
343
|
+
vertex: innerVertexOptions,
|
|
304
344
|
},
|
|
305
345
|
headers,
|
|
306
346
|
abortSignal,
|
|
@@ -310,18 +350,24 @@ export class GoogleVertexImageModel implements ImageModelV3 {
|
|
|
310
350
|
|
|
311
351
|
const images: string[] = [];
|
|
312
352
|
for (const part of result.content) {
|
|
313
|
-
if (
|
|
314
|
-
|
|
353
|
+
if (
|
|
354
|
+
part.type === 'file' &&
|
|
355
|
+
part.mediaType.startsWith('image/') &&
|
|
356
|
+
part.data.type === 'data'
|
|
357
|
+
) {
|
|
358
|
+
images.push(convertToBase64(part.data.data));
|
|
315
359
|
}
|
|
316
360
|
}
|
|
317
361
|
|
|
362
|
+
const geminiPayload = {
|
|
363
|
+
images: images.map(() => ({})),
|
|
364
|
+
};
|
|
318
365
|
return {
|
|
319
366
|
images,
|
|
320
367
|
warnings,
|
|
321
368
|
providerMetadata: {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
},
|
|
369
|
+
googleVertex: geminiPayload,
|
|
370
|
+
vertex: geminiPayload,
|
|
325
371
|
},
|
|
326
372
|
response: {
|
|
327
373
|
timestamp: currentDate,
|
|
@@ -347,7 +393,7 @@ function isGeminiModel(modelId: string): boolean {
|
|
|
347
393
|
|
|
348
394
|
// minimal version of the schema, focussed on what is needed for the implementation
|
|
349
395
|
// this approach limits breakages when the API changes and increases efficiency
|
|
350
|
-
const
|
|
396
|
+
const googleVertexImageResponseSchema = z.object({
|
|
351
397
|
predictions: z
|
|
352
398
|
.array(
|
|
353
399
|
z.object({
|
|
@@ -359,83 +405,10 @@ const vertexImageResponseSchema = z.object({
|
|
|
359
405
|
.nullish(),
|
|
360
406
|
});
|
|
361
407
|
|
|
362
|
-
const googleVertexImageModelOptionsSchema = z.object({
|
|
363
|
-
negativePrompt: z.string().nullish(),
|
|
364
|
-
personGeneration: z
|
|
365
|
-
.enum(['dont_allow', 'allow_adult', 'allow_all'])
|
|
366
|
-
.nullish(),
|
|
367
|
-
safetySetting: z
|
|
368
|
-
.enum([
|
|
369
|
-
'block_low_and_above',
|
|
370
|
-
'block_medium_and_above',
|
|
371
|
-
'block_only_high',
|
|
372
|
-
'block_none',
|
|
373
|
-
])
|
|
374
|
-
.nullish(),
|
|
375
|
-
addWatermark: z.boolean().nullish(),
|
|
376
|
-
storageUri: z.string().nullish(),
|
|
377
|
-
sampleImageSize: z.enum(['1K', '2K']).nullish(),
|
|
378
|
-
/**
|
|
379
|
-
* Configuration for image editing operations
|
|
380
|
-
*/
|
|
381
|
-
edit: z
|
|
382
|
-
.object({
|
|
383
|
-
/**
|
|
384
|
-
* An integer that represents the number of sampling steps.
|
|
385
|
-
* A higher value offers better image quality, a lower value offers better latency.
|
|
386
|
-
* Try 35 steps to start. If the quality doesn't meet your requirements,
|
|
387
|
-
* increase the value towards an upper limit of 75.
|
|
388
|
-
*/
|
|
389
|
-
baseSteps: z.number().nullish(),
|
|
390
|
-
|
|
391
|
-
// Edit mode options
|
|
392
|
-
// https://cloud.google.com/vertex-ai/generative-ai/docs/image/edit-insert-objects
|
|
393
|
-
mode: z
|
|
394
|
-
.enum([
|
|
395
|
-
'EDIT_MODE_INPAINT_INSERTION',
|
|
396
|
-
'EDIT_MODE_INPAINT_REMOVAL',
|
|
397
|
-
'EDIT_MODE_OUTPAINT',
|
|
398
|
-
'EDIT_MODE_CONTROLLED_EDITING',
|
|
399
|
-
'EDIT_MODE_PRODUCT_IMAGE',
|
|
400
|
-
'EDIT_MODE_BGSWAP',
|
|
401
|
-
])
|
|
402
|
-
.nullish(),
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* The mask mode to use.
|
|
406
|
-
* - `MASK_MODE_DEFAULT` - Default value for mask mode.
|
|
407
|
-
* - `MASK_MODE_USER_PROVIDED` - User provided mask. No segmentation needed.
|
|
408
|
-
* - `MASK_MODE_DETECTION_BOX` - Mask from detected bounding boxes.
|
|
409
|
-
* - `MASK_MODE_CLOTHING_AREA` - Masks from segmenting the clothing area with open-vocab segmentation.
|
|
410
|
-
* - `MASK_MODE_PARSED_PERSON` - Masks from segmenting the person body and clothing using the person-parsing model.
|
|
411
|
-
*/
|
|
412
|
-
maskMode: z
|
|
413
|
-
.enum([
|
|
414
|
-
'MASK_MODE_DEFAULT',
|
|
415
|
-
'MASK_MODE_USER_PROVIDED',
|
|
416
|
-
'MASK_MODE_DETECTION_BOX',
|
|
417
|
-
'MASK_MODE_CLOTHING_AREA',
|
|
418
|
-
'MASK_MODE_PARSED_PERSON',
|
|
419
|
-
])
|
|
420
|
-
.nullish(),
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Optional. A float value between 0 and 1, inclusive, that represents the
|
|
424
|
-
* percentage of the image width to grow the mask by. Using dilation helps
|
|
425
|
-
* compensate for imprecise masks. We recommend a value of 0.01.
|
|
426
|
-
*/
|
|
427
|
-
maskDilation: z.number().nullish(),
|
|
428
|
-
})
|
|
429
|
-
.nullish(),
|
|
430
|
-
});
|
|
431
|
-
export type GoogleVertexImageModelOptions = z.infer<
|
|
432
|
-
typeof googleVertexImageModelOptionsSchema
|
|
433
|
-
>;
|
|
434
|
-
|
|
435
408
|
/**
|
|
436
|
-
* Helper to convert
|
|
409
|
+
* Helper to convert ImageModelV4File data to base64 string
|
|
437
410
|
*/
|
|
438
|
-
function getBase64Data(file:
|
|
411
|
+
function getBase64Data(file: ImageModelV4File): string {
|
|
439
412
|
if (file.type === 'url') {
|
|
440
413
|
throw new Error(
|
|
441
414
|
'URL-based images are not supported for Google Vertex image editing. Please provide the image data directly.',
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// https://console.cloud.google.com/vertex-ai/studio/
|
|
4
4
|
export type GoogleVertexModelId =
|
|
5
5
|
// Stable models
|
|
6
|
+
| 'gemini-3.5-flash'
|
|
6
7
|
| 'gemini-2.5-pro'
|
|
7
8
|
| 'gemini-2.5-flash'
|
|
8
9
|
| 'gemini-2.5-flash-lite'
|
|
@@ -21,7 +22,6 @@ export type GoogleVertexModelId =
|
|
|
21
22
|
| 'gemini-1.0-pro-002'
|
|
22
23
|
// Preview models
|
|
23
24
|
| 'gemini-2.0-flash-lite-preview-02-05'
|
|
24
|
-
| 'gemini-2.5-flash-lite-preview-09-2025'
|
|
25
25
|
| 'gemini-2.5-flash-preview-09-2025'
|
|
26
26
|
| 'gemini-3-pro-preview'
|
|
27
27
|
| 'gemini-3-pro-image-preview'
|