@ai-sdk/google-vertex 4.0.23 → 4.0.24

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/anthropic/edge/index.js +1 -1
  3. package/dist/anthropic/edge/index.mjs +1 -1
  4. package/dist/edge/index.js +1 -1
  5. package/dist/edge/index.mjs +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/index.mjs +1 -1
  8. package/package.json +5 -4
  9. package/src/__snapshots__/google-vertex-embedding-model.test.ts.snap +39 -0
  10. package/src/anthropic/edge/google-vertex-anthropic-provider-edge.test.ts +87 -0
  11. package/src/anthropic/edge/google-vertex-anthropic-provider-edge.ts +41 -0
  12. package/src/anthropic/edge/index.ts +8 -0
  13. package/src/anthropic/google-vertex-anthropic-messages-options.ts +15 -0
  14. package/src/anthropic/google-vertex-anthropic-provider-node.test.ts +73 -0
  15. package/src/anthropic/google-vertex-anthropic-provider-node.ts +40 -0
  16. package/src/anthropic/google-vertex-anthropic-provider.test.ts +208 -0
  17. package/src/anthropic/google-vertex-anthropic-provider.ts +210 -0
  18. package/src/anthropic/index.ts +8 -0
  19. package/src/edge/google-vertex-auth-edge.test.ts +308 -0
  20. package/src/edge/google-vertex-auth-edge.ts +161 -0
  21. package/src/edge/google-vertex-provider-edge.test.ts +105 -0
  22. package/src/edge/google-vertex-provider-edge.ts +50 -0
  23. package/src/edge/index.ts +5 -0
  24. package/src/google-vertex-auth-google-auth-library.test.ts +59 -0
  25. package/src/google-vertex-auth-google-auth-library.ts +27 -0
  26. package/src/google-vertex-config.ts +8 -0
  27. package/src/google-vertex-embedding-model.test.ts +315 -0
  28. package/src/google-vertex-embedding-model.ts +135 -0
  29. package/src/google-vertex-embedding-options.ts +63 -0
  30. package/src/google-vertex-error.ts +19 -0
  31. package/src/google-vertex-image-model.test.ts +926 -0
  32. package/src/google-vertex-image-model.ts +288 -0
  33. package/src/google-vertex-image-settings.ts +8 -0
  34. package/src/google-vertex-options.ts +32 -0
  35. package/src/google-vertex-provider-node.test.ts +88 -0
  36. package/src/google-vertex-provider-node.ts +49 -0
  37. package/src/google-vertex-provider.test.ts +318 -0
  38. package/src/google-vertex-provider.ts +217 -0
  39. package/src/google-vertex-tools.ts +11 -0
  40. package/src/index.ts +7 -0
  41. package/src/version.ts +6 -0
