@ai-sdk/openai 4.0.41 → 4.0.43
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 +26 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +148 -11
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +21 -5
- package/dist/internal/index.js +147 -10
- package/dist/internal/index.js.map +1 -1
- package/docs/03-openai.mdx +93 -0
- package/package.json +3 -3
- package/src/responses/openai-responses-api.ts +21 -1
- package/src/responses/openai-responses-language-model-options.ts +6 -0
- package/src/responses/openai-responses-language-model.ts +7 -0
- package/src/responses/openai-responses-prepare-tools.ts +188 -5
package/docs/03-openai.mdx
CHANGED
|
@@ -264,6 +264,9 @@ The following provider options are available:
|
|
|
264
264
|
- `type`: `'compaction'`
|
|
265
265
|
- `compactThreshold`: _number_ — the token count at which compaction is triggered
|
|
266
266
|
|
|
267
|
+
- **compactionTrigger** _boolean_
|
|
268
|
+
Request explicit server-side compaction. When `true`, the provider appends a terminal `{ type: 'compaction_trigger' }` item to the Responses input. Support depends on the configured Responses-compatible endpoint and model.
|
|
269
|
+
|
|
267
270
|
The OpenAI responses provider also returns provider-specific metadata:
|
|
268
271
|
|
|
269
272
|
For Responses models, you can type this metadata using `OpenaiResponsesProviderMetadata`:
|
|
@@ -1400,6 +1403,64 @@ The custom tool can be configured with:
|
|
|
1400
1403
|
- **definition** _string_ - (grammar only) The grammar definition string (a regex pattern or Lark grammar).
|
|
1401
1404
|
- **execute** _function_ (optional) - An async function that receives the raw string input and returns a string result. Enables multi-turn tool calling.
|
|
1402
1405
|
|
|
1406
|
+
#### Restricting Callable Tools
|
|
1407
|
+
|
|
1408
|
+
The `allowedTools` provider option restricts which of the tools you declared the model is allowed to
|
|
1409
|
+
call, while still sending the full `tools` list to OpenAI. Because the tools list stays byte-identical
|
|
1410
|
+
across requests, the prompt cache is preserved — unlike `activeTools`, which removes tools from the
|
|
1411
|
+
request and invalidates the cache whenever the allow-list changes.
|
|
1412
|
+
|
|
1413
|
+
`allowedTools` is only supported by the Responses API, and it overrides the request-level `toolChoice`.
|
|
1414
|
+
|
|
1415
|
+
```ts
|
|
1416
|
+
import { openai } from '@ai-sdk/openai';
|
|
1417
|
+
import { generateText } from 'ai';
|
|
1418
|
+
|
|
1419
|
+
const result = await generateText({
|
|
1420
|
+
model: openai.responses('gpt-5.5'),
|
|
1421
|
+
tools: {
|
|
1422
|
+
weather: weatherTool,
|
|
1423
|
+
cityAttractions: cityAttractionsTool,
|
|
1424
|
+
search: openai.tools.webSearch(),
|
|
1425
|
+
},
|
|
1426
|
+
providerOptions: {
|
|
1427
|
+
openai: {
|
|
1428
|
+
allowedTools: { toolNames: ['weather', 'search'], mode: 'auto' },
|
|
1429
|
+
},
|
|
1430
|
+
},
|
|
1431
|
+
prompt: 'What is the weather in San Francisco?',
|
|
1432
|
+
});
|
|
1433
|
+
```
|
|
1434
|
+
|
|
1435
|
+
- **toolNames** _string[]_ - The tools the model may call, named as you declared them in `tools`. For
|
|
1436
|
+
provider-defined tools you may also use the canonical OpenAI name (for example `web_search`).
|
|
1437
|
+
- **mode** _'auto' | 'required'_ (optional) - `'auto'` (default) lets the model pick one of the allowed
|
|
1438
|
+
tools or answer with a message; `'required'` forces it to call at least one of them.
|
|
1439
|
+
|
|
1440
|
+
Both function tools and provider-defined tools can be allow-listed, including web search, file search,
|
|
1441
|
+
image generation, code interpreter, computer, apply patch, shell, programmatic tool calling, custom
|
|
1442
|
+
tools, and MCP servers.
|
|
1443
|
+
|
|
1444
|
+
If a name matches both a tool you declared and the canonical OpenAI name of a different tool, the tool
|
|
1445
|
+
you declared under that name wins, and a warning reports the ambiguity. If several tools share the same
|
|
1446
|
+
canonical name — two MCP servers, for example — that name is ambiguous, so it is dropped with a warning;
|
|
1447
|
+
name those tools as you declared them instead.
|
|
1448
|
+
|
|
1449
|
+
<Note>
|
|
1450
|
+
Three kinds of tools cannot be allow-listed, because OpenAI's `allowed_tools`
|
|
1451
|
+
only sees the eagerly-loaded tool list: the [tool search tool](#tool-search),
|
|
1452
|
+
tools marked with `deferLoading`, and tools grouped into a namespace. Naming
|
|
1453
|
+
one of these in `allowedTools` removes it from the allow-list and emits a
|
|
1454
|
+
warning; if that leaves no tools at all, the request fails with an error
|
|
1455
|
+
instead of silently sending no restriction.
|
|
1456
|
+
</Note>
|
|
1457
|
+
|
|
1458
|
+
<Note>
|
|
1459
|
+
An MCP server is allow-listed as a whole: the entry carries the server label,
|
|
1460
|
+
so every tool on that server is callable. To restrict which tools on a server
|
|
1461
|
+
the model may call, use the MCP tool's own `allowedTools` argument.
|
|
1462
|
+
</Note>
|
|
1463
|
+
|
|
1403
1464
|
#### Image Inputs
|
|
1404
1465
|
|
|
1405
1466
|
The OpenAI Responses API supports Image inputs for appropriate models.
|
|
@@ -1776,6 +1837,38 @@ const result = await generateText({
|
|
|
1776
1837
|
requests.
|
|
1777
1838
|
</Note>
|
|
1778
1839
|
|
|
1840
|
+
##### Explicit Compaction
|
|
1841
|
+
|
|
1842
|
+
For Responses-compatible endpoints that support explicit compaction, set
|
|
1843
|
+
`compactionTrigger: true`. The provider appends the required
|
|
1844
|
+
`{ type: 'compaction_trigger' }` request control after all converted messages
|
|
1845
|
+
and input items.
|
|
1846
|
+
|
|
1847
|
+
```ts highlight="9"
|
|
1848
|
+
import {
|
|
1849
|
+
openai,
|
|
1850
|
+
type OpenAILanguageModelResponsesOptions,
|
|
1851
|
+
} from '@ai-sdk/openai';
|
|
1852
|
+
import { generateText } from 'ai';
|
|
1853
|
+
|
|
1854
|
+
const result = await generateText({
|
|
1855
|
+
model: openai.responses('gpt-5.3-codex'),
|
|
1856
|
+
messages: conversationHistory,
|
|
1857
|
+
providerOptions: {
|
|
1858
|
+
openai: {
|
|
1859
|
+
store: false,
|
|
1860
|
+
compactionTrigger: true,
|
|
1861
|
+
} satisfies OpenAILanguageModelResponsesOptions,
|
|
1862
|
+
},
|
|
1863
|
+
});
|
|
1864
|
+
```
|
|
1865
|
+
|
|
1866
|
+
This is distinct from `contextManagement`, which configures automatic,
|
|
1867
|
+
threshold-based compaction. When omitted or `false`, `compactionTrigger` does
|
|
1868
|
+
not add an input item. The resulting compaction output uses the existing
|
|
1869
|
+
`openai.compaction` custom part representation. Endpoint and model support can
|
|
1870
|
+
vary.
|
|
1871
|
+
|
|
1779
1872
|
##### Detecting Compaction in Streams
|
|
1780
1873
|
|
|
1781
1874
|
When using `streamText`, you can detect compaction by checking the `providerMetadata` on `text-start` and `text-end` events:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/openai",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.43",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"tsup": "^8.5.1",
|
|
44
44
|
"typescript": "5.8.3",
|
|
45
45
|
"zod": "3.25.76",
|
|
46
|
-
"@
|
|
47
|
-
"@ai-
|
|
46
|
+
"@ai-sdk/test-server": "2.0.1",
|
|
47
|
+
"@vercel/ai-tsconfig": "0.0.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"zod": "^3.25.76 || ^4.1.8"
|
|
@@ -133,7 +133,8 @@ export type OpenAIResponsesInputItem =
|
|
|
133
133
|
| OpenAIResponsesToolSearchOutput
|
|
134
134
|
| OpenAIResponsesReasoning
|
|
135
135
|
| OpenAIResponsesItemReference
|
|
136
|
-
| OpenAIResponsesCompactionItem
|
|
136
|
+
| OpenAIResponsesCompactionItem
|
|
137
|
+
| OpenAIResponsesCompactionTrigger;
|
|
137
138
|
|
|
138
139
|
export type OpenAIResponsesIncludeValue =
|
|
139
140
|
| 'web_search_call.action.sources'
|
|
@@ -431,6 +432,10 @@ export type OpenAIResponsesCompactionItem = {
|
|
|
431
432
|
encrypted_content: string;
|
|
432
433
|
};
|
|
433
434
|
|
|
435
|
+
export type OpenAIResponsesCompactionTrigger = {
|
|
436
|
+
type: 'compaction_trigger';
|
|
437
|
+
};
|
|
438
|
+
|
|
434
439
|
/**
|
|
435
440
|
* A filter used to compare a specified attribute key to a given value using a defined comparison operation.
|
|
436
441
|
*/
|
|
@@ -480,6 +485,21 @@ export type OpenAIResponsesFunctionTool = {
|
|
|
480
485
|
output_schema?: JSONSchema7;
|
|
481
486
|
};
|
|
482
487
|
|
|
488
|
+
/**
|
|
489
|
+
* Entry in `tool_choice.allowed_tools.tools`. OpenAI identifies most built-in
|
|
490
|
+
* tools by type alone; only `function`, `custom` and `mcp` carry an identifier.
|
|
491
|
+
*/
|
|
492
|
+
export type OpenAIResponsesAllowedTool =
|
|
493
|
+
| { type: 'function'; name: string }
|
|
494
|
+
| { type: 'custom'; name: string }
|
|
495
|
+
| { type: 'mcp'; server_label: string }
|
|
496
|
+
| {
|
|
497
|
+
type: Exclude<
|
|
498
|
+
OpenAIResponsesTool['type'],
|
|
499
|
+
'function' | 'custom' | 'mcp' | 'namespace' | 'tool_search'
|
|
500
|
+
>;
|
|
501
|
+
};
|
|
502
|
+
|
|
483
503
|
export type OpenAIResponsesTool =
|
|
484
504
|
| OpenAIResponsesFunctionTool
|
|
485
505
|
| {
|
|
@@ -375,6 +375,12 @@ export const openaiLanguageModelResponsesOptionsSchema = lazySchema(() =>
|
|
|
375
375
|
)
|
|
376
376
|
.nullish(),
|
|
377
377
|
|
|
378
|
+
/**
|
|
379
|
+
* Request explicit server-side compaction by appending a
|
|
380
|
+
* `compaction_trigger` item to the Responses input.
|
|
381
|
+
*/
|
|
382
|
+
compactionTrigger: z.boolean().optional(),
|
|
383
|
+
|
|
378
384
|
/**
|
|
379
385
|
* Restrict the callable tools to a subset while keeping the full tools
|
|
380
386
|
* list intact, so prompt caching is preserved across requests with
|
|
@@ -369,6 +369,13 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
369
369
|
|
|
370
370
|
warnings.push(...inputWarnings);
|
|
371
371
|
|
|
372
|
+
// A compaction trigger is a request control, not conversation history.
|
|
373
|
+
// OpenAI requires it to be the final input item, so append it only after
|
|
374
|
+
// the complete prompt has been converted.
|
|
375
|
+
if (openaiOptions?.compactionTrigger) {
|
|
376
|
+
input.push({ type: 'compaction_trigger' });
|
|
377
|
+
}
|
|
378
|
+
|
|
372
379
|
const strictJsonSchema = openaiOptions?.strictJsonSchema ?? true;
|
|
373
380
|
|
|
374
381
|
let include: OpenAIResponsesIncludeOptions = openaiOptions?.include;
|
|
@@ -22,10 +22,15 @@ import { toolSearchArgsSchema } from '../tool/tool-search';
|
|
|
22
22
|
import { webSearchArgsSchema } from '../tool/web-search';
|
|
23
23
|
import { webSearchPreviewArgsSchema } from '../tool/web-search-preview';
|
|
24
24
|
import type {
|
|
25
|
+
OpenAIResponsesAllowedTool,
|
|
25
26
|
OpenAIResponsesFunctionTool,
|
|
26
27
|
OpenAIResponsesTool,
|
|
27
28
|
} from './openai-responses-api';
|
|
28
29
|
|
|
30
|
+
type AllowedToolResolution =
|
|
31
|
+
| { supported: true; entry: OpenAIResponsesAllowedTool }
|
|
32
|
+
| { supported: false; reason: string };
|
|
33
|
+
|
|
29
34
|
export type OpenAIToolOptions = {
|
|
30
35
|
allowedCallers?: Array<'direct' | 'programmatic'>;
|
|
31
36
|
deferLoading?: boolean;
|
|
@@ -73,7 +78,7 @@ export async function prepareResponsesTools({
|
|
|
73
78
|
| {
|
|
74
79
|
type: 'allowed_tools';
|
|
75
80
|
mode: 'auto' | 'required';
|
|
76
|
-
tools: Array<
|
|
81
|
+
tools: Array<OpenAIResponsesAllowedTool>;
|
|
77
82
|
};
|
|
78
83
|
toolWarnings: SharedV4Warning[];
|
|
79
84
|
}> {
|
|
@@ -94,6 +99,35 @@ export async function prepareResponsesTools({
|
|
|
94
99
|
const resolvedCustomProviderToolNames =
|
|
95
100
|
customProviderToolNames ?? new Set<string>();
|
|
96
101
|
|
|
102
|
+
const allowedToolResolutions = new Map<string, AllowedToolResolution>();
|
|
103
|
+
const allowedToolAliases = new Map<
|
|
104
|
+
string,
|
|
105
|
+
AllowedToolResolution | 'ambiguous'
|
|
106
|
+
>();
|
|
107
|
+
|
|
108
|
+
const recordAllowedTool = (
|
|
109
|
+
toolName: string,
|
|
110
|
+
resolution: AllowedToolResolution,
|
|
111
|
+
canonicalName: string | undefined,
|
|
112
|
+
) => {
|
|
113
|
+
allowedToolResolutions.set(toolName, resolution);
|
|
114
|
+
|
|
115
|
+
if (canonicalName == null || canonicalName === toolName) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const existingAlias = allowedToolAliases.get(canonicalName);
|
|
120
|
+
|
|
121
|
+
if (existingAlias == null) {
|
|
122
|
+
allowedToolAliases.set(canonicalName, resolution);
|
|
123
|
+
} else if (
|
|
124
|
+
existingAlias !== 'ambiguous' &&
|
|
125
|
+
!isSameAllowedTool(existingAlias, resolution)
|
|
126
|
+
) {
|
|
127
|
+
allowedToolAliases.set(canonicalName, 'ambiguous');
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
97
131
|
for (const tool of tools) {
|
|
98
132
|
switch (tool.type) {
|
|
99
133
|
case 'function': {
|
|
@@ -131,9 +165,32 @@ export async function prepareResponsesTools({
|
|
|
131
165
|
|
|
132
166
|
namespaceTool.tools.push(openaiFunctionTool);
|
|
133
167
|
}
|
|
168
|
+
|
|
169
|
+
recordAllowedTool(
|
|
170
|
+
tool.name,
|
|
171
|
+
namespace != null
|
|
172
|
+
? {
|
|
173
|
+
supported: false,
|
|
174
|
+
reason:
|
|
175
|
+
'tools inside an OpenAI tool namespace are not visible to tool_choice.allowed_tools',
|
|
176
|
+
}
|
|
177
|
+
: openaiOptions?.deferLoading === true
|
|
178
|
+
? {
|
|
179
|
+
supported: false,
|
|
180
|
+
reason:
|
|
181
|
+
'deferred tools are not visible to tool_choice.allowed_tools',
|
|
182
|
+
}
|
|
183
|
+
: {
|
|
184
|
+
supported: true,
|
|
185
|
+
entry: { type: 'function', name: tool.name },
|
|
186
|
+
},
|
|
187
|
+
undefined,
|
|
188
|
+
);
|
|
134
189
|
break;
|
|
135
190
|
}
|
|
136
191
|
case 'provider': {
|
|
192
|
+
const openaiToolCountBefore = openaiTools.length;
|
|
193
|
+
|
|
137
194
|
switch (tool.id) {
|
|
138
195
|
case 'openai.file_search': {
|
|
139
196
|
const args = await validateTypes({
|
|
@@ -349,6 +406,16 @@ export async function prepareResponsesTools({
|
|
|
349
406
|
break;
|
|
350
407
|
}
|
|
351
408
|
}
|
|
409
|
+
|
|
410
|
+
if (openaiTools.length > openaiToolCountBefore) {
|
|
411
|
+
const openaiTool = openaiTools[openaiToolCountBefore];
|
|
412
|
+
|
|
413
|
+
recordAllowedTool(
|
|
414
|
+
tool.name,
|
|
415
|
+
toAllowedToolResolution(openaiTool),
|
|
416
|
+
toolNameMapping?.toProviderToolName(tool.name),
|
|
417
|
+
);
|
|
418
|
+
}
|
|
352
419
|
break;
|
|
353
420
|
}
|
|
354
421
|
default:
|
|
@@ -361,15 +428,74 @@ export async function prepareResponsesTools({
|
|
|
361
428
|
}
|
|
362
429
|
|
|
363
430
|
if (allowedTools != null) {
|
|
431
|
+
const allowedToolEntries: Array<OpenAIResponsesAllowedTool> = [];
|
|
432
|
+
const droppedToolNames: string[] = [];
|
|
433
|
+
|
|
434
|
+
for (const name of allowedTools.toolNames) {
|
|
435
|
+
const directResolution = allowedToolResolutions.get(name);
|
|
436
|
+
const resolution = directResolution ?? allowedToolAliases.get(name);
|
|
437
|
+
|
|
438
|
+
if (directResolution != null && allowedToolAliases.has(name)) {
|
|
439
|
+
toolWarnings.push({
|
|
440
|
+
type: 'unsupported',
|
|
441
|
+
feature: `allowedTools entry "${name}"`,
|
|
442
|
+
details:
|
|
443
|
+
'this name is both a tool name and the provider tool name of another tool in this request; the tool with this name is allowed',
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (resolution === 'ambiguous') {
|
|
448
|
+
toolWarnings.push({
|
|
449
|
+
type: 'unsupported',
|
|
450
|
+
feature: `allowedTools entry "${name}"`,
|
|
451
|
+
details:
|
|
452
|
+
'several tools in this request share this provider tool name; use the tool name from the tools for this request instead',
|
|
453
|
+
});
|
|
454
|
+
droppedToolNames.push(name);
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (resolution == null) {
|
|
459
|
+
toolWarnings.push({
|
|
460
|
+
type: 'unsupported',
|
|
461
|
+
feature: `allowedTools entry "${name}"`,
|
|
462
|
+
details:
|
|
463
|
+
'the tool is not part of the tools for this request and is sent as a function tool',
|
|
464
|
+
});
|
|
465
|
+
allowedToolEntries.push({
|
|
466
|
+
type: 'function',
|
|
467
|
+
name: toolNameMapping?.toProviderToolName(name) ?? name,
|
|
468
|
+
});
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (!resolution.supported) {
|
|
473
|
+
toolWarnings.push({
|
|
474
|
+
type: 'unsupported',
|
|
475
|
+
feature: `allowedTools entry "${name}"`,
|
|
476
|
+
details: `${resolution.reason}; the tool is removed from the allowed tools`,
|
|
477
|
+
});
|
|
478
|
+
droppedToolNames.push(name);
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
allowedToolEntries.push(resolution.entry);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (allowedToolEntries.length === 0) {
|
|
486
|
+
throw new UnsupportedFunctionalityError({
|
|
487
|
+
functionality: `allowedTools with only tools that cannot be allow-listed (${droppedToolNames.join(
|
|
488
|
+
', ',
|
|
489
|
+
)})`,
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
|
|
364
493
|
return {
|
|
365
494
|
tools: openaiTools,
|
|
366
495
|
toolChoice: {
|
|
367
496
|
type: 'allowed_tools',
|
|
368
497
|
mode: allowedTools.mode ?? 'auto',
|
|
369
|
-
tools:
|
|
370
|
-
type: 'function',
|
|
371
|
-
name: toolNameMapping?.toProviderToolName(name) ?? name,
|
|
372
|
-
})),
|
|
498
|
+
tools: allowedToolEntries,
|
|
373
499
|
},
|
|
374
500
|
toolWarnings,
|
|
375
501
|
};
|
|
@@ -419,6 +545,63 @@ export async function prepareResponsesTools({
|
|
|
419
545
|
}
|
|
420
546
|
}
|
|
421
547
|
|
|
548
|
+
function allowedToolKey(entry: OpenAIResponsesAllowedTool): string {
|
|
549
|
+
switch (entry.type) {
|
|
550
|
+
case 'mcp':
|
|
551
|
+
return `mcp:${entry.server_label}`;
|
|
552
|
+
case 'function':
|
|
553
|
+
case 'custom':
|
|
554
|
+
return `${entry.type}:${entry.name}`;
|
|
555
|
+
default:
|
|
556
|
+
return entry.type;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
function isSameAllowedTool(
|
|
561
|
+
a: AllowedToolResolution,
|
|
562
|
+
b: AllowedToolResolution,
|
|
563
|
+
): boolean {
|
|
564
|
+
if (a.supported && b.supported) {
|
|
565
|
+
return allowedToolKey(a.entry) === allowedToolKey(b.entry);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
if (!a.supported && !b.supported) {
|
|
569
|
+
return a.reason === b.reason;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
return false;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
function toAllowedToolResolution(
|
|
576
|
+
tool: OpenAIResponsesTool,
|
|
577
|
+
): AllowedToolResolution {
|
|
578
|
+
switch (tool.type) {
|
|
579
|
+
case 'custom':
|
|
580
|
+
return { supported: true, entry: { type: 'custom', name: tool.name } };
|
|
581
|
+
case 'mcp':
|
|
582
|
+
return {
|
|
583
|
+
supported: true,
|
|
584
|
+
entry: { type: 'mcp', server_label: tool.server_label },
|
|
585
|
+
};
|
|
586
|
+
case 'file_search':
|
|
587
|
+
case 'web_search':
|
|
588
|
+
case 'web_search_preview':
|
|
589
|
+
case 'image_generation':
|
|
590
|
+
case 'code_interpreter':
|
|
591
|
+
case 'computer':
|
|
592
|
+
case 'apply_patch':
|
|
593
|
+
case 'shell':
|
|
594
|
+
case 'local_shell':
|
|
595
|
+
case 'programmatic_tool_calling':
|
|
596
|
+
return { supported: true, entry: { type: tool.type } };
|
|
597
|
+
default:
|
|
598
|
+
return {
|
|
599
|
+
supported: false,
|
|
600
|
+
reason: `OpenAI does not support ${tool.type} tools in tool_choice.allowed_tools`,
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
422
605
|
function prepareFunctionTool({
|
|
423
606
|
tool,
|
|
424
607
|
options,
|