@openclaw/ai 2026.9.1-beta.1 → 2026.9.1

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 (81) hide show
  1. package/dist/{anthropic-compaction-replay-nhKaCXu6.mjs → anthropic-compaction-replay-OMJZ0uyo.mjs} +37 -34
  2. package/dist/{anthropic-DI4PZKKB.mjs → anthropic-hk7F7ptG.mjs} +28 -25
  3. package/dist/{anthropic-payload-policy-B_0n0enE.d.mts → anthropic-payload-policy-DBT1itQ-.d.mts} +3 -3
  4. package/dist/{api-registry-CTd8NzcD.d.mts → api-registry-Cs6HGNqY.d.mts} +2 -2
  5. package/dist/{azure-openai-responses-D8dI0ekg.mjs → azure-openai-responses-CN4Fy5zV.mjs} +10 -7
  6. package/dist/{number-coercion-H9qHik3g.mjs → base64-CEFBpSkN.mjs} +73 -1
  7. package/dist/{diagnostics-COpOtRwq.mjs → diagnostics-CPeq9F7y.mjs} +5 -1
  8. package/dist/{diagnostics-BaTA9eVl.d.mts → diagnostics-DnPnOui6.d.mts} +5 -1
  9. package/dist/diagnostics-KhXK-QJI.mjs +136 -0
  10. package/dist/diagnostics.d.mts +8 -3
  11. package/dist/diagnostics.mjs +4 -3
  12. package/dist/{env-api-keys-DrgeBuva.mjs → env-api-keys-bktO00EJ.mjs} +2 -15
  13. package/dist/event-stream-DeDhbCc5.d.mts +1 -0
  14. package/dist/{event-stream-LiXePESD.d.mts → event-stream-vK_7r3bj.d.mts} +1 -1
  15. package/dist/event-stream.d.mts +2 -2
  16. package/dist/{google-Od-LLdVK.mjs → google-CC-nrwXg.mjs} +8 -6
  17. package/dist/{google-shared-Bgr9lFPw.mjs → google-shared-CjPY0hZM.mjs} +25 -23
  18. package/dist/{google-vertex-aerRSXc4.mjs → google-vertex-DCr0pyzQ.mjs} +7 -5
  19. package/dist/{host-D51fmkH6.mjs → host-BIaiBURL.mjs} +2 -2
  20. package/dist/{host-DsbPMFU6.d.mts → host-BztR4tQj.d.mts} +3 -3
  21. package/dist/index-AfaxKT8w.d.mts +111 -0
  22. package/dist/index.d.mts +10 -11
  23. package/dist/index.mjs +5 -5
  24. package/dist/internal/anthropic.d.mts +53 -52
  25. package/dist/internal/anthropic.mjs +5 -5
  26. package/dist/internal/openai-responses-payload-policy.d.mts +3 -3
  27. package/dist/internal/openai-responses-payload-policy.mjs +2 -3
  28. package/dist/internal/openai.d.mts +65 -63
  29. package/dist/internal/openai.mjs +9 -9
  30. package/dist/internal/retry-after.d.mts +2 -3
  31. package/dist/internal/runtime.d.mts +43 -43
  32. package/dist/internal/runtime.mjs +10 -8
  33. package/dist/internal/shared.d.mts +25 -25
  34. package/dist/internal/shared.mjs +95 -4
  35. package/dist/{mistral-EiHdymeb.mjs → mistral-B7etBd_H.mjs} +25 -20
  36. package/dist/{openai-chatgpt-responses-DHpF9o1e.mjs → openai-chatgpt-responses-BAJ4gq3i.mjs} +63 -122
  37. package/dist/{openai-completions-EFPiUGfS.mjs → openai-completions-D0QZ0AyB.mjs} +24 -20
  38. package/dist/{openai-completions-compat-BefmHT26.d.mts → openai-completions-compat-4IjSBpr6.d.mts} +5 -5
  39. package/dist/{openai-completions-stream-DUlGwRMz.mjs → openai-completions-stream-DZjwK8vp.mjs} +97 -90
  40. package/dist/{openai-responses-BogP8OjX.mjs → openai-responses-BEUlxfDu.mjs} +12 -8
  41. package/dist/openai-responses-compaction-window-DO7yV7az.mjs +686 -0
  42. package/dist/{openai-responses-contracts-Dvj_UtPy.d.mts → openai-responses-contracts-bPzSN_Ba.d.mts} +14 -5
  43. package/dist/{openai-responses-payload-policy-CNGFT9zr.d.mts → openai-responses-payload-policy-rLRPsSmB.d.mts} +1 -0
  44. package/dist/{openai-responses-prompt-observer-internal-Cd4hJG-S.mjs → openai-responses-prompt-observer-internal-C7x4IK7r.mjs} +4 -18
  45. package/dist/{openai-responses-shared-DJThc6jW.mjs → openai-responses-shared-DiAdpNAM.mjs} +274 -221
  46. package/dist/{openai-tool-schema-ho-hIkQf.mjs → openai-tool-schema-BMiHFH36.mjs} +14 -12
  47. package/dist/{provider-error-DDOs_Bz0.mjs → provider-error-B6EGq6gg.mjs} +14 -85
  48. package/dist/{provider-options-MdMBLzlU.d.mts → provider-options-CxFPtvh7.d.mts} +11 -3
  49. package/dist/{provider-transcript-transform-C01bQ5a3.mjs → provider-transcript-transform-WvJmFUAf.mjs} +1 -1
  50. package/dist/provider-types.d.mts +19 -20
  51. package/dist/providers.d.mts +5 -5
  52. package/dist/providers.mjs +9 -9
  53. package/dist/{reasoning-tag-text-partitioner-5ygO2rZc.mjs → reasoning-tag-text-partitioner-C-4uedDb.mjs} +93 -77
  54. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  55. package/dist/{sanitize-unicode-DCkltN94.mjs → sanitize-unicode-S6binQG-.mjs} +2 -8
  56. package/dist/{simple-options-CFj7x3J4.mjs → simple-options-0PLDyJ-d.mjs} +42 -6
  57. package/dist/{src-Bu3FiFAG.mjs → src-C8U7lkoa.mjs} +75 -2
  58. package/dist/{stream-first-event-timeout-MK28puvq.mjs → stream-first-event-timeout-DcNjoFQE.mjs} +1 -1
  59. package/dist/{tool-schema-json-projection-qvTEs5Am.mjs → tool-schema-json-projection-BtZiml7r.mjs} +21 -31
  60. package/dist/{transport-stream-shared-rvaCyFYt.d.mts → transport-stream-shared-BrvFTkoO.d.mts} +5 -5
  61. package/dist/{transport-stream-shared-ljShVIZB.mjs → transport-stream-shared-CytPVLIg.mjs} +18 -5
  62. package/dist/{transport-utils-LJ1_rbi-.mjs → transport-utils-CtuS1Upe.mjs} +5 -8
  63. package/dist/transports.d.mts +120 -85
  64. package/dist/transports.mjs +218 -249
  65. package/dist/types-B5EFUmXs.d.mts +1 -0
  66. package/dist/{types-DhLoJbFm.d.mts → types-DbrhszyQ.d.mts} +27 -13
  67. package/dist/types.d.mts +7 -7
  68. package/dist/types.mjs +4 -4
  69. package/dist/{validation-Dk7q7NMN.d.mts → validation-BOwtcl9X.d.mts} +1 -1
  70. package/dist/{validation-B61OhAio.mjs → validation-CJZtym2g.mjs} +7 -5
  71. package/dist/validation.d.mts +1 -1
  72. package/dist/validation.mjs +1 -1
  73. package/package.json +5 -5
  74. package/dist/anthropic-BECQCNdF.d.mts +0 -98
  75. package/dist/event-stream-BKp4fOt_.d.mts +0 -1
  76. package/dist/index-Qbej8io0.d.mts +0 -3
  77. package/dist/openai-responses-contracts-QUY12X0B.mjs +0 -233
  78. package/dist/openai-responses-payload-policy-D8EdimYe.mjs +0 -204
  79. package/dist/provider-options-AvldWZt8.mjs +0 -21
  80. package/dist/tls-certificate-errors-DXSpluKI.mjs +0 -93
  81. package/dist/types-GiAjXatj.d.mts +0 -1
