@ai-sdk/openai 4.0.19 → 4.0.20

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.
@@ -457,6 +457,68 @@ metadata on tool-call parts. The SDK uses `providerMetadata.openai.namespace` or
457
457
  `providerOptions.openai.namespace` to round-trip the namespace back to OpenAI on
458
458
  subsequent requests.
459
459
 
460
+ #### Programmatic Tool Calling
461
+
462
+ OpenAI Programmatic Tool Calling lets supported Responses models generate and run
463
+ hosted JavaScript that coordinates client-side function tools. Add the hosted tool
464
+ with `openai.tools.programmaticToolCalling()`, then opt each eligible function into
465
+ programmatic calls with `allowedCallers`.
466
+
467
+ ```ts
468
+ import { openai, type OpenAIToolOptions } from '@ai-sdk/openai';
469
+ import { generateText, isStepCount, tool } from 'ai';
470
+ import { z } from 'zod';
471
+
472
+ const result = await generateText({
473
+ model: openai('gpt-5.6'),
474
+ stopWhen: isStepCount(10),
475
+ prompt: 'Compare inventory with demand for sku_123.',
476
+ tools: {
477
+ program: openai.tools.programmaticToolCalling(),
478
+ getInventory: tool({
479
+ description: 'Get available inventory for a SKU.',
480
+ inputSchema: z.object({ sku: z.string() }),
481
+ execute: async ({ sku }) => ({ sku, availableUnits: 42 }),
482
+ providerOptions: {
483
+ openai: {
484
+ allowedCallers: ['programmatic'],
485
+ outputSchema: {
486
+ type: 'object',
487
+ properties: {
488
+ sku: { type: 'string' },
489
+ availableUnits: { type: 'number' },
490
+ },
491
+ required: ['sku', 'availableUnits'],
492
+ additionalProperties: false,
493
+ },
494
+ } satisfies OpenAIToolOptions,
495
+ },
496
+ }),
497
+ },
498
+ });
499
+ ```
500
+
501
+ `allowedCallers` supports:
502
+
503
+ - `['direct']` (or omitted): only direct model tool calls
504
+ - `['programmatic']`: only calls from hosted JavaScript
505
+ - `['direct', 'programmatic']`: both invocation modes
506
+
507
+ Use `outputSchema` to describe the JSON value returned by the function. This schema
508
+ is sent to OpenAI as `output_schema` so generated JavaScript can safely use the
509
+ returned fields. It does not replace the tool's AI SDK output validation or execution
510
+ logic.
511
+
512
+ The provider preserves program code, replay fingerprints, program outputs, and nested
513
+ function caller metadata across the `generateText` and `streamText` tool loops,
514
+ including stateless requests with `store: false`. Programmatic invocation is
515
+ currently supported for AI SDK function tools; other OpenAI tool types remain
516
+ direct-only through this integration.
517
+
518
+ Treat generated programs and tool arguments as untrusted. Enforce authorization and
519
+ approval inside every tool, avoid programmatic access to side-effecting tools unless
520
+ the operation is idempotent, and set explicit step limits.
521
+
460
522
  #### Web Search Tool
461
523
 
462
524
  The OpenAI responses API supports web search through the `openai.tools.webSearch` tool.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/openai",
3
- "version": "4.0.19",
3
+ "version": "4.0.20",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ export type {
7
7
  /** @deprecated Use `OpenAILanguageModelResponsesOptions` instead. */
8
8
  OpenAILanguageModelResponsesOptions as OpenAIResponsesProviderOptions,
9
9
  } from './responses/openai-responses-language-model-options';
