@openclaw/ai 2026.7.2-beta.2 → 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.
Files changed (34) hide show
  1. package/dist/{anthropic-BIRSg5x9.mjs → anthropic-D7SyZQ5v.mjs} +54 -35
  2. package/dist/{api-registry-Byvoz8Ha.d.mts → api-registry-DXBIXISf.d.mts} +1 -1
  3. package/dist/{azure-openai-responses-CHi7Wo4A.mjs → azure-openai-responses-BkZgyZ3I.mjs} +5 -4
  4. package/dist/{event-stream-uQspnL8S.d.mts → event-stream-BPemFrFW.d.mts} +1 -1
  5. package/dist/event-stream.d.mts +1 -1
  6. package/dist/{google-BmsqsNwR.mjs → google-C_biGbV7.mjs} +2 -2
  7. package/dist/{google-shared-Dx2aba47.mjs → google-shared-BK-NoHl8.mjs} +4 -3
  8. package/dist/{google-vertex-HZ_0rTwS.mjs → google-vertex-CvdzF1U7.mjs} +2 -2
  9. package/dist/index.d.mts +4 -4
  10. package/dist/internal/anthropic.d.mts +8 -2
  11. package/dist/internal/anthropic.mjs +3 -3
  12. package/dist/internal/openai.d.mts +2 -1
  13. package/dist/internal/openai.mjs +4 -4
  14. package/dist/internal/runtime.d.mts +2 -2
  15. package/dist/internal/runtime.mjs +3 -2
  16. package/dist/internal/shared.d.mts +4 -2
  17. package/dist/internal/shared.mjs +2 -2
  18. package/dist/{mistral-DxMPt9q9.mjs → mistral-BdrQmDWp.mjs} +23 -7
  19. package/dist/{model-utils-Q1LSRIdo.mjs → model-utils-1GiZ2_rr.mjs} +3 -1
  20. package/dist/{openai-chatgpt-responses-BuH2NvsR.mjs → openai-chatgpt-responses-DP63Qt01.mjs} +11 -9
  21. package/dist/{openai-completions-DPR_O2RW.mjs → openai-completions-zLDfebnN.mjs} +39 -15
  22. package/dist/{openai-responses-Cov-Vdc2.mjs → openai-responses-ClspWt4I.mjs} +3 -3
  23. package/dist/{openai-responses-shared-Befb4D6R.mjs → openai-responses-shared-CwnGU0KW.mjs} +323 -223
  24. package/dist/{openai-tool-projection-CFqm42J2.mjs → openai-tool-projection-WHf2nuOI.mjs} +1 -1
  25. package/dist/provider-error-LMfTEkfO.mjs +40 -0
  26. package/dist/providers.d.mts +1 -1
  27. package/dist/providers.mjs +8 -8
  28. package/dist/{transform-messages-BmS70CP5.mjs → transform-messages-eb6lxDLB.mjs} +8 -2
  29. package/dist/{types-Cx2zJtyz.d.mts → types-CYORveZ7.d.mts} +6 -0
  30. package/dist/types.d.mts +3 -3
  31. package/dist/{validation-Cej7htKc.d.mts → validation-BX8euiDv.d.mts} +1 -1
  32. package/dist/validation.d.mts +1 -1
  33. package/npm-shrinkwrap.json +2 -2
  34. 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-Q1LSRIdo.mjs";
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 { C as stripSystemPromptCacheBoundary, D as normalizeOptionalString, E as normalizeLowercaseStringOrEmpty, d as isRecord, i as extractToolResultText, n as describeToolResultMediaPlaceholder, o as isImageWithMediaPayload, t as transformMessages } from "./transform-messages-BmS70CP5.mjs";
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-CFqm42J2.mjs";
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
@@ -1462,7 +1462,8 @@ function convertResponsesMessages(model, context, allowedToolCallProviders, opti
1462
1462
  };
1463
1463
  const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