@@ -1,19 +1,18 @@
1
1
  import { c as normalizeLowercaseStringOrEmpty, d as normalizeOptionalString, o as isRecord, t as truncateUtf16Safe } from "./utf16-slice-qz3nsy87.mjs";
2
- import { i as clampThinkingLevel, r as calculateCost } from "./sanitize-unicode-DCkltN94.mjs";
3
- import { a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, n as getAiTransportHost } from "./host-D51fmkH6.mjs";
4
- import { n as projectProviderError } from "./provider-error-DDOs_Bz0.mjs";
5
- import { t as asFiniteNumber } from "./number-coercion-H9qHik3g.mjs";
6
- import { f as sortPromptCacheToolsByName, l as stripSystemPromptCacheBoundary } from "./simple-options-CFj7x3J4.mjs";
7
- import { c as transformTransportMessages } from "./tool-schema-json-projection-qvTEs5Am.mjs";
8
- import { d as redactSensitiveText, u as redactIdentifier } from "./transport-utils-LJ1_rbi-.mjs";
9
- import { _ as transportAbortError, g as sanitizeTransportPayloadText, h as sanitizeNonEmptyTransportPayloadText, m as parseTerminalToolCallArguments, y as withProviderResponseHook } from "./transport-stream-shared-ljShVIZB.mjs";
2
+ import { i as clampThinkingLevel, r as calculateCost } from "./sanitize-unicode-S6binQG-.mjs";
3
+ import { a as describeToolResultMediaPlaceholder, c as extractToolResultText, d as isImageWithMediaPayload, n as getAiTransportHost } from "./host-BIaiBURL.mjs";
4
+ import { r as asFiniteNumber } from "./base64-CEFBpSkN.mjs";
5
+ import { d as stripSystemPromptCacheBoundary, m as sortPromptCacheToolsByName } from "./simple-options-0PLDyJ-d.mjs";
6
+ import { c as transformTransportMessages } from "./tool-schema-json-projection-BtZiml7r.mjs";
7
+ import { d as redactSensitiveText, u as redactIdentifier } from "./transport-utils-CtuS1Upe.mjs";
8
+ import { _ as transportAbortError, c as finalizeTransportStream, g as sanitizeTransportPayloadText, h as sanitizeNonEmptyTransportPayloadText, m as parseTerminalToolCallArguments, o as failTransportStream, y as withProviderResponseHook } from "./transport-stream-shared-CytPVLIg.mjs";
10
9
  import { r as parseStreamingJson, t as createToolArgumentPreviewSchedule } from "./json-parse-BuAJEbdW.mjs";
11
10
  import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
12
11
  import { t as shortHash } from "./hash-CHgqbJmD.mjs";
13
- import { C as createOpenAIProviderAcceptanceHook, E as log, S as createModelStreamCooperativeScheduler, a as resolveOpenAIProjectedToolsStrictToolFlag, r as normalizeOpenAIStrictToolParameters, t as findOpenAIStrictToolProjectionDiagnostics, v as projectOpenAITools } from "./openai-tool-schema-ho-hIkQf.mjs";
14
- import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-MK28puvq.mjs";
15
- import { t as transformProviderMessages } from "./provider-transcript-transform-C01bQ5a3.mjs";
16
- import { S as supportsOpenAITemperature, a as OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE, c as OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE, f as RESPONSE_FAILED_NO_DETAILS_MESSAGE, o as OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY, s as OPENAI_RESPONSES_REASONING_REPLAY_META_KEY, x as supportsOpenAIReasoningEffort, y as resolveOpenAIReasoningEffortForModel } from "./openai-responses-contracts-QUY12X0B.mjs";
12
+ import { C as createOpenAIProviderAcceptanceHook, E as log, S as createModelStreamCooperativeScheduler, a as resolveOpenAIProjectedToolsStrictToolFlag, r as normalizeOpenAIStrictToolParameters, t as findOpenAIStrictToolProjectionDiagnostics, v as projectOpenAITools } from "./openai-tool-schema-BMiHFH36.mjs";
13
+ import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-DcNjoFQE.mjs";
14
+ import { t as transformProviderMessages } from "./provider-transcript-transform-WvJmFUAf.mjs";
15
+ import { A as supportsOpenAITemperature, D as resolveOpenAIReasoningEffortForModel, b as RESPONSE_FAILED_NO_DETAILS_MESSAGE, g as OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE, h as OPENAI_RESPONSES_REASONING_REPLAY_META_KEY, k as supportsOpenAIReasoningEffort, m as OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY, n as isOpenAIResponsesCompactionOutput, p as OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE, r as readOpenAIResponsesCompactionWindow } from "./openai-responses-compaction-window-DO7yV7az.mjs";
17
16
  import { createHash, randomUUID } from "node:crypto";
18
17
  //#region packages/ai/src/transports/model-transport-debug.ts
