@openclaw/ai 2026.10.1 → 2026.10.5-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 (106) hide show
  1. package/README.md +6 -0
  2. package/dist/{anthropic-BDfXKgF1.mjs → anthropic-BAHKgWam.mjs} +30 -59
  3. package/dist/{anthropic-payload-policy-BZUAchqb.d.mts → anthropic-payload-policy-DGblkHL5.d.mts} +19 -16
  4. package/dist/{anthropic-stream-reducer-DHt9uFWX.mjs → anthropic-stream-reducer-g6w1YVii.mjs} +195 -283
  5. package/dist/{api-registry-DcEP_o4h.d.mts → api-registry-BhXXYdRA.d.mts} +2 -2
  6. package/dist/assistant-message-events-CHMJgbhs.mjs +18 -0
  7. package/dist/{assistant-output-mJ9cL4Qg.mjs → assistant-output-CUEeSotf.mjs} +2 -2
  8. package/dist/{assistant-text-phase-DAv1BdTm.mjs → assistant-text-phase-BrV8KdFO.mjs} +7 -6
  9. package/dist/{azure-openai-responses-gn9hMf8x.mjs → azure-openai-responses-C7qBuR23.mjs} +8 -9
  10. package/dist/{credential-redaction-BKv49aiv.d.mts → credential-redaction-BHxruEH6.d.mts} +3 -1
  11. package/dist/{diagnostics-Caj-4RBA.mjs → diagnostics-tQasYct1.mjs} +10 -3
  12. package/dist/diagnostics.d.mts +7 -7
  13. package/dist/diagnostics.mjs +3 -3
  14. package/dist/{env-api-keys-CyX4VKGO.mjs → env-api-keys-CrxwdylR.mjs} +24 -35
  15. package/dist/event-stream-6UNs-AhN.d.mts +1 -0
  16. package/dist/{event-stream-DrRM_90c.d.mts → event-stream-BcqWLo_u.d.mts} +1 -1
  17. package/dist/{event-stream-C5AbCAaZ.mjs → event-stream-X2gmsUWv.mjs} +5 -8
  18. package/dist/event-stream.d.mts +2 -2
  19. package/dist/event-stream.mjs +1 -1
  20. package/dist/google-Boz2QcpK.mjs +20 -0
  21. package/dist/{google-interactions-DXu4IYGb.mjs → google-interactions-tjAb1mc5.mjs} +52 -84
  22. package/dist/{google-messages-Bmheetdg.mjs → google-messages-C-RZzloH.mjs} +25 -35
  23. package/dist/google-provider-stream-CMImyxbX.mjs +58 -0
  24. package/dist/{google-shared-DE_ddfsC.mjs → google-shared-OyAtMTZv.mjs} +6 -15
  25. package/dist/google-vertex-hCxTJea7.mjs +40 -0
  26. package/dist/{host-BjIYEjwT.d.mts → host-CTDz7LXD.d.mts} +6 -3
  27. package/dist/{host-JpNulOOs.mjs → host-JWXZWa-c.mjs} +3 -2
  28. package/dist/{host-policy-CC5H0iRZ.mjs → host-policy-q4Azym9F.mjs} +1 -1
  29. package/dist/{index-DJrNQnKw.d.mts → index-BYDvopUB.d.mts} +8 -5
  30. package/dist/index.d.mts +7 -7
  31. package/dist/index.mjs +7 -6
  32. package/dist/internal/anthropic.d.mts +5 -5
  33. package/dist/internal/anthropic.mjs +4 -4
  34. package/dist/internal/openai-completions-compat.d.mts +1 -1
  35. package/dist/internal/openai-completions-compat.mjs +1 -1
  36. package/dist/internal/openai-responses-payload-policy.d.mts +8 -1
  37. package/dist/internal/openai-responses-payload-policy.mjs +3 -3
  38. package/dist/internal/openai.d.mts +9 -9
  39. package/dist/internal/openai.mjs +9 -11
  40. package/dist/internal/runtime.d.mts +31 -13
  41. package/dist/internal/runtime.mjs +10 -13
  42. package/dist/internal/shared.d.mts +5 -5
  43. package/dist/internal/shared.mjs +6 -7
  44. package/dist/internal/tool-schema.mjs +2 -2
  45. package/dist/{llm-request-activity-D8f_oxHj.mjs → llm-request-activity-CfMuh5cC.mjs} +2 -2
  46. package/dist/{mistral-1Bnbneg1.mjs → mistral-DUveP4hF.mjs} +71 -146
  47. package/dist/{model-transport-url-C5f59L3Y.d.mts → model-transport-url-BrsjjdjR.d.mts} +5 -1
  48. package/dist/{number-coercion-V8-BhME4.mjs → number-coercion-C3hztWoY.mjs} +5 -4
  49. package/dist/{openai-chatgpt-responses-CB1JwNFF.mjs → openai-chatgpt-responses-OCwckGhY.mjs} +164 -234
  50. package/dist/{openai-completions-BPadHHKe.mjs → openai-completions-DOltBUe9.mjs} +7 -6
  51. package/dist/{openai-completions-compat-CJ0ktmGy.d.mts → openai-completions-compat-i-nLZxFy.d.mts} +10 -11
  52. package/dist/{openai-completions-compat-D7hWYB0G.mjs → openai-completions-compat-pg1q4uNG.mjs} +10 -6
  53. package/dist/{openai-completions-transport-DITBEALX.mjs → openai-completions-transport-OMrn7gnZ.mjs} +1429 -294
  54. package/dist/{openai-prompt-cache-Dj8qeOHT.mjs → openai-prompt-cache-Cr2xKVrS.mjs} +1 -1
  55. package/dist/{openai-prompt-cache-C-Q1Ksfs.d.mts → openai-prompt-cache-DIPMrMFy.d.mts} +2 -2
  56. package/dist/{openai-responses-1_TvcWI3.mjs → openai-responses-BSBJUA19.mjs} +9 -10
  57. package/dist/{openai-responses-compaction-replay-BB2SWdsx.d.mts → openai-responses-compaction-replay-B2FE4Nw8.d.mts} +4 -4
  58. package/dist/{openai-responses-contracts-sAvdqNjS.d.mts → openai-responses-contracts-DKqMJ1Ct.d.mts} +9 -4
  59. package/dist/{openai-responses-contracts-BKu8O7l4.mjs → openai-responses-contracts-DlKMMTxK.mjs} +26 -6
  60. package/dist/{openai-responses-compaction-window-m878aVpU.mjs → openai-responses-endpoint-CinGh4VZ.mjs} +14 -4
  61. package/dist/{openai-responses-prompt-observer-internal-CbH84xIS.mjs → openai-responses-request-lifecycle-D2IFiI0-.mjs} +39 -4
  62. package/dist/{openai-responses-shared-TCJRAoMW.mjs → openai-responses-shared-DVGhq5xF.mjs} +1036 -327
  63. package/dist/{openai-responses-terminal-usage-BVvyXZ8u.d.mts → openai-responses-terminal-usage-BygjiAdi.d.mts} +2 -2
  64. package/dist/{openai-tool-schema-DYNePiF8.mjs → openai-tool-schema-DDPXsvJP.mjs} +236 -399
  65. package/dist/{positive-integer-CwLi8LUL.mjs → positive-integer-CqWjqSi9.mjs} +1 -1
  66. package/dist/{provider-error-DQBE1bUQ.mjs → provider-error-CF9GWCs2.mjs} +5 -3
  67. package/dist/{provider-options-Dk4PeQV3.d.mts → provider-options-CVrXZBtA.d.mts} +3 -2
  68. package/dist/{provider-transport-turn-state-8c_Nj2NS.mjs → provider-transport-turn-state-LuCaTsSO.mjs} +2 -2
  69. package/dist/{provider-types-De8PRdR0.d.mts → provider-types-CHtRx0dI.d.mts} +3 -3
  70. package/dist/provider-types.d.mts +6 -6
  71. package/dist/providers.d.mts +2 -2
  72. package/dist/providers.mjs +12 -12
  73. package/dist/{reasoning-tag-text-partitioner-Ju9VpUGl.mjs → reasoning-tag-text-partitioner-0-Rsezog.mjs} +13 -12
  74. package/dist/{required-api-key-D4kn3252.mjs → required-api-key-CFJvcFy_.mjs} +1 -1
  75. package/dist/{simple-options-wW3117Fu.mjs → simple-options-BARFAzk9.mjs} +9 -11
  76. package/dist/{src-DWJq14pn.mjs → src-C_wfIUmV.mjs} +19 -4
  77. package/dist/{stream-CElngO8h.mjs → stream-DwrETW0_.mjs} +12 -21
  78. package/dist/{stream-first-event-timeout-D9ZmL_s9.mjs → stream-first-event-timeout-Dc42hKv6.mjs} +8 -21
  79. package/dist/{streaming-byte-guard-CC-HMn_u.mjs → streaming-byte-guard-DBXr1XYn.mjs} +16 -1
  80. package/dist/{string-normalization-PN10hf6d.mjs → string-normalization-I3ux50s9.mjs} +1 -1
  81. package/dist/{text-signature-rOn31nxc.mjs → text-signature-B_MB6U_9.mjs} +32 -5
  82. package/dist/{tool-schema-json-projection-Ct8SeBeJ.mjs → tool-schema-json-projection-B8sG1I9v.mjs} +29 -23
  83. package/dist/{transport-stream-shared-CAxkgOSj.d.mts → transport-stream-shared-BmpzDtdQ.d.mts} +4 -4
  84. package/dist/{transport-stream-shared-C5TAc3U_.mjs → transport-stream-shared-DH08b7Il.mjs} +8 -16
  85. package/dist/transports.d.mts +33 -22
  86. package/dist/transports.mjs +73 -1234
  87. package/dist/{types-DvzmWW8J.d.mts → types-Bd2T86VJ.d.mts} +5 -23
  88. package/dist/types-Kdfw_04V.d.mts +1 -0
  89. package/dist/types.d.mts +6 -6
  90. package/dist/types.mjs +5 -4
  91. package/dist/{validation-B3lQt_VE.d.mts → validation-DdGB1yy3.d.mts} +1 -1
  92. package/dist/{validation-DbqlIfDn.mjs → validation-opC2pjk9.mjs} +2 -3
  93. package/dist/validation.d.mts +1 -1
  94. package/dist/validation.mjs +1 -1
  95. package/package.json +4 -9
  96. package/dist/env-api-keys-BR0MUYYD.d.mts +0 -17
  97. package/dist/event-stream-DqDQWqiy.d.mts +0 -1
  98. package/dist/google-CyMz2jF_.mjs +0 -54
  99. package/dist/google-vertex-BEW0OQIA.mjs +0 -88
  100. package/dist/internal/env-api-keys.d.mts +0 -2
  101. package/dist/internal/env-api-keys.mjs +0 -2
  102. package/dist/openai-responses-request-lifecycle-Fsag-IGZ.mjs +0 -36
  103. package/dist/openai-transport-params-ildrm49s.mjs +0 -735
  104. package/dist/openai-web-search-tools-Cfu0uLyN.mjs +0 -14
  105. package/dist/provider-replay-context-ywPKKLjL.mjs +0 -25
  106. package/dist/types-Dlz-8qcy.d.mts +0 -1
@@ -1,91 +1,751 @@
1
- import "./src-DWJq14pn.mjs";
1
+ import "./src-C_wfIUmV.mjs";
2
2
  import { _ as runtimeContextContentToText, f as hasRuntimeContextMarker, p as isRuntimeContextMessage } from "./types-CQc6JNG4.mjs";
3
3
  import { o as readProviderRefusalReview, t as appendAssistantMessageDiagnostic } from "./diagnostics-DzrF1h4J.mjs";
4
- import { r as appendAssistantThinking } from "./event-stream-C5AbCAaZ.mjs";
5
- import { o as isRecord } from "./record-coerce-CNDovvft.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-JpNulOOs.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";
4
+ import { r as appendAssistantThinking } from "./event-stream-X2gmsUWv.mjs";
5
+ import { o as isRecord, r as asOptionalObjectRecord } from "./record-coerce-CNDovvft.mjs";
6
+ import { a as normalizeOptionalString, c as readStringValue, n as normalizeLowercaseStringOrEmpty, o as normalizeStringifiedOptionalString } from "./string-coerce-CtgOVOSv.mjs";
7
+ import { t as asFiniteNumber } from "./number-coercion-C3hztWoY.mjs";
8
+ import { D as applyProviderReportedUsageCost, E as headersToRecord, N as isImageWithMediaPayload, O as calculateCost, a as resolveAiTransportHeaderSentinels, k as clampThinkingLevel, r as getAiTransportHost } from "./host-JWXZWa-c.mjs";
9
+ import { A as MODEL_CATALOG_THINKING_LEVELS, C as normalizeOpenAIReasoningEffort, E as resolveOpenAIReasoningEffortMapping, M as resolveOpenAIThinkingApi, O as supportsOpenAIReasoningEffort, T as resolveOpenAIReasoningEffortForModel, _ as isResponsesServiceTierRejection, 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, i as OPENAI_RESPONSES_APIS, k as supportsOpenAITemperature, o as OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY, p as isPreviousResponseRejection, s as OPENAI_RESPONSES_REASONING_REPLAY_META_KEY, v as nextResponsesServiceTier, w as resolveOpenAIModelReasoningEfforts } from "./openai-responses-contracts-DlKMMTxK.mjs";
9
10
  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-rOn31nxc.mjs";
