@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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @ai-sdk/openai
|
|
2
2
|
|
|
3
|
+
## 4.0.43
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- a062795: fix(openai): support built-in and provider-defined tools in the Responses `allowedTools` option
|
|
8
|
+
|
|
9
|
+
`allowedTools` emitted every allow-list entry as `{ type: 'function', name }`, but OpenAI identifies
|
|
10
|
+
built-in tools by type. Allow-listing a declared provider-defined tool (web search, image generation,
|
|
11
|
+
MCP, custom, ...) therefore failed with `Tool choice '<name>' not found in 'tools' parameter`. Entries
|
|
12
|
+
are now derived from the declared tool, including the MCP server label and custom tool name.
|
|
13
|
+
|
|
14
|
+
Tools that OpenAI cannot allow-list (the tool search tool, deferred tools, and namespaced tools) are
|
|
15
|
+
dropped from the allow-list with a warning, and an error is thrown if that would leave the allow-list
|
|
16
|
+
empty rather than silently sending an unrestricted request.
|
|
17
|
+
|
|
18
|
+
Ambiguous names are now reported instead of resolved silently. A name that matches both a declared tool
|
|
19
|
+
and another tool's provider tool name resolves to the declared tool and warns; a provider tool name
|
|
20
|
+
shared by several tools in the same request (two MCP servers, for example) is dropped with a warning.
|
|
21
|
+
A name that matches no declared tool keeps its existing behavior and is now warned about.
|
|
22
|
+
|
|
23
|
+
## 4.0.42
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- b6fff2e: feat(provider/openai): support explicit Responses compaction triggers
|
|
28
|
+
|
|
3
29
|
## 4.0.41
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1379,6 +1379,7 @@ declare const openaiLanguageModelResponsesOptionsSchema: _ai_sdk_provider_utils.
|
|
|
1379
1379
|
type: "compaction";
|
|
1380
1380
|
compactThreshold: number;
|
|
1381
1381
|
}[] | null | undefined;
|
|
1382
|
+
compactionTrigger?: boolean | undefined;
|
|
1382
1383
|
allowedTools?: {
|
|
1383
1384
|
toolNames: string[];
|
|
1384
1385
|
mode?: "auto" | "required" | undefined;
|
package/dist/index.js
CHANGED
|
@@ -5609,6 +5609,11 @@ var openaiLanguageModelResponsesOptionsSchema = lazySchema25(
|
|
|
5609
5609
|
compactThreshold: z27.number()
|
|
5610
5610
|
})
|
|
5611
5611
|
).nullish(),
|
|
5612
|
+
/**
|
|
5613
|
+
* Request explicit server-side compaction by appending a
|
|
5614
|
+
* `compaction_trigger` item to the Responses input.
|
|
5615
|
+
*/
|
|
5616
|
+
compactionTrigger: z27.boolean().optional(),
|
|
5612
5617
|
/**
|
|
5613
5618
|
* Restrict the callable tools to a subset while keeping the full tools
|
|
5614
5619
|
* list intact, so prompt caching is preserved across requests with
|
|
@@ -5643,7 +5648,7 @@ async function prepareResponsesTools({
|
|
|
5643
5648
|
customProviderToolNames,
|
|
5644
5649
|
outputSchemaToolNames
|
|
5645
5650
|
}) {
|
|
5646
|
-
var _a, _b, _c;
|
|
5651
|
+
var _a, _b, _c, _d;
|
|
5647
5652
|
tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
|
|
5648
5653
|
const toolWarnings = [];
|
|
5649
5654
|
if (tools == null) {
|
|
@@ -5652,6 +5657,20 @@ async function prepareResponsesTools({
|
|
|
5652
5657
|
const openaiTools2 = [];
|
|
5653
5658
|
const namespaceTools = /* @__PURE__ */ new Map();
|
|
5654
5659
|
const resolvedCustomProviderToolNames = customProviderToolNames != null ? customProviderToolNames : /* @__PURE__ */ new Set();
|
|
5660
|
+
const allowedToolResolutions = /* @__PURE__ */ new Map();
|
|
5661
|
+
const allowedToolAliases = /* @__PURE__ */ new Map();
|
|
5662
|
+
const recordAllowedTool = (toolName, resolution, canonicalName) => {
|
|
5663
|
+
allowedToolResolutions.set(toolName, resolution);
|
|
5664
|
+
if (canonicalName == null || canonicalName === toolName) {
|
|
5665
|
+
return;
|
|
5666
|
+
}
|
|
5667
|
+
const existingAlias = allowedToolAliases.get(canonicalName);
|
|
5668
|
+
if (existingAlias == null) {
|
|
5669
|
+
allowedToolAliases.set(canonicalName, resolution);
|
|
5670
|
+
} else if (existingAlias !== "ambiguous" && !isSameAllowedTool(existingAlias, resolution)) {
|
|
5671
|
+
allowedToolAliases.set(canonicalName, "ambiguous");
|
|
5672
|
+
}
|
|
5673
|
+
};
|
|
5655
5674
|
for (const tool of tools) {
|
|
5656
5675
|
switch (tool.type) {
|
|
5657
5676
|
case "function": {
|
|
@@ -5684,9 +5703,24 @@ async function prepareResponsesTools({
|
|
|
5684
5703
|
}
|
|
5685
5704
|
namespaceTool.tools.push(openaiFunctionTool);
|
|
5686
5705
|
}
|
|
5706
|
+
recordAllowedTool(
|
|
5707
|
+
tool.name,
|
|
5708
|
+
namespace != null ? {
|
|
5709
|
+
supported: false,
|
|
5710
|
+
reason: "tools inside an OpenAI tool namespace are not visible to tool_choice.allowed_tools"
|
|
5711
|
+
} : (openaiOptions == null ? void 0 : openaiOptions.deferLoading) === true ? {
|
|
5712
|
+
supported: false,
|
|
5713
|
+
reason: "deferred tools are not visible to tool_choice.allowed_tools"
|
|
5714
|
+
} : {
|
|
5715
|
+
supported: true,
|
|
5716
|
+
entry: { type: "function", name: tool.name }
|
|
5717
|
+
},
|
|
5718
|
+
void 0
|
|
5719
|
+
);
|
|
5687
5720
|
break;
|
|
5688
5721
|
}
|
|
5689
5722
|
case "provider": {
|
|
5723
|
+
const openaiToolCountBefore = openaiTools2.length;
|
|
5690
5724
|
switch (tool.id) {
|
|
5691
5725
|
case "openai.file_search": {
|
|
5692
5726
|
const args = await validateTypes2({
|
|
@@ -5859,6 +5893,14 @@ async function prepareResponsesTools({
|
|
|
5859
5893
|
break;
|
|
5860
5894
|
}
|
|
5861
5895
|
}
|
|
5896
|
+
if (openaiTools2.length > openaiToolCountBefore) {
|
|
5897
|
+
const openaiTool = openaiTools2[openaiToolCountBefore];
|
|
5898
|
+
recordAllowedTool(
|
|
5899
|
+
tool.name,
|
|
5900
|
+
toAllowedToolResolution(openaiTool),
|
|
5901
|
+
toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(tool.name)
|
|
5902
|
+
);
|
|
5903
|
+
}
|
|
5862
5904
|
break;
|
|
5863
5905
|
}
|
|
5864
5906
|
default:
|
|
@@ -5870,18 +5912,63 @@ async function prepareResponsesTools({
|
|
|
5870
5912
|
}
|
|
5871
5913
|
}
|
|
5872
5914
|
if (allowedTools != null) {
|
|
5915
|
+
const allowedToolEntries = [];
|
|
5916
|
+
const droppedToolNames = [];
|
|
5917
|
+
for (const name of allowedTools.toolNames) {
|
|
5918
|
+
const directResolution = allowedToolResolutions.get(name);
|
|
5919
|
+
const resolution = directResolution != null ? directResolution : allowedToolAliases.get(name);
|
|
5920
|
+
if (directResolution != null && allowedToolAliases.has(name)) {
|
|
5921
|
+
toolWarnings.push({
|
|
5922
|
+
type: "unsupported",
|
|
5923
|
+
feature: `allowedTools entry "${name}"`,
|
|
5924
|
+
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"
|
|
5925
|
+
});
|
|
5926
|
+
}
|
|
5927
|
+
if (resolution === "ambiguous") {
|
|
5928
|
+
toolWarnings.push({
|
|
5929
|
+
type: "unsupported",
|
|
5930
|
+
feature: `allowedTools entry "${name}"`,
|
|
5931
|
+
details: "several tools in this request share this provider tool name; use the tool name from the tools for this request instead"
|
|
5932
|
+
});
|
|
5933
|
+
droppedToolNames.push(name);
|
|
5934
|
+
continue;
|
|
5935
|
+
}
|
|
5936
|
+
if (resolution == null) {
|
|
5937
|
+
toolWarnings.push({
|
|
5938
|
+
type: "unsupported",
|
|
5939
|
+
feature: `allowedTools entry "${name}"`,
|
|
5940
|
+
details: "the tool is not part of the tools for this request and is sent as a function tool"
|
|
5941
|
+
});
|
|
5942
|
+
allowedToolEntries.push({
|
|
5943
|
+
type: "function",
|
|
5944
|
+
name: (_b = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(name)) != null ? _b : name
|
|
5945
|
+
});
|
|
5946
|
+
continue;
|
|
5947
|
+
}
|
|
5948
|
+
if (!resolution.supported) {
|
|
5949
|
+
toolWarnings.push({
|
|
5950
|
+
type: "unsupported",
|
|
5951
|
+
feature: `allowedTools entry "${name}"`,
|
|
5952
|
+
details: `${resolution.reason}; the tool is removed from the allowed tools`
|
|
5953
|
+
});
|
|
5954
|
+
droppedToolNames.push(name);
|
|
5955
|
+
continue;
|
|
5956
|
+
}
|
|
5957
|
+
allowedToolEntries.push(resolution.entry);
|
|
5958
|
+
}
|
|
5959
|
+
if (allowedToolEntries.length === 0) {
|
|
5960
|
+
throw new UnsupportedFunctionalityError5({
|
|
5961
|
+
functionality: `allowedTools with only tools that cannot be allow-listed (${droppedToolNames.join(
|
|
5962
|
+
", "
|
|
5963
|
+
)})`
|
|
5964
|
+
});
|
|
5965
|
+
}
|
|
5873
5966
|
return {
|
|
5874
5967
|
tools: openaiTools2,
|
|
5875
5968
|
toolChoice: {
|
|
5876
5969
|
type: "allowed_tools",
|
|
5877
|
-
mode: (
|
|
5878
|
-
tools:
|
|
5879
|
-
var _a2;
|
|
5880
|
-
return {
|
|
5881
|
-
type: "function",
|
|
5882
|
-
name: (_a2 = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(name)) != null ? _a2 : name
|
|
5883
|
-
};
|
|
5884
|
-
})
|
|
5970
|
+
mode: (_c = allowedTools.mode) != null ? _c : "auto",
|
|
5971
|
+
tools: allowedToolEntries
|
|
5885
5972
|
},
|
|
5886
5973
|
toolWarnings
|
|
5887
5974
|
};
|
|
@@ -5896,7 +5983,7 @@ async function prepareResponsesTools({
|
|
|
5896
5983
|
case "required":
|
|
5897
5984
|
return { tools: openaiTools2, toolChoice: type, toolWarnings };
|
|
5898
5985
|
case "tool": {
|
|
5899
|
-
const resolvedToolName = (
|
|
5986
|
+
const resolvedToolName = (_d = toolNameMapping == null ? void 0 : toolNameMapping.toProviderToolName(toolChoice.toolName)) != null ? _d : toolChoice.toolName;
|
|
5900
5987
|
return {
|
|
5901
5988
|
tools: openaiTools2,
|
|
5902
5989
|
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 },
|
|
@@ -5911,6 +5998,53 @@ async function prepareResponsesTools({
|
|
|
5911
5998
|
}
|
|
5912
5999
|
}
|
|
5913
6000
|
}
|
|
6001
|
+
function allowedToolKey(entry) {
|
|
6002
|
+
switch (entry.type) {
|
|
6003
|
+
case "mcp":
|
|
6004
|
+
return `mcp:${entry.server_label}`;
|
|
6005
|
+
case "function":
|
|
6006
|
+
case "custom":
|
|
6007
|
+
return `${entry.type}:${entry.name}`;
|
|
6008
|
+
default:
|
|
6009
|
+
return entry.type;
|
|
6010
|
+
}
|
|
6011
|
+
}
|
|
6012
|
+
function isSameAllowedTool(a, b) {
|
|
6013
|
+
if (a.supported && b.supported) {
|
|
6014
|
+
return allowedToolKey(a.entry) === allowedToolKey(b.entry);
|
|
6015
|
+
}
|
|
6016
|
+
if (!a.supported && !b.supported) {
|
|
6017
|
+
return a.reason === b.reason;
|
|
6018
|
+
}
|
|
6019
|
+
return false;
|
|
6020
|
+
}
|
|
6021
|
+
function toAllowedToolResolution(tool) {
|
|
6022
|
+
switch (tool.type) {
|
|
6023
|
+
case "custom":
|
|
6024
|
+
return { supported: true, entry: { type: "custom", name: tool.name } };
|
|
6025
|
+
case "mcp":
|
|
6026
|
+
return {
|
|
6027
|
+
supported: true,
|
|
6028
|
+
entry: { type: "mcp", server_label: tool.server_label }
|
|
6029
|
+
};
|
|
6030
|
+
case "file_search":
|
|
6031
|
+
case "web_search":
|
|
6032
|
+
case "web_search_preview":
|
|
6033
|
+
case "image_generation":
|
|
6034
|
+
case "code_interpreter":
|
|
6035
|
+
case "computer":
|
|
6036
|
+
case "apply_patch":
|
|
6037
|
+
case "shell":
|
|
6038
|
+
case "local_shell":
|
|
6039
|
+
case "programmatic_tool_calling":
|
|
6040
|
+
return { supported: true, entry: { type: tool.type } };
|
|
6041
|
+
default:
|
|
6042
|
+
return {
|
|
6043
|
+
supported: false,
|
|
6044
|
+
reason: `OpenAI does not support ${tool.type} tools in tool_choice.allowed_tools`
|
|
6045
|
+
};
|
|
6046
|
+
}
|
|
6047
|
+
}
|
|
5914
6048
|
function prepareFunctionTool({
|
|
5915
6049
|
tool,
|
|
5916
6050
|
options
|
|
@@ -6192,6 +6326,9 @@ var OpenAIResponsesLanguageModel = class _OpenAIResponsesLanguageModel {
|
|
|
6192
6326
|
outputSchemaToolNames: outputSchemaToolNames.size > 0 ? outputSchemaToolNames : void 0
|
|
6193
6327
|
});
|
|
6194
6328
|
warnings.push(...inputWarnings);
|
|
6329
|
+
if (openaiOptions == null ? void 0 : openaiOptions.compactionTrigger) {
|
|
6330
|
+
input.push({ type: "compaction_trigger" });
|
|
6331
|
+
}
|
|
6195
6332
|
const strictJsonSchema = (_g = openaiOptions == null ? void 0 : openaiOptions.strictJsonSchema) != null ? _g : true;
|
|
6196
6333
|
let include = openaiOptions == null ? void 0 : openaiOptions.include;
|
|
6197
6334
|
function addInclude(key) {
|
|
@@ -10023,7 +10160,7 @@ var OpenAISkills = class {
|
|
|
10023
10160
|
};
|
|
10024
10161
|
|
|
10025
10162
|
// src/version.ts
|
|
10026
|
-
var VERSION = true ? "4.0.
|
|
10163
|
+
var VERSION = true ? "4.0.43" : "0.0.0-test";
|
|
10027
10164
|
|
|
10028
10165
|
// src/openai-provider.ts
|
|
10029
10166
|
function createOpenAI(options = {}) {
|