@ai-sdk/gateway 4.0.100 → 4.0.102

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.
@@ -625,16 +625,20 @@ const result = await generateText({
625
625
  });
626
626
 
627
627
  // Get the generation ID from provider metadata
628
- const generationId = result.providerMetadata?.gateway?.generationId;
628
+ const generationId = result.providerMetadata?.gateway?.generationId as
629
+ | string
630
+ | undefined;
629
631
 
630
632
  // Look up detailed generation info
631
- const generation = await gateway.getGenerationInfo({ id: generationId });
633
+ if (generationId) {
634
+ const generation = await gateway.getGenerationInfo({ id: generationId });
632
635
 
633
- console.log(`Model: ${generation.model}`);
634
- console.log(`Cost: $${generation.totalCost.toFixed(6)}`);
635
- console.log(`Latency: ${generation.latency}ms`);
636
- console.log(`Prompt tokens: ${generation.promptTokens}`);
637
- console.log(`Completion tokens: ${generation.completionTokens}`);
636
+ console.log(`Model: ${generation.model}`);
637
+ console.log(`Cost: $${generation.totalCost.toFixed(6)}`);
638
+ console.log(`Latency: ${generation.latency}ms`);
639
+ console.log(`Prompt tokens: ${generation.promptTokens}`);
640
+ console.log(`Completion tokens: ${generation.completionTokens}`);
641
+ }
638
642
  ```
639
643
 
640
644
  With `streamText`, you can capture the generation ID from the first chunk via `stream`:
@@ -1600,15 +1604,15 @@ const { text } = await generateText({
1600
1604
  prompt: 'Write a TypeScript haiku',
1601
1605
  providerOptions: {
1602
1606
  gateway: {
1603
- models: ['openai/gpt-5.4-nano', 'gemini-3.8-flash'], // Fallback models
1607
+ models: ['openai/gpt-5.4-nano', 'google/gemini-3.8-flash'], // Fallback models
1604
1608
  } satisfies GatewayProviderOptions,
1605
1609
  },
1606
1610
  });
1607
1611
 
1608
1612
  // This will:
1609
- // 1. Try openai/gpt-5.4 first
1613
+ // 1. Try openai/gpt-6-astra first
1610
1614
  // 2. If it fails, try openai/gpt-5.4-nano
1611
- // 3. If that fails, try gemini-3-flash-preview
1615
+ // 3. If that fails, try google/gemini-3.8-flash
1612
1616
  // 4. Return the result from the first model that succeeds
1613
1617
  ```
1614
1618
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ai-sdk/gateway",
3
3
  "private": false,
4
- "version": "4.0.100",
4
+ "version": "4.0.102",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "sideEffects": false,
@@ -30,15 +30,15 @@
30
30
  }
31
31
  },
32
32
  "dependencies": {
33
- "@ai-sdk/provider": "4.0.19",
34
- "@ai-sdk/provider-utils": "5.0.51",
33
+ "@ai-sdk/provider": "4.0.21",
34
+ "@ai-sdk/provider-utils": "5.0.53",
35
35
  "@vercel/oidc": "3.2.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@ai-sdk/test-server": "2.0.2",
38
+ "@ai-sdk/test-server": "2.0.3",
39
39
  "@types/node": "22.19.19",
40
40
  "@vercel/ai-tsconfig": "0.0.0",
41
- "tsup": "^8.5.1",
41
+ "tsdown": "^0.23.0",
42
42
  "tsx": "4.23.12",
43
43
  "typescript": "5.8.3",
44
44
  "zod": "3.25.76"
@@ -66,9 +66,9 @@
66
66
  "ai"
67
67
  ],
