@ai-sdk/openai 3.0.98 → 3.0.99
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 +6 -0
- package/dist/index.js +564 -231
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +488 -153
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +584 -253
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +485 -152
- package/dist/internal/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/responses/convert-to-openai-responses-input.ts +309 -90
- package/src/responses/expand-parallel-tool-call.ts +142 -0
- package/src/responses/openai-responses-language-model.ts +171 -29
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type LanguageModelV3CallOptions,
|
|
7
7
|
type LanguageModelV3Content,
|
|
8
8
|
type LanguageModelV3FinishReason,
|
|
9
|
+
type LanguageModelV3FunctionTool,
|
|
9
10
|
type LanguageModelV3GenerateResult,
|
|
10
11
|
type LanguageModelV3ProviderTool,
|
|
11
12
|
type LanguageModelV3StreamPart,
|
|
@@ -49,6 +50,10 @@ import {
|
|
|
49
50
|
type OpenAIResponsesUsage,
|
|
50
51
|
} from './convert-openai-responses-usage';
|
|
51
52
|
import { convertToOpenAIResponsesInput } from './convert-to-openai-responses-input';
|
|
53
|
+
import {
|
|
54
|
+
expandParallelToolCall,
|
|
55
|
+
isUndeclaredParallelToolCall,
|
|
56
|
+
} from './expand-parallel-tool-call';
|
|
52
57
|
import { mapOpenAIResponseFinishReason } from './map-openai-responses-finish-reason';
|
|
53
58
|
import {
|
|
54
59
|
openaiResponsesChunkSchema,
|
|
@@ -538,6 +543,10 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
538
543
|
|
|
539
544
|
const content: Array<LanguageModelV3Content> = [];
|
|
540
545
|
const logprobs: Array<OpenAIResponsesLogprobs> = [];
|
|
546
|
+
const functionTools =
|
|
547
|
+
options.tools?.filter(
|
|
548
|
+
(tool): tool is LanguageModelV3FunctionTool => tool.type === 'function',
|
|
549
|
+
) ?? [];
|
|
541
550
|
|
|
542
551
|
// flag that checks if there have been client-side tool calls (not executed by openai)
|
|
543
552
|
let hasFunctionCall = false;
|
|
@@ -798,6 +807,22 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
798
807
|
case 'function_call': {
|
|
799
808
|
hasFunctionCall = true;
|
|
800
809
|
|
|
810
|
+
const expandedToolCalls = await expandParallelToolCall({
|
|
811
|
+
toolCall: {
|
|
812
|
+
toolCallId: part.call_id,
|
|
813
|
+
toolName: part.name,
|
|
814
|
+
input: part.arguments,
|
|
815
|
+
},
|
|
816
|
+
tools: functionTools,
|
|
817
|
+
providerOptionsName,
|
|
818
|
+
itemId: part.id,
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
if (expandedToolCalls != null) {
|
|
822
|
+
content.push(...expandedToolCalls);
|
|
823
|
+
break;
|
|
824
|
+
}
|
|
825
|
+
|
|
801
826
|
content.push({
|
|
802
827
|
type: 'tool-call',
|
|
803
828
|
toolCallId: part.call_id,
|
|
@@ -1105,6 +1130,11 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
1105
1130
|
const approvalRequestIdToDummyToolCallIdFromPrompt =
|
|
1106
1131
|
extractApprovalRequestIdToToolCallIdMapping(options.prompt);
|
|
1107
1132
|
|
|
1133
|
+
const functionTools =
|
|
1134
|
+
options.tools?.filter(
|
|
1135
|
+
(tool): tool is LanguageModelV3FunctionTool => tool.type === 'function',
|
|
1136
|
+
) ?? [];
|
|
1137
|
+
|
|
1108
1138
|
const approvalRequestIdToDummyToolCallIdFromStream = new Map<
|
|
1109
1139
|
string,
|
|
1110
1140
|
string
|
|
@@ -1131,6 +1161,8 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
1131
1161
|
endEmitted: boolean;
|
|
1132
1162
|
};
|
|
1133
1163
|
toolSearchExecution?: 'server' | 'client';
|
|
1164
|
+
suppressInputStreaming?: boolean;
|
|
1165
|
+
bufferedInputDeltas?: string[];
|
|
1134
1166
|
}
|
|
1135
1167
|
| undefined
|
|
1136
1168
|
> = {};
|
|
@@ -1199,16 +1231,25 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
1199
1231
|
|
|
1200
1232
|
if (isResponseOutputItemAddedChunk(value)) {
|
|
1201
1233
|
if (value.item.type === 'function_call') {
|
|
1234
|
+
const suppressInputStreaming = isUndeclaredParallelToolCall({
|
|
1235
|
+
toolName: value.item.name,
|
|
1236
|
+
tools: functionTools,
|
|
1237
|
+
});
|
|
1238
|
+
|
|
1202
1239
|
ongoingToolCalls[value.output_index] = {
|
|
1203
1240
|
toolName: value.item.name,
|
|
1204
1241
|
toolCallId: value.item.call_id,
|
|
1242
|
+
suppressInputStreaming,
|
|
1243
|
+
bufferedInputDeltas: suppressInputStreaming ? [] : undefined,
|
|
1205
1244
|
};
|
|
1206
1245
|
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1246
|
+
if (!suppressInputStreaming) {
|
|
1247
|
+
controller.enqueue({
|
|
1248
|
+
type: 'tool-input-start',
|
|
1249
|
+
id: value.item.call_id,
|
|
1250
|
+
toolName: value.item.name,
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1212
1253
|
} else if (value.item.type === 'custom_tool_call') {
|
|
1213
1254
|
const toolName = toolNameMapping.toCustomToolName(
|
|
1214
1255
|
value.item.name,
|
|
@@ -1439,34 +1480,111 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
1439
1480
|
},
|
|
1440
1481
|
});
|
|
1441
1482
|
} else if (value.item.type === 'function_call') {
|
|
1483
|
+
const item = value.item;
|
|
1484
|
+
const ongoingToolCall = ongoingToolCalls[value.output_index];
|
|
1442
1485
|
ongoingToolCalls[value.output_index] = undefined;
|
|
1443
1486
|
hasFunctionCall = true;
|
|
1444
1487
|
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1488
|
+
const suppressInputStreaming =
|
|
1489
|
+
ongoingToolCall?.suppressInputStreaming ??
|
|
1490
|
+
isUndeclaredParallelToolCall({
|
|
1491
|
+
toolName: item.name,
|
|
1492
|
+
tools: functionTools,
|
|
1493
|
+
});
|
|
1494
|
+
|
|
1495
|
+
const enqueueUnexpandedToolCall = () => {
|
|
1496
|
+
if (suppressInputStreaming) {
|
|
1497
|
+
controller.enqueue({
|
|
1498
|
+
type: 'tool-input-start',
|
|
1499
|
+
id: item.call_id,
|
|
1500
|
+
toolName: item.name,
|
|
1501
|
+
});
|
|
1502
|
+
|
|
1503
|
+
const bufferedInputDeltas =
|
|
1504
|
+
ongoingToolCall?.bufferedInputDeltas ?? [];
|
|
1505
|
+
|
|
1506
|
+
if (bufferedInputDeltas.length > 0) {
|
|
1507
|
+
for (const delta of bufferedInputDeltas) {
|
|
1508
|
+
controller.enqueue({
|
|
1509
|
+
type: 'tool-input-delta',
|
|
1510
|
+
id: item.call_id,
|
|
1511
|
+
delta,
|
|
1512
|
+
});
|
|
1513
|
+
}
|
|
1514
|
+
} else if (item.arguments.length > 0) {
|
|
1515
|
+
controller.enqueue({
|
|
1516
|
+
type: 'tool-input-delta',
|
|
1517
|
+
id: item.call_id,
|
|
1518
|
+
delta: item.arguments,
|
|
1519
|
+
});
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
controller.enqueue({
|
|
1524
|
+
type: 'tool-input-end',
|
|
1525
|
+
id: item.call_id,
|
|
1526
|
+
...(item.namespace != null && {
|
|
1527
|
+
providerMetadata: {
|
|
1528
|
+
[providerOptionsName]: {
|
|
1529
|
+
namespace: item.namespace,
|
|
1530
|
+
},
|
|
1531
|
+
},
|
|
1532
|
+
}),
|
|
1533
|
+
});
|
|
1534
|
+
|
|
1535
|
+
controller.enqueue({
|
|
1536
|
+
type: 'tool-call',
|
|
1537
|
+
toolCallId: item.call_id,
|
|
1538
|
+
toolName: item.name,
|
|
1539
|
+
input: item.arguments,
|
|
1449
1540
|
providerMetadata: {
|
|
1450
1541
|
[providerOptionsName]: {
|
|
1451
|
-
|
|
1542
|
+
itemId: item.id,
|
|
1543
|
+
...(item.namespace != null && {
|
|
1544
|
+
namespace: item.namespace,
|
|
1545
|
+
}),
|
|
1452
1546
|
},
|
|
1453
1547
|
},
|
|
1454
|
-
})
|
|
1455
|
-
}
|
|
1548
|
+
});
|
|
1549
|
+
};
|
|
1456
1550
|
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
}),
|
|
1468
|
-
},
|
|
1551
|
+
if (!suppressInputStreaming) {
|
|
1552
|
+
enqueueUnexpandedToolCall();
|
|
1553
|
+
return;
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
return expandParallelToolCall({
|
|
1557
|
+
toolCall: {
|
|
1558
|
+
toolCallId: item.call_id,
|
|
1559
|
+
toolName: item.name,
|
|
1560
|
+
input: item.arguments,
|
|
1469
1561
|
},
|
|
1562
|
+
tools: functionTools,
|
|
1563
|
+
providerOptionsName,
|
|
1564
|
+
itemId: item.id,
|
|
1565
|
+
}).then(expandedToolCalls => {
|
|
1566
|
+
if (expandedToolCalls == null) {
|
|
1567
|
+
enqueueUnexpandedToolCall();
|
|
1568
|
+
return;
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
for (const toolCall of expandedToolCalls) {
|
|
1572
|
+
controller.enqueue({
|
|
1573
|
+
type: 'tool-input-start',
|
|
1574
|
+
id: toolCall.toolCallId,
|
|
1575
|
+
toolName: toolCall.toolName,
|
|
1576
|
+
});
|
|
1577
|
+
controller.enqueue({
|
|
1578
|
+
type: 'tool-input-delta',
|
|
1579
|
+
id: toolCall.toolCallId,
|
|
1580
|
+
delta: toolCall.input,
|
|
1581
|
+
});
|
|
1582
|
+
controller.enqueue({
|
|
1583
|
+
type: 'tool-input-end',
|
|
1584
|
+
id: toolCall.toolCallId,
|
|
1585
|
+
});
|
|
1586
|
+
controller.enqueue(toolCall);
|
|
1587
|
+
}
|
|
1470
1588
|
});
|
|
1471
1589
|
} else if (value.item.type === 'custom_tool_call') {
|
|
1472
1590
|
ongoingToolCalls[value.output_index] = undefined;
|
|
@@ -1863,11 +1981,15 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
1863
1981
|
const toolCall = ongoingToolCalls[value.output_index];
|
|
1864
1982
|
|
|
1865
1983
|
if (toolCall != null) {
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1984
|
+
if (toolCall.suppressInputStreaming) {
|
|
1985
|
+
toolCall.bufferedInputDeltas?.push(value.delta);
|
|
1986
|
+
} else {
|
|
1987
|
+
controller.enqueue({
|
|
1988
|
+
type: 'tool-input-delta',
|
|
1989
|
+
id: toolCall.toolCallId,
|
|
1990
|
+
delta: value.delta,
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1871
1993
|
}
|
|
1872
1994
|
} else if (isResponseCustomToolCallInputDeltaChunk(value)) {
|
|
1873
1995
|
const toolCall = ongoingToolCalls[value.output_index];
|
|
@@ -2189,6 +2311,26 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
2189
2311
|
},
|
|
2190
2312
|
|
|
2191
2313
|
flush(controller) {
|
|
2314
|
+
for (const toolCall of Object.values(ongoingToolCalls)) {
|
|
2315
|
+
if (!toolCall?.suppressInputStreaming) {
|
|
2316
|
+
continue;
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
controller.enqueue({
|
|
2320
|
+
type: 'tool-input-start',
|
|
2321
|
+
id: toolCall.toolCallId,
|
|
2322
|
+
toolName: toolCall.toolName,
|
|
2323
|
+
});
|
|
2324
|
+
|
|
2325
|
+
for (const delta of toolCall.bufferedInputDeltas ?? []) {
|
|
2326
|
+
controller.enqueue({
|
|
2327
|
+
type: 'tool-input-delta',
|
|
2328
|
+
id: toolCall.toolCallId,
|
|
2329
|
+
delta,
|
|
2330
|
+
});
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
|
|
2192
2334
|
const providerMetadata: SharedV3ProviderMetadata = {
|
|
2193
2335
|
[providerOptionsName]: {
|
|
2194
2336
|
responseId: responseId,
|