@ai-sdk/google-vertex 4.0.23 → 4.0.25
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 +18 -0
- package/dist/anthropic/edge/index.js +1 -1
- package/dist/anthropic/edge/index.mjs +1 -1
- package/dist/edge/index.js +1 -1
- package/dist/edge/index.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/docs/16-google-vertex.mdx +1407 -0
- package/package.json +10 -5
- package/src/__snapshots__/google-vertex-embedding-model.test.ts.snap +39 -0
- package/src/anthropic/edge/google-vertex-anthropic-provider-edge.test.ts +87 -0
- package/src/anthropic/edge/google-vertex-anthropic-provider-edge.ts +41 -0
- package/src/anthropic/edge/index.ts +8 -0
- package/src/anthropic/google-vertex-anthropic-messages-options.ts +15 -0
- package/src/anthropic/google-vertex-anthropic-provider-node.test.ts +73 -0
- package/src/anthropic/google-vertex-anthropic-provider-node.ts +40 -0
- package/src/anthropic/google-vertex-anthropic-provider.test.ts +208 -0
- package/src/anthropic/google-vertex-anthropic-provider.ts +210 -0
- package/src/anthropic/index.ts +8 -0
- package/src/edge/google-vertex-auth-edge.test.ts +308 -0
- package/src/edge/google-vertex-auth-edge.ts +161 -0
- package/src/edge/google-vertex-provider-edge.test.ts +105 -0
- package/src/edge/google-vertex-provider-edge.ts +50 -0
- package/src/edge/index.ts +5 -0
- package/src/google-vertex-auth-google-auth-library.test.ts +59 -0
- package/src/google-vertex-auth-google-auth-library.ts +27 -0
- package/src/google-vertex-config.ts +8 -0
- package/src/google-vertex-embedding-model.test.ts +315 -0
- package/src/google-vertex-embedding-model.ts +135 -0
- package/src/google-vertex-embedding-options.ts +63 -0
- package/src/google-vertex-error.ts +19 -0
- package/src/google-vertex-image-model.test.ts +926 -0
- package/src/google-vertex-image-model.ts +288 -0
- package/src/google-vertex-image-settings.ts +8 -0
- package/src/google-vertex-options.ts +32 -0
- package/src/google-vertex-provider-node.test.ts +88 -0
- package/src/google-vertex-provider-node.ts +49 -0
- package/src/google-vertex-provider.test.ts +318 -0
- package/src/google-vertex-provider.ts +217 -0
- package/src/google-vertex-tools.ts +11 -0
- package/src/index.ts +7 -0
- package/src/version.ts +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/google-vertex",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.25",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -8,12 +8,17 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist/**/*",
|
|
11
|
+
"docs/**/*",
|
|
12
|
+
"src",
|
|
11
13
|
"CHANGELOG.md",
|
|
12
14
|
"README.md",
|
|
13
15
|
"edge.d.ts",
|
|
14
16
|
"anthropic/edge.d.ts",
|
|
15
17
|
"anthropic/index.d.ts"
|
|
16
18
|
],
|
|
19
|
+
"directories": {
|
|
20
|
+
"doc": "./docs"
|
|
21
|
+
},
|
|
17
22
|
"exports": {
|
|
18
23
|
"./package.json": "./package.json",
|
|
19
24
|
".": {
|
|
@@ -39,8 +44,8 @@
|
|
|
39
44
|
},
|
|
40
45
|
"dependencies": {
|
|
41
46
|
"google-auth-library": "^10.5.0",
|
|
42
|
-
"@ai-sdk/anthropic": "3.0.
|
|
43
|
-
"@ai-sdk/google": "3.0.
|
|
47
|
+
"@ai-sdk/anthropic": "3.0.20",
|
|
48
|
+
"@ai-sdk/google": "3.0.12",
|
|
44
49
|
"@ai-sdk/provider": "3.0.4",
|
|
45
50
|
"@ai-sdk/provider-utils": "4.0.8"
|
|
46
51
|
},
|
|
@@ -49,7 +54,7 @@
|
|
|
49
54
|
"tsup": "^8",
|
|
50
55
|
"typescript": "5.8.3",
|
|
51
56
|
"zod": "3.25.76",
|
|
52
|
-
"@ai-sdk/test-server": "1.0.
|
|
57
|
+
"@ai-sdk/test-server": "1.0.2",
|
|
53
58
|
"@vercel/ai-tsconfig": "0.0.0"
|
|
54
59
|
},
|
|
55
60
|
"peerDependencies": {
|
|
@@ -75,7 +80,7 @@
|
|
|
75
80
|
"scripts": {
|
|
76
81
|
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
77
82
|
"build:watch": "pnpm clean && tsup --watch",
|
|
78
|
-
"clean": "del-cli dist *.tsbuildinfo",
|
|
83
|
+
"clean": "del-cli dist docs *.tsbuildinfo",
|
|
79
84
|
"lint": "eslint \"./**/*.ts*\"",
|
|
80
85
|
"type-check": "tsc --build",
|
|
81
86
|
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`GoogleVertexEmbeddingModel > should expose the raw response 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"body": {
|
|
6
|
+
"predictions": [
|
|
7
|
+
{
|
|
8
|
+
"embeddings": {
|
|
9
|
+
"statistics": {
|
|
10
|
+
"token_count": 1,
|
|
11
|
+
},
|
|
12
|
+
"values": [
|
|
13
|
+
0.1,
|
|
14
|
+
0.2,
|
|
15
|
+
0.3,
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"embeddings": {
|
|
21
|
+
"statistics": {
|
|
22
|
+
"token_count": 1,
|
|
23
|
+
},
|
|
24
|
+
"values": [
|
|
25
|
+
0.4,
|
|
26
|
+
0.5,
|
|
27
|
+
0.6,
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
"headers": {
|
|
34
|
+
"content-length": "159",
|
|
35
|
+
"content-type": "application/json",
|
|
36
|
+
"test-header": "test-value",
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { resolve } from '@ai-sdk/provider-utils';
|
|
2
|
+
import * as edgeAuth from '../../edge/google-vertex-auth-edge';
|
|
3
|
+
import { createVertexAnthropic as createVertexAnthropicOriginal } from '../google-vertex-anthropic-provider';
|
|
4
|
+
import { createVertexAnthropic as createVertexAnthropicEdge } from './google-vertex-anthropic-provider-edge';
|
|
5
|
+
import { describe, beforeEach, expect, it, vi } from 'vitest';
|
|
6
|
+
|
|
7
|
+
// Mock the imported modules
|
|
8
|
+
vi.mock('../../edge/google-vertex-auth-edge', () => ({
|
|
9
|
+
generateAuthToken: vi.fn().mockResolvedValue('mock-auth-token'),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
vi.mock('../google-vertex-anthropic-provider', () => ({
|
|
13
|
+
createVertexAnthropic: vi.fn().mockImplementation(options => ({
|
|
14
|
+
...options,
|
|
15
|
+
})),
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
describe('google-vertex-anthropic-provider-edge', () => {
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
vi.clearAllMocks();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('default headers function should return auth token', async () => {
|
|
24
|
+
createVertexAnthropicEdge({ project: 'test-project' });
|
|
25
|
+
|
|
26
|
+
const mockCreateVertex = vi.mocked(createVertexAnthropicOriginal);
|
|
27
|
+
const passedOptions = mockCreateVertex.mock.calls[0][0];
|
|
28
|
+
|
|
29
|
+
expect(mockCreateVertex).toHaveBeenCalledTimes(1);
|
|
30
|
+
expect(typeof passedOptions?.headers).toBe('function');
|
|
31
|
+
|
|
32
|
+
expect(await resolve(passedOptions?.headers)).toStrictEqual({
|
|
33
|
+
Authorization: 'Bearer mock-auth-token',
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should use custom headers in addition to auth token when provided', async () => {
|
|
38
|
+
createVertexAnthropicEdge({
|
|
39
|
+
project: 'test-project',
|
|
40
|
+
headers: async () => ({
|
|
41
|
+
'Custom-Header': 'custom-value',
|
|
42
|
+
}),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const mockCreateVertex = vi.mocked(createVertexAnthropicOriginal);
|
|
46
|
+
const passedOptions = mockCreateVertex.mock.calls[0][0];
|
|
47
|
+
|
|
48
|
+
expect(mockCreateVertex).toHaveBeenCalledTimes(1);
|
|
49
|
+
expect(typeof passedOptions?.headers).toBe('function');
|
|
50
|
+
expect(await resolve(passedOptions?.headers)).toEqual({
|
|
51
|
+
Authorization: 'Bearer mock-auth-token',
|
|
52
|
+
'Custom-Header': 'custom-value',
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should use edge auth token generator', async () => {
|
|
57
|
+
createVertexAnthropicEdge({ project: 'test-project' });
|
|
58
|
+
|
|
59
|
+
const mockCreateVertex = vi.mocked(createVertexAnthropicOriginal);
|
|
60
|
+
const passedOptions = mockCreateVertex.mock.calls[0][0];
|
|
61
|
+
|
|
62
|
+
// Verify the headers function actually calls generateAuthToken by checking its result
|
|
63
|
+
expect(passedOptions?.headers).toBeDefined();
|
|
64
|
+
await resolve(passedOptions?.headers);
|
|
65
|
+
expect(edgeAuth.generateAuthToken).toHaveBeenCalled();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('passes googleCredentials to generateAuthToken', async () => {
|
|
69
|
+
createVertexAnthropicEdge({
|
|
70
|
+
project: 'test-project',
|
|
71
|
+
googleCredentials: {
|
|
72
|
+
clientEmail: 'test@example.com',
|
|
73
|
+
privateKey: 'test-key',
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const mockCreateVertex = vi.mocked(createVertexAnthropicOriginal);
|
|
78
|
+
const passedOptions = mockCreateVertex.mock.calls[0][0];
|
|
79
|
+
|
|
80
|
+
await resolve(passedOptions?.headers); // call the headers function
|
|
81
|
+
|
|
82
|
+
expect(edgeAuth.generateAuthToken).toHaveBeenCalledWith({
|
|
83
|
+
clientEmail: 'test@example.com',
|
|
84
|
+
privateKey: 'test-key',
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { resolve } from '@ai-sdk/provider-utils';
|
|
2
|
+
import {
|
|
3
|
+
generateAuthToken,
|
|
4
|
+
GoogleCredentials,
|
|
5
|
+
} from '../../edge/google-vertex-auth-edge';
|
|
6
|
+
import {
|
|
7
|
+
createVertexAnthropic as createVertexAnthropicOriginal,
|
|
8
|
+
GoogleVertexAnthropicProvider,
|
|
9
|
+
GoogleVertexAnthropicProviderSettings as GoogleVertexAnthropicProviderSettingsOriginal,
|
|
10
|
+
} from '../google-vertex-anthropic-provider';
|
|
11
|
+
|
|
12
|
+
export type { GoogleVertexAnthropicProvider };
|
|
13
|
+
|
|
14
|
+
export interface GoogleVertexAnthropicProviderSettings
|
|
15
|
+
extends GoogleVertexAnthropicProviderSettingsOriginal {
|
|
16
|
+
/**
|
|
17
|
+
* Optional. The Google credentials for the Google Cloud service account. If
|
|
18
|
+
* not provided, the Google Vertex provider will use environment variables to
|
|
19
|
+
* load the credentials.
|
|
20
|
+
*/
|
|
21
|
+
googleCredentials?: GoogleCredentials;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function createVertexAnthropic(
|
|
25
|
+
options: GoogleVertexAnthropicProviderSettings = {},
|
|
26
|
+
): GoogleVertexAnthropicProvider {
|
|
27
|
+
return createVertexAnthropicOriginal({
|
|
28
|
+
...options,
|
|
29
|
+
headers: async () => ({
|
|
30
|
+
Authorization: `Bearer ${await generateAuthToken(
|
|
31
|
+
options.googleCredentials,
|
|
32
|
+
)}`,
|
|
33
|
+
...(await resolve(options.headers)),
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Default Google Vertex AI Anthropic provider instance.
|
|
40
|
+
*/
|
|
41
|
+
export const vertexAnthropic = createVertexAnthropic();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/claude
|
|
2
|
+
export type GoogleVertexAnthropicMessagesModelId =
|
|
3
|
+
| 'claude-opus-4-5@20251101'
|
|
4
|
+
| 'claude-sonnet-4-5@20250929'
|
|
5
|
+
| 'claude-opus-4-1@20250805'
|
|
6
|
+
| 'claude-opus-4@20250514'
|
|
7
|
+
| 'claude-sonnet-4@20250514'
|
|
8
|
+
| 'claude-3-7-sonnet@20250219'
|
|
9
|
+
| 'claude-3-5-sonnet-v2@20241022'
|
|
10
|
+
| 'claude-3-5-haiku@20241022'
|
|
11
|
+
| 'claude-3-5-sonnet@20240620'
|
|
12
|
+
| 'claude-3-haiku@20240307'
|
|
13
|
+
| 'claude-3-sonnet@20240229'
|
|
14
|
+
| 'claude-3-opus@20240229'
|
|
15
|
+
| (string & {});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { resolve } from '@ai-sdk/provider-utils';
|
|
2
|
+
import { createVertexAnthropic as createVertexAnthropicOriginal } from './google-vertex-anthropic-provider';
|
|
3
|
+
import { createVertexAnthropic as createVertexAnthropicNode } from './google-vertex-anthropic-provider-node';
|
|
4
|
+
import { generateAuthToken } from '../google-vertex-auth-google-auth-library';
|
|
5
|
+
import { describe, beforeEach, expect, it, vi } from 'vitest';
|
|
6
|
+
|
|
7
|
+
// Mock the imported modules
|
|
8
|
+
vi.mock('../google-vertex-auth-google-auth-library', () => ({
|
|
9
|
+
generateAuthToken: vi.fn().mockResolvedValue('mock-auth-token'),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
vi.mock('./google-vertex-anthropic-provider', () => ({
|
|
13
|
+
createVertexAnthropic: vi.fn().mockImplementation(options => ({
|
|
14
|
+
...options,
|
|
15
|
+
})),
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
describe('google-vertex-anthropic-provider-node', () => {
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
vi.clearAllMocks();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('default headers function should return auth token', async () => {
|
|
24
|
+
createVertexAnthropicNode({ project: 'test-project' });
|
|
25
|
+
|
|
26
|
+
expect(createVertexAnthropicOriginal).toHaveBeenCalledTimes(1);
|
|
27
|
+
const passedOptions = vi.mocked(createVertexAnthropicOriginal).mock
|
|
28
|
+
.calls[0][0];
|
|
29
|
+
|
|
30
|
+
expect(typeof passedOptions?.headers).toBe('function');
|
|
31
|
+
expect(await resolve(passedOptions?.headers)).toStrictEqual({
|
|
32
|
+
Authorization: 'Bearer mock-auth-token',
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should use custom headers in addition to auth token when provided', async () => {
|
|
37
|
+
createVertexAnthropicNode({
|
|
38
|
+
project: 'test-project',
|
|
39
|
+
headers: async () => ({
|
|
40
|
+
'Custom-Header': 'custom-value',
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
expect(createVertexAnthropicOriginal).toHaveBeenCalledTimes(1);
|
|
45
|
+
const passedOptions = vi.mocked(createVertexAnthropicOriginal).mock
|
|
46
|
+
.calls[0][0];
|
|
47
|
+
|
|
48
|
+
expect(await resolve(passedOptions?.headers)).toEqual({
|
|
49
|
+
Authorization: 'Bearer mock-auth-token',
|
|
50
|
+
'Custom-Header': 'custom-value',
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('passes googleAuthOptions to generateAuthToken', async () => {
|
|
55
|
+
createVertexAnthropicNode({
|
|
56
|
+
googleAuthOptions: {
|
|
57
|
+
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
|
|
58
|
+
keyFile: 'path/to/key.json',
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
expect(createVertexAnthropicOriginal).toHaveBeenCalledTimes(1);
|
|
63
|
+
const passedOptions = vi.mocked(createVertexAnthropicOriginal).mock
|
|
64
|
+
.calls[0][0];
|
|
65
|
+
|
|
66
|
+
await resolve(passedOptions?.headers); // call the headers function
|
|
67
|
+
|
|
68
|
+
expect(generateAuthToken).toHaveBeenCalledWith({
|
|
69
|
+
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
|
|
70
|
+
keyFile: 'path/to/key.json',
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { resolve } from '@ai-sdk/provider-utils';
|
|
2
|
+
import { GoogleAuthOptions } from 'google-auth-library';
|
|
3
|
+
import { generateAuthToken } from '../google-vertex-auth-google-auth-library';
|
|
4
|
+
import {
|
|
5
|
+
createVertexAnthropic as createVertexAnthropicOriginal,
|
|
6
|
+
GoogleVertexAnthropicProvider,
|
|
7
|
+
GoogleVertexAnthropicProviderSettings as GoogleVertexAnthropicProviderSettingsOriginal,
|
|
8
|
+
} from './google-vertex-anthropic-provider';
|
|
9
|
+
|
|
10
|
+
export type { GoogleVertexAnthropicProvider };
|
|
11
|
+
|
|
12
|
+
export interface GoogleVertexAnthropicProviderSettings
|
|
13
|
+
extends GoogleVertexAnthropicProviderSettingsOriginal {
|
|
14
|
+
/**
|
|
15
|
+
Optional. The Authentication options provided by google-auth-library.
|
|
16
|
+
Complete list of authentication options is documented in the
|
|
17
|
+
GoogleAuthOptions interface:
|
|
18
|
+
https://github.com/googleapis/google-auth-library-nodejs/blob/main/src/auth/googleauth.ts.
|
|
19
|
+
*/
|
|
20
|
+
googleAuthOptions?: GoogleAuthOptions;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function createVertexAnthropic(
|
|
24
|
+
options: GoogleVertexAnthropicProviderSettings = {},
|
|
25
|
+
): GoogleVertexAnthropicProvider {
|
|
26
|
+
return createVertexAnthropicOriginal({
|
|
27
|
+
...options,
|
|
28
|
+
headers: async () => ({
|
|
29
|
+
Authorization: `Bearer ${await generateAuthToken(
|
|
30
|
+
options.googleAuthOptions,
|
|
31
|
+
)}`,
|
|
32
|
+
...(await resolve(options.headers)),
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
Default Google Vertex Anthropic provider instance.
|
|
39
|
+
*/
|
|
40
|
+
export const vertexAnthropic = createVertexAnthropic();
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createVertexAnthropic,
|
|
3
|
+
vertexAnthropicTools,
|
|
4
|
+
} from './google-vertex-anthropic-provider';
|
|
5
|
+
import { NoSuchModelError } from '@ai-sdk/provider';
|
|
6
|
+
import { AnthropicMessagesLanguageModel } from '@ai-sdk/anthropic/internal';
|
|
7
|
+
import { vi, describe, beforeEach, it, expect } from 'vitest';
|
|
8
|
+
|
|
9
|
+
// Mock the imported modules
|
|
10
|
+
vi.mock('@ai-sdk/provider-utils', () => ({
|
|
11
|
+
loadOptionalSetting: vi
|
|
12
|
+
.fn()
|
|
13
|
+
.mockImplementation(({ settingValue }) => settingValue),
|
|
14
|
+
withoutTrailingSlash: vi.fn().mockImplementation(url => url),
|
|
15
|
+
createJsonErrorResponseHandler: vi.fn(),
|
|
16
|
+
createProviderToolFactory: vi.fn(),
|
|
17
|
+
createProviderToolFactoryWithOutputSchema: vi.fn(),
|
|
18
|
+
lazySchema: vi.fn(),
|
|
19
|
+
zodSchema: vi.fn(),
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
vi.mock('@ai-sdk/anthropic/internal', async () => {
|
|
23
|
+
const originalModule = await vi.importActual('@ai-sdk/anthropic/internal');
|
|
24
|
+
return {
|
|
25
|
+
...originalModule,
|
|
26
|
+
AnthropicMessagesLanguageModel: vi.fn(),
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe('google-vertex-anthropic-provider', () => {
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
vi.clearAllMocks();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should create a language model with default settings', () => {
|
|
36
|
+
const provider = createVertexAnthropic({
|
|
37
|
+
project: 'test-project',
|
|
38
|
+
location: 'test-location',
|
|
39
|
+
});
|
|
40
|
+
provider('test-model-id');
|
|
41
|
+
|
|
42
|
+
// Assert that the model constructor was called with the correct arguments
|
|
43
|
+
expect(AnthropicMessagesLanguageModel).toHaveBeenCalledWith(
|
|
44
|
+
'test-model-id',
|
|
45
|
+
expect.objectContaining({
|
|
46
|
+
baseURL: expect.stringContaining(
|
|
47
|
+
'/projects/test-project/locations/test-location/publishers/anthropic/models',
|
|
48
|
+
),
|
|
49
|
+
provider: 'vertex.anthropic.messages',
|
|
50
|
+
headers: expect.any(Object),
|
|
51
|
+
buildRequestUrl: expect.any(Function),
|
|
52
|
+
transformRequestBody: expect.any(Function),
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should throw an error when using new keyword', () => {
|
|
58
|
+
const provider = createVertexAnthropic({ project: 'test-project' });
|
|
59
|
+
|
|
60
|
+
expect(() => new (provider as any)('test-model-id')).toThrow(
|
|
61
|
+
'The Anthropic model function cannot be called with the new keyword.',
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should pass baseURL to the model when created', () => {
|
|
66
|
+
const customBaseURL = 'https://custom-url.com';
|
|
67
|
+
const provider = createVertexAnthropic({
|
|
68
|
+
project: 'test-project',
|
|
69
|
+
baseURL: customBaseURL,
|
|
70
|
+
});
|
|
71
|
+
provider('test-model-id');
|
|
72
|
+
|
|
73
|
+
// Assert that the constructor was called with the correct baseURL
|
|
74
|
+
expect(AnthropicMessagesLanguageModel).toHaveBeenCalledWith(
|
|
75
|
+
expect.anything(), // modelId
|
|
76
|
+
expect.objectContaining({
|
|
77
|
+
baseURL: customBaseURL,
|
|
78
|
+
}),
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should throw NoSuchModelError for textEmbeddingModel', () => {
|
|
83
|
+
const provider = createVertexAnthropic({ project: 'test-project' });
|
|
84
|
+
|
|
85
|
+
expect(() => provider.embeddingModel('invalid-model-id')).toThrow(
|
|
86
|
+
NoSuchModelError,
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should include vertexAnthropicTools (subset of anthropicTools)', () => {
|
|
91
|
+
const provider = createVertexAnthropic({ project: 'test-project' });
|
|
92
|
+
|
|
93
|
+
expect(provider.tools).toBe(vertexAnthropicTools);
|
|
94
|
+
expect(provider.tools).toHaveProperty('bash_20241022');
|
|
95
|
+
expect(provider.tools).toHaveProperty('bash_20250124');
|
|
96
|
+
expect(provider.tools).toHaveProperty('textEditor_20241022');
|
|
97
|
+
expect(provider.tools).toHaveProperty('textEditor_20250124');
|
|
98
|
+
expect(provider.tools).toHaveProperty('textEditor_20250429');
|
|
99
|
+
expect(provider.tools).toHaveProperty('textEditor_20250728');
|
|
100
|
+
expect(provider.tools).toHaveProperty('computer_20241022');
|
|
101
|
+
expect(provider.tools).toHaveProperty('webSearch_20250305');
|
|
102
|
+
expect(provider.tools).not.toHaveProperty('codeExecution_20250825');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should pass custom headers to the model constructor', () => {
|
|
106
|
+
const customHeaders = { 'Custom-Header': 'custom-value' };
|
|
107
|
+
const provider = createVertexAnthropic({
|
|
108
|
+
project: 'test-project',
|
|
109
|
+
headers: customHeaders,
|
|
110
|
+
});
|
|
111
|
+
provider('test-model-id');
|
|
112
|
+
|
|
113
|
+
// Assert that the model constructor was called with the correct headers
|
|
114
|
+
expect(AnthropicMessagesLanguageModel).toHaveBeenCalledWith(
|
|
115
|
+
expect.anything(), // modelId
|
|
116
|
+
expect.objectContaining({
|
|
117
|
+
headers: customHeaders,
|
|
118
|
+
}),
|
|
119
|
+
);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should create a Google Vertex Anthropic provider instance with custom settings', () => {
|
|
123
|
+
const customProvider = createVertexAnthropic({
|
|
124
|
+
project: 'custom-project',
|
|
125
|
+
location: 'custom-location',
|
|
126
|
+
baseURL: 'https://custom.base.url',
|
|
127
|
+
headers: { 'Custom-Header': 'value' },
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
expect(customProvider).toBeDefined();
|
|
131
|
+
expect(typeof customProvider).toBe('function');
|
|
132
|
+
expect(customProvider.languageModel).toBeDefined();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should not support URL sources to force base64 conversion', () => {
|
|
136
|
+
const provider = createVertexAnthropic();
|
|
137
|
+
provider('test-model-id');
|
|
138
|
+
|
|
139
|
+
// Assert that the model constructor was called with supportedUrls function
|
|
140
|
+
expect(AnthropicMessagesLanguageModel).toHaveBeenCalledWith(
|
|
141
|
+
'test-model-id',
|
|
142
|
+
expect.objectContaining({
|
|
143
|
+
supportedUrls: expect.any(Function),
|
|
144
|
+
}),
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
// Get the actual config passed to the constructor
|
|
148
|
+
const constructorCall = vi.mocked(AnthropicMessagesLanguageModel).mock
|
|
149
|
+
.calls[vi.mocked(AnthropicMessagesLanguageModel).mock.calls.length - 1];
|
|
150
|
+
const config = constructorCall[1];
|
|
151
|
+
|
|
152
|
+
// Verify that supportedUrls returns empty object to force base64 conversion
|
|
153
|
+
expect(config.supportedUrls?.()).toEqual({});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should use correct URL for global location', () => {
|
|
157
|
+
const provider = createVertexAnthropic({
|
|
158
|
+
project: 'test-project',
|
|
159
|
+
location: 'global',
|
|
160
|
+
});
|
|
161
|
+
provider('test-model-id');
|
|
162
|
+
|
|
163
|
+
expect(AnthropicMessagesLanguageModel).toHaveBeenCalledWith(
|
|
164
|
+
'test-model-id',
|
|
165
|
+
expect.objectContaining({
|
|
166
|
+
baseURL:
|
|
167
|
+
'https://aiplatform.googleapis.com/v1/projects/test-project/locations/global/publishers/anthropic/models',
|
|
168
|
+
provider: 'vertex.anthropic.messages',
|
|
169
|
+
}),
|
|
170
|
+
);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('should use region-prefixed URL for non-global locations', () => {
|
|
174
|
+
const provider = createVertexAnthropic({
|
|
175
|
+
project: 'test-project',
|
|
176
|
+
location: 'us-east5',
|
|
177
|
+
});
|
|
178
|
+
provider('test-model-id');
|
|
179
|
+
|
|
180
|
+
expect(AnthropicMessagesLanguageModel).toHaveBeenCalledWith(
|
|
181
|
+
'test-model-id',
|
|
182
|
+
expect.objectContaining({
|
|
183
|
+
baseURL:
|
|
184
|
+
'https://us-east5-aiplatform.googleapis.com/v1/projects/test-project/locations/us-east5/publishers/anthropic/models',
|
|
185
|
+
provider: 'vertex.anthropic.messages',
|
|
186
|
+
}),
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should support combining tools with structured outputs (inherited from Anthropic)', () => {
|
|
191
|
+
const provider = createVertexAnthropic({
|
|
192
|
+
project: 'test-project',
|
|
193
|
+
location: 'us-east5',
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Create a model instance
|
|
197
|
+
const model = provider('claude-3-5-sonnet-v2@20241022');
|
|
198
|
+
|
|
199
|
+
// Verify the model was created using AnthropicMessagesLanguageModel
|
|
200
|
+
// which already supports combining tools with structured outputs
|
|
201
|
+
expect(AnthropicMessagesLanguageModel).toHaveBeenCalledWith(
|
|
202
|
+
'claude-3-5-sonnet-v2@20241022',
|
|
203
|
+
expect.objectContaining({
|
|
204
|
+
provider: 'vertex.anthropic.messages',
|
|
205
|
+
}),
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
});
|