@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.
@@ -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;
@@ -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: (_b = allowedTools.mode) != null ? _b : "auto",
6275
- tools: allowedTools.toolNames.map((name) => {
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 = (_c = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(toolChoice.toolName)) != null ? _c : toolChoice.toolName;
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