@ai-sdk/openai 3.0.130 → 3.0.132

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.
@@ -6,65 +6,79 @@ import {
6
6
  } from '@ai-sdk/provider-utils';
7
7
  import { z } from 'zod/v4';
8
8
 
9
- const jsonValueSchema: z.ZodType<JSONValue> = z.lazy(() =>
10
- z.union([
11
- z.string(),
12
- z.number(),
13
- z.boolean(),
14
- z.null(),
15
- z.array(jsonValueSchema),
16
- z.record(z.string(), jsonValueSchema.optional()),
17
- ]),
18
- );
9
+ let cachedJsonValueSchema: z.ZodType<JSONValue> | undefined;
10
+ const jsonValueSchema = (): z.ZodType<JSONValue> =>
11
+ (cachedJsonValueSchema ??= z.lazy(() =>
12
+ z.union([
13
+ z.string(),
14
+ z.number(),
15
+ z.boolean(),
16
+ z.null(),
17
+ z.array(jsonValueSchema()),
18
+ z.record(z.string(), jsonValueSchema().optional()),
19
+ ]),
20
+ ));
19
21
 
20
- const jsonObjectSchema = z.record(z.string(), jsonValueSchema.optional());
22
+ const jsonObjectSchema = () =>
23
+ z.record(z.string(), jsonValueSchema().optional());
21
24
 
22
- const openaiResponsesUsageSchema = z.intersection(
23
- jsonObjectSchema,
24
- z.object({
25
- input_tokens: z.number(),
26
- input_tokens_details: z
27
- .intersection(
28
- jsonObjectSchema,
29
- z.object({
30
- cached_tokens: z.number().nullish(),
31
- cache_write_tokens: z.number().nullish(),
32
- orchestration_input_tokens: z.number().nullish(),
33
- orchestration_input_cached_tokens: z.number().nullish(),
34
- }),
35
- )
36
- .nullish(),
37
- output_tokens: z.number(),
38
- output_tokens_details: z
39
- .intersection(
40
- jsonObjectSchema,
41
- z.object({
42
- reasoning_tokens: z.number().nullish(),
43
- orchestration_output_tokens: z.number().nullish(),
44
- }),
45
- )
46
- .nullish(),
47
- total_tokens: z.number().optional(),
48
- }),
49
- );
25
+ const openaiResponsesUsageSchema = () =>
26
+ z.intersection(
27
+ jsonObjectSchema(),
28
+ z.object({
29
+ input_tokens: z.number(),
30
+ input_tokens_details: z
31
+ .intersection(
32
+ jsonObjectSchema(),
33
+ z.object({
34
+ cached_tokens: z.number().nullish(),
35
+ cache_write_tokens: z.number().nullish(),
36
+ cache_write_tokens_details: z
37
+ .intersection(
38
+ jsonObjectSchema(),
39
+ z.object({
40
+ ttl_30m_tokens: z.number().nullish(),
41
+ ttl_12h_tokens: z.number().nullish(),
42
+ }),
43
+ )
44
+ .nullish(),
45
+ orchestration_input_tokens: z.number().nullish(),
46
+ orchestration_input_cached_tokens: z.number().nullish(),
47
+ }),
48
+ )
49
+ .nullish(),
50
+ output_tokens: z.number(),
51
+ output_tokens_details: z
52
+ .intersection(
53
+ jsonObjectSchema(),
54
+ z.object({
55
+ reasoning_tokens: z.number().nullish(),
56
+ orchestration_output_tokens: z.number().nullish(),
57
+ }),
58
+ )
59
+ .nullish(),
60
+ total_tokens: z.number().optional(),
61
+ }),
62
+ );
50
63
 
51
64
  function isRecord(value: unknown): value is Record<string, unknown> {
52
65
  return value != null && typeof value === 'object' && !Array.isArray(value);
53
66
  }
54
67
 