1464
1464
  if ((options?.includeSystemPrompt ?? true) && context.systemPrompt) {
1465
- const role = model.reasoning ? "developer" : "system";
1465
+ const compat = model.compat;
1466
+ const role = model.reasoning && compat?.supportsDeveloperRole !== false ? "developer" : "system";
1466
1467
  messages.push({
1467
1468
  type: "message",
1468
1469
  role,
@@ -1631,7 +1632,7 @@ function resolveResponsesReasoningEffort(model, reasoning) {
1631
1632
  return clampedReasoning;
1632
1633
  }
1633
1634
  function applyCommonResponsesParams(params, model, context, options, config) {
1634
- if (options?.maxTokens) params.max_output_tokens = options.maxTokens;
1635
+ if (options?.maxTokens) params.max_output_tokens = Math.max(options.maxTokens, 16);
1635
1636
  if (options?.temperature !== void 0 && supportsOpenAITemperature(model)) params.temperature = options.temperature;
1636
1637
  if (context.tools) {
1637
1638
  const converted = convertResponsesToolPayload(context.tools, { model });
@@ -1650,7 +1651,7 @@ function buildResponsesRequestOptions(options) {
1650
1651
  return {
1651
1652
  ...options?.signal ? { signal: options.signal } : {},
1652
1653
  ...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
1653
- ...options?.maxRetries !== void 0 ? { maxRetries: options.maxRetries } : {}
1654
+ maxRetries: options?.maxRetries ?? 0
1654
1655
  };
1655
1656
  }
1656
1657
  function cleanStreamingScratchBuffers(output) {
@@ -1689,7 +1690,7 @@ async function runResponsesStreamLifecycle(params) {
1689
1690
  onFirstEventTimeout: params.processStreamOptions?.onFirstEventTimeout ?? onFirstEventTimeout
1690
1691
  } : void 0);
1691
1692
  if (options?.signal?.aborted) throw new Error("Request was aborted");
1692
- 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");
1693
1694
  stream.push({
1694
1695
  type: "done",
1695
1696
  reason: output.stopReason,
@@ -1711,13 +1712,49 @@ async function runResponsesStreamLifecycle(params) {
1711
1712
  }
1712
1713
  }
1713
1714
  async function processResponsesStream(openaiStream, output, stream, model, options) {
1714
- let currentItem = null;
1715
- let currentBlock = null;
1716
1715
  const streamingToolCalls = createResponsesToolCallTracker();
1716
+ const outputSlots = /* @__PURE__ */ new Map();
1717
+ const reasoningBlocksById = /* @__PURE__ */ new Map();
1718
+ let unindexedOutputSlot;
1719
+ let terminalResponseEvent;
1717
1720
  let lastTextBlock = null;
1718
- let pendingMessageText = null;
1719
1721
  const blocks = output.content;
1720
1722
  const blockIndex = () => blocks.length - 1;
1723
+ const readOutputIndex = (event) => {
1724
+ const outputIndex = event.output_index;
1725
+ return typeof outputIndex === "number" && Number.isInteger(outputIndex) && outputIndex >= 0 ? outputIndex : void 0;
1726
+ };
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);
1736
+ };
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;
1745
+ };
1746
+ const forgetOutputSlot = (event, slot) => {
1747
+ const outputIndex = readOutputIndex(event);
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;
1752
+ }
1753
+ if (outputSlots.get(outputIndex) === slot) outputSlots.delete(outputIndex);
1754
+ };
1755
+ const forgetToolCallOutputSlot = (toolCall) => {
1756
+ for (const [outputIndex, slot] of outputSlots) if (slot.type === "toolCall" && slot.toolCall === toolCall) outputSlots.delete(outputIndex);
1757
+ };
1721
1758
  const readIdentityValue = (value) => {
1722
1759
  return (typeof value === "string" ? value.trim() : "") || void 0;
1723
1760
  };
@@ -1729,28 +1766,143 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1729
1766
  if (!name) throw new Error("Responses stream completed tool call without a function name");
1730
1767
  return name;
1731
1768
  };
1732
- const appendPendingMessageDelta = (delta) => {
1733
- pendingMessageText = `${pendingMessageText ?? ""}${delta}`;
1734
- const priorText = lastTextBlock?.block.text ?? "";
1735
- if (priorText.startsWith(pendingMessageText) || pendingMessageText.startsWith(priorText)) return;
1736
- currentBlock = {
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 = {
1737
1829
  type: "text",
1738
- text: pendingMessageText,
1739
- ...currentItem?.type === "message" && currentItem.phase ? { textSignature: encodeTextSignatureV1(currentItem.id, currentItem.phase ?? void 0) } : {}
1830
+ text,
1831
+ ...slot.item.phase ? { textSignature: encodeTextSignatureV1(slot.item.id, slot.item.phase) } : {}
1740
1832
  };
1741
- blocks.push(currentBlock);
1833
+ blocks.push(slot.block);
1834
+ slot.contentIndex = blockIndex();
1742
1835
  stream.push({
1743
1836
  type: "text_start",
1744
- contentIndex: blockIndex(),
1837
+ contentIndex: slot.contentIndex,
1745
1838
  partial: output
1746
1839
  });
1747
- stream.push({
1840
+ if (text) stream.push({
1748
1841
  type: "text_delta",
1749
- contentIndex: blockIndex(),
1750
- delta: pendingMessageText,
1842
+ contentIndex: slot.contentIndex,
1843
+ delta: text,
1751
1844
  partial: output
1752
1845
  });
1753
- pendingMessageText = null;
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";
1754
1906
  };
1755
1907
  const guardedStream = withFirstStreamEventTimeout(openaiStream, {
1756
1908
  provider: model.provider,
@@ -1764,42 +1916,11 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1764
1916
  });
1765
1917
  for await (const event of guardedStream) if (event.type === "response.created") output.responseId = event.response.id;
1766
1918
  else if (event.type === "response.output_item.added") {
1919
+ materializeDeferredTextSlots();
1767
1920
  const item = event.item;
1768
- if (item.type !== "message") {
1769
- lastTextBlock = null;
1770
- pendingMessageText = null;
1771
- }
1772
- if (item.type === "reasoning") {
1773
- currentItem = item;
1774
- currentBlock = {
1775
- type: "thinking",
1776
- thinking: ""
1777
- };
1778
- output.content.push(currentBlock);
1779
- stream.push({
1780
- type: "thinking_start",
1781
- contentIndex: blockIndex(),
1782
- partial: output
1783
- });
1784
- } else if (item.type === "message") {
1785
- currentItem = item;
1786
- if (lastTextBlock) {
1787
- currentBlock = null;
1788
- pendingMessageText = "";
1789
- } else {
1790
- currentBlock = {
1791
- type: "text",
1792
- text: "",
1793
- ...item.phase ? { textSignature: encodeTextSignatureV1(item.id, item.phase) } : {}
1794
- };
1795
- output.content.push(currentBlock);
1796
- stream.push({
1797
- type: "text_start",
1798
- contentIndex: blockIndex(),
1799
- partial: output
1800
- });
1801
- }
1802
- } else if (item.type === "function_call") {
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") {
1803
1924
  const toolCallBlock = {
1804
1925
  type: "toolCall",
1805
1926
  id: resolveResponsesToolCallId(item),
@@ -1815,8 +1936,10 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1815
1936
  ...readResponsesToolCallItemIdentity(item)
1816
1937
  };
1817
1938
  streamingToolCalls.register(event, toolCallState);
1818
- currentItem = item;
1819
- currentBlock = toolCallBlock;
1939
+ if (readOutputIndex(event) !== void 0) registerOutputSlot(event, {
1940
+ type: "toolCall",
1941
+ toolCall: toolCallState
1942
+ });
1820
1943
  output.content.push(toolCallBlock);
1821
1944
  stream.push({
1822
1945
  type: "toolcall_start",
@@ -1825,113 +1948,107 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1825
1948
  });
1826
1949
  }
1827
1950
  } else if (event.type === "response.reasoning_summary_part.added") {
1828
- if (currentItem && currentItem.type === "reasoning") {
1829
- currentItem.summary = currentItem.summary || [];
1830
- currentItem.summary.push(event.part);
1831
- }
1951
+ const slot = resolveOutputSlot(event, "thinking");
1952
+ if (!slot) continue;
1953
+ slot.item.summary = slot.item.summary || [];
1954
+ slot.item.summary.push(event.part);
1832
1955
  } else if (event.type === "response.reasoning_summary_text.delta") {
1833
- if (currentItem?.type === "reasoning" && currentBlock?.type === "thinking") {
1834
- currentItem.summary = currentItem.summary || [];
1835
- const lastPart = currentItem.summary[currentItem.summary.length - 1];
1836
- if (lastPart) {
1837
- currentBlock.thinking += event.delta;
1838
- lastPart.text += event.delta;
1839
- stream.push({
1840
- type: "thinking_delta",
1841
- contentIndex: blockIndex(),
1842
- delta: event.delta,
1843
- partial: output
1844
- });
1845
- }
1846
- }
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
+ });
1847
1969
  } else if (event.type === "response.reasoning_summary_part.done") {
1848
- if (currentItem?.type === "reasoning" && currentBlock?.type === "thinking") {
1849
- currentItem.summary = currentItem.summary || [];
1850
- const lastPart = currentItem.summary[currentItem.summary.length - 1];
1851
- if (lastPart) {
1852
- currentBlock.thinking += "\n\n";
1853
- lastPart.text += "\n\n";
1854
- stream.push({
1855
- type: "thinking_delta",
1856
- contentIndex: blockIndex(),
1857
- delta: "\n\n",
1858
- partial: output
1859
- });
1860
- }
1861
- }
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
+ });
1862
1983
  } else if (event.type === "response.reasoning_text.delta") {
1863
- if (currentItem?.type === "reasoning" && currentBlock?.type === "thinking") {
1864
- currentBlock.thinking += event.delta;
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;
1865
2007
  stream.push({
1866
- type: "thinking_delta",
1867
- contentIndex: blockIndex(),
2008
+ type: "text_delta",
2009
+ contentIndex: slot.contentIndex,
1868
2010
  delta: event.delta,
1869
2011
  partial: output
1870
2012
  });
1871
2013
  }
1872
- } else if (event.type === "response.content_part.added") {
1873
- if (currentItem?.type === "message") {
1874
- currentItem.content = currentItem.content || [];
1875
- if (event.part.type === "output_text" || event.part.type === "text" || event.part.type === "refusal") currentItem.content.push(event.part);
1876
- }
1877
- } else if (event.type === "response.output_text.delta") {
1878
- if (currentItem?.type === "message") {
1879
- if (!currentItem.content || currentItem.content.length === 0) continue;
1880
- const lastPart = currentItem.content[currentItem.content.length - 1];
1881
- if (isResponsesTextContentPartType(lastPart?.type)) {
1882
- lastPart.text += event.delta;
1883
- if (pendingMessageText !== null) appendPendingMessageDelta(event.delta);
1884
- else if (currentBlock?.type === "text") {
1885
- currentBlock.text += event.delta;
1886
- stream.push({
1887
- type: "text_delta",
1888
- contentIndex: blockIndex(),
1889
- delta: event.delta,
1890
- partial: output
1891
- });
1892
- }
1893
- }
1894
- }
1895
2014
  } else if (isAzureResponsesTextDeltaEvent(event)) {
1896
- if (currentItem?.type === "message") {
1897
- currentItem.content = currentItem.content || [];
1898
- let lastPart = currentItem.content[currentItem.content.length - 1];
1899
- if (lastPart?.type !== "text") {
1900
- lastPart = {
1901
- type: "text",
1902
- text: ""
1903
- };
1904
- currentItem.content.push(lastPart);
1905
- }
1906
- lastPart.text += event.delta;
1907
- if (pendingMessageText !== null) appendPendingMessageDelta(event.delta);
1908
- else if (currentBlock?.type === "text") {
1909
- currentBlock.text += event.delta;
1910
- stream.push({
1911
- type: "text_delta",
1912
- contentIndex: blockIndex(),
1913
- delta: event.delta,
1914
- partial: output
1915
- });
1916
- }
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
+ });
1917
2036
  }
