@ai-sdk/openai 4.0.42 → 4.0.44

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;
@@ -1143,7 +1143,7 @@ var OpenAIChatLanguageModel = class _OpenAIChatLanguageModel {
1143
1143
  };
1144
1144
  }
1145
1145
  async doGenerate(options) {
1146
- var _a, _b, _c, _d, _e, _f, _g, _h;
1146
+ var _a, _b, _c, _d, _e, _f, _g;
1147
1147
  const { args: body, warnings } = await this.getArgs(options);
1148
1148
  const {
1149
1149
  responseHeaders,
@@ -1172,12 +1172,12 @@ var OpenAIChatLanguageModel = class _OpenAIChatLanguageModel {
1172
1172
  for (const toolCall of (_c = choice.message.tool_calls) != null ? _c : []) {
1173
1173
  content.push({
1174
1174
  type: "tool-call",
1175
- toolCallId: (_d = toolCall.id) != null ? _d : generateId(),
1175
+ toolCallId: toolCall.id || generateId(),
1176
1176
  toolName: toolCall.function.name,
1177
1177
  input: toolCall.function.arguments
1178
1178
  });
1179
1179
  }
1180
- for (const annotation of (_e = choice.message.annotations) != null ? _e : []) {
1180
+ for (const annotation of (_d = choice.message.annotations) != null ? _d : []) {
1181
1181
  content.push({
1182
1182
  type: "source",
1183
1183
  sourceType: "url",
@@ -1186,7 +1186,7 @@ var OpenAIChatLanguageModel = class _OpenAIChatLanguageModel {
1186
1186
  title: annotation.url_citation.title
1187
1187
  });
1188
1188
  }
1189
- const completionTokenDetails = (_f = response.usage) == null ? void 0 : _f.completion_tokens_details;
1189
+ const completionTokenDetails = (_e = response.usage) == null ? void 0 : _e.completion_tokens_details;
1190
1190
  const providerMetadata = { openai: {} };
1191
1191
  if ((completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens) != null) {
1192
1192
  providerMetadata.openai.acceptedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens;
@@ -1194,14 +1194,14 @@ var OpenAIChatLanguageModel = class _OpenAIChatLanguageModel {
1194
1194
  if ((completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens) != null) {
1195
1195
  providerMetadata.openai.rejectedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens;
1196
1196
  }
1197
- if (((_g = choice.logprobs) == null ? void 0 : _g.content) != null) {
1197
+ if (((_f = choice.logprobs) == null ? void 0 : _f.content) != null) {
1198
1198
  providerMetadata.openai.logprobs = choice.logprobs.content;
1199
1199
  }
1200
1200
  return {
1201
1201
  content,
1202
1202
  finishReason: {
1203
1203
  unified: mapOpenAIFinishReason(choice.finish_reason),
1204
- raw: (_h = choice.finish_reason) != null ? _h : void 0
1204
+ raw: (_g = choice.finish_reason) != null ? _g : void 0
1205
1205
  },
1206
1206
  usage: convertOpenAIChatUsage(response.usage),
1207
1207
  request: { body },
@@ -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