@ai-sdk/gateway 4.0.20 → 4.0.22
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 +14 -0
- package/dist/index.d.ts +33 -2
- package/dist/index.js +26 -6
- package/dist/index.js.map +1 -1
- package/docs/00-ai-gateway.mdx +1 -1
- package/package.json +1 -1
- package/src/gateway-language-model-settings.ts +4 -0
- package/src/gateway-provider.ts +80 -11
- package/src/gateway-transcription-model-settings.ts +1 -0
- package/src/gateway-transcription-model.ts +4 -1
package/docs/00-ai-gateway.mdx
CHANGED
|
@@ -1065,7 +1065,7 @@ The following gateway provider options are available:
|
|
|
1065
1065
|
per-provider option each provider expects, and overrides any tier
|
|
1066
1066
|
also set in the per-provider options. Leave unset for provider
|
|
1067
1067
|
default. See the [OpenAI](/providers/ai-sdk-providers/openai),
|
|
1068
|
-
[Google Generative AI](/providers/ai-sdk-providers/google
|
|
1068
|
+
[Google Generative AI](/providers/ai-sdk-providers/google),
|
|
1069
1069
|
and [Google Vertex AI](/providers/ai-sdk-providers/google-vertex)
|
|
1070
1070
|
provider docs for tier semantics, model availability, and graceful
|
|
1071
1071
|
downgrade behavior on each provider.
|
package/package.json
CHANGED
|
@@ -35,7 +35,9 @@ export type GatewayModelId =
|
|
|
35
35
|
| 'anthropic/claude-opus-4.5'
|
|
36
36
|
| 'anthropic/claude-opus-4.6'
|
|
37
37
|
| 'anthropic/claude-opus-4.7'
|
|
38
|
+
| 'anthropic/claude-opus-4.7-fast'
|
|
38
39
|
| 'anthropic/claude-opus-4.8'
|
|
40
|
+
| 'anthropic/claude-opus-4.8-fast'
|
|
39
41
|
| 'anthropic/claude-sonnet-4'
|
|
40
42
|
| 'anthropic/claude-sonnet-4.5'
|
|
41
43
|
| 'anthropic/claude-sonnet-4.6'
|
|
@@ -115,6 +117,7 @@ export type GatewayModelId =
|
|
|
115
117
|
| 'moonshotai/kimi-k2.6'
|
|
116
118
|
| 'moonshotai/kimi-k2.7-code'
|
|
117
119
|
| 'moonshotai/kimi-k2.7-code-highspeed'
|
|
120
|
+
| 'moonshotai/kimi-k3'
|
|
118
121
|
| 'morph/morph-v3-fast'
|
|
119
122
|
| 'morph/morph-v3-large'
|
|
120
123
|
| 'nvidia/nemotron-3-nano-30b-a3b'
|
|
@@ -171,6 +174,7 @@ export type GatewayModelId =
|
|
|
171
174
|
| 'sakana/fugu-ultra'
|
|
172
175
|
| 'stepfun/step-3.5-flash'
|
|
173
176
|
| 'stepfun/step-3.7-flash'
|
|
177
|
+
| 'thinkingmachines/inkling'
|
|
174
178
|
| 'xai/grok-4.1-fast-non-reasoning'
|
|
175
179
|
| 'xai/grok-4.1-fast-reasoning'
|
|
176
180
|
| 'xai/grok-4.20-multi-agent'
|
package/src/gateway-provider.ts
CHANGED
|
@@ -36,7 +36,10 @@ import { GatewayImageModel } from './gateway-image-model';
|
|
|
36
36
|
import { GatewayVideoModel } from './gateway-video-model';
|
|
37
37
|
import { GatewayRerankingModel } from './gateway-reranking-model';
|
|
38
38
|
import { GatewaySpeechModel } from './gateway-speech-model';
|
|
39
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
GatewayTranscriptionModel,
|
|
41
|
+
toGatewayTranscriptionUrl,
|
|
42
|
+
} from './gateway-transcription-model';
|
|
40
43
|
import { GatewayRealtimeModel } from './gateway-realtime-model';
|
|
41
44
|
import type { GatewayEmbeddingModelId } from './gateway-embedding-model-settings';
|
|
42
45
|
import type { GatewayImageModelId } from './gateway-image-model-settings';
|
|
@@ -174,12 +177,50 @@ export interface GatewayProvider extends ProviderV4 {
|
|
|
174
177
|
*/
|
|
175
178
|
experimental_realtime: RealtimeFactoryV4;
|
|
176
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Experimental streaming-transcription entry point. Callable like
|
|
182
|
+
* `transcription(modelId)`, plus `getToken` for minting a short-lived
|
|
183
|
+
* client secret (`vcst_`) a browser can use to open the streaming
|
|
184
|
+
* transcription WebSocket without holding the Gateway credential.
|
|
185
|
+
*/
|
|
186
|
+
experimental_transcription: GatewayTranscriptionFactory;
|
|
187
|
+
|
|
177
188
|
/**
|
|
178
189
|
* Gateway-specific tools executed server-side.
|
|
179
190
|
*/
|
|
180
191
|
tools: typeof gatewayTools;
|
|
181
192
|
}
|
|
182
193
|
|
|
194
|
+
export type GatewayTranscriptionFactoryGetTokenOptions = {
|
|
195
|
+
model: GatewayTranscriptionModelId;
|
|
196
|
+
/** Token lifetime in seconds. Gateway default is 60s (max 300s). */
|
|
197
|
+
expiresAfterSeconds?: number;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
export type GatewayTranscriptionFactoryGetTokenResult = {
|
|
201
|
+
/** The minted `vcst_` client secret. */
|
|
202
|
+
token: string;
|
|
203
|
+
/** WebSocket URL of the streaming transcription surface for this model. */
|
|
204
|
+
url: string;
|
|
205
|
+
/** Token expiry, epoch seconds. */
|
|
206
|
+
expiresAt?: number;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Streaming-transcription factory: callable like `transcription(modelId)`,
|
|
211
|
+
* plus a server-side `getToken` that mints a transcription-bound short-lived
|
|
212
|
+
* client secret (`vcst_`). The browser connects with
|
|
213
|
+
* `createGateway({ apiKey: token }).transcription(modelId)` — the token rides
|
|
214
|
+
* the same auth subprotocol an API key does, without exposing the credential.
|
|
215
|
+
*/
|
|
216
|
+
export interface GatewayTranscriptionFactory {
|
|
217
|
+
(modelId: GatewayTranscriptionModelId): TranscriptionModelV4;
|
|
218
|
+
|
|
219
|
+
getToken(
|
|
220
|
+
options: GatewayTranscriptionFactoryGetTokenOptions,
|
|
221
|
+
): Promise<GatewayTranscriptionFactoryGetTokenResult>;
|
|
222
|
+
}
|
|
223
|
+
|
|
183
224
|
export interface GatewayProviderSettings {
|
|
184
225
|
/**
|
|
185
226
|
* The base URL prefix for API calls. Defaults to `https://ai-gateway.vercel.sh/v4/ai`.
|
|
@@ -297,18 +338,21 @@ export function createGateway(
|
|
|
297
338
|
}
|
|
298
339
|
};
|
|
299
340
|
|
|
300
|
-
// Mints a short-lived
|
|
341
|
+
// Mints a short-lived client secret (`vcst_`) via the Gateway's
|
|
301
342
|
// `/v1/realtime/client-secrets` route, authenticated with the long-lived
|
|
302
343
|
// Gateway credential. Server-side only (asserted) — the credential never
|
|
303
344
|
// belongs in a browser; the browser receives only the minted token. The
|
|
304
345
|
// mint route lives at the gateway origin's `/v1/realtime/client-secrets`,
|
|
305
|
-
// not under the
|
|
306
|
-
//
|
|
307
|
-
|
|
346
|
+
// not under the `baseURL` path (which targets `/v4/ai`), so the URL is
|
|
347
|
+
// resolved against the origin. `routeKind` binds the token to a WebSocket
|
|
348
|
+
// surface; it is omitted for realtime (the gateway default) so older
|
|
349
|
+
// gateway deployments keep accepting realtime mints.
|
|
350
|
+
const mintClientSecret = async (params: {
|
|
308
351
|
modelId: string;
|
|
309
352
|
expiresAfterSeconds?: number;
|
|
353
|
+
routeKind?: 'transcription';
|
|
310
354
|
}): Promise<{ token: string; expiresAt?: number }> => {
|
|
311
|
-
|
|
355
|
+
assertGatewayClientSecretServerEnvironment();
|
|
312
356
|
const auth = await getRealtimeAuthToken();
|
|
313
357
|
const headers = createAuthHeaders(auth);
|
|
314
358
|
const url = new URL('/v1/realtime/client-secrets', baseURL).toString();
|
|
@@ -318,6 +362,7 @@ export function createGateway(
|
|
|
318
362
|
headers,
|
|
319
363
|
body: {
|
|
320
364
|
model: params.modelId,
|
|
365
|
+
...(params.routeKind != null && { routeKind: params.routeKind }),
|
|
321
366
|
...(params.expiresAfterSeconds != null && {
|
|
322
367
|
expiresIn: params.expiresAfterSeconds,
|
|
323
368
|
}),
|
|
@@ -530,18 +575,42 @@ export function createGateway(
|
|
|
530
575
|
};
|
|
531
576
|
provider.transcriptionModel = createTranscriptionModel;
|
|
532
577
|
provider.transcription = createTranscriptionModel;
|
|
578
|
+
// Callable like `transcription(modelId)`; `getToken` mints a
|
|
579
|
+
// transcription-bound client secret (server-side only) the browser uses to
|
|
580
|
+
// connect via `createGateway({ apiKey: token }).transcription(modelId)`.
|
|
581
|
+
provider.experimental_transcription = Object.assign(
|
|
582
|
+
(modelId: GatewayTranscriptionModelId) => createTranscriptionModel(modelId),
|
|
583
|
+
{
|
|
584
|
+
getToken: async (
|
|
585
|
+
tokenOptions: GatewayTranscriptionFactoryGetTokenOptions,
|
|
586
|
+
): Promise<GatewayTranscriptionFactoryGetTokenResult> => {
|
|
587
|
+
const secret = await mintClientSecret({
|
|
588
|
+
modelId: tokenOptions.model,
|
|
589
|
+
routeKind: 'transcription',
|
|
590
|
+
...(tokenOptions.expiresAfterSeconds != null && {
|
|
591
|
+
expiresAfterSeconds: tokenOptions.expiresAfterSeconds,
|
|
592
|
+
}),
|
|
593
|
+
});
|
|
594
|
+
return {
|
|
595
|
+
token: secret.token,
|
|
596
|
+
url: toGatewayTranscriptionUrl(baseURL, tokenOptions.model),
|
|
597
|
+
...(secret.expiresAt != null && { expiresAt: secret.expiresAt }),
|
|
598
|
+
};
|
|
599
|
+
},
|
|
600
|
+
},
|
|
601
|
+
) as GatewayTranscriptionFactory;
|
|
533
602
|
|
|
534
603
|
// No server-environment guard here: building the realtime model is just the
|
|
535
604
|
// event codec + WebSocket-config helper, which the browser legitimately
|
|
536
605
|
// needs to drive the transport with a server-minted client secret. The
|
|
537
|
-
// server-only boundary is enforced on minting itself
|
|
538
|
-
//
|
|
606
|
+
// server-only boundary is enforced on minting itself (`mintClientSecret`),
|
|
607
|
+
// which requires the Gateway credential.
|
|
539
608
|
const createRealtimeModel = (modelId: GatewayRealtimeModelId) =>
|
|
540
609
|
new GatewayRealtimeModel(modelId, {
|
|
541
610
|
provider: 'gateway.realtime',
|
|
542
611
|
baseURL,
|
|
543
612
|
teamIdOrSlug: options.teamIdOrSlug,
|
|
544
|
-
createClientSecret:
|
|
613
|
+
createClientSecret: mintClientSecret,
|
|
545
614
|
});
|
|
546
615
|
provider.experimental_realtime = Object.assign(
|
|
547
616
|
(modelId: GatewayRealtimeModelId) => createRealtimeModel(modelId),
|
|
@@ -591,10 +660,10 @@ export async function getGatewayAuthToken(
|
|
|
591
660
|
};
|
|
592
661
|
}
|
|
593
662
|
|
|
594
|
-
function
|
|
663
|
+
function assertGatewayClientSecretServerEnvironment(): void {
|
|
595
664
|
if (typeof globalThis.window !== 'undefined') {
|
|
596
665
|
throw new Error(
|
|
597
|
-
'AI Gateway
|
|
666
|
+
'AI Gateway client secrets must be minted server-side: minting needs your Gateway credential, which must never reach the browser. Call gateway.experimental_realtime.getToken() or gateway.experimental_transcription.getToken() from your server and pass the returned token to the client.',
|
|
598
667
|
);
|
|
599
668
|
}
|
|
600
669
|
}
|
|
@@ -181,7 +181,10 @@ export class GatewayTranscriptionModel implements TranscriptionModelV4 {
|
|
|
181
181
|
* WS(S), model id in `?ai-model-id=` (browser `WebSocket` cannot set headers;
|
|
182
182
|
* slash-safe for qualified ids like `openai/gpt-realtime-whisper`).
|
|
183
183
|
*/
|
|
184
|
-
function toGatewayTranscriptionUrl(
|
|
184
|
+
export function toGatewayTranscriptionUrl(
|
|
185
|
+
baseURL: string,
|
|
186
|
+
modelId: string,
|
|
187
|
+
): string {
|
|
185
188
|
const url = new URL(`${baseURL.replace(/^http/, 'ws')}/transcription-model`);
|
|
186
189
|
url.searchParams.set('ai-model-id', modelId);
|
|
187
190
|
return url.toString();
|