@ai-sdk/openai 3.0.104 → 3.0.106

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/openai",
3
- "version": "3.0.104",
3
+ "version": "3.0.106",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@ai-sdk/provider": "3.0.15",
40
- "@ai-sdk/provider-utils": "4.0.49"
40
+ "@ai-sdk/provider-utils": "4.0.50"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "20.17.24",
@@ -46,22 +46,40 @@ function serializeToolCallArguments(input: unknown): string {
46
46
 
47
47
  async function convertFunctionToolResultOutput({
48
48
  output,
49
+ promptCacheBreakpoint,
49
50
  providerOptionsName,
50
51
  warnings,
51
52
  }: {
52
53
  output: LanguageModelV3ToolResultOutput;
54
+ promptCacheBreakpoint?: OpenAIPromptCacheBreakpoint;
53
55
  providerOptionsName: string;
54
56
  warnings: Array<SharedV3Warning>;
55
57
  }): Promise<OpenAIResponsesFunctionCallOutput['output']> {
58
+ const convertScalarOutput = (
59
+ value: string,
60
+ ): OpenAIResponsesFunctionCallOutput['output'] =>
61
+ promptCacheBreakpoint == null
62
+ ? value
63
+ : [
64
+ {
65
+ type: 'input_text',
66
+ text: value,
67
+ prompt_cache_breakpoint: promptCacheBreakpoint,
68
+ },
69
+ ];
70
+
56
71
  switch (output.type) {
57
72
  case 'text':
58
73
  case 'error-text':
59
- return output.value;
60
- case 'execution-denied':
61
- return output.reason ?? 'Tool call execution denied.';
74
+ return convertScalarOutput(output.value);
75
+ case 'execution-denied': {
76
+ return convertScalarOutput(
77
+ output.reason ?? 'Tool call execution denied.',
78
+ );
79
+ }
62
80
  case 'json':
63
81
  case 'error-json':
64
- return JSON.stringify(output.value);
82
+ return convertScalarOutput(JSON.stringify(output.value));
65
83
  case 'content':
66
84
  return output.value
67
85
  .map(item => {
@@ -246,6 +264,24 @@ function getPromptCacheBreakpoint(
246
264
  | undefined;
247
265
  }
248
266
 
267
+ function getScalarToolResultPromptCacheBreakpoint({
268
+ output,
269
+ toolResultProviderOptions,
270
+ providerOptionsName,
271
+ }: {
272
+ output: LanguageModelV3ToolResultOutput;
273
+ toolResultProviderOptions: SharedV3ProviderOptions | undefined;
274
+ providerOptionsName: string;
275
+ }): OpenAIPromptCacheBreakpoint | undefined {
276
+ return output.type === 'content'
277
+ ? undefined
278
+ : (getPromptCacheBreakpoint(output.providerOptions, providerOptionsName) ??
279
+ getPromptCacheBreakpoint(
280
+ toolResultProviderOptions,
281
+ providerOptionsName,
282
+ ));
283
+ }
284
+
249
285
  /**
250
286
  * Check if a string is a file ID based on the given prefixes
251
287
  * Returns false if prefixes is undefined (disables file ID detection)
@@ -989,13 +1025,29 @@ export async function convertToOpenAIResponsesInput({
989
1025
  );
990
1026
 
991
1027
  const toolOutputs = await Promise.all(
992
- parallelToolResultGroup.results.map(async result =>
993
- convertFunctionToolResultOutput({
994
- output: result.output,
995
- providerOptionsName,
996
- warnings,
997
- }),
998
- ),
1028
+ parallelToolResultGroup.results.map(async result => {
1029
+ const promptCacheBreakpoint =
1030
+ getScalarToolResultPromptCacheBreakpoint({
1031
+ output: result.output,
1032
+ toolResultProviderOptions: result.providerOptions,
1033
+ providerOptionsName,
1034
+ });
1035
+
1036
+ return {
1037
+ output: await convertFunctionToolResultOutput({
1038
+ output: result.output,
1039
+ providerOptionsName,
1040
+ warnings,
1041
+ }),
1042
+ promptCacheBreakpoint,
1043
+ };
1044
+ }),
1045
+ );
1046
+ const serializedToolOutputs = toolOutputs.map(({ output }) =>
1047
+ typeof output === 'string' ? output : JSON.stringify(output),
1048
+ );
1049
+ const hasPromptCacheBreakpoint = toolOutputs.some(
1050
+ ({ promptCacheBreakpoint }) => promptCacheBreakpoint != null,
999
1051
  );
1000
1052
 
1001
1053
  input.push({
@@ -1003,13 +1055,16 @@ export async function convertToOpenAIResponsesInput({
1003
1055
  call_id: parallelToolResultGroup.metadata.toolCallId,
1004
1056
  // The internal wrapper returns one output containing the child
1005
1057
  // results in the same order as the original tool_uses array.
1006
- output: toolOutputs
1007
- .map(output =>
1008
- typeof output === 'string'
1009
- ? output
1010
- : JSON.stringify(output),
1011
- )
1012
- .join('\n'),
1058
+ output: hasPromptCacheBreakpoint
1059
+ ? serializedToolOutputs.map((text, index) => ({
1060
+ type: 'input_text',
1061
+ text: index === 0 ? text : `\n${text}`,
1062
+ ...(toolOutputs[index].promptCacheBreakpoint != null && {
1063
+ prompt_cache_breakpoint:
1064
+ toolOutputs[index].promptCacheBreakpoint,
1065
+ }),
1066
+ }))
1067
+ : serializedToolOutputs.join('\n'),
1013
1068
  });
1014
1069
  }
1015
1070
  continue;
@@ -1114,18 +1169,38 @@ export async function convertToOpenAIResponsesInput({
1114
1169
  }
1115
1170
 
1116
1171
  if (customProviderToolNames?.has(resolvedToolName)) {
1172
+ const promptCacheBreakpoint =
1173
+ getScalarToolResultPromptCacheBreakpoint({
1174
+ output,
1175
+ toolResultProviderOptions: part.providerOptions,
1176
+ providerOptionsName,
1177
+ });
1178
+ const convertScalarOutput = (
1179
+ value: string,
1180
+ ): OpenAIResponsesCustomToolCallOutput['output'] =>
1181
+ promptCacheBreakpoint == null
1182
+ ? value
1183
+ : [
1184
+ {
1185
+ type: 'input_text',
1186
+ text: value,
1187
+ prompt_cache_breakpoint: promptCacheBreakpoint,
1188
+ },
1189
+ ];
1117
1190
  let outputValue: OpenAIResponsesCustomToolCallOutput['output'];
1118
1191
  switch (output.type) {
1119
1192
  case 'text':
1120
1193
  case 'error-text':
1121
- outputValue = output.value;
1194
+ outputValue = convertScalarOutput(output.value);
1122
1195
  break;
1123
1196
  case 'execution-denied':
1124
- outputValue = output.reason ?? 'Tool call execution denied.';
1197
+ outputValue = convertScalarOutput(
1198
+ output.reason ?? 'Tool call execution denied.',
1199
+ );
1125
1200
  break;
1126
1201
  case 'json':
1127
1202
  case 'error-json':
1128
- outputValue = JSON.stringify(output.value);
1203
+ outputValue = convertScalarOutput(JSON.stringify(output.value));
1129
1204
  break;
1130
1205
  case 'content':
1131
1206
  outputValue = output.value
@@ -1205,6 +1280,11 @@ export async function convertToOpenAIResponsesInput({
1205
1280
 
1206
1281
  const contentValue = await convertFunctionToolResultOutput({
1207
1282
  output,
1283
+ promptCacheBreakpoint: getScalarToolResultPromptCacheBreakpoint({
1284
+ output,
1285
+ toolResultProviderOptions: part.providerOptions,
1286
+ providerOptionsName,
1287
+ }),
1208
1288
  providerOptionsName,
1209
1289
  warnings,
1210
1290
  });