19
18
  /**
@@ -97,7 +96,7 @@ function readOpenAIResponsesCompactionReplayState(value) {
97
96
  function openAIResponsesReplayContextMatches(state, context) {
98
97
  return state.provider === context.provider && state.api === context.api && state.model === context.model && state.baseUrlHash === context.baseUrlHash && state.sessionHash === context.sessionHash && state.authProfileHash === context.authProfileHash;
99
98
  }
100
- function captureOpenAIResponsesCompaction(output, item, boundary, model, captureMetadata) {
99
+ function captureOpenAIResponsesCompaction(output, item, boundary, model, captureMetadata, compactedOutput) {
101
100
  const metadata = captureMetadata ?? buildOpenAIResponsesReasoningReplayMetadata(model);
102
101
  if (!item.encrypted_content) return;
103
102
  if (!metadata?.baseUrlHash) {
@@ -106,19 +105,28 @@ function captureOpenAIResponsesCompaction(output, item, boundary, model, capture
106
105
  }
107
106
  const currentReplay = readOpenAIResponsesCompactionReplayState(output.providerReplay);
108
107
  if (typeof boundary === "number" && currentReplay?.type === "openai-responses-compaction" && (currentReplay.replayIndex ?? -1) > boundary) return;
109
- output.providerReplay = {
108
+ if (compactedOutput && !isOpenAIResponsesCompactionOutput(compactedOutput, model)) throw new Error("Responses compact endpoint checkpoint is invalid");
109
+ const replay = {
110
110
  v: 1,
111
- type: boundary === "retained-users" ? OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE : OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE,
111
+ ...boundary === "retained-users" ? { type: OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE } : {
112
+ type: OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE,
113
+ replayIndex: boundary
114
+ },
112
115
  ...item.id ? { id: item.id } : {},
113
116
  data: item.encrypted_content,
114
- ...typeof boundary === "number" ? { replayIndex: boundary } : {},
115
117
  provider: metadata.provider,
116
118
  api: metadata.api,
117
119
  model: metadata.model,
118
120
  baseUrlHash: metadata.baseUrlHash,
119
121
  ...metadata.sessionHash ? { sessionHash: metadata.sessionHash } : {},
120
- ...metadata.authProfileHash ? { authProfileHash: metadata.authProfileHash } : {}
122
+ ...metadata.authProfileHash ? { authProfileHash: metadata.authProfileHash } : {},
123
+ ...compactedOutput ? { compactedWindow: {
124
+ state: "ready",
125
+ output: JSON.stringify(compactedOutput)
126
+ } } : {}
121
127
  };
128
+ if (compactedOutput && !readOpenAIResponsesCompactionWindow(replay, model)) throw new Error("Responses compact endpoint checkpoint is invalid or exceeds 16 MiB");
129
+ output.providerReplay = replay;
122
130
  }
123
131
  function suppressOpenAIResponsesCompaction(output, model, options, rejectedCheckpoint) {
124
132
  const context = buildOpenAIResponsesReplayContext(model, options);
@@ -167,6 +175,21 @@ function resolveNewestOpenAIResponsesCompactionReplay(messages, model, options)
167
175
  continue;
168
176
  }
169
177
  if (!openAIResponsesReplayContextMatches(replay, context)) return;
178
+ if (replay.compactedWindow !== void 0 || replay.type === "openai-responses-retained-compaction") {
179
+ const output = readOpenAIResponsesCompactionWindow(replay, model);
180
+ const item = output?.at(-1);
181
+ if (!output || item?.type !== "compaction") return {
182
+ owner: message,
183
+ mode: "refresh-required"
184
+ };
185
+ return {
186
+ owner: message,
187
+ mode: "complete-window",
188
+ output,
189
+ item,
190
+ replayIndex: replay.type === "openai-responses-retained-compaction" ? message.content.length : replay.replayIndex ?? 0
191
+ };
192
+ }
170
193
  return {
171
194
  owner: message,
172
195
  item: {
@@ -174,13 +197,17 @@ function resolveNewestOpenAIResponsesCompactionReplay(messages, model, options)
174
197
  ...isSafeResponsesReplayItemId(replay.id) ? { id: replay.id } : {},
175
198
  encrypted_content: replay.data
176
199
  },
177
- ...replay.type === "openai-responses-retained-compaction" ? { mode: "retained-users" } : {
178
- mode: "compacted-prefix",
179
- replayIndex: replay.replayIndex ?? 0
180
- }
200
+ mode: "compacted-prefix",
201
+ replayIndex: replay.replayIndex ?? 0
181
202
  };
182
203
  }
183
204
  }
205
+ var CompactionReplayRefreshRequiredError = class extends Error {
206
+ constructor() {
207
+ super("Provider compaction checkpoint needs rebuilding. Run /compact to rebuild from saved conversation history.");
208
+ this.name = "CompactionReplayRefreshRequiredError";
209
+ }
210
+ };
184
211
  function buildOpenAIResponsesCompactionReplayPlan(messages, model, options) {
185
212
  if (options?.mode === "full-history") return {
186
213
  messages,
@@ -191,22 +218,14 @@ function buildOpenAIResponsesCompactionReplayPlan(messages, model, options) {
191
218
  messages,
192
219
  preserveUnframedToolResults: false
193
220
  };
221
+ if (compaction.mode === "refresh-required") throw new CompactionReplayRefreshRequiredError();
194
222
  const ownerIndex = messages.indexOf(compaction.owner);
195
- const collectRetainedUserMessages = (prefix) => {
196
- const previous = resolveNewestOpenAIResponsesCompactionReplay(prefix, model, options);
197
- if (!previous) return prefix.filter((message) => message.role === "user");
198
- const previousOwnerIndex = prefix.indexOf(previous.owner);
199
- const laterUsers = prefix.slice(previousOwnerIndex + 1).filter((message) => message.role === "user");
200
- return previous.mode === "retained-users" ? [...collectRetainedUserMessages(prefix.slice(0, previousOwnerIndex)), ...laterUsers] : laterUsers;
201
- };
202
- const retainedMessages = compaction.mode === "retained-users" ? collectRetainedUserMessages(messages.slice(0, ownerIndex)) : void 0;
203
223
  return {
204
224
  messages: [{
205
225
  ...compaction.owner,
206
- content: compaction.mode === "retained-users" ? [] : compaction.owner.content.slice(compaction.replayIndex)
226
+ content: compaction.owner.content.slice(compaction.replayIndex)
207
227
  }, ...messages.slice(ownerIndex + 1)],
208
- ...retainedMessages?.length ? { retainedMessages } : {},
209
- compaction: compaction.item,
228
+ ...compaction.mode === "complete-window" ? { compactedWindow: compaction.output } : { compaction: compaction.item },
210
229
  preserveUnframedToolResults: true
211
230
  };
212
231
  }
@@ -398,39 +417,47 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
398
417
  preserveUnframedToolResults: replayPlan.preserveUnframedToolResults
399
418
  });
400
419
  const transformedMessages = transformMessages(replayPlan.messages);
401
- const transformedRetainedMessages = replayPlan.retainedMessages ? transformMessages(replayPlan.retainedMessages) : [];
402
- if ((options?.includeSystemPrompt ?? true) && context.systemPrompt) messages.push(buildResponsesInputMessage(model.reasoning && (providerStyle ? model.compat?.supportsDeveloperRole !== false : options?.supportsDeveloperRole !== false) ? "developer" : "system", [{
420
+ if ((options?.includeSystemPrompt ?? true) && context.systemPrompt) messages.push(buildResponsesInputMessage(model.reasoning && model.compat?.supportsDeveloperRole !== false ? "developer" : "system", [{
403
421
  type: "input_text",
404
422
  text: sanitizeTransportPayloadText(stripSystemPromptCacheBoundary(context.systemPrompt))
405
423
  }]));
406
- const replayMessages = replayPlan.compaction ? [
407
- ...transformedRetainedMessages,
408
- replayPlan.compaction,
409
- ...transformedMessages
410
- ] : transformedMessages;
424
+ if (replayPlan.compactedWindow) messages.push(...replayPlan.compactedWindow);
425
+ let replayMessages = replayPlan.compaction ? [replayPlan.compaction, ...transformedMessages] : transformedMessages;
426
+ const isCarrier = (message) => "role" in message && message.role === "user" && message.runtimeContextCarrier === true;
427
+ const carriers = replayMessages.filter(isCarrier);
428
+ if (carriers.length > 0) {
429
+ const stableMessages = replayMessages.filter((message) => !isCarrier(message));
430
+ const insertionIndex = stableMessages.findLastIndex((message) => "role" in message ? message.role === "user" : message.type === "compaction") + 1;
431
+ if (insertionIndex > 0 || replayPlan.compactedWindow) replayMessages = [
432
+ ...stableMessages.slice(0, insertionIndex),
433
+ ...carriers,
434
+ ...stableMessages.slice(insertionIndex)
435
+ ];
436
+ }
411
437
  let msgIndex = 0;
412
438
  for (const msg of replayMessages) {
413
439
  if (!("role" in msg)) {
414
440
  messages.push(msg);
415
441
  continue;
416
442
  }
417
- if (msg.role === "user") if (typeof msg.content === "string") messages.push(buildResponsesInputMessage("user", [{
418
- type: "input_text",
419
- text: sanitizeTransportPayloadText(msg.content)
420
- }]));
421
- else {
422
- const content = msg.content.map((item) => item.type === "text" ? {
443
+ if (msg.role === "user") {
444
+ if (typeof msg.content === "string") messages.push(buildResponsesInputMessage("user", [{
423
445
  type: "input_text",
424
- text: sanitizeTransportPayloadText(item.text)
425
- } : {
426
- type: "input_image",
427
- detail: "auto",
428
- image_url: `data:${item.mimeType};base64,${item.data}`
429
- }).filter((item) => providerStyle || model.input.includes("image") || item.type !== "input_image");
430
- if (content.length > 0) messages.push(buildResponsesInputMessage("user", content));
431
- else if (providerStyle) continue;
432
- }
433
- else if (msg.role === "assistant") {
446
+ text: sanitizeTransportPayloadText(msg.content)
447
+ }]));
448
+ else {
449
+ const content = msg.content.map((item) => item.type === "text" ? {
450
+ type: "input_text",
451
+ text: sanitizeTransportPayloadText(item.text)
452
+ } : {
453
+ type: "input_image",
454
+ detail: "auto",
455
+ image_url: `data:${item.mimeType};base64,${item.data}`
456
+ }).filter((item) => providerStyle || model.input.includes("image") || item.type !== "input_image");
457
+ if (content.length > 0) messages.push(buildResponsesInputMessage("user", content));
458
+ else if (providerStyle) continue;
459
+ }
460
+ } else if (msg.role === "assistant") {
434
461
  const output = [];
435
462
  let textFallbackOrdinal = 0;
436
463
  let previousReplayItemWasReasoning = false;
@@ -592,84 +619,83 @@ async function resolveNextResponsesEncryptedContentAttempt(attempt, error, optio
592
619
  };
593
620
  }
594
621
  async function createResponsesStreamWithEncryptedContentRetry(params) {
595
- const sendAttempt = async (attempt) => {
596
- const { data, response } = await params.client.responses.create(attempt.request, params.requestOptions).withResponse();
597
- commitResponsesEncryptedContentAttempt(attempt, (checkpoint) => {
598
- if (checkpoint) params.onCompactionRejected?.(checkpoint);
599
- });
600
- if (!isAsyncIterable(data)) throw new Error("OpenAI Responses streaming request returned a non-stream response");
601
- return {
602
- stream: data,
603
- response,
604
- attempt
605
- };
622
+ const send = async (initialAttempt) => {
623
+ let attempt = initialAttempt;
624
+ for (;;) {
625
+ params.observePrompt?.(attempt.request, {
626
+ egress: "responses-sdk",
627
+ payloadVariant: attempt.kind
628
+ });
629
+ try {
630
+ const { data, response } = await params.client.responses.create(attempt.request, params.requestOptions).withResponse();
631
+ commitResponsesEncryptedContentAttempt(attempt, (checkpoint) => {
632
+ if (checkpoint) params.onCompactionRejected?.(checkpoint);
633
+ });
634
+ if (!isAsyncIterable(data)) throw new Error("OpenAI Responses streaming request returned a non-stream response");
635
+ return {
636
+ stream: data,
637
+ response,
638
+ attempt
639
+ };
640
+ } catch (error) {
641
+ let nextAttempt = await resolveNextResponsesEncryptedContentAttempt(attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest });
642
+ if (!nextAttempt && attempt.request.previous_response_id && error && typeof error === "object" && typeof error.status === "number" && error.code === "previous_response_not_found") {
643
+ const request = { ...params.buildFullHistoryRequest ? await params.buildFullHistoryRequest() : attempt.request };
644
+ delete request.previous_response_id;
645
+ nextAttempt = {
646
+ kind: "continuation-rejected",
647
+ request
648
+ };
649
+ }
650
+ if (!nextAttempt) throw error;
651
+ const retryDescription = nextAttempt.kind === "reasoning-stripped" ? "without encrypted reasoning content" : nextAttempt.kind === "compaction-stripped" ? "without encrypted compaction content" : "full history after rejected previous_response_id";
652
+ log.warn(`[responses] retrying ${retryDescription} provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
653
+ attempt = nextAttempt;
654
+ }
655
+ }
606
656
  };
607
- let attempt = {
657
+ const result = await send({
608
658
  kind: params.initialAttemptKind ?? "initial",
609
659
  request: params.request,
610
660
  ...params.initialRejectedCompaction ? { rejectedCompaction: params.initialRejectedCompaction } : {}
611
- };
612
- while (true) {
613
- params.observePrompt?.(attempt.request, {
614
- egress: "responses-sdk",
615
- payloadVariant: attempt.kind
616
- });
617
- try {
618
- const result = await sendAttempt(attempt);
619
- return {
620
- ...result,
621
- stream: { async *[Symbol.asyncIterator]() {
622
- let rejectedEvent;
623
- try {
624
- for await (const event of params.wrapStream?.(result) ?? result.stream) {
625
- if (isRecord(event)) {
626
- const failure = event.type === "response.failed" && isRecord(event.response) ? event.response.error : event.type === "error" ? event.error ?? event : void 0;
627
- if (isRecord(failure) && params.canRetryStream?.() === true && isInvalidEncryptedContentError(failure)) {
628
- rejectedEvent = event;
629
- const message = typeof failure.message === "string" ? failure.message : "";
630
- throw Object.assign(new Error(message), {
631
- code: failure.code,
632
- status: failure.status
633
- });
634
- }
661
+ });
662
+ return {
663
+ ...result,
664
+ stream: { async *[Symbol.asyncIterator]() {
665
+ let current = result;
666
+ for (;;) {
667
+ let rejectedEvent;
668
+ try {
669
+ for await (const event of params.wrapStream?.(current) ?? current.stream) {
670
+ if (isRecord(event)) {
671
+ const failure = event.type === "response.failed" && isRecord(event.response) ? event.response.error : event.type === "error" ? event.error ?? event : void 0;
672
+ if (isRecord(failure) && params.canRetryStream?.() === true && isInvalidEncryptedContentError(failure)) {
673
+ rejectedEvent = event;
674
+ const message = typeof failure.message === "string" ? failure.message : "";
675
+ throw Object.assign(new Error(message), {
676
+ code: failure.code,
677
+ status: failure.status
678
+ });
635
679
  }
636
- yield event;
637
680
  }
638
- } catch (error) {
639
- const nextAttempt = params.canRetryStream?.() === true && !params.requestOptions?.signal?.aborted ? await resolveNextResponsesEncryptedContentAttempt(result.attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest }) : void 0;
640
- if (!nextAttempt) {
641
- if (rejectedEvent !== void 0) {
642
- yield rejectedEvent;
643
- return;
644
- }
645
- throw error;
681
+ yield event;
682
+ }
683
+ return;
684
+ } catch (error) {
685
+ const nextAttempt = params.canRetryStream?.() === true && !params.requestOptions?.signal?.aborted ? await resolveNextResponsesEncryptedContentAttempt(current.attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest }) : void 0;
686
+ if (!nextAttempt) {
687
+ if (rejectedEvent !== void 0) {
688
+ yield rejectedEvent;
689
+ return;
646
690
  }
647
- log.warn(`[responses] retrying streamed encrypted content provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
648
- yield* (await createResponsesStreamWithEncryptedContentRetry({
649
- ...params,
650
- request: nextAttempt.request,
651
- initialAttemptKind: nextAttempt.kind,
652
- initialRejectedCompaction: nextAttempt.rejectedCompaction
653
- })).stream;
691
+ throw error;
654
692
  }
655
- } }
656
- };
657
- } catch (error) {
658
- let nextAttempt = await resolveNextResponsesEncryptedContentAttempt(attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest });
659
- if (!nextAttempt && attempt.request.previous_response_id && error && typeof error === "object" && typeof error.status === "number" && error.code === "previous_response_not_found") {
660
- const request = { ...params.buildFullHistoryRequest ? await params.buildFullHistoryRequest() : attempt.request };
661
- delete request.previous_response_id;
662
- nextAttempt = {
663
- kind: "continuation-rejected",
664
- request
665
- };
693
+ log.warn(`[responses] retrying streamed encrypted content provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
694
+ current = await send(nextAttempt);
695
+ }
666
696
  }
667
- if (!nextAttempt) throw error;
668
- const retryDescription = nextAttempt.kind === "reasoning-stripped" ? "without encrypted reasoning content" : nextAttempt.kind === "compaction-stripped" ? "without encrypted compaction content" : "full history after rejected previous_response_id";
669
- log.warn(`[responses] retrying ${retryDescription} provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
670
- attempt = nextAttempt;
671
- }
672
- }
697
+ } }
698
+ };
673
699
  }
674
700
  function resolveAzureOpenAIApiVersion(env = process.env) {
675
701
  return env.AZURE_OPENAI_API_VERSION?.trim() || "preview";
@@ -725,14 +751,14 @@ function createResponsesToolCallTracker() {
725
751
  state.callId ??= identity.callId;
726
752
  return state;
727
753
  };
728
- const resolveCompatible = (candidates, identity) => {
754
+ const resolveCompatible = (candidates, identity, allowUnmatchedIdentity) => {
729
755
  const uniqueCandidates = [...new Set(candidates)];
730
- if (!identity.itemId && !identity.callId) return uniqueCandidates.length === 1 ? uniqueCandidates.at(0) : void 0;
756
+ if (!identity.itemId && !identity.callId) return allowUnmatchedIdentity && uniqueCandidates.length === 1 ? uniqueCandidates.at(0) : void 0;
731
757
  const compatible = uniqueCandidates.filter((state) => !identitiesConflict(state, identity));
732
758
  const matches = compatible.filter((state) => sharesIdentity(state, identity));
733
759
  const matched = matches.length === 1 ? matches.at(0) : void 0;
734
760
  if (matched) return adoptIdentity(matched, identity);
735
- const soleCompatible = uniqueCandidates.length === 1 && compatible.length === 1 && matches.length === 0 ? compatible.at(0) : void 0;
761
+ const soleCompatible = allowUnmatchedIdentity && uniqueCandidates.length === 1 && compatible.length === 1 && matches.length === 0 ? compatible.at(0) : void 0;
736
762
  return soleCompatible ? adoptIdentity(soleCompatible, identity) : void 0;
737
763
  };
738
764
  return {
@@ -743,9 +769,10 @@ function createResponsesToolCallTracker() {
743
769
  return;
744
770
  }
745
771
  if (indexedCalls.has(outputIndex)) throw new Error(`Responses stream reused active tool-call output index ${outputIndex}`);
772
+ state.outputIndex = outputIndex;
746
773
  indexedCalls.set(outputIndex, state);
747
774
  },
748
- resolve(event, identity = readEventIdentity(event)) {
775
+ resolve(event, identity = readEventIdentity(event), allowUnmatchedIdentity = true) {
749
776
  const outputIndex = readOutputIndex(event);
750
777
  if (outputIndex !== void 0) {
751
778
  const indexed = indexedCalls.get(outputIndex);
@@ -753,14 +780,15 @@ function createResponsesToolCallTracker() {
753
780
  if (indexed.callId && identity.callId && indexed.callId !== identity.callId) return;
754
781
  return adoptIdentity(indexed, identity);
755
782
  }
756
- const unindexed = resolveCompatible(unindexedCalls, identity);
783
+ const unindexed = resolveCompatible(unindexedCalls, identity, allowUnmatchedIdentity);
757
784
  if (unindexed) {
758
785
  unindexedCalls.delete(unindexed);
786
+ unindexed.outputIndex = outputIndex;
759
787
  indexedCalls.set(outputIndex, unindexed);
760
788
  }
761
789
  return unindexed;
762
790
  }
763
- return resolveCompatible([...indexedCalls.values(), ...unindexedCalls], identity);
791
+ return resolveCompatible([...indexedCalls.values(), ...unindexedCalls], identity, allowUnmatchedIdentity);
764
792
  },
765
793
  forget(toolCall) {
766
794
  for (const [outputIndex, tracked] of indexedCalls) if (tracked === toolCall) indexedCalls.delete(outputIndex);
@@ -771,6 +799,10 @@ function createResponsesToolCallTracker() {
771
799
  },
772
800
  hasActive() {
773
801
  return indexedCalls.size > 0 || unindexedCalls.size > 0;
802
+ },
803
+ hasExactlyActive(expected) {
804
+ const active = /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls]);
805
+ return active.size === expected.length && expected.every((state) => active.has(state));
774
806
  }
775
807
  };
776
808
  }
@@ -896,9 +928,10 @@ const RESPONSE_FAILED_FAILURE_FIELD_KEYS = [
896
928
  function readResponseFailedString(record, key) {
897
929
  return stringifyUnknown(record?.[key]);
898
930
  }
899
- function buildResponsesFailedEventSummary(message, responseId, observation) {
931
+ function buildResponsesFailedEventSummary(message, responseId, code, observation) {
900
932
  const summary = { message };
901
933
  if (responseId) summary.responseId = responseId;
934
+ if (code) summary.code = code;
902
935
  if (observation) summary.observation = observation;
903
936
  return summary;
904
937
  }
@@ -1017,11 +1050,11 @@ function normalizeResponsesFailedEvent(event, model) {
1017
1050
  if (error) {
1018
1051
  const code = readResponseFailedString(error, "code").trim();
1019
1052
  const message = readResponseFailedString(error, "message").trim();
1020
- if (code || message) return buildResponsesFailedEventSummary(`${code || "unknown"}: ${message || "no message"}`, responseId);
1053
+ if (code || message) return buildResponsesFailedEventSummary(`${code || "unknown"}: ${message || "no message"}`, responseId, code || void 0);
1021
1054
  }
1022
1055
  const incompleteReason = readResponseFailedString(isRecord(response?.incomplete_details) ? response.incomplete_details : void 0, "reason");
1023
1056
  if (incompleteReason) return buildResponsesFailedEventSummary(`incomplete: ${incompleteReason}`, responseId);
1024
- return buildResponsesFailedEventSummary(RESPONSE_FAILED_NO_DETAILS_MESSAGE, responseId, buildResponsesFailedNoDetailsObservation(event, model, response));
1057
+ return buildResponsesFailedEventSummary(RESPONSE_FAILED_NO_DETAILS_MESSAGE, responseId, void 0, buildResponsesFailedNoDetailsObservation(event, model, response));
1025
1058
  }
1026
1059
  var ResponsesStreamFailure = class extends Error {
1027
1060
  constructor(failure, response) {
@@ -1029,6 +1062,7 @@ var ResponsesStreamFailure = class extends Error {
1029
1062
  this.name = "ResponsesStreamFailure";
1030
1063
  this.responseId = failure.responseId;
1031
1064
  this.response = response;
1065
+ this.code = failure.code;
1032
1066
  this.observation = failure.observation;
1033
1067
  }
1034
1068
  };
@@ -1123,7 +1157,8 @@ function createResponsesOutputTracker() {
1123
1157
  const outputs = /* @__PURE__ */ new Map();