68
68
  "scripts": {
69
- "build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
70
- "build:watch": "pnpm clean && tsup --watch",
71
- "clean": "del-cli dist docs *.tsbuildinfo",
69
+ "build": "pnpm clean && tsdown",
70
+ "build:watch": "pnpm clean && tsdown --watch",
71
+ "clean": "del-cli docs *.tsbuildinfo",
72
72
  "generate-model-settings": "tsx scripts/generate-model-settings.ts",
73
73
  "type-check": "tsc --build",
74
74
  "test": "pnpm test:node && pnpm test:edge",
@@ -1 +1,4 @@
1
- export type GatewayEvaluationModelId = 'typesafe-ai/jev' | (string & {});
1
+ export type GatewayEvaluationModelId =
2
+ | 'liquid/d1'
3
+ | 'typesafe-ai/jev'
4
+ | (string & {});
@@ -10,6 +10,7 @@ import {
10
10
  import { z } from './zod';
11
11
  import { asGatewayError } from './errors';
12
12
  import type { GatewayConfig } from './gateway-config';
13
+ import { VERCEL_AI_GATEWAY_TEAM_HEADER } from './gateway-headers';
13
14
  import {
14
15
  KNOWN_MODEL_TYPES,
15
16
  type GatewayLanguageModelEntry,
@@ -58,13 +59,27 @@ export class GatewayFetchMetadata {
58
59
  async getCredits(): Promise<GatewayCreditsResponse> {
59
60
  try {
60
61
  const baseUrl = new URL(this.config.baseURL);
62
+ const headers = this.config.headers
63
+ ? await resolve(this.config.headers)
64
+ : undefined;
65
+
66
+ // The credits endpoint selects the team from the `teamId` / `slug`
67
+ // query parameter rather than the team header, so forward it there.
68
+ // Without it, tokens that can access multiple teams (e.g. Vercel access
69
+ // tokens) cannot be scoped to a team and the request is rejected.
70
+ const url = new URL('/v1/credits', baseUrl.origin);
71
+ const teamIdOrSlug = getTeamIdOrSlug(headers);
72
+ if (teamIdOrSlug) {
73
+ url.searchParams.set(
74
+ teamIdOrSlug.startsWith('team_') ? 'teamId' : 'slug',
75
+ teamIdOrSlug,
76
+ );
77
+ }
61
78
 
62
79
  const { value } = await getFromApi({
63
- url: `${baseUrl.origin}/v1/credits`,
80
+ url: url.toString(),
64
81
  validateUrl: false,
65
- headers: this.config.headers
66
- ? await resolve(this.config.headers)
67
- : undefined,
82
+ headers,
68
83
  successfulResponseHandler: createJsonResponseHandler(
69
84
  gatewayCreditsResponseSchema,
70
85
  ),
@@ -82,6 +97,18 @@ export class GatewayFetchMetadata {
82
97
  }
83
98
  }
84
99
 
100
+ function getTeamIdOrSlug(
101
+ headers: Record<string, string | undefined> | undefined,
102
+ ): string | undefined {
103
+ if (!headers) return undefined;
104
+ for (const [name, value] of Object.entries(headers)) {
105
+ if (name.toLowerCase() === VERCEL_AI_GATEWAY_TEAM_HEADER) {
106
+ return value?.trim() || undefined;
107
+ }
108
+ }
109
+ return undefined;
110
+ }
111
+
85
112
  const gatewayAvailableModelsResponseSchema = lazySchema(() =>
86
113
  zodSchema(
87
114
  z.object({
@@ -98,6 +98,8 @@ export type GatewayModelId =
98
98
  | 'inclusionai/ling-3.0-flash-sante'
99
99
  | 'inclusionai/ling-3.0-flash-sante-free'
100
100
  | 'inclusionai/ling-3.0-flash-vl'
101
+ | 'inclusionai/ling-3.1-flash'
102
+ | 'inclusionai/ling-3.1-flash-free'
101
103
  | 'inference-net/schematron-v2-small'
102
104
  | 'inference-net/schematron-v2-turbo'
103
105
  | 'interfaze/interfaze-beta'
@@ -197,6 +199,8 @@ export type GatewayModelId =
197
199
  | 'openai/gpt-6-luna-fast'
198
200
  | 'openai/gpt-6-sol'
199
201
  | 'openai/gpt-6-sol-fast'
202
+ | 'openai/gpt-6.1-sol'
203
+ | 'openai/gpt-6.1-sol-fast'
200
204
  | 'openai/gpt-oss-120b'
201
205
  | 'openai/gpt-oss-20b'
202
206
  | 'openai/gpt-oss-safeguard-120b'
@@ -84,6 +84,7 @@ export class GatewaySpeechModel implements SpeechModelV4 {
84
84
  return {
85
85
  audio: responseBody.audio,
86
86
  warnings: (responseBody.warnings ?? []) as Array<SharedV4Warning>,
87
+ ...(responseBody.usage != null && { usage: responseBody.usage }),
87
88
  providerMetadata:
88
89
  responseBody.providerMetadata as SharedV4ProviderMetadata,
89
90
  response: {
@@ -140,6 +141,7 @@ const gatewaySpeechWarningSchema = z.discriminatedUnion('type', [
140
141
  const gatewaySpeechResponseSchema = z.object({
141
142
  audio: z.string(),
142
143
  warnings: z.array(gatewaySpeechWarningSchema).optional(),
144
+ usage: z.record(z.string(), z.json()).optional(),
143
145
  providerMetadata: z
144
146
  .record(z.string(), providerMetadataEntrySchema)
145
147
  .optional(),
@@ -105,6 +105,7 @@ export class GatewayTranscriptionModel implements TranscriptionModelV4 {
105
105
  language: responseBody.language ?? undefined,
106
106
  durationInSeconds: responseBody.durationInSeconds ?? undefined,
107
107
  warnings: (responseBody.warnings ?? []) as Array<SharedV4Warning>,
108
+ ...(responseBody.usage != null && { usage: responseBody.usage }),
108
109
  providerMetadata:
109
110
  responseBody.providerMetadata as SharedV4ProviderMetadata,
110
111
  response: {
@@ -433,6 +434,7 @@ const gatewayTranscriptionResponseSchema = z.object({
433
434
  language: z.string().nullish(),
434
435
  durationInSeconds: z.number().nullish(),
435
436
  warnings: z.array(gatewayTranscriptionWarningSchema).optional(),
437
+ usage: z.record(z.string(), z.json()).optional(),
436
438
  providerMetadata: z
437
439
  .record(z.string(), providerMetadataEntrySchema)
438
440
  .optional(),
package/src/zod.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  discriminatedUnion,
6
6
  enum as enumType,
7
7
  literal,
8
+ json,
8
9
  number,
9
10
  object,
10
11
  record,
@@ -22,6 +23,7 @@ export const z = {
22
23
  discriminatedUnion,
23
24
  enum: enumType,
24
25
  literal,
26
+ json,
25
27
  number,
26
28
  object,
27
29
  record,