@ai-sdk/openai 4.0.43 → 4.0.45
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 +14 -0
- package/dist/index.js +524 -186
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +517 -181
- package/dist/internal/index.js.map +1 -1
- package/package.json +2 -2
- package/src/chat/openai-chat-language-model.ts +1 -1
- package/src/responses/convert-to-openai-responses-input.ts +333 -108
- package/src/responses/expand-parallel-tool-call.ts +142 -0
- package/src/responses/openai-responses-language-model.ts +180 -38
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type LanguageModelV4CallOptions,
|
|
7
7
|
type LanguageModelV4Content,
|
|
8
8
|
type LanguageModelV4FinishReason,
|
|
9
|
+
type LanguageModelV4FunctionTool,
|
|
9
10
|
type LanguageModelV4GenerateResult,
|
|
10
11
|
type LanguageModelV4ProviderTool,
|
|
11
12
|
type LanguageModelV4StreamPart,
|
|
@@ -58,6 +59,10 @@ import {
|
|
|
58
59
|
type OpenAIResponsesUsage,
|
|
59
60
|
} from './convert-openai-responses-usage';
|
|
60
61
|
import { convertToOpenAIResponsesInput } from './convert-to-openai-responses-input';
|
|
62
|
+
import {
|
|
63
|
+
expandParallelToolCall,
|
|
64
|
+
isUndeclaredParallelToolCall,
|
|
65
|
+
} from './expand-parallel-tool-call';
|
|
61
66
|
import { mapOpenAIResponseFinishReason } from './map-openai-responses-finish-reason';
|
|
62
67
|
import {
|
|
63
68
|
openaiResponsesChunkSchema,
|
|
@@ -691,6 +696,10 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
691
696
|
|
|
692
697
|
const content: Array<LanguageModelV4Content> = [];
|
|
693
698
|
const logprobs: Array<OpenAIResponsesLogprobs> = [];
|
|
699
|
+
const functionTools =
|
|
700
|
+
options.tools?.filter(
|
|
701
|
+
(tool): tool is LanguageModelV4FunctionTool => tool.type === 'function',
|
|
702
|
+
) ?? [];
|
|
694
703
|
|
|
695
704
|
// flag that checks if there have been client-side tool calls (not executed by openai)
|
|
696
705
|
let hasFunctionCall = false;
|
|
@@ -951,6 +960,22 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
951
960
|
case 'function_call': {
|
|
952
961
|
hasFunctionCall = true;
|
|
953
962
|
|
|
963
|
+
const expandedToolCalls = await expandParallelToolCall({
|
|
964
|
+
toolCall: {
|
|
965
|
+
toolCallId: part.call_id,
|
|
966
|
+
toolName: part.name,
|
|
967
|
+
input: part.arguments,
|
|
968
|
+
},
|
|
969
|
+
tools: functionTools,
|
|
970
|
+
providerOptionsName,
|
|
971
|
+
itemId: part.id,
|
|
972
|
+
});
|
|
973
|
+
|
|
974
|
+
if (expandedToolCalls != null) {
|
|
975
|
+
content.push(...expandedToolCalls);
|
|
976
|
+
break;
|
|
977
|
+
}
|
|
978
|
+
|
|
954
979
|
content.push({
|
|
955
980
|
type: 'tool-call',
|
|
956
981
|
toolCallId: part.call_id,
|
|
@@ -1342,6 +1367,11 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1342
1367
|
const approvalRequestIdToDummyToolCallIdFromPrompt =
|
|
1343
1368
|
extractApprovalRequestIdToToolCallIdMapping(options.prompt);
|
|
1344
1369
|
|
|
1370
|
+
const functionTools =
|
|
1371
|
+
options.tools?.filter(
|
|
1372
|
+
(tool): tool is LanguageModelV4FunctionTool => tool.type === 'function',
|
|
1373
|
+
) ?? [];
|
|
1374
|
+
|
|
1345
1375
|
const approvalRequestIdToDummyToolCallIdFromStream = new Map<
|
|
1346
1376
|
string,
|
|
1347
1377
|
string
|
|
@@ -1368,6 +1398,8 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1368
1398
|
endEmitted: boolean;
|
|
1369
1399
|
};
|
|
1370
1400
|
toolSearchExecution?: 'server' | 'client';
|
|
1401
|
+
suppressInputStreaming?: boolean;
|
|
1402
|
+
bufferedInputDeltas?: string[];
|
|
1371
1403
|
}
|
|
1372
1404
|
| undefined
|
|
1373
1405
|
> = {};
|
|
@@ -1450,16 +1482,25 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1450
1482
|
|
|
1451
1483
|
if (isResponseOutputItemAddedChunk(value)) {
|
|
1452
1484
|
if (value.item.type === 'function_call') {
|
|
1485
|
+
const suppressInputStreaming = isUndeclaredParallelToolCall({
|
|
1486
|
+
toolName: value.item.name,
|
|
1487
|
+
tools: functionTools,
|
|
1488
|
+
});
|
|
1489
|
+
|
|
1453
1490
|
ongoingToolCalls[value.output_index] = {
|
|
1454
1491
|
toolName: value.item.name,
|
|
1455
1492
|
toolCallId: value.item.call_id,
|
|
1493
|
+
suppressInputStreaming,
|
|
1494
|
+
bufferedInputDeltas: suppressInputStreaming ? [] : undefined,
|
|
1456
1495
|
};
|
|
1457
1496
|
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1497
|
+
if (!suppressInputStreaming) {
|
|
1498
|
+
controller.enqueue({
|
|
1499
|
+
type: 'tool-input-start',
|
|
1500
|
+
id: value.item.call_id,
|
|
1501
|
+
toolName: value.item.name,
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
1463
1504
|
} else if (value.item.type === 'custom_tool_call') {
|
|
1464
1505
|
const toolName = toolNameMapping.toCustomToolName(
|
|
1465
1506
|
value.item.name,
|
|
@@ -1697,43 +1738,120 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1697
1738
|
});
|
|
1698
1739
|
activeOutputItemIds[value.output_index] = undefined;
|
|
1699
1740
|
} else if (value.item.type === 'function_call') {
|
|
1741
|
+
const item = value.item;
|
|
1742
|
+
const ongoingToolCall = ongoingToolCalls[value.output_index];
|
|
1700
1743
|
ongoingToolCalls[value.output_index] = undefined;
|
|
1701
1744
|
hasFunctionCall = true;
|
|
1702
1745
|
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1746
|
+
const suppressInputStreaming =
|
|
1747
|
+
ongoingToolCall?.suppressInputStreaming ??
|
|
1748
|
+
isUndeclaredParallelToolCall({
|
|
1749
|
+
toolName: item.name,
|
|
1750
|
+
tools: functionTools,
|
|
1751
|
+
});
|
|
1752
|
+
|
|
1753
|
+
const enqueueUnexpandedToolCall = () => {
|
|
1754
|
+
if (suppressInputStreaming) {
|
|
1755
|
+
controller.enqueue({
|
|
1756
|
+
type: 'tool-input-start',
|
|
1757
|
+
id: item.call_id,
|
|
1758
|
+
toolName: item.name,
|
|
1759
|
+
});
|
|
1760
|
+
|
|
1761
|
+
const bufferedInputDeltas =
|
|
1762
|
+
ongoingToolCall?.bufferedInputDeltas ?? [];
|
|
1763
|
+
|
|
1764
|
+
if (bufferedInputDeltas.length > 0) {
|
|
1765
|
+
for (const delta of bufferedInputDeltas) {
|
|
1766
|
+
controller.enqueue({
|
|
1767
|
+
type: 'tool-input-delta',
|
|
1768
|
+
id: item.call_id,
|
|
1769
|
+
delta,
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
} else if (item.arguments.length > 0) {
|
|
1773
|
+
controller.enqueue({
|
|
1774
|
+
type: 'tool-input-delta',
|
|
1775
|
+
id: item.call_id,
|
|
1776
|
+
delta: item.arguments,
|
|
1777
|
+
});
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
controller.enqueue({
|
|
1782
|
+
type: 'tool-input-end',
|
|
1783
|
+
id: item.call_id,
|
|
1784
|
+
...(item.namespace != null && {
|
|
1785
|
+
providerMetadata: {
|
|
1786
|
+
[providerOptionsName]: {
|
|
1787
|
+
namespace: item.namespace,
|
|
1788
|
+
},
|
|
1789
|
+
},
|
|
1790
|
+
}),
|
|
1791
|
+
});
|
|
1792
|
+
|
|
1793
|
+
controller.enqueue({
|
|
1794
|
+
type: 'tool-call',
|
|
1795
|
+
toolCallId: item.call_id,
|
|
1796
|
+
toolName: item.name,
|
|
1797
|
+
input: item.arguments,
|
|
1707
1798
|
providerMetadata: {
|
|
1708
1799
|
[providerOptionsName]: {
|
|
1709
|
-
|
|
1800
|
+
itemId: item.id,
|
|
1801
|
+
...(item.namespace != null && {
|
|
1802
|
+
namespace: item.namespace,
|
|
1803
|
+
}),
|
|
1804
|
+
...(item.caller != null && {
|
|
1805
|
+
caller:
|
|
1806
|
+
item.caller.type === 'program'
|
|
1807
|
+
? {
|
|
1808
|
+
type: 'program',
|
|
1809
|
+
callerId: item.caller.caller_id,
|
|
1810
|
+
}
|
|
1811
|
+
: item.caller,
|
|
1812
|
+
}),
|
|
1710
1813
|
},
|
|
1711
1814
|
},
|
|
1712
|
-
})
|
|
1713
|
-
}
|
|
1815
|
+
});
|
|
1816
|
+
};
|
|
1714
1817
|
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
}),
|
|
1726
|
-
...(value.item.caller != null && {
|
|
1727
|
-
caller:
|
|
1728
|
-
value.item.caller.type === 'program'
|
|
1729
|
-
? {
|
|
1730
|
-
type: 'program',
|
|
1731
|
-
callerId: value.item.caller.caller_id,
|
|
1732
|
-
}
|
|
1733
|
-
: value.item.caller,
|
|
1734
|
-
}),
|
|
1735
|
-
},
|
|
1818
|
+
if (!suppressInputStreaming) {
|
|
1819
|
+
enqueueUnexpandedToolCall();
|
|
1820
|
+
return;
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
return expandParallelToolCall({
|
|
1824
|
+
toolCall: {
|
|
1825
|
+
toolCallId: item.call_id,
|
|
1826
|
+
toolName: item.name,
|
|
1827
|
+
input: item.arguments,
|
|
1736
1828
|
},
|
|
1829
|
+
tools: functionTools,
|
|
1830
|
+
providerOptionsName,
|
|
1831
|
+
itemId: item.id,
|
|
1832
|
+
}).then(expandedToolCalls => {
|
|
1833
|
+
if (expandedToolCalls == null) {
|
|
1834
|
+
enqueueUnexpandedToolCall();
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
for (const toolCall of expandedToolCalls) {
|
|
1839
|
+
controller.enqueue({
|
|
1840
|
+
type: 'tool-input-start',
|
|
1841
|
+
id: toolCall.toolCallId,
|
|
1842
|
+
toolName: toolCall.toolName,
|
|
1843
|
+
});
|
|
1844
|
+
controller.enqueue({
|
|
1845
|
+
type: 'tool-input-delta',
|
|
1846
|
+
id: toolCall.toolCallId,
|
|
1847
|
+
delta: toolCall.input,
|
|
1848
|
+
});
|
|
1849
|
+
controller.enqueue({
|
|
1850
|
+
type: 'tool-input-end',
|
|
1851
|
+
id: toolCall.toolCallId,
|
|
1852
|
+
});
|
|
1853
|
+
controller.enqueue(toolCall);
|
|
1854
|
+
}
|
|
1737
1855
|
});
|
|
1738
1856
|
} else if (value.item.type === 'program') {
|
|
1739
1857
|
controller.enqueue({
|
|
@@ -2216,11 +2334,15 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
2216
2334
|
const toolCall = ongoingToolCalls[value.output_index];
|
|
2217
2335
|
|
|
2218
2336
|
if (toolCall != null) {
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2337
|
+
if (toolCall.suppressInputStreaming) {
|
|
2338
|
+
toolCall.bufferedInputDeltas?.push(value.delta);
|
|
2339
|
+
} else {
|
|
2340
|
+
controller.enqueue({
|
|
2341
|
+
type: 'tool-input-delta',
|
|
2342
|
+
id: toolCall.toolCallId,
|
|
2343
|
+
delta: value.delta,
|
|
2344
|
+
});
|
|
2345
|
+
}
|
|
2224
2346
|
}
|
|
2225
2347
|
} else if (isResponseCustomToolCallInputDeltaChunk(value)) {
|
|
2226
2348
|
const toolCall = ongoingToolCalls[value.output_index];
|
|
@@ -2561,6 +2683,26 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
2561
2683
|
},
|
|
2562
2684
|
|
|
2563
2685
|
flush(controller) {
|
|
2686
|
+
for (const toolCall of Object.values(ongoingToolCalls)) {
|
|
2687
|
+
if (!toolCall?.suppressInputStreaming) {
|
|
2688
|
+
continue;
|
|
2689
|
+
}
|
|
2690
|
+
|
|
2691
|
+
controller.enqueue({
|
|
2692
|
+
type: 'tool-input-start',
|
|
2693
|
+
id: toolCall.toolCallId,
|
|
2694
|
+
toolName: toolCall.toolName,
|
|
2695
|
+
});
|
|
2696
|
+
|
|
2697
|
+
for (const delta of toolCall.bufferedInputDeltas ?? []) {
|
|
2698
|
+
controller.enqueue({
|
|
2699
|
+
type: 'tool-input-delta',
|
|
2700
|
+
id: toolCall.toolCallId,
|
|
2701
|
+
delta,
|
|
2702
|
+
});
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2564
2706
|
const providerMetadata: SharedV4ProviderMetadata = {
|
|
2565
2707
|
[providerOptionsName]: {
|
|
2566
2708
|
responseId: responseId,
|