@openclaw/ai 2026.9.7 → 2026.10.1-beta.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 (115) hide show
  1. package/README.md +4 -1
  2. package/dist/{anthropic-Cw2pgccz.mjs → anthropic-CZv6XFER.mjs} +52 -147
  3. package/dist/{anthropic-payload-policy-NIPVYXPq.d.mts → anthropic-payload-policy-BhCcgNdm.d.mts} +7 -4
  4. package/dist/{anthropic-stream-reducer-D9MCkl8Z.mjs → anthropic-stream-reducer-BQ1tjd7x.mjs} +369 -233
  5. package/dist/{api-registry-D-nbmSqr.d.mts → api-registry-DpU0Rj-I.d.mts} +4 -4
  6. package/dist/{provider-transcript-transform-JbFbHV8h.mjs → assistant-output-OLm-Oln0.mjs} +17 -17
  7. package/dist/{assistant-text-phase-C20rxWwP.mjs → assistant-text-phase-Bl1aDCB7.mjs} +2 -8
  8. package/dist/{azure-openai-responses-BwT3-X8P.mjs → azure-openai-responses-DH7bd3QT.mjs} +12 -17
  9. package/dist/{azure-openai-responses-client-compat-C7K7QfUE.mjs → azure-openai-responses-client-compat-D0dvJMbZ.mjs} +3 -10
  10. package/dist/{base64-C1PsYcRQ.mjs → base64-C8CdcsjU.mjs} +3 -45
  11. package/dist/cloudflare-5qSGvIUH.mjs +39 -0
  12. package/dist/{diagnostics-CJaB6g8J.mjs → diagnostics-Caj-4RBA.mjs} +19 -37
  13. package/dist/diagnostics.d.mts +4 -4
  14. package/dist/diagnostics.mjs +2 -2
  15. package/dist/{event-stream-vd9UnCAU.mjs → event-stream-C5AbCAaZ.mjs} +29 -1
  16. package/dist/event-stream-DqDQWqiy.d.mts +1 -0
  17. package/dist/{event-stream-DOPFYVqs.d.mts → event-stream-DrRM_90c.d.mts} +1 -1
  18. package/dist/event-stream.d.mts +2 -2
  19. package/dist/event-stream.mjs +1 -1
  20. package/dist/{github-copilot-request-facts-BTEBMeOv.mjs → github-copilot-request-facts-DEE6gcB9.mjs} +3 -1
  21. package/dist/{google-BfapkS_K.mjs → google-1WLOtb8w.mjs} +12 -9
  22. package/dist/{google-interactions-DW3iXzjc.mjs → google-interactions-wrnE6MLw.mjs} +39 -49
  23. package/dist/{google-messages-CtjVtVot.mjs → google-messages-BwPPycw6.mjs} +11 -17
  24. package/dist/{google-shared-Y2YfotEu.mjs → google-shared-Eql1OMPU.mjs} +5 -6
  25. package/dist/{google-vertex-Dov4kBWu.mjs → google-vertex-0LrlRoO3.mjs} +11 -11
  26. package/dist/{host-rxlNaBwm.d.mts → host-BinBeGcQ.d.mts} +12 -4
  27. package/dist/{host-CHi3X87F.mjs → host-DCW52iHe.mjs} +57 -9
  28. package/dist/{host-policy-BOAwRg_M.mjs → host-policy-B3jc4Rpn.mjs} +9 -2
  29. package/dist/{index-D6KsSE74.d.mts → index-a8e_oKnu.d.mts} +7 -5
  30. package/dist/index.d.mts +23 -7
  31. package/dist/index.mjs +7 -7
  32. package/dist/internal/anthropic.d.mts +6 -6
  33. package/dist/internal/anthropic.mjs +5 -5
  34. package/dist/internal/google-model-family.mjs +1 -1
  35. package/dist/internal/openai-completions-compat.d.mts +1 -1
  36. package/dist/internal/openai-completions-compat.mjs +1 -1
  37. package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
  38. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  39. package/dist/internal/openai.d.mts +14 -10
  40. package/dist/internal/openai.mjs +12 -12
  41. package/dist/internal/runtime.d.mts +18 -9
  42. package/dist/internal/runtime.mjs +9 -9
  43. package/dist/internal/shared.d.mts +6 -4
  44. package/dist/internal/shared.mjs +6 -6
  45. package/dist/internal/tool-schema.mjs +1 -1
  46. package/dist/json-schema-Bp07Qui3.mjs +22 -0
  47. package/dist/{llm-request-activity-BjtkplhG.mjs → llm-request-activity-D8f_oxHj.mjs} +1 -2
  48. package/dist/{mistral-RS6mboC-.mjs → mistral-DSt4vQAO.mjs} +18 -29
  49. package/dist/number-coercion-V8-BhME4.mjs +47 -0
  50. package/dist/{openai-chatgpt-responses-CYbidtrn.mjs → openai-chatgpt-responses-BC2x0Oqx.mjs} +215 -164
  51. package/dist/openai-completions-DNyHnXKg.mjs +25 -0
  52. package/dist/{openai-completions-compat-qJjmqQ71.d.mts → openai-completions-compat-BYdYpXhU.d.mts} +3 -3
  53. package/dist/{openai-completions-compat-BOVWBZDn.mjs → openai-completions-compat-BdmlhD4u.mjs} +30 -23
  54. package/dist/{openai-completions-stream-CDCuw3DP.mjs → openai-completions-transport-DWM2mQDB.mjs} +389 -76
  55. package/dist/{openai-prompt-cache-CouErLh7.d.mts → openai-prompt-cache-45-AH_xv.d.mts} +2 -2
  56. package/dist/{openai-prompt-cache-D2V7MqR7.mjs → openai-prompt-cache-I8YQTzf8.mjs} +1 -1
  57. package/dist/{openai-responses-compaction-replay-DiYn-gFM.d.mts → openai-responses-compaction-replay-BClApUIf.d.mts} +4 -4
  58. package/dist/{openai-responses-compaction-window-UNK1GDpy.mjs → openai-responses-compaction-window-m878aVpU.mjs} +25 -83
  59. package/dist/{openai-reasoning-effort-ConhwkeX.mjs → openai-responses-contracts-BKu8O7l4.mjs} +106 -7
  60. package/dist/{openai-responses-contracts-D1iZ0njF.d.mts → openai-responses-contracts-Br5IIw_h.d.mts} +16 -5
  61. package/dist/openai-responses-prompt-observer-internal-CCg7B6l4.mjs +32 -0
  62. package/dist/{openai-responses-shared-DL4ulQn7.mjs → openai-responses-shared-C7oVyjED.mjs} +297 -312
  63. package/dist/{openai-responses-terminal-usage-BE7lf7nW.d.mts → openai-responses-terminal-usage-DgImcyJu.d.mts} +2 -2
  64. package/dist/{openai-responses-CKCBEc2W.mjs → openai-responses-uZ5oWSp7.mjs} +12 -21
  65. package/dist/{openai-tool-schema-vsl-cE-n.mjs → openai-tool-schema-DYNePiF8.mjs} +66 -36
  66. package/dist/{openai-transport-params-BwlpzX-2.mjs → openai-transport-params-JFsnIyto.mjs} +25 -30
  67. package/dist/openai-web-search-tools-Cfu0uLyN.mjs +14 -0
  68. package/dist/{positive-integer-CjN5OJbH.mjs → positive-integer-CwLi8LUL.mjs} +1 -1
  69. package/dist/{provider-error-CwT_j2v0.mjs → provider-error-DQBE1bUQ.mjs} +17 -28
  70. package/dist/{provider-options-Df7ov0K1.d.mts → provider-options-D5ABCV_l.d.mts} +2 -2
  71. package/dist/{provider-replay-context-DsyI5jOP.mjs → provider-replay-context-C7Bmi84a.mjs} +6 -2
  72. package/dist/{provider-transport-turn-state-BheUi_hl.mjs → provider-transport-turn-state-_M2kLdUE.mjs} +25 -3
  73. package/dist/{provider-types-d4XnoZMd.d.mts → provider-types-F8Mqc9Ma.d.mts} +3 -3
  74. package/dist/provider-types.d.mts +6 -6
  75. package/dist/providers.d.mts +2 -2
  76. package/dist/providers.mjs +14 -26
  77. package/dist/{reasoning-tag-text-partitioner-B6FIIBt6.mjs → reasoning-tag-text-partitioner-Ju9VpUGl.mjs} +23 -37
  78. package/dist/required-api-key-D4kn3252.mjs +9 -0
  79. package/dist/sanitize-unicode-CjDG6jJx.d.mts +5 -0
  80. package/dist/{session-affinity-Bcunsn4I.mjs → session-affinity-DA4WHv1h.mjs} +2 -6
  81. package/dist/session-resources-D1wgDQ8C.mjs +40 -0
  82. package/dist/{simple-options-CGAkCwtM.mjs → simple-options-BkKTXxhp.mjs} +7 -11
  83. package/dist/{src-H4aXcFuX.mjs → src-B0NIt2UK.mjs} +7 -4
  84. package/dist/stream-DSdzKsDK.mjs +275 -0
  85. package/dist/{stream-first-event-timeout-B9o0S4SZ.mjs → stream-first-event-timeout-D9ZmL_s9.mjs} +3 -3
  86. package/dist/{string-coerce-fsri9iCu.mjs → string-coerce-CtgOVOSv.mjs} +5 -1
  87. package/dist/{string-normalization-J9ZiLfGO.mjs → string-normalization-PN10hf6d.mjs} +1 -1
  88. package/dist/{transport-utils-C-4bf2Ok.mjs → text-signature-MLwfi6fq.mjs} +18 -18
  89. package/dist/{transport-stream-shared-yYhXa4kX.d.mts → transport-stream-shared-BcAKh2XH.d.mts} +6 -19
  90. package/dist/{transport-stream-shared-Dh5qKJ8e.mjs → transport-stream-shared-CxXXz_Dd.mjs} +171 -56
  91. package/dist/transports.d.mts +22 -23
  92. package/dist/transports.mjs +251 -495
  93. package/dist/types-BuiEBM3u.d.mts +1 -0
  94. package/dist/types-CQc6JNG4.mjs +69 -0
  95. package/dist/{types-CLLR3eB4.d.mts → types-DvzmWW8J.d.mts} +58 -6
  96. package/dist/types.d.mts +6 -6
  97. package/dist/types.mjs +5 -5
  98. package/dist/usage-CJH5D6Ea.mjs +19 -0
  99. package/dist/{validation-Cat2wQsc.d.mts → validation-B3lQt_VE.d.mts} +1 -1
  100. package/dist/{validation-BFZc40Ig.mjs → validation-DbqlIfDn.mjs} +15 -30
  101. package/dist/validation.d.mts +1 -1
  102. package/dist/validation.mjs +1 -1
  103. package/package.json +4 -4
  104. package/dist/cache-retention-0x979a5V.mjs +0 -12
  105. package/dist/event-stream-CMQfX_yr.d.mts +0 -1
  106. package/dist/github-copilot-headers-B37TB3rB.mjs +0 -30
  107. package/dist/openai-completions-D14ihPYk.mjs +0 -188
  108. package/dist/openai-provider-client-CwfsGBbA.mjs +0 -24
  109. package/dist/openai-responses-contracts-CLxnqS9p.mjs +0 -81
  110. package/dist/openai-responses-prompt-observer-internal-iAqLb4tk.mjs +0 -198
  111. package/dist/sanitize-unicode-BZiVbGwK.d.mts +0 -24
  112. package/dist/session-resources-CkR4WWy1.mjs +0 -21
  113. package/dist/stream-DDsCBgd-.mjs +0 -68
  114. package/dist/types-CB-_vNyI.d.mts +0 -1
  115. package/dist/types-LFWwv0cF.mjs +0 -8
