@ai-sdk/gateway 4.0.103 → 4.0.105
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 +27 -0
- package/dist/index.d.ts +124 -107
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -22
- package/dist/index.js.map +1 -1
- package/docs/00-ai-gateway.mdx +15 -6
- package/package.json +5 -5
- package/src/gateway-batch.ts +4 -1
- package/src/gateway-decision-model-settings.ts +6 -0
- package/src/{gateway-evaluation-model.ts → gateway-decision-model.ts} +20 -15
- package/src/gateway-embedding-model-settings.ts +2 -0
- package/src/gateway-image-model-settings.ts +1 -0
- package/src/gateway-language-model-settings.ts +3 -1
- package/src/gateway-model-entry.ts +2 -0
- package/src/gateway-provider-options.ts +24 -24
- package/src/gateway-provider.ts +29 -12
- package/src/gateway-transcription-model.ts +48 -1
- package/src/gateway-video-model-settings.ts +1 -0
- package/src/index.ts +11 -2
- package/src/gateway-evaluation-model-settings.ts +0 -4
package/docs/00-ai-gateway.mdx
CHANGED
|
@@ -78,6 +78,15 @@ const gateway = createGateway({
|
|
|
78
78
|
|
|
79
79
|
You can use the following optional settings to customize the AI Gateway provider instance:
|
|
80
80
|
|
|
81
|
+
- **batchResultDownloads** _object_
|
|
82
|
+
|
|
83
|
+
Settings for downloading JSON Lines batch results.
|
|
84
|
+
- **maxLineBytes** _number_
|
|
85
|
+
|
|
86
|
+
Maximum UTF-8 bytes per row, excluding the LF delimiter. Defaults to 64 MiB
|
|
87
|
+
(67,108,864 bytes). Must be a positive safe integer. Oversized rows throw a
|
|
88
|
+
`DownloadError` and cancel the download.
|
|
89
|
+
|
|
81
90
|
- **baseURL** _string_
|
|
82
91
|
|
|
83
92
|
Use a different URL prefix for API calls. The default prefix is `https://ai-gateway.vercel.sh/v4/ai`.
|
|
@@ -1478,7 +1487,7 @@ The following gateway provider options are available:
|
|
|
1478
1487
|
|
|
1479
1488
|
- **models** _string[] | [GatewayModelFallback, ...string[]]_
|
|
1480
1489
|
|
|
1481
|
-
Specifies fallback models in attempt order. String entries keep their existing behavior: the gateway tries them when the primary model fails or is unavailable.
|
|
1490
|
+
Specifies fallback models in attempt order. String entries keep their existing behavior: the gateway tries them when the primary model fails or is unavailable. Decision requests can also start the list with one conditional `{ model, when }` entry to retry a successful but uncertain decision with another model. Only the first entry can be conditional, and only one conditional entry is allowed. If the primary model fails, the gateway also advances to the conditional entry under its existing error fallback behavior. Conditional entries are rejected on non-decision requests.
|
|
1482
1491
|
|
|
1483
1492
|
Example: `models: ['openai/gpt-5.4-nano', 'google/gemini-3.8-flash']` will try the fallback models in order if the primary model fails.
|
|
1484
1493
|
|
|
@@ -1616,15 +1625,15 @@ const { text } = await generateText({
|
|
|
1616
1625
|
// 4. Return the result from the first model that succeeds
|
|
1617
1626
|
```
|
|
1618
1627
|
|
|
1619
|
-
#### Conditional
|
|
1628
|
+
#### Conditional Decision Fallbacks Example
|
|
1620
1629
|
|
|
1621
|
-
Conditional model entries are available only for
|
|
1622
|
-
configuration under `providerOptions.gateway.models`. `
|
|
1630
|
+
Conditional model entries are available only for decision requests. Keep the
|
|
1631
|
+
configuration under `providerOptions.gateway.models`. `experimental_decide`
|
|
1623
1632
|
does not have a top-level fallback option.
|
|
1624
1633
|
|
|
1625
1634
|
```ts
|
|
1626
1635
|
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
1627
|
-
import {
|
|
1636
|
+
import { experimental_decide } from 'ai';
|
|
1628
1637
|
|
|
1629
1638
|
const questions = {
|
|
1630
1639
|
department: {
|
|
@@ -1638,7 +1647,7 @@ const questions = {
|
|
|
1638
1647
|
},
|
|
1639
1648
|
} as const;
|
|
1640
1649
|
|
|
1641
|
-
const result = await
|
|
1650
|
+
const result = await experimental_decide({
|
|
1642
1651
|
model: 'typesafe-ai/jev',
|
|
1643
1652
|
state: 'I was charged twice. Please refund the duplicate.',
|
|
1644
1653
|
questions,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/gateway",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "4.0.
|
|
4
|
+
"version": "4.0.105",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -30,17 +30,17 @@
|
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@ai-sdk/provider": "4.0.
|
|
34
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
33
|
+
"@ai-sdk/provider": "4.0.23",
|
|
34
|
+
"@ai-sdk/provider-utils": "5.0.55",
|
|
35
35
|
"@vercel/oidc": "3.2.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@ai-sdk/test-server": "2.0.
|
|
38
|
+
"@ai-sdk/test-server": "2.0.4",
|
|
39
39
|
"@types/node": "22.19.19",
|
|
40
40
|
"@vercel/ai-tsconfig": "0.0.0",
|
|
41
41
|
"tsdown": "^0.23.0",
|
|
42
42
|
"tsx": "4.23.12",
|
|
43
|
-
"typescript": "
|
|
43
|
+
"typescript": "6.0.3",
|
|
44
44
|
"zod": "3.25.76"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
package/src/gateway-batch.ts
CHANGED
|
@@ -35,7 +35,9 @@ export class GatewayBatch implements BatchV4<{ text: GatewayModelId }> {
|
|
|
35
35
|
readonly provider: string;
|
|
36
36
|
readonly supportedUrls = { '*/*': [/.*/] };
|
|
37
37
|
|
|
38
|
-
constructor(
|
|
38
|
+
constructor(
|
|
39
|
+
private readonly config: GatewayChatConfig & { maxLineBytes?: number },
|
|
40
|
+
) {
|
|
39
41
|
this.provider = `${config.provider}.batch`;
|
|
40
42
|
}
|
|
41
43
|
|
|
@@ -191,6 +193,7 @@ export class GatewayBatch implements BatchV4<{ text: GatewayModelId }> {
|
|
|
191
193
|
body: { batchId },
|
|
192
194
|
successfulResponseHandler: createJsonLinesResponseHandler(
|
|
193
195
|
gatewayBatchItemResultLineSchema,
|
|
196
|
+
{ maxLineBytes: this.config.maxLineBytes },
|
|
194
197
|
),
|
|
195
198
|
failedResponseHandler: createJsonErrorResponseHandler({
|
|
196
199
|
errorSchema: z.any(),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
2
|
+
Experimental_DecisionModelV4 as DecisionModelV4,
|
|
3
3
|
SharedV4ProviderMetadata,
|
|
4
4
|
} from '@ai-sdk/provider';
|
|
5
5
|
import {
|
|
@@ -18,9 +18,9 @@ import { z } from './zod';
|
|
|
18
18
|
import { asGatewayError } from './errors';
|
|
19
19
|
import { parseAuthMethod } from './errors/parse-auth-method';
|
|
20
20
|
import type { GatewayConfig } from './gateway-config';
|
|
21
|
-
import {
|
|
21
|
+
import { gatewayDecisionProviderOptionsSchema } from './gateway-provider-options';
|
|
22
22
|
|
|
23
|
-
export class
|
|
23
|
+
export class GatewayDecisionModel implements DecisionModelV4 {
|
|
24
24
|
readonly specificationVersion = 'v4';
|
|
25
25
|
|
|
26
26
|
readonly supportedQuestionTypes = ['choice', 'score', 'boolean'] as const;
|
|
@@ -37,19 +37,24 @@ export class GatewayEvaluationModel implements EvaluationModelV4 {
|
|
|
37
37
|
return this.config.provider;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
/** @deprecated Use `doDecide` instead. */
|
|
41
|
+
doEvaluate(options: Parameters<DecisionModelV4['doDecide']>[0]) {
|
|
42
|
+
return this.doDecide(options);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async doDecide({
|
|
41
46
|
state,
|
|
42
47
|
questions,
|
|
43
48
|
headers,
|
|
44
49
|
abortSignal,
|
|
45
50
|
providerOptions,
|
|
46
|
-
}: Parameters<
|
|
47
|
-
Awaited<ReturnType<
|
|
51
|
+
}: Parameters<DecisionModelV4['doDecide']>[0]): Promise<
|
|
52
|
+
Awaited<ReturnType<DecisionModelV4['doDecide']>>
|
|
48
53
|
> {
|
|
49
54
|
const gatewayOptions = await parseProviderOptions({
|
|
50
55
|
provider: 'gateway',
|
|
51
56
|
providerOptions,
|
|
52
|
-
schema:
|
|
57
|
+
schema: gatewayDecisionProviderOptionsSchema,
|
|
53
58
|
});
|
|
54
59
|
const validatedProviderOptions =
|
|
55
60
|
gatewayOptions == null
|
|
@@ -79,7 +84,7 @@ export class GatewayEvaluationModel implements EvaluationModelV4 {
|
|
|
79
84
|
: {}),
|
|
80
85
|
},
|
|
81
86
|
successfulResponseHandler: createJsonResponseHandler(
|
|
82
|
-
|
|
87
|
+
gatewayDecisionResponseSchema,
|
|
83
88
|
),
|
|
84
89
|
failedResponseHandler: createJsonErrorResponseHandler({
|
|
85
90
|
errorSchema: z.any(),
|
|
@@ -111,18 +116,18 @@ export class GatewayEvaluationModel implements EvaluationModelV4 {
|
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
private getUrl() {
|
|
114
|
-
return `${this.config.baseURL}/
|
|
119
|
+
return `${this.config.baseURL}/decision-model`;
|
|
115
120
|
}
|
|
116
121
|
|
|
117
122
|
private getModelConfigHeaders() {
|
|
118
123
|
return {
|
|
119
|
-
'ai-
|
|
124
|
+
'ai-decision-model-specification-version': '4',
|
|
120
125
|
'ai-model-id': this.modelId,
|
|
121
126
|
};
|
|
122
127
|
}
|
|
123
128
|
}
|
|
124
129
|
|
|
125
|
-
const
|
|
130
|
+
const gatewayDecisionAnswerSchema = z.discriminatedUnion('type', [
|
|
126
131
|
z.object({
|
|
127
132
|
type: z.literal('choice'),
|
|
128
133
|
choice: z.string(),
|
|
@@ -139,7 +144,7 @@ const gatewayEvaluationAnswerSchema = z.discriminatedUnion('type', [
|
|
|
139
144
|
}),
|
|
140
145
|
]);
|
|
141
146
|
|
|
142
|
-
const
|
|
147
|
+
const gatewayDecisionWarningSchema = z.discriminatedUnion('type', [
|
|
143
148
|
z.object({
|
|
144
149
|
type: z.literal('unsupported'),
|
|
145
150
|
feature: z.string(),
|
|
@@ -161,10 +166,10 @@ const gatewayEvaluationWarningSchema = z.discriminatedUnion('type', [
|
|
|
161
166
|
}),
|
|
162
167
|
]);
|
|
163
168
|
|
|
164
|
-
const
|
|
169
|
+
const gatewayDecisionResponseSchema = lazySchema(() =>
|
|
165
170
|
zodSchema(
|
|
166
171
|
z.object({
|
|
167
|
-
answers: z.record(z.string(),
|
|
172
|
+
answers: z.record(z.string(), gatewayDecisionAnswerSchema),
|
|
168
173
|
model: z.string().optional(),
|
|
169
174
|
rounding: z
|
|
170
175
|
.object({
|
|
@@ -178,7 +183,7 @@ const gatewayEvaluationResponseSchema = lazySchema(() =>
|
|
|
178
183
|
outputTokens: z.number().optional(),
|
|
179
184
|
})
|
|
180
185
|
.optional(),
|
|
181
|
-
warnings: z.array(
|
|
186
|
+
warnings: z.array(gatewayDecisionWarningSchema).optional(),
|
|
182
187
|
providerMetadata: z
|
|
183
188
|
.record(z.string(), z.record(z.string(), z.unknown()))
|
|
184
189
|
.optional(),
|
|
@@ -4,6 +4,8 @@ export type GatewayEmbeddingModelId =
|
|
|
4
4
|
| 'alibaba/qwen3-embedding-8b'
|
|
5
5
|
| 'amazon/titan-embed-text-v2'
|
|
6
6
|
| 'cohere/embed-v4.0'
|
|
7
|
+
| 'cohere/embed-v5.0-fast'
|
|
8
|
+
| 'cohere/embed-v5.0-pro'
|
|
7
9
|
| 'google/gemini-embedding-001'
|
|
8
10
|
| 'google/gemini-embedding-2'
|
|
9
11
|
| 'google/text-embedding-005'
|
|
@@ -70,6 +70,7 @@ export type GatewayModelId =
|
|
|
70
70
|
| 'deepseek/deepseek-v4-pro'
|
|
71
71
|
| 'deepseek/deepseek-v4-pro-0813'
|
|
72
72
|
| 'deepseek/deepseek-v4.1-flash'
|
|
73
|
+
| 'deepseek/deepseek-v4.1-flash-fast'
|
|
73
74
|
| 'fireworks/ember-1'
|
|
74
75
|
| 'google/gemini-2.5-flash'
|
|
75
76
|
| 'google/gemini-2.5-flash-image'
|
|
@@ -87,6 +88,7 @@ export type GatewayModelId =
|
|
|
87
88
|
| 'google/gemini-3.6-flash'
|
|
88
89
|
| 'google/gemini-3.7-flash'
|
|
89
90
|
| 'google/gemini-3.8-flash'
|
|
91
|
+
| 'google/gemini-nano-banana-2.1'
|
|
90
92
|
| 'google/gemini-omni-flash-preview'
|
|
91
93
|
| 'google/gemma-4-26b-a4b-it'
|
|
92
94
|
| 'google/gemma-4-31b-it'
|
|
@@ -96,7 +98,6 @@ export type GatewayModelId =
|
|
|
96
98
|
| 'inclusionai/ling-3.0-flash'
|
|
97
99
|
| 'inclusionai/ling-3.0-flash-fin'
|
|
98
100
|
| 'inclusionai/ling-3.0-flash-sante'
|
|
99
|
-
| 'inclusionai/ling-3.0-flash-sante-free'
|
|
100
101
|
| 'inclusionai/ling-3.0-flash-vl'
|
|
101
102
|
| 'inclusionai/ling-3.1-flash'
|
|
102
103
|
| 'inclusionai/ling-3.1-flash-free'
|
|
@@ -128,6 +129,7 @@ export type GatewayModelId =
|
|
|
128
129
|
| 'mistral/ministral-3b'
|
|
129
130
|
| 'mistral/ministral-8b'
|
|
130
131
|
| 'mistral/mistral-large-3'
|
|
132
|
+
| 'mistral/mistral-large-4'
|
|
131
133
|
| 'mistral/mistral-medium-3.5'
|
|
132
134
|
| 'mistral/mistral-nemo'
|
|
133
135
|
| 'mistral/mistral-small'
|
|
@@ -3,11 +3,11 @@ import type { ZodType } from 'zod/v4';
|
|
|
3
3
|
import { z } from './zod';
|
|
4
4
|
|
|
5
5
|
// https://vercel.com/docs/ai-gateway/provider-options
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
8
|
-
export const
|
|
6
|
+
export const DECISION_FALLBACK_MAX_CONDITION_DEPTH = 5;
|
|
7
|
+
export const DECISION_FALLBACK_MAX_CONDITIONS_PER_LIST = 20;
|
|
8
|
+
export const DECISION_FALLBACK_MAX_QUESTION_LENGTH = 256;
|
|
9
9
|
|
|
10
|
-
export const
|
|
10
|
+
export const gatewayDecisionProviderOptionsSchema = lazySchema(() =>
|
|
11
11
|
zodSchema(
|
|
12
12
|
z
|
|
13
13
|
.object({
|
|
@@ -24,18 +24,18 @@ export const gatewayEvaluationProviderOptionsSchema = lazySchema(() =>
|
|
|
24
24
|
* Boolean question. Groups nest at most five levels deep, which the SDK
|
|
25
25
|
* checks at runtime.
|
|
26
26
|
*/
|
|
27
|
-
export type
|
|
27
|
+
export type DecisionFallbackCondition<QUESTION_ID extends string = string> =
|
|
28
28
|
| ExclusiveCondition<{ question?: QUESTION_ID; confidenceBelow: number }>
|
|
29
29
|
| ExclusiveCondition<{
|
|
30
30
|
question?: QUESTION_ID;
|
|
31
31
|
probabilityBetween: [number, number];
|
|
32
32
|
}>
|
|
33
|
-
| ExclusiveCondition<{ any:
|
|
34
|
-
| ExclusiveCondition<{ all:
|
|
33
|
+
| ExclusiveCondition<{ any: DecisionFallbackConditionList<QUESTION_ID> }>
|
|
34
|
+
| ExclusiveCondition<{ all: DecisionFallbackConditionList<QUESTION_ID> }>
|
|
35
35
|
| ExclusiveCondition<{
|
|
36
36
|
atLeast: {
|
|
37
37
|
count: number;
|
|
38
|
-
conditions:
|
|
38
|
+
conditions: DecisionFallbackConditionList<QUESTION_ID>;
|
|
39
39
|
};
|
|
40
40
|
}>;
|
|
41
41
|
|
|
@@ -43,7 +43,7 @@ export type GatewayModelFallback<QUESTION_ID extends string = string> =
|
|
|
43
43
|
| string
|
|
44
44
|
| {
|
|
45
45
|
model: string;
|
|
46
|
-
when:
|
|
46
|
+
when: DecisionFallbackCondition<QUESTION_ID>;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
export type GatewayProviderOptions<QUESTION_ID extends string = string> = {
|
|
@@ -91,8 +91,8 @@ export type GatewayProviderOptions<QUESTION_ID extends string = string> = {
|
|
|
91
91
|
idempotencyKey?: string;
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
|
-
* Fallback models to try in order. On
|
|
95
|
-
* can be a conditional `{ model, when }` fallback that reruns the
|
|
94
|
+
* Fallback models to try in order. On decision requests, the first entry
|
|
95
|
+
* can be a conditional `{ model, when }` fallback that reruns the decision
|
|
96
96
|
* when `when` matches the primary answers. Other request types reject a
|
|
97
97
|
* conditional entry. Pass your question IDs as `QUESTION_ID` to check the
|
|
98
98
|
* `question` names in `when`.
|
|
@@ -129,9 +129,9 @@ export type GatewayProviderOptions<QUESTION_ID extends string = string> = {
|
|
|
129
129
|
zeroDataRetention?: boolean;
|
|
130
130
|
};
|
|
131
131
|
|
|
132
|
-
type
|
|
133
|
-
|
|
134
|
-
...
|
|
132
|
+
type DecisionFallbackConditionList<QUESTION_ID extends string> = [
|
|
133
|
+
DecisionFallbackCondition<QUESTION_ID>,
|
|
134
|
+
...DecisionFallbackCondition<QUESTION_ID>[],
|
|
135
135
|
];
|
|
136
136
|
|
|
137
137
|
type ConditionKey =
|
|
@@ -160,7 +160,7 @@ const probabilitySchema = z.number().finite().min(0).max(1);
|
|
|
160
160
|
const questionSchema = z
|
|
161
161
|
.string()
|
|
162
162
|
.min(1)
|
|
163
|
-
.max(
|
|
163
|
+
.max(DECISION_FALLBACK_MAX_QUESTION_LENGTH);
|
|
164
164
|
const directConditionSchema = z.union([
|
|
165
165
|
z
|
|
166
166
|
.object({
|
|
@@ -180,7 +180,7 @@ const directConditionSchema = z.union([
|
|
|
180
180
|
}),
|
|
181
181
|
})
|
|
182
182
|
.strict(),
|
|
183
|
-
]) as ZodType<
|
|
183
|
+
]) as ZodType<DecisionFallbackCondition>;
|
|
184
184
|
|
|
185
185
|
const groupBeyondMaxDepthSchema = z
|
|
186
186
|
.union([
|
|
@@ -191,7 +191,7 @@ const groupBeyondMaxDepthSchema = z
|
|
|
191
191
|
.superRefine((_, context) => {
|
|
192
192
|
context.addIssue({
|
|
193
193
|
code: 'custom',
|
|
194
|
-
message: `conditions can be nested at most ${
|
|
194
|
+
message: `conditions can be nested at most ${DECISION_FALLBACK_MAX_CONDITION_DEPTH} levels deep`,
|
|
195
195
|
});
|
|
196
196
|
});
|
|
197
197
|
|
|
@@ -211,32 +211,32 @@ const gatewayModelFallbacksSchema = z
|
|
|
211
211
|
if (conditionalIndexes.length > 1) {
|
|
212
212
|
context.addIssue({
|
|
213
213
|
code: 'custom',
|
|
214
|
-
message: 'models supports at most one conditional
|
|
214
|
+
message: 'models supports at most one conditional decision fallback',
|
|
215
215
|
});
|
|
216
216
|
}
|
|
217
217
|
if (conditionalIndexes[0] !== undefined && conditionalIndexes[0] !== 0) {
|
|
218
218
|
context.addIssue({
|
|
219
219
|
code: 'custom',
|
|
220
220
|
message:
|
|
221
|
-
'a conditional
|
|
221
|
+
'a conditional decision fallback must be the first models entry',
|
|
222
222
|
path: [conditionalIndexes[0]],
|
|
223
223
|
});
|
|
224
224
|
}
|
|
225
225
|
});
|
|
226
226
|
|
|
227
|
-
function conditionSchema(depth: number): ZodType<
|
|
228
|
-
if (depth ===
|
|
227
|
+
function conditionSchema(depth: number): ZodType<DecisionFallbackCondition> {
|
|
228
|
+
if (depth === DECISION_FALLBACK_MAX_CONDITION_DEPTH) {
|
|
229
229
|
return z.union([
|
|
230
230
|
directConditionSchema,
|
|
231
231
|
groupBeyondMaxDepthSchema,
|
|
232
|
-
]) as ZodType<
|
|
232
|
+
]) as ZodType<DecisionFallbackCondition>;
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
const childConditionSchema = conditionSchema(depth + 1);
|
|
236
236
|
const conditionListSchema = z
|
|
237
237
|
.array(childConditionSchema)
|
|
238
238
|
.min(1)
|
|
239
|
-
.max(
|
|
239
|
+
.max(DECISION_FALLBACK_MAX_CONDITIONS_PER_LIST);
|
|
240
240
|
|
|
241
241
|
return z.union([
|
|
242
242
|
directConditionSchema,
|
|
@@ -256,5 +256,5 @@ function conditionSchema(depth: number): ZodType<EvaluationFallbackCondition> {
|
|
|
256
256
|
}),
|
|
257
257
|
})
|
|
258
258
|
.strict(),
|
|
259
|
-
]) as ZodType<
|
|
259
|
+
]) as ZodType<DecisionFallbackCondition>;
|
|
260
260
|
}
|
package/src/gateway-provider.ts
CHANGED
|
@@ -36,7 +36,7 @@ import { GatewayLanguageModel } from './gateway-language-model';
|
|
|
36
36
|
import { GatewayEmbeddingModel } from './gateway-embedding-model';
|
|
37
37
|
import { GatewayImageModel } from './gateway-image-model';
|
|
38
38
|
import { GatewayVideoModel } from './gateway-video-model';
|
|
39
|
-
import {
|
|
39
|
+
import { GatewayDecisionModel } from './gateway-decision-model';
|
|
40
40
|
import { GatewayRerankingModel } from './gateway-reranking-model';
|
|
41
41
|
import { GatewaySpeechModel } from './gateway-speech-model';
|
|
42
42
|
import {
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
} from './gateway-transcription-model';
|
|
46
46
|
import { GatewayRealtimeModel } from './gateway-realtime-model';
|
|
47
47
|
import type { GatewayEmbeddingModelId } from './gateway-embedding-model-settings';
|
|
48
|
-
import type {
|
|
48
|
+
import type { GatewayDecisionModelId } from './gateway-decision-model-settings';
|
|
49
49
|
import type { GatewayImageModelId } from './gateway-image-model-settings';
|
|
50
50
|
import type { GatewayRerankingModelId } from './gateway-reranking-model-settings';
|
|
51
51
|
import type { GatewaySpeechModelId } from './gateway-speech-model-settings';
|
|
@@ -63,7 +63,7 @@ import type {
|
|
|
63
63
|
SpeechModelV4,
|
|
64
64
|
TranscriptionModelV4,
|
|
65
65
|
Experimental_VideoModelV4,
|
|
66
|
-
|
|
66
|
+
Experimental_DecisionModelV4,
|
|
67
67
|
Experimental_RealtimeFactoryV4 as RealtimeFactoryV4,
|
|
68
68
|
Experimental_RealtimeFactoryV4GetTokenOptions as RealtimeFactoryV4GetTokenOptions,
|
|
69
69
|
ProviderV4,
|
|
@@ -159,16 +159,24 @@ export interface GatewayProvider extends ProviderV4 {
|
|
|
159
159
|
rerankingModel(modelId: GatewayRerankingModelId): RerankingModelV4;
|
|
160
160
|
|
|
161
161
|
/**
|
|
162
|
-
* Creates a model for
|
|
162
|
+
* Creates a model for deciding answers to questions against shared state.
|
|
163
163
|
*/
|
|
164
|
-
|
|
164
|
+
decision(modelId: GatewayDecisionModelId): Experimental_DecisionModelV4;
|
|
165
165
|
|
|
166
166
|
/**
|
|
167
|
-
* Creates a model for
|
|
167
|
+
* Creates a model for deciding answers to questions against shared state.
|
|
168
168
|
*/
|
|
169
|
+
decisionModel(modelId: GatewayDecisionModelId): Experimental_DecisionModelV4;
|
|
170
|
+
/** @deprecated Use `decisionModel` instead. */
|
|
169
171
|
evaluationModel(
|
|
170
|
-
modelId:
|
|
171
|
-
):
|
|
172
|
+
modelId: GatewayDecisionModelId,
|
|
173
|
+
): Experimental_DecisionModelV4 & {
|
|
174
|
+
doEvaluate: Experimental_DecisionModelV4['doDecide'];
|
|
175
|
+
};
|
|
176
|
+
/** @deprecated Use `decision` instead. */
|
|
177
|
+
evaluation(
|
|
178
|
+
modelId: GatewayDecisionModelId,
|
|
179
|
+
): ReturnType<GatewayProvider['evaluationModel']>;
|
|
172
180
|
|
|
173
181
|
/**
|
|
174
182
|
* Creates a model for text-to-speech generation.
|
|
@@ -243,6 +251,12 @@ export interface GatewayTranscriptionFactory {
|
|
|
243
251
|
}
|
|
244
252
|
|
|
245
253
|
export interface GatewayProviderSettings {
|
|
254
|
+
/** Settings for downloading JSON Lines batch results. */
|
|
255
|
+
batchResultDownloads?: {
|
|
256
|
+
/** Maximum UTF-8 bytes per row, excluding LF. Defaults to 64 MiB. */
|
|
257
|
+
maxLineBytes?: number;
|
|
258
|
+
};
|
|
259
|
+
|
|
246
260
|
/**
|
|
247
261
|
* The base URL prefix for API calls. Defaults to `https://ai-gateway.vercel.sh/v4/ai`.
|
|
248
262
|
*/
|
|
@@ -449,6 +463,7 @@ export function createGateway(
|
|
|
449
463
|
const createBatch = () =>
|
|
450
464
|
new GatewayBatch({
|
|
451
465
|
provider: 'gateway',
|
|
466
|
+
maxLineBytes: options.batchResultDownloads?.maxLineBytes,
|
|
452
467
|
baseURL,
|
|
453
468
|
headers: getHeaders,
|
|
454
469
|
fetch: options.fetch,
|
|
@@ -583,8 +598,8 @@ export function createGateway(
|
|
|
583
598
|
};
|
|
584
599
|
provider.rerankingModel = createRerankingModel;
|
|
585
600
|
provider.reranking = createRerankingModel;
|
|
586
|
-
const
|
|
587
|
-
return new
|
|
601
|
+
const createDecisionModel = (modelId: GatewayDecisionModelId) => {
|
|
602
|
+
return new GatewayDecisionModel(modelId, {
|
|
588
603
|
provider: 'gateway',
|
|
589
604
|
baseURL,
|
|
590
605
|
headers: getHeaders,
|
|
@@ -592,8 +607,10 @@ export function createGateway(
|
|
|
592
607
|
o11yHeaders: createO11yHeaders(),
|
|
593
608
|
});
|
|
594
609
|
};
|
|
595
|
-
provider.
|
|
596
|
-
provider.
|
|
610
|
+
provider.decisionModel = createDecisionModel;
|
|
611
|
+
provider.decision = createDecisionModel;
|
|
612
|
+
provider.evaluationModel = createDecisionModel;
|
|
613
|
+
provider.evaluation = createDecisionModel;
|
|
597
614
|
const createSpeechModel = (modelId: GatewaySpeechModelId) => {
|
|
598
615
|
return new GatewaySpeechModel(modelId, {
|
|
599
616
|
provider: 'gateway',
|
|
@@ -99,12 +99,28 @@ export class GatewayTranscriptionModel implements TranscriptionModelV4 {
|
|
|
99
99
|
fetch: this.config.fetch,
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
+
const warnings = [
|
|
103
|
+
...(responseBody.warnings ?? []),
|
|
104
|
+
] as Array<SharedV4Warning>;
|
|
105
|
+
if (
|
|
106
|
+
isXaiTranscriptionModel(this.modelId) &&
|
|
107
|
+
requestsXaiDiarization(providerOptions) &&
|
|
108
|
+
!containsSpeaker(rawValue)
|
|
109
|
+
) {
|
|
110
|
+
warnings.push({
|
|
111
|
+
type: 'unsupported',
|
|
112
|
+
feature: 'providerOptions.xai.diarize',
|
|
113
|
+
details:
|
|
114
|
+
'AI Gateway does not currently expose xAI speaker diarization metadata.',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
102
118
|
return {
|
|
103
119
|
text: responseBody.text,
|
|
104
120
|
segments: responseBody.segments ?? [],
|
|
105
121
|
language: responseBody.language ?? undefined,
|
|
106
122
|
durationInSeconds: responseBody.durationInSeconds ?? undefined,
|
|
107
|
-
warnings
|
|
123
|
+
warnings,
|
|
108
124
|
...(responseBody.usage != null && { usage: responseBody.usage }),
|
|
109
125
|
providerMetadata:
|
|
110
126
|
responseBody.providerMetadata as SharedV4ProviderMetadata,
|
|
@@ -177,6 +193,37 @@ export class GatewayTranscriptionModel implements TranscriptionModelV4 {
|
|
|
177
193
|
}
|
|
178
194
|
}
|
|
179
195
|
|
|
196
|
+
function isXaiTranscriptionModel(modelId: string): boolean {
|
|
197
|
+
return modelId.startsWith('spacexai/') || modelId.startsWith('xai/');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function requestsXaiDiarization(
|
|
201
|
+
providerOptions:
|
|
202
|
+
| Parameters<TranscriptionModelV4['doGenerate']>[0]['providerOptions']
|
|
203
|
+
| undefined,
|
|
204
|
+
): boolean {
|
|
205
|
+
return (
|
|
206
|
+
providerOptions?.xai?.diarize === true ||
|
|
207
|
+
providerOptions?.spacexai?.diarize === true
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function containsSpeaker(value: unknown): boolean {
|
|
212
|
+
if (Array.isArray(value)) {
|
|
213
|
+
return value.some(containsSpeaker);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (value == null || typeof value !== 'object') {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return Object.entries(value).some(
|
|
221
|
+
([key, nestedValue]) =>
|
|
222
|
+
(key === 'speaker' && nestedValue != null) ||
|
|
223
|
+
containsSpeaker(nestedValue),
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
180
227
|
/**
|
|
181
228
|
* Gateway streaming transcription WebSocket URL: HTTP(S) base upgraded to
|
|
182
229
|
* WS(S), model id in `?ai-model-id=` (browser `WebSocket` cannot set headers;
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import type { GatewayDecisionModelId } from './gateway-decision-model-settings';
|
|
2
|
+
import type { DecisionFallbackCondition } from './gateway-provider-options';
|
|
3
|
+
|
|
1
4
|
export type { GatewayEmbeddingModelId } from './gateway-embedding-model-settings';
|
|
2
|
-
export type {
|
|
5
|
+
export type { GatewayDecisionModelId } from './gateway-decision-model-settings';
|
|
3
6
|
export type { GatewayImageModelId } from './gateway-image-model-settings';
|
|
4
7
|
export type { GatewayModelId } from './gateway-language-model-settings';
|
|
5
8
|
export {
|
|
@@ -47,7 +50,7 @@ export type {
|
|
|
47
50
|
GatewayProviderMetadata,
|
|
48
51
|
} from './gateway-provider-metadata';
|
|
49
52
|
export type {
|
|
50
|
-
|
|
53
|
+
DecisionFallbackCondition,
|
|
51
54
|
GatewayModelFallback,
|
|
52
55
|
GatewayProviderOptions,
|
|
53
56
|
/** @deprecated Use `GatewayProviderOptions` instead. */
|
|
@@ -67,3 +70,9 @@ export {
|
|
|
67
70
|
} from './errors';
|
|
68
71
|
export type { GatewayErrorResponse } from './errors';
|
|
69
72
|
export { VERSION } from './version';
|
|
73
|
+
|
|
74
|
+
/** @deprecated Use `GatewayDecisionModelId` instead. */
|
|
75
|
+
export type GatewayEvaluationModelId = GatewayDecisionModelId;
|
|
76
|
+
/** @deprecated Use `DecisionFallbackCondition` instead. */
|
|
77
|
+
export type EvaluationFallbackCondition<QUESTION_ID extends string = string> =
|
|
78
|
+
DecisionFallbackCondition<QUESTION_ID>;
|