1124
1158
  const identity = (item) => {
1125
1159
  if ((item.type === "reasoning" || item.type === "message") && item.id) return `${item.type}:${item.id}`;
1126
- return item.type === "function_call" ? `function_call:${item.call_id ?? item.id ?? ""}` : void 0;
1160
+ const callId = item.call_id ?? item.id;
1161
+ return item.type === "function_call" && callId ? `function_call:${callId}` : void 0;
1127
1162
  };
1128
1163
  const get = (item, outputIndex) => {
1129
1164
  const key = identity(item);
@@ -1210,8 +1245,11 @@ function createResponsesOutputSlotTracker() {
1210
1245
  * package and managed transports from drifting on token buckets, service-tier pricing, or future
1211
1246
  * terminal-event semantics.
1212
1247
  */
1248
+ function readReportedCount(value) {
1249
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
1250
+ }
1213
1251
  function readCount(value) {
1214
- return typeof value === "number" && Number.isFinite(value) ? value : 0;
1252
+ return readReportedCount(value) ?? 0;
1215
1253
  }
1216
1254
  /**
1217
1255
  * Split a terminal usage payload into the priced buckets.
@@ -1229,12 +1267,21 @@ function mapResponsesTerminalUsage(usage) {
1229
1267
  const input = Math.max(0, readCount(usage.input_tokens) - cacheRead - cacheWrite);
1230
1268
  const output = readCount(usage.output_tokens);
1231
1269
  const bucketTotal = input + output + cacheRead + cacheWrite;
1270
+ const totalTokens = Math.max(bucketTotal, readCount(usage.total_tokens));
1271
+ const reportedInput = readReportedCount(usage.input_tokens);
1272
+ const reportedOutput = readReportedCount(usage.output_tokens);
1273
+ const reportedTotal = readReportedCount(usage.total_tokens);
1232
1274
  return {
1233
1275
  input,
1234
1276
  output,
1235
1277
  cacheRead,
1236
1278
  cacheWrite,
1237
- totalTokens: Math.max(bucketTotal, readCount(usage.total_tokens))
1279
+ contextUsage: reportedInput !== void 0 && (reportedOutput !== void 0 || reportedTotal !== void 0 && reportedTotal >= reportedInput) && cacheRead + cacheWrite <= reportedInput ? {
1280
+ state: "available",
1281
+ promptTokens: reportedInput,
1282
+ totalTokens: Math.max(totalTokens, reportedInput + (reportedOutput ?? 0))
1283
+ } : { state: "unavailable" },
1284
+ totalTokens
1238
1285
  };
1239
1286
  }
1240
1287
  /** Reasoning tokens are reported by the agent path only; the package path does not track them. */
@@ -1392,30 +1439,34 @@ function createResponsesTerminalController(params) {
1392
1439
  });
1393
1440
  return index;
1394
1441
  };
