@ai-sdk/openai 4.0.42 → 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 +20 -0
- package/dist/index.js +140 -11
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +17 -4
- package/dist/internal/index.js +139 -10
- package/dist/internal/index.js.map +1 -1
- package/docs/03-openai.mdx +58 -0
- package/package.json +1 -1
- package/src/responses/openai-responses-api.ts +15 -0
- package/src/responses/openai-responses-prepare-tools.ts +188 -5
package/dist/internal/index.d.ts
CHANGED
|
@@ -688,6 +688,22 @@ type OpenAIResponsesFunctionTool = {
|
|
|
688
688
|
allowed_callers?: Array<'direct' | 'programmatic'>;
|
|
689
689
|
output_schema?: JSONSchema7;
|
|
690
690
|
};
|
|
691
|
+
/**
|
|
692
|
+
* Entry in `tool_choice.allowed_tools.tools`. OpenAI identifies most built-in
|
|
693
|
+
* tools by type alone; only `function`, `custom` and `mcp` carry an identifier.
|
|
694
|
+
*/
|
|
695
|
+
type OpenAIResponsesAllowedTool = {
|
|
696
|
+
type: 'function';
|
|
697
|
+
name: string;
|
|
698
|
+
} | {
|
|
699
|
+
type: 'custom';
|
|
700
|
+
name: string;
|
|
701
|
+
} | {
|
|
702
|
+
type: 'mcp';
|
|
703
|
+
server_label: string;
|
|
704
|
+
} | {
|
|
705
|
+
type: Exclude<OpenAIResponsesTool['type'], 'function' | 'custom' | 'mcp' | 'namespace' | 'tool_search'>;
|
|
706
|
+
};
|
|
691
707
|
type OpenAIResponsesTool = OpenAIResponsesFunctionTool | {
|
|
692
708
|
type: 'namespace';
|
|
693
709
|
name: string;
|
|
@@ -1600,10 +1616,7 @@ declare class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1600
1616
|
} | {
|
|
1601
1617
|
type: "allowed_tools";
|
|
1602
1618
|
mode: "auto" | "required";
|
|
1603
|
-
tools: Array<
|
|
1604
|
-
type: "function";
|
|
1605
|
-
name: string;
|
|
1606
|
-
}>;
|
|
1619
|
+
tools: Array<OpenAIResponsesAllowedTool>;
|
|
1607
1620
|
} | undefined;
|
|
1608
1621
|
reasoning?: {
|
|
1609
1622
|
context?: "auto" | "current_turn" | "all_turns" | undefined;
|
package/dist/internal/index.js
CHANGED
|
@@ -6040,7 +6040,7 @@ async function prepareResponsesTools({
|
|
|
6040
6040
|
customProviderToolNames,
|
|
6041
6041
|
outputSchemaToolNames
|
|
6042
6042
|
}) {
|
|
6043
|
-
var _a, _b, _c;
|
|
6043
|
+
var _a, _b, _c, _d;
|
|
6044
6044
|
tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
|
|
6045
6045
|
const toolWarnings = [];
|
|
6046
6046
|
if (tools == null) {
|
|
@@ -6049,6 +6049,20 @@ async function prepareResponsesTools({
|
|
|
6049
6049
|
const openaiTools = [];
|
|
6050
6050
|
const namespaceTools = /* @__PURE__ */ new Map();
|
|
6051
6051
|
const resolvedCustomProviderToolNames = customProviderToolNames != null ? customProviderToolNames : /* @__PURE__ */ new Set();
|
|
6052
|
+
const allowedToolResolutions = /* @__PURE__ */ new Map();
|
|
6053
|
+
const allowedToolAliases = /* @__PURE__ */ new Map();
|
|
6054
|
+
const recordAllowedTool = (toolName, resolution, canonicalName) => {
|
|
6055
|
+
allowedToolResolutions.set(toolName, resolution);
|
|
6056
|
+
if (canonicalName == null || canonicalName === toolName) {
|
|
6057
|
+
return;
|
|
6058
|
+
}
|
|
6059
|
+
const existingAlias = allowedToolAliases.get(canonicalName);
|
|
6060
|
+
if (existingAlias == null) {
|
|
6061
|
+
allowedToolAliases.set(canonicalName, resolution);
|
|
6062
|
+
} else if (existingAlias !== "ambiguous" && !isSameAllowedTool(existingAlias, resolution)) {
|
|
6063
|
+
allowedToolAliases.set(canonicalName, "ambiguous");
|
|
6064
|
+
}
|
|
6065
|
+
};
|
|
6052
6066
|
for (const tool of tools) {
|
|
6053
6067
|
switch (tool.type) {
|
|
6054
6068
|
case "function": {
|
|
@@ -6081,9 +6095,24 @@ async function prepareResponsesTools({
|
|
|
6081
6095
|
}
|
|
6082
6096
|
namespaceTool.tools.push(openaiFunctionTool);
|
|
6083
6097
|
}
|
|
6098
|
+
recordAllowedTool(
|
|
6099
|
+
tool.name,
|
|
6100
|
+
namespace != null ? {
|
|
6101
|
+
supported: false,
|
|
6102
|
+
reason: "tools inside an OpenAI tool namespace are not visible to tool_choice.allowed_tools"
|
|
6103
|
+
} : (openaiOptions == null ? void 0 : openaiOptions.deferLoading) === true ? {
|
|
6104
|
+
supported: false,
|
|
6105
|
+
reason: "deferred tools are not visible to tool_choice.allowed_tools"
|
|
6106
|
+
} : {
|
|
6107
|
+
supported: true,
|
|
6108
|
+
entry: { type: "function", name: tool.name }
|
|
6109
|
+
},
|
|
6110
|
+
void 0
|
|
6111
|
+
);
|
|
6084
6112
|
break;
|
|
6085
6113
|
}
|
|
6086
6114
|
case "provider": {
|
|
6115
|
+
const openaiToolCountBefore = openaiTools.length;
|
|
6087
6116
|
switch (tool.id) {
|
|
6088
6117
|
case "openai.file_search": {
|
|
6089
6118
|
const args = await validateTypes2({
|
|
@@ -6256,6 +6285,14 @@ async function prepareResponsesTools({
|
|
|
6256
6285
|
break;
|
|
6257
6286
|
}
|
|
6258
6287
|
}
|
|
6288
|
+
if (openaiTools.length > openaiToolCountBefore) {
|
|
6289
|
+
const openaiTool = openaiTools[openaiToolCountBefore];
|
|
6290
|
+
recordAllowedTool(
|
|
6291
|
+
tool.name,
|
|
6292
|
+
toAllowedToolResolution(openaiTool),
|
|
6293
|
+
toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(tool.name)
|
|
6294
|
+
);
|
|
6295
|
+
}
|
|
6259
6296
|
break;
|
|
6260
6297
|
}
|
|
6261
6298
|
default:
|
|
@@ -6267,18 +6304,63 @@ async function prepareResponsesTools({
|
|
|
6267
6304
|
}
|
|
6268
6305
|
}
|
|
6269
6306
|
if (allowedTools != null) {
|
|
6307
|
+
const allowedToolEntries = [];
|
|
6308
|
+
const droppedToolNames = [];
|
|
6309
|
+
for (const name of allowedTools.toolNames) {
|
|
6310
|
+
const directResolution = allowedToolResolutions.get(name);
|
|
6311
|
+
const resolution = directResolution != null ? directResolution : allowedToolAliases.get(name);
|
|
6312
|
+
if (directResolution != null && allowedToolAliases.has(name)) {
|
|
6313
|
+
toolWarnings.push({
|
|
6314
|
+
type: "unsupported",
|
|
6315
|
+
feature: `allowedTools entry "${name}"`,
|
|
6316
|
+
details: "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"
|
|
6317
|
+
});
|
|
6318
|
+
}
|
|
6319
|
+
if (resolution === "ambiguous") {
|
|
6320
|
+
toolWarnings.push({
|
|
6321
|
+
type: "unsupported",
|
|
6322
|
+
feature: `allowedTools entry "${name}"`,
|
|
6323
|
+
details: "several tools in this request share this provider tool name; use the tool name from the tools for this request instead"
|
|
6324
|
+
});
|
|
6325
|
+
droppedToolNames.push(name);
|
|
6326
|
+
continue;
|
|
6327
|
+
}
|
|
6328
|
+
if (resolution == null) {
|
|
6329
|
+
toolWarnings.push({
|
|
6330
|
+
type: "unsupported",
|
|
6331
|
+
feature: `allowedTools entry "${name}"`,
|
|
6332
|
+
details: "the tool is not part of the tools for this request and is sent as a function tool"
|
|
6333
|
+
});
|
|
6334
|
+
allowedToolEntries.push({
|
|
6335
|
+
type: "function",
|
|
6336
|
+
name: (_b = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(name)) != null ? _b : name
|
|
6337
|
+
});
|
|
6338
|
+
continue;
|
|
6339
|
+
}
|
|
6340
|
+
if (!resolution.supported) {
|
|
6341
|
+
toolWarnings.push({
|
|
6342
|
+
type: "unsupported",
|
|
6343
|
+
feature: `allowedTools entry "${name}"`,
|
|
6344
|
+
details: `${resolution.reason}; the tool is removed from the allowed tools`
|
|
6345
|
+
});
|
|
6346
|
+
droppedToolNames.push(name);
|
|
6347
|
+
continue;
|
|
6348
|
+
}
|
|
6349
|
+
allowedToolEntries.push(resolution.entry);
|
|
6350
|
+
}
|
|
6351
|
+
if (allowedToolEntries.length === 0) {
|
|
6352
|
+
throw new UnsupportedFunctionalityError6({
|
|
6353
|
+
functionality: `allowedTools with only tools that cannot be allow-listed (${droppedToolNames.join(
|
|
6354
|
+
", "
|
|
6355
|
+
)})`
|
|
6356
|
+
});
|
|
6357
|
+
}
|
|
6270
6358
|
return {
|
|
6271
6359
|
tools: openaiTools,
|
|
6272
6360
|
toolChoice: {
|
|
6273
6361
|
type: "allowed_tools",
|
|
6274
|
-
mode: (
|
|
6275
|
-
tools:
|
|
6276
|
-
var _a2;
|
|
6277
|
-
return {
|
|
6278
|
-
type: "function",
|
|
6279
|
-
name: (_a2 = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(name)) != null ? _a2 : name
|
|
6280
|
-
};
|
|
6281
|
-
})
|
|
6362
|
+
mode: (_c = allowedTools.mode) != null ? _c : "auto",
|
|
6363
|
+
tools: allowedToolEntries
|
|
6282
6364
|
},
|
|
6283
6365
|
toolWarnings
|
|
6284
6366
|
};
|
|
@@ -6293,7 +6375,7 @@ async function prepareResponsesTools({
|
|
|
6293
6375
|
case "required":
|
|
6294
6376
|
return { tools: openaiTools, toolChoice: type, toolWarnings };
|
|
6295
6377
|
case "tool": {
|
|
6296
|
-
const resolvedToolName = (
|
|
6378
|
+
const resolvedToolName = (_d = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(toolChoice.toolName)) != null ? _d : toolChoice.toolName;
|
|
6297
6379
|
return {
|
|
6298
6380
|
tools: openaiTools,
|
|
6299
6381
|
toolChoice: resolvedToolName === "code_interpreter" || resolvedToolName === "file_search" || resolvedToolName === "image_generation" || resolvedToolName === "web_search_preview" || resolvedToolName === "web_search" || resolvedToolName === "mcp" || resolvedToolName === "apply_patch" || resolvedToolName === "computer" || resolvedToolName === "programmatic_tool_calling" ? { type: resolvedToolName } : resolvedCustomProviderToolNames.has(resolvedToolName) ? { type: "custom", name: resolvedToolName } : { type: "function", name: resolvedToolName },
|
|
@@ -6308,6 +6390,53 @@ async function prepareResponsesTools({
|
|
|
6308
6390
|
}
|
|
6309
6391
|
}
|
|
6310
6392
|
}
|
|
6393
|
+
function allowedToolKey(entry) {
|
|
6394
|
+
switch (entry.type) {
|
|
6395
|
+
case "mcp":
|
|
6396
|
+
return `mcp:${entry.server_label}`;
|
|
6397
|
+
case "function":
|
|
6398
|
+
case "custom":
|
|
6399
|
+
return `${entry.type}:${entry.name}`;
|
|
6400
|
+
default:
|
|
6401
|
+
return entry.type;
|
|
6402
|
+
}
|
|
6403
|
+
}
|
|
6404
|
+
function isSameAllowedTool(a, b) {
|
|
6405
|
+
if (a.supported && b.supported) {
|
|
6406
|
+
return allowedToolKey(a.entry) === allowedToolKey(b.entry);
|
|
6407
|
+
}
|
|
6408
|
+
if (!a.supported && !b.supported) {
|
|
6409
|
+
return a.reason === b.reason;
|
|
6410
|
+
}
|
|
6411
|
+
return false;
|
|
6412
|
+
}
|
|
6413
|
+
function toAllowedToolResolution(tool) {
|
|
6414
|
+
switch (tool.type) {
|
|
6415
|
+
case "custom":
|
|
6416
|
+
return { supported: true, entry: { type: "custom", name: tool.name } };
|
|
6417
|
+
case "mcp":
|
|
6418
|
+
return {
|
|
6419
|
+
supported: true,
|
|
6420
|
+
entry: { type: "mcp", server_label: tool.server_label }
|
|
6421
|
+
};
|
|
6422
|
+
case "file_search":
|
|
6423
|
+
case "web_search":
|
|
6424
|
+
case "web_search_preview":
|
|
6425
|
+
case "image_generation":
|
|
6426
|
+
case "code_interpreter":
|
|
6427
|
+
case "computer":
|
|
6428
|
+
case "apply_patch":
|
|
6429
|
+
case "shell":
|
|
6430
|
+
case "local_shell":
|
|
6431
|
+
case "programmatic_tool_calling":
|
|
6432
|
+
return { supported: true, entry: { type: tool.type } };
|
|
6433
|
+
default:
|
|
6434
|
+
return {
|
|
6435
|
+
supported: false,
|
|
6436
|
+
reason: `OpenAI does not support ${tool.type} tools in tool_choice.allowed_tools`
|
|
6437
|
+
};
|
|
6438
|
+
}
|
|
6439
|
+
}
|
|
6311
6440
|
function prepareFunctionTool({
|
|
6312
6441
|
tool,
|
|
6313
6442
|
options
|