@@ -0,0 +1,318 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { createVertex } from './google-vertex-provider';
3
+ import { GoogleGenerativeAILanguageModel } from '@ai-sdk/google/internal';
4
+ import { GoogleVertexEmbeddingModel } from './google-vertex-embedding-model';
5
+ import { GoogleVertexImageModel } from './google-vertex-image-model';
6
+
7
+ // Mock the imported modules
8
+ vi.mock('@ai-sdk/provider-utils', () => ({
9
+ loadSetting: vi.fn().mockImplementation(({ settingValue }) => settingValue),
10
+ loadOptionalSetting: vi
11
+ .fn()
12
+ .mockImplementation(({ settingValue, environmentVariableName }) => {
13
+ if (settingValue) return settingValue;
14
+ if (
15
+ environmentVariableName === 'GOOGLE_VERTEX_API_KEY' &&
16
+ process.env.GOOGLE_VERTEX_API_KEY
17
+ ) {
18
+ return process.env.GOOGLE_VERTEX_API_KEY;
19
+ }
20
+ return undefined;
21
+ }),
22
+ generateId: vi.fn().mockReturnValue('mock-id'),
23
+ withoutTrailingSlash: vi.fn().mockImplementation(url => url),
24
+ resolve: vi.fn().mockImplementation(async value => {
25
+ if (typeof value === 'function') return value();
26
+ return value;
27
+ }),
28
+ withUserAgentSuffix: vi.fn().mockImplementation(headers => headers),
29
+ }));
30
+
31
+ vi.mock('@ai-sdk/google/internal', () => ({
32
+ GoogleGenerativeAILanguageModel: vi.fn(),
33
+ googleTools: {
34
+ googleSearch: vi.fn(),
35
+ urlContext: vi.fn(),
36
+ fileSearch: vi.fn(),
37
+ codeExecution: vi.fn(),
38
+ },
39
+ }));
40
+
41
+ vi.mock('./google-vertex-embedding-model', () => ({
42
+ GoogleVertexEmbeddingModel: vi.fn(),
43
+ }));
44
+
45
+ vi.mock('./google-vertex-image-model', () => ({
46
+ GoogleVertexImageModel: vi.fn(),
47
+ }));
48
+
49
+ describe('google-vertex-provider', () => {
50
+ beforeEach(() => {
51
+ vi.clearAllMocks();
52
+ delete process.env.GOOGLE_VERTEX_API_KEY;
53
+ });
54
+
55
+ afterEach(() => {
56
+ delete process.env.GOOGLE_VERTEX_API_KEY;
57
+ });
58
+
59
+ it('should create a language model with default settings', () => {
60
+ const provider = createVertex({
61
+ project: 'test-project',
62
+ location: 'test-location',
63
+ });
64
+ provider('test-model-id');
65
+
66
+ expect(GoogleGenerativeAILanguageModel).toHaveBeenCalledWith(
67
+ 'test-model-id',
68
+ expect.objectContaining({
69
+ provider: 'google.vertex.chat',
70
+ baseURL:
71
+ 'https://test-location-aiplatform.googleapis.com/v1beta1/projects/test-project/locations/test-location/publishers/google',
72
+ headers: expect.any(Function),
73
+ generateId: expect.any(Function),
74
+ }),
75
+ );
76
+ });
77
+
78
+ it('should throw an error when using new keyword', () => {
79
+ const provider = createVertex({ project: 'test-project' });
80
+
81
+ expect(() => new (provider as any)('test-model-id')).toThrow(
82
+ 'The Google Vertex AI model function cannot be called with the new keyword.',
83
+ );
84
+ });
85
+
86
+ it('should create an embedding model with correct settings', () => {
87
+ const provider = createVertex({
88
+ project: 'test-project',
89
+ location: 'test-location',
90
+ });
91
+ provider.embeddingModel('test-embedding-model');
92
+
93
+ expect(GoogleVertexEmbeddingModel).toHaveBeenCalledWith(
94
+ 'test-embedding-model',
95
+ expect.objectContaining({
96
+ provider: 'google.vertex.embedding',
97
+ headers: expect.any(Function),
98
+ baseURL:
99
+ 'https://test-location-aiplatform.googleapis.com/v1beta1/projects/test-project/locations/test-location/publishers/google',
100
+ }),
101
+ );
102
+ });
103
+
104
+ it('should pass custom headers to the model constructor', () => {
105
+ const customHeaders = { 'Custom-Header': 'custom-value' };
106
+ const provider = createVertex({
107
+ project: 'test-project',
108
+ location: 'test-location',
109
+ headers: customHeaders,
110
+ });
111
+ provider('test-model-id');
112
+
113
+ expect(GoogleGenerativeAILanguageModel).toHaveBeenCalledWith(
114
+ expect.anything(),
115
+ expect.objectContaining({
116
+ headers: expect.any(Function),
117
+ }),
118
+ );
119
+ });
120
+
121
+ it('should pass custom generateId function to the model constructor', () => {
122
+ const customGenerateId = () => 'custom-id';
123
+ const provider = createVertex({
124
+ project: 'test-project',
125
+ location: 'test-location',
126
+ generateId: customGenerateId,
127
+ });
128
+ provider('test-model-id');
129
+
130
+ expect(GoogleGenerativeAILanguageModel).toHaveBeenCalledWith(
131
+ expect.anything(),
132
+ expect.objectContaining({
133
+ generateId: customGenerateId,
134
+ }),
135
+ );
136
+ });
137
+
138
+ it('should use languageModel method to create a model', () => {
139
+ const provider = createVertex({
140
+ project: 'test-project',
141
+ location: 'test-location',
142
+ });
143
+ provider.languageModel('test-model-id');
144
+
145
+ expect(GoogleGenerativeAILanguageModel).toHaveBeenCalledWith(
146
+ 'test-model-id',
147
+ expect.any(Object),
148
+ );
149
+ });
150
+
151
+ it('should use custom baseURL when provided', () => {
152
+ const customBaseURL = 'https://custom-endpoint.example.com';
153
+ const provider = createVertex({
154
+ project: 'test-project',
155
+ location: 'test-location',
156
+ baseURL: customBaseURL,
157
+ });
158
+ provider('test-model-id');
159
+
160
+ expect(GoogleGenerativeAILanguageModel).toHaveBeenCalledWith(
161
+ 'test-model-id',
162
+ expect.objectContaining({
163
+ baseURL: customBaseURL,
164
+ }),
165
+ );
166
+ });
167
+
168
+ it('should create an image model with default settings', () => {
169
+ const provider = createVertex({
170
+ project: 'test-project',
171
+ location: 'test-location',
172
+ });
173
+ provider.image('imagen-3.0-generate-002');
174
+
175
+ expect(GoogleVertexImageModel).toHaveBeenCalledWith(
176
+ 'imagen-3.0-generate-002',
177
+ expect.objectContaining({
178
+ provider: 'google.vertex.image',
179
+ baseURL:
180
+ 'https://test-location-aiplatform.googleapis.com/v1beta1/projects/test-project/locations/test-location/publishers/google',
181
+ headers: expect.any(Function),
182
+ }),
183
+ );
184
+ });
185
+
186
+ it('should use correct URL for global region', () => {
187
+ const provider = createVertex({
188
+ project: 'test-project',
189
+ location: 'global',
190
+ });
191
+ provider('test-model-id');
192
+
193
+ expect(GoogleGenerativeAILanguageModel).toHaveBeenCalledWith(
194
+ 'test-model-id',
195
+ expect.objectContaining({
196
+ provider: 'google.vertex.chat',
197
+ baseURL:
198
+ 'https://aiplatform.googleapis.com/v1beta1/projects/test-project/locations/global/publishers/google',
199
+ headers: expect.any(Function),
200
+ generateId: expect.any(Function),
201
+ }),
202
+ );
203
+ });
204
+
205
+ it('should use correct URL for global region with embedding model', () => {
206
+ const provider = createVertex({
207
+ project: 'test-project',
208
+ location: 'global',
209
+ });
210
+ provider.embeddingModel('test-embedding-model');
211
+
212
+ expect(GoogleVertexEmbeddingModel).toHaveBeenCalledWith(
213
+ 'test-embedding-model',
214
+ expect.objectContaining({
215
+ provider: 'google.vertex.embedding',
216
+ headers: expect.any(Function),
217
+ baseURL:
218
+ 'https://aiplatform.googleapis.com/v1beta1/projects/test-project/locations/global/publishers/google',
219
+ }),
220
+ );
221
+ });
222
+
223
+ it('should use correct URL for global region with image model', () => {
224
+ const provider = createVertex({
225
+ project: 'test-project',
226
+ location: 'global',
227
+ });
228
+ provider.image('imagen-3.0-generate-002');
229
+
230
+ expect(GoogleVertexImageModel).toHaveBeenCalledWith(
231
+ 'imagen-3.0-generate-002',
232
+ expect.objectContaining({
233
+ provider: 'google.vertex.image',
234
+ baseURL:
235
+ 'https://aiplatform.googleapis.com/v1beta1/projects/test-project/locations/global/publishers/google',
236
+ headers: expect.any(Function),
237
+ }),
238
+ );
239
+ });
240
+
241
+ it('should expose tools', () => {
242
+ const provider = createVertex({
243
+ project: 'test-project',
244
+ location: 'test-location',
245
+ });
246
+
247
+ expect(provider.tools).toBeDefined();
248
+ expect(provider.tools.googleSearch).toBeDefined();
249
+ expect(provider.tools.urlContext).toBeDefined();
250
+ expect(provider.tools.codeExecution).toBeDefined();
251
+ });
252
+
253
+ it('should use region-prefixed URL for non-global regions', () => {
254
+ const provider = createVertex({
255
+ project: 'test-project',
256
+ location: 'us-central1',
257
+ });
258
+ provider('test-model-id');
259
+
260
+ expect(GoogleGenerativeAILanguageModel).toHaveBeenCalledWith(
261
+ 'test-model-id',
262
+ expect.objectContaining({
263
+ provider: 'google.vertex.chat',
264
+ baseURL:
265
+ 'https://us-central1-aiplatform.googleapis.com/v1beta1/projects/test-project/locations/us-central1/publishers/google',
266
+ headers: expect.any(Function),
267
+ generateId: expect.any(Function),
268
+ }),
269
+ );
270
+ });
271
+
272
+ it('should use express mode base URL when apiKey is provided', () => {
273
+ const provider = createVertex({
274
+ apiKey: 'test-api-key',
275
+ });
276
+ provider('test-model-id');
277
+
278
+ expect(GoogleGenerativeAILanguageModel).toHaveBeenCalledWith(
279
+ 'test-model-id',
280
+ expect.objectContaining({
281
+ baseURL: 'https://aiplatform.googleapis.com/v1/publishers/google',
282
+ }),
283
+ );
284
+ });
285
+
286
+ it('should add API key as query parameter via custom fetch', async () => {
287
+ const provider = createVertex({
288
+ apiKey: 'test-api-key',
289
+ });
290
+ provider('test-model-id');
291
+
292
+ const calledConfig = vi.mocked(GoogleGenerativeAILanguageModel).mock
293
+ .calls[0][1];
294
+ const customFetch = calledConfig.fetch;
295
+
296
+ expect(customFetch).toBeDefined();
297
+
298
+ const mockResponse = new Response('{}');
299
+ const originalFetch = vi.fn().mockResolvedValue(mockResponse);
300
+ vi.stubGlobal('fetch', originalFetch);
301
+
302
+ await customFetch!(
303
+ 'https://aiplatform.googleapis.com/v1/publishers/google/models/gemini-2.5-pro:streamGenerateContent',
304
+ {},
305
+ );
306
+
307
+ expect(originalFetch).toHaveBeenCalledWith(
308
+ 'https://aiplatform.googleapis.com/v1/publishers/google/models/gemini-2.5-pro:streamGenerateContent',
309
+ {
310
+ headers: {
311
+ 'x-goog-api-key': 'test-api-key',
312
+ },
313
+ },
314
+ );
315
+
316
+ vi.unstubAllGlobals();
317
+ });
318
+ });
@@ -0,0 +1,217 @@
1
+ import { GoogleGenerativeAILanguageModel } from '@ai-sdk/google/internal';
2
+ import { ImageModelV3, LanguageModelV3, ProviderV3 } from '@ai-sdk/provider';
3
+ import {
4
+ FetchFunction,
5
+ generateId,
6
+ loadOptionalSetting,
7
+ loadSetting,
8
+ normalizeHeaders,
9
+ resolve,
10
+ Resolvable,
11
+ withoutTrailingSlash,
12
+ withUserAgentSuffix,
13
+ } from '@ai-sdk/provider-utils';
14
+ import { VERSION } from './version';
15
+ import { GoogleVertexConfig } from './google-vertex-config';
16
+ import { GoogleVertexEmbeddingModel } from './google-vertex-embedding-model';
17
+ import { GoogleVertexEmbeddingModelId } from './google-vertex-embedding-options';
18
+ import { GoogleVertexImageModel } from './google-vertex-image-model';
19
+ import { GoogleVertexImageModelId } from './google-vertex-image-settings';
20
+ import { GoogleVertexModelId } from './google-vertex-options';
21
+ import { googleVertexTools } from './google-vertex-tools';
22
+
23
+ const EXPRESS_MODE_BASE_URL =
24
+ 'https://aiplatform.googleapis.com/v1/publishers/google';
25
+
26
+ // set `x-goog-api-key` header to API key for express mode
27
+ function createExpressModeFetch(
28
+ apiKey: string,
29
+ customFetch?: FetchFunction,
30
+ ): FetchFunction {
31
+ return async (url, init) => {
32
+ const modifiedInit: RequestInit = {
33
+ ...init,
34
+ headers: {
35
+ ...(init?.headers ? normalizeHeaders(init.headers) : {}),
36
+ 'x-goog-api-key': apiKey,
37
+ },
38
+ };
39
+ return (customFetch ?? fetch)(url.toString(), modifiedInit);
40
+ };
41
+ }
42
+
43
+ export interface GoogleVertexProvider extends ProviderV3 {
44
+ /**
45
+ Creates a model for text generation.
46
+ */
47
+ (modelId: GoogleVertexModelId): LanguageModelV3;
48
+
49
+ languageModel: (modelId: GoogleVertexModelId) => LanguageModelV3;
50
+
51
+ /**
52
+ * Creates a model for image generation.
53
+ */
54
+ image(modelId: GoogleVertexImageModelId): ImageModelV3;
55
+
56
+ /**
57
+ Creates a model for image generation.
58
+ */
59
+ imageModel(modelId: GoogleVertexImageModelId): ImageModelV3;
60
+
61
+ tools: typeof googleVertexTools;
62
+
63
+ /**
64
+ * @deprecated Use `embeddingModel` instead.
65
+ */
66
+ textEmbeddingModel(
67
+ modelId: GoogleVertexEmbeddingModelId,
68
+ ): GoogleVertexEmbeddingModel;
69
+ }
70
+
71
+ export interface GoogleVertexProviderSettings {
72
+ /**
73
+ * Optional. The API key for the Google Cloud project. If provided, the
74
+ * provider will use express mode with API key authentication. Defaults to
75
+ * the value of the `GOOGLE_VERTEX_API_KEY` environment variable.
76
+ */
77
+ apiKey?: string;
78
+
79
+ /**
80
+ Your Google Vertex location. Defaults to the environment variable `GOOGLE_VERTEX_LOCATION`.
81
+ */
82
+ location?: string;
83
+
84
+ /**
85
+ Your Google Vertex project. Defaults to the environment variable `GOOGLE_VERTEX_PROJECT`.
86
+ */
87
+ project?: string;
88
+
89
+ /**
90
+ * Headers to use for requests. Can be:
91
+ * - A headers object
92
+ * - A Promise that resolves to a headers object
93
+ * - A function that returns a headers object
94
+ * - A function that returns a Promise of a headers object
95
+ */
96
+ headers?: Resolvable<Record<string, string | undefined>>;
97
+
98
+ /**
99
+ Custom fetch implementation. You can use it as a middleware to intercept requests,
100
+ or to provide a custom fetch implementation for e.g. testing.
101
+ */
102
+ fetch?: FetchFunction;
103
+
104
+ // for testing
105
+ generateId?: () => string;
106
+
107
+ /**
108
+ Base URL for the Google Vertex API calls.
109
+ */
110
+ baseURL?: string;
111
+ }
112
+
113
+ /**
114
+ Create a Google Vertex AI provider instance.
115
+ */
116
+ export function createVertex(
117
+ options: GoogleVertexProviderSettings = {},
118
+ ): GoogleVertexProvider {
119
+ const apiKey = loadOptionalSetting({
120
+ settingValue: options.apiKey,
121
+ environmentVariableName: 'GOOGLE_VERTEX_API_KEY',
122
+ });
123
+
124
+ const loadVertexProject = () =>
125
+ loadSetting({
126
+ settingValue: options.project,
127
+ settingName: 'project',
128
+ environmentVariableName: 'GOOGLE_VERTEX_PROJECT',
129
+ description: 'Google Vertex project',
130
+ });
131
+
132
+ const loadVertexLocation = () =>
133
+ loadSetting({
134
+ settingValue: options.location,
135
+ settingName: 'location',
136
+ environmentVariableName: 'GOOGLE_VERTEX_LOCATION',
137
+ description: 'Google Vertex location',
138
+ });
139
+
140
+ const loadBaseURL = () => {
141
+ if (apiKey) {
142
+ return withoutTrailingSlash(options.baseURL) ?? EXPRESS_MODE_BASE_URL;
143
+ }
144
+
145
+ const region = loadVertexLocation();
146
+ const project = loadVertexProject();
147
+
148
+ // For global region, use aiplatform.googleapis.com directly
149
+ // For other regions, use region-aiplatform.googleapis.com
150
+ const baseHost = `${region === 'global' ? '' : region + '-'}aiplatform.googleapis.com`;
151
+
152
+ return (
153
+ withoutTrailingSlash(options.baseURL) ??
154
+ `https://${baseHost}/v1beta1/projects/${project}/locations/${region}/publishers/google`
155
+ );
156
+ };
157
+
158
+ const createConfig = (name: string): GoogleVertexConfig => {
159
+ const getHeaders = async () => {
160
+ const originalHeaders = await resolve(options.headers ?? {});
161
+ return withUserAgentSuffix(
162
+ originalHeaders,
163
+ `ai-sdk/google-vertex/${VERSION}`,
164
+ );
165
+ };
166
+
167
+ return {
168
+ provider: `google.vertex.${name}`,
169
+ headers: getHeaders,
170
+ fetch: apiKey
171
+ ? createExpressModeFetch(apiKey, options.fetch)
172
+ : options.fetch,
173
+ baseURL: loadBaseURL(),
174
+ };
175
+ };
176
+
177
+ const createChatModel = (modelId: GoogleVertexModelId) => {
178
+ return new GoogleGenerativeAILanguageModel(modelId, {
179
+ ...createConfig('chat'),
180
+ generateId: options.generateId ?? generateId,
181
+ supportedUrls: () => ({
182
+ '*': [
183
+ // HTTP URLs:
184
+ /^https?:\/\/.*$/,
185
+ // Google Cloud Storage URLs:
186
+ /^gs:\/\/.*$/,
187
+ ],
188
+ }),
189
+ });
190
+ };
191
+
192
+ const createEmbeddingModel = (modelId: GoogleVertexEmbeddingModelId) =>
193
+ new GoogleVertexEmbeddingModel(modelId, createConfig('embedding'));
194
+
195
+ const createImageModel = (modelId: GoogleVertexImageModelId) =>
196
+ new GoogleVertexImageModel(modelId, createConfig('image'));
197
+
198
+ const provider = function (modelId: GoogleVertexModelId) {
199
+ if (new.target) {
200
+ throw new Error(
201
+ 'The Google Vertex AI model function cannot be called with the new keyword.',
202
+ );
203
+ }
204
+
205
+ return createChatModel(modelId);
206
+ };
207
+
208
+ provider.specificationVersion = 'v3' as const;
209
+ provider.languageModel = createChatModel;
210
+ provider.embeddingModel = createEmbeddingModel;
211
+ provider.textEmbeddingModel = createEmbeddingModel;
212
+ provider.image = createImageModel;
213
+ provider.imageModel = createImageModel;
214
+ provider.tools = googleVertexTools;
215
+
216
+ return provider;
217
+ }
@@ -0,0 +1,11 @@
1
+ import { googleTools } from '@ai-sdk/google/internal';
2
+
3
+ export const googleVertexTools = {
4
+ googleSearch: googleTools.googleSearch,
5
+ enterpriseWebSearch: googleTools.enterpriseWebSearch,
6
+ googleMaps: googleTools.googleMaps,
7
+ urlContext: googleTools.urlContext,
8
+ fileSearch: googleTools.fileSearch,
9
+ codeExecution: googleTools.codeExecution,
10
+ vertexRagStore: googleTools.vertexRagStore,
11
+ };
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export type { GoogleVertexImageProviderOptions } from './google-vertex-image-model';
2
+ export { createVertex, vertex } from './google-vertex-provider-node';
3
+ export type {
4
+ GoogleVertexProvider,
5
+ GoogleVertexProviderSettings,
6
+ } from './google-vertex-provider-node';
7
+ export { VERSION } from './version';
package/src/version.ts ADDED
@@ -0,0 +1,6 @@
1
+ // Version string of this package injected at build time.
2
+ declare const __PACKAGE_VERSION__: string | undefined;
3
+ export const VERSION: string =
4
+ typeof __PACKAGE_VERSION__ !== 'undefined'
5
+ ? __PACKAGE_VERSION__
6
+ : '0.0.0-test';