@ai-sdk/gateway 4.0.0-beta.49 → 4.0.0-beta.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -159,6 +159,8 @@ You can connect your own provider credentials to use with Vercel AI Gateway. Thi
159
159
 
160
160
  To set up BYOK, add your provider credentials in your Vercel team's AI Gateway settings. Once configured, AI Gateway automatically uses your credentials. No code changes are needed.
161
161
 
162
+ For providers like Azure where you can use custom deployment names, you can configure model mappings to map gateway model slugs to your deployment names. See [model mappings](https://vercel.com/docs/ai-gateway/byok#model-mappings) for details.
163
+
162
164
  Learn more in the [BYOK documentation](https://vercel.com/docs/ai-gateway/byok).
163
165
 
164
166
  ## Language Models
@@ -816,11 +818,14 @@ The following gateway provider options are available:
816
818
 
817
819
  Each provider can have multiple credentials (tried in order). The structure is a record where keys are provider slugs and values are arrays of credential objects.
818
820
 
821
+ Each credential can optionally include a `modelMappings` array to map AI Gateway model slugs to your deployment names (for example, custom Azure deployment names). If a BYOK request fails, the gateway falls back to system credentials using the default model name.
822
+
819
823
  Examples:
820
824
 
821
825
  - Single provider: `byok: { 'anthropic': [{ apiKey: 'sk-ant-...' }] }`
822
826
  - Multiple credentials: `byok: { 'vertex': [{ project: 'proj-1', googleCredentials: { privateKey: '...', clientEmail: '...' } }, { project: 'proj-2', googleCredentials: { privateKey: '...', clientEmail: '...' } }] }`
823
827
  - Multiple providers: `byok: { 'anthropic': [{ apiKey: '...' }], 'bedrock': [{ accessKeyId: '...', secretAccessKey: '...' }] }`
828
+ - With model mappings: `byok: { 'azure': [{ apiKey: '...', resourceName: '...', modelMappings: [{ gatewayModelSlug: 'openai/gpt-5.4-nano', customModelId: 'my-deployment' }] }] }`
824
829
 
825
830
  - **zeroDataRetention** _boolean_
826
831
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ai-sdk/gateway",
3
3
  "private": false,
4
- "version": "4.0.0-beta.49",
4
+ "version": "4.0.0-beta.50",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "sideEffects": false,
@@ -31,8 +31,8 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@vercel/oidc": "3.2.0",
34
- "@ai-sdk/provider": "4.0.0-beta.11",
35
- "@ai-sdk/provider-utils": "5.0.0-beta.19"
34
+ "@ai-sdk/provider": "4.0.0-beta.12",
35
+ "@ai-sdk/provider-utils": "5.0.0-beta.20"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "18.15.11",
@@ -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: () => Resolvable<Record<string, string | undefined>>;
5
+ headers?: Resolvable<Record<string, string | undefined>>;
6
6
  fetch?: FetchFunction;
7
7
  };
@@ -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
 
23
+ type GatewayEmbeddingConfig = GatewayConfig & {
24
+ provider: string;
25
+ o11yHeaders: Resolvable<Record<string, string>>;
26
+ };
27
+
20
28
  export class GatewayEmbeddingModel implements EmbeddingModelV4 {
21
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: GatewayConfig & {
28
- provider: string;
29
- o11yHeaders: Resolvable<Record<string, string>>;
30
- },
49
+ private readonly config: GatewayEmbeddingConfig,
31
50
  ) {}
32
51
 
33
52
  get provider(): string {
@@ -42,7 +61,9 @@ export class GatewayEmbeddingModel implements EmbeddingModelV4 {
42
61
  }: Parameters<EmbeddingModelV4['doEmbed']>[0]): Promise<
43
62
  Awaited<ReturnType<EmbeddingModelV4['doEmbed']>>
44
63
  > {
45
- const resolvedHeaders = await resolve(this.config.headers());
64
+ const resolvedHeaders = this.config.headers
65
+ ? await resolve(this.config.headers)
66
+ : undefined;
46
67
  try {
47
68
  const {
48
69
  responseHeaders,
@@ -80,7 +101,10 @@ export class GatewayEmbeddingModel implements EmbeddingModelV4 {
80
101
  warnings: [],
81
102
  };
82
103
  } catch (error) {
83
- throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders));
104
+ throw await asGatewayError(
105
+ error,
106
+ await parseAuthMethod(resolvedHeaders ?? {}),
107
+ );
84
108
  }
85
109
  }
86
110
 