10
+ export type { OpenAIToolOptions } from './responses/openai-responses-prepare-tools';
10
11
  export type {
11
12
  OpenAILanguageModelChatOptions,
12
13
  /** @deprecated Use `OpenAILanguageModelChatOptions` instead. */
@@ -16,5 +16,6 @@ export * from '../tool/apply-patch';
16
16
  export * from '../tool/code-interpreter';
17
17
  export * from '../tool/file-search';
18
18
  export * from '../tool/image-generation';
19
+ export * from '../tool/programmatic-tool-calling';
19
20
  export * from '../tool/web-search';
20
21
  export * from '../tool/web-search-preview';
@@ -10,6 +10,7 @@ import { toolSearch } from './tool/tool-search';
10
10
  import { webSearch } from './tool/web-search';
11
11
  import { webSearchPreview } from './tool/web-search-preview';
12
12
  import { mcp } from './tool/mcp';
13
+ import { programmaticToolCalling } from './tool/programmatic-tool-calling';
13
14
 
14
15
  export const openaiTools = {
15
16
  /**
@@ -135,6 +136,12 @@ export const openaiTools = {
135
136
  */
136
137
  mcp,
137
138
 
139
+ /**
140
+ * Programmatic Tool Calling lets OpenAI Responses models write and execute
141
+ * JavaScript that orchestrates eligible tools.
142
+ */
143
+ programmaticToolCalling,
144
+
138
145
  /**
139
146
  * Tool search allows the model to dynamically search for and load deferred
140
147
  * tools into the model's context as needed. This helps reduce overall token
@@ -33,16 +33,34 @@ import type {
33
33
  OpenAIResponsesFunctionCallOutput,
34
34
  OpenAIResponsesInput,
35
35
  OpenAIResponsesReasoning,
36
+ OpenAIResponsesToolCaller,
36
37
  } from './openai-responses-api';
37
38
  import {
38
39
  toolSearchInputSchema,
39
40
  toolSearchOutputSchema,
40
41
  } from '../tool/tool-search';
42
+ import {
43
+ programmaticToolCallingInputSchema,
44
+ programmaticToolCallingOutputSchema,
45
+ } from '../tool/programmatic-tool-calling';
41
46
 
42
47
  function serializeToolCallArguments(input: unknown): string {
43
48
  return JSON.stringify(input === undefined ? {} : input);
44
49
  }
45
50
 
51
+ function mapToolCaller(
52
+ caller:
53
+ | { type: 'direct' }
54
+ | { type: 'program'; callerId: string }
55
+ | undefined,
56
+ ): OpenAIResponsesToolCaller | undefined {
57
+ return caller == null
58
+ ? undefined
59
+ : caller.type === 'program'
60
+ ? { type: 'program', caller_id: caller.callerId }
61
+ : caller;
62
+ }
63
+
46
64
  type OpenAIPromptCacheBreakpoint = { mode: 'explicit' };
47
65
 
48
66
  function getPromptCacheBreakpoint(
@@ -350,6 +368,11 @@ export async function convertToOpenAIResponsesInput({
350
368
  ).providerMetadata?.[providerOptionsName]?.namespace) as
351
369
  | string
352
370
  | undefined;
371
+ const caller = part.providerOptions?.[providerOptionsName]
372
+ ?.caller as
373
+ | { type: 'direct' }
374
+ | { type: 'program'; callerId: string }
375
+ | undefined;
353
376
 
354
377
  if (hasConversation && id != null) {
355
378
  break;
@@ -390,6 +413,27 @@ export async function convertToOpenAIResponsesInput({
390
413
  break;
391
414
  }
392
415
 
416
+ if (resolvedToolName === 'programmatic_tool_calling') {
417
+ if (store && id != null) {
418
+ input.push({ type: 'item_reference', id });
419
+ break;
420
+ }
421
+
422
+ const parsedInput = await validateTypes({
423
+ value: part.input,
424
+ schema: programmaticToolCallingInputSchema,
425
+ });
426
+
427
+ input.push({
428
+ type: 'program',
429
+ id: id ?? part.toolCallId,
430
+ call_id: part.toolCallId,
431
+ code: parsedInput.code,
432
+ fingerprint: parsedInput.fingerprint,
433
+ });
434
+ break;
435
+ }
436
+
393
437
  if (part.providerExecuted) {
394
438
  if (store && id != null) {
395
439
  input.push({ type: 'item_reference', id });
@@ -552,6 +596,9 @@ export async function convertToOpenAIResponsesInput({
552
596
  name: resolvedToolName,
553
597
  arguments: serializeToolCallArguments(part.input),
554
598
  ...(namespace != null && { namespace }),
599
+ ...(caller != null && {
600
+ caller: mapToolCaller(caller),
601
+ }),
555
602
  });
556
603
  break;
557
604
  }
@@ -613,6 +660,37 @@ export async function convertToOpenAIResponsesInput({
613
660
  break;
614
661
  }
615
662
 
663
+ if (resolvedResultToolName === 'programmatic_tool_calling') {
664
+ const itemId = (part.providerOptions?.[providerOptionsName]
665
+ ?.itemId ??
666
+ (
667
+ part as {
668
+ providerMetadata?: {
669
+ [providerOptionsName]?: { itemId?: string };
670
+ };
671
+ }
672
+ ).providerMetadata?.[providerOptionsName]?.itemId ??
673
+ part.toolCallId) as string;
674
+
675
+ if (store) {
676
+ input.push({ type: 'item_reference', id: itemId });
677
+ } else if (part.output.type === 'json') {
678
+ const parsedOutput = await validateTypes({
679
+ value: part.output.value,
680
+ schema: programmaticToolCallingOutputSchema,
681
+ });
682
+
683
+ input.push({
684
+ type: 'program_output',
685
+ id: itemId,
686
+ call_id: part.toolCallId,
687
+ result: parsedOutput.result,
688
+ status: parsedOutput.status,
689
+ });
690
+ }
691
+ break;
692
+ }
693
+
616
694
  /*
617
695
  * Shell tool results are separate output items (shell_call_output)
618
696
  * with their own item IDs distinct from the shell_call's item ID.
@@ -1163,10 +1241,18 @@ export async function convertToOpenAIResponsesInput({
1163
1241
  break;
1164
1242
  }
1165
1243
 
1244
+ const caller = mapToolCaller(
1245
+ part.providerOptions?.[providerOptionsName]?.caller as
1246
+ | { type: 'direct' }
1247
+ | { type: 'program'; callerId: string }
1248
+ | undefined,
1249
+ );
1250
+
1166
1251
  input.push({
1167
1252
  type: 'function_call_output',
1168
1253
  call_id: part.toolCallId,
1169
1254
  output: contentValue,
1255
+ ...(caller != null && { caller }),
1170
1256
  });
1171
1257
  }
1172
1258
 
@@ -84,6 +84,30 @@ const openaiResponsesComputerCallSchema = z.object({
84
84
  .nullish(),
85
85
  });
86
86
 
87
+ const openaiResponsesToolCallerSchema = z.discriminatedUnion('type', [
88
+ z.object({ type: z.literal('direct') }),
89
+ z.object({
90
+ type: z.literal('program'),
91
+ caller_id: z.string(),
92
+ }),
93
+ ]);
94
+
95
+ const openaiResponsesProgramSchema = z.object({
96
+ type: z.literal('program'),
97
+ id: z.string(),
98
+ call_id: z.string(),
99
+ code: z.string(),
100
+ fingerprint: z.string(),
101
+ });
102
+
103
+ const openaiResponsesProgramOutputSchema = z.object({
104
+ type: z.literal('program_output'),
105
+ id: z.string(),
106
+ call_id: z.string(),
107
+ result: z.string(),
108
+ status: z.enum(['completed', 'incomplete']),
109
+ });
110
+
87
111
  export type OpenAIResponsesInput = Array<OpenAIResponsesInputItem>;
88
112
 
89
113
  export type OpenAIResponsesInputItem =
@@ -92,6 +116,8 @@ export type OpenAIResponsesInputItem =
92
116
  | OpenAIResponsesAssistantMessage
93
117
  | OpenAIResponsesFunctionCall
94
118
  | OpenAIResponsesFunctionCallOutput
119
+ | OpenAIResponsesProgram
120
+ | OpenAIResponsesProgramOutput
95
121
  | OpenAIResponsesCustomToolCall
96
122
  | OpenAIResponsesCustomToolCallOutput
97
123
  | OpenAIResponsesMcpApprovalResponse
@@ -201,6 +227,7 @@ export type OpenAIResponsesFunctionCall = {
201
227
  arguments: string;
202
228
  id?: string;
203
229
  namespace?: string;
230
+ caller?: OpenAIResponsesToolCaller;
204
231
  };
205
232
 
206
233
  export type OpenAIResponsesFunctionCallOutput = {
@@ -231,6 +258,27 @@ export type OpenAIResponsesFunctionCallOutput = {
231
258
  prompt_cache_breakpoint?: { mode: 'explicit' };
232
259
  }
233
260
  >;
261
+ caller?: OpenAIResponsesToolCaller;
262
+ };
263
+
264
+ export type OpenAIResponsesToolCaller =
265
+ | { type: 'direct' }
266
+ | { type: 'program'; caller_id: string };
267
+
268
+ export type OpenAIResponsesProgram = {
269
+ type: 'program';
270
+ id: string;
271
+ call_id: string;
272
+ code: string;
273
+ fingerprint: string;
274
+ };
275
+
276
+ export type OpenAIResponsesProgramOutput = {
277
+ type: 'program_output';
278
+ id: string;
279
+ call_id: string;
280
+ result: string;
281
+ status: 'completed' | 'incomplete';
234
282
  };
235
283
 
236
284
  export type OpenAIResponsesCustomToolCall = {
@@ -428,6 +476,8 @@ export type OpenAIResponsesFunctionTool = {
428
476
  parameters: JSONSchema7;
429
477
  strict?: boolean;
430
478
  defer_loading?: boolean;
479
+ allowed_callers?: Array<'direct' | 'programmatic'>;
480
+ output_schema?: JSONSchema7;
431
481
  };
432
482
 
433
483
  export type OpenAIResponsesTool =
@@ -604,6 +654,9 @@ export type OpenAIResponsesTool =
604
654
  execution?: 'server' | 'client';
605
655
  description?: string;
606
656
  parameters?: Record<string, unknown>;
657
+ }
658
+ | {
659
+ type: 'programmatic_tool_calling';
607
660
  };
608
661
 
609
662
  export type OpenAIResponsesReasoning = {
@@ -761,7 +814,10 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
761
814
  name: z.string(),
762
815
  arguments: z.string(),
763
816
  namespace: z.string().nullish(),
817
+ caller: openaiResponsesToolCallerSchema.nullish(),
764
818
  }),
819
+ openaiResponsesProgramSchema,
820
+ openaiResponsesProgramOutputSchema,
765
821
  z.object({
766
822
  type: z.literal('web_search_call'),
767
823
  id: z.string(),
@@ -905,9 +961,12 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
905
961
  call_id: z.string(),
906
962
  name: z.string(),
907
963
  arguments: z.string(),
908
- status: z.literal('completed'),
964
+ status: z.enum(['in_progress', 'completed', 'incomplete']),
909
965
  namespace: z.string().nullish(),
966
+ caller: openaiResponsesToolCallerSchema.nullish(),
910
967
  }),
968
+ openaiResponsesProgramSchema,
969
+ openaiResponsesProgramOutputSchema,
911
970
  z.object({
912
971
  type: z.literal('custom_tool_call'),
913
972
  id: z.string(),
@@ -1413,7 +1472,10 @@ export const openaiResponsesResponseSchema = lazySchema(() =>
1413
1472
  arguments: z.string(),
1414
1473
  id: z.string(),
1415
1474
  namespace: z.string().nullish(),
1475
+ caller: openaiResponsesToolCallerSchema.nullish(),
1416
1476
  }),
1477
+ openaiResponsesProgramSchema,
1478
+ openaiResponsesProgramOutputSchema,
1417
1479
  z.object({
1418
1480
  type: z.literal('custom_tool_call'),
1419
1481
  call_id: z.string(),
@@ -48,6 +48,10 @@ import type {
48
48
  toolSearchInputSchema,
49
49
  toolSearchOutputSchema,
50
50
  } from '../tool/tool-search';
51
+ import type {
52
+ programmaticToolCallingInputSchema,
53
+ programmaticToolCallingOutputSchema,
54
+ } from '../tool/programmatic-tool-calling';
51
55
  import type { webSearchOutputSchema } from '../tool/web-search';
52
56
  import {
53
57
  convertOpenAIResponsesUsage,
@@ -313,6 +317,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
313
317
  'openai.mcp': 'mcp',
314
318
  'openai.apply_patch': 'apply_patch',
315
319
  'openai.tool_search': 'tool_search',
320
+ 'openai.programmatic_tool_calling': 'programmatic_tool_calling',
316
321
  },
317
322
  });
318
323
 
@@ -940,6 +945,56 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
940
945
  [providerOptionsName]: {
941
946
  itemId: part.id,
942
947
  ...(part.namespace != null && { namespace: part.namespace }),
948
+ ...(part.caller != null && {
949
+ caller:
950
+ part.caller.type === 'program'
951
+ ? {
952
+ type: 'program',
953
+ callerId: part.caller.caller_id,
954
+ }
955
+ : part.caller,
956
+ }),
957
+ },
958
+ },
959
+ });
960
+ break;
961
+ }
962
+
963
+ case 'program': {
964
+ content.push({
965
+ type: 'tool-call',
966
+ toolCallId: part.call_id,
967
+ toolName: toolNameMapping.toCustomToolName(
968
+ 'programmatic_tool_calling',
969
+ ),
970
+ input: JSON.stringify({
971
+ code: part.code,
972
+ fingerprint: part.fingerprint,
973
+ } satisfies InferSchema<typeof programmaticToolCallingInputSchema>),
974
+ providerExecuted: true,
975
+ providerMetadata: {
976
+ [providerOptionsName]: {
977
+ itemId: part.id,
978
+ },
979
+ },
980
+ });
981
+ break;
982
+ }
983
+
984
+ case 'program_output': {
985
+ content.push({
986
+ type: 'tool-result',
987
+ toolCallId: part.call_id,
988
+ toolName: toolNameMapping.toCustomToolName(
989
+ 'programmatic_tool_calling',
990
+ ),
991
+ result: {
992
+ result: part.result,
993
+ status: part.status,
994
+ } satisfies InferSchema<typeof programmaticToolCallingOutputSchema>,
995
+ providerMetadata: {
996
+ [providerOptionsName]: {
997
+ itemId: part.id,
943
998
  },
944
999
  },
945
1000
  });
@@ -1631,6 +1686,54 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
1631
1686
  ...(value.item.namespace != null && {
1632
1687
  namespace: value.item.namespace,
1633
1688
  }),
1689
+ ...(value.item.caller != null && {
1690
+ caller:
1691
+ value.item.caller.type === 'program'
1692
+ ? {
1693
+ type: 'program',
1694
+ callerId: value.item.caller.caller_id,
1695
+ }
1696
+ : value.item.caller,
1697
+ }),
1698
+ },
1699
+ },
1700
+ });
1701
+ } else if (value.item.type === 'program') {
1702
+ controller.enqueue({
1703
+ type: 'tool-call',
1704
+ toolCallId: value.item.call_id,
1705
+ toolName: toolNameMapping.toCustomToolName(
1706
+ 'programmatic_tool_calling',
1707
+ ),
1708
+ input: JSON.stringify({
1709
+ code: value.item.code,
1710
+ fingerprint: value.item.fingerprint,
1711
+ } satisfies InferSchema<
1712
+ typeof programmaticToolCallingInputSchema
1713
+ >),
1714
+ providerExecuted: true,
1715
+ providerMetadata: {
1716
+ [providerOptionsName]: {
1717
+ itemId: value.item.id,
1718
+ },
1719
+ },
1720
+ });
1721
+ } else if (value.item.type === 'program_output') {
1722
+ controller.enqueue({
1723
+ type: 'tool-result',
1724
+ toolCallId: value.item.call_id,
1725
+ toolName: toolNameMapping.toCustomToolName(
1726
+ 'programmatic_tool_calling',
1727
+ ),
1728
+ result: {
1729
+ result: value.item.result,
1730
+ status: value.item.status,
1731
+ } satisfies InferSchema<
1732
+ typeof programmaticToolCallingOutputSchema
1733
+ >,
1734
+ providerMetadata: {
1735
+ [providerOptionsName]: {
1736
+ itemId: value.item.id,
1634
1737
  },
1635
1738
  },
1636
1739
  });
@@ -1,5 +1,7 @@
1
1
  import {
2
2
  UnsupportedFunctionalityError,
3
+ type JSONSchema7,
4
+ type JSONObject,
3
5
  type LanguageModelV4CallOptions,
4
6
  type LanguageModelV4FunctionTool,
5
7
  type SharedV4ProviderReference,
@@ -24,8 +26,10 @@ import type {
24
26
  OpenAIResponsesTool,
25
27
  } from './openai-responses-api';
26
28
 
27
- type OpenAIToolOptions = {
29
+ export type OpenAIToolOptions = {
30
+ allowedCallers?: Array<'direct' | 'programmatic'>;
28
31
  deferLoading?: boolean;
32
+ outputSchema?: JSONObject;
29
33
  namespace?: {
30
34
  name: string;
31
35
  description: string;
@@ -63,6 +67,7 @@ export async function prepareResponsesTools({
63
67
  | { type: 'image_generation' }
64
68
  | { type: 'apply_patch' }
65
69
  | { type: 'computer' }
70
+ | { type: 'programmatic_tool_calling' }
66
71
  | {
67
72
  type: 'allowed_tools';
68
73
  mode: 'auto' | 'required';
@@ -312,6 +317,12 @@ export async function prepareResponsesTools({
312
317
  resolvedCustomProviderToolNames.add(tool.name);
313
318
  break;
314
319
  }
320
+ case 'openai.programmatic_tool_calling': {
321
+ openaiTools.push({
322
+ type: 'programmatic_tool_calling',
323
+ });
324
+ break;
325
+ }
315
326
  case 'openai.tool_search': {
316
327
  const args = await validateTypes({
317
328
  value: tool.args,
@@ -382,7 +393,8 @@ export async function prepareResponsesTools({
382
393
  resolvedToolName === 'web_search' ||
383
394
  resolvedToolName === 'mcp' ||
384
395
  resolvedToolName === 'apply_patch' ||
385
- resolvedToolName === 'computer'
396
+ resolvedToolName === 'computer' ||
397
+ resolvedToolName === 'programmatic_tool_calling'
386
398
  ? { type: resolvedToolName }
387
399
  : resolvedCustomProviderToolNames.has(resolvedToolName)
388
400
  ? { type: 'custom', name: resolvedToolName }
@@ -415,6 +427,12 @@ function prepareFunctionTool({
415
427
  parameters: tool.inputSchema,
416
428
  ...(tool.strict != null ? { strict: tool.strict } : {}),
417
429
  ...(deferLoading != null ? { defer_loading: deferLoading } : {}),
430
+ ...(options?.allowedCallers != null
431
+ ? { allowed_callers: options.allowedCallers }
432
+ : {}),
433
+ ...(options?.outputSchema != null
434
+ ? { output_schema: options.outputSchema as JSONSchema7 }
435
+ : {}),
418
436
  };
419
437
  }
420
438
 
@@ -0,0 +1,57 @@
1
+ import {
2
+ createProviderExecutedToolFactory,
3
+ lazySchema,
4
+ zodSchema,
5
+ } from '@ai-sdk/provider-utils';
6
+ import { z } from 'zod/v4';
7
+
8
+ export const programmaticToolCallingInputSchema = lazySchema(() =>
9
+ zodSchema(
10
+ z.object({
11
+ code: z.string(),
12
+ fingerprint: z.string(),
13
+ }),
14
+ ),
15
+ );
16
+
17
+ export const programmaticToolCallingOutputSchema = lazySchema(() =>
18
+ zodSchema(
19
+ z.object({
20
+ result: z.string(),
21
+ status: z.enum(['completed', 'incomplete']),
22
+ }),
23
+ ),
24
+ );
25
+
26
+ const programmaticToolCallingFactory = createProviderExecutedToolFactory<
27
+ {
28
+ /**
29
+ * JavaScript source generated and executed by OpenAI.
30
+ */
31
+ code: string;
32
+
33
+ /**
34
+ * Opaque replay fingerprint that must be preserved across requests.
35
+ */
36
+ fingerprint: string;
37
+ },
38
+ {
39
+ /**
40
+ * The result emitted by the hosted JavaScript program.
41
+ */
42
+ result: string;
43
+
44
+ /**
45
+ * Whether the program completed or stopped before producing a final result.
46
+ */
47
+ status: 'completed' | 'incomplete';
48
+ },
49
+ {}
50
+ >({
51
+ id: 'openai.programmatic_tool_calling',
52
+ inputSchema: programmaticToolCallingInputSchema,
53
+ outputSchema: programmaticToolCallingOutputSchema,
54
+ supportsDeferredResults: true,
55
+ });
56
+
57
+ export const programmaticToolCalling = () => programmaticToolCallingFactory({});