1918
2037
  } else if (event.type === "response.refusal.delta") {
1919
- if (currentItem?.type === "message") {
1920
- if (!currentItem.content || currentItem.content.length === 0) continue;
1921
- const lastPart = currentItem.content[currentItem.content.length - 1];
1922
- if (lastPart?.type === "refusal") {
1923
- lastPart.refusal += event.delta;
1924
- if (pendingMessageText !== null) appendPendingMessageDelta(event.delta);
1925
- else if (currentBlock?.type === "text") {
1926
- currentBlock.text += event.delta;
1927
- stream.push({
1928
- type: "text_delta",
1929
- contentIndex: blockIndex(),
1930
- delta: event.delta,
1931
- partial: output
1932
- });
1933
- }
1934
- }
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
+ });
1935
2052
  }
1936
2053
  } else if (event.type === "response.function_call_arguments.delta") {
1937
2054
  const toolCall = streamingToolCalls.resolve(event);
@@ -1967,72 +2084,78 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1967
2084
  } else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
1968
2085
  } else if (event.type === "response.output_item.done") {
1969
2086
  const item = event.item;
1970
- if (item.type !== "message") {
1971
- lastTextBlock = null;
1972
- pendingMessageText = null;
1973
- }
1974
- if (item.type === "reasoning" && currentBlock?.type === "thinking") {
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") {
1975
2092
  const summaryText = item.summary?.map((s) => s.text).join("\n\n") || "";
1976
2093
  const contentText = item.content?.map((c) => c.text).join("\n\n") || "";
1977
- currentBlock.thinking = summaryText || contentText || currentBlock.thinking;
1978
- currentBlock.thinkingSignature = JSON.stringify(item);
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);
1979
2097
  stream.push({
1980
2098
  type: "thinking_end",
1981
- contentIndex: blockIndex(),
1982
- content: currentBlock.thinking,
2099
+ contentIndex: outputSlot.contentIndex,
2100
+ content: outputSlot.block.thinking,
1983
2101
  partial: output
1984
2102
  });
1985
- currentBlock = null;
1986
- } else if (item.type === "message" && (currentBlock?.type === "text" || pendingMessageText !== null)) {
1987
- const finalText = item.content.map((c) => c.type === "output_text" || c.type === "text" ? c.text : c.refusal).join("");
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("");
1988
2107
  const phase = item.phase ?? void 0;
1989
- const collapse = pendingMessageText !== null ? resolveResponsesMessageSnapshotCollapse({
1990
- prior: lastTextBlock && {
1991
- text: lastTextBlock.block.text,
1992
- phase: lastTextBlock.phase
2108
+ const collapse = outputSlot.pendingText !== null ? resolveResponsesMessageSnapshotCollapse({
2109
+ prior: outputSlot.collapseCandidate && {
2110
+ text: outputSlot.collapseCandidate.block.text,
2111
+ phase: outputSlot.collapseCandidate.phase
1993
2112
  },
1994
2113
  nextText: finalText,
1995
2114
  nextPhase: phase
1996
2115
  }) : { kind: "keep" };
1997
- pendingMessageText = null;
1998
- if (collapse.kind === "extend" && lastTextBlock) {
1999
- lastTextBlock.block.text = collapse.text;
2000
- lastTextBlock.block.textSignature = encodeTextSignatureV1(item.id, phase);
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);
2001
2120
  stream.push({
2002
2121
  type: "text_end",
2003
- contentIndex: lastTextBlock.index,
2122
+ contentIndex: outputSlot.collapseCandidate.index,
2004
2123
  content: collapse.text,
2005
2124
  partial: output
2006
2125
  });
2126
+ lastTextBlock = outputSlot.collapseCandidate;
2007
2127
  } else {
2008
- if (currentBlock?.type !== "text") {
2009
- currentBlock = {
2128
+ if (!outputSlot.block) {
2129
+ outputSlot.block = {
2010
2130
  type: "text",
2011
2131
  text: "",
2012
2132
  ...phase ? { textSignature: encodeTextSignatureV1(item.id, phase) } : {}
2013
2133
  };
2014
- blocks.push(currentBlock);
2134
+ blocks.push(outputSlot.block);
2135
+ outputSlot.contentIndex = blockIndex();
2015
2136
  stream.push({
2016
2137
  type: "text_start",
2017
- contentIndex: blockIndex(),
2138
+ contentIndex: outputSlot.contentIndex,
2018
2139
  partial: output
2019
2140
  });
2020
2141
  }
2021
- currentBlock.text = finalText;
2022
- currentBlock.textSignature = encodeTextSignatureV1(item.id, phase);
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");
2023
2146
  lastTextBlock = {
2024
- block: currentBlock,
2025
- index: blockIndex(),
2147
+ block: outputSlot.block,
2148
+ index: contentIndex,
2026
2149
  phase
2027
2150
  };
2028
2151
  stream.push({
2029
2152
  type: "text_end",
2030
- contentIndex: blockIndex(),
2031
- content: currentBlock.text,
2153
+ contentIndex,
2154
+ content: outputSlot.block.text,
2032
2155
  partial: output
2033
2156
  });
2034
2157
  }
2035
- currentBlock = null;
2158
+ forgetOutputSlot(event, outputSlot);
2036
2159
  } else if (item.type === "function_call") {
2037
2160
  const streamingToolCall = streamingToolCalls.resolve(event, readResponsesToolCallItemIdentity(item));
2038
2161
  if (!streamingToolCall && streamingToolCalls.hasActive()) continue;
@@ -2066,10 +2189,9 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2066
2189
  partial: output
2067
2190
  });
2068
2191
  }
2069
- if (streamingToolCall) streamingToolCalls.forget(streamingToolCall);
2070
- if (currentBlock === toolCall) {
2071
- currentBlock = null;
2072
- currentItem = null;
2192
+ if (streamingToolCall) {
2193
+ streamingToolCalls.forget(streamingToolCall);
2194
+ forgetToolCallOutputSlot(streamingToolCall);
2073
2195
  }
2074
2196
  stream.push({
2075
2197
  type: "toolcall_end",
@@ -2078,44 +2200,22 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
2078
2200
  partial: output
2079
2201
  });
2080
2202
  }
2081
- } else if (event.type === "response.completed") {
2203
+ } else if (event.type === "response.completed" || event.type === "response.incomplete") {
2082
2204
  if (streamingToolCalls.hasActive()) throw new Error("Responses stream completed with unresolved tool calls");
2083
- const response = event.response;
2084
- if (response?.id) output.responseId = response.id;
2085
- if (response?.usage) {
2086
- const inputTokenDetails = response.usage.input_tokens_details;
2087
- const cachedTokens = inputTokenDetails?.cached_tokens || 0;
2088
- const cacheWriteTokens = inputTokenDetails?.cache_write_tokens || 0;
2089
- output.usage = {
2090
- input: Math.max(0, (response.usage.input_tokens || 0) - cachedTokens - cacheWriteTokens),
2091
- output: response.usage.output_tokens || 0,
2092
- cacheRead: cachedTokens,
2093
- cacheWrite: cacheWriteTokens,
2094
- totalTokens: response.usage.total_tokens || 0,
2095
- cost: {
2096
- input: 0,
2097
- output: 0,
2098
- cacheRead: 0,
2099
- cacheWrite: 0,
2100
- total: 0
2101
- }
2102
- };
2103
- }
2104
- calculateCost(model, output.usage);
2105
- if (options?.applyServiceTierPricing) {
2106
- const serviceTier = options.resolveServiceTier ? options.resolveServiceTier(response?.service_tier, options.serviceTier) : response?.service_tier ?? options.serviceTier;
2107
- options.applyServiceTierPricing(output.usage, serviceTier);
2108
- }
2109
- output.stopReason = mapStopReason(response?.status);
2110
- if (output.content.some((b) => b.type === "toolCall") && output.stopReason === "stop") output.stopReason = "toolUse";
2205
+ finalizeResponse(event.response);
2111
2206
  } else if (event.type === "error") throw new Error(event.message ? `Error Code ${event.code}: ${event.message}` : "Unknown error");
2112
2207
  else if (event.type === "response.failed") {
2113
2208
  const error = event.response?.error;
2114
2209
  const details = event.response?.incomplete_details;
2115
- const msg = error ? `${error.code || "unknown"}: ${error.message || "no message"}` : details?.reason ? `incomplete: ${details.reason}` : "Unknown error (no error details in response)";
2116
- throw new Error(msg);
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;
2117
2215
  }
2216
+ if (terminalResponseEvent === "failed") return;
2118
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");
2119
2219
  }
2120
2220
  function mapStopReason(status) {
2121
2221
  if (!status) return "stop";