@ai-sdk/gateway 4.0.0-beta.11 → 4.0.0-beta.110
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 +756 -4
- package/dist/index.d.ts +314 -42
- package/dist/index.js +1413 -397
- package/dist/index.js.map +1 -1
- package/docs/00-ai-gateway.mdx +447 -61
- package/package.json +14 -14
- package/src/errors/as-gateway-error.ts +2 -1
- package/src/errors/create-gateway-error.ts +17 -3
- package/src/errors/gateway-authentication-error.ts +8 -5
- package/src/errors/gateway-error.ts +8 -0
- package/src/errors/gateway-failed-dependency-error.ts +35 -0
- package/src/errors/gateway-forbidden-error.ts +34 -0
- package/src/errors/gateway-response-error.ts +1 -1
- package/src/errors/index.ts +2 -0
- package/src/errors/parse-auth-method.ts +1 -2
- package/src/gateway-config.ts +1 -1
- package/src/gateway-embedding-model-settings.ts +1 -0
- package/src/gateway-embedding-model.ts +62 -15
- package/src/gateway-fetch-metadata.ts +51 -38
- package/src/gateway-generation-info.ts +149 -0
- package/src/gateway-headers.ts +3 -0
- package/src/gateway-image-model-settings.ts +8 -1
- package/src/gateway-image-model.ts +46 -21
- package/src/gateway-language-model-settings.ts +45 -26
- package/src/gateway-language-model.ts +72 -42
- package/src/gateway-model-entry.ts +15 -3
- package/src/gateway-provider-options.ts +50 -78
- package/src/gateway-provider.ts +296 -35
- package/src/gateway-realtime-auth.ts +126 -0
- package/src/gateway-realtime-model-settings.ts +1 -0
- package/src/gateway-realtime-model.ts +118 -0
- package/src/gateway-reranking-model-settings.ts +7 -0
- package/src/gateway-reranking-model.ts +142 -0
- package/src/gateway-speech-model-settings.ts +1 -0
- package/src/gateway-speech-model.ts +145 -0
- package/src/gateway-spend-report.ts +193 -0
- package/src/gateway-transcription-model-settings.ts +1 -0
- package/src/gateway-transcription-model.ts +155 -0
- package/src/gateway-video-model-settings.ts +4 -0
- package/src/gateway-video-model.ts +29 -19
- package/src/index.ts +30 -5
- package/src/tool/parallel-search.ts +10 -11
- package/src/tool/perplexity-search.ts +10 -11
- package/dist/index.d.mts +0 -602
- package/dist/index.mjs +0 -1539
- package/dist/index.mjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/gateway",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "4.0.0-beta.
|
|
4
|
+
"version": "4.0.0-beta.110",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"license": "Apache-2.0",
|
|
6
7
|
"sideEffects": false,
|
|
7
8
|
"main": "./dist/index.js",
|
|
8
|
-
"module": "./dist/index.mjs",
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
10
|
"files": [
|
|
11
11
|
"dist/**/*",
|
|
@@ -25,37 +25,39 @@
|
|
|
25
25
|
"./package.json": "./package.json",
|
|
26
26
|
".": {
|
|
27
27
|
"types": "./dist/index.d.ts",
|
|
28
|
-
"import": "./dist/index.
|
|
29
|
-
"
|
|
28
|
+
"import": "./dist/index.js",
|
|
29
|
+
"default": "./dist/index.js"
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@vercel/oidc": "3.2.0",
|
|
34
|
-
"@ai-sdk/provider": "4.0.0-beta.
|
|
35
|
-
"@ai-sdk/provider-utils": "5.0.0-beta.
|
|
34
|
+
"@ai-sdk/provider": "4.0.0-beta.19",
|
|
35
|
+
"@ai-sdk/provider-utils": "5.0.0-beta.49"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@types/node": "
|
|
39
|
-
"tsup": "^8",
|
|
38
|
+
"@types/node": "22.19.19",
|
|
39
|
+
"tsup": "^8.5.1",
|
|
40
40
|
"tsx": "4.19.2",
|
|
41
41
|
"typescript": "5.8.3",
|
|
42
42
|
"zod": "3.25.76",
|
|
43
|
-
"@ai-sdk/test-server": "2.0.0-beta.
|
|
43
|
+
"@ai-sdk/test-server": "2.0.0-beta.7",
|
|
44
44
|
"@vercel/ai-tsconfig": "0.0.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"zod": "^3.25.76 || ^4.1.8"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|
|
50
|
-
"node": ">=
|
|
50
|
+
"node": ">=22"
|
|
51
51
|
},
|
|
52
52
|
"publishConfig": {
|
|
53
|
-
"access": "public"
|
|
53
|
+
"access": "public",
|
|
54
|
+
"provenance": true
|
|
54
55
|
},
|
|
55
56
|
"homepage": "https://ai-sdk.dev/docs",
|
|
56
57
|
"repository": {
|
|
57
58
|
"type": "git",
|
|
58
|
-
"url": "
|
|
59
|
+
"url": "https://github.com/vercel/ai",
|
|
60
|
+
"directory": "packages/gateway"
|
|
59
61
|
},
|
|
60
62
|
"bugs": {
|
|
61
63
|
"url": "https://github.com/vercel/ai/issues"
|
|
@@ -68,9 +70,7 @@
|
|
|
68
70
|
"build:watch": "pnpm clean && tsup --watch",
|
|
69
71
|
"clean": "del-cli dist docs *.tsbuildinfo",
|
|
70
72
|
"generate-model-settings": "tsx scripts/generate-model-settings.ts",
|
|
71
|
-
"lint": "eslint \"./**/*.ts*\"",
|
|
72
73
|
"type-check": "tsc --build",
|
|
73
|
-
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
74
74
|
"test": "pnpm test:node && pnpm test:edge",
|
|
75
75
|
"test:update": "pnpm test:node -u",
|
|
76
76
|
"test:watch": "vitest --config vitest.node.config.js",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { APICallError } from '@ai-sdk/provider';
|
|
2
|
-
import { extractApiCallResponse, GatewayError } from '.';
|
|
3
2
|
import { createGatewayErrorFromResponse } from './create-gateway-error';
|
|
3
|
+
import { extractApiCallResponse } from './extract-api-call-response';
|
|
4
|
+
import { GatewayError } from './gateway-error';
|
|
4
5
|
import { GatewayTimeoutError } from './gateway-timeout-error';
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -8,15 +8,15 @@ import {
|
|
|
8
8
|
modelNotFoundParamSchema,
|
|
9
9
|
} from './gateway-model-not-found-error';
|
|
10
10
|
import { GatewayInternalServerError } from './gateway-internal-server-error';
|
|
11
|
+
import { GatewayFailedDependencyError } from './gateway-failed-dependency-error';
|
|
12
|
+
import { GatewayForbiddenError } from './gateway-forbidden-error';
|
|
11
13
|
import { GatewayResponseError } from './gateway-response-error';
|
|
12
14
|
import {
|
|
13
|
-
InferSchema,
|
|
14
15
|
lazySchema,
|
|
15
16
|
safeValidateTypes,
|
|
16
|
-
validateTypes,
|
|
17
17
|
zodSchema,
|
|
18
|
+
type InferSchema,
|
|
18
19
|
} from '@ai-sdk/provider-utils';
|
|
19
|
-
|
|
20
20
|
export async function createGatewayErrorFromResponse({
|
|
21
21
|
response,
|
|
22
22
|
statusCode,
|
|
@@ -103,6 +103,20 @@ export async function createGatewayErrorFromResponse({
|
|
|
103
103
|
cause,
|
|
104
104
|
generationId,
|
|
105
105
|
});
|
|
106
|
+
case 'failed_dependency':
|
|
107
|
+
return new GatewayFailedDependencyError({
|
|
108
|
+
message,
|
|
109
|
+
statusCode,
|
|
110
|
+
cause,
|
|
111
|
+
generationId,
|
|
112
|
+
});
|
|
113
|
+
case 'forbidden':
|
|
114
|
+
return new GatewayForbiddenError({
|
|
115
|
+
message,
|
|
116
|
+
statusCode,
|
|
117
|
+
cause,
|
|
118
|
+
generationId,
|
|
119
|
+
});
|
|
106
120
|
default:
|
|
107
121
|
return new GatewayInternalServerError({
|
|
108
122
|
message,
|
|
@@ -37,7 +37,6 @@ export class GatewayAuthenticationError extends GatewayError {
|
|
|
37
37
|
static createContextualError({
|
|
38
38
|
apiKeyProvided,
|
|
39
39
|
oidcTokenProvided,
|
|
40
|
-
message = 'Authentication failed',
|
|
41
40
|
statusCode = 401,
|
|
42
41
|
cause,
|
|
43
42
|
generationId,
|
|
@@ -52,17 +51,18 @@ export class GatewayAuthenticationError extends GatewayError {
|
|
|
52
51
|
let contextualMessage: string;
|
|
53
52
|
|
|
54
53
|
if (apiKeyProvided) {
|
|
55
|
-
contextualMessage = `AI Gateway authentication failed: Invalid API key.
|
|
54
|
+
contextualMessage = `AI Gateway authentication failed: Invalid API key or token.
|
|
56
55
|
|
|
57
56
|
Create a new API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys
|
|
58
57
|
|
|
59
|
-
Provide via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable.`;
|
|
58
|
+
Provide an API key or Vercel access token via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable.`;
|
|
60
59
|
} else if (oidcTokenProvided) {
|
|
61
60
|
contextualMessage = `AI Gateway authentication failed: Invalid OIDC token.
|
|
62
61
|
|
|
63
62
|
Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the token.
|
|
64
63
|
|
|
65
|
-
Alternatively, use an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys
|
|
64
|
+
Alternatively, use an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys
|
|
65
|
+
or pass a Vercel access token via the 'apiKey' option.`;
|
|
66
66
|
} else {
|
|
67
67
|
contextualMessage = `AI Gateway authentication failed: No authentication provided.
|
|
68
68
|
|
|
@@ -70,7 +70,10 @@ Option 1 - API key:
|
|
|
70
70
|
Create an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys
|
|
71
71
|
Provide via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable.
|
|
72
72
|
|
|
73
|
-
Option 2 -
|
|
73
|
+
Option 2 - Vercel access token:
|
|
74
|
+
Pass a Vercel personal access token or Vercel app access token via the 'apiKey' option.
|
|
75
|
+
|
|
76
|
+
Option 3 - OIDC token:
|
|
74
77
|
Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the token.`;
|
|
75
78
|
}
|
|
76
79
|
|
|
@@ -9,22 +9,30 @@ export abstract class GatewayError extends Error {
|
|
|
9
9
|
readonly statusCode: number;
|
|
10
10
|
readonly cause?: unknown;
|
|
11
11
|
readonly generationId?: string;
|
|
12
|
+
readonly isRetryable: boolean;
|
|
12
13
|
|
|
13
14
|
constructor({
|
|
14
15
|
message,
|
|
15
16
|
statusCode = 500,
|
|
16
17
|
cause,
|
|
17
18
|
generationId,
|
|
19
|
+
isRetryable = statusCode != null &&
|
|
20
|
+
(statusCode === 408 || // request timeout
|
|
21
|
+
statusCode === 409 || // conflict
|
|
22
|
+
statusCode === 429 || // too many requests
|
|
23
|
+
statusCode >= 500), // server error
|
|
18
24
|
}: {
|
|
19
25
|
message: string;
|
|
20
26
|
statusCode?: number;
|
|
21
27
|
cause?: unknown;
|
|
22
28
|
generationId?: string;
|
|
29
|
+
isRetryable?: boolean;
|
|
23
30
|
}) {
|
|
24
31
|
super(generationId ? `${message} [${generationId}]` : message);
|
|
25
32
|
this.statusCode = statusCode;
|
|
26
33
|
this.cause = cause;
|
|
27
34
|
this.generationId = generationId;
|
|
35
|
+
this.isRetryable = isRetryable;
|
|
28
36
|
}
|
|
29
37
|
|
|
30
38
|
/**
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { GatewayError } from './gateway-error';
|
|
2
|
+
|
|
3
|
+
const name = 'GatewayFailedDependencyError';
|
|
4
|
+
const marker = `vercel.ai.gateway.error.${name}`;
|
|
5
|
+
const symbol = Symbol.for(marker);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The request could not be fulfilled because a dependency it relied on was not
|
|
9
|
+
* available on the credentials or provider used to serve it (HTTP 424). Not
|
|
10
|
+
* retryable — the caller must change the request.
|
|
11
|
+
*/
|
|
12
|
+
export class GatewayFailedDependencyError extends GatewayError {
|
|
13
|
+
private readonly [symbol] = true; // used in isInstance
|
|
14
|
+
|
|
15
|
+
readonly name = name;
|
|
16
|
+
readonly type = 'failed_dependency';
|
|
17
|
+
|
|
18
|
+
constructor({
|
|
19
|
+
message = 'Failed dependency',
|
|
20
|
+
statusCode = 424,
|
|
21
|
+
cause,
|
|
22
|
+
generationId,
|
|
23
|
+
}: {
|
|
24
|
+
message?: string;
|
|
25
|
+
statusCode?: number;
|
|
26
|
+
cause?: unknown;
|
|
27
|
+
generationId?: string;
|
|
28
|
+
} = {}) {
|
|
29
|
+
super({ message, statusCode, cause, generationId });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static isInstance(error: unknown): error is GatewayFailedDependencyError {
|
|
33
|
+
return GatewayError.hasMarker(error) && symbol in error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { GatewayError } from './gateway-error';
|
|
2
|
+
|
|
3
|
+
const name = 'GatewayForbiddenError';
|
|
4
|
+
const marker = `vercel.ai.gateway.error.${name}`;
|
|
5
|
+
const symbol = Symbol.for(marker);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Forbidden - the request was rejected by policy (e.g. a routing rule),
|
|
9
|
+
* not an authentication failure.
|
|
10
|
+
*/
|
|
11
|
+
export class GatewayForbiddenError extends GatewayError {
|
|
12
|
+
private readonly [symbol] = true; // used in isInstance
|
|
13
|
+
|
|
14
|
+
readonly name = name;
|
|
15
|
+
readonly type = 'forbidden';
|
|
16
|
+
|
|
17
|
+
constructor({
|
|
18
|
+
message = 'Forbidden',
|
|
19
|
+
statusCode = 403,
|
|
20
|
+
cause,
|
|
21
|
+
generationId,
|
|
22
|
+
}: {
|
|
23
|
+
message?: string;
|
|
24
|
+
statusCode?: number;
|
|
25
|
+
cause?: unknown;
|
|
26
|
+
generationId?: string;
|
|
27
|
+
} = {}) {
|
|
28
|
+
super({ message, statusCode, cause, generationId });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static isInstance(error: unknown): error is GatewayForbiddenError {
|
|
32
|
+
return GatewayError.hasMarker(error) && symbol in error;
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/errors/index.ts
CHANGED
|
@@ -6,6 +6,8 @@ export {
|
|
|
6
6
|
export { extractApiCallResponse } from './extract-api-call-response';
|
|
7
7
|
export { GatewayError } from './gateway-error';
|
|
8
8
|
export { GatewayAuthenticationError } from './gateway-authentication-error';
|
|
9
|
+
export { GatewayFailedDependencyError } from './gateway-failed-dependency-error';
|
|
10
|
+
export { GatewayForbiddenError } from './gateway-forbidden-error';
|
|
9
11
|
export { GatewayInternalServerError } from './gateway-internal-server-error';
|
|
10
12
|
export { GatewayInvalidRequestError } from './gateway-invalid-request-error';
|
|
11
13
|
export {
|
|
@@ -4,8 +4,7 @@ import {
|
|
|
4
4
|
safeValidateTypes,
|
|
5
5
|
zodSchema,
|
|
6
6
|
} from '@ai-sdk/provider-utils';
|
|
7
|
-
|
|
8
|
-
export const GATEWAY_AUTH_METHOD_HEADER = 'ai-gateway-auth-method' as const;
|
|
7
|
+
import { GATEWAY_AUTH_METHOD_HEADER } from '../gateway-headers';
|
|
9
8
|
|
|
10
9
|
export async function parseAuthMethod(
|
|
11
10
|
headers: Record<string, string | undefined>,
|
package/src/gateway-config.ts
CHANGED
|
@@ -2,6 +2,6 @@ import type { FetchFunction, Resolvable } from '@ai-sdk/provider-utils';
|
|
|
2
2
|
|
|
3
3
|
export type GatewayConfig = {
|
|
4
4
|
baseURL: string;
|
|
5
|
-
headers
|
|
5
|
+
headers?: Resolvable<Record<string, string | undefined>>;
|
|
6
6
|
fetch?: FetchFunction;
|
|
7
7
|
};
|
|
@@ -5,6 +5,7 @@ export type GatewayEmbeddingModelId =
|
|
|
5
5
|
| 'amazon/titan-embed-text-v2'
|
|
6
6
|
| 'cohere/embed-v4.0'
|
|
7
7
|
| 'google/gemini-embedding-001'
|
|
8
|
+
| 'google/gemini-embedding-2'
|
|
8
9
|
| 'google/text-embedding-005'
|
|
9
10
|
| 'google/text-multilingual-embedding-002'
|
|
10
11
|
| 'mistral/codestral-embed'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
EmbeddingModelV4,
|
|
3
|
+
SharedV4ProviderMetadata,
|
|
4
4
|
} from '@ai-sdk/provider';
|
|
5
5
|
import {
|
|
6
6
|
combineHeaders,
|
|
@@ -9,6 +9,9 @@ import {
|
|
|
9
9
|
lazySchema,
|
|
10
10
|
postJsonToApi,
|
|
11
11
|
resolve,
|
|
12
|
+
serializeModelOptions,
|
|
13
|
+
WORKFLOW_SERIALIZE,
|
|
14
|
+
WORKFLOW_DESERIALIZE,
|
|
12
15
|
zodSchema,
|
|
13
16
|
type Resolvable,
|
|
14
17
|
} from '@ai-sdk/provider-utils';
|
|
@@ -17,17 +20,33 @@ import { asGatewayError } from './errors';
|
|
|
17
20
|
import { parseAuthMethod } from './errors/parse-auth-method';
|
|
18
21
|
import type { GatewayConfig } from './gateway-config';
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
type GatewayEmbeddingConfig = GatewayConfig & {
|
|
24
|
+
provider: string;
|
|
25
|
+
o11yHeaders: Resolvable<Record<string, string>>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export class GatewayEmbeddingModel implements EmbeddingModelV4 {
|
|
29
|
+
readonly specificationVersion = 'v4';
|
|
22
30
|
readonly maxEmbeddingsPerCall = 2048;
|
|
23
31
|
readonly supportsParallelCalls = true;
|
|
24
32
|
|
|
33
|
+
static [WORKFLOW_SERIALIZE](model: GatewayEmbeddingModel) {
|
|
34
|
+
return serializeModelOptions({
|
|
35
|
+
modelId: model.modelId,
|
|
36
|
+
config: model.config,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
41
|
+
modelId: string;
|
|
42
|
+
config: GatewayEmbeddingConfig;
|
|
43
|
+
}) {
|
|
44
|
+
return new GatewayEmbeddingModel(options.modelId, options.config);
|
|
45
|
+
}
|
|
46
|
+
|
|
25
47
|
constructor(
|
|
26
48
|
readonly modelId: string,
|
|
27
|
-
private readonly config:
|
|
28
|
-
provider: string;
|
|
29
|
-
o11yHeaders: Resolvable<Record<string, string>>;
|
|
30
|
-
},
|
|
49
|
+
private readonly config: GatewayEmbeddingConfig,
|
|
31
50
|
) {}
|
|
32
51
|
|
|
33
52
|
get provider(): string {
|
|
@@ -39,10 +58,12 @@ export class GatewayEmbeddingModel implements EmbeddingModelV3 {
|
|
|
39
58
|
headers,
|
|
40
59
|
abortSignal,
|
|
41
60
|
providerOptions,
|
|
42
|
-
}: Parameters<
|
|
43
|
-
Awaited<ReturnType<
|
|
61
|
+
}: Parameters<EmbeddingModelV4['doEmbed']>[0]): Promise<
|
|
62
|
+
Awaited<ReturnType<EmbeddingModelV4['doEmbed']>>
|
|
44
63
|
> {
|
|
45
|
-
const resolvedHeaders =
|
|
64
|
+
const resolvedHeaders = this.config.headers
|
|
65
|
+
? await resolve(this.config.headers)
|
|
66
|
+
: undefined;
|
|
46
67
|
try {
|
|
47
68
|
const {
|
|
48
69
|
responseHeaders,
|
|
@@ -75,12 +96,15 @@ export class GatewayEmbeddingModel implements EmbeddingModelV3 {
|
|
|
75
96
|
embeddings: responseBody.embeddings,
|
|
76
97
|
usage: responseBody.usage ?? undefined,
|
|
77
98
|
providerMetadata:
|
|
78
|
-
responseBody.providerMetadata as unknown as
|
|
99
|
+
responseBody.providerMetadata as unknown as SharedV4ProviderMetadata,
|
|
79
100
|
response: { headers: responseHeaders, body: rawValue },
|
|
80
|
-
warnings: [],
|
|
101
|
+
warnings: responseBody.warnings ?? [],
|
|
81
102
|
};
|
|
82
103
|
} catch (error) {
|
|
83
|
-
throw await asGatewayError(
|
|
104
|
+
throw await asGatewayError(
|
|
105
|
+
error,
|
|
106
|
+
await parseAuthMethod(resolvedHeaders ?? {}),
|
|
107
|
+
);
|
|
84
108
|
}
|
|
85
109
|
}
|
|
86
110
|
|
|
@@ -90,17 +114,40 @@ export class GatewayEmbeddingModel implements EmbeddingModelV3 {
|
|
|
90
114
|
|
|
91
115
|
private getModelConfigHeaders() {
|
|
92
116
|
return {
|
|
93
|
-
'ai-embedding-model-specification-version': '
|
|
117
|
+
'ai-embedding-model-specification-version': '4',
|
|
94
118
|
'ai-model-id': this.modelId,
|
|
95
119
|
};
|
|
96
120
|
}
|
|
97
121
|
}
|
|
98
122
|
|
|
123
|
+
const gatewayEmbeddingWarningSchema = z.discriminatedUnion('type', [
|
|
124
|
+
z.object({
|
|
125
|
+
type: z.literal('unsupported'),
|
|
126
|
+
feature: z.string(),
|
|
127
|
+
details: z.string().optional(),
|
|
128
|
+
}),
|
|
129
|
+
z.object({
|
|
130
|
+
type: z.literal('compatibility'),
|
|
131
|
+
feature: z.string(),
|
|
132
|
+
details: z.string().optional(),
|
|
133
|
+
}),
|
|
134
|
+
z.object({
|
|
135
|
+
type: z.literal('deprecated'),
|
|
136
|
+
setting: z.string(),
|
|
137
|
+
message: z.string(),
|
|
138
|
+
}),
|
|
139
|
+
z.object({
|
|
140
|
+
type: z.literal('other'),
|
|
141
|
+
message: z.string(),
|
|
142
|
+
}),
|
|
143
|
+
]);
|
|
144
|
+
|
|
99
145
|
const gatewayEmbeddingResponseSchema = lazySchema(() =>
|
|
100
146
|
zodSchema(
|
|
101
147
|
z.object({
|
|
102
148
|
embeddings: z.array(z.array(z.number())),
|
|
103
149
|
usage: z.object({ tokens: z.number() }).nullish(),
|
|
150
|
+
warnings: z.array(gatewayEmbeddingWarningSchema).optional(),
|
|
104
151
|
providerMetadata: z
|
|
105
152
|
.record(z.string(), z.record(z.string(), z.unknown()))
|
|
106
153
|
.optional(),
|
|
@@ -9,8 +9,11 @@ import {
|
|
|
9
9
|
import { z } from 'zod/v4';
|
|
10
10
|
import { asGatewayError } from './errors';
|
|
11
11
|
import type { GatewayConfig } from './gateway-config';
|
|
12
|
-
import
|
|
13
|
-
|
|
12
|
+
import {
|
|
13
|
+
KNOWN_MODEL_TYPES,
|
|
14
|
+
type GatewayLanguageModelEntry,
|
|
15
|
+
type KnownModelType,
|
|
16
|
+
} from './gateway-model-entry';
|
|
14
17
|
type GatewayFetchMetadataConfig = GatewayConfig;
|
|
15
18
|
|
|
16
19
|
export interface GatewayFetchMetadataResponse {
|
|
@@ -31,7 +34,9 @@ export class GatewayFetchMetadata {
|
|
|
31
34
|
try {
|
|
32
35
|
const { value } = await getFromApi({
|
|
33
36
|
url: `${this.config.baseURL}/config`,
|
|
34
|
-
headers:
|
|
37
|
+
headers: this.config.headers
|
|
38
|
+
? await resolve(this.config.headers)
|
|
39
|
+
: undefined,
|
|
35
40
|
successfulResponseHandler: createJsonResponseHandler(
|
|
36
41
|
gatewayAvailableModelsResponseSchema,
|
|
37
42
|
),
|
|
@@ -54,7 +59,9 @@ export class GatewayFetchMetadata {
|
|
|
54
59
|
|
|
55
60
|
const { value } = await getFromApi({
|
|
56
61
|
url: `${baseUrl.origin}/v1/credits`,
|
|
57
|
-
headers:
|
|
62
|
+
headers: this.config.headers
|
|
63
|
+
? await resolve(this.config.headers)
|
|
64
|
+
: undefined,
|
|
58
65
|
successfulResponseHandler: createJsonResponseHandler(
|
|
59
66
|
gatewayCreditsResponseSchema,
|
|
60
67
|
),
|
|
@@ -75,41 +82,47 @@ export class GatewayFetchMetadata {
|
|
|
75
82
|
const gatewayAvailableModelsResponseSchema = lazySchema(() =>
|
|
76
83
|
zodSchema(
|
|
77
84
|
z.object({
|
|
78
|
-
models: z
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
(
|
|
92
|
-
input,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
85
|
+
models: z
|
|
86
|
+
.array(
|
|
87
|
+
z.object({
|
|
88
|
+
id: z.string(),
|
|
89
|
+
name: z.string(),
|
|
90
|
+
description: z.string().nullish(),
|
|
91
|
+
pricing: z
|
|
92
|
+
.object({
|
|
93
|
+
input: z.string(),
|
|
94
|
+
output: z.string(),
|
|
95
|
+
input_cache_read: z.string().nullish(),
|
|
96
|
+
input_cache_write: z.string().nullish(),
|
|
97
|
+
})
|
|
98
|
+
.transform(
|
|
99
|
+
({ input, output, input_cache_read, input_cache_write }) => ({
|
|
100
|
+
input,
|
|
101
|
+
output,
|
|
102
|
+
...(input_cache_read
|
|
103
|
+
? { cachedInputTokens: input_cache_read }
|
|
104
|
+
: {}),
|
|
105
|
+
...(input_cache_write
|
|
106
|
+
? { cacheCreationInputTokens: input_cache_write }
|
|
107
|
+
: {}),
|
|
108
|
+
}),
|
|
109
|
+
)
|
|
110
|
+
.nullish(),
|
|
111
|
+
specification: z.object({
|
|
112
|
+
specificationVersion: z.literal('v4'),
|
|
113
|
+
provider: z.string(),
|
|
114
|
+
modelId: z.string(),
|
|
115
|
+
}),
|
|
116
|
+
modelType: z.string().nullish(),
|
|
107
117
|
}),
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
118
|
+
)
|
|
119
|
+
.transform(models =>
|
|
120
|
+
models.filter(
|
|
121
|
+
(m): m is typeof m & { modelType?: KnownModelType | null } =>
|
|
122
|
+
m.modelType == null ||
|
|
123
|
+
KNOWN_MODEL_TYPES.includes(m.modelType as KnownModelType),
|
|
124
|
+
),
|
|
125
|
+
),
|
|
113
126
|
}),
|
|
114
127
|
),
|
|
115
128
|
);
|