@openclaw/ai 2026.7.2-beta.1 → 2026.7.2-beta.3
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/dist/{anthropic-Cvm71xlk.mjs → anthropic-D7SyZQ5v.mjs} +58 -39
- package/dist/{api-registry-Byvoz8Ha.d.mts → api-registry-DXBIXISf.d.mts} +1 -1
- package/dist/{azure-openai-responses-b4lfJxYS.mjs → azure-openai-responses-BkZgyZ3I.mjs} +5 -4
- package/dist/{event-stream-uQspnL8S.d.mts → event-stream-BPemFrFW.d.mts} +1 -1
- package/dist/event-stream.d.mts +1 -1
- package/dist/{google-C7PoDjpW.mjs → google-C_biGbV7.mjs} +2 -2
- package/dist/{google-shared-C7ohrmOI.mjs → google-shared-BK-NoHl8.mjs} +5 -4
- package/dist/{google-vertex-L_ABazIA.mjs → google-vertex-CvdzF1U7.mjs} +2 -2
- package/dist/index.d.mts +4 -4
- package/dist/internal/anthropic.d.mts +8 -2
- package/dist/internal/anthropic.mjs +3 -3
- package/dist/internal/openai.d.mts +27 -2
- package/dist/internal/openai.mjs +5 -5
- package/dist/internal/runtime.d.mts +2 -2
- package/dist/internal/runtime.mjs +3 -2
- package/dist/internal/shared.d.mts +13 -2
- package/dist/internal/shared.mjs +2 -2
- package/dist/{mistral-D-39Trax.mjs → mistral-BdrQmDWp.mjs} +25 -9
- package/dist/{model-utils-Q1LSRIdo.mjs → model-utils-1GiZ2_rr.mjs} +3 -1
- package/dist/{openai-chatgpt-responses-DCA0K85L.mjs → openai-chatgpt-responses-DP63Qt01.mjs} +11 -9
- package/dist/{openai-completions-B2jr3vtJ.mjs → openai-completions-zLDfebnN.mjs} +42 -21
- package/dist/{openai-responses-DTpD8YVy.mjs → openai-responses-ClspWt4I.mjs} +3 -3
- package/dist/{openai-responses-shared-B9mtGvXq.mjs → openai-responses-shared-CwnGU0KW.mjs} +412 -284
- package/dist/{openai-tool-projection-cTLC4F65.mjs → openai-tool-projection-WHf2nuOI.mjs} +1 -1
- package/dist/provider-error-LMfTEkfO.mjs +40 -0
- package/dist/providers.d.mts +1 -1
- package/dist/providers.mjs +8 -8
- package/dist/{transform-messages-DNWpwvXA.mjs → transform-messages-eb6lxDLB.mjs} +18 -3
- package/dist/{types-Cx2zJtyz.d.mts → types-CYORveZ7.d.mts} +6 -0
- package/dist/types.d.mts +3 -3
- package/dist/{validation-Cej7htKc.d.mts → validation-BX8euiDv.d.mts} +1 -1
- package/dist/validation.d.mts +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { n as getAiTransportHost } from "./host-4t713IeR.mjs";
|
|
2
|
-
import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-
|
|
2
|
+
import { n as calculateCost, r as clampThinkingLevel } from "./model-utils-1GiZ2_rr.mjs";
|
|
3
3
|
import { t as headersToRecord } from "./headers-B_e4-1J0.mjs";
|
|
4
4
|
import { n as parseStreamingJson } from "./json-parse-BvXNt1-7.mjs";
|
|
5
5
|
import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { D as normalizeLowercaseStringOrEmpty, O as normalizeOptionalString, f as isRecord, i as extractToolResultText, n as describeToolResultMediaPlaceholder, o as isImageWithMediaPayload, t as transformMessages, w as stripSystemPromptCacheBoundary } from "./transform-messages-eb6lxDLB.mjs";
|
|
7
7
|
import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-RjWszj8c.mjs";
|
|
8
|
-
import { t as projectOpenAITools } from "./openai-tool-projection-
|
|
8
|
+
import { t as projectOpenAITools } from "./openai-tool-projection-WHf2nuOI.mjs";
|
|
9
9
|
import { t as shortHash } from "./hash-CHgqbJmD.mjs";
|
|
10
10
|
import { createHash, randomUUID } from "node:crypto";
|
|
11
11
|
//#region packages/normalization-core/src/string-normalization.ts
|
|
@@ -1076,6 +1076,82 @@ function resolveResponsesMessageSnapshotCollapse(params) {
|
|
|
1076
1076
|
return { kind: "keep" };
|
|
1077
1077
|
}
|
|
1078
1078
|
//#endregion
|
|
1079
|
+
//#region packages/ai/src/providers/openai-responses-tool-call-tracker.ts
|
|
1080
|
+
function readIdentityValue(value) {
|
|
1081
|
+
return (typeof value === "string" ? value.trim() : "") || void 0;
|
|
1082
|
+
}
|
|
1083
|
+
function readOutputIndex(event) {
|
|
1084
|
+
return typeof event.output_index === "number" && Number.isInteger(event.output_index) && event.output_index >= 0 ? event.output_index : void 0;
|
|
1085
|
+
}
|
|
1086
|
+
function readEventIdentity(event) {
|
|
1087
|
+
return { itemId: readIdentityValue(event.item_id) };
|
|
1088
|
+
}
|
|
1089
|
+
function readResponsesToolCallItemIdentity(item) {
|
|
1090
|
+
return {
|
|
1091
|
+
itemId: readIdentityValue(item.id),
|
|
1092
|
+
callId: readIdentityValue(item.call_id)
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
function createResponsesToolCallTracker() {
|
|
1096
|
+
const indexedCalls = /* @__PURE__ */ new Map();
|
|
1097
|
+
const unindexedCalls = /* @__PURE__ */ new Set();
|
|
1098
|
+
const identitiesConflict = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId !== identity.itemId || state.callId && identity.callId && state.callId !== identity.callId);
|
|
1099
|
+
const sharesIdentity = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId === identity.itemId || state.callId && identity.callId && state.callId === identity.callId);
|
|
1100
|
+
const adoptIdentity = (state, identity) => {
|
|
1101
|
+
state.itemId ??= identity.itemId;
|
|
1102
|
+
state.callId ??= identity.callId;
|
|
1103
|
+
return state;
|
|
1104
|
+
};
|
|
1105
|
+
const resolveCompatible = (candidates, identity) => {
|
|
1106
|
+
const uniqueCandidates = [...new Set(candidates)];
|
|
1107
|
+
if (!identity.itemId && !identity.callId) return uniqueCandidates.length === 1 ? uniqueCandidates.at(0) : void 0;
|
|
1108
|
+
const compatible = uniqueCandidates.filter((state) => !identitiesConflict(state, identity));
|
|
1109
|
+
const matches = compatible.filter((state) => sharesIdentity(state, identity));
|
|
1110
|
+
const matched = matches.length === 1 ? matches.at(0) : void 0;
|
|
1111
|
+
if (matched) return adoptIdentity(matched, identity);
|
|
1112
|
+
const soleCompatible = uniqueCandidates.length === 1 && compatible.length === 1 && matches.length === 0 ? compatible.at(0) : void 0;
|
|
1113
|
+
return soleCompatible ? adoptIdentity(soleCompatible, identity) : void 0;
|
|
1114
|
+
};
|
|
1115
|
+
return {
|
|
1116
|
+
register(event, state) {
|
|
1117
|
+
const outputIndex = readOutputIndex(event);
|
|
1118
|
+
if (outputIndex === void 0) {
|
|
1119
|
+
unindexedCalls.add(state);
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
if (indexedCalls.has(outputIndex)) throw new Error(`Responses stream reused active tool-call output index ${outputIndex}`);
|
|
1123
|
+
indexedCalls.set(outputIndex, state);
|
|
1124
|
+
},
|
|
1125
|
+
resolve(event, identity = readEventIdentity(event)) {
|
|
1126
|
+
const outputIndex = readOutputIndex(event);
|
|
1127
|
+
if (outputIndex !== void 0) {
|
|
1128
|
+
const indexed = indexedCalls.get(outputIndex);
|
|
1129
|
+
if (indexed) {
|
|
1130
|
+
if (indexed.callId && identity.callId && indexed.callId !== identity.callId) return;
|
|
1131
|
+
return adoptIdentity(indexed, identity);
|
|
1132
|
+
}
|
|
1133
|
+
const unindexed = resolveCompatible(unindexedCalls, identity);
|
|
1134
|
+
if (unindexed) {
|
|
1135
|
+
unindexedCalls.delete(unindexed);
|
|
1136
|
+
indexedCalls.set(outputIndex, unindexed);
|
|
1137
|
+
}
|
|
1138
|
+
return unindexed;
|
|
1139
|
+
}
|
|
1140
|
+
return resolveCompatible([...indexedCalls.values(), ...unindexedCalls], identity);
|
|
1141
|
+
},
|
|
1142
|
+
forget(toolCall) {
|
|
1143
|
+
for (const [outputIndex, tracked] of indexedCalls) if (tracked === toolCall) indexedCalls.delete(outputIndex);
|
|
1144
|
+
unindexedCalls.delete(toolCall);
|
|
1145
|
+
},
|
|
1146
|
+
markArgumentsUnreliable() {
|
|
1147
|
+
for (const toolCall of /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls])) toolCall.argumentStreamReliable = false;
|
|
1148
|
+
},
|
|
1149
|
+
hasActive() {
|
|
1150
|
+
return indexedCalls.size > 0 || unindexedCalls.size > 0;
|
|
1151
|
+
}
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
//#endregion
|
|
1079
1155
|
//#region packages/ai/src/providers/openai-tool-schema.ts
|
|
1080
1156
|
/**
|
|
1081
1157
|
* OpenAI strict JSON-schema normalization for tool inventories and request payloads.
|
|
@@ -1386,7 +1462,8 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
|
|
|
1386
1462
|
};
|
|
1387
1463
|
const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
|
|
1388
1464
|
if ((options?.includeSystemPrompt ?? true) && context.systemPrompt) {
|
|
1389
|
-
const
|
|
1465
|
+
const compat = model.compat;
|
|
1466
|
+
const role = model.reasoning && compat?.supportsDeveloperRole !== false ? "developer" : "system";
|
|
1390
1467
|
messages.push({
|
|
1391
1468
|
type: "message",
|
|
1392
1469
|
role,
|
|
@@ -1484,7 +1561,7 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
|
|
|
1484
1561
|
} else if (msg.role === "toolResult") {
|
|
1485
1562
|
const textResult = extractToolResultText(msg.content);
|
|
1486
1563
|
const sanitizedTextResult = sanitizeSurrogates(textResult);
|
|
1487
|
-
const hasImages = msg.content.some(
|
|
1564
|
+
const hasImages = msg.content.some(isImageWithMediaPayload);
|
|
1488
1565
|
const mediaPlaceholder = describeToolResultMediaPlaceholder(msg.content);
|
|
1489
1566
|
const hasText = sanitizedTextResult.trim().length > 0;
|
|
1490
1567
|
const [callId] = splitResponsesToolCallId(msg.toolCallId);
|
|
@@ -1499,7 +1576,7 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
|
|
|
1499
1576
|
type: "input_text",
|
|
1500
1577
|
text: mediaPlaceholder
|
|
1501
1578
|
});
|
|
1502
|
-
for (const block of msg.content) if (block
|
|
1579
|
+
for (const block of msg.content) if (isImageWithMediaPayload(block)) contentParts.push({
|
|
1503
1580
|
type: "input_image",
|
|
1504
1581
|
detail: "auto",
|
|
1505
1582
|
image_url: `data:${block.mimeType};base64,${block.data}`
|
|
@@ -1555,7 +1632,7 @@ function resolveResponsesReasoningEffort(model, reasoning) {
|
|
|
1555
1632
|
return clampedReasoning;
|
|
1556
1633
|
}
|
|
1557
1634
|
function applyCommonResponsesParams(params, model, context, options, config) {
|
|
1558
|
-
if (options?.maxTokens) params.max_output_tokens = options.maxTokens;
|
|
1635
|
+
if (options?.maxTokens) params.max_output_tokens = Math.max(options.maxTokens, 16);
|
|
1559
1636
|
if (options?.temperature !== void 0 && supportsOpenAITemperature(model)) params.temperature = options.temperature;
|
|
1560
1637
|
if (context.tools) {
|
|
1561
1638
|
const converted = convertResponsesToolPayload(context.tools, { model });
|
|
@@ -1574,7 +1651,7 @@ function buildResponsesRequestOptions(options) {
|
|
|
1574
1651
|
return {
|
|
1575
1652
|
...options?.signal ? { signal: options.signal } : {},
|
|
1576
1653
|
...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
|
|
1577
|
-
|
|
1654
|
+
maxRetries: options?.maxRetries ?? 0
|
|
1578
1655
|
};
|
|
1579
1656
|
}
|
|
1580
1657
|
function cleanStreamingScratchBuffers(output) {
|
|
@@ -1613,7 +1690,7 @@ async function runResponsesStreamLifecycle(params) {
|
|
|
1613
1690
|
onFirstEventTimeout: params.processStreamOptions?.onFirstEventTimeout ?? onFirstEventTimeout
|
|
1614
1691
|
} : void 0);
|
|
1615
1692
|
if (options?.signal?.aborted) throw new Error("Request was aborted");
|
|
1616
|
-
if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error("An unknown error occurred");
|
|
1693
|
+
if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage ?? "An unknown error occurred");
|
|
1617
1694
|
stream.push({
|
|
1618
1695
|
type: "done",
|
|
1619
1696
|
reason: output.stopReason,
|
|
@@ -1635,62 +1712,52 @@ async function runResponsesStreamLifecycle(params) {
|
|
|
1635
1712
|
}
|
|
1636
1713
|
}
|
|
1637
1714
|
async function processResponsesStream(openaiStream, output, stream, model, options) {
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
const
|
|
1641
|
-
|
|
1715
|
+
const streamingToolCalls = createResponsesToolCallTracker();
|
|
1716
|
+
const outputSlots = /* @__PURE__ */ new Map();
|
|
1717
|
+
const reasoningBlocksById = /* @__PURE__ */ new Map();
|
|
1718
|
+
let unindexedOutputSlot;
|
|
1719
|
+
let terminalResponseEvent;
|
|
1642
1720
|
let lastTextBlock = null;
|
|
1643
|
-
let pendingMessageText = null;
|
|
1644
1721
|
const blocks = output.content;
|
|
1645
1722
|
const blockIndex = () => blocks.length - 1;
|
|
1646
|
-
const readOutputIndex = (event) =>
|
|
1647
|
-
|
|
1648
|
-
return
|
|
1723
|
+
const readOutputIndex = (event) => {
|
|
1724
|
+
const outputIndex = event.output_index;
|
|
1725
|
+
return typeof outputIndex === "number" && Number.isInteger(outputIndex) && outputIndex >= 0 ? outputIndex : void 0;
|
|
1649
1726
|
};
|
|
1650
|
-
const
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
state.callId ??= identity.callId;
|
|
1660
|
-
return state;
|
|
1727
|
+
const registerOutputSlot = (event, slot) => {
|
|
1728
|
+
const outputIndex = readOutputIndex(event);
|
|
1729
|
+
if (outputIndex === void 0) {
|
|
1730
|
+
if (unindexedOutputSlot) throw new Error("Responses stream added overlapping unindexed output items");
|
|
1731
|
+
unindexedOutputSlot = slot;
|
|
1732
|
+
return;
|
|
1733
|
+
}
|
|
1734
|
+
if (outputSlots.has(outputIndex)) throw new Error(`Responses stream reused active output index ${outputIndex}`);
|
|
1735
|
+
outputSlots.set(outputIndex, slot);
|
|
1661
1736
|
};
|
|
1662
|
-
const
|
|
1663
|
-
const
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
return soleCompatible ? adoptToolCallIdentity(soleCompatible, identity) : void 0;
|
|
1737
|
+
const resolveOutputSlot = (event, type) => {
|
|
1738
|
+
const outputIndex = readOutputIndex(event);
|
|
1739
|
+
let slot = outputIndex === void 0 ? unindexedOutputSlot : outputSlots.get(outputIndex);
|
|
1740
|
+
if (outputIndex === void 0 && !slot) {
|
|
1741
|
+
const matchingSlots = [...outputSlots.values()].filter((candidate) => candidate.type === type);
|
|
1742
|
+
slot = matchingSlots.length === 1 ? matchingSlots[0] : void 0;
|
|
1743
|
+
}
|
|
1744
|
+
return slot?.type === type ? slot : void 0;
|
|
1671
1745
|
};
|
|
1672
|
-
const
|
|
1746
|
+
const forgetOutputSlot = (event, slot) => {
|
|
1673
1747
|
const outputIndex = readOutputIndex(event);
|
|
1674
|
-
if (outputIndex
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
if (unindexed) {
|
|
1679
|
-
unindexedToolCalls.delete(unindexed);
|
|
1680
|
-
toolCallsByOutputIndex.set(outputIndex, unindexed);
|
|
1681
|
-
}
|
|
1682
|
-
return unindexed;
|
|
1748
|
+
if (outputIndex === void 0) {
|
|
1749
|
+
if (unindexedOutputSlot === slot) unindexedOutputSlot = void 0;
|
|
1750
|
+
else for (const [indexedOutput, indexedSlot] of outputSlots) if (indexedSlot === slot) outputSlots.delete(indexedOutput);
|
|
1751
|
+
return;
|
|
1683
1752
|
}
|
|
1684
|
-
|
|
1753
|
+
if (outputSlots.get(outputIndex) === slot) outputSlots.delete(outputIndex);
|
|
1685
1754
|
};
|
|
1686
|
-
const
|
|
1687
|
-
for (const [
|
|
1688
|
-
unindexedToolCalls.delete(toolCall);
|
|
1755
|
+
const forgetToolCallOutputSlot = (toolCall) => {
|
|
1756
|
+
for (const [outputIndex, slot] of outputSlots) if (slot.type === "toolCall" && slot.toolCall === toolCall) outputSlots.delete(outputIndex);
|
|
1689
1757
|
};
|
|
1690
|
-
const
|
|
1691
|
-
|
|
1758
|
+
const readIdentityValue = (value) => {
|
|
1759
|
+
return (typeof value === "string" ? value.trim() : "") || void 0;
|
|
1692
1760
|
};
|
|
1693
|
-
const hasActiveStreamingToolCall = () => toolCallsByOutputIndex.size > 0 || unindexedToolCalls.size > 0;
|
|
1694
1761
|
const resolveCompletedToolCallName = (toolCall, value) => {
|
|
1695
1762
|
const streamedName = readIdentityValue(toolCall?.block.name);
|
|
1696
1763
|
const completedName = readIdentityValue(value);
|
|
@@ -1699,28 +1766,143 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
1699
1766
|
if (!name) throw new Error("Responses stream completed tool call without a function name");
|
|
1700
1767
|
return name;
|
|
1701
1768
|
};
|
|
1702
|
-
const
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1769
|
+
const createOutputSlot = (event, item) => {
|
|
1770
|
+
if (item.type === "reasoning") {
|
|
1771
|
+
const block = {
|
|
1772
|
+
type: "thinking",
|
|
1773
|
+
thinking: ""
|
|
1774
|
+
};
|
|
1775
|
+
const slot = {
|
|
1776
|
+
type: "thinking",
|
|
1777
|
+
item,
|
|
1778
|
+
block,
|
|
1779
|
+
contentIndex: blocks.length
|
|
1780
|
+
};
|
|
1781
|
+
blocks.push(block);
|
|
1782
|
+
registerOutputSlot(event, slot);
|
|
1783
|
+
stream.push({
|
|
1784
|
+
type: "thinking_start",
|
|
1785
|
+
contentIndex: slot.contentIndex,
|
|
1786
|
+
partial: output
|
|
1787
|
+
});
|
|
1788
|
+
return slot;
|
|
1789
|
+
}
|
|
1790
|
+
if (item.type === "message") {
|
|
1791
|
+
const messageItem = item;
|
|
1792
|
+
const collapseCandidate = lastTextBlock;
|
|
1793
|
+
const block = collapseCandidate ? null : {
|
|
1794
|
+
type: "text",
|
|
1795
|
+
text: "",
|
|
1796
|
+
...messageItem.phase ? { textSignature: encodeTextSignatureV1(messageItem.id, messageItem.phase) } : {}
|
|
1797
|
+
};
|
|
1798
|
+
const slot = {
|
|
1799
|
+
type: "text",
|
|
1800
|
+
item: messageItem,
|
|
1801
|
+
block,
|
|
1802
|
+
contentIndex: block ? blocks.length : void 0,
|
|
1803
|
+
pendingText: collapseCandidate ? "" : null,
|
|
1804
|
+
collapseCandidate
|
|
1805
|
+
};
|
|
1806
|
+
if (block) blocks.push(block);
|
|
1807
|
+
registerOutputSlot(event, slot);
|
|
1808
|
+
if (slot.contentIndex !== void 0) stream.push({
|
|
1809
|
+
type: "text_start",
|
|
1810
|
+
contentIndex: slot.contentIndex,
|
|
1811
|
+
partial: output
|
|
1812
|
+
});
|
|
1813
|
+
return slot;
|
|
1814
|
+
}
|
|
1815
|
+
};
|
|
1816
|
+
const resolveOutputItemSlot = (event, item) => {
|
|
1817
|
+
if (item.type === "reasoning") return resolveOutputSlot(event, "thinking");
|
|
1818
|
+
if (item.type === "message") return resolveOutputSlot(event, "text");
|
|
1819
|
+
const outputIndex = readOutputIndex(event);
|
|
1820
|
+
return outputIndex === void 0 ? void 0 : outputSlots.get(outputIndex);
|
|
1821
|
+
};
|
|
1822
|
+
const getOrCreateOutputSlot = (event, item) => {
|
|
1823
|
+
return resolveOutputItemSlot(event, item) ?? createOutputSlot(event, item);
|
|
1824
|
+
};
|
|
1825
|
+
const materializeDeferredTextSlot = (slot) => {
|
|
1826
|
+
if (slot.block || slot.pendingText === null) return;
|
|
1827
|
+
const text = slot.pendingText;
|
|
1828
|
+
slot.block = {
|
|
1707
1829
|
type: "text",
|
|
1708
|
-
text
|
|
1709
|
-
...
|
|
1830
|
+
text,
|
|
1831
|
+
...slot.item.phase ? { textSignature: encodeTextSignatureV1(slot.item.id, slot.item.phase) } : {}
|
|
1710
1832
|
};
|
|
1711
|
-
blocks.push(
|
|
1833
|
+
blocks.push(slot.block);
|
|
1834
|
+
slot.contentIndex = blockIndex();
|
|
1712
1835
|
stream.push({
|
|
1713
1836
|
type: "text_start",
|
|
1714
|
-
contentIndex:
|
|
1837
|
+
contentIndex: slot.contentIndex,
|
|
1715
1838
|
partial: output
|
|
1716
1839
|
});
|
|
1717
|
-
stream.push({
|
|
1840
|
+
if (text) stream.push({
|
|
1718
1841
|
type: "text_delta",
|
|
1719
|
-
contentIndex:
|
|
1720
|
-
delta:
|
|
1842
|
+
contentIndex: slot.contentIndex,
|
|
1843
|
+
delta: text,
|
|
1721
1844
|
partial: output
|
|
1722
1845
|
});
|
|
1723
|
-
|
|
1846
|
+
if (lastTextBlock === slot.collapseCandidate) lastTextBlock = null;
|
|
1847
|
+
slot.pendingText = null;
|
|
1848
|
+
slot.collapseCandidate = null;
|
|
1849
|
+
};
|
|
1850
|
+
const materializeDeferredTextSlots = (except) => {
|
|
1851
|
+
for (const slot of outputSlots.values()) if (slot !== except && slot.type === "text") materializeDeferredTextSlot(slot);
|
|
1852
|
+
if (unindexedOutputSlot !== except && unindexedOutputSlot?.type === "text") materializeDeferredTextSlot(unindexedOutputSlot);
|
|
1853
|
+
};
|
|
1854
|
+
const appendPendingMessageDelta = (slot, delta) => {
|
|
1855
|
+
slot.pendingText = `${slot.pendingText ?? ""}${delta}`;
|
|
1856
|
+
const priorText = slot.collapseCandidate?.block.text ?? "";
|
|
1857
|
+
if (priorText.startsWith(slot.pendingText) || slot.pendingText.startsWith(priorText)) return;
|
|
1858
|
+
materializeDeferredTextSlot(slot);
|
|
1859
|
+
};
|
|
1860
|
+
const backfillReasoningSignatures = (responseOutput) => {
|
|
1861
|
+
for (const item of responseOutput) {
|
|
1862
|
+
if (item.type !== "reasoning" || !item.encrypted_content) continue;
|
|
1863
|
+
const block = reasoningBlocksById.get(item.id);
|
|
1864
|
+
if (!block?.thinkingSignature) continue;
|
|
1865
|
+
const storedItem = JSON.parse(block.thinkingSignature);
|
|
1866
|
+
if (storedItem.encrypted_content) continue;
|
|
1867
|
+
block.thinkingSignature = JSON.stringify({
|
|
1868
|
+
...storedItem,
|
|
1869
|
+
encrypted_content: item.encrypted_content
|
|
1870
|
+
});
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
const finalizeResponse = (response) => {
|
|
1874
|
+
terminalResponseEvent = "finalized";
|
|
1875
|
+
backfillReasoningSignatures(response.output ?? []);
|
|
1876
|
+
if (response.id) output.responseId = response.id;
|
|
1877
|
+
if (response.usage) {
|
|
1878
|
+
const inputTokenDetails = response.usage.input_tokens_details;
|
|
1879
|
+
const cachedTokens = inputTokenDetails?.cached_tokens || 0;
|
|
1880
|
+
const cacheWriteTokens = inputTokenDetails?.cache_write_tokens || 0;
|
|
1881
|
+
output.usage = {
|
|
1882
|
+
input: Math.max(0, (response.usage.input_tokens || 0) - cachedTokens - cacheWriteTokens),
|
|
1883
|
+
output: response.usage.output_tokens || 0,
|
|
1884
|
+
cacheRead: cachedTokens,
|
|
1885
|
+
cacheWrite: cacheWriteTokens,
|
|
1886
|
+
totalTokens: response.usage.total_tokens || 0,
|
|
1887
|
+
cost: {
|
|
1888
|
+
input: 0,
|
|
1889
|
+
output: 0,
|
|
1890
|
+
cacheRead: 0,
|
|
1891
|
+
cacheWrite: 0,
|
|
1892
|
+
total: 0
|
|
1893
|
+
}
|
|
1894
|
+
};
|
|
1895
|
+
}
|
|
1896
|
+
calculateCost(model, output.usage);
|
|
1897
|
+
if (options?.applyServiceTierPricing) {
|
|
1898
|
+
const serviceTier = options.resolveServiceTier ? options.resolveServiceTier(response.service_tier, options.serviceTier) : response.service_tier ?? options.serviceTier;
|
|
1899
|
+
options.applyServiceTierPricing(output.usage, serviceTier);
|
|
1900
|
+
}
|
|
1901
|
+
if (response.status === "incomplete" && response.incomplete_details?.reason === "content_filter") {
|
|
1902
|
+
output.stopReason = "error";
|
|
1903
|
+
output.errorMessage = "Provider incomplete_reason: content_filter";
|
|
1904
|
+
} else output.stopReason = mapStopReason(response.status);
|
|
1905
|
+
if (output.content.some((block) => block.type === "toolCall") && output.stopReason === "stop") output.stopReason = "toolUse";
|
|
1724
1906
|
};
|
|
1725
1907
|
const guardedStream = withFirstStreamEventTimeout(openaiStream, {
|
|
1726
1908
|
provider: model.provider,
|
|
@@ -1734,62 +1916,31 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
1734
1916
|
});
|
|
1735
1917
|
for await (const event of guardedStream) if (event.type === "response.created") output.responseId = event.response.id;
|
|
1736
1918
|
else if (event.type === "response.output_item.added") {
|
|
1919
|
+
materializeDeferredTextSlots();
|
|
1737
1920
|
const item = event.item;
|
|
1738
|
-
if (item.type !== "message")
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
if (item.type === "reasoning") {
|
|
1743
|
-
currentItem = item;
|
|
1744
|
-
currentBlock = {
|
|
1745
|
-
type: "thinking",
|
|
1746
|
-
thinking: ""
|
|
1747
|
-
};
|
|
1748
|
-
output.content.push(currentBlock);
|
|
1749
|
-
stream.push({
|
|
1750
|
-
type: "thinking_start",
|
|
1751
|
-
contentIndex: blockIndex(),
|
|
1752
|
-
partial: output
|
|
1753
|
-
});
|
|
1754
|
-
} else if (item.type === "message") {
|
|
1755
|
-
currentItem = item;
|
|
1756
|
-
if (lastTextBlock) {
|
|
1757
|
-
currentBlock = null;
|
|
1758
|
-
pendingMessageText = "";
|
|
1759
|
-
} else {
|
|
1760
|
-
currentBlock = {
|
|
1761
|
-
type: "text",
|
|
1762
|
-
text: "",
|
|
1763
|
-
...item.phase ? { textSignature: encodeTextSignatureV1(item.id, item.phase) } : {}
|
|
1764
|
-
};
|
|
1765
|
-
output.content.push(currentBlock);
|
|
1766
|
-
stream.push({
|
|
1767
|
-
type: "text_start",
|
|
1768
|
-
contentIndex: blockIndex(),
|
|
1769
|
-
partial: output
|
|
1770
|
-
});
|
|
1771
|
-
}
|
|
1772
|
-
} else if (item.type === "function_call") {
|
|
1773
|
-
const outputIndex = readOutputIndex(event);
|
|
1774
|
-
if (outputIndex !== void 0 && toolCallsByOutputIndex.has(outputIndex)) throw new Error(`Responses stream reused active tool-call output index ${outputIndex}`);
|
|
1775
|
-
currentItem = item;
|
|
1776
|
-
currentBlock = {
|
|
1921
|
+
if (item.type !== "message") lastTextBlock = null;
|
|
1922
|
+
if (item.type === "reasoning" || item.type === "message") createOutputSlot(event, item);
|
|
1923
|
+
else if (item.type === "function_call") {
|
|
1924
|
+
const toolCallBlock = {
|
|
1777
1925
|
type: "toolCall",
|
|
1778
1926
|
id: resolveResponsesToolCallId(item),
|
|
1779
1927
|
name: readIdentityValue(item.name) ?? "",
|
|
1780
1928
|
arguments: {},
|
|
1781
1929
|
partialJson: item.arguments || ""
|
|
1782
1930
|
};
|
|
1783
|
-
output.content.
|
|
1784
|
-
const contentIndex = blockIndex();
|
|
1931
|
+
const contentIndex = output.content.length;
|
|
1785
1932
|
const toolCallState = {
|
|
1786
|
-
block:
|
|
1933
|
+
block: toolCallBlock,
|
|
1787
1934
|
contentIndex,
|
|
1788
1935
|
argumentStreamReliable: true,
|
|
1789
|
-
...
|
|
1936
|
+
...readResponsesToolCallItemIdentity(item)
|
|
1790
1937
|
};
|
|
1791
|
-
|
|
1792
|
-
|
|
1938
|
+
streamingToolCalls.register(event, toolCallState);
|
|
1939
|
+
if (readOutputIndex(event) !== void 0) registerOutputSlot(event, {
|
|
1940
|
+
type: "toolCall",
|
|
1941
|
+
toolCall: toolCallState
|
|
1942
|
+
});
|
|
1943
|
+
output.content.push(toolCallBlock);
|
|
1793
1944
|
stream.push({
|
|
1794
1945
|
type: "toolcall_start",
|
|
1795
1946
|
contentIndex,
|
|
@@ -1797,116 +1948,110 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
1797
1948
|
});
|
|
1798
1949
|
}
|
|
1799
1950
|
} else if (event.type === "response.reasoning_summary_part.added") {
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1951
|
+
const slot = resolveOutputSlot(event, "thinking");
|
|
1952
|
+
if (!slot) continue;
|
|
1953
|
+
slot.item.summary = slot.item.summary || [];
|
|
1954
|
+
slot.item.summary.push(event.part);
|
|
1804
1955
|
} else if (event.type === "response.reasoning_summary_text.delta") {
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
}
|
|
1956
|
+
const slot = resolveOutputSlot(event, "thinking");
|
|
1957
|
+
if (!slot) continue;
|
|
1958
|
+
slot.item.summary = slot.item.summary || [];
|
|
1959
|
+
const lastPart = slot.item.summary[slot.item.summary.length - 1];
|
|
1960
|
+
if (!lastPart) continue;
|
|
1961
|
+
slot.block.thinking += event.delta;
|
|
1962
|
+
lastPart.text += event.delta;
|
|
1963
|
+
stream.push({
|
|
1964
|
+
type: "thinking_delta",
|
|
1965
|
+
contentIndex: slot.contentIndex,
|
|
1966
|
+
delta: event.delta,
|
|
1967
|
+
partial: output
|
|
1968
|
+
});
|
|
1819
1969
|
} else if (event.type === "response.reasoning_summary_part.done") {
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
}
|
|
1970
|
+
const slot = resolveOutputSlot(event, "thinking");
|
|
1971
|
+
if (!slot) continue;
|
|
1972
|
+
slot.item.summary = slot.item.summary || [];
|
|
1973
|
+
const lastPart = slot.item.summary[slot.item.summary.length - 1];
|
|
1974
|
+
if (!lastPart) continue;
|
|
1975
|
+
slot.block.thinking += "\n\n";
|
|
1976
|
+
lastPart.text += "\n\n";
|
|
1977
|
+
stream.push({
|
|
1978
|
+
type: "thinking_delta",
|
|
1979
|
+
contentIndex: slot.contentIndex,
|
|
1980
|
+
delta: "\n\n",
|
|
1981
|
+
partial: output
|
|
1982
|
+
});
|
|
1834
1983
|
} else if (event.type === "response.reasoning_text.delta") {
|
|
1835
|
-
|
|
1836
|
-
|
|
1984
|
+
const slot = resolveOutputSlot(event, "thinking");
|
|
1985
|
+
if (!slot) continue;
|
|
1986
|
+
slot.block.thinking += event.delta;
|
|
1987
|
+
stream.push({
|
|
1988
|
+
type: "thinking_delta",
|
|
1989
|
+
contentIndex: slot.contentIndex,
|
|
1990
|
+
delta: event.delta,
|
|
1991
|
+
partial: output
|
|
1992
|
+
});
|
|
1993
|
+
} else if (event.type === "response.content_part.added") {
|
|
1994
|
+
const slot = resolveOutputSlot(event, "text");
|
|
1995
|
+
if (!slot) continue;
|
|
1996
|
+
slot.item.content = slot.item.content || [];
|
|
1997
|
+
if (event.part.type === "output_text" || event.part.type === "text" || event.part.type === "refusal") slot.item.content.push(event.part);
|
|
1998
|
+
} else if (event.type === "response.output_text.delta") {
|
|
1999
|
+
const slot = resolveOutputSlot(event, "text");
|
|
2000
|
+
if (!slot?.item.content || slot.item.content.length === 0) continue;
|
|
2001
|
+
const lastPart = slot.item.content[slot.item.content.length - 1];
|
|
2002
|
+
if (!isResponsesTextContentPartType(lastPart?.type)) continue;
|
|
2003
|
+
lastPart.text += event.delta;
|
|
2004
|
+
if (slot.pendingText !== null) appendPendingMessageDelta(slot, event.delta);
|
|
2005
|
+
else if (slot.block && slot.contentIndex !== void 0) {
|
|
2006
|
+
slot.block.text += event.delta;
|
|
1837
2007
|
stream.push({
|
|
1838
|
-
type: "
|
|
1839
|
-
contentIndex:
|
|
2008
|
+
type: "text_delta",
|
|
2009
|
+
contentIndex: slot.contentIndex,
|
|
1840
2010
|
delta: event.delta,
|
|
1841
2011
|
partial: output
|
|
1842
2012
|
});
|
|
1843
2013
|
}
|
|
1844
|
-
} else if (event.type === "response.content_part.added") {
|
|
1845
|
-
if (currentItem?.type === "message") {
|
|
1846
|
-
currentItem.content = currentItem.content || [];
|
|
1847
|
-
if (event.part.type === "output_text" || event.part.type === "text" || event.part.type === "refusal") currentItem.content.push(event.part);
|
|
1848
|
-
}
|
|
1849
|
-
} else if (event.type === "response.output_text.delta") {
|
|
1850
|
-
if (currentItem?.type === "message") {
|
|
1851
|
-
if (!currentItem.content || currentItem.content.length === 0) continue;
|
|
1852
|
-
const lastPart = currentItem.content[currentItem.content.length - 1];
|
|
1853
|
-
if (isResponsesTextContentPartType(lastPart?.type)) {
|
|
1854
|
-
lastPart.text += event.delta;
|
|
1855
|
-
if (pendingMessageText !== null) appendPendingMessageDelta(event.delta);
|
|
1856
|
-
else if (currentBlock?.type === "text") {
|
|
1857
|
-
currentBlock.text += event.delta;
|
|
1858
|
-
stream.push({
|
|
1859
|
-
type: "text_delta",
|
|
1860
|
-
contentIndex: blockIndex(),
|
|
1861
|
-
delta: event.delta,
|
|
1862
|
-
partial: output
|
|
1863
|
-
});
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
}
|
|
1867
2014
|
} else if (isAzureResponsesTextDeltaEvent(event)) {
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
}
|
|
2015
|
+
const slot = resolveOutputSlot(event, "text");
|
|
2016
|
+
if (!slot) continue;
|
|
2017
|
+
slot.item.content = slot.item.content || [];
|
|
2018
|
+
let lastPart = slot.item.content[slot.item.content.length - 1];
|
|
2019
|
+
if (lastPart?.type !== "text") {
|
|
2020
|
+
lastPart = {
|
|
2021
|
+
type: "text",
|
|
2022
|
+
text: ""
|
|
2023
|
+
};
|
|
2024
|
+
slot.item.content.push(lastPart);
|
|
2025
|
+
}
|
|
2026
|
+
lastPart.text += event.delta;
|
|
2027
|
+
if (slot.pendingText !== null) appendPendingMessageDelta(slot, event.delta);
|
|
2028
|
+
else if (slot.block && slot.contentIndex !== void 0) {
|
|
2029
|
+
slot.block.text += event.delta;
|
|
2030
|
+
stream.push({
|
|
2031
|
+
type: "text_delta",
|
|
2032
|
+
contentIndex: slot.contentIndex,
|
|
2033
|
+
delta: event.delta,
|
|
2034
|
+
partial: output
|
|
2035
|
+
});
|
|
1889
2036
|
}
|
|
1890
2037
|
} else if (event.type === "response.refusal.delta") {
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
}
|
|
1906
|
-
}
|
|
2038
|
+
const slot = resolveOutputSlot(event, "text");
|
|
2039
|
+
if (!slot?.item.content || slot.item.content.length === 0) continue;
|
|
2040
|
+
const lastPart = slot.item.content[slot.item.content.length - 1];
|
|
2041
|
+
if (lastPart?.type !== "refusal") continue;
|
|
2042
|
+
lastPart.refusal += event.delta;
|
|
2043
|
+
if (slot.pendingText !== null) appendPendingMessageDelta(slot, event.delta);
|
|
2044
|
+
else if (slot.block && slot.contentIndex !== void 0) {
|
|
2045
|
+
slot.block.text += event.delta;
|
|
2046
|
+
stream.push({
|
|
2047
|
+
type: "text_delta",
|
|
2048
|
+
contentIndex: slot.contentIndex,
|
|
2049
|
+
delta: event.delta,
|
|
2050
|
+
partial: output
|
|
2051
|
+
});
|
|
1907
2052
|
}
|
|
1908
2053
|
} else if (event.type === "response.function_call_arguments.delta") {
|
|
1909
|
-
const toolCall =
|
|
2054
|
+
const toolCall = streamingToolCalls.resolve(event);
|
|
1910
2055
|
if (toolCall) {
|
|
1911
2056
|
toolCall.block.partialJson += event.delta;
|
|
1912
2057
|
toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
|
|
@@ -1916,9 +2061,9 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
1916
2061
|
delta: event.delta,
|
|
1917
2062
|
partial: output
|
|
1918
2063
|
});
|
|
1919
|
-
} else if (
|
|
2064
|
+
} else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
|
|
1920
2065
|
} else if (event.type === "response.function_call_arguments.done") {
|
|
1921
|
-
const toolCall =
|
|
2066
|
+
const toolCall = streamingToolCalls.resolve(event);
|
|
1922
2067
|
if (toolCall) {
|
|
1923
2068
|
const previousPartialJson = toolCall.block.partialJson;
|
|
1924
2069
|
const doneArguments = typeof event.arguments === "string" ? event.arguments : void 0;
|
|
@@ -1936,78 +2081,84 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
1936
2081
|
partial: output
|
|
1937
2082
|
});
|
|
1938
2083
|
}
|
|
1939
|
-
} else if (
|
|
2084
|
+
} else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
|
|
1940
2085
|
} else if (event.type === "response.output_item.done") {
|
|
1941
2086
|
const item = event.item;
|
|
1942
|
-
if (item.type !== "message")
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
if (item.type === "reasoning" &&
|
|
2087
|
+
if (item.type !== "message") lastTextBlock = null;
|
|
2088
|
+
const existingOutputSlot = resolveOutputItemSlot(event, item);
|
|
2089
|
+
materializeDeferredTextSlots(existingOutputSlot);
|
|
2090
|
+
const outputSlot = existingOutputSlot ?? getOrCreateOutputSlot(event, item);
|
|
2091
|
+
if (item.type === "reasoning" && outputSlot?.type === "thinking") {
|
|
1947
2092
|
const summaryText = item.summary?.map((s) => s.text).join("\n\n") || "";
|
|
1948
2093
|
const contentText = item.content?.map((c) => c.text).join("\n\n") || "";
|
|
1949
|
-
|
|
1950
|
-
|
|
2094
|
+
outputSlot.block.thinking = summaryText || contentText || outputSlot.block.thinking;
|
|
2095
|
+
outputSlot.block.thinkingSignature = JSON.stringify(item);
|
|
2096
|
+
if (typeof item.id === "string") reasoningBlocksById.set(item.id, outputSlot.block);
|
|
1951
2097
|
stream.push({
|
|
1952
2098
|
type: "thinking_end",
|
|
1953
|
-
contentIndex:
|
|
1954
|
-
content:
|
|
2099
|
+
contentIndex: outputSlot.contentIndex,
|
|
2100
|
+
content: outputSlot.block.thinking,
|
|
1955
2101
|
partial: output
|
|
1956
2102
|
});
|
|
1957
|
-
|
|
1958
|
-
} else if (item.type === "message" &&
|
|
1959
|
-
const
|
|
2103
|
+
forgetOutputSlot(event, outputSlot);
|
|
2104
|
+
} else if (item.type === "message" && outputSlot?.type === "text" && (outputSlot.block || outputSlot.pendingText !== null)) {
|
|
2105
|
+
const streamedText = outputSlot.pendingText ?? outputSlot.block?.text ?? "";
|
|
2106
|
+
const finalText = item.content == null ? streamedText : item.content.map((c) => c.type === "output_text" || c.type === "text" ? c.text : c.refusal).join("");
|
|
1960
2107
|
const phase = item.phase ?? void 0;
|
|
1961
|
-
const collapse =
|
|
1962
|
-
prior:
|
|
1963
|
-
text:
|
|
1964
|
-
phase:
|
|
2108
|
+
const collapse = outputSlot.pendingText !== null ? resolveResponsesMessageSnapshotCollapse({
|
|
2109
|
+
prior: outputSlot.collapseCandidate && {
|
|
2110
|
+
text: outputSlot.collapseCandidate.block.text,
|
|
2111
|
+
phase: outputSlot.collapseCandidate.phase
|
|
1965
2112
|
},
|
|
1966
2113
|
nextText: finalText,
|
|
1967
2114
|
nextPhase: phase
|
|
1968
2115
|
}) : { kind: "keep" };
|
|
1969
|
-
|
|
1970
|
-
if (collapse.kind === "extend" &&
|
|
1971
|
-
|
|
1972
|
-
|
|
2116
|
+
outputSlot.pendingText = null;
|
|
2117
|
+
if (collapse.kind === "extend" && outputSlot.collapseCandidate) {
|
|
2118
|
+
outputSlot.collapseCandidate.block.text = collapse.text;
|
|
2119
|
+
outputSlot.collapseCandidate.block.textSignature = encodeTextSignatureV1(item.id, phase);
|
|
1973
2120
|
stream.push({
|
|
1974
2121
|
type: "text_end",
|
|
1975
|
-
contentIndex:
|
|
2122
|
+
contentIndex: outputSlot.collapseCandidate.index,
|
|
1976
2123
|
content: collapse.text,
|
|
1977
2124
|
partial: output
|
|
1978
2125
|
});
|
|
2126
|
+
lastTextBlock = outputSlot.collapseCandidate;
|
|
1979
2127
|
} else {
|
|
1980
|
-
if (
|
|
1981
|
-
|
|
2128
|
+
if (!outputSlot.block) {
|
|
2129
|
+
outputSlot.block = {
|
|
1982
2130
|
type: "text",
|
|
1983
2131
|
text: "",
|
|
1984
2132
|
...phase ? { textSignature: encodeTextSignatureV1(item.id, phase) } : {}
|
|
1985
2133
|
};
|
|
1986
|
-
blocks.push(
|
|
2134
|
+
blocks.push(outputSlot.block);
|
|
2135
|
+
outputSlot.contentIndex = blockIndex();
|
|
1987
2136
|
stream.push({
|
|
1988
2137
|
type: "text_start",
|
|
1989
|
-
contentIndex:
|
|
2138
|
+
contentIndex: outputSlot.contentIndex,
|
|
1990
2139
|
partial: output
|
|
1991
2140
|
});
|
|
1992
2141
|
}
|
|
1993
|
-
|
|
1994
|
-
|
|
2142
|
+
outputSlot.block.text = finalText;
|
|
2143
|
+
outputSlot.block.textSignature = encodeTextSignatureV1(item.id, phase);
|
|
2144
|
+
const contentIndex = outputSlot.contentIndex;
|
|
2145
|
+
if (contentIndex === void 0) throw new Error("Responses stream finalized text without a content index");
|
|
1995
2146
|
lastTextBlock = {
|
|
1996
|
-
block:
|
|
1997
|
-
index:
|
|
2147
|
+
block: outputSlot.block,
|
|
2148
|
+
index: contentIndex,
|
|
1998
2149
|
phase
|
|
1999
2150
|
};
|
|
2000
2151
|
stream.push({
|
|
2001
2152
|
type: "text_end",
|
|
2002
|
-
contentIndex
|
|
2003
|
-
content:
|
|
2153
|
+
contentIndex,
|
|
2154
|
+
content: outputSlot.block.text,
|
|
2004
2155
|
partial: output
|
|
2005
2156
|
});
|
|
2006
2157
|
}
|
|
2007
|
-
|
|
2158
|
+
forgetOutputSlot(event, outputSlot);
|
|
2008
2159
|
} else if (item.type === "function_call") {
|
|
2009
|
-
const streamingToolCall =
|
|
2010
|
-
if (!streamingToolCall &&
|
|
2160
|
+
const streamingToolCall = streamingToolCalls.resolve(event, readResponsesToolCallItemIdentity(item));
|
|
2161
|
+
if (!streamingToolCall && streamingToolCalls.hasActive()) continue;
|
|
2011
2162
|
const completedName = resolveCompletedToolCallName(streamingToolCall, item.name);
|
|
2012
2163
|
const streamedArguments = streamingToolCall?.block.partialJson ?? "";
|
|
2013
2164
|
const completedArguments = typeof item.arguments === "string" ? item.arguments : void 0;
|
|
@@ -2038,10 +2189,9 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2038
2189
|
partial: output
|
|
2039
2190
|
});
|
|
2040
2191
|
}
|
|
2041
|
-
if (streamingToolCall)
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
currentItem = null;
|
|
2192
|
+
if (streamingToolCall) {
|
|
2193
|
+
streamingToolCalls.forget(streamingToolCall);
|
|
2194
|
+
forgetToolCallOutputSlot(streamingToolCall);
|
|
2045
2195
|
}
|
|
2046
2196
|
stream.push({
|
|
2047
2197
|
type: "toolcall_end",
|
|
@@ -2050,44 +2200,22 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
|
|
|
2050
2200
|
partial: output
|
|
2051
2201
|
});
|
|
2052
2202
|
}
|
|
2053
|
-
} else if (event.type === "response.completed") {
|
|
2054
|
-
if (
|
|
2055
|
-
|
|
2056
|
-
if (response?.id) output.responseId = response.id;
|
|
2057
|
-
if (response?.usage) {
|
|
2058
|
-
const inputTokenDetails = response.usage.input_tokens_details;
|
|
2059
|
-
const cachedTokens = inputTokenDetails?.cached_tokens || 0;
|
|
2060
|
-
const cacheWriteTokens = inputTokenDetails?.cache_write_tokens || 0;
|
|
2061
|
-
output.usage = {
|
|
2062
|
-
input: Math.max(0, (response.usage.input_tokens || 0) - cachedTokens - cacheWriteTokens),
|
|
2063
|
-
output: response.usage.output_tokens || 0,
|
|
2064
|
-
cacheRead: cachedTokens,
|
|
2065
|
-
cacheWrite: cacheWriteTokens,
|
|
2066
|
-
totalTokens: response.usage.total_tokens || 0,
|
|
2067
|
-
cost: {
|
|
2068
|
-
input: 0,
|
|
2069
|
-
output: 0,
|
|
2070
|
-
cacheRead: 0,
|
|
2071
|
-
cacheWrite: 0,
|
|
2072
|
-
total: 0
|
|
2073
|
-
}
|
|
2074
|
-
};
|
|
2075
|
-
}
|
|
2076
|
-
calculateCost(model, output.usage);
|
|
2077
|
-
if (options?.applyServiceTierPricing) {
|
|
2078
|
-
const serviceTier = options.resolveServiceTier ? options.resolveServiceTier(response?.service_tier, options.serviceTier) : response?.service_tier ?? options.serviceTier;
|
|
2079
|
-
options.applyServiceTierPricing(output.usage, serviceTier);
|
|
2080
|
-
}
|
|
2081
|
-
output.stopReason = mapStopReason(response?.status);
|
|
2082
|
-
if (output.content.some((b) => b.type === "toolCall") && output.stopReason === "stop") output.stopReason = "toolUse";
|
|
2203
|
+
} else if (event.type === "response.completed" || event.type === "response.incomplete") {
|
|
2204
|
+
if (streamingToolCalls.hasActive()) throw new Error("Responses stream completed with unresolved tool calls");
|
|
2205
|
+
finalizeResponse(event.response);
|
|
2083
2206
|
} else if (event.type === "error") throw new Error(event.message ? `Error Code ${event.code}: ${event.message}` : "Unknown error");
|
|
2084
2207
|
else if (event.type === "response.failed") {
|
|
2085
2208
|
const error = event.response?.error;
|
|
2086
2209
|
const details = event.response?.incomplete_details;
|
|
2087
|
-
|
|
2088
|
-
|
|
2210
|
+
output.responseId = event.response.id;
|
|
2211
|
+
output.stopReason = "error";
|
|
2212
|
+
output.errorMessage = error ? `${error.code || "unknown"}: ${error.message || "no message"}` : details?.reason ? `incomplete: ${details.reason}` : "Unknown error (no error details in response)";
|
|
2213
|
+
terminalResponseEvent = "failed";
|
|
2214
|
+
break;
|
|
2089
2215
|
}
|
|
2090
|
-
if (
|
|
2216
|
+
if (terminalResponseEvent === "failed") return;
|
|
2217
|
+
if (streamingToolCalls.hasActive()) throw new Error("Responses stream ended with unresolved tool calls");
|
|
2218
|
+
if (!terminalResponseEvent) throw new Error("OpenAI Responses stream ended before a terminal response event");
|
|
2091
2219
|
}
|
|
2092
2220
|
function mapStopReason(status) {
|
|
2093
2221
|
if (!status) return "stop";
|
|
@@ -2102,4 +2230,4 @@ function mapStopReason(status) {
|
|
|
2102
2230
|
}
|
|
2103
2231
|
}
|
|
2104
2232
|
//#endregion
|
|
2105
|
-
export {
|
|
2233
|
+
export { resolveOpenAISupportedReasoningEfforts as A, isResponsesTextDeltaEventType as C, isOpenAIGpt56Model as D, isOpenAIGpt55Model as E, resolveUnsupportedToolSchemaKeywords as F, shouldOmitEmptyArrayItems as I, stripUnsupportedSchemaKeywords as L, supportsOpenAITemperature as M, extractToolSchemaModelCompat as N, normalizeOpenAIReasoningEffort as O, normalizeToolParameterSchema as P, GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS as R, isResponsesTextContentPartType as S, isOpenAIGpt54MiniModel as T, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as _, resolveResponsesReasoningEffort as a, isAzureResponsesTextDeltaEvent as b, clearOpenAIToolSchemaCacheForTest as c, normalizeOpenAIStrictToolParameters as d, normalizeStrictOpenAIJsonSchema as f, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as g, readResponsesToolCallItemIdentity as h, processResponsesStream as i, supportsOpenAIReasoningEffort as j, resolveOpenAIReasoningEffortForModel as k, findOpenAIStrictToolProjectionDiagnostics as l, createResponsesToolCallTracker as m, convertResponsesMessages as n, runResponsesStreamLifecycle as o, resolveOpenAIProjectedToolsStrictToolFlag as p, createResponsesAssistantOutput as r, convertResponsesToolPayload as s, applyCommonResponsesParams as t, isStrictOpenAIJsonSchemaCompatible as u, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as v, resolveResponsesMessageSnapshotCollapse as w, isAzureResponsesTextDeltaEventType as x, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as y, cleanSchemaForGemini as z };
|