13
- import { c as resolveOpenAIResponsesTextFormat, i as resolveOpenAICompletionsCompat } from "./openai-completions-compat-D7hWYB0G.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-C5TAc3U_.mjs";
15
- import { C as stripSystemPromptCacheBoundary, D as sortPromptCacheToolsByName, d as describeToolResultMediaPlaceholder, m as extractToolResultText, s as prepareModelRequestBody } from "./simple-options-wW3117Fu.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-ildrm49s.mjs";
17
- import { n as isProviderReplayContext, r as providerReplayContextMatches, t as buildProviderReplayContext } from "./provider-replay-context-ywPKKLjL.mjs";
18
- import { n as transformProviderMessages } from "./assistant-output-mJ9cL4Qg.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";
23
- import { randomUUID } from "node:crypto";
24
- //#region packages/ai/src/transports/openai-responses-replay.ts
25
- /** Resolves the assistant message id that can be replayed to OpenAI Responses. */
26
- function resolveReplayableResponsesMessageId(params) {
27
- if (!params.replayResponsesItemIds) return;
28
- if (!params.textSignatureId) return params.fallbackOrdinal === 0 ? params.fallbackId : `${params.fallbackId}_${params.fallbackOrdinal}`;
29
- return params.previousReplayItemWasReasoning ? params.textSignatureId : void 0;
11
+ import { c as stableStringify, s as truncateUtf16Safe } from "./provider-error-CF9GWCs2.mjs";
12
+ import { n as clampOpenAIPromptCacheKey } from "./openai-prompt-cache-Cr2xKVrS.mjs";
13
+ import { _ as resolveResponsesTerminalStopReason, a as resolveModelPayloadDebugMode, d as hasOnlyResponsesFunctionTools, f as isResponsesProviderTool, g as readResponsesReasoningTokens, h as mapResponsesTerminalUsage, o as resolveModelSseDebugMode, r as emitModelTransportDebug, u as ResponsesOutputIdentityError } from "./diagnostics-tQasYct1.mjs";
14
+ import { i as providerReplayContextMatches, l as redactSensitiveText, n as buildProviderReplayContext, r as isProviderReplayContext, s as isCodeModeModelVisibleToolName, t as encodeTextSignatureV1 } from "./text-signature-B_MB6U_9.mjs";
15
+ import { c as resolveOpenAIResponsesTextFormat, i as resolveOpenAICompletionsCompat, o as usesNativeOpenAICodexResponsesBackend } from "./openai-completions-compat-pg1q4uNG.mjs";
16
+ import { r as resolveModelRequestTimeoutMs } from "./host-policy-q4Azym9F.mjs";
17
+ import { A as shortHash, C as parseJsonObjectPreservingUnsafeIntegers, E as createToolArgumentPreviewSchedule, O as parseStreamingJson, S as withProviderResponseHook, b as transportAbortError, c as failTransportStream, d as iterateModelStream, g as parseTerminalToolCallArguments, m as notifyProviderHttpResponse, t as IncompleteToolCallError, u as finalizeTransportStream, v as sanitizeTransportPayloadText } from "./transport-stream-shared-DH08b7Il.mjs";
18
+ import { C as stripSystemPromptCacheBoundary, D as sortPromptCacheToolsByName, d as describeToolResultMediaPlaceholder, m as extractToolResultText, s as prepareModelRequestBody } from "./simple-options-BARFAzk9.mjs";
19
+ import { n as transformProviderMessages } from "./assistant-output-CUEeSotf.mjs";
20
+ import { n as projectRuntimeToolInputSchema, t as prepareRuntimeToolInputSchema } from "./tool-schema-json-projection-B8sG1I9v.mjs";
21
+ import { t as notifyLlmRequestActivity } from "./llm-request-activity-CfMuh5cC.mjs";
22
+ import { n as resolveOpencodeSessionHeaders } from "./session-affinity-DA4WHv1h.mjs";
23
+ import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-Dc42hKv6.mjs";
24
+ import { a as resolveOpenAIProjectedToolsStrictToolFlag, f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters, t as findOpenAIStrictToolProjectionDiagnostics } from "./openai-tool-schema-DDPXsvJP.mjs";
25
+ import { a as readOpenAIResponsesCompactionWindow, i as isOpenAIResponsesCompactionOutput, n as supportsNativeOpenAIResponsesEndpoint } from "./openai-responses-endpoint-CinGh4VZ.mjs";
26
+ import { hash, randomUUID } from "node:crypto";
27
+ //#region packages/normalization-core/src/node-crypto.ts
28
+ function sha256Hex(input) {
29
+ return hash("sha256", input, "hex");
30
+ }
31
+ function sha256HexPrefixCore(input, length) {
32
+ return sha256Hex(input).slice(0, length);
33
+ }
34
+ /** Redacts an identifier to a stable hash label, or "-" for missing values. */
35
+ function redactIdentifier(value, opts) {
36
+ const trimmed = normalizeOptionalString(value);
37
+ if (!trimmed) return "-";
38
+ const len = opts?.len ?? 12;
39
+ return `sha256:${sha256HexPrefixCore(trimmed, Number.isFinite(len) ? Math.max(1, Math.floor(len)) : 12)}`;
30
40
  }
31
41
  //#endregion
32
- //#region packages/ai/src/transports/openai-responses-tool-call-id-shape.ts
33
- /**
34
- * Pure OpenAI Responses `call_*`/`fc_*` tool-call-id shape helpers.
35
- *
36
- * Moved out of embedded-agent-helpers/openai.ts (the AgentMessage[]-walking
37
- * caller lives in src/agents and imports from packages/ai, so the reverse
38
- * import direction is not available) so the continuation transport can
39
- * recognize its own cached raw ids after this same reshaping and restore
40
- * them on a replayed wire request -- see openai-responses-continuation.ts.
41
- */
42
- const OPENAI_RESPONSES_ID_MAX_LENGTH = 64;
43
- const OPENAI_RESPONSES_CALL_ID_RE = /^call_[A-Za-z0-9_-]{1,59}$/;
44
- const OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE = /^fc_[A-Za-z0-9_-]{1,61}$/;
45
- function splitOpenAIFunctionCallPairing(id) {
46
- const separator = id.indexOf("|");
47
- if (separator <= 0 || separator >= id.length - 1) return { callId: id };
42
+ //#region packages/ai/src/transports/openai-transport-shared.ts
43
+ const OPENAI_RESPONSE_MODEL_HEADER_NAMES = /* @__PURE__ */ new Set(["openai-model", "x-openai-model"]);
44
+ const OPENAI_RESPONSE_MODEL_EVENT_TYPES = /* @__PURE__ */ new Set([
45
+ "response.created",
46
+ "response.in_progress",
47
+ "response.completed",
48
+ "response.done",
49
+ "response.incomplete",
50
+ "response.failed"
51
+ ]);
52
+ const OPENAI_DATED_MODEL_SUFFIX = /-(?:\d{8}|\d{4}-\d{2}-\d{2})$/;
53
+ const GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP = "skip_thought_signature_validator";
54
+ const log = {
55
+ debug(message, data) {
56
+ getAiTransportHost().logDebug("openai-transport", () => ({
57
+ message,
58
+ data
59
+ }));
60
+ },
61
+ info(message, data) {
62
+ getAiTransportHost().logInfo("openai-transport", message, data);
63
+ },
64
+ warn(message, data) {
65
+ getAiTransportHost().logWarn("openai-transport", message, data);
66
+ }
67
+ };
68
+ function splitOpenAIResponseModelHeader(value) {
69
+ return value ? value.split(",").map((part) => part.trim()).filter(Boolean) : [];
70
+ }
71
+ function readOpenAIResponseModelHeaders(headers) {
72
+ return [...OPENAI_RESPONSE_MODEL_HEADER_NAMES].flatMap((name) => splitOpenAIResponseModelHeader(headers.get(name)));
73
+ }
74
+ function readOpenAIResponseModelHeaderRecord(headers) {
75
+ if (!isRecord(headers)) return [];
76
+ return Object.entries(headers).filter(([name]) => OPENAI_RESPONSE_MODEL_HEADER_NAMES.has(name.toLowerCase())).flatMap(([, value]) => typeof value === "string" ? splitOpenAIResponseModelHeader(value) : []);
77
+ }
78
+ function readOpenAIResponseModelEvent(event) {
79
+ if (!isRecord(event)) return [];
80
+ const response = isRecord(event.response) ? event.response : void 0;
81
+ return [
82
+ ...OPENAI_RESPONSE_MODEL_EVENT_TYPES.has(String(event.type)) && typeof response?.model === "string" && response.model.trim() ? [response.model.trim()] : [],
83
+ ...readOpenAIResponseModelHeaderRecord(response?.headers),
84
+ ...readOpenAIResponseModelHeaderRecord(event.headers)
85
+ ];
86
+ }
87
+ function reconcileOpenAIResponseModels(current, observed) {
88
+ if (!current || current === observed) return observed;
89
+ const currentBase = current.replace(OPENAI_DATED_MODEL_SUFFIX, "");
90
+ const observedBase = observed.replace(OPENAI_DATED_MODEL_SUFFIX, "");
91
+ if (currentBase !== observedBase) return;
92
+ if (currentBase === current && observedBase !== observed) return observed;
93
+ if (observedBase === observed && currentBase !== current) return current;
94
+ }
95
+ function createResponseModelTracker(enabled = true) {
96
+ let responseModel;
97
+ const observe = (models) => {
98
+ for (const model of models) {
99
+ const reconciled = reconcileOpenAIResponseModels(responseModel, model);
100
+ if (!reconciled) throw new Error("Conflicting OpenAI response model attestations");
101
+ responseModel = reconciled;
102
+ }
103
+ };
104
+ const begin = (headers) => {
105
+ responseModel = void 0;
106
+ if (enabled && headers) observe(readOpenAIResponseModelHeaders(headers));
107
+ };
108
+ const observeEvent = (event) => {
109
+ if (enabled) observe(readOpenAIResponseModelEvent(event));
110
+ return responseModel;
111
+ };
112
+ const resolve = () => responseModel;
48
113
  return {
49
- callId: id.slice(0, separator),
50
- itemId: id.slice(separator + 1)
114
+ begin,
115
+ observeEvent,
116
+ resolve,
117
+ track(response, stream) {
118
+ if (!enabled) return stream;
119
+ return (async function* () {
120
+ begin(response?.headers);
121
+ for await (const event of stream) {
122
+ observeEvent(event);
123
+ yield event;
124
+ }
125
+ })();
126
+ },
127
+ terminalOptions: enabled ? { resolveResponseModel: resolve } : {}
51
128
  };
52
129
  }
53
- function shortOpenAIResponsesIdHash(id) {
54
- return sha256Hex(id).slice(0, 10);
130
+ function resolveOpenAIClientBaseUrl(model, baseUrl = model.baseUrl) {
131
+ if (baseUrl?.trim()) return baseUrl;
132
+ if (model.provider.trim().toLowerCase() === "openai") return;
133
+ throw new Error(`Provider "${model.provider}" requires an explicit base URL before using an OpenAI-compatible API. Reload provider metadata or configure an endpoint.`);
55
134
  }
56
- function sanitizeOpenAIResponsesIdTail(value) {
57
- return value.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "");
135
+ const EMPTY_OPENAI_COMPLETIONS_REASONING_BATCH = {
136
+ deltas: [],
137
+ mirroredThinking: [],
138
+ hasThinking: false,
139
+ hasVisibleText: false
140
+ };
141
+ const OPENAI_COMPLETIONS_REASONING_FIELDS = [
142
+ "reasoning_content",
143
+ "reasoning",
144
+ "reasoning_text"
145
+ ];
146
+ function appendOpenAICompletionsReasoningDelta(deltas, mirroredThinking, next) {
147
+ const previous = deltas[deltas.length - 1];
148
+ if (!previous || previous.kind !== next.kind || next.kind === "thinking" && previous.kind === "thinking" && previous.signature !== next.signature) {
149
+ deltas.push(next);
150
+ if (next.kind === "thinking") mirroredThinking.push(next.text);
151
+ return;
152
+ }
153
+ previous.text += next.text;
154
+ if (next.kind === "thinking") mirroredThinking[mirroredThinking.length - 1] += next.text;
155
+ }
156
+ function readOpenAICompletionsReasoningBatch(delta, visibleReasoningDetailTypes) {
157
+ let deltas;
158
+ const mirroredThinking = [];
159
+ const reasoningDetails = delta.reasoning_details;
160
+ if (Array.isArray(reasoningDetails)) for (const detail of reasoningDetails) {
161
+ if (!isRecord(detail)) continue;
162
+ if (typeof detail.text !== "string" || !detail.text) continue;
163
+ if (detail.type === "reasoning.text") {
164
+ deltas ??= [];
165
+ appendOpenAICompletionsReasoningDelta(deltas, mirroredThinking, {
166
+ kind: "thinking",
167
+ signature: "reasoning_details",
168
+ text: detail.text
169
+ });
170
+ continue;
171
+ }
172
+ if (typeof detail.type === "string" && visibleReasoningDetailTypes.has(detail.type)) {
173
+ deltas ??= [];
174
+ appendOpenAICompletionsReasoningDelta(deltas, mirroredThinking, {
175
+ kind: "text",
176
+ text: detail.text,
177
+ source: "reasoning_detail"
178
+ });
179
+ }
180
+ }
181
+ if (mirroredThinking.length === 0) for (const field of OPENAI_COMPLETIONS_REASONING_FIELDS) {
182
+ const value = delta[field];
183
+ if (typeof value === "string" && value.length > 0) {
184
+ deltas ??= [];
185
+ appendOpenAICompletionsReasoningDelta(deltas, mirroredThinking, {
186
+ kind: "thinking",
187
+ signature: field,
188
+ text: value
189
+ });
190
+ break;
191
+ }
192
+ }
193
+ if (!deltas) return EMPTY_OPENAI_COMPLETIONS_REASONING_BATCH;
194
+ return {
195
+ deltas,
196
+ mirroredThinking,
197
+ hasThinking: mirroredThinking.length > 0,
198
+ hasVisibleText: mirroredThinking.length < deltas.length
199
+ };
200
+ }
201
+ function parseOpenAICompletionsUsage(rawUsage, model, options) {
202
+ const cacheRead = rawUsage.prompt_tokens_details?.cached_tokens ?? rawUsage.prompt_cache_hit_tokens ?? 0;
203
+ const cacheWrite = rawUsage.prompt_tokens_details?.cache_write_tokens ?? rawUsage.prompt_tokens_details?.cache_creation_input_tokens ?? rawUsage.cache_creation_input_tokens ?? 0;
204
+ const input = Math.max(0, (rawUsage.prompt_tokens || 0) - cacheRead - cacheWrite);
205
+ const output = rawUsage.completion_tokens || 0;
206
+ const reasoningTokens = asFiniteNumber(rawUsage.completion_tokens_details?.reasoning_tokens);
207
+ const hasCoherentContext = [
208
+ rawUsage.prompt_tokens,
209
+ rawUsage.completion_tokens,
210
+ rawUsage.total_tokens,
211
+ cacheRead,
212
+ cacheWrite
213
+ ].every((value) => typeof value === "number" && Number.isFinite(value) && value >= 0) && rawUsage.prompt_tokens >= cacheRead + cacheWrite && rawUsage.total_tokens >= rawUsage.prompt_tokens + rawUsage.completion_tokens;
214
+ const usage = {
215
+ input,
216
+ output,
217
+ cacheRead,
218
+ cacheWrite,
219
+ ...options?.includeReasoningTokens !== false && reasoningTokens !== void 0 ? { reasoningTokens } : {},
220
+ contextUsage: hasCoherentContext ? {
221
+ state: "available",
222
+ promptTokens: rawUsage.prompt_tokens,
223
+ totalTokens: Math.max(input + output + cacheRead + cacheWrite, rawUsage.total_tokens)
224
+ } : { state: "unavailable" },
225
+ totalTokens: input + output + cacheRead + cacheWrite,
226
+ cost: {
227
+ input: 0,
228
+ output: 0,
229
+ cacheRead: 0,
230
+ cacheWrite: 0,
231
+ total: 0
232
+ }
233
+ };
234
+ calculateCost(model, usage);
235
+ applyProviderReportedUsageCost(usage, rawUsage.cost);
236
+ return usage;
58
237
  }
59
- function normalizeOpenAIResponsesIdPart(params) {
60
- const trimmed = params.value.trim();
61
- if (params.isValid(trimmed)) return trimmed;
62
- const rawTail = trimmed.startsWith(params.prefix) ? trimmed.slice(params.prefix.length) : trimmed;
63
- const hash = shortOpenAIResponsesIdHash(trimmed || params.prefix);
64
- const maxTailLength = 64 - params.prefix.length;
65
- const hashSuffix = `_${hash}`;
66
- const tail = `${sanitizeOpenAIResponsesIdTail(rawTail).slice(0, Math.max(1, maxTailLength - hashSuffix.length)) || "id"}${hashSuffix}`.slice(0, maxTailLength);
67
- return `${params.prefix}${tail}`;
238
+ function createOpenAIResponseHook(onResponse, response, model) {
239
+ return onResponse ? () => onResponse({
240
+ status: response.status,
241
+ headers: headersToRecord(response.headers)
242
+ }, model) : void 0;
68
243
  }
69
- /** Same shaping `normalizeOpenAIResponsesToolCallIds` applies to a replayed `call_id`/`call_id|fc_id` pair. */
70
- function normalizeOpenAIResponsesFunctionCallId(id) {
71
- const { callId, itemId } = splitOpenAIFunctionCallPairing(id);
72
- const normalizedCallId = normalizeOpenAIResponsesIdPart({
73
- value: itemId ? `${callId}|${itemId}` : callId,
74
- prefix: "call_",
75
- isValid: (value) => OPENAI_RESPONSES_CALL_ID_RE.test(value)
244
+ function createOpenAIProviderAcceptanceHook(options, response, model) {
245
+ return () => notifyProviderHttpResponse({
246
+ options,
247
+ response,
248
+ model
76
249
  });
77
- if (!itemId) return normalizedCallId;
78
- return `${normalizedCallId}|${normalizeOpenAIResponsesIdPart({
79
- value: itemId,
80
- prefix: "fc_",
81
- isValid: (value) => OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE.test(value)
82
- })}`;
83
250
  }
84
- function shouldNormalizeOpenAIResponsesToolCallId(id) {
85
- const pairing = splitOpenAIFunctionCallPairing(id);
86
- if (!OPENAI_RESPONSES_CALL_ID_RE.test(pairing.callId)) return true;
87
- if (pairing.itemId === void 0) return false;
88
- return !OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE.test(pairing.itemId);
251
+ /** Measure one UTF-8 append without double-counting a surrogate pair split across chunks. */
252
+ function measureUtf8AppendBytes(bufferEndsWithHighSurrogate, chunk) {
253
+ let bytes = Buffer.byteLength(chunk, "utf8");
254
+ if (!chunk) return {
255
+ bytes,
256
+ endsWithHighSurrogate: bufferEndsWithHighSurrogate
257
+ };
258
+ const nextCodeUnit = chunk.charCodeAt(0);
259
+ if (bufferEndsWithHighSurrogate && nextCodeUnit >= 56320 && nextCodeUnit <= 57343) bytes -= 2;
260
+ const finalCodeUnit = chunk.charCodeAt(chunk.length - 1);
261
+ return {
262
+ bytes,
263
+ endsWithHighSurrogate: finalCodeUnit >= 55296 && finalCodeUnit <= 56319
264
+ };
265
+ }
266
+ function resolvePromptCacheKey(options, cacheRetention) {
267
+ if (cacheRetention === "none") return;
268
+ return clampOpenAIPromptCacheKey(options?.promptCacheKey ?? options?.sessionId);
269
+ }
270
+ function isOpenAICompletionsThinkingEnabled(effort) {
271
+ const normalized = effort.trim().toLowerCase();
272
+ return normalized !== "off" && normalized !== "none";
273
+ }
274
+ function readOpenAICompletionsContentDeltas(content, topLevelRefusal, mirroredThinking = []) {
275
+ let deltas = readOpenAICompletionsContentPartDeltas(content);
276
+ if (mirroredThinking.length > 0) {
277
+ const structuredThinking = deltas.filter((delta) => delta.kind === "thinking").map((delta) => delta.text);
278
+ const mirrorsCombinedThinking = structuredThinking.length > 1 && mirroredThinking.includes(structuredThinking.join(""));
279
+ deltas = deltas.filter((delta) => delta.kind !== "thinking" || !mirrorsCombinedThinking && !mirroredThinking.includes(delta.text));
280
+ }
281
+ if (typeof topLevelRefusal !== "string" || !topLevelRefusal) return deltas;
282
+ const structuredRefusals = deltas.filter((delta) => delta.kind === "text" && delta.source === "refusal").map((delta) => delta.text);
283
+ if (structuredRefusals.some((refusal) => refusal === topLevelRefusal) || structuredRefusals.length > 1 && structuredRefusals.join("") === topLevelRefusal) return deltas;
284
+ return [...deltas, {
285
+ kind: "text",
286
+ text: topLevelRefusal,
287
+ source: "refusal"
288
+ }];
289
+ }
290
+ function readOpenAICompletionsContentPartDeltas(content) {
291
+ if (typeof content === "string") return content ? [{
292
+ kind: "text",
293
+ text: content
294
+ }] : [];
295
+ if (Array.isArray(content)) return content.flatMap(readOpenAICompletionsContentPartDeltas);
296
+ if (!content || typeof content !== "object") return [];
297
+ const record = content;
298
+ const type = typeof record.type === "string" ? record.type.toLowerCase() : "";
299
+ const extractText = (value) => {
300
+ if (typeof value === "string") return value;
301
+ if (Array.isArray(value)) return value.map(extractText).join("");
302
+ if (value && typeof value === "object") {
303
+ const nested = value;
304
+ return extractText(nested.text ?? nested.content ?? nested.thinking ?? nested.refusal);
305
+ }
306
+ return "";
307
+ };
308
+ const text = extractText(record.text ?? record.content ?? record.thinking ?? record.refusal);
309
+ if (!text) return [];
310
+ if (type.includes("thinking") || type.includes("reasoning")) return [{
311
+ kind: "thinking",
312
+ text
313
+ }];
314
+ if (type === "refusal") return [{
315
+ kind: "text",
316
+ text,
317
+ source: "refusal"
318
+ }];
319
+ if (["text", "output_text"].includes(type) || type.endsWith(".output_text")) return [{
320
+ kind: "text",
321
+ text
322
+ }];
323
+ return [];
324
+ }
325
+ //#endregion
326
+ //#region packages/ai/src/providers/openai-tool-projection.ts
327
+ function unreadableToolDiagnostic(toolIndex) {
328
+ return {
329
+ toolIndex,
330
+ violations: [`tool[${toolIndex}] is unreadable`]
331
+ };
332
+ }
333
+ /** Snapshots direct/custom tool descriptors before OpenAI payload construction. */
334
+ function projectOpenAITools(tools) {
335
+ return projectOpenAIToolDescriptors(tools);
336
+ }
337
+ /** Package-private facts are consumed before the projection or payload can escape. */
338
+ function prepareOpenAITools(tools) {
339
+ const schemas = /* @__PURE__ */ new Map();
340
+ return {
341
+ projection: projectOpenAIToolDescriptors(tools, schemas),
342
+ schemas
343
+ };
344
+ }
345
+ function projectOpenAIToolDescriptors(tools, schemas) {
346
+ let inputToolCount;
347
+ try {
348
+ inputToolCount = tools.length;
349
+ } catch {
350
+ return {
351
+ inputToolCount: 0,
352
+ tools: [],
353
+ diagnostics: [unreadableToolDiagnostic(0)]
354
+ };
355
+ }
356
+ const projectedTools = [];
357
+ const diagnostics = [];
358
+ for (let toolIndex = 0; toolIndex < inputToolCount; toolIndex += 1) {
359
+ let tool;
360
+ let name;
361
+ let parameters;
362
+ let readPath = `tool[${toolIndex}]`;
363
+ try {
364
+ const candidate = tools[toolIndex];
365
+ if (!candidate) {
366
+ diagnostics.push(unreadableToolDiagnostic(toolIndex));
367
+ continue;
368
+ }
369
+ tool = candidate;
370
+ readPath += ".name";
371
+ const nameValue = tool.name;
372
+ if (typeof nameValue !== "string" || !nameValue) {
373
+ diagnostics.push({
374
+ toolIndex,
375
+ violations: [`${readPath} is empty`]
376
+ });
377
+ continue;
378
+ }
379
+ name = nameValue;
380
+ readPath = `${name}.parameters`;
381
+ parameters = tool.parameters;
382
+ } catch {
383
+ diagnostics.push({
384
+ toolIndex,
385
+ ...name ? { toolName: name } : {},
386
+ violations: [`${readPath} is unreadable`]
387
+ });
388
+ continue;
389
+ }
390
+ const prepared = schemas ? prepareRuntimeToolInputSchema(parameters ?? {}, `${name}.parameters`) : void 0;
391
+ const schemaProjection = prepared?.projection ?? projectRuntimeToolInputSchema(parameters ?? {}, `${name}.parameters`);
392
+ if (!isRecord(schemaProjection.schema) || schemaProjection.violations.length > 0) {
393
+ diagnostics.push({
394
+ toolIndex,
395
+ toolName: name,
396
+ violations: schemaProjection.violations.length > 0 ? schemaProjection.violations : [`${name}.parameters must be a JSON object schema`]
397
+ });
398
+ continue;
399
+ }
400
+ if (prepared?.normalization) schemas?.set(schemaProjection.schema, prepared.normalization);
401
+ let descriptionValue;
402
+ try {
403
+ descriptionValue = tool.description;
404
+ } catch {}
405
+ const description = typeof descriptionValue === "string" ? descriptionValue : void 0;
406
+ projectedTools.push({
407
+ toolIndex,
408
+ name,
409
+ ...description !== void 0 ? { description } : {},
410
+ parameters: schemaProjection.schema
411
+ });
412
+ }
413
+ return {
414
+ inputToolCount,
415
+ tools: projectedTools,
416
+ diagnostics
417
+ };
418
+ }
419
+ function reconcileToolChoice(choice, projection, responses) {
420
+ const label = responses ? "OpenAI Responses" : "OpenAI Chat Completions";
421
+ if (choice === "auto") return projection.tools.length > 0 ? choice : void 0;
422
+ if (choice === "required") {
423
+ if (projection.tools.length === 0) throw new Error(`${label} tool_choice requires a tool, but no tools survived schema conversion`);
424
+ return choice;
425
+ }
426
+ if (choice === "none" || !isRecord(choice)) return choice;
427
+ const choiceType = choice.type;
428
+ if (!responses && choiceType === "custom") throw new Error("OpenAI Chat Completions custom tool_choice is unsupported because this adapter emits function tools only");
429
+ if (choiceType === "function") {
430
+ const functionChoice = responses ? choice : choice.function;
431
+ const functionName = isRecord(functionChoice) ? functionChoice.name : void 0;
432
+ if (typeof functionName !== "string") return choice;
433
+ if (!projection.tools.some((tool) => tool.name === functionName)) throw new Error(`${label} tool_choice requested unavailable tool "${functionName}" after schema conversion`);
434
+ return responses ? {
435
+ type: "function",
436
+ name: functionName
437
+ } : {
438
+ type: "function",
439
+ function: { name: functionName }
440
+ };
441
+ }
442
+ if (choiceType !== "allowed_tools") return choice;
443
+ const allowedConfig = responses ? choice : choice.allowed_tools;
444
+ if (!isRecord(allowedConfig)) return choice;
445
+ const { mode, tools } = allowedConfig;
446
+ if (mode !== "auto" && mode !== "required" || !Array.isArray(tools)) return choice;
447
+ const responseTools = [];
448
+ const completionTools = [];
449
+ for (const tool of tools) {
450
+ if (!isRecord(tool) || tool.type !== "function") {
451
+ if (responses) responseTools.push(tool);
452
+ continue;
453
+ }
454
+ const functionChoice = responses ? tool : tool.function;
455
+ const functionName = isRecord(functionChoice) ? functionChoice.name : void 0;
456
+ if (typeof functionName === "string" && projection.tools.some((projectedTool) => projectedTool.name === functionName)) {
457
+ if (responses) responseTools.push({
458
+ type: "function",
459
+ name: functionName
460
+ });
461
+ else completionTools.push({
462
+ type: "function",
463
+ function: { name: functionName }
464
+ });
465
+ }
466
+ }
467
+ if (responseTools.length === 0 && completionTools.length === 0) {
468
+ if (mode === "auto") return "none";
469
+ throw new Error(`${label} tool_choice requires a tool, but no allowed tools survived schema conversion`);
470
+ }
471
+ return responses ? {
472
+ type: "allowed_tools",
473
+ mode,
474
+ tools: responseTools
475
+ } : {
476
+ type: "allowed_tools",
477
+ allowed_tools: {
478
+ mode,
479
+ tools: completionTools
480
+ }
481
+ };
482
+ }
483
+ /** Keeps Responses tool choices aligned with surviving function schemas. */
484
+ function reconcileOpenAIResponsesToolChoice(choice, projection) {
485
+ return reconcileToolChoice(choice, projection, true);
486
+ }
487
+ /** Keeps Chat Completions tool choices aligned with surviving function schemas. */
488
+ function reconcileOpenAICompletionsToolChoice(choice, projection) {
489
+ return reconcileToolChoice(choice, projection, false);
490
+ }
491
+ /** Re-expresses an object Chat Completions tool choice in the Responses wire shape. */
492
+ function toOpenAIResponsesToolChoice(choice) {
493
+ if (choice.type === "function") return {
494
+ type: "function",
495
+ name: choice.function.name
496
+ };
497
+ return {
498
+ type: "allowed_tools",
499
+ mode: choice.allowed_tools.mode,
500
+ tools: choice.allowed_tools.tools.map((tool) => tool.type === "function" && isRecord(tool.function) && typeof tool.function.name === "string" ? {
501
+ type: "function",
502
+ name: tool.function.name
503
+ } : tool)
504
+ };
505
+ }
506
+ //#endregion
507
+ //#region packages/ai/src/transports/openai-reasoning-compat.ts
508
+ /** Explicit model reasoning-effort compatibility metadata. */
509
+ function readCompatReasoningEffortMap(compat) {
510
+ const rawMap = asOptionalObjectRecord(asOptionalObjectRecord(compat)?.reasoningEffortMap);
511
+ if (!rawMap) return {};
512
+ return Object.fromEntries(Object.entries(rawMap).filter((entry) => typeof entry[1] === "string"));
513
+ }
514
+ /** Resolves the reasoning effort remap for an OpenAI-compatible model. */
515
+ function resolveOpenAIReasoningEffortMap(model, fallbackMap = {}) {
516
+ return {
517
+ ...fallbackMap,
518
+ ...readCompatReasoningEffortMap(model.compat)
519
+ };
520
+ }
521
+ //#endregion
522
+ //#region packages/ai/src/providers/openai-request-reasoning.ts
523
+ /** Preserve explicit off until the selected route maps it to its native value. */
524
+ function resolveOpenAISimpleReasoningEffort(model, reasoning) {
525
+ return reasoning === void 0 ? void 0 : clampThinkingLevel(model, reasoning);
526
+ }
527
+ function resolveOpenAIRequestReasoning(model, reasoning, offDefault = "none") {
528
+ const requested = normalizeOpenAIReasoningEffort(reasoning ?? "off");
529
+ const modelLevel = MODEL_CATALOG_THINKING_LEVELS.find((candidate) => candidate === requested);
530
+ const modelMapped = modelLevel ? model.thinkingLevelMap?.[modelLevel] : void 0;
531
+ const mapped = modelMapped === null ? null : resolveOpenAIReasoningEffortMapping(requested, resolveOpenAIReasoningEffortMap(model)) ?? modelMapped;
532
+ const intent = mapped !== void 0 ? mapped?.trim() : reasoning === void 0 || requested === "off" && offDefault === null ? void 0 : requested;
533
+ const normalizedIntent = normalizeOpenAIReasoningEffort(intent ?? "off");
534
+ const supported = resolveOpenAIModelReasoningEfforts(model);
535
+ const effort = !model.reasoning || supported?.length === 0 || intent === void 0 ? void 0 : supported === void 0 ? mapped !== void 0 ? intent : requested === "off" ? "none" : requested : resolveOpenAIReasoningEffortForModel({
536
+ model,
537
+ effort: requested,
538
+ fallbackMap: { [requested]: intent }
539
+ });
540
+ return {
541
+ effort: effort === "none" && resolveOpenAIThinkingApi(model.api) === "openai-chatgpt-responses" && !supportsOpenAIReasoningEffort(model.id === "gpt-6-sol" || model.id === "gpt-6-luna" ? model : { compat: model.compat }, "none") ? void 0 : effort,
542
+ thinkingEnabled: intent === void 0 ? void 0 : model.reasoning && normalizedIntent !== "off" && normalizedIntent !== "none"
543
+ };
544
+ }
545
+ //#endregion
546
+ //#region packages/ai/src/transports/openai-transport-params.ts
547
+ const MAX_OPENAI_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS = 256;
548
+ const loggedOpenAIStrictToolDowngradeDiagnosticKeys = /* @__PURE__ */ new Set();
549
+ const OPENAI_COMPLETIONS_APIS = /* @__PURE__ */ new Set(["openai-completions", "openclaw-openai-completions-transport"]);
550
+ function readToolPayloadField$1(record, field) {
551
+ try {
552
+ return Object.hasOwn(record, field) ? record[field] : void 0;
553
+ } catch {
554
+ return;
555
+ }
556
+ }
557
+ function readCodeModePayloadToolName(tool) {
558
+ if (!isRecord(tool)) return;
559
+ const name = readToolPayloadField$1(tool, "name");
560
+ if (typeof name === "string") return name;
561
+ const fn = readToolPayloadField$1(tool, "function");
562
+ if (!isRecord(fn)) return;
563
+ const fnName = readToolPayloadField$1(fn, "name");
564
+ return typeof fnName === "string" ? fnName : void 0;
565
+ }
566
+ function readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes) {
567
+ if (!isRecord(tool)) return;
568
+ const type = readToolPayloadField$1(tool, "type");
569
+ if (typeof type === "string" && allowedHostedToolTypes?.has(type)) {
570
+ try {
571
+ if (Object.hasOwn(tool, "name") || Object.hasOwn(tool, "function") || Object.hasOwn(tool, "functionDeclarations") || Object.hasOwn(tool, "function_declarations")) return false;
572
+ } catch {
573
+ return false;
574
+ }
575
+ return `hosted:${type}`;
576
+ }
577
+ const name = readCodeModePayloadToolName(tool);
578
+ return typeof name === "string" && isCodeModeModelVisibleToolName(name, visibleToolNames) ? `client:${name}` : void 0;
579
+ }
580
+ function readCodeModePayloadToolIdentities(payload) {
581
+ if (!isRecord(payload)) return [];
582
+ const tools = readToolPayloadField$1(payload, "tools");
583
+ if (!Array.isArray(tools)) return [];
584
+ return tools.flatMap((tool) => {
585
+ if (!isRecord(tool)) return [];
586
+ const identities = [];
587
+ const name = readCodeModePayloadToolName(tool);
588
+ if (name) identities.push(`client:${name}`);
589
+ for (const key of ["functionDeclarations", "function_declarations"]) {
590
+ const declarations = readToolPayloadField$1(tool, key);
591
+ if (!Array.isArray(declarations)) continue;
592
+ for (const declaration of declarations) {
593
+ const declarationName = readCodeModePayloadToolName(declaration);
594
+ if (declarationName) identities.push(`client:${declarationName}`);
595
+ }
596
+ }
597
+ const type = readToolPayloadField$1(tool, "type");
598
+ if (typeof type === "string" && type !== "function") identities.push(`hosted:${type}`);
599
+ return identities;
600
+ });
601
+ }
602
+ function filterCodeModePayloadTools(payload, visibleToolNames, allowedHostedToolTypes, observer) {
603
+ if (!isRecord(payload)) return;
604
+ const tools = readToolPayloadField$1(payload, "tools");
605
+ if (!Array.isArray(tools)) return;
606
+ const beforeToolIdentities = observer ? readCodeModePayloadToolIdentities(payload) : void 0;
607
+ payload.tools = tools.flatMap((tool) => {
608
+ const identity = readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes);
609
+ if (identity) return [tool];
610
+ if (identity === false) return [];
611
+ if (!isRecord(tool)) return [];
612
+ const filteredGroups = {};
613
+ for (const key of ["functionDeclarations", "function_declarations"]) {
614
+ const declarations = readToolPayloadField$1(tool, key);
615
+ if (!Array.isArray(declarations)) continue;
616
+ const filtered = declarations.filter((declaration) => {
617
+ const declarationName = readCodeModePayloadToolName(declaration);
618
+ return typeof declarationName === "string" && isCodeModeModelVisibleToolName(declarationName, visibleToolNames);
619
+ });
620
+ if (filtered.length > 0) filteredGroups[key] = filtered;
621
+ }
622
+ return Object.keys(filteredGroups).length > 0 ? [filteredGroups] : [];
623
+ });
624
+ if (beforeToolIdentities) observer?.({
625
+ beforeToolIdentities,
626
+ afterToolIdentities: readCodeModePayloadToolIdentities(payload)
627
+ });
628
+ }
629
+ function resolveCodeModeResponsesVisibleToolNames(context) {
630
+ return new Set((context.tools ?? []).map(readCodeModePayloadToolName).filter((name) => typeof name === "string"));
631
+ }
632
+ function enforceCodeModeResponsesToolSurface(payload, visibleToolNames, allowedHostedToolTypes, observer) {
633
+ if (!isRecord(payload)) return;
634
+ const tools = readToolPayloadField$1(payload, "tools");
635
+ if (!Array.isArray(tools)) return;
636
+ const beforeToolIdentities = observer ? readCodeModePayloadToolIdentities(payload) : void 0;
637
+ payload.tools = tools.filter((tool) => Boolean(readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes)));
638
+ if (beforeToolIdentities) observer?.({
639
+ beforeToolIdentities,
640
+ afterToolIdentities: readCodeModePayloadToolIdentities(payload)
641
+ });
642
+ }
643
+ function assertCodeModeResponsesToolSurface(payload, visibleToolNames, allowedHostedToolTypes) {
644
+ const tools = isRecord(payload) ? readToolPayloadField$1(payload, "tools") : void 0;
645
+ if (!Array.isArray(tools)) throw new Error("Code mode payload tool surface violation: expected exec,wait; got no tools");
646
+ const identities = tools.map((tool) => readCodeModePayloadToolIdentity(tool, visibleToolNames, allowedHostedToolTypes));
647
+ const names = identities.flatMap((identity) => typeof identity === "string" && identity.startsWith("client:") ? [identity.slice(7)] : []).toSorted((left, right) => left.localeCompare(right));
648
+ if (names.length >= 2 && identities.every((identity) => typeof identity === "string") && new Set(identities).size === identities.length && names.includes("exec") && names.includes("wait")) return;
649
+ throw new Error(`Code mode payload tool surface violation: expected exec,wait plus direct-only tools; got ${names.length > 0 ? names.join(",") : "none"}`);
650
+ }
651
+ function resolveOpenAIStrictToolFlagWithDiagnostics(projection, strictSetting, context) {
652
+ const strict = resolveOpenAIProjectedToolsStrictToolFlag(projection, strictSetting);
653
+ if (strictSetting === true && strict === false) getAiTransportHost().logDebug("openai-transport", () => {
654
+ const diagnostics = findOpenAIStrictToolProjectionDiagnostics(projection);
655
+ const key = sha256Hex(JSON.stringify({
656
+ transport: context.transport,
657
+ provider: context.model.provider ?? null,
658
+ model: context.model.id ?? null,
659
+ diagnostics: diagnostics.map((entry) => ({
660
+ toolIndex: entry.toolIndex,
661
+ toolName: entry.toolName ?? null,
662
+ violations: entry.violations
663
+ }))
664
+ }));
665
+ if (loggedOpenAIStrictToolDowngradeDiagnosticKeys.has(key)) return null;
666
+ if (loggedOpenAIStrictToolDowngradeDiagnosticKeys.size >= MAX_OPENAI_STRICT_TOOL_DOWNGRADE_DIAGNOSTIC_KEYS) loggedOpenAIStrictToolDowngradeDiagnosticKeys.clear();
667
+ loggedOpenAIStrictToolDowngradeDiagnosticKeys.add(key);
668
+ const sample = diagnostics.slice(0, 5).map((entry) => ({
669
+ tool: entry.toolName ?? `tool[${entry.toolIndex}]`,
670
+ violations: entry.violations.slice(0, 8)
671
+ }));
672
+ return {
673
+ message: `OpenAI ${context.transport} tool schema strict mode downgraded to strict=false for ${context.model.provider ?? "unknown"}/${context.model.id ?? "unknown"} because ${diagnostics.length} tool schema(s) are not strict-compatible`,
674
+ data: {
675
+ transport: context.transport,
676
+ provider: context.model.provider,
677
+ model: context.model.id,
678
+ incompatibleToolCount: diagnostics.length,
679
+ sample
680
+ }
681
+ };
682
+ });
683
+ return strict;
684
+ }
685
+ function buildOpenAIClientHeaders(model, context, optionHeaders, turnHeaders, sessionId, cacheRetention) {
686
+ const providerHeaders = { ...model.headers };
687
+ if (model.provider === "github-copilot") Object.assign(providerHeaders, getAiTransportHost().buildCopilotDynamicHeaders(context.messages));
688
+ if (OPENAI_COMPLETIONS_APIS.has(model.api) && sessionId && cacheRetention !== "none") {
689
+ const { sessionAffinity } = resolveOpenAICompletionsCompat(model);
690
+ if (sessionAffinity !== "none") {
691
+ const affinityValue = clampOpenAIPromptCacheKey(sessionId) ?? sessionId;
692
+ const affinityHeaders = sessionAffinity === "openrouter" ? ["x-session-id"] : [
693
+ "session_id",
694
+ "x-client-request-id",
695
+ "x-session-affinity"
696
+ ];
697
+ const configuredHeaders = new Set(Object.keys(providerHeaders).map((key) => key.toLowerCase()));
698
+ for (const name of affinityHeaders) if (!configuredHeaders.has(name)) providerHeaders[name] = affinityValue;
699
+ }
700
+ }
701
+ const callerHeaders = {
702
+ ...optionHeaders,
703
+ ...turnHeaders
704
+ };
705
+ const resolvedHeaders = getAiTransportHost().resolveProviderRequestHeaders({
706
+ provider: model.provider,
707
+ api: model.api,
708
+ baseUrl: model.baseUrl,
709
+ providerHeaders,
710
+ callerHeaders: Object.keys(callerHeaders).length > 0 ? callerHeaders : void 0,
711
+ precedence: "caller-wins",
712
+ model
713
+ }) ?? {};
714
+ const sendSessionIdHeader = (OPENAI_RESPONSES_APIS.has(model.api) && model.compat && "sendSessionIdHeader" in model.compat ? model.compat?.sendSessionIdHeader : void 0) ?? usesNativeOpenAICodexResponsesBackend(model);
715
+ if (sessionId && cacheRetention !== "none" && sendSessionIdHeader && !Object.keys(resolvedHeaders).some((key) => normalizeLowercaseStringOrEmpty(key) === "session_id")) resolvedHeaders.session_id = clampOpenAIPromptCacheKey(sessionId) ?? sessionId;
716
+ return resolveOpencodeSessionHeaders(model, {
717
+ sessionId,
718
+ headers: resolvedHeaders
719
+ }) ?? resolvedHeaders;
720
+ }
721
+ function buildOpenAISdkClientOptions(model) {
722
+ const timeout = resolveModelRequestTimeoutMs(model);
723
+ return {
724
+ ...timeout === void 0 ? {} : { timeout },
725
+ maxRetries: 0
726
+ };
727
+ }
728
+ function buildOpenAISdkRequestOptions(model, signal, options) {
729
+ const timeout = resolveModelRequestTimeoutMs(model, options?.timeoutMs);
730
+ const headers = options?.stream === true && usesNativeOpenAICodexResponsesBackend(model) ? { Accept: "text/event-stream" } : void 0;
731
+ if (timeout === void 0 && !signal && !headers) return;
732
+ return {
733
+ ...headers ? { headers } : {},
734
+ ...signal ? { signal } : {},
735
+ ...timeout !== void 0 ? { timeout } : {},
736
+ maxRetries: 0
737
+ };
738
+ }
739
+ function getCompat(model) {
740
+ const resolved = resolveOpenAICompletionsCompat(model);
741
+ const compat = model.compat ?? {};
742
+ return {
743
+ ...resolved,
744
+ reasoningEffortMap: resolveOpenAIReasoningEffortMap(model, {}),
745
+ openRouterRouting: resolved.openRouterRouting ?? {},
746
+ requiresStringContent: compat.requiresStringContent ?? false,
747
+ strictMessageKeys: compat.strictMessageKeys === true
748
+ };
89
749
  }
90
750
  //#endregion
91
751
  //#region packages/ai/src/transports/openai-responses-compaction-replay.ts
@@ -94,8 +754,8 @@ const OPENAI_RESPONSES_COMPACTION_SUPPRESSION_DATA = "rejected";
94
754
  function isOpenAIResponsesCompactionState(state) {
95
755
  if (typeof state.baseUrlHash !== "string" || state.v !== 1) return false;
96
756
  if (state.type === OPENAI_RESPONSES_COMPACTION_SUPPRESSION_TYPE) return state.data === OPENAI_RESPONSES_COMPACTION_SUPPRESSION_DATA;
97
- if (state.type === "openai-responses-retained-compaction") return typeof state.data === "string" && state.data.length > 0 && (state.id === void 0 || typeof state.id === "string") && state.replayIndex === void 0;
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);
757
+ const retained = state.type === OPENAI_RESPONSES_RETAINED_COMPACTION_REPLAY_TYPE;
758
+ return (retained || 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 || !retained && typeof state.replayIndex === "number" && Number.isSafeInteger(state.replayIndex) && state.replayIndex >= 0);
99
759
  }
100
760
  function readOpenAIResponsesCompactionReplayState(value) {
101
761
  return isRecord(value) && isProviderReplayContext(value) && isOpenAIResponsesCompactionState(value) ? value : void 0;
@@ -289,6 +949,50 @@ function replayResponsesReasoningUpdates(previous, request, previousOutputLength
289
949
  };
290
950
  }
291
951
  //#endregion
952
+ //#region packages/ai/src/transports/openai-responses-tool-call-id-shape.ts
953
+ /**
954
+ * Pure OpenAI Responses `call_*`/`fc_*` tool-call-id shape helpers.
955
+ *
956
+ * Moved out of embedded-agent-helpers/openai.ts (the AgentMessage[]-walking
957
+ * caller lives in src/agents and imports from packages/ai, so the reverse
958
+ * import direction is not available) so the continuation transport can
959
+ * recognize its own cached raw ids after this same reshaping and restore
960
+ * them on a replayed wire request -- see openai-responses-continuation.ts.
961
+ */
962
+ const OPENAI_RESPONSES_ID_MAX_LENGTH = 64;
963
+ const OPENAI_RESPONSES_CALL_ID_RE = /^call_[A-Za-z0-9_-]{1,59}$/;
964
+ const OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE = /^fc_[A-Za-z0-9_-]{1,61}$/;
965
+ function splitOpenAIFunctionCallPairing(id) {
966
+ const separator = id.indexOf("|");
967
+ if (separator <= 0 || separator >= id.length - 1) return { callId: id };
968
+ return {
969
+ callId: id.slice(0, separator),
970
+ itemId: id.slice(separator + 1)
971
+ };
972
+ }
973
+ function normalizeOpenAIResponsesIdPart(value, prefix) {
974
+ const trimmed = value.trim();
975
+ if ((prefix === "call_" ? OPENAI_RESPONSES_CALL_ID_RE : OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE).test(trimmed)) return trimmed;
976
+ const rawTail = trimmed.startsWith(prefix) ? trimmed.slice(prefix.length) : trimmed;
977
+ const hash = sha256Hex(trimmed || prefix).slice(0, 10);
978
+ const maxTailLength = 64 - prefix.length;
979
+ const hashSuffix = `_${hash}`;
980
+ return `${prefix}${`${rawTail.replace(/[^A-Za-z0-9_-]/g, "_").replace(/^_+|_+$/g, "").slice(0, Math.max(1, maxTailLength - hashSuffix.length)) || "id"}${hashSuffix}`.slice(0, maxTailLength)}`;
981
+ }
982
+ /** Same shaping `normalizeOpenAIResponsesToolCallIds` applies to a replayed `call_id`/`call_id|fc_id` pair. */
983
+ function normalizeOpenAIResponsesFunctionCallId(id) {
984
+ const { callId, itemId } = splitOpenAIFunctionCallPairing(id);
985
+ const normalizedCallId = normalizeOpenAIResponsesIdPart(itemId ? `${callId}|${itemId}` : callId, "call_");
986
+ if (!itemId) return normalizedCallId;
987
+ return `${normalizedCallId}|${normalizeOpenAIResponsesIdPart(itemId, "fc_")}`;
988
+ }
989
+ function shouldNormalizeOpenAIResponsesToolCallId(id) {
990
+ const pairing = splitOpenAIFunctionCallPairing(id);
991
+ if (!OPENAI_RESPONSES_CALL_ID_RE.test(pairing.callId)) return true;
992
+ if (pairing.itemId === void 0) return false;
993
+ return !OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE.test(pairing.itemId);
994
+ }
995
+ //#endregion
292
996
  //#region packages/ai/src/transports/openai-responses-continuation.ts
293
997
  const HTTP_CONTINUATION_IDLE_TTL_MS = 54e5;
294
998
  const MAX_HTTP_CONTINUATION_READY_ENTRIES = 1e3;
@@ -351,13 +1055,9 @@ function pendingResponsesToolCalls(calls, input) {
351
1055
  for (const [inputIndex, item] of input.entries()) {
352
1056
  if (!isRecord(item) || typeof item.call_id !== "string") continue;
353
1057
  const owner = ownerByReplayShape.get(item.call_id);
354
- if (item.type === "function_call") {
355
- replayedCallIds.add(item.call_id);
356
- if (owner !== void 0 && owner !== null) lastCallPosition.set(owner, inputIndex);
357
- continue;
358
- }
359
- if (item.type !== "function_call_output") continue;
360
- if (owner !== void 0 && owner !== null) lastOutputPosition.set(owner, inputIndex);
1058
+ if (item.type === "function_call") replayedCallIds.add(item.call_id);
1059
+ const positions = item.type === "function_call" ? lastCallPosition : item.type === "function_call_output" ? lastOutputPosition : void 0;
1060
+ if (positions && owner !== void 0 && owner !== null) positions.set(owner, inputIndex);
361
1061
  }
362
1062
  return calls.filter((_call, index) => {
363
1063
  const callPosition = lastCallPosition.get(index);
@@ -516,7 +1216,7 @@ function resolveResponsesContinuationRequest(continuation, request, steering) {
516
1216
  };
517
1217
  const replayedToolRoundInput = currentInput.slice(previousInput.length, baselineLength);
518
1218
  const replayedToolRound = normalizeAssistantReplayInput(replayedToolRoundInput);
519
- const historyToolRoundUnchanged = jsonValuesEqual(replayedToolRound, normalizeAssistantReplayInput(continuation.lastResponseItems, true)) || jsonValuesEqual(replayedToolRound, normalizeAssistantReplayInput(continuation.lastResponseItems, true, true));
1219
+ const historyToolRoundUnchanged = [false, true].some((ignoreCachedItemIds) => jsonValuesEqual(replayedToolRound, normalizeAssistantReplayInput(continuation.lastResponseItems, true, ignoreCachedItemIds)));
520
1220
  if (!continuationHistoryMatches(previousInput, currentInput.slice(0, previousInput.length)) || !historyToolRoundUnchanged) return {
521
1221
  request,
522
1222
  continuationStatus: "history_changed"
@@ -540,6 +1240,14 @@ function resolveResponsesContinuationRequest(continuation, request, steering) {
540
1240
  const httpContinuationEntries = /* @__PURE__ */ new Map();
541
1241
  const readyHttpContinuationEntries = /* @__PURE__ */ new Map();
542
1242
  let httpContinuationRetainedBytes = 0;
1243
+ function createHttpContinuationTimer(key) {
1244
+ const timer = setTimeout(() => {
1245
+ const entry = httpContinuationEntries.get(key);
1246
+ if (entry?.kind === "ready" && entry.idleTimer === timer) deleteHttpContinuationIfOwned(key, entry);
1247
+ }, HTTP_CONTINUATION_IDLE_TTL_MS);
1248
+ timer.unref?.();
1249
+ return timer;
1250
+ }
543
1251
  function deleteHttpContinuationIfOwned(key, entry) {
544
1252
  if (httpContinuationEntries.get(key) !== entry) return;
545
1253
  if (entry.kind === "ready") {
@@ -573,7 +1281,7 @@ function claimOpenAIResponsesHttpContinuation(params) {
573
1281
  const key = `${getSessionResourceOwnerId(owner)}\0${params.sessionId}\0${connectionIdentity(params)}`;
574
1282
  const previous = httpContinuationEntries.get(key);
575
1283
  if (previous?.kind === "claimed") return;
576
- if (previous?.kind === "ready") deleteHttpContinuationIfOwned(key, previous);
1284
+ if (previous) deleteHttpContinuationIfOwned(key, previous);
577
1285
  const claimed = {
578
1286
  kind: "claimed",
579
1287
  sessionId: params.sessionId,
@@ -581,15 +1289,15 @@ function claimOpenAIResponsesHttpContinuation(params) {
581
1289
  };
582
1290
  httpContinuationEntries.set(key, claimed);
583
1291
  try {
584
- const request = previous?.kind === "ready" ? params.request : params.restoreRequest?.() ?? params.request;
585
- const resolved = resolveResponsesContinuationRequest(previous?.kind === "ready" ? previous.state : void 0, request);
1292
+ const request = previous ? params.request : params.restoreRequest?.() ?? params.request;
1293
+ const resolved = resolveResponsesContinuationRequest(previous?.state, request);
586
1294
  const fullRequest = resolved.fullRequest ?? request;
587
1295
  return {
588
1296
  request: params.request.store === false ? fullRequest : resolved.request,
589
1297
  fullRequest,
590
1298
  commit: (effectiveRequest, response, dispatchedPreviousResponseId) => {
591
1299
  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);
1300
+ const state = recordResponsesContinuationState(previous?.state, effectiveRequest, response, previous !== void 0 && dispatchedPreviousResponseId === previous.state.lastResponseId);
593
1301
  const retainedBytes = Buffer.byteLength(JSON.stringify(state), "utf8");
594
1302
  if (httpContinuationEntries.get(key) !== claimed) return;
595
1303
  if (retainedBytes > MAX_HTTP_CONTINUATION_RETAINED_BYTES) {
@@ -601,10 +1309,9 @@ function claimOpenAIResponsesHttpContinuation(params) {
601
1309
  ...claimed,
602
1310
  kind: "ready",
603
1311
  state,
604
- idleTimer: setTimeout(() => deleteHttpContinuationIfOwned(key, ready), HTTP_CONTINUATION_IDLE_TTL_MS),
1312
+ idleTimer: owner.runInDetachedAsyncContext(() => createHttpContinuationTimer(key)),
605
1313
  retainedBytes
606
1314
  };
607
- ready.idleTimer.unref?.();
608
1315
  httpContinuationRetainedBytes += retainedBytes;
609
1316
  httpContinuationEntries.set(key, ready);
610
1317
  readyHttpContinuationEntries.set(key, ready);
@@ -681,36 +1388,32 @@ function createResponsesInputReplay(model) {
681
1388
  };
682
1389
  }
683
1390
  //#endregion
1391
+ //#region packages/ai/src/transports/openai-responses-replay.ts
1392
+ /** Resolves the assistant message id that can be replayed to OpenAI Responses. */
1393
+ function resolveReplayableResponsesMessageId(params) {
1394
+ if (!params.replayResponsesItemIds) return;
1395
+ if (!params.textSignatureId) return params.fallbackOrdinal === 0 ? params.fallbackId : `${params.fallbackId}_${params.fallbackOrdinal}`;
1396
+ return params.previousReplayItemWasReasoning ? params.textSignatureId : void 0;
1397
+ }
1398
+ //#endregion
684
1399
  //#region packages/ai/src/transports/openai-responses-replay-messages-internal.ts
685
1400
  function resolveResponsesInstructionRole(model) {
686
1401
  const supportsDeveloperRole = !isRecord(model.compat) || model.compat.supportsDeveloperRole !== false;
687
1402
  return model.reasoning && supportsDeveloperRole ? "developer" : "system";
688
1403
  }
689
1404
  function stripEncryptedReasoningContentFields(value) {
690
- if (!value || typeof value !== "object") return {
691
- value,
692
- changed: false
693
- };
1405
+ if (!value || typeof value !== "object") return value;
694
1406
  if (Array.isArray(value)) {
695
1407
  let changed = false;
696
1408
  const next = value.map((item) => {
697
1409
  const stripped = stripEncryptedReasoningContentFields(item);
698
- changed ||= stripped.changed;
699
- return stripped.value;
1410
+ changed ||= !Object.is(stripped, item);
1411
+ return stripped;
700
1412
  });
701
- return changed ? {
702
- value: next,
703
- changed: true
704
- } : {
705
- value,
706
- changed: false
707
- };
1413
+ return changed ? next : value;
708
1414
  }
709
1415
  const source = value;
710
- if (source.type === "compaction") return {
711
- value,
712
- changed: false
713
- };
1416
+ if (source.type === "compaction") return value;
714
1417
  let changed = false;
715
1418
  const next = {};
716
1419
  for (const [key, child] of Object.entries(source)) {
@@ -719,21 +1422,13 @@ function stripEncryptedReasoningContentFields(value) {
719
1422
  continue;
720
1423
  }
721
1424
  const stripped = stripEncryptedReasoningContentFields(child);
722
- changed ||= stripped.changed;
723
- next[key] = stripped.value;
1425
+ changed ||= !Object.is(stripped, child);
1426
+ next[key] = stripped;
724
1427
  }
725
- return changed ? {
726
- value: next,
727
- changed: true
728
- } : {
729
- value,
730
- changed: false
731
- };
1428
+ return changed ? next : value;
732
1429
  }
733
1430
  function isOpenAIResponsesReasoningReplayMetadata(value) {
734
- if (!isProviderReplayContext(value)) return false;
735
- const record = value;
736
- return record.v === 1 && record.source === "openai-responses";
1431
+ return isProviderReplayContext(value) && value.v === 1 && value.source === "openai-responses";
737
1432
  }
738
1433
  function readOpenAIResponsesReasoningReplayBlockMetadata(block) {
739
1434
  if (!Object.hasOwn(block, "openclawReasoningReplay")) return;
@@ -741,26 +1436,23 @@ function readOpenAIResponsesReasoningReplayBlockMetadata(block) {
741
1436
  return isOpenAIResponsesReasoningReplayMetadata(value) ? value : null;
742
1437
  }
743
1438
  function normalizeOpenAIResponsesReasoningReplayItem(item) {
744
- const record = item;
745
- if (record.type !== "reasoning" || Array.isArray(record.summary)) return item;
746
- return {
747
- ...record,
1439
+ return Array.isArray(item.summary) ? item : {
1440
+ ...item,
748
1441
  summary: []
749
1442
  };
750
1443
  }
751
1444
  function prepareOpenAIResponsesReasoningItemForReplay(item, context, blockMetadata, options) {
752
- const record = item;
753
- const hasRawMetadata = Object.hasOwn(record, OPENAI_RESPONSES_REASONING_REPLAY_META_KEY);
754
- const { [OPENAI_RESPONSES_REASONING_REPLAY_META_KEY]: rawMetadata, ...rest } = record;
1445
+ const hasRawMetadata = Object.hasOwn(item, OPENAI_RESPONSES_REASONING_REPLAY_META_KEY);
1446
+ const { [OPENAI_RESPONSES_REASONING_REPLAY_META_KEY]: rawMetadata, ...rest } = item;
755
1447
  if (!("encrypted_content" in rest)) return normalizeOpenAIResponsesReasoningReplayItem(rest);
756
1448
  const metadata = blockMetadata !== void 0 ? blockMetadata ?? void 0 : isOpenAIResponsesReasoningReplayMetadata(rawMetadata) ? rawMetadata : void 0;
757
1449
  if (blockMetadata === void 0 && !hasRawMetadata && options?.preserveUnattributedEncryptedContent === true || metadata && providerReplayContextMatches(metadata, context)) return normalizeOpenAIResponsesReasoningReplayItem(rest);
758
- return normalizeOpenAIResponsesReasoningReplayItem(stripEncryptedReasoningContentFields(rest).value);
1450
+ return normalizeOpenAIResponsesReasoningReplayItem(stripEncryptedReasoningContentFields(rest));
759
1451
  }
760
- function normalizeResponsesReplayItemId(id, prefix) {
1452
+ function normalizeResponsesReplayItemId(id) {
761
1453
  if (!id) return;
762
1454
  if (id.length <= 64) return id;
763
- return `${prefix}_${shortHash(id)}`;
1455
+ return `msg_${shortHash(id)}`;
764
1456
  }
765
1457
  function orderResponsesAsyncToolResults(source) {
766
1458
  const turnKey = (message) => {
@@ -898,6 +1590,7 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
898
1590
  }
899
1591
  let msgIndex = 0;
900
1592
  const appendAssistant = createResponsesInputReplay(model);
1593
+ const inHistorySystemUpdates = supportsNativeOpenAIResponsesEndpoint(model);
901
1594
  for (const msg of replayMessages) {
902
1595
  if (!("role" in msg)) {
903
1596
  messages.push(msg);
@@ -908,22 +1601,20 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
908
1601
  text: sanitizeTransportPayloadText(runtimeContextContentToText(msg.content))
909
1602
  }]));
910
1603
  else if (msg.role === "user") {
911
- if (typeof msg.content === "string") messages.push(buildResponsesInputMessage("user", [{
1604
+ const role = msg.operatorMessage && inHistorySystemUpdates && (typeof msg.content === "string" || msg.content.every((block) => block.type === "text")) ? resolveResponsesInstructionRole(model) : "user";
1605
+ const content = typeof msg.content === "string" ? [{
912
1606
  type: "input_text",
913
1607
  text: sanitizeTransportPayloadText(msg.content)
914
- }], msg));
915
- else {
916
- const content = msg.content.map((item) => item.type === "text" ? {
917
- type: "input_text",
918
- text: sanitizeTransportPayloadText(item.text)
919
- } : {
920
- type: "input_image",
921
- detail: "auto",
922
- image_url: `data:${item.mimeType};base64,${item.data}`
923
- }).filter((item) => providerStyle || model.input.includes("image") || item.type !== "input_image");
924
- if (content.length > 0) messages.push(buildResponsesInputMessage("user", content, msg));
925
- else if (providerStyle) continue;
926
- }
1608
+ }] : msg.content.map((item) => item.type === "text" ? {
1609
+ type: "input_text",
1610
+ text: sanitizeTransportPayloadText(item.text)
1611
+ } : {
1612
+ type: "input_image",
1613
+ detail: "auto",
1614
+ image_url: `data:${item.mimeType};base64,${item.data}`
1615
+ }).filter((item) => providerStyle || model.input.includes("image") || item.type !== "input_image");
1616
+ if (content.length > 0) messages.push(buildResponsesInputMessage(role, content, msg));
1617
+ else if (providerStyle) continue;
927
1618
  } else if (msg.role === "assistant") {
928
1619
  const output = [];
929
1620
  let textFallbackOrdinal = 0;
@@ -954,7 +1645,7 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
954
1645
  previousReplayItemWasReasoning
955
1646
  });
956
1647
  if (!textSignature?.id) textFallbackOrdinal += 1;
957
- msgId = normalizeResponsesReplayItemId(msgId, "msg");
1648
+ msgId = normalizeResponsesReplayItemId(msgId);
958
1649
  const messageItem = {
959
1650
  type: "message",
960
1651
  role: "assistant",
@@ -993,8 +1684,7 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
993
1684
  if (output.length === 0 && providerStyle) continue;
994
1685
  } else if (msg.role === "toolResult") {
995
1686
  const textResult = extractToolResultText(msg.content);
996
- const sanitizedTextResult = sanitizeTransportPayloadText(textResult);
997
- const hasText = sanitizedTextResult.trim().length > 0;
1687
+ const hasText = textResult.trim().length > 0;
998
1688
  const mediaPlaceholder = describeToolResultMediaPlaceholder(msg.content);
999
1689
  const hasImages = msg.content.some(isImageWithMediaPayload);
1000
1690
  const separatorIndex = msg.toolCallId.indexOf("|");
@@ -1004,7 +1694,7 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
1004
1694
  call_id: callId,
1005
1695
  output: hasImages && model.input.includes("image") ? [...hasText ? [{
1006
1696
  type: "input_text",
1007
- text: sanitizedTextResult
1697
+ text: textResult
1008
1698
  }] : mediaPlaceholder === "(see attached media)" ? [{
1009
1699
  type: "input_text",
1010
1700
  text: mediaPlaceholder
@@ -1012,7 +1702,7 @@ function convertResponsesMessagesWithStyle(model, context, allowedToolCallProvid
1012
1702
  type: "input_image",
1013
1703
  detail: "auto",
1014
1704
  image_url: `data:${item.mimeType};base64,${item.data}`
1015
- }))] : sanitizeNonEmptyTransportPayloadText(textResult, mediaPlaceholder ?? "(no output)")
1705
+ }))] : hasText ? textResult : mediaPlaceholder ?? "(no output)"
1016
1706
  });
1017
1707
  }
1018
1708
  msgIndex += 1;
@@ -1100,10 +1790,10 @@ function isProviderMessage(message) {
1100
1790
  }
1101
1791
  //#endregion
1102
1792
  //#region packages/ai/src/transports/openai-responses-debug.ts
1103
- function stringifyUnknown(value, fallback = "") {
1793
+ function stringifyUnknown(value) {
1104
1794
  if (typeof value === "string") return value;
1105
1795
  if (typeof value === "number" || typeof value === "boolean") return String(value);
1106
- return fallback;
1796
+ return "";
1107
1797
  }
1108
1798
  function safeDebugValue(value) {
1109
1799
  if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") return String(value);
@@ -1361,6 +2051,19 @@ function summarizeOpenAITransportError(error) {
1361
2051
  function isAsyncIterable(value) {
1362
2052
  return (typeof value === "object" && value !== null || typeof value === "function") && Symbol.asyncIterator in value;
1363
2053
  }
2054
+ function readResponsesRecoveryEvent(event) {
2055
+ const record = isRecord(event) ? event : void 0;
2056
+ const response = isRecord(record?.response) ? record.response : void 0;
2057
+ return {
2058
+ failure: record?.type === "response.failed" ? response?.error : record?.type === "error" ? record.error ?? record : void 0,
2059
+ hasResponseOutput: Array.isArray(response?.output) && response.output.length > 0,
2060
+ isPrelude: record !== void 0 && [
2061
+ "response.created",
2062
+ "response.in_progress",
2063
+ "response.queued"
2064
+ ].includes(String(record.type))
2065
+ };
2066
+ }
1364
2067
  function isInvalidEncryptedContentError(error) {
1365
2068
  if (!error || typeof error !== "object") return false;
1366
2069
  const record = error;
@@ -1379,10 +2082,9 @@ function commitResponsesEncryptedContentAttempt(attempt, commit) {
1379
2082
  }
1380
2083
  function stripResponsesRequestEncryptedReasoning(request) {
1381
2084
  const stripped = stripEncryptedReasoningContentFields(request.input);
1382
- if (!stripped.changed) return request;
1383
- return {
2085
+ return stripped === request.input ? request : {
1384
2086
  ...request,
1385
- input: stripped.value
2087
+ input: stripped
1386
2088
  };
1387
2089
  }
1388
2090
  function stripResponsesRequestCompaction(request) {
@@ -1422,16 +2124,44 @@ async function resolveNextResponsesEncryptedContentAttempt(attempt, error, optio
1422
2124
  rejectedCompaction: readOpenAIResponsesCompactionRejection(attempt.request)
1423
2125
  };
1424
2126
  }
1425
- async function createResponsesStreamWithEncryptedContentRetry(params) {
2127
+ async function createResponsesStreamWithRecovery(params) {
1426
2128
  const encodeBody = params.encodeBody ?? prepareModelRequestBody(void 0);
2129
+ let tierCeiling;
2130
+ const limitTier = (request) => tierCeiling && (request.service_tier === "ultrafast" || tierCeiling === "default" && request.service_tier === "priority") ? {
2131
+ ...request,
2132
+ service_tier: tierCeiling
2133
+ } : request;
2134
+ const recoverServiceTier = (attempt, error) => {
2135
+ if (params.requestOptions?.signal?.aborted || !supportsNativeOpenAIResponsesEndpoint(params.model)) return;
2136
+ const tier = attempt.request.service_tier;
2137
+ const next = nextResponsesServiceTier(tier, error);
2138
+ if (!next || tier !== "ultrafast" && tier !== "priority") return;
2139
+ tierCeiling = next;
2140
+ params.onServiceTierRejected?.(tier);
2141
+ log.info(`[responses] rejected ${tier} tier; retrying with ${next}`);
2142
+ return {
2143
+ ...attempt,
2144
+ request: {
2145
+ ...attempt.request,
2146
+ service_tier: next
2147
+ }
2148
+ };
2149
+ };
1427
2150
  const send = async (initialAttempt) => {
1428
2151
  let attempt = initialAttempt;
1429
2152
  for (;;) {
2153
+ const cappedRequest = limitTier(attempt.request);
2154
+ if (cappedRequest !== attempt.request) attempt = {
2155
+ kind: attempt.kind,
2156
+ request: cappedRequest,
2157
+ rejectedCompaction: attempt.rejectedCompaction
2158
+ };
1430
2159
  params.observePrompt?.(attempt.request, {
1431
2160
  egress: "responses-sdk",
1432
2161
  payloadVariant: attempt.kind
1433
2162
  });
1434
2163
  const bodyOptions = await encodeBody(attempt.request);
2164
+ let responseAccepted = false;
1435
2165
  try {
1436
2166
  const { data, response } = await params.client.responses.create(attempt.request, {
1437
2167
  ...params.requestOptions,
@@ -1441,6 +2171,7 @@ async function createResponsesStreamWithEncryptedContentRetry(params) {
1441
2171
  ...params.requestOptions?.headers
1442
2172
  }
1443
2173
  }).withResponse();
2174
+ responseAccepted = true;
1444
2175
  commitResponsesEncryptedContentAttempt(attempt, (checkpoint) => {
1445
2176
  if (checkpoint) params.onCompactionRejected?.(checkpoint);
1446
2177
  });
@@ -1451,7 +2182,7 @@ async function createResponsesStreamWithEncryptedContentRetry(params) {
1451
2182
  attempt
1452
2183
  };
1453
2184
  } catch (error) {
1454
- let nextAttempt = await resolveNextResponsesEncryptedContentAttempt(attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest });
2185
+ let nextAttempt = (!responseAccepted ? recoverServiceTier(attempt, error) : void 0) ?? await resolveNextResponsesEncryptedContentAttempt(attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest });
1455
2186
  if (!nextAttempt && attempt.request.previous_response_id && error && typeof error === "object" && typeof error.status === "number" && isPreviousResponseRejection(error)) {
1456
2187
  const request = { ...params.buildFullHistoryRequest ? await params.buildFullHistoryRequest() : attempt.request };
1457
2188
  delete request.previous_response_id;
@@ -1461,7 +2192,7 @@ async function createResponsesStreamWithEncryptedContentRetry(params) {
1461
2192
  };
1462
2193
  }
1463
2194
  if (!nextAttempt) throw error;
1464
- 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";
2195
+ const retryDescription = nextAttempt.request.service_tier !== attempt.request.service_tier ? "with a slower service tier" : nextAttempt.kind === "reasoning-stripped" ? "without encrypted reasoning content" : nextAttempt.kind === "compaction-stripped" ? "without encrypted compaction content" : "full history after rejected previous_response_id";
1465
2196
  log.warn(`[responses] retrying ${retryDescription} provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
1466
2197
  attempt = nextAttempt;
1467
2198
  }
@@ -1474,26 +2205,42 @@ async function createResponsesStreamWithEncryptedContentRetry(params) {
1474
2205
  });
1475
2206
  return { stream: { async *[Symbol.asyncIterator]() {
1476
2207
  let current = result;
2208
+ let outputObserved = false;
1477
2209
  for (;;) {
1478
2210
  let rejectedEvent;
2211
+ let sourceError;
2212
+ const source = current.stream;
2213
+ const providerStream = { async *[Symbol.asyncIterator]() {
2214
+ try {
2215
+ yield* source;
2216
+ } catch (error) {
2217
+ sourceError = error;
2218
+ throw error;
2219
+ }
2220
+ } };
1479
2221
  try {
1480
- for await (const event of params.wrapStream?.(current) ?? current.stream) {
1481
- if (isRecord(event)) {
1482
- const failure = event.type === "response.failed" && isRecord(event.response) ? event.response.error : event.type === "error" ? event.error ?? event : void 0;
1483
- if (isRecord(failure) && params.canRetryStream?.() === true && isInvalidEncryptedContentError(failure)) {
1484
- rejectedEvent = event;
1485
- const message = typeof failure.message === "string" ? failure.message : "";
1486
- throw Object.assign(new Error(message), {
1487
- code: failure.code,
1488
- status: failure.status
1489
- });
1490
- }
2222
+ for await (const event of params.wrapStream?.({
2223
+ ...current,
2224
+ stream: providerStream
2225
+ }) ?? providerStream) {
2226
+ const { failure, hasResponseOutput, isPrelude } = readResponsesRecoveryEvent(event);
2227
+ outputObserved ||= hasResponseOutput;
2228
+ if (isRecord(failure) && params.canRetryStream?.() === true && (isInvalidEncryptedContentError(failure) || !outputObserved && isResponsesServiceTierRejection(failure))) {
2229
+ rejectedEvent = event;
2230
+ const message = typeof failure.message === "string" ? failure.message : "";
2231
+ throw Object.assign(new Error(message), {
2232
+ code: failure.code,
2233
+ status: failure.status,
2234
+ type: failure.type,
2235
+ param: failure.param
2236
+ });
1491
2237
  }
2238
+ outputObserved ||= !isPrelude;
1492
2239
  yield event;
1493
2240
  }
1494
2241
  return;
1495
2242
  } catch (error) {
1496
- const nextAttempt = params.canRetryStream?.() === true && !params.requestOptions?.signal?.aborted ? await resolveNextResponsesEncryptedContentAttempt(current.attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest }) : void 0;
2243
+ const nextAttempt = params.canRetryStream?.() === true && !params.requestOptions?.signal?.aborted ? (!outputObserved && (rejectedEvent !== void 0 || sourceError === error) ? recoverServiceTier(current.attempt, error) : void 0) ?? await resolveNextResponsesEncryptedContentAttempt(current.attempt, error, { buildFullHistoryRequest: params.buildFullHistoryRequest }) : void 0;
1497
2244
  if (!nextAttempt) {
1498
2245
  if (rejectedEvent !== void 0) {
1499
2246
  yield rejectedEvent;
@@ -1501,7 +2248,7 @@ async function createResponsesStreamWithEncryptedContentRetry(params) {
1501
2248
  }
1502
2249
  throw error;
1503
2250
  }
1504
- log.warn(`[responses] retrying streamed encrypted content provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
2251
+ log.warn(`[responses] retrying explicitly rejected stream provider=${params.model.provider} api=${params.model.api} model=${params.model.id}`);
1505
2252
  current = await send(nextAttempt);
1506
2253
  }
1507
2254
  }
@@ -1618,31 +2365,24 @@ function readResponsesOutputIndex(event) {
1618
2365
  return typeof outputIndex === "number" && Number.isInteger(outputIndex) && outputIndex >= 0 ? outputIndex : void 0;
1619
2366
  }
1620
2367
  function createResponsesOutputSlotTracker() {
1621
- const indexed = /* @__PURE__ */ new Map();
1622
- let unindexed;
2368
+ const slots = /* @__PURE__ */ new Map();
1623
2369
  return {
1624
2370
  register(event, slot) {
1625
2371
  const outputIndex = readResponsesOutputIndex(event);
1626
- if (outputIndex === void 0) {
1627
- if (unindexed) throw new Error("Responses stream added overlapping unindexed output items");
1628
- unindexed = slot;
1629
- return;
1630
- }
1631
- if (indexed.has(outputIndex)) throw new Error(`Responses stream reused active output index ${outputIndex}`);
1632
- indexed.set(outputIndex, slot);
2372
+ if (slots.has(outputIndex)) throw new Error(outputIndex === void 0 ? "Responses stream added overlapping unindexed output items" : `Responses stream reused active output index ${outputIndex}`);
2373
+ slots.set(outputIndex, slot);
1633
2374
  },
1634
2375
  resolve(event, type) {
1635
2376
  const outputIndex = readResponsesOutputIndex(event);
1636
- let slot = outputIndex === void 0 ? unindexed : indexed.get(outputIndex);
2377
+ let slot = slots.get(outputIndex);
1637
2378
  if (outputIndex === void 0 && !slot) {
1638
- const matches = [...indexed.values()].filter((candidate) => candidate.type === type);
2379
+ const matches = [...slots.values()].filter((candidate) => candidate.type === type);
1639
2380
  slot = matches.length === 1 ? matches[0] : void 0;
1640
2381
  }
1641
2382
  return slot?.type === type ? slot : void 0;
1642
2383
  },
1643
2384
  get(event) {
1644
- const outputIndex = readResponsesOutputIndex(event);
1645
- return outputIndex === void 0 ? unindexed : indexed.get(outputIndex);
2385
+ return slots.get(readResponsesOutputIndex(event));
1646
2386
  },
1647
2387
  resolveOutputItem(event, item) {
1648
2388
  if (item.type === "reasoning") return this.resolve(event, "thinking");
@@ -1650,11 +2390,12 @@ function createResponsesOutputSlotTracker() {
1650
2390
  return readResponsesOutputIndex(event) === void 0 ? void 0 : this.get(event);
1651
2391
  },
1652
2392
  values() {
1653
- return [.../* @__PURE__ */ new Set([...indexed.values(), ...unindexed ? [unindexed] : []])];
2393
+ const indexed = [...slots].filter(([index]) => index !== void 0).map(([, slot]) => slot);
2394
+ const unindexed = slots.get(void 0);
2395
+ return [.../* @__PURE__ */ new Set([...indexed, ...unindexed ? [unindexed] : []])];
1654
2396
  },
1655
2397
  forget(slot) {
1656
- if (unindexed === slot) unindexed = void 0;
1657
- for (const [outputIndex, candidate] of indexed) if (candidate === slot) indexed.delete(outputIndex);
2398
+ for (const [outputIndex, candidate] of slots) if (candidate === slot) slots.delete(outputIndex);
1658
2399
  }
1659
2400
  };
1660
2401
  }
@@ -1783,11 +2524,9 @@ function resolveResponsesToolCallId(item, fallbackId) {
1783
2524
  const callId = typeof item.call_id === "string" ? item.call_id.trim() : "";
1784
2525
  const itemId = typeof item.id === "string" ? item.id.trim() : "";
1785
2526
  const [fallbackCallId, fallbackItemId = ""] = splitToolCallId(fallbackId ?? "");
1786
- const resolvedCallId = callId || fallbackCallId;
2527
+ const resolvedCallId = callId || fallbackCallId || `call_${randomUUID().replaceAll("-", "").slice(0, 24)}`;
1787
2528
  const resolvedItemId = itemId || fallbackItemId;
1788
- if (resolvedCallId) return resolvedItemId ? `${resolvedCallId}|${resolvedItemId}` : resolvedCallId;
1789
- const generated = `call_${randomUUID().replaceAll("-", "").slice(0, 24)}`;
1790
- return resolvedItemId ? `${generated}|${resolvedItemId}` : generated;
2529
+ return resolvedItemId ? `${resolvedCallId}|${resolvedItemId}` : resolvedCallId;
1791
2530
  }
1792
2531
  function resolveCompletedResponsesToolCall(item, streamed) {
1793
2532
  if (item.status && item.status !== "completed") throw new IncompleteToolCallError("Responses stream completed with an incomplete terminal tool call");
@@ -1822,7 +2561,8 @@ function createResponsesTerminalController(params) {
1822
2561
  if (options?.reasoningReplayMetadata) Object.assign(block, { [OPENAI_RESPONSES_REASONING_REPLAY_BLOCK_META_KEY]: options.reasoningReplayMetadata });
1823
2562
  }
1824
2563
  };
1825
- const appendText = (item, contentIndex) => {
2564
+ const appendText = (item, initialIndex) => {
2565
+ let contentIndex = initialIndex;
1826
2566
  const text = (Array.isArray(item.content) ? item.content : []).map((part) => {
1827
2567
  const content = part;
1828
2568
  return content.type === "output_text" || content.type === "text" ? content.text ?? "" : content.refusal ?? "";
@@ -1848,58 +2588,47 @@ function createResponsesTerminalController(params) {
1848
2588
  delta
1849
2589
  });
1850
2590
  }
1851
- stream.push({
1852
- type: "text_end",
1853
- contentIndex,
1854
- content: text,
1855
- partial: output
1856
- });
1857
- return contentIndex;
1858
- }
1859
- const previous = params.getLastTextBlock();
1860
- const collapse = resolveResponsesMessageSnapshotCollapse({
1861
- prior: previous && {
1862
- text: previous.block.text,
1863
- phase: previous.phase
1864
- },
1865
- nextText: text,
1866
- nextPhase: phase
1867
- });
1868
- if (collapse.kind === "extend" && previous) {
1869
- previous.block.text = collapse.text;
1870
- previous.block.textSignature = encodeTextSignatureV1(item.id, phase);
1871
- stream.push({
1872
- type: "text_end",
1873
- contentIndex: previous.index,
1874
- content: collapse.text,
1875
- partial: output
2591
+ } else {
2592
+ const previous = params.getLastTextBlock();
2593
+ const collapse = resolveResponsesMessageSnapshotCollapse({
2594
+ prior: previous && {
2595
+ text: previous.block.text,
2596
+ phase: previous.phase
2597
+ },
2598
+ nextText: text,
2599
+ nextPhase: phase
1876
2600
  });
1877
- return previous.index;
2601
+ if (collapse.kind === "extend" && previous) {
2602
+ previous.block.text = collapse.text;
2603
+ previous.block.textSignature = encodeTextSignatureV1(item.id, phase);
2604
+ contentIndex = previous.index;
2605
+ } else {
2606
+ const newBlock = {
2607
+ type: "text",
2608
+ text,
2609
+ textSignature: encodeTextSignatureV1(item.id, phase)
2610
+ };
2611
+ blocks.push(newBlock);
2612
+ contentIndex = blocks.length - 1;
2613
+ params.setLastTextBlock({
2614
+ block: newBlock,
2615
+ index: contentIndex,
2616
+ phase
2617
+ });
2618
+ stream.push({
2619
+ type: "text_start",
2620
+ contentIndex,
2621
+ partial: output
2622
+ });
2623
+ }
1878
2624
  }
1879
- const newBlock = {
1880
- type: "text",
1881
- text,
1882
- textSignature: encodeTextSignatureV1(item.id, phase)
1883
- };
1884
- blocks.push(newBlock);
1885
- const index = blocks.length - 1;
1886
- params.setLastTextBlock({
1887
- block: newBlock,
1888
- index,
1889
- phase
1890
- });
1891
- stream.push({
1892
- type: "text_start",
1893
- contentIndex: index,
1894
- partial: output
1895
- });
1896
2625
  stream.push({
1897
2626
  type: "text_end",
1898
- contentIndex: index,
2627
+ contentIndex,
1899
2628
  content: text,
1900
2629
  partial: output
1901
2630
  });
1902
- return index;
2631
+ return contentIndex;
1903
2632
  };
1904
2633
  const emitToolCallCompletion = (item, outputIndex, started, validated) => {
1905
2634
  const completed = {
@@ -2043,67 +2772,52 @@ async function processResponsesStream(openaiStream, output, sink, model, options
2043
2772
  let lastTextBlock = null;
2044
2773
  const blocks = output.content;
2045
2774
  const compactionTracker = createCompactionTracker(output, model, options);
2775
+ const createTextBlock = (item, text) => ({
2776
+ type: "text",
2777
+ text,
2778
+ ...item.phase ? { textSignature: encodeTextSignatureV1(item.id, item.phase) } : {}
2779
+ });
2046
2780
  const createOutputSlot = (event, item) => {
2047
- if (item.type === "reasoning") {
2048
- const block = {
2781
+ let slot;
2782
+ if (item.type === "reasoning") slot = {
2783
+ type: "thinking",
2784
+ item,
2785
+ block: {
2049
2786
  type: "thinking",
2050
2787
  thinking: ""
2051
- };
2052
- const slot = {
2053
- type: "thinking",
2054
- item,
2055
- block,
2056
- contentIndex: blocks.length,
2057
- outputIndex: readResponsesOutputIndex(event)
2058
- };
2059
- blocks.push(block);
2060
- outputs.set(item, slot.contentIndex, slot.outputIndex);
2061
- outputSlots.register(event, slot);
2062
- stream.push({
2063
- type: "thinking_start",
2064
- contentIndex: slot.contentIndex,
2065
- partial: output
2066
- });
2067
- return slot;
2068
- }
2069
- if (item.type === "message") {
2070
- const messageItem = item;
2788
+ },
2789
+ contentIndex: blocks.length,
2790
+ outputIndex: readResponsesOutputIndex(event)
2791
+ };
2792
+ else if (item.type === "message") {
2071
2793
  const collapseCandidate = lastTextBlock;
2072
- const block = collapseCandidate ? null : {
2073
- type: "text",
2074
- text: "",
2075
- ...messageItem.phase ? { textSignature: encodeTextSignatureV1(messageItem.id, messageItem.phase) } : {}
2076
- };
2077
- const slot = {
2794
+ const block = collapseCandidate ? null : createTextBlock(item, "");
2795
+ slot = {
2078
2796
  type: "text",
2079
- item: messageItem,
2797
+ item,
2080
2798
  block,
2081
2799
  contentIndex: block ? blocks.length : void 0,
2082
2800
  outputIndex: readResponsesOutputIndex(event),
2083
2801
  pendingText: collapseCandidate ? "" : null,
2084
2802
  collapseCandidate
2085
2803
  };
2086
- if (block) {
2087
- blocks.push(block);
2088
- outputs.set(messageItem, slot.contentIndex ?? blocks.length - 1, slot.outputIndex);
2089
- }
2090
- outputSlots.register(event, slot);
2091
- if (slot.contentIndex !== void 0) stream.push({
2092
- type: "text_start",
2093
- contentIndex: slot.contentIndex,
2094
- partial: output
2095
- });
2096
- return slot;
2804
+ } else return;
2805
+ if (slot.block) {
2806
+ blocks.push(slot.block);
2807
+ outputs.set(slot.item, slot.contentIndex ?? blocks.length - 1, slot.outputIndex);
2097
2808
  }
2809
+ outputSlots.register(event, slot);
2810
+ if (slot.contentIndex !== void 0) stream.push({
2811
+ type: slot.type === "thinking" ? "thinking_start" : "text_start",
2812
+ contentIndex: slot.contentIndex,
2813
+ partial: output
2814
+ });
2815
+ return slot;
2098
2816
  };
2099
2817
  const materializeDeferredTextSlot = (slot) => {
2100
2818
  if (slot.block || slot.pendingText === null) return;
2101
2819
  const text = slot.pendingText;
2102
- slot.block = {
2103
- type: "text",
2104
- text,
2105
- ...slot.item.phase ? { textSignature: encodeTextSignatureV1(slot.item.id, slot.item.phase) } : {}
2106
- };
2820
+ slot.block = createTextBlock(slot.item, text);
2107
2821
  blocks.push(slot.block);
2108
2822
  slot.contentIndex = blocks.length - 1;
2109
2823
  outputs.set(slot.item, slot.contentIndex, slot.outputIndex);
@@ -2263,19 +2977,17 @@ async function processResponsesStream(openaiStream, output, sink, model, options
2263
2977
  if (!slot) continue;
2264
2978
  slot.item.summary = slot.item.summary || [];
2265
2979
  slot.item.summary.push(event.part);
2266
- } else if (event.type === "response.reasoning_summary_text.delta" || event.type === "response.reasoning_summary_part.done") {
2980
+ } else if (event.type === "response.reasoning_summary_text.delta" || event.type === "response.reasoning_summary_part.done" || event.type === "response.reasoning_text.delta") {
2267
2981
  const slot = outputSlots.resolve(event, "thinking");
2268
2982
  if (!slot) continue;
2269
- slot.item.summary = slot.item.summary || [];
2270
- const lastPart = slot.item.summary[slot.item.summary.length - 1];
2271
- if (!lastPart) continue;
2272
- const delta = event.type === "response.reasoning_summary_text.delta" ? event.delta : "\n\n";
2273
- lastPart.text += delta;
2983
+ const delta = event.type === "response.reasoning_summary_part.done" ? "\n\n" : event.delta;
2984
+ if (event.type !== "response.reasoning_text.delta") {
2985
+ slot.item.summary = slot.item.summary || [];
2986
+ const lastPart = slot.item.summary[slot.item.summary.length - 1];
2987
+ if (!lastPart) continue;
2988
+ lastPart.text += delta;
2989
+ }
2274
2990
  appendThinkingDelta(slot, delta);
2275
- } else if (event.type === "response.reasoning_text.delta") {
2276
- const slot = outputSlots.resolve(event, "thinking");
2277
- if (!slot) continue;
2278
- appendThinkingDelta(slot, event.delta);
2279
2991
  } else if (event.type === "response.content_part.added") {
2280
2992
  const slot = outputSlots.resolve(event, "text");
2281
2993
  if (!slot) continue;
@@ -2311,22 +3023,19 @@ async function processResponsesStream(openaiStream, output, sink, model, options
2311
3023
  lastPart.text += event.delta;
2312
3024
  }
2313
3025
  projectTextDelta(slot, event.delta);
2314
- } else if (event.type === "response.function_call_arguments.delta") {
3026
+ } else if (event.type === "response.function_call_arguments.delta" || event.type === "response.function_call_arguments.done") {
2315
3027
  const toolCall = streamingToolCalls.resolve(event);
2316
- if (toolCall) {
3028
+ if (!toolCall) {
3029
+ if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
3030
+ continue;
3031
+ }
3032
+ let delta;
3033
+ if (event.type === "response.function_call_arguments.delta") {
2317
3034
  toolCall.block.partialJson += event.delta;
2318
3035
  toolCall.argumentsStreamed = true;
2319
3036
  if (toolCall.previewSchedule(toolCall.block.partialJson.length)) toolCall.block.arguments = parseStreamingJson(toolCall.block.partialJson);
2320
- stream.push({
2321
- type: "toolcall_delta",
2322
- contentIndex: toolCall.contentIndex,
2323
- delta: event.delta,
2324
- partial: output
2325
- });
2326
- } else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
2327
- } else if (event.type === "response.function_call_arguments.done") {
2328
- const toolCall = streamingToolCalls.resolve(event);
2329
- if (toolCall) {
3037
+ delta = event.delta;
3038
+ } else {
2330
3039
  const previousPartialJson = toolCall.block.partialJson;
2331
3040
  const doneArguments = typeof event.arguments === "string" ? event.arguments : void 0;
2332
3041
  if (doneArguments !== void 0 && (doneArguments.length > 0 || previousPartialJson === "")) {
@@ -2335,16 +3044,14 @@ async function processResponsesStream(openaiStream, output, sink, model, options
2335
3044
  toolCall.argumentStreamReliable = true;
2336
3045
  toolCall.argumentsStreamed = true;
2337
3046
  }
2338
- if (doneArguments?.startsWith(previousPartialJson)) {
2339
- const delta = doneArguments.slice(previousPartialJson.length);
2340
- if (delta.length > 0) stream.push({
2341
- type: "toolcall_delta",
2342
- contentIndex: toolCall.contentIndex,
2343
- delta,
2344
- partial: output
2345
- });
2346
- }
2347
- } else if (streamingToolCalls.hasActive()) streamingToolCalls.markArgumentsUnreliable();
3047
+ if (doneArguments?.startsWith(previousPartialJson)) delta = doneArguments.slice(previousPartialJson.length) || void 0;
3048
+ }
3049
+ if (delta !== void 0) stream.push({
3050
+ type: "toolcall_delta",
3051
+ contentIndex: toolCall.contentIndex,
3052
+ delta,
3053
+ partial: output
3054
+ });
2348
3055
  } else if (event.type === "response.output_item.done") {
2349
3056
  const item = event.item;
2350
3057
  if (item.type !== "message") lastTextBlock = null;
@@ -2392,11 +3099,7 @@ async function processResponsesStream(openaiStream, output, sink, model, options
2392
3099
  outputs.set(item, outputSlot.collapseCandidate.index, readResponsesOutputIndex(event) ?? outputSlot.outputIndex, true);
2393
3100
  } else {
2394
3101
  if (!outputSlot.block) {
2395
- outputSlot.block = {
2396
- type: "text",
2397
- text: "",
2398
- ...phase ? { textSignature: encodeTextSignatureV1(item.id, phase) } : {}
2399
- };
3102
+ outputSlot.block = createTextBlock(item, "");
2400
3103
  blocks.push(outputSlot.block);
2401
3104
  outputSlot.contentIndex = blocks.length - 1;
2402
3105
  stream.push({
@@ -2588,7 +3291,7 @@ async function runResponsesStreamLifecycle(params) {
2588
3291
  let started = false;
2589
3292
  let admittedRequest;
2590
3293
  let requestedTier;
2591
- const { stream: hookedOpenAIStream } = await createResponsesStreamWithEncryptedContentRetry({
3294
+ const { stream: hookedOpenAIStream } = await createResponsesStreamWithRecovery({
2592
3295
  client,
2593
3296
  request: requestParams,
2594
3297
  requestOptions: {
@@ -2601,6 +3304,7 @@ async function runResponsesStreamLifecycle(params) {
2601
3304
  buildFullHistoryRequest: () => buildRequest("full-history"),
2602
3305
  onCompactionRejected: (checkpoint) => suppressOpenAIResponsesCompaction(output, model, options, checkpoint),
2603
3306
  canRetryStream: () => output.content.length === 0,
3307
+ onServiceTierRejected: (tier) => responsesServiceTierObserver.reject(options, tier),
2604
3308
  wrapStream: ({ stream: openaiStream, response, attempt }) => {
2605
3309
  requestedTier = attempt.request.service_tier;
2606
3310
  admittedRequest = attempt.kind === "initial" ? attempt.request : void 0;
@@ -2623,14 +3327,19 @@ async function runResponsesStreamLifecycle(params) {
2623
3327
  });
2624
3328
  const firstEventTimeoutMs = getFirstStreamEventTimeoutMs(options);
2625
3329
  const onFirstEventTimeout = getFirstStreamEventTimeoutHandler(options);
3330
+ const processStreamOptions = params.processStreamOptions || firstEventTimeoutMs !== void 0 || onFirstEventTimeout !== void 0 ? {
3331
+ ...params.processStreamOptions,
3332
+ firstEventTimeoutMs: params.processStreamOptions?.firstEventTimeoutMs ?? firstEventTimeoutMs,
3333
+ abortFirstEventStream: params.processStreamOptions?.abortFirstEventStream ?? firstEventAbort.abort,
3334
+ onFirstEventTimeout: params.processStreamOptions?.onFirstEventTimeout ?? onFirstEventTimeout,
3335
+ signal: params.processStreamOptions?.signal ?? options?.signal
3336
+ } : void 0;
2626
3337
  const terminal = await processResponsesStream(hookedOpenAIStream, output, stream, model, {
2627
- ...params.processStreamOptions || firstEventTimeoutMs !== void 0 || onFirstEventTimeout !== void 0 ? {
2628
- ...params.processStreamOptions,
2629
- firstEventTimeoutMs: params.processStreamOptions?.firstEventTimeoutMs ?? firstEventTimeoutMs,
2630
- abortFirstEventStream: params.processStreamOptions?.abortFirstEventStream ?? firstEventAbort.abort,
2631
- onFirstEventTimeout: params.processStreamOptions?.onFirstEventTimeout ?? onFirstEventTimeout,
2632
- signal: params.processStreamOptions?.signal ?? options?.signal
2633
- } : void 0,
3338
+ ...processStreamOptions,
3339
+ resolveServiceTier: (responseTier, originalTier) => {
3340
+ const tier = requestedTier === "priority" || requestedTier === "default" ? requestedTier : originalTier;
3341
+ return processStreamOptions?.resolveServiceTier ? processStreamOptions.resolveServiceTier(responseTier, tier) : responseTier ?? tier;
3342
+ },
2634
3343
  onServiceTier: (responseTier) => responsesServiceTierObserver.observe(options, requestedTier, responseTier),
2635
3344
  canRetryIdentityConflict: () => hasOnlyResponsesFunctionTools(admittedRequest),
2636
3345
  reasoningReplayMetadata: buildOpenAIResponsesReasoningReplayMetadata(model, {
@@ -2671,4 +3380,4 @@ async function runResponsesStreamLifecycle(params) {
2671
3380
  }
2672
3381
  }
2673
3382
  //#endregion
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 };
3383
+ export { replayResponsesReasoningUpdates as $, summarizeResponsesPayload as A, measureUtf8AppendBytes as At, responsesInputFingerprint as B, readResponsesRecoveryEvent as C, toOpenAIResponsesToolChoice as Ct, logResponsesFailedNoDetails as D, createResponseModelTracker as Dt, ResponsesStreamFailure as E, createOpenAIResponseHook as Et, convertProviderResponsesMessages as F, resolvePromptCacheKey as Ft, responsesContinuationRequestFingerprint as G, recordResponsesContinuationState as H, convertResponsesMessages as I, redactIdentifier as It, OPENAI_RESPONSES_ID_MAX_LENGTH as J, OPENAI_RESPONSES_CALL_ID_RE as K, resolveReplayableResponsesMessageId as L, sha256Hex as Lt, resolveResponsesContextUsageBoundary as M, readOpenAICompletionsContentDeltas as Mt, bindResponsesInputMessage as N, readOpenAICompletionsReasoningBatch as Nt, safeDebugValue as O, isOpenAICompletionsThinkingEnabled as Ot, buildResponsesInputMessage as P, resolveOpenAIClientBaseUrl as Pt, isConfigurationUpdate as Q, readResponsesInputReplayState as R, isInvalidEncryptedContentError as S, reconcileOpenAIResponsesToolChoice as St, resolveNextResponsesEncryptedContentAttempt as T, createOpenAIProviderAcceptanceHook as Tt, resolveResponsesContinuationRequest as U, claimOpenAIResponsesHttpContinuation as V, responsesContinuationPrefixFingerprint as W, shouldNormalizeOpenAIResponsesToolCallId as X, normalizeOpenAIResponsesFunctionCallId as Y, splitOpenAIFunctionCallPairing as Z, isResponsesTextContentPartType as _, resolveOpenAISimpleReasoningEffort as _t, prepareResponsesTools as a, suppressOpenAIResponsesCompaction as at, commitResponsesEncryptedContentAttempt as b, projectOpenAITools as bt, observeResponsesStream as c, buildOpenAISdkClientOptions as ct, AZURE_RESPONSES_TEXT_CONTENT_PART_TYPE as d, filterCodeModePayloadTools as dt, supportsResponsesReasoningUpdate as et, AZURE_RESPONSES_TEXT_DELTA_EVENT_TYPE as f, getCompat as ft, isAzureResponsesTextDeltaEventType as g, resolveOpenAIRequestReasoning as gt, isAzureResponsesTextDeltaEvent as h, resolveOpenAIStrictToolFlagWithDiagnostics as ht, convertResponsesToolPayload as i, resolveNewestOpenAIResponsesCompactionReplay as it, recordResponsesContextUsage as j, parseOpenAICompletionsUsage as jt, summarizeOpenAITransportError as k, log as kt, createResponsesToolCallTracker as l, buildOpenAISdkRequestOptions as lt, OPENAI_RESPONSES_OUTPUT_TEXT_DELTA_EVENT_TYPE as m, resolveCodeModeResponsesVisibleToolNames as mt, applyResponsesServiceTierPricing as n, buildOpenAIResponsesReasoningReplayMetadata as nt, readOpenAIMisalignmentReview as o, assertCodeModeResponsesToolSurface as ot, OPENAI_RESPONSES_OUTPUT_TEXT_CONTENT_PART_TYPE as p, readCodeModePayloadToolName as pt, OPENAI_RESPONSES_FUNCTION_CALL_ITEM_ID_RE as q, runResponsesStreamLifecycle as r, captureOpenAIResponsesCompaction as rt, processResponsesStream as s, buildOpenAIClientHeaders as st, applyCommonResponsesParams as t, CompactionReplayRefreshRequiredError as tt, readResponsesToolCallItemIdentity as u, enforceCodeModeResponsesToolSurface as ut, isResponsesTextDeltaEventType as v, resolveOpenAIReasoningEffortMap as vt, resolveAzureOpenAIApiVersion as w, GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP as wt, createResponsesStreamWithRecovery as x, reconcileOpenAICompletionsToolChoice as xt, resolveResponsesMessageSnapshotCollapse as y, prepareOpenAITools as yt, recordResponsesInputReplay as z };