1395
- const appendToolCall = (item) => {
1396
- const validated = resolveCompletedResponsesToolCall(item);
1397
- const toolCall = {
1442
+ const emitToolCallCompletion = (item, outputIndex, started, validated) => {
1443
+ const completed = {
1444
+ id: resolveResponsesToolCallId(item, started?.block.id),
1445
+ ...validated
1446
+ };
1447
+ const toolCall = started ? Object.assign(started.block, completed) : {
1398
1448
  type: "toolCall",
1399
- id: resolveResponsesToolCallId(item),
1400
- name: validated.name,
1401
- arguments: validated.arguments
1449
+ ...completed
1402
1450
  };
1403
- blocks.push(toolCall);
1404
- const contentIndex = blocks.length - 1;
1405
- stream.push({
1406
- type: "toolcall_start",
1407
- contentIndex,
1408
- partial: output
1409
- });
1451
+ delete toolCall.partialJson;
1452
+ const contentIndex = started?.contentIndex ?? blocks.length;
1453
+ if (!started) {
1454
+ blocks.push(toolCall);
1455
+ stream.push({
1456
+ type: "toolcall_start",
1457
+ contentIndex,
1458
+ partial: output
1459
+ });
1460
+ }
1461
+ params.outputs.set(item, contentIndex, outputIndex, true);
1410
1462
  stream.push({
1411
1463
  type: "toolcall_end",
1412
1464
  contentIndex,
1413
1465
  toolCall,
1414
1466
  partial: output
1415
1467
  });
1416
- return contentIndex;
1417
1468
  };
1418
- const recoverTerminalOutput = (items, includeToolCalls) => {
1469
+ const recoverTerminalOutput = (items, completeToolCall) => {
1419
1470
  let hasCompletedLaterOutput = false;
1420
1471
  for (const [outputIndex, item] of [...items.entries()].toReversed()) {
1421
1472
  const tracked = params.outputs.get(item, outputIndex);
@@ -1428,9 +1479,8 @@ function createResponsesTerminalController(params) {
1428
1479
  hasCompletedLaterOutput = true;
1429
1480
  continue;
1430
1481
  }
1431
- if (item.type === "function_call" && !includeToolCalls) continue;
1482
+ if (item.type === "function_call" && !completeToolCall) continue;
1432
1483
  if (hasCompletedLaterOutput) throw new Error("Responses stream omitted an output item before completed output");
1433
- if (item.type === "function_call") resolveCompletedResponsesToolCall(item);
1434
1484
  }
1435
1485
  for (const [terminalIndex, item] of items.entries()) if (item.type === "message") {
1436
1486
  const tracked = params.outputs.get(item, terminalIndex);
@@ -1451,9 +1501,9 @@ function createResponsesTerminalController(params) {
1451
1501
  }
1452
1502
  }
1453
1503
  captureOpenAIResponsesCompaction(output, item, replayIndex, model, options?.reasoningReplayMetadata);
1454
- } else if (includeToolCalls && item.type === "function_call") {
1455
- if (params.outputs.get(item, terminalIndex)) continue;
1456
- params.outputs.set(item, appendToolCall(item), terminalIndex, true);
1504
+ } else if (completeToolCall && item.type === "function_call") {
1505
+ if (params.outputs.get(item, terminalIndex)?.completed) continue;
1506
+ completeToolCall(terminalIndex);
1457
1507
  }
1458
1508
  }
1459
1509
  };
@@ -1480,7 +1530,6 @@ function createResponsesTerminalController(params) {
1480
1530
  }
1481
1531
  };