@@ -1,24 +1,25 @@
1
+ import "./src-B0NIt2UK.mjs";
2
+ import { _ as runtimeContextContentToText, f as hasRuntimeContextMarker, p as isRuntimeContextMessage } from "./types-CQc6JNG4.mjs";
1
3
  import { o as readProviderRefusalReview, t as appendAssistantMessageDiagnostic } from "./diagnostics-DzrF1h4J.mjs";
2
- import { r as appendAssistantThinking } from "./event-stream-vd9UnCAU.mjs";
4
+ import { r as appendAssistantThinking } from "./event-stream-C5AbCAaZ.mjs";
3
5
  import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
4
- import { k as isImageWithMediaPayload, n as getAiTransportHost, r as resolveAiTransportHeaderSentinels, w as calculateCost } from "./host-CHi3X87F.mjs";
5
- import { a as normalizeOptionalString, o as normalizeStringifiedOptionalString, s as readStringValue } from "./string-coerce-fsri9iCu.mjs";
6
- import { d as supportsOpenAITemperature } from "./openai-reasoning-effort-ConhwkeX.mjs";
7
- import { o as truncateUtf16Safe, s as stableStringify } from "./provider-error-CwT_j2v0.mjs";
8
- import { a as resolveModelSseDebugMode, d as isResponsesProviderTool, g as resolveResponsesTerminalStopReason, h as readResponsesReasoningTokens, i as resolveModelPayloadDebugMode, l as ResponsesOutputIdentityError, m as mapResponsesTerminalUsage, r as emitModelTransportDebug, u as hasOnlyResponsesFunctionTools } from "./diagnostics-CJaB6g8J.mjs";
9
- import { o as redactSensitiveText } from "./transport-utils-C-4bf2Ok.mjs";
10
- import { i as resolveOpenAICompletionsCompat } from "./openai-completions-compat-BOVWBZDn.mjs";
11
- import { A as shortHash, C as parseJsonObjectPreservingUnsafeIntegers, E as createToolArgumentPreviewSchedule, O as parseStreamingJson, S as withProviderResponseHook, _ as sanitizeNonEmptyTransportPayloadText, b as transportAbortError, c as failTransportStream, d as iterateModelStream, g as parseTerminalToolCallArguments, t as IncompleteToolCallError, u as finalizeTransportStream, v as sanitizeTransportPayloadText } from "./transport-stream-shared-Dh5qKJ8e.mjs";
12
- import { C as stripSystemPromptCacheBoundary, D as sortPromptCacheToolsByName, d as describeToolResultMediaPlaceholder, m as extractToolResultText, s as prepareModelRequestBody } from "./simple-options-CGAkCwtM.mjs";
13
- import { A as redactIdentifier, C as log, d as prepareOpenAITools, h as resolveOpenAIRequestReasoning, j as sha256Hex, u as resolveOpenAIStrictToolFlagWithDiagnostics, y as createOpenAIProviderAcceptanceHook } from "./openai-transport-params-BwlpzX-2.mjs";
14
- import { n as providerReplayContextMatches, t as buildProviderReplayContext } from "./provider-replay-context-DsyI5jOP.mjs";
15
- import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
16
- import { t as transformProviderMessages } from "./provider-transcript-transform-JbFbHV8h.mjs";
17
- import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-B9o0S4SZ.mjs";
18
- import { a as resolveOpenAIProjectedToolsStrictToolFlag, f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-vsl-cE-n.mjs";
19
- import { 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, p as isPreviousResponseRejection, s as OPENAI_RESPONSES_REASONING_REPLAY_META_KEY } from "./openai-responses-contracts-CLxnqS9p.mjs";
20
- import { n as isOpenAIResponsesCompactionOutput, r as readOpenAIResponsesCompactionWindow } from "./openai-responses-compaction-window-UNK1GDpy.mjs";
21
- import { n as registerSessionResourceCleanup } from "./session-resources-CkR4WWy1.mjs";
6
+ import { a as normalizeOptionalString, c as readStringValue, o as normalizeStringifiedOptionalString } from "./string-coerce-CtgOVOSv.mjs";
7
+ import { N as isImageWithMediaPayload, O as calculateCost, a as resolveAiTransportHeaderSentinels, r as getAiTransportHost } from "./host-DCW52iHe.mjs";
8
+ import { D as supportsOpenAITemperature, a as OPENAI_RESPONSES_COMPACTION_REPLAY_TYPE, c as OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE, f as RESPONSE_FAILED_NO_DETAILS_MESSAGE, g as responsesServiceTierObserver, o as OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY, p as isPreviousResponseRejection, s as OPENAI_RESPONSES_REASONING_REPLAY_META_KEY } from "./openai-responses-contracts-BKu8O7l4.mjs";
9
+ import { n as getSessionResourceOwnerId, r as registerSessionResourceCleanup } from "./session-resources-D1wgDQ8C.mjs";
10
+ import { o as truncateUtf16Safe, s as stableStringify } from "./provider-error-DQBE1bUQ.mjs";
11
+ import { a as resolveModelSseDebugMode, d as isResponsesProviderTool, g as resolveResponsesTerminalStopReason, h as readResponsesReasoningTokens, i as resolveModelPayloadDebugMode, l as ResponsesOutputIdentityError, m as mapResponsesTerminalUsage, r as emitModelTransportDebug, u as hasOnlyResponsesFunctionTools } from "./diagnostics-Caj-4RBA.mjs";
12
+ import { o as redactSensitiveText, t as encodeTextSignatureV1 } from "./text-signature-MLwfi6fq.mjs";
13
+ import { c as resolveOpenAIResponsesTextFormat, i as resolveOpenAICompletionsCompat } from "./openai-completions-compat-BdmlhD4u.mjs";
14
+ import { A as shortHash, C as parseJsonObjectPreservingUnsafeIntegers, E as createToolArgumentPreviewSchedule, O as parseStreamingJson, S as withProviderResponseHook, _ as sanitizeNonEmptyTransportPayloadText, b as transportAbortError, c as failTransportStream, d as iterateModelStream, g as parseTerminalToolCallArguments, t as IncompleteToolCallError, u as finalizeTransportStream, v as sanitizeTransportPayloadText } from "./transport-stream-shared-CxXXz_Dd.mjs";
15
+ import { C as stripSystemPromptCacheBoundary, D as sortPromptCacheToolsByName, d as describeToolResultMediaPlaceholder, m as extractToolResultText, s as prepareModelRequestBody } from "./simple-options-BkKTXxhp.mjs";
16
+ import { A as redactIdentifier, C as log, d as prepareOpenAITools, h as resolveOpenAIRequestReasoning, j as sha256Hex, u as resolveOpenAIStrictToolFlagWithDiagnostics, y as createOpenAIProviderAcceptanceHook } from "./openai-transport-params-JFsnIyto.mjs";
17
+ import { n as isProviderReplayContext, r as providerReplayContextMatches, t as buildProviderReplayContext } from "./provider-replay-context-C7Bmi84a.mjs";
18
+ import { n as transformProviderMessages } from "./assistant-output-OLm-Oln0.mjs";
19
+ import { t as notifyLlmRequestActivity } from "./llm-request-activity-D8f_oxHj.mjs";
20
+ import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-D9ZmL_s9.mjs";
21
+ import { a as resolveOpenAIProjectedToolsStrictToolFlag, f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-DYNePiF8.mjs";
22
+ import { n as isOpenAIResponsesCompactionOutput, r as readOpenAIResponsesCompactionWindow } from "./openai-responses-compaction-window-m878aVpU.mjs";
22
23
  import { randomUUID } from "node:crypto";
23
24
  //#region packages/ai/src/transports/openai-responses-replay.ts
24
25
  /** Resolves the assistant message id that can be replayed to OpenAI Responses. */
@@ -90,10 +91,6 @@ function shouldNormalizeOpenAIResponsesToolCallId(id) {
90
91
  //#region packages/ai/src/transports/openai-responses-compaction-replay.ts
91
92
  const OPENAI_RESPONSES_COMPACTION_SUPPRESSION_TYPE = "openai-responses-compaction-suppression";
92
93
  const OPENAI_RESPONSES_COMPACTION_SUPPRESSION_DATA = "rejected";
93
- function isOpenAIResponsesReplayContext(value) {
94
- if (!isRecord(value)) return false;
95
- return typeof value.provider === "string" && typeof value.api === "string" && typeof value.model === "string" && (value.baseUrlHash === void 0 || typeof value.baseUrlHash === "string") && (value.sessionHash === void 0 || typeof value.sessionHash === "string") && (value.authProfileHash === void 0 || typeof value.authProfileHash === "string");
96
- }
97
94
  function isOpenAIResponsesCompactionState(state) {
98
95
  if (typeof state.baseUrlHash !== "string" || state.v !== 1) return false;
99
96
  if (state.type === OPENAI_RESPONSES_COMPACTION_SUPPRESSION_TYPE) return state.data === OPENAI_RESPONSES_COMPACTION_SUPPRESSION_DATA;
@@ -101,7 +98,7 @@ function isOpenAIResponsesCompactionState(state) {
101
98
  return state.type === "openai-responses-compaction" && typeof state.data === "string" && state.data.length > 0 && (state.id === void 0 || typeof state.id === "string") && (state.replayIndex === void 0 || typeof state.replayIndex === "number" && Number.isSafeInteger(state.replayIndex) && state.replayIndex >= 0);
102
99
  }
103
100
  function readOpenAIResponsesCompactionReplayState(value) {
104
- return isRecord(value) && isOpenAIResponsesReplayContext(value) && isOpenAIResponsesCompactionState(value) ? value : void 0;
101
+ return isRecord(value) && isProviderReplayContext(value) && isOpenAIResponsesCompactionState(value) ? value : void 0;
105
102
  }
106
103
  function captureOpenAIResponsesCompaction(output, item, boundary, model, captureMetadata, compactedOutput) {
107
104
  const metadata = captureMetadata ?? buildOpenAIResponsesReasoningReplayMetadata(model);
@@ -293,7 +290,9 @@ function replayResponsesReasoningUpdates(previous, request, previousOutputLength
293
290
  }
294
291
  //#endregion
295
292
  //#region packages/ai/src/transports/openai-responses-continuation.ts
296
- const HTTP_CONTINUATION_IDLE_TTL_MS = 3e5;
293
+ const HTTP_CONTINUATION_IDLE_TTL_MS = 54e5;
294
+ const MAX_HTTP_CONTINUATION_READY_ENTRIES = 1e3;
295
+ const MAX_HTTP_CONTINUATION_RETAINED_BYTES = 67108864;
297
296
  const TURN_HEADERS = /* @__PURE__ */ new Set([
298
297
  "traceparent",
299
298
  "x-openclaw-turn-id",
@@ -539,8 +538,27 @@ function resolveResponsesContinuationRequest(continuation, request, steering) {
539
538
  };
540
539
  }
541
540
  const httpContinuationEntries = /* @__PURE__ */ new Map();
541
+ const readyHttpContinuationEntries = /* @__PURE__ */ new Map();
542
+ let httpContinuationRetainedBytes = 0;
542
543
  function deleteHttpContinuationIfOwned(key, entry) {
543
- if (httpContinuationEntries.get(key) === entry) httpContinuationEntries.delete(key);
544
+ if (httpContinuationEntries.get(key) !== entry) return;
545
+ if (entry.kind === "ready") {
546
+ clearTimeout(entry.idleTimer);
547
+ httpContinuationRetainedBytes -= entry.retainedBytes;
548
+ readyHttpContinuationEntries.delete(key);
549
+ }
550
+ httpContinuationEntries.delete(key);
551
+ }
552
+ function evictReadyEntriesForCapacity(pendingBytes) {
553
+ for (;;) {
554
+ const overCapacity = readyHttpContinuationEntries.size >= MAX_HTTP_CONTINUATION_READY_ENTRIES;
555
+ const overBudget = httpContinuationRetainedBytes + pendingBytes > MAX_HTTP_CONTINUATION_RETAINED_BYTES;
556
+ if (!overCapacity && !overBudget) return;
557
+ const oldest = readyHttpContinuationEntries.entries().next();
558
+ if (oldest.done) return;
559
+ const [oldestKey, oldestEntry] = oldest.value;
560
+ deleteHttpContinuationIfOwned(oldestKey, oldestEntry);
561
+ }
544
562
  }
545
563
  function connectionIdentity(params) {
546
564
  const headers = Object.entries(resolveAiTransportHeaderSentinels(params.headers) ?? {}).map(([name, value]) => [name.toLowerCase(), value]).filter(([name]) => !TURN_HEADERS.has(name)).toSorted(([a], [b]) => a.localeCompare(b));
@@ -551,13 +569,15 @@ function connectionIdentity(params) {
551
569
  ]));
552
570
  }
553
571
  function claimOpenAIResponsesHttpContinuation(params) {
554
- const key = `${params.sessionId}\0${connectionIdentity(params)}`;
572
+ const owner = getAiTransportHost();
573
+ const key = `${getSessionResourceOwnerId(owner)}\0${params.sessionId}\0${connectionIdentity(params)}`;
555
574
  const previous = httpContinuationEntries.get(key);
556
575
  if (previous?.kind === "claimed") return;
557
- if (previous?.kind === "ready") clearTimeout(previous.idleTimer);
576
+ if (previous?.kind === "ready") deleteHttpContinuationIfOwned(key, previous);
558
577
  const claimed = {
559
578
  kind: "claimed",
560
- sessionId: params.sessionId
579
+ sessionId: params.sessionId,
580
+ owner
561
581
  };
562
582
  httpContinuationEntries.set(key, claimed);
563
583
  try {
@@ -569,14 +589,25 @@ function claimOpenAIResponsesHttpContinuation(params) {
569
589
  fullRequest,
570
590
  commit: (effectiveRequest, response, dispatchedPreviousResponseId) => {
571
591
  if (httpContinuationEntries.get(key) !== claimed) return;
592
+ const state = recordResponsesContinuationState(previous?.kind === "ready" ? previous.state : void 0, effectiveRequest, response, previous?.kind === "ready" && dispatchedPreviousResponseId === previous.state.lastResponseId);
593
+ const retainedBytes = Buffer.byteLength(JSON.stringify(state), "utf8");
594
+ if (httpContinuationEntries.get(key) !== claimed) return;
595
+ if (retainedBytes > MAX_HTTP_CONTINUATION_RETAINED_BYTES) {
596
+ deleteHttpContinuationIfOwned(key, claimed);
597
+ return;
598
+ }
599
+ evictReadyEntriesForCapacity(retainedBytes);
572
600
  const ready = {
573
601
  ...claimed,
574
602
  kind: "ready",
575
- state: recordResponsesContinuationState(previous?.kind === "ready" ? previous.state : void 0, effectiveRequest, response, previous?.kind === "ready" && dispatchedPreviousResponseId === previous.state.lastResponseId),
576
- idleTimer: setTimeout(() => deleteHttpContinuationIfOwned(key, ready), HTTP_CONTINUATION_IDLE_TTL_MS)
603
+ state,
604
+ idleTimer: setTimeout(() => deleteHttpContinuationIfOwned(key, ready), HTTP_CONTINUATION_IDLE_TTL_MS),
605
+ retainedBytes
577
606
  };
578
607
  ready.idleTimer.unref?.();
608
+ httpContinuationRetainedBytes += retainedBytes;
579
609
  httpContinuationEntries.set(key, ready);
610
+ readyHttpContinuationEntries.set(key, ready);
580
611
  },
581
612
  release: () => deleteHttpContinuationIfOwned(key, claimed)
582
613
  };
@@ -585,20 +616,21 @@ function claimOpenAIResponsesHttpContinuation(params) {
585
616
  throw error;
586
617
  }
587
618
  }
588
- registerSessionResourceCleanup((sessionId) => {
589
- for (const [key, entry] of httpContinuationEntries) if (!sessionId || entry.sessionId === sessionId) {
590
- if (entry.kind === "ready") clearTimeout(entry.idleTimer);
591
- httpContinuationEntries.delete(key);
592
- }
619
+ registerSessionResourceCleanup((sessionId, owner) => {
620
+ for (const [key, entry] of httpContinuationEntries) if ((!owner || entry.owner === owner) && (!sessionId || entry.sessionId === sessionId)) deleteHttpContinuationIfOwned(key, entry);
593
621
  });
594
622
  //#endregion
595
623
  //#region packages/ai/src/transports/openai-responses-input-replay.ts
596
624
  function recordResponsesInputReplay(message, replay) {
597
625
  if (replay) Object.assign(message, { openclawResponsesInputReplay: replay });
598
626
  }
599
- function readResponsesInputReplay(message) {
627
+ function readResponsesInputReplayState(message) {
600
628
  const replay = "openclawResponsesInputReplay" in message ? message.openclawResponsesInputReplay : void 0;
601
- if (isRecord(replay) && typeof replay.afterResponseId === "string" && Array.isArray(replay.before) && replay.before.every((item) => typeof item === "string") && Array.isArray(replay.after) && replay.after.every((item) => typeof item === "string")) return {
629
+ return isRecord(replay) ? replay : void 0;
630
+ }
631
+ function readResponsesInputReplay(message) {
632
+ const replay = readResponsesInputReplayState(message);
633
+ if (replay && typeof replay.afterResponseId === "string" && Array.isArray(replay.before) && replay.before.every((item) => typeof item === "string") && Array.isArray(replay.after) && replay.after.every((item) => typeof item === "string")) return {
602
634
  afterResponseId: replay.afterResponseId,
603
635
  before: replay.before,
604
636
  after: replay.after
@@ -650,6 +682,10 @@ function createResponsesInputReplay(model) {
650
682
  }
651
683
  //#endregion
652
684
  //#region packages/ai/src/transports/openai-responses-replay-messages-internal.ts
685
+ function resolveResponsesInstructionRole(model) {
686
+ const supportsDeveloperRole = !isRecord(model.compat) || model.compat.supportsDeveloperRole !== false;
687
+ return model.reasoning && supportsDeveloperRole ? "developer" : "system";
688
+ }
653
689
  function stripEncryptedReasoningContentFields(value) {
654
690
  if (!value || typeof value !== "object") return {
655
691
  value,
@@ -695,7 +731,7 @@ function stripEncryptedReasoningContentFields(value) {
695
731
  };
696
732
  }
697
733
  function isOpenAIResponsesReasoningReplayMetadata(value) {
698
- if (!isOpenAIResponsesReplayContext(value)) return false;
734
+ if (!isProviderReplayContext(value)) return false;
699
735
  const record = value;
700
736
  return record.v === 1 && record.source === "openai-responses";
701
737
  }
@@ -726,13 +762,6 @@ function normalizeResponsesReplayItemId(id, prefix) {
726
762
  if (id.length <= 64) return id;
727
763
  return `${prefix}_${shortHash(id)}`;
728
764
  }
729
- function encodeTextSignatureV1(id, phase) {
730
- return JSON.stringify({
731
- v: 1,
732
- id,
733
- ...phase ? { phase } : {}
734
- });
735
- }
736
765
  function orderResponsesAsyncToolResults(source) {
737
766
  const turnKey = (message) => {
738
767
  const id = message.turnId || message.responseId;
@@ -821,18 +850,14 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
821
850
  const sanitized = sanitizeIdPart(part);
822
851
  return (sanitized.length > 64 ? sanitized.slice(0, 64) : sanitized).replace(/_+$/, "");
823
852
  };
824
- const buildForeignResponsesItemId = (itemId) => {
825
- const normalized = `fc_${shortHash(itemId)}`;
826
- return normalized.length > 64 ? normalized.slice(0, 64) : normalized;
827
- };
853
+ const buildForeignResponsesItemId = (itemId) => `fc_${shortHash(itemId)}`;
828
854
  const buildSameProviderCopilotResponsesItemId = (itemId) => {
829
855
  const sanitized = sanitizeIdPart(itemId);
830
856
  const candidate = sanitized.startsWith("fc_") ? sanitized : `fc_${sanitized}`;
831
857
  return candidate.length > 64 ? buildForeignResponsesItemId(itemId) : candidate;
832
858
  };
833
859
  const normalizeToolCallId = (id, _targetModel, source) => {
834
- if (!allowedToolCallProviders.has(model.provider)) return normalizeIdPart(id);
835
- if (!id.includes("|")) return normalizeIdPart(id);
860
+ if (!allowedToolCallProviders.has(model.provider) || !id.includes("|")) return normalizeIdPart(id);
836
861
  const separatorIndex = id.indexOf("|");
837
862
  const callId = id.slice(0, separatorIndex);
838
863
  const itemId = id.slice(separatorIndex + 1);
@@ -851,13 +876,13 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
851
876
  preserveUnframedToolResults: replayPlan.preserveUnframedToolResults
852
877
  });
853
878
  const transformedMessages = orderResponsesAsyncToolResults(transformMessages(replayPlan.messages));
854
- if ((options?.includeSystemPrompt ?? true) && context.systemPrompt) messages.push(buildResponsesInputMessage(model.reasoning && model.compat?.supportsDeveloperRole !== false ? "developer" : "system", [{
879
+ if ((options?.includeSystemPrompt ?? true) && context.systemPrompt) messages.push(buildResponsesInputMessage(resolveResponsesInstructionRole(model), [{
855
880
  type: "input_text",
856
881
  text: sanitizeTransportPayloadText(stripSystemPromptCacheBoundary(context.systemPrompt))
857
882
  }]));
858
883
  if (replayPlan.compactedWindow) messages.push(...replayPlan.compactedWindow);
859
884
  let replayMessages = replayPlan.compaction ? [replayPlan.compaction, ...transformedMessages] : transformedMessages;
860
- const isCarrier = (message) => "role" in message && message.role === "user" && message.runtimeContextCarrier === true;
885
+ const isCarrier = (message) => "role" in message && hasRuntimeContextMarker(message);
861
886
  if (replayMessages.some(isCarrier)) {
862
887
  const anchored = [];
863
888
  let insertionIndex = replayPlan.compactedWindow ? 0 : void 0;
@@ -878,7 +903,11 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
878
903
  messages.push(msg);
879
904
  continue;
880
905
  }
881
- if (msg.role === "user") {
906
+ if (isRuntimeContextMessage(msg)) messages.push(buildResponsesInputMessage(resolveResponsesInstructionRole(model), [{
907
+ type: "input_text",
908
+ text: sanitizeTransportPayloadText(runtimeContextContentToText(msg.content))
909
+ }]));
910
+ else if (msg.role === "user") {
882
911
  if (typeof msg.content === "string") messages.push(buildResponsesInputMessage("user", [{
883
912
  type: "input_text",
884
913
  text: sanitizeTransportPayloadText(msg.content)
@@ -1004,10 +1033,6 @@ const TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set([
1004
1033
  "azure-openai-responses",
1005
1034
  "github-copilot"
1006
1035
  ]);
1007
- function inputReplay(message) {
1008
- const value = "openclawResponsesInputReplay" in message ? message.openclawResponsesInputReplay : void 0;
1009
- return isRecord(value) ? value : void 0;
1010
- }
1011
1036
  function contextFingerprint(input, output = []) {
1012
1037
  const reasoning = [...input, ...output].flatMap((item) => {
1013
1038
  if (!isRecord(item) || item.type !== "reasoning") return [];
@@ -1038,7 +1063,7 @@ function recordResponsesContextUsage(message, model, identity, request, output,
1038
1063
  totalTokens: usage.totalTokens
1039
1064
  };
1040
1065
  Object.assign(message, { openclawResponsesInputReplay: {
1041
- ...inputReplay(message),
1066
+ ...readResponsesInputReplayState(message),
1042
1067
  contextUsage
1043
1068
  } });
1044
1069
  }
@@ -1047,11 +1072,11 @@ function resolveResponsesContextUsageBoundary(messages, model, identity, systemP
1047
1072
  for (let index = messages.length - 1; index >= 0; index -= 1) {
1048
1073
  const message = messages[index];
1049
1074
  if (!message || !isAssistant(message)) continue;
1050
- const state = inputReplay(message)?.contextUsage;
1075
+ const state = readResponsesInputReplayState(message)?.contextUsage;
1051
1076
  const usage = message.usage.contextUsage;
1052
1077
  if (!isRecord(state) || usage?.state !== "available") continue;
1053
1078
  const { projection, prefixHash, prefixLength, promptTokens, totalTokens, includeSystemPrompt } = state;
1054
- if (!isOpenAIResponsesReplayContext(state) || !providerReplayContextMatches(state, buildProviderReplayContext(model, identity)) || message.provider !== model.provider || message.api !== model.api || message.model !== model.id || projection !== "transport" && projection !== "provider" || typeof prefixHash !== "string" || typeof prefixLength !== "number" || !Number.isSafeInteger(prefixLength) || prefixLength <= 0 || promptTokens !== usage.promptTokens || totalTokens !== usage.totalTokens || !Number.isSafeInteger(usage.totalTokens) || usage.totalTokens <= 0) return;
1079
+ if (!isProviderReplayContext(state) || !providerReplayContextMatches(state, buildProviderReplayContext(model, identity)) || message.provider !== model.provider || message.api !== model.api || message.model !== model.id || projection !== "transport" && projection !== "provider" || typeof prefixHash !== "string" || typeof prefixLength !== "number" || !Number.isSafeInteger(prefixLength) || prefixLength <= 0 || promptTokens !== usage.promptTokens || totalTokens !== usage.totalTokens || !Number.isSafeInteger(usage.totalTokens) || usage.totalTokens <= 0) return;
1055
1080
  const input = (projection === "transport" ? convertResponsesMessages : convertProviderResponsesMessages)(model, {
1056
1081
  messages: messages.filter(isProviderMessage),
1057
1082
  systemPrompt
@@ -1081,10 +1106,7 @@ function stringifyUnknown(value, fallback = "") {
1081
1106
  return fallback;
1082
1107
  }
1083
1108
  function safeDebugValue(value) {
1084
- if (typeof value === "string") return value;
1085
- if (typeof value === "number" || typeof value === "boolean") return String(value);
1086
- if (value === null) return "null";
1087
- if (value === void 0) return "undefined";
1109
+ if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") return String(value);
1088
1110
  return Array.isArray(value) ? "array" : typeof value;
1089
1111
  }
1090
1112
  function responseInputTextChars(input) {
@@ -1116,13 +1138,7 @@ function responseInputItemShape(input) {
1116
1138
  }).join(",") || "none";
1117
1139
  }
1118
1140
  function summarizeResponsesCompactionItems(input) {
1119
- if (!Array.isArray(input)) return [
1120
- "compactionItems=0",
1121
- "compactionIdHashes=none",
1122
- "compactionPayloadHashes=none",
1123
- "compactionInputIndexes=none"
1124
- ];
1125
- const compactions = input.flatMap((item, inputIndex) => {
1141
+ const compactions = (Array.isArray(input) ? input : []).flatMap((item, inputIndex) => {
1126
1142
  if (!isRecord(item) || item.type !== "compaction") return [];
1127
1143
  return [{
1128
1144
  idHash: typeof item.id === "string" ? sha256Hex(item.id) : void 0,
@@ -1170,7 +1186,7 @@ function stringifyRedactedPayload(value) {
1170
1186
  try {
1171
1187
  const encoded = JSON.stringify(value, (key, child) => key === "encrypted_content" ? "<opaque data omitted>" : child);
1172
1188
  if (!encoded) return "<empty>";
1173
- const redacted = redactSensitiveText(encoded, { mode: "tools" });
1189
+ const redacted = redactSensitiveText(encoded);
1174
1190
  return redacted.length > 8e3 ? `${truncateUtf16Safe(redacted, 8e3)}…<truncated>` : redacted;
1175
1191
  } catch {
1176
1192
  return "<unserializable>";
@@ -1189,85 +1205,51 @@ const RESPONSE_FAILED_FAILURE_FIELD_KEYS = [
1189
1205
  "provider_error",
1190
1206
  "error_details"
1191
1207
  ];
1192
- function readResponseFailedString(record, key) {
1193
- return stringifyUnknown(record?.[key]);
1194
- }
1195
1208
  function buildResponsesFailedEventSummary(message, responseId, code, observation) {
1196
- const summary = { message };
1197
- if (responseId) summary.responseId = responseId;
1198
- if (code) summary.code = code;
1199
- if (observation) summary.observation = observation;
1200
- return summary;
1209
+ return {
1210
+ message,
1211
+ ...responseId ? { responseId } : {},
1212
+ ...code ? { code } : {},
1213
+ ...observation ? { observation } : {}
1214
+ };
1201
1215
  }
1202
1216
  function isResponseFailedIdentifierKey(key) {
1203
1217
  const normalized = key.replace(/[-_\s]/g, "").toLowerCase();
1204
- return normalized === "requestid" || normalized === "xrequestid" || normalized === "providerrequestid" || normalized === "providerresponseid" || normalized === "litellmrequestid" || normalized.includes("request") && normalized.endsWith("id") || normalized.includes("provider") && normalized.endsWith("id");
1205
- }
1206
- function collectResponseFailedIdentifierHashes(value, opts = {}) {
1207
- const path = opts.path ?? "";
1208
- const depth = opts.depth ?? 0;
1209
- const identifierKey = opts.identifierKey ?? "";
1210
- const out = opts.out ?? [];
1211
- const seen = opts.seen ?? /* @__PURE__ */ new WeakSet();
1212
- if (out.length >= 12 || depth > 4 || !value || typeof value !== "object") return out;
1213
- if (seen.has(value)) return out;
1214
- seen.add(value);
1215
- if (Array.isArray(value)) {
1216
- for (const [index, item] of value.entries()) {
1217
- if (index >= 8 || out.length >= 12) break;
1218
- const itemString = typeof item === "string" || typeof item === "number" ? String(item).trim() : "";
1219
- if (identifierKey && isResponseFailedIdentifierKey(identifierKey) && itemString) {
1220
- out.push(`${path}[${index}]=${redactIdentifier(itemString, { len: 12 })}`);
1221
- continue;
1222
- }
1223
- collectResponseFailedIdentifierHashes(item, {
1224
- path: `${path}[${index}]`,
1225
- depth: depth + 1,
1226
- identifierKey,
1227
- out,
1228
- seen
1229
- });
1230
- }
1231
- return out;
1232
- }
1233
- for (const [key, child] of Object.entries(value)) {
1234
- if (out.length >= 12) break;
1235
- const childPath = path ? `${path}.${key}` : key;
1236
- const childString = typeof child === "string" || typeof child === "number" ? String(child).trim() : "";
1237
- if (isResponseFailedIdentifierKey(key) && childString) {
1238
- out.push(`${childPath}=${redactIdentifier(childString, { len: 12 })}`);
1239
- continue;
1218
+ return normalized.includes("request") && normalized.endsWith("id") || normalized.includes("provider") && normalized.endsWith("id");
1219
+ }
1220
+ function collectResponseFailedIdentifierHashes(input) {
1221
+ const out = [];
1222
+ const seen = /* @__PURE__ */ new WeakSet();
1223
+ const visit = (value, path, depth, identifierKey) => {
1224
+ if (out.length >= 12 || depth > 4 || !value || typeof value !== "object" || seen.has(value)) return;
1225
+ seen.add(value);
1226
+ const entries = Array.isArray(value) ? value.entries() : Object.entries(value);
1227
+ for (const [key, child] of entries) {
1228
+ if (out.length >= 12 || typeof key === "number" && key >= 8) break;
1229
+ const childPath = typeof key === "number" ? `${path}[${key}]` : path ? `${path}.${key}` : key;
1230
+ const childIdentifierKey = typeof key === "number" ? identifierKey : key;
1231
+ const isIdentifier = isResponseFailedIdentifierKey(childIdentifierKey);
1232
+ const childString = typeof child === "string" || typeof child === "number" ? String(child).trim() : "";
1233
+ if (isIdentifier && childString) out.push(`${childPath}=${redactIdentifier(childString, { len: 12 })}`);
1234
+ else visit(child, childPath, depth + 1, isIdentifier ? childIdentifierKey : "");
1240
1235
  }
1241
- collectResponseFailedIdentifierHashes(child, {
1242
- path: childPath,
1243
- depth: depth + 1,
1244
- identifierKey: isResponseFailedIdentifierKey(key) ? key : void 0,
1245
- out,
1246
- seen
1247
- });
1248
- }
1236
+ };
1237
+ visit(input, "", 0, "");
1249
1238
  return out;
1250
1239
  }
1251
- function redactResponseFailedDiagnosticValue(value, opts = {}) {
1252
- const key = opts.key ?? "";
1253
- const depth = opts.depth ?? 0;
1254
- if (typeof value === "string" || typeof value === "number") return key && isResponseFailedIdentifierKey(key) ? redactIdentifier(String(value), { len: 12 }) : value;
1255
- if (depth > 6 || !value || typeof value !== "object") return value;
1256
- const seen = opts.seen ?? /* @__PURE__ */ new WeakSet();
1257
- if (seen.has(value)) return "<circular>";
1258
- seen.add(value);
1259
- if (Array.isArray(value)) return value.slice(0, 16).map((item) => redactResponseFailedDiagnosticValue(item, {
1260
- key,
1261
- depth: depth + 1,
1262
- seen
1263
- }));
1264
- const out = {};
1265
- for (const [childKey, child] of Object.entries(value)) out[childKey] = redactResponseFailedDiagnosticValue(child, {
1266
- key: childKey,
1267
- depth: depth + 1,
1268
- seen
1269
- });
1270
- return out;
1240
+ function redactResponseFailedDiagnosticValue(input) {
1241
+ const seen = /* @__PURE__ */ new WeakSet();
1242
+ const redact = (value, key, depth) => {
1243
+ if (typeof value === "string" || typeof value === "number") return key && isResponseFailedIdentifierKey(key) ? redactIdentifier(String(value), { len: 12 }) : value;
1244
+ if (depth > 6 || !value || typeof value !== "object") return value;
1245
+ if (seen.has(value)) return "<circular>";
1246
+ seen.add(value);
1247
+ if (Array.isArray(value)) return value.slice(0, 16).map((item) => redact(item, key, depth + 1));
1248
+ const out = {};
1249
+ for (const [childKey, child] of Object.entries(value)) out[childKey] = redact(child, childKey, depth + 1);
1250
+ return out;
1251
+ };
1252
+ return redact(input, "", 0);
1271
1253
  }
1272
1254
  function buildResponsesFailedFailureFields(response) {
1273
1255
  if (!response) return {};
@@ -1279,10 +1261,10 @@ function buildResponsesFailedNoDetailsObservation(event, model, response = isRec
1279
1261
  const failureFields = redactResponseFailedDiagnosticValue(buildResponsesFailedFailureFields(response));
1280
1262
  const metadataKeys = isRecord(response?.metadata) ? Object.keys(response.metadata).toSorted() : [];
1281
1263
  const responsePreview = {
1282
- id: readResponseFailedString(response, "id"),
1283
- status: readResponseFailedString(response, "status"),
1284
- model: readResponseFailedString(response, "model"),
1285
- object: readResponseFailedString(response, "object"),
1264
+ id: stringifyUnknown(response?.id),
1265
+ status: stringifyUnknown(response?.status),
1266
+ model: stringifyUnknown(response?.model),
1267
+ object: stringifyUnknown(response?.object),
1286
1268
  failureFields,
1287
1269
  metadataKeys
1288
1270
  };
@@ -1309,14 +1291,14 @@ function summarizeResponsesFailedNoDetailsObservation(observation) {
1309
1291
  }
1310
1292
  function normalizeResponsesFailedEvent(event, model) {
1311
1293
  const response = isRecord(event.response) ? event.response : void 0;
1312
- const responseId = readResponseFailedString(response, "id") || void 0;
1294
+ const responseId = stringifyUnknown(response?.id) || void 0;
1313
1295
  const error = isRecord(response?.error) ? response.error : void 0;
1314
1296
  if (error) {
1315
- const code = readResponseFailedString(error, "code").trim();
1316
- const message = readResponseFailedString(error, "message").trim();
1297
+ const code = stringifyUnknown(error.code).trim();
1298
+ const message = stringifyUnknown(error.message).trim();
1317
1299
  if (code || message) return buildResponsesFailedEventSummary(`${code || "unknown"}: ${message || "no message"}`, responseId, code || void 0);
1318
1300
  }
1319
- const incompleteReason = readResponseFailedString(isRecord(response?.incomplete_details) ? response.incomplete_details : void 0, "reason");
1301
+ const incompleteReason = stringifyUnknown((isRecord(response?.incomplete_details) ? response.incomplete_details : void 0)?.reason);
1320
1302
  if (incompleteReason) return buildResponsesFailedEventSummary(`incomplete: ${incompleteReason}`, responseId);
1321
1303
  return buildResponsesFailedEventSummary(RESPONSE_FAILED_NO_DETAILS_MESSAGE, responseId, void 0, buildResponsesFailedNoDetailsObservation(event, model, response));
1322
1304
  }
@@ -1556,123 +1538,6 @@ function resolveResponsesMessageSnapshotCollapse(params) {
1556
1538
  return { kind: "keep" };
1557
1539
  }
1558
1540
  //#endregion
1559
- //#region packages/ai/src/providers/openai-responses-tool-call-tracker.ts
1560
- function readOutputIndex(event) {
1561
- return typeof event.output_index === "number" && Number.isInteger(event.output_index) && event.output_index >= 0 ? event.output_index : void 0;
1562
- }
1563
- function readEventIdentity(event) {
1564
- return { itemId: normalizeOptionalString(event.item_id) };
1565
- }
1566
- function readResponsesToolCallItemIdentity(item) {
1567
- return {
1568
- itemId: normalizeOptionalString(item.id),
1569
- callId: normalizeOptionalString(item.call_id)
1570
- };
1571
- }
1572
- function createResponsesToolCallTracker() {
1573
- const indexedCalls = /* @__PURE__ */ new Map();
1574
- const unindexedCalls = /* @__PURE__ */ new Set();
1575
- const identitiesConflict = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId !== identity.itemId || state.callId && identity.callId && state.callId !== identity.callId);
1576
- const sharesIdentity = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId === identity.itemId || state.callId && identity.callId && state.callId === identity.callId);
1577
- const adoptIdentity = (state, identity) => {
1578
- state.itemId ??= identity.itemId;
1579
- state.callId ??= identity.callId;
1580
- return state;
1581
- };
1582
- const resolveCompatible = (candidates, identity, allowUnmatchedIdentity) => {
1583
- const uniqueCandidates = [...new Set(candidates)];
1584
- if (!identity.itemId && !identity.callId) return allowUnmatchedIdentity && uniqueCandidates.length === 1 ? uniqueCandidates.at(0) : void 0;
1585
- const compatible = uniqueCandidates.filter((state) => !identitiesConflict(state, identity));
1586
- const matches = compatible.filter((state) => sharesIdentity(state, identity));
1587
- const matched = matches.length === 1 ? matches.at(0) : void 0;
1588
- if (matched) return adoptIdentity(matched, identity);
1589
- const soleCompatible = allowUnmatchedIdentity && uniqueCandidates.length === 1 && compatible.length === 1 && matches.length === 0 ? compatible.at(0) : void 0;
1590
- return soleCompatible ? adoptIdentity(soleCompatible, identity) : void 0;
1591
- };
1592
- return {
1593
- register(event, state) {
1594
- const outputIndex = readOutputIndex(event);
1595
- if (outputIndex === void 0) {
1596
- unindexedCalls.add(state);
1597
- return;
1598
- }
1599
- if (indexedCalls.has(outputIndex)) throw new Error(`Responses stream reused active tool-call output index ${outputIndex}`);
1600
- state.outputIndex = outputIndex;
1601
- indexedCalls.set(outputIndex, state);
1602
- },
1603
- resolve(event, identity = readEventIdentity(event), allowUnmatchedIdentity = true) {
1604
- const outputIndex = readOutputIndex(event);
1605
- if (outputIndex !== void 0) {
1606
- const indexed = indexedCalls.get(outputIndex);
1607
- if (indexed) {
1608
- if (indexed.callId && identity.callId && indexed.callId !== identity.callId) return;
1609
- return adoptIdentity(indexed, identity);
1610
- }
1611
- const unindexed = resolveCompatible(unindexedCalls, identity, allowUnmatchedIdentity);
1612
- if (unindexed) {
1613
- unindexedCalls.delete(unindexed);
1614
- unindexed.outputIndex = outputIndex;
1615
- indexedCalls.set(outputIndex, unindexed);
1616
- }
1617
- return unindexed;
1618
- }
1619
- return resolveCompatible([...indexedCalls.values(), ...unindexedCalls], identity, allowUnmatchedIdentity);
1620
- },
1621
- forget(toolCall) {
1622
- for (const [outputIndex, tracked] of indexedCalls) if (tracked === toolCall) indexedCalls.delete(outputIndex);
1623
- unindexedCalls.delete(toolCall);
1624
- },
1625
- markArgumentsUnreliable() {
1626
- for (const toolCall of /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls])) toolCall.argumentStreamReliable = false;
1627
- },
1628
- hasActive() {
1629
- return indexedCalls.size > 0 || unindexedCalls.size > 0;
1630
- },
1631
- hasExactlyActive(expected) {
1632
- const active = /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls]);
1633
- return active.size === expected.length && expected.every((state) => active.has(state));
1634
- }
1635
- };
1636
- }
1637
- //#endregion
1638
- //#region packages/ai/src/transports/openai-responses-stream-observer-internal.ts
1639
- const STRING_DELTA_EVENTS = /* @__PURE__ */ new Set([
1640
- "response.function_call_arguments.delta",
1641
- "response.output_text.delta",
1642
- "response.reasoning_summary_text.delta",
1643
- "response.reasoning_text.delta",
1644
- "response.refusal.delta",
1645
- "response.text.delta"
1646
- ]);
1647
- async function* adaptResponsesStream(stream, signal) {
1648
- for await (const event of iterateModelStream(stream, signal)) {
1649
- if (!isRecord(event) || typeof event.type !== "string") throw new Error("Responses stream delivered a malformed event without a string type");
1650
- if (STRING_DELTA_EVENTS.has(event.type) && typeof event.delta !== "string") throw new Error(`Responses stream delivered malformed ${event.type} delta`);
1651
- if ((event.type === "response.output_item.added" || event.type === "response.output_item.done") && !isRecord(event.item)) throw new Error(`Responses stream delivered malformed ${event.type} item`);
1652
- if ((event.type === "response.created" || event.type === "response.completed" || event.type === "response.incomplete" || event.type === "response.failed") && !isRecord(event.response)) throw new Error(`Responses stream delivered malformed ${event.type} response`);
1653
- yield event;
1654
- }
1655
- }
1656
- async function* observeResponsesStream(stream, model, requestStartedAt) {
1657
- const startedAt = Date.now();
1658
- const eventTypes = /* @__PURE__ */ new Map();
1659
- const debugMode = resolveModelSseDebugMode();
1660
- let eventCount = 0;
1661
- try {
1662
- for await (const event of stream) {
1663
- const type = isRecord(event) && typeof event.type === "string" ? event.type : "unknown";
1664
- eventCount += 1;
1665
- eventTypes.set(type, (eventTypes.get(type) ?? 0) + 1);
1666
- if (eventCount === 1) emitModelTransportDebug(log, `[responses] first_event provider=${model.provider} api=${model.api} model=${model.id} elapsedMs=${Date.now() - (requestStartedAt ?? startedAt)} headersToEventMs=${Date.now() - startedAt} type=${type}`);
1667
- if (debugMode === "peek" && eventCount <= 5) emitModelTransportDebug(log, `[responses] event_peek provider=${model.provider} api=${model.api} model=${model.id} index=${eventCount} type=${type} event=${stringifyRedactedEvent(event)}`);
1668
- yield event;
1669
- }
1670
- } finally {
1671
- const types = [...eventTypes].map(([type, count]) => `${type}:${count}`).join(",");
1672
- emitModelTransportDebug(log, `[responses] stream_done provider=${model.provider} api=${model.api} model=${model.id} elapsedMs=${Date.now() - startedAt} events=${eventCount} types=${types}`);
1673
- }
1674
- }
1675
- //#endregion
1676
1541
  //#region packages/ai/src/transports/openai-responses-stream-slots-internal.ts
1677
1542
  function createResponsesOutputTracker(params) {
1678
1543
  const outputs = /* @__PURE__ */ new Map();
@@ -1794,6 +1659,121 @@ function createResponsesOutputSlotTracker() {
1794
1659
  };
1795
1660
  }
1796
1661
  //#endregion
1662
+ //#region packages/ai/src/providers/openai-responses-tool-call-tracker.ts
1663
+ function readEventIdentity(event) {
1664
+ return { itemId: normalizeOptionalString(event.item_id) };
1665
+ }
1666
+ function readResponsesToolCallItemIdentity(item) {
1667
+ return {
1668
+ itemId: normalizeOptionalString(item.id),
1669
+ callId: normalizeOptionalString(item.call_id)
1670
+ };
1671
+ }
1672
+ function createResponsesToolCallTracker() {
1673
+ const indexedCalls = /* @__PURE__ */ new Map();
1674
+ const unindexedCalls = /* @__PURE__ */ new Set();
1675
+ const identitiesConflict = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId !== identity.itemId || state.callId && identity.callId && state.callId !== identity.callId);
1676
+ const sharesIdentity = (state, identity) => Boolean(state.itemId && identity.itemId && state.itemId === identity.itemId || state.callId && identity.callId && state.callId === identity.callId);
1677
+ const adoptIdentity = (state, identity) => {
1678
+ state.itemId ??= identity.itemId;
1679
+ state.callId ??= identity.callId;
1680
+ return state;
1681
+ };
1682
+ const resolveCompatible = (candidates, identity, allowUnmatchedIdentity) => {
1683
+ const uniqueCandidates = [...new Set(candidates)];
1684
+ if (!identity.itemId && !identity.callId) return allowUnmatchedIdentity && uniqueCandidates.length === 1 ? uniqueCandidates.at(0) : void 0;
1685
+ const compatible = uniqueCandidates.filter((state) => !identitiesConflict(state, identity));
1686
+ const matches = compatible.filter((state) => sharesIdentity(state, identity));
1687
+ const matched = matches.length === 1 ? matches.at(0) : allowUnmatchedIdentity && uniqueCandidates.length === 1 ? compatible.at(0) : void 0;
1688
+ return matched ? adoptIdentity(matched, identity) : void 0;
1689
+ };
1690
+ return {
1691
+ register(event, state) {
1692
+ const outputIndex = readResponsesOutputIndex(event);
1693
+ if (outputIndex === void 0) {
1694
+ unindexedCalls.add(state);
1695
+ return;
1696
+ }
1697
+ if (indexedCalls.has(outputIndex)) throw new Error(`Responses stream reused active tool-call output index ${outputIndex}`);
1698
+ state.outputIndex = outputIndex;
1699
+ indexedCalls.set(outputIndex, state);
1700
+ },
1701
+ resolve(event, identity = readEventIdentity(event), allowUnmatchedIdentity = true) {
1702
+ const outputIndex = readResponsesOutputIndex(event);
1703
+ if (outputIndex !== void 0) {
1704
+ const indexed = indexedCalls.get(outputIndex);
1705
+ if (indexed) {
1706
+ if (indexed.callId && identity.callId && indexed.callId !== identity.callId) return;
1707
+ return adoptIdentity(indexed, identity);
1708
+ }
1709
+ const unindexed = resolveCompatible(unindexedCalls, identity, allowUnmatchedIdentity);
1710
+ if (unindexed) {
1711
+ unindexedCalls.delete(unindexed);
1712
+ unindexed.outputIndex = outputIndex;
1713
+ indexedCalls.set(outputIndex, unindexed);
1714
+ }
1715
+ return unindexed;
1716
+ }
1717
+ return resolveCompatible([...indexedCalls.values(), ...unindexedCalls], identity, allowUnmatchedIdentity);
1718
+ },
1719
+ forget(toolCall) {
1720
+ for (const [outputIndex, tracked] of indexedCalls) if (tracked === toolCall) indexedCalls.delete(outputIndex);
1721
+ unindexedCalls.delete(toolCall);
1722
+ },
1723
+ markArgumentsUnreliable() {
1724
+ for (const toolCall of /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls])) toolCall.argumentStreamReliable = false;
1725
+ },
1726
+ hasActive() {
1727
+ return indexedCalls.size > 0 || unindexedCalls.size > 0;
1728
+ },
1729
+ values() {
1730
+ return [.../* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls])];
1731
+ },
1732
+ hasExactlyActive(expected) {
1733
+ const active = /* @__PURE__ */ new Set([...indexedCalls.values(), ...unindexedCalls]);
1734
+ return active.size === expected.length && expected.every((state) => active.has(state));
1735
+ }
1736
+ };
1737
+ }
1738
+ //#endregion
1739
+ //#region packages/ai/src/transports/openai-responses-stream-observer-internal.ts
1740
+ const STRING_DELTA_EVENTS = /* @__PURE__ */ new Set([
1741
+ "response.function_call_arguments.delta",
1742
+ "response.output_text.delta",
1743
+ "response.reasoning_summary_text.delta",
1744
+ "response.reasoning_text.delta",
1745
+ "response.refusal.delta",
1746
+ "response.text.delta"
1747
+ ]);
1748
+ async function* adaptResponsesStream(stream, signal) {
1749
+ for await (const event of iterateModelStream(stream, signal)) {
1750
+ if (!isRecord(event) || typeof event.type !== "string") throw new Error("Responses stream delivered a malformed event without a string type");
1751
+ if (STRING_DELTA_EVENTS.has(event.type) && typeof event.delta !== "string") throw new Error(`Responses stream delivered malformed ${event.type} delta`);
1752
+ if ((event.type === "response.output_item.added" || event.type === "response.output_item.done") && !isRecord(event.item)) throw new Error(`Responses stream delivered malformed ${event.type} item`);
1753
+ if ((event.type === "response.created" || event.type === "response.completed" || event.type === "response.incomplete" || event.type === "response.failed") && !isRecord(event.response)) throw new Error(`Responses stream delivered malformed ${event.type} response`);
1754
+ yield event;
1755
+ }
1756
+ }
1757
+ async function* observeResponsesStream(stream, model, requestStartedAt) {
1758
+ const startedAt = Date.now();
1759
+ const eventTypes = /* @__PURE__ */ new Map();
1760
+ const debugMode = resolveModelSseDebugMode();
1761
+ let eventCount = 0;
1762
+ try {
1763
+ for await (const event of stream) {
1764
+ const type = isRecord(event) && typeof event.type === "string" ? event.type : "unknown";
1765
+ eventCount += 1;
1766
+ eventTypes.set(type, (eventTypes.get(type) ?? 0) + 1);
1767
+ if (eventCount === 1) emitModelTransportDebug(log, `[responses] first_event provider=${model.provider} api=${model.api} model=${model.id} elapsedMs=${Date.now() - (requestStartedAt ?? startedAt)} headersToEventMs=${Date.now() - startedAt} type=${type}`);
1768
+ if (debugMode === "peek" && eventCount <= 5) emitModelTransportDebug(log, `[responses] event_peek provider=${model.provider} api=${model.api} model=${model.id} index=${eventCount} type=${type} event=${stringifyRedactedEvent(event)}`);
1769
+ yield event;
1770
+ }
1771
+ } finally {
1772
+ const types = [...eventTypes].map(([type, count]) => `${type}:${count}`).join(",");
1773
+ emitModelTransportDebug(log, `[responses] stream_done provider=${model.provider} api=${model.api} model=${model.id} elapsedMs=${Date.now() - startedAt} events=${eventCount} types=${types}`);
1774
+ }
1775
+ }
1776
+ //#endregion
1797
1777
  //#region packages/ai/src/transports/openai-responses-stream-terminal-internal.ts
1798
1778
  function splitToolCallId(id) {
1799
1779
  const separator = id.indexOf("|");
@@ -1824,6 +1804,10 @@ function resolveCompletedResponsesToolCall(item, streamed) {
1824
1804
  function createResponsesTerminalController(params) {
1825
1805
  const { output, stream, model, options } = params;
1826
1806
  const blocks = output.content;
1807
+ let rejectedToolCallId;
1808
+ const recordIncompleteToolCall = (event, item) => {
1809
+ rejectedToolCallId = params.toolCalls.resolve(event, readResponsesToolCallItemIdentity(item))?.block.id ?? (item.call_id ? resolveResponsesToolCallId(item) : void 0);
1810
+ };
1827
1811
  const backfillReasoning = (items) => {
1828
1812
  for (const [outputIndex, item] of items.entries()) {
1829
1813
  if (item.type !== "reasoning" || !item.encrypted_content) continue;
@@ -1986,6 +1970,7 @@ function createResponsesTerminalController(params) {
1986
1970
  }
1987
1971
  };
1988
1972
  const finalizeTerminalFacts = (response, responseId = response.id) => {
1973
+ options?.onServiceTier?.(response.service_tier);
1989
1974
  output.responseId = responseId || output.responseId;
1990
1975
  output.responseModel = options?.resolveResponseModel ? options.resolveResponseModel()?.trim() || void 0 : response.model?.trim() || void 0;
1991
1976
  const usage = mapResponsesTerminalUsage(response.usage);
@@ -2007,7 +1992,7 @@ function createResponsesTerminalController(params) {
2007
1992
  options.applyServiceTierPricing(output.usage, tier);
2008
1993
  }
2009
1994
  };
2010
- const finalizeResponse = (response, terminalEventType) => {
1995
+ const finalizeResponse = (response, terminalEventType, hasRejectedToolCall) => {
2011
1996
  backfillReasoning(response.output ?? []);
2012
1997
  finalizeTerminalFacts(response);
2013
1998
  const terminal = resolveResponsesTerminalStopReason({
@@ -2020,20 +2005,25 @@ function createResponsesTerminalController(params) {
2020
2005
  output.errorMessage = terminal.errorMessage;
2021
2006
  if (terminalEventType === "response.completed" && typeof response.end_turn === "boolean") output.endTurn = response.end_turn;
2022
2007
  const incompleteReason = response.incomplete_details?.reason;
2008
+ const incompleteCall = response.output?.find((item) => item.type === "function_call" && item.status && item.status !== "completed");
2009
+ const incompleteToolCallId = rejectedToolCallId ?? (terminalEventType === "response.incomplete" && !hasRejectedToolCall ? params.toolCalls.values()[0]?.block.id : void 0) ?? (incompleteCall?.type === "function_call" && incompleteCall.call_id ? resolveResponsesToolCallId(incompleteCall) : void 0);
2023
2010
  appendAssistantMessageDiagnostic(output, {
2024
2011
  type: "openai_responses_terminal",
2025
2012
  timestamp: Date.now(),
2026
2013
  details: {
2027
2014
  eventType: terminalEventType,
2028
2015
  stopReason: terminal.stopReason,
2016
+ ...incompleteToolCallId ? { incompleteToolCallId } : {},
2029
2017
  ...terminalEventType === "response.incomplete" ? { incompleteReason: incompleteReason === "max_output_tokens" || incompleteReason === "max_messages" || incompleteReason === "content_filter" || incompleteReason === "steered" ? incompleteReason : "unknown" } : {},
2030
2018
  endTurn: typeof response.end_turn === "boolean" ? response.end_turn : response.end_turn === void 0 ? "absent" : "invalid"
2031
2019
  }
2032
2020
  });
2021
+ if (!hasRejectedToolCall && terminalEventType === "response.incomplete" && params.toolCalls.hasActive()) throw output.errorMessage ? new Error(output.errorMessage) : new IncompleteToolCallError("Responses stream completed with unresolved tool calls");
2033
2022
  };
2034
2023
  return {
2035
2024
  finalizeResponse,
2036
2025
  finalizeFailedResponse: finalizeTerminalFacts,
2026
+ recordIncompleteToolCall,
2037
2027
  recoverTerminalOutput,
2038
2028
  emitToolCallCompletion
2039
2029
  };
@@ -2160,6 +2150,7 @@ async function processResponsesStream(openaiStream, output, sink, model, options
2160
2150
  model,
2161
2151
  options,
2162
2152
  outputs,
2153
+ toolCalls: streamingToolCalls,
2163
2154
  getLastTextBlock: () => lastTextBlock,
2164
2155
  setLastTextBlock: (block) => {
2165
2156
  lastTextBlock = block;
@@ -2226,6 +2217,7 @@ async function processResponsesStream(openaiStream, output, sink, model, options
2226
2217
  if (event.type === "response.output_item.done" && event.item.type === "function_call" && event.item.status && event.item.status !== "completed" && !rejectedToolCall) try {
2227
2218
  resolveCompletedResponsesToolCall(event.item);
2228
2219
  } catch (error) {
2220
+ terminal.recordIncompleteToolCall(event, event.item);
2229
2221
  rejectedToolCall = { error };
2230
2222
  }
2231
2223
  if (rejectedToolCall && event.type !== "response.completed" && event.type !== "response.incomplete" && event.type !== "response.failed" && event.type !== "error") continue;
@@ -2289,48 +2281,35 @@ async function processResponsesStream(openaiStream, output, sink, model, options
2289
2281
  if (!slot) continue;
2290
2282
  slot.item.content = slot.item.content || [];
2291
2283
  if (event.part.type === "output_text" || event.part.type === "text" || event.part.type === "refusal") slot.item.content.push(event.part);
2292
- } else if (event.type === "response.output_text.delta") {
2284
+ } else if (event.type === "response.output_text.delta" || isAzureResponsesTextDeltaEvent(event) || event.type === "response.refusal.delta") {
2293
2285
  const slot = outputSlots.resolve(event, "text");
2294
2286
  if (!slot) continue;
2295
2287
  slot.item.content ||= [];
2296
2288
  let lastPart = slot.item.content[slot.item.content.length - 1];
2297
- if (!isResponsesTextContentPartType(lastPart?.type)) {
2298
- lastPart = {
2299
- type: "output_text",
2300
- text: "",
2301
- annotations: []
2302
- };
2303
- slot.item.content.push(lastPart);
2304
- }
2305
- lastPart.text += event.delta;
2306
- projectTextDelta(slot, event.delta);
2307
- } else if (isAzureResponsesTextDeltaEvent(event)) {
2308
- const slot = outputSlots.resolve(event, "text");
2309
- if (!slot) continue;
2310
- slot.item.content = slot.item.content || [];
2311
- let lastPart = slot.item.content[slot.item.content.length - 1];
2312
- if (lastPart?.type !== "text") {
2313
- lastPart = {
2314
- type: "text",
2315
- text: ""
2316
- };
2317
- slot.item.content.push(lastPart);
2318
- }
2319
- lastPart.text += event.delta;
2320
- projectTextDelta(slot, event.delta);
2321
- } else if (event.type === "response.refusal.delta") {
2322
- const slot = outputSlots.resolve(event, "text");
2323
- if (!slot) continue;
2324
- slot.item.content ||= [];
2325
- let lastPart = slot.item.content[slot.item.content.length - 1];
2326
- if (lastPart?.type !== "refusal") {
2327
- lastPart = {
2328
- type: "refusal",
2329
- refusal: ""
2330
- };
2331
- slot.item.content.push(lastPart);
2289
+ if (event.type === "response.refusal.delta") {
2290
+ if (lastPart?.type !== "refusal") {
2291
+ lastPart = {
2292
+ type: "refusal",
2293
+ refusal: ""
2294
+ };
2295
+ slot.item.content.push(lastPart);
2296
+ }
2297
+ lastPart.refusal += event.delta;
2298
+ } else {
2299
+ const azure = isAzureResponsesTextDeltaEvent(event);
2300
+ if (!isResponsesTextContentPartType(lastPart?.type) || azure && lastPart.type !== "text") {
2301
+ lastPart = azure ? {
2302
+ type: "text",
2303
+ text: ""
2304
+ } : {
2305
+ type: "output_text",
2306
+ text: "",
2307
+ annotations: []
2308
+ };
2309
+ slot.item.content.push(lastPart);
2310
+ }
2311
+ lastPart.text += event.delta;
2332
2312
  }
2333
- lastPart.refusal += event.delta;
2334
2313
  projectTextDelta(slot, event.delta);
2335
2314
  } else if (event.type === "response.function_call_arguments.delta") {
2336
2315
  const toolCall = streamingToolCalls.resolve(event);
@@ -2465,9 +2444,8 @@ async function processResponsesStream(openaiStream, output, sink, model, options
2465
2444
  finalizeToolCall(item, readResponsesOutputIndex(event), streamingToolCall, validated);
2466
2445
  }
2467
2446
  } else if (event.type === "response.completed" || event.type === "response.incomplete") {
2468
- terminal.finalizeResponse(event.response, event.type);
2447
+ terminal.finalizeResponse(event.response, event.type, Boolean(rejectedToolCall));
2469
2448
  if (rejectedToolCall) throw output.errorMessage ? new Error(output.errorMessage) : rejectedToolCall.error;
2470
- if (event.type === "response.incomplete" && streamingToolCalls.hasActive()) throw output.errorMessage ? new Error(output.errorMessage) : new IncompleteToolCallError("Responses stream completed with unresolved tool calls");
2471
2449
  if (event.type === "response.completed" || output.stopReason === "length") {
2472
2450
  const items = event.response.output ?? [];
2473
2451
  const completeToolCall = event.type === "response.completed" ? prepareTerminalToolCalls(items) : void 0;
@@ -2567,6 +2545,10 @@ function applyResponsesServiceTierPricing(usage, serviceTier, model) {
2567
2545
  function applyCommonResponsesParams(params, model, context, options, config) {
2568
2546
  if (options?.maxTokens) params.max_output_tokens = Math.max(options.maxTokens, 16);
2569
2547
  if (options?.temperature !== void 0 && supportsOpenAITemperature(model)) params.temperature = options.temperature;
2548
+ if (options?.responseFormat !== void 0) params.text = {
2549
+ ...params.text,
2550
+ format: resolveOpenAIResponsesTextFormat(options.responseFormat)
2551
+ };
2570
2552
  if (context.tools) {
2571
2553
  const tools = convertResponsesToolPayload(context.tools, { model });
2572
2554
  if (tools.length > 0) params.tools = tools;
@@ -2605,6 +2587,7 @@ async function runResponsesStreamLifecycle(params) {
2605
2587
  firstEventAbort = firstEvent;
2606
2588
  let started = false;
2607
2589
  let admittedRequest;
2590
+ let requestedTier;
2608
2591
  const { stream: hookedOpenAIStream } = await createResponsesStreamWithEncryptedContentRetry({
2609
2592
  client,
2610
2593
  request: requestParams,
@@ -2619,6 +2602,7 @@ async function runResponsesStreamLifecycle(params) {
2619
2602
  onCompactionRejected: (checkpoint) => suppressOpenAIResponsesCompaction(output, model, options, checkpoint),
2620
2603
  canRetryStream: () => output.content.length === 0,
2621
2604
  wrapStream: ({ stream: openaiStream, response, attempt }) => {
2605
+ requestedTier = attempt.request.service_tier;
2622
2606
  admittedRequest = attempt.kind === "initial" ? attempt.request : void 0;
2623
2607
  return withProviderResponseHook({
2624
2608
  stream: openaiStream,
@@ -2647,6 +2631,7 @@ async function runResponsesStreamLifecycle(params) {
2647
2631
  onFirstEventTimeout: params.processStreamOptions?.onFirstEventTimeout ?? onFirstEventTimeout,
2648
2632
  signal: params.processStreamOptions?.signal ?? options?.signal
2649
2633
  } : void 0,
2634
+ onServiceTier: (responseTier) => responsesServiceTierObserver.observe(options, requestedTier, responseTier),
2650
2635
  canRetryIdentityConflict: () => hasOnlyResponsesFunctionTools(admittedRequest),
2651
2636
  reasoningReplayMetadata: buildOpenAIResponsesReasoningReplayMetadata(model, {
2652
2637
  sessionId: options?.sessionId,
@@ -2686,4 +2671,4 @@ async function runResponsesStreamLifecycle(params) {
2686
2671
  }
2687
2672
  }
2688
2673
  //#endregion
2689
- export { OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE as $, recordResponsesContextUsage as A, resolveResponsesContinuationRequest as B, resolveAzureOpenAIApiVersion as C, safeDebugValue as D, logResponsesFailedNoDetails as E, convertResponsesMessages as F, supportsResponsesReasoningUpdate as G, responsesContinuationRequestFingerprint as H, recordResponsesInputReplay as I, captureOpenAIResponsesCompaction as J, CompactionReplayRefreshRequiredError as K, responsesInputFingerprint as L, bindResponsesInputMessage as M, buildResponsesInputMessage as N, summarizeOpenAITransportError as O, convertProviderResponsesMessages as P, OPENAI_RESPONSES_CALL_ID_RE as Q, claimOpenAIResponsesHttpContinuation as R, isInvalidEncryptedContentError as S, ResponsesStreamFailure as T, isConfigurationUpdate as U, responsesContinuationPrefixFingerprint as V, replayResponsesReasoningUpdates as W, resolveNewestOpenAIResponsesCompactionReplay as X, isOpenAIResponsesReplayContext as Y, suppressOpenAIResponsesCompaction as Z, isResponsesTextContentPartType as _, prepareResponsesTools as a, commitResponsesEncryptedContentAttempt as b, observeResponsesStream as c, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as d, OPENAI_RESPONSES_ID_MAX_LENGTH as et, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as f, isAzureResponsesTextDeltaEventType as g, isAzureResponsesTextDeltaEvent as h, convertResponsesToolPayload as i, resolveReplayableResponsesMessageId as it, resolveResponsesContextUsageBoundary as j, summarizeResponsesPayload as k, createResponsesToolCallTracker as l, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as m, applyResponsesServiceTierPricing as n, shouldNormalizeOpenAIResponsesToolCallId as nt, readOpenAIMisalignmentReview as o, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as p, buildOpenAIResponsesReasoningReplayMetadata as q, runResponsesStreamLifecycle as r, splitOpenAIFunctionCallPairing as rt, processResponsesStream as s, applyCommonResponsesParams as t, normalizeOpenAIResponsesFunctionCallId as tt, readResponsesToolCallItemIdentity as u, isResponsesTextDeltaEventType as v, resolveNextResponsesEncryptedContentAttempt as w, createResponsesStreamWithEncryptedContentRetry as x, resolveResponsesMessageSnapshotCollapse as y, recordResponsesContinuationState as z };
2674
+ export { OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE as $, recordResponsesContextUsage as A, recordResponsesContinuationState as B, resolveAzureOpenAIApiVersion as C, safeDebugValue as D, logResponsesFailedNoDetails as E, convertResponsesMessages as F, replayResponsesReasoningUpdates as G, responsesContinuationPrefixFingerprint as H, readResponsesInputReplayState as I, buildOpenAIResponsesReasoningReplayMetadata as J, supportsResponsesReasoningUpdate as K, recordResponsesInputReplay as L, bindResponsesInputMessage as M, buildResponsesInputMessage as N, summarizeOpenAITransportError as O, convertProviderResponsesMessages as P, OPENAI_RESPONSES_CALL_ID_RE as Q, responsesInputFingerprint as R, isInvalidEncryptedContentError as S, ResponsesStreamFailure as T, responsesContinuationRequestFingerprint as U, resolveResponsesContinuationRequest as V, isConfigurationUpdate as W, resolveNewestOpenAIResponsesCompactionReplay as X, captureOpenAIResponsesCompaction as Y, suppressOpenAIResponsesCompaction as Z, isResponsesTextContentPartType as _, prepareResponsesTools as a, commitResponsesEncryptedContentAttempt as b, observeResponsesStream as c, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as d, OPENAI_RESPONSES_ID_MAX_LENGTH as et, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as f, isAzureResponsesTextDeltaEventType as g, isAzureResponsesTextDeltaEvent as h, convertResponsesToolPayload as i, resolveReplayableResponsesMessageId as it, resolveResponsesContextUsageBoundary as j, summarizeResponsesPayload as k, createResponsesToolCallTracker as l, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as m, applyResponsesServiceTierPricing as n, shouldNormalizeOpenAIResponsesToolCallId as nt, readOpenAIMisalignmentReview as o, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as p, CompactionReplayRefreshRequiredError as q, runResponsesStreamLifecycle as r, splitOpenAIFunctionCallPairing as rt, processResponsesStream as s, applyCommonResponsesParams as t, normalizeOpenAIResponsesFunctionCallId as tt, readResponsesToolCallItemIdentity as u, isResponsesTextDeltaEventType as v, resolveNextResponsesEncryptedContentAttempt as w, createResponsesStreamWithEncryptedContentRetry as x, resolveResponsesMessageSnapshotCollapse as y, claimOpenAIResponsesHttpContinuation as z };