@@ -31,7 +31,9 @@ export class GatewayFetchMetadata {
31
31
  try {
32
32
  const { value } = await getFromApi({
33
33
  url: `${this.config.baseURL}/config`,
34
- headers: await resolve(this.config.headers()),
34
+ headers: this.config.headers
35
+ ? await resolve(this.config.headers)
36
+ : undefined,
35
37
  successfulResponseHandler: createJsonResponseHandler(
36
38
  gatewayAvailableModelsResponseSchema,
37
39
  ),
@@ -54,7 +56,9 @@ export class GatewayFetchMetadata {
54
56
 
55
57
  const { value } = await getFromApi({
56
58
  url: `${baseUrl.origin}/v1/credits`,
57
- headers: await resolve(this.config.headers()),
59
+ headers: this.config.headers
60
+ ? await resolve(this.config.headers)
61
+ : undefined,
58
62
  successfulResponseHandler: createJsonResponseHandler(
59
63
  gatewayCreditsResponseSchema,
60
64
  ),
@@ -65,7 +65,9 @@ export class GatewayGenerationInfoFetcher {
65
65
 
66
66
  const { value } = await getFromApi({
67
67
  url: `${baseUrl.origin}/v1/generation?id=${encodeURIComponent(params.id)}`,
68
- headers: await resolve(this.config.headers()),
68
+ headers: this.config.headers
69
+ ? await resolve(this.config.headers)
70
+ : undefined,
69
71
  successfulResponseHandler: createJsonResponseHandler(
70
72
  gatewayGenerationInfoResponseSchema,
71
73
  ),
@@ -10,6 +10,9 @@ import {
10
10
  createJsonErrorResponseHandler,
11
11
  postJsonToApi,
12
12
  resolve,
13
+ serializeModelOptions,
14
+ WORKFLOW_SERIALIZE,
15
+ WORKFLOW_DESERIALIZE,
13
16
  type Resolvable,
14
17
  } from '@ai-sdk/provider-utils';
15
18
  import { z } from 'zod/v4';
@@ -17,17 +20,33 @@ import type { GatewayConfig } from './gateway-config';
17
20
  import { asGatewayError } from './errors';
18
21
  import { parseAuthMethod } from './errors/parse-auth-method';
19
22
 
23
+ type GatewayImageConfig = GatewayConfig & {
24
+ provider: string;
25
+ o11yHeaders: Resolvable<Record<string, string>>;
26
+ };
27
+
20
28
  export class GatewayImageModel implements ImageModelV4 {
21
29
  readonly specificationVersion = 'v4' as const;
22
30
  // Set a very large number to prevent client-side splitting of requests
23
31
  readonly maxImagesPerCall = Number.MAX_SAFE_INTEGER;
24
32
 
33
+ static [WORKFLOW_SERIALIZE](model: GatewayImageModel) {
34
+ return serializeModelOptions({
35
+ modelId: model.modelId,
36
+ config: model.config,
37
+ });
38
+ }
39
+
40
+ static [WORKFLOW_DESERIALIZE](options: {
41
+ modelId: string;
42
+ config: GatewayImageConfig;
43
+ }) {
44
+ return new GatewayImageModel(options.modelId, options.config);
45
+ }
46
+
25
47
  constructor(
26
48
  readonly modelId: string,
27
- private readonly config: GatewayConfig & {
28
- provider: string;
29
- o11yHeaders: Resolvable<Record<string, string>>;
30
- },
49
+ private readonly config: GatewayImageConfig,
31
50
  ) {}
32
51
 
33
52
  get provider(): string {
@@ -48,7 +67,9 @@ export class GatewayImageModel implements ImageModelV4 {
48
67
  }: Parameters<ImageModelV4['doGenerate']>[0]): Promise<
49
68
  Awaited<ReturnType<ImageModelV4['doGenerate']>>
50
69
  > {
51
- const resolvedHeaders = await resolve(this.config.headers());
70
+ const resolvedHeaders = this.config.headers
71
+ ? await resolve(this.config.headers)
72
+ : undefined;
52
73
  try {
53
74
  const { responseHeaders, value: responseBody } = await postJsonToApi({
54
75
  url: this.getUrl(),
@@ -100,7 +121,10 @@ export class GatewayImageModel implements ImageModelV4 {
100
121
  }),
101
122
  };
102
123
  } catch (error) {
103
- throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders));
124
+ throw await asGatewayError(
125
+ error,
126
+ await parseAuthMethod(resolvedHeaders ?? {}),
127
+ );
104
128
  }
105
129
  }
106
130
 
@@ -13,6 +13,9 @@ import {
13
13
  createJsonResponseHandler,
14
14
  postJsonToApi,
15
15
  resolve,
16
+ serializeModelOptions,
17
+ WORKFLOW_SERIALIZE,
18
+ WORKFLOW_DESERIALIZE,
16
19
  type ParseResult,
17
20
  type Resolvable,
18
21
  } from '@ai-sdk/provider-utils';
@@ -31,6 +34,20 @@ export class GatewayLanguageModel implements LanguageModelV4 {
31
34
  readonly specificationVersion = 'v4';
32
35
  readonly supportedUrls = { '*/*': [/.*/] };
33
36
 
37
+ static [WORKFLOW_SERIALIZE](model: GatewayLanguageModel) {
38
+ return serializeModelOptions({
39
+ modelId: model.modelId,
40
+ config: model.config,
41
+ });
42
+ }
43
+
44
+ static [WORKFLOW_DESERIALIZE](options: {
45
+ modelId: GatewayModelId;
46
+ config: GatewayChatConfig;
47
+ }) {
48
+ return new GatewayLanguageModel(options.modelId, options.config);
49
+ }
50
+
34
51
  constructor(
35
52
  readonly modelId: GatewayModelId,
36
53
  private readonly config: GatewayChatConfig,
@@ -55,7 +72,9 @@ export class GatewayLanguageModel implements LanguageModelV4 {
55
72
  const { args, warnings } = await this.getArgs(options);
56
73
  const { abortSignal } = options;
57
74
 
58
- const resolvedHeaders = await resolve(this.config.headers());
75
+ const resolvedHeaders = this.config.headers
76
+ ? await resolve(this.config.headers)
77
+ : undefined;
59
78
 
60
79
  try {
61
80
  const {
@@ -87,7 +106,10 @@ export class GatewayLanguageModel implements LanguageModelV4 {
87
106
  warnings,
88
107
  };
89
108
  } catch (error) {
90
- throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders));
109
+ throw await asGatewayError(
110
+ error,
111
+ await parseAuthMethod(resolvedHeaders ?? {}),
112
+ );
91
113
  }
92
114
  }
93
115
 
@@ -97,7 +119,9 @@ export class GatewayLanguageModel implements LanguageModelV4 {
97
119
  const { args, warnings } = await this.getArgs(options);
98
120
  const { abortSignal } = options;
99
121
 
100
- const resolvedHeaders = await resolve(this.config.headers());
122
+ const resolvedHeaders = this.config.headers
123
+ ? await resolve(this.config.headers)
124
+ : undefined;
101
125
 
102
126
  try {
103
127
  const { value: response, responseHeaders } = await postJsonToApi({
@@ -160,7 +184,10 @@ export class GatewayLanguageModel implements LanguageModelV4 {
160
184
  response: { headers: responseHeaders },
161
185
  };
162
186
  } catch (error) {
163
- throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders));
187
+ throw await asGatewayError(
188
+ error,
189
+ await parseAuthMethod(resolvedHeaders ?? {}),
190
+ );
164
191
  }
165
192
  }
166
193
 
@@ -42,7 +42,9 @@ export class GatewayRerankingModel implements RerankingModelV4 {
42
42
  }: Parameters<RerankingModelV4['doRerank']>[0]): Promise<
43
43
  Awaited<ReturnType<RerankingModelV4['doRerank']>>
44
44
  > {
45
- const resolvedHeaders = await resolve(this.config.headers());
45
+ const resolvedHeaders = this.config.headers
46
+ ? await resolve(this.config.headers)
47
+ : undefined;
46
48
  try {
47
49
  const {
48
50
  responseHeaders,
@@ -81,7 +83,10 @@ export class GatewayRerankingModel implements RerankingModelV4 {
81
83
  warnings: [],
82
84
  };
83
85
  } catch (error) {
84
- throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders));
86
+ throw await asGatewayError(
87
+ error,
88
+ await parseAuthMethod(resolvedHeaders ?? {}),
89
+ );
85
90
  }
86
91
  }
87
92
 
@@ -106,7 +106,9 @@ export class GatewaySpendReport {
106
106
 
107
107
  const { value } = await getFromApi({
108
108
  url: `${baseUrl.origin}/v1/report?${searchParams.toString()}`,
109
- headers: await resolve(this.config.headers()),
109
+ headers: this.config.headers
110
+ ? await resolve(this.config.headers)
111
+ : undefined,
110
112
  successfulResponseHandler: createJsonResponseHandler(
111
113
  gatewaySpendReportResponseSchema,
112
114
  ),
@@ -60,7 +60,9 @@ export class GatewayVideoModel implements Experimental_VideoModelV4 {
60
60
  headers: Record<string, string> | undefined;
61
61
  };
62
62
  }> {
63
- const resolvedHeaders = await resolve(this.config.headers());
63
+ const resolvedHeaders = this.config.headers
64
+ ? await resolve(this.config.headers)
65
+ : undefined;
64
66
  try {
65
67
  const { responseHeaders, value: responseBody } = await postJsonToApi({
66
68
  url: this.getUrl(),
@@ -178,7 +180,10 @@ export class GatewayVideoModel implements Experimental_VideoModelV4 {
178
180
  },
179
181
  };
180
182
  } catch (error) {
181
- throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders));
183
+ throw await asGatewayError(
184
+ error,
185
+ await parseAuthMethod(resolvedHeaders ?? {}),
186
+ );
182
187
  }
183
188
  }
184
189