1482
1532
  const finalizeResponse = (response, terminalEventType) => {
1483
- params.markFinalized();
1484
1533
  backfillReasoning(response.output ?? []);
1485
1534
  finalizeTerminalFacts(response);
1486
1535
  const terminal = resolveResponsesTerminalStopReason({
@@ -1495,7 +1544,8 @@ function createResponsesTerminalController(params) {
1495
1544
  return {
1496
1545
  finalizeResponse,
1497
1546
  finalizeFailedResponse: finalizeTerminalFacts,
1498
- recoverTerminalOutput
1547
+ recoverTerminalOutput,
1548
+ emitToolCallCompletion
1499
1549
  };
1500
1550
  }
1501
1551
  //#endregion
@@ -1594,7 +1644,7 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1594
1644
  const materializeDeferredTextSlots = (except) => {
1595
1645
  for (const slot of outputSlots.values()) if (slot !== except && slot.type === "text") materializeDeferredTextSlot(slot);
1596
1646
  };
1597
- const { finalizeResponse, finalizeFailedResponse, recoverTerminalOutput } = createResponsesTerminalController({
1647
+ const terminal = createResponsesTerminalController({
1598
1648
  output,
1599
1649
  stream,
1600
1650
  model,
@@ -1603,9 +1653,49 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1603
1653
  getLastTextBlock: () => lastTextBlock,
1604
1654
  setLastTextBlock: (block) => {
1605
1655
  lastTextBlock = block;
1606
- },
1607
- markFinalized: () => void 0
1656
+ }
1608
1657
  });
1658
+ const finalizeToolCall = (item, outputIndex, streamingToolCall, validated) => {
1659
+ const identity = {
1660
+ type: item.type,
1661
+ id: item.id || streamingToolCall?.itemId,
1662
+ call_id: item.call_id || streamingToolCall?.callId
1663
+ };
1664
+ const finalOutputIndex = outputIndex ?? streamingToolCall?.outputIndex;
1665
+ if (finalOutputIndex === void 0 && !identity.id && !identity.call_id) {
1666
+ if (!streamingToolCall) throw new Error("Responses stream completed tool call without an output identity");
1667
+ return;
1668
+ }
1669
+ if (streamingToolCall) {
1670
+ streamingToolCalls.forget(streamingToolCall);
1671
+ for (const slot of outputSlots.values()) if (slot.type === "toolCall" && slot.toolCall === streamingToolCall) outputSlots.forget(slot);
1672
+ }
1673
+ terminal.emitToolCallCompletion(identity, finalOutputIndex, streamingToolCall, validated);
1674
+ };
1675
+ const prepareTerminalToolCalls = (items) => {
1676
+ const prepared = /* @__PURE__ */ new Map();
1677
+ const recovered = [];
1678
+ const callIds = /* @__PURE__ */ new Set();
1679
+ const allowUnmatchedIdentity = items.filter((item, index) => item.type === "function_call" && !outputs.get(item, index)?.completed).length === 1;
1680
+ for (const [outputIndex, item] of items.entries()) {
1681
+ const tracked = outputs.get(item, outputIndex);
1682
+ if (item.type !== "function_call") continue;
1683
+ if (item.call_id && callIds.has(item.call_id)) throw new Error("Responses stream repeated a terminal tool-call identity");
1684
+ if (item.call_id) callIds.add(item.call_id);
1685
+ if (tracked?.completed) continue;
1686
+ const state = streamingToolCalls.resolve({ output_index: outputIndex }, readResponsesToolCallItemIdentity(item), allowUnmatchedIdentity);
1687
+ if (tracked && !state) throw new Error("Responses stream completed with unresolved tool calls");
1688
+ const validated = resolveCompletedResponsesToolCall(item, { name: state?.block.name });
1689
+ if (state) recovered.push(state);
1690
+ prepared.set(outputIndex, () => finalizeToolCall(item, outputIndex, state, validated));
1691
+ }
1692
+ if (!streamingToolCalls.hasExactlyActive(recovered)) throw new Error("Responses stream completed with unresolved tool calls");
1693
+ return (outputIndex) => {
1694
+ const complete = prepared.get(outputIndex);
1695
+ if (!complete) throw new Error("Responses stream completed with unresolved tool calls");
1696
+ complete();
1697
+ };
1698
+ };
1609
1699
  const guardedStream = adaptResponsesStream(withFirstStreamEventTimeout(openaiStream, {
1610
1700
  provider: model.provider,
1611
1701
  api: model.api,
@@ -1881,64 +1971,32 @@ async function processResponsesStream(openaiStream, output, stream, model, optio
1881
1971
  }
1882
1972
  outputSlots.forget(outputSlot);
1883
1973
  } else if (item.type === "function_call") {
1974
+ if (outputs.get(item, readResponsesOutputIndex(event))?.completed) continue;
1884
1975
  const streamingToolCall = streamingToolCalls.resolve(event, readResponsesToolCallItemIdentity(item));
1885
1976
  if (!streamingToolCall && streamingToolCalls.hasActive()) continue;
1886
- const streamedArguments = streamingToolCall?.block.partialJson ?? "";
1887
1977
  const completedArguments = typeof item.arguments === "string" ? item.arguments : void 0;
1888
1978
  if (streamingToolCall && !streamingToolCall.argumentStreamReliable && !completedArguments) continue;
1889
- const finalArguments = completedArguments !== void 0 && (completedArguments.length > 0 || !streamedArguments) ? completedArguments : streamedArguments;
1890
1979
  const validated = resolveCompletedResponsesToolCall(item, {
1891
1980
  name: streamingToolCall?.block.name,
1892
- arguments: finalArguments
1893
- });
1894
- let toolCall;
1895
- let contentIndex;
1896
- if (streamingToolCall) {
1897
- const block = streamingToolCall.block;
1898
- block.id = resolveResponsesToolCallId(item, block.id);
1899
- block.name = validated.name;
1900
- block.arguments = validated.arguments;
1901
- delete block.partialJson;
1902
- toolCall = block;
1903
- contentIndex = streamingToolCall.contentIndex;
1904
- } else {
1905
- toolCall = {
1906
- type: "toolCall",
1907
- id: resolveResponsesToolCallId(item),
1908
- name: validated.name,
1909
- arguments: validated.arguments
1910
- };
1911
- blocks.push(toolCall);
1912
- contentIndex = blocks.length - 1;
1913
- stream.push({
1914
- type: "toolcall_start",
1915
- contentIndex,
1916
- partial: output
1917
- });
1918
- }
1919
- if (streamingToolCall) {
1920
- streamingToolCalls.forget(streamingToolCall);
1921
- for (const slot of outputSlots.values()) if (slot.type === "toolCall" && slot.toolCall === streamingToolCall) outputSlots.forget(slot);
1922
- }
1923
- stream.push({
1924
- type: "toolcall_end",
1925
- contentIndex,
1926
- toolCall,
1927
- partial: output
1981
+ arguments: completedArguments || streamingToolCall?.block.partialJson || ""
1928
1982
  });
1929
- outputs.set(item, contentIndex, readResponsesOutputIndex(event), true);
1983
+ finalizeToolCall(item, readResponsesOutputIndex(event), streamingToolCall, validated);
1930
1984
  }
1931
1985
  } else if (event.type === "response.completed" || event.type === "response.incomplete") {
1932
- if (streamingToolCalls.hasActive()) throw new Error("Responses stream completed with unresolved tool calls");
1933
- finalizeResponse(event.response, event.type);
1934
- if (event.type === "response.completed" || output.stopReason === "length") recoverTerminalOutput(event.response.output ?? [], event.type === "response.completed");
1986
+ if (event.type === "response.incomplete" && streamingToolCalls.hasActive()) throw new Error("Responses stream completed with unresolved tool calls");
1987
+ terminal.finalizeResponse(event.response, event.type);
1988
+ if (event.type === "response.completed" || output.stopReason === "length") {
1989
+ const items = event.response.output ?? [];
1990
+ const completeToolCall = event.type === "response.completed" ? prepareTerminalToolCalls(items) : void 0;
1991
+ terminal.recoverTerminalOutput(items, completeToolCall);
1992
+ }
1935
1993
  terminalResponse = event.type === "response.completed" ? event.response : null;
1936
1994
  if (output.stopReason === "stop" && output.content.some((block) => block.type === "toolCall")) output.stopReason = "toolUse";
1937
1995
  break;
1938
1996
  } else if (event.type === "error") throw new Error(event.message ? `Error Code ${event.code}: ${event.message}` : "Unknown error");
1939
1997
  else if (event.type === "response.failed") {
1940
1998
  const failure = normalizeResponsesFailedEvent(isRecord(event) ? event : {}, model);
1941
- finalizeFailedResponse(event.response, failure.responseId);
1999
+ terminal.finalizeFailedResponse(event.response, failure.responseId);
1942
2000
  throw new ResponsesStreamFailure(failure, event.response);
1943
2001
  }
1944
2002
  }
@@ -2070,7 +2128,7 @@ function buildResponsesRequestOptions(options) {
2070
2128
  return {
2071
2129
  ...options?.signal ? { signal: options.signal } : {},
2072
2130
  ...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
2073
- maxRetries: options?.maxRetries ?? 0
2131
+ maxRetries: 0
2074
2132
  };
2075
2133
  }
2076
2134
  function cleanStreamingScratchBuffers(output) {
@@ -2137,27 +2195,22 @@ async function runResponsesStreamLifecycle(params) {
2137
2195
  authProfileId: options?.authProfileId
2138
2196
  })
2139
2197
  });
2140
- if (options?.signal?.aborted) throw transportAbortError(options.signal);
2141
- if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage ?? "An unknown error occurred");
2142
- stream.push({
2143
- type: "done",
2144
- reason: output.stopReason,
2145
- message: output
2198
+ finalizeTransportStream({
2199
+ stream,
2200
+ output,
2201
+ signal: options?.signal
2146
2202
  });
2147
- stream.end();
2148
2203
  } catch (error) {
2149
- cleanStreamingScratchBuffers(output);
2150
- const terminal = projectProviderError(error, options?.signal);
2151
- Object.assign(output, terminal);
2152
- stream.push({
2153
- type: "error",
2154
- reason: terminal.stopReason,
2155
- error: output
2204
+ failTransportStream({
2205
+ stream,
2206
+ output,
2207
+ signal: options?.signal,
2208
+ error,
2209
+ cleanup: () => cleanStreamingScratchBuffers(output)
2156
2210
  });
2157
- stream.end();
2158
2211
  } finally {
2159
2212
  firstEventAbort?.dispose();
2160
2213
  }
2161
2214
  }
2162
2215
  //#endregion
2163
- export { isAzureResponsesTextDeltaEvent as A, buildResponsesInputMessage as B, summarizeResponsesTools as C, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as D, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as E, commitResponsesEncryptedContentAttempt as F, suppressOpenAIResponsesCompaction as G, createOpenAIResponsesAssistantOutput as H, createResponsesStreamWithEncryptedContentRetry as I, resolveModelPayloadDebugMode as J, resolveReplayableResponsesMessageId as K, isInvalidEncryptedContentError as L, isResponsesTextContentPartType as M, isResponsesTextDeltaEventType as N, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as O, resolveResponsesMessageSnapshotCollapse as P, resolveAzureOpenAIApiVersion as R, summarizeResponsesPayload as S, readResponsesToolCallItemIdentity as T, buildOpenAIResponsesReasoningReplayMetadata as U, convertResponsesMessages$1 as V, captureOpenAIResponsesCompaction as W, resolveModelSseDebugMode as Y, safeDebugValue as _, resolveResponsesReasoningEffort as a, summarizeOpenAITransportError as b, processResponsesStream as c, resolveResponsesTerminalStopReason as d, observeResponsesStream as f, normalizeResponsesFailedEvent as g, logResponsesFailedNoDetails as h, createResponsesAssistantOutput as i, isAzureResponsesTextDeltaEventType as j, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as k, mapResponsesTerminalUsage as l, buildResponsesFailedNoDetailsObservation as m, applyResponsesServiceTierPricing as n, runResponsesStreamLifecycle as o, ResponsesStreamFailure as p, emitModelTransportDebug as q, convertResponsesMessages as r, convertResponsesToolPayload as s, applyCommonResponsesParams as t, readResponsesReasoningTokens as u, stringifyRedactedEvent as v, createResponsesToolCallTracker as w, summarizeResponsesFailedNoDetailsObservation as x, stringifyRedactedPayload as y, resolveNextResponsesEncryptedContentAttempt as z };
2216
+ export { isAzureResponsesTextDeltaEvent as A, buildResponsesInputMessage as B, summarizeResponsesTools as C, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as D, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as E, commitResponsesEncryptedContentAttempt as F, captureOpenAIResponsesCompaction as G, createOpenAIResponsesAssistantOutput as H, createResponsesStreamWithEncryptedContentRetry as I, resolveReplayableResponsesMessageId as J, resolveNewestOpenAIResponsesCompactionReplay as K, isInvalidEncryptedContentError as L, isResponsesTextContentPartType as M, isResponsesTextDeltaEventType as N, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as O, resolveResponsesMessageSnapshotCollapse as P, resolveAzureOpenAIApiVersion as R, summarizeResponsesPayload as S, readResponsesToolCallItemIdentity as T, CompactionReplayRefreshRequiredError as U, convertResponsesMessages$1 as V, buildOpenAIResponsesReasoningReplayMetadata as W, resolveModelPayloadDebugMode as X, emitModelTransportDebug as Y, resolveModelSseDebugMode as Z, safeDebugValue as _, resolveResponsesReasoningEffort as a, summarizeOpenAITransportError as b, processResponsesStream as c, resolveResponsesTerminalStopReason as d, observeResponsesStream as f, normalizeResponsesFailedEvent as g, logResponsesFailedNoDetails as h, createResponsesAssistantOutput as i, isAzureResponsesTextDeltaEventType as j, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as k, mapResponsesTerminalUsage as l, buildResponsesFailedNoDetailsObservation as m, applyResponsesServiceTierPricing as n, runResponsesStreamLifecycle as o, ResponsesStreamFailure as p, suppressOpenAIResponsesCompaction as q, convertResponsesMessages as r, convertResponsesToolPayload as s, applyCommonResponsesParams as t, readResponsesReasoningTokens as u, stringifyRedactedEvent as v, createResponsesToolCallTracker as w, summarizeResponsesFailedNoDetailsObservation as x, stringifyRedactedPayload as y, resolveNextResponsesEncryptedContentAttempt as z };