55
- const openaiResponsesLocalShellCallSchema = z.object({
56
- type: z.literal('local_shell_call'),
57
- id: z.string(),
58
- call_id: z.string(),
59
- action: z.object({
60
- type: z.literal('exec'),
61
- command: z.array(z.string()),
62
- timeout_ms: z.number().optional(),
63
- user: z.string().optional(),
64
- working_directory: z.string().optional(),
65
- env: z.record(z.string(), z.string()).optional(),
66
- }),
67
- });
68
+ const openaiResponsesLocalShellCallSchema = () =>
69
+ z.object({
70
+ type: z.literal('local_shell_call'),
71
+ id: z.string(),
72
+ call_id: z.string(),
73
+ action: z.object({
74
+ type: z.literal('exec'),
75
+ command: z.array(z.string()),
76
+ timeout_ms: z.number().optional(),
77
+ user: z.string().optional(),
78
+ working_directory: z.string().optional(),
79
+ env: z.record(z.string(), z.string()).optional(),
80
+ }),
81
+ });
68
82
 
69
83
  export type OpenAIResponsesInput = Array<OpenAIResponsesInputItem>;
70
84
 
@@ -121,6 +135,11 @@ export type OpenAIResponsesApplyPatchOperationDiffDoneChunk = {
121
135
  diff: string;
122
136
  };
123
137
 
138
+ export type OpenAIResponsesPromptCacheBreakpoint = {
139
+ mode: 'explicit';
140
+ ttl?: '30m' | '12h';
141
+ };
142
+
124
143
  export type OpenAIResponsesSystemMessage = {
125
144
  type?: 'message';
126
145
  role: 'system' | 'developer';
@@ -129,7 +148,7 @@ export type OpenAIResponsesSystemMessage = {
129
148
  | Array<{
130
149
  type: 'input_text';
131
150
  text: string;
132
- prompt_cache_breakpoint?: { mode: 'explicit' };
151
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
133
152
  }>;
134
153
  };
135
154
 
@@ -140,33 +159,33 @@ export type OpenAIResponsesUserMessage = {
140
159
  | {
141
160
  type: 'input_text';
142
161
  text: string;
143
- prompt_cache_breakpoint?: { mode: 'explicit' };
162
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
144
163
  }
145
164
  | {
146
165
  type: 'input_image';
147
166
  image_url: string;
148
- prompt_cache_breakpoint?: { mode: 'explicit' };
167
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
149
168
  }
150
169
  | {
151
170
  type: 'input_image';
152
171
  file_id: string;
153
- prompt_cache_breakpoint?: { mode: 'explicit' };
172
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
154
173
  }
155
174
  | {
156
175
  type: 'input_file';
157
176
  file_url: string;
158
- prompt_cache_breakpoint?: { mode: 'explicit' };
177
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
159
178
  }
160
179
  | {
161
180
  type: 'input_file';
162
181
  filename: string;
163
182
  file_data: string;
164
- prompt_cache_breakpoint?: { mode: 'explicit' };
183
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
165
184
  }
166
185
  | {
167
186
  type: 'input_file';
168
187
  file_id: string;
169
- prompt_cache_breakpoint?: { mode: 'explicit' };
188
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
170
189
  }
171
190
  >;
172
191
  };
@@ -198,33 +217,33 @@ export type OpenAIResponsesFunctionCallOutput = {
198
217
  | {
199
218
  type: 'input_text';
200
219
  text: string;
201
- prompt_cache_breakpoint?: { mode: 'explicit' };
220
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
202
221
  }
203
222
  | {
204
223
  type: 'input_image';
205
224
  image_url: string;
206
- prompt_cache_breakpoint?: { mode: 'explicit' };
225
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
207
226
  }
208
227
  | {
209
228
  type: 'input_image';
210
229
  file_id: string;
211
- prompt_cache_breakpoint?: { mode: 'explicit' };
230
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
212
231
  }
213
232
  | {
214
233
  type: 'input_file';
215
234
  filename: string;
216
235
  file_data: string;
217
- prompt_cache_breakpoint?: { mode: 'explicit' };
236
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
218
237
  }
219
238
  | {
220
239
  type: 'input_file';
221
240
  file_url: string;
222
- prompt_cache_breakpoint?: { mode: 'explicit' };
241
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
223
242
  }
224
243
  | {
225
244
  type: 'input_file';
226
245
  file_id: string;
227
- prompt_cache_breakpoint?: { mode: 'explicit' };
246
+ prompt_cache_breakpoint?: OpenAIResponsesPromptCacheBreakpoint;
228
247
  }
229
248
  >;
230
249
  };
@@ -264,7 +283,7 @@ export type OpenAIResponsesComputerCall = {
264
283
  };
265
284
 
266
285
  export type OpenAIResponsesLocalShellCall = InferSchema<
267
- typeof openaiResponsesLocalShellCallSchema
286
+ ReturnType<typeof openaiResponsesLocalShellCallSchema>
268
287
  >;
269
288
 
270
289
  export type OpenAIResponsesLocalShellCallOutput = {
@@ -615,27 +634,29 @@ export type OpenAIResponsesConfigurationUpdate = {
615
634
  // Captured from the Responses API when OpenAI returned an early
616
635
  // insufficient_quota stream error after HTTP 200. This shape differs from the
617
636
  // currently documented ResponseErrorEvent below.
618
- const openaiResponsesNestedErrorChunkSchema = z.object({
619
- type: z.literal('error'),
620
- sequence_number: z.number(),
621
- error: z.object({
622
- type: z.string(),
623
- code: z.string().nullish(),
624
- message: z.string(),
625
- param: z.string().nullish(),
626
- }),
627
- });
637
+ const openaiResponsesNestedErrorChunkSchema = () =>
638
+ z.object({
639
+ type: z.literal('error'),
640
+ sequence_number: z.number(),
641
+ error: z.object({
642
+ type: z.string(),
643
+ code: z.string().nullish(),
644
+ message: z.string(),
645
+ param: z.string().nullish(),
646
+ }),
647
+ });
628
648
 
629
649
  // Current OpenAI OpenAPI docs define ResponseErrorEvent with top-level
630
650
  // code/message/param fields:
631
651
  // https://developers.openai.com/api/reference/resources/responses/streaming-events
632
- const openaiResponsesErrorChunkSchema = z.object({
633
- type: z.literal('error'),
634
- sequence_number: z.number(),
635
- code: z.string().nullish(),
636
- message: z.string(),
637
- param: z.string().nullish(),
638
- });
652
+ const openaiResponsesErrorChunkSchema = () =>
653
+ z.object({
654
+ type: z.literal('error'),
655
+ sequence_number: z.number(),
656
+ code: z.string().nullish(),
657
+ message: z.string(),
658
+ param: z.string().nullish(),
659
+ });
639
660
 
640
661
  /**
641
662
  * Chunk types explicitly modeled by openaiResponsesChunkSchema. Keep this set
@@ -739,7 +760,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
739
760
  type: z.enum(['response.completed', 'response.incomplete']),
740
761
  response: z.object({
741
762
  incomplete_details: z.object({ reason: z.string() }).nullish(),
742
- usage: openaiResponsesUsageSchema.nullish(),
763
+ usage: openaiResponsesUsageSchema().nullish(),
743
764
  reasoning: z
744
765
  .object({
745
766
  context: z.string().nullish(),
@@ -759,7 +780,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
759
780
  })
760
781
  .nullish(),
761
782
  incomplete_details: z.object({ reason: z.string() }).nullish(),
762
- usage: openaiResponsesUsageSchema.nullish(),
783
+ usage: openaiResponsesUsageSchema().nullish(),
763
784
  reasoning: z
764
785
  .object({
765
786
  context: z.string().nullish(),
@@ -814,7 +835,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
814
835
  type: z.literal('file_search_call'),
815
836
  id: z.string(),
816
837
  }),
817
- openaiResponsesLocalShellCallSchema,
838
+ openaiResponsesLocalShellCallSchema(),
818
839
  z.object({
819
840
  type: z.literal('image_generation_call'),
820
841
  id: z.string(),
@@ -920,7 +941,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
920
941
  execution: z.enum(['server', 'client']),
921
942
  call_id: z.string().nullable(),
922
943
  status: z.enum(['in_progress', 'completed', 'incomplete']),
923
- tools: z.array(z.record(z.string(), jsonValueSchema.optional())),
944
+ tools: z.array(z.record(z.string(), jsonValueSchema().optional())),
924
945
  }),
925
946
  ]),
926
947
  }),
@@ -1026,7 +1047,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
1026
1047
  )
1027
1048
  .nullish(),
1028
1049
  }),
1029
- openaiResponsesLocalShellCallSchema,
1050
+ openaiResponsesLocalShellCallSchema(),
1030
1051
  z.object({
1031
1052
  type: z.literal('computer_call'),
1032
1053
  id: z.string(),
@@ -1151,7 +1172,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
1151
1172
  execution: z.enum(['server', 'client']),
1152
1173
  call_id: z.string().nullable(),
1153
1174
  status: z.enum(['in_progress', 'completed', 'incomplete']),
1154
- tools: z.array(z.record(z.string(), jsonValueSchema.optional())),
1175
+ tools: z.array(z.record(z.string(), jsonValueSchema().optional())),
1155
1176
  }),
1156
1177
  ]),
1157
1178
  }),
@@ -1253,8 +1274,8 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
1253
1274
  output_index: z.number(),
1254
1275
  diff: z.string(),
1255
1276
  }),
1256
- openaiResponsesNestedErrorChunkSchema,
1257
- openaiResponsesErrorChunkSchema,
1277
+ openaiResponsesNestedErrorChunkSchema(),
1278
+ openaiResponsesErrorChunkSchema(),
1258
1279
  z
1259
1280
  .object({ type: z.string() })
1260
1281
  .loose()
@@ -1432,7 +1453,7 @@ export const openaiResponsesResponseSchema = lazySchema(() =>
1432
1453
  id: z.string(),
1433
1454
  result: z.string(),
1434
1455
  }),
1435
- openaiResponsesLocalShellCallSchema,
1456
+ openaiResponsesLocalShellCallSchema(),
1436
1457
  z.object({
1437
1458
  type: z.literal('function_call'),
1438
1459
  call_id: z.string(),
@@ -1585,7 +1606,9 @@ export const openaiResponsesResponseSchema = lazySchema(() =>
1585
1606
  execution: z.enum(['server', 'client']),
1586
1607
  call_id: z.string().nullable(),
1587
1608
  status: z.enum(['in_progress', 'completed', 'incomplete']),
1588
- tools: z.array(z.record(z.string(), jsonValueSchema.optional())),
1609
+ tools: z.array(
1610
+ z.record(z.string(), jsonValueSchema().optional()),
1611
+ ),
1589
1612
  }),
1590
1613
  ]),
1591
1614
  )
@@ -1597,7 +1620,7 @@ export const openaiResponsesResponseSchema = lazySchema(() =>
1597
1620
  })
1598
1621
  .nullish(),
1599
1622
  incomplete_details: z.object({ reason: z.string() }).nullish(),
1600
- usage: openaiResponsesUsageSchema.nullish(),
1623
+ usage: openaiResponsesUsageSchema().nullish(),
1601
1624
  }),
1602
1625
  ),
1603
1626
  );
@@ -271,6 +271,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
271
271
  toolNameMapping,
272
272
  customProviderToolNames,
273
273
  supportsAsyncToolCalling: modelCapabilities.supportsAsyncToolCalling,
274
+ providerOptionsName,
274
275
  });
275
276
 
276
277
  const configurationUpdateUnsupportedReason =
@@ -241,12 +241,14 @@ export const openaiLanguageModelResponsesOptionsSchema = lazySchema(() =>
241
241
  /**
242
242
  * Prompt cache behavior for GPT-5.6 and later models.
243
243
  * `mode` controls whether OpenAI also places an implicit breakpoint.
244
- * `ttl` sets the minimum cache lifetime and currently only supports 30 minutes.
244
+ * `ttl` sets the minimum cache lifetime: `'30m'` (default) or `'12h'`.
245
+ * `prewarm` writes the prompt to the cache without generating output.
245
246
  */
246
247
  promptCacheOptions: z
247
248
  .object({
248
249
  mode: z.enum(['implicit', 'explicit']).optional(),
249
- ttl: z.literal('30m').optional(),
250
+ ttl: z.enum(['30m', '12h']).optional(),
251
+ prewarm: z.boolean().optional(),
250
252
  })
251
253
  .optional(),
252
254
 
@@ -44,6 +44,7 @@ export async function prepareResponsesTools({
44
44
  toolNameMapping,
45
45
  customProviderToolNames,
46
46
  supportsAsyncToolCalling = true,
47
+ providerOptionsName = 'openai',
47
48
  }: {
48
49
  tools: LanguageModelV3CallOptions['tools'];
49
50
  toolChoice: LanguageModelV3CallOptions['toolChoice'] | undefined;
@@ -54,6 +55,7 @@ export async function prepareResponsesTools({
54
55
  toolNameMapping?: ToolNameMapping;
55
56
  customProviderToolNames?: Set<string>;
56
57
  supportsAsyncToolCalling?: boolean;
58
+ providerOptionsName?: string;
57
59
  }): Promise<{
58
60
  tools?: Array<OpenAIResponsesTool>;
59
61
  toolChoice?:
@@ -125,9 +127,8 @@ export async function prepareResponsesTools({
125
127
  for (const tool of tools) {
126
128
  switch (tool.type) {
127
129
  case 'function': {
128
- const openaiOptions = tool.providerOptions?.openai as
129
- | OpenAIToolOptions
130
- | undefined;
130
+ const openaiOptions = (tool.providerOptions?.[providerOptionsName] ??
131
+ tool.providerOptions?.openai) as OpenAIToolOptions | undefined;
131
132
  const openaiFunctionTool = prepareFunctionTool({
132
133
  tool,
133
134
  options: openaiOptions,
@@ -9,18 +9,21 @@ import type {
9
9
  OpenAIResponsesFileSearchToolCompoundFilter,
10
10
  } from '../responses/openai-responses-api';
11
11
 
12
- const comparisonFilterSchema = z.object({
13
- key: z.string(),
14
- type: z.enum(['eq', 'ne', 'gt', 'gte', 'lt', 'lte', 'in', 'nin']),
15
- value: z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]),
16
- });
12
+ const comparisonFilterSchema = () =>
13
+ z.object({
14
+ key: z.string(),
15
+ type: z.enum(['eq', 'ne', 'gt', 'gte', 'lt', 'lte', 'in', 'nin']),
16
+ value: z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]),
17
+ });
17
18
 
18
- const compoundFilterSchema: z.ZodType<any> = z.object({
19
- type: z.enum(['and', 'or']),
20
- filters: z.array(
21
- z.union([comparisonFilterSchema, z.lazy(() => compoundFilterSchema)]),
22
- ),
23
- });
19
+ let cachedCompoundFilterSchema: z.ZodType<any> | undefined;
20
+ const compoundFilterSchema = (): z.ZodType<any> =>
21
+ (cachedCompoundFilterSchema ??= z.object({
22
+ type: z.enum(['and', 'or']),
23
+ filters: z.array(
24
+ z.union([comparisonFilterSchema(), z.lazy(() => compoundFilterSchema())]),
25
+ ),
26
+ }));
24
27
 
25
28
  export const fileSearchArgsSchema = lazySchema(() =>
26
29
  zodSchema(
@@ -34,7 +37,7 @@ export const fileSearchArgsSchema = lazySchema(() =>
34
37
  })
35
38
  .optional(),
36
39
  filters: z
37
- .union([comparisonFilterSchema, compoundFilterSchema])
40
+ .union([comparisonFilterSchema(), compoundFilterSchema()])
38
41
  .optional(),
39
42
  }),
40
43
  ),
package/src/tool/mcp.ts CHANGED
@@ -6,16 +6,18 @@ import {
6
6
  import type { JSONValue } from '@ai-sdk/provider';
7
7
  import { z } from 'zod/v4';
8
8
 
9
- const jsonValueSchema: z.ZodType<JSONValue> = z.lazy(() =>
10
- z.union([
11
- z.string(),
12
- z.number(),
13
- z.boolean(),
14
- z.null(),
15
- z.array(jsonValueSchema),
16
- z.record(z.string(), jsonValueSchema),
17
- ]),
18
- );
9
+ let cachedJsonValueSchema: z.ZodType<JSONValue> | undefined;
10
+ const jsonValueSchema = (): z.ZodType<JSONValue> =>
11
+ (cachedJsonValueSchema ??= z.lazy(() =>
12
+ z.union([
13
+ z.string(),
14
+ z.number(),
15
+ z.boolean(),
16
+ z.null(),
17
+ z.array(jsonValueSchema()),
18
+ z.record(z.string(), jsonValueSchema()),
19
+ ]),
20
+ ));
19
21
 
20
22
  export const mcpArgsSchema = lazySchema(() =>
21
23
  zodSchema(
@@ -67,7 +69,7 @@ export const mcpOutputSchema = lazySchema(() =>
67
69
  name: z.string(),
68
70
  arguments: z.string(),
69
71
  output: z.string().nullish(),
70
- error: z.union([z.string(), jsonValueSchema]).optional(),
72
+ error: z.union([z.string(), jsonValueSchema()]).optional(),
71
73
  }),
72
74
  ),
73
75
  );
package/src/tool/shell.ts CHANGED
@@ -34,27 +34,28 @@ export const shellOutputSchema = lazySchema(() =>
34
34
  ),
35
35
  );
36
36
 
37
- const shellSkillsSchema = z
38
- .array(
39
- z.discriminatedUnion('type', [
40
- z.object({
41
- type: z.literal('skillReference'),
42
- skillId: z.string(),
43
- version: z.string().optional(),
44
- }),
45
- z.object({
46
- type: z.literal('inline'),
47
- name: z.string(),
48
- description: z.string(),
49
- source: z.object({
50
- type: z.literal('base64'),
51
- mediaType: z.literal('application/zip'),
52
- data: z.string(),
37
+ const shellSkillsSchema = () =>
38
+ z
39
+ .array(
40
+ z.discriminatedUnion('type', [
41
+ z.object({
42
+ type: z.literal('skillReference'),
43
+ skillId: z.string(),
44
+ version: z.string().optional(),
53
45
  }),
54
- }),
55
- ]),
56
- )
57
- .optional();
46
+ z.object({
47
+ type: z.literal('inline'),
48
+ name: z.string(),
49
+ description: z.string(),
50
+ source: z.object({
51
+ type: z.literal('base64'),
52
+ mediaType: z.literal('application/zip'),
53
+ data: z.string(),
54
+ }),
55
+ }),
56
+ ]),
57
+ )
58
+ .optional();
58
59
 
59
60
  export const shellArgsSchema = lazySchema(() =>
60
61
  zodSchema(
@@ -83,7 +84,7 @@ export const shellArgsSchema = lazySchema(() =>
83
84
  }),
84
85
  ])
85
86
  .optional(),
86
- skills: shellSkillsSchema,
87
+ skills: shellSkillsSchema(),
87
88
  }),
88
89
  z.object({
89
90
  type: z.literal('containerReference'),