@openclaw/ai 2026.9.8 → 2026.10.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +4 -1
  2. package/dist/{anthropic-CTXJlfnS.mjs → anthropic-CZv6XFER.mjs} +52 -147
  3. package/dist/{anthropic-payload-policy-NIPVYXPq.d.mts → anthropic-payload-policy-BhCcgNdm.d.mts} +7 -4
  4. package/dist/{anthropic-stream-reducer-DrsBCsFY.mjs → anthropic-stream-reducer-BQ1tjd7x.mjs} +369 -233
  5. package/dist/{api-registry-D-nbmSqr.d.mts → api-registry-DpU0Rj-I.d.mts} +4 -4
  6. package/dist/{provider-transcript-transform-DjA5Fk2P.mjs → assistant-output-OLm-Oln0.mjs} +17 -17
  7. package/dist/{assistant-text-phase-C20rxWwP.mjs → assistant-text-phase-Bl1aDCB7.mjs} +2 -8
  8. package/dist/{azure-openai-responses-BBxv4QVI.mjs → azure-openai-responses-DH7bd3QT.mjs} +12 -17
  9. package/dist/{azure-openai-responses-client-compat-C7K7QfUE.mjs → azure-openai-responses-client-compat-D0dvJMbZ.mjs} +3 -10
  10. package/dist/{base64-C1PsYcRQ.mjs → base64-C8CdcsjU.mjs} +3 -45
  11. package/dist/cloudflare-5qSGvIUH.mjs +39 -0
  12. package/dist/{diagnostics-CJaB6g8J.mjs → diagnostics-Caj-4RBA.mjs} +19 -37
  13. package/dist/diagnostics.d.mts +4 -4
  14. package/dist/diagnostics.mjs +2 -2
  15. package/dist/{event-stream-vd9UnCAU.mjs → event-stream-C5AbCAaZ.mjs} +29 -1
  16. package/dist/event-stream-DqDQWqiy.d.mts +1 -0
  17. package/dist/{event-stream-DOPFYVqs.d.mts → event-stream-DrRM_90c.d.mts} +1 -1
  18. package/dist/event-stream.d.mts +2 -2
  19. package/dist/event-stream.mjs +1 -1
  20. package/dist/{github-copilot-request-facts-BTEBMeOv.mjs → github-copilot-request-facts-DEE6gcB9.mjs} +3 -1
  21. package/dist/{google-B3HEK0Ag.mjs → google-1WLOtb8w.mjs} +12 -9
  22. package/dist/{google-interactions-vMlEfPAA.mjs → google-interactions-wrnE6MLw.mjs} +39 -49
  23. package/dist/{google-messages-Dz2dAnGo.mjs → google-messages-BwPPycw6.mjs} +11 -17
  24. package/dist/{google-shared-B58i3c8H.mjs → google-shared-Eql1OMPU.mjs} +5 -6
  25. package/dist/{google-vertex-DYFXzEbh.mjs → google-vertex-0LrlRoO3.mjs} +11 -11
  26. package/dist/{host-rxlNaBwm.d.mts → host-BinBeGcQ.d.mts} +12 -4
  27. package/dist/{host-DwBmNMCC.mjs → host-DCW52iHe.mjs} +57 -9
  28. package/dist/{host-policy-wK-ay_RK.mjs → host-policy-B3jc4Rpn.mjs} +9 -2
  29. package/dist/{index-D6KsSE74.d.mts → index-a8e_oKnu.d.mts} +7 -5
  30. package/dist/index.d.mts +23 -7
  31. package/dist/index.mjs +7 -7
  32. package/dist/internal/anthropic.d.mts +6 -6
  33. package/dist/internal/anthropic.mjs +5 -5
  34. package/dist/internal/google-model-family.mjs +1 -1
  35. package/dist/internal/openai-completions-compat.d.mts +1 -1
  36. package/dist/internal/openai-completions-compat.mjs +1 -1
  37. package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
  38. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  39. package/dist/internal/openai.d.mts +14 -10
  40. package/dist/internal/openai.mjs +12 -12
  41. package/dist/internal/runtime.d.mts +18 -9
  42. package/dist/internal/runtime.mjs +9 -9
  43. package/dist/internal/shared.d.mts +6 -4
  44. package/dist/internal/shared.mjs +6 -6
  45. package/dist/internal/tool-schema.mjs +1 -1
  46. package/dist/json-schema-Bp07Qui3.mjs +22 -0
  47. package/dist/{llm-request-activity-BjtkplhG.mjs → llm-request-activity-D8f_oxHj.mjs} +1 -2
  48. package/dist/{mistral-7wDWcjfF.mjs → mistral-DSt4vQAO.mjs} +18 -29
  49. package/dist/number-coercion-V8-BhME4.mjs +47 -0
  50. package/dist/{openai-chatgpt-responses-Bc7NZrQR.mjs → openai-chatgpt-responses-BC2x0Oqx.mjs} +215 -164
  51. package/dist/openai-completions-DNyHnXKg.mjs +25 -0
  52. package/dist/{openai-completions-compat-qJjmqQ71.d.mts → openai-completions-compat-BYdYpXhU.d.mts} +3 -3
  53. package/dist/{openai-completions-compat-BJf57ZxN.mjs → openai-completions-compat-BdmlhD4u.mjs} +30 -23
  54. package/dist/{openai-completions-stream-dju_5F3P.mjs → openai-completions-transport-DWM2mQDB.mjs} +389 -76
  55. package/dist/{openai-prompt-cache-CouErLh7.d.mts → openai-prompt-cache-45-AH_xv.d.mts} +2 -2
  56. package/dist/{openai-prompt-cache-BTMs80_O.mjs → openai-prompt-cache-I8YQTzf8.mjs} +1 -1
  57. package/dist/{openai-responses-compaction-replay-DiYn-gFM.d.mts → openai-responses-compaction-replay-BClApUIf.d.mts} +4 -4
  58. package/dist/{openai-responses-compaction-window-CYGCjAQz.mjs → openai-responses-compaction-window-m878aVpU.mjs} +25 -83
  59. package/dist/{openai-reasoning-effort-C_0p3psG.mjs → openai-responses-contracts-BKu8O7l4.mjs} +103 -4
  60. package/dist/{openai-responses-contracts-D1iZ0njF.d.mts → openai-responses-contracts-Br5IIw_h.d.mts} +16 -5
  61. package/dist/openai-responses-prompt-observer-internal-CCg7B6l4.mjs +32 -0
  62. package/dist/{openai-responses-shared-CIEHiKx7.mjs → openai-responses-shared-C7oVyjED.mjs} +297 -312
  63. package/dist/{openai-responses-terminal-usage-BE7lf7nW.d.mts → openai-responses-terminal-usage-DgImcyJu.d.mts} +2 -2
  64. package/dist/{openai-responses-DbPe3-Py.mjs → openai-responses-uZ5oWSp7.mjs} +12 -21
  65. package/dist/{openai-tool-schema-vsl-cE-n.mjs → openai-tool-schema-DYNePiF8.mjs} +66 -36
  66. package/dist/{openai-transport-params-DyFJ4cgR.mjs → openai-transport-params-JFsnIyto.mjs} +25 -30
  67. package/dist/openai-web-search-tools-Cfu0uLyN.mjs +14 -0
  68. package/dist/{positive-integer-CjN5OJbH.mjs → positive-integer-CwLi8LUL.mjs} +1 -1
  69. package/dist/{provider-error-CwT_j2v0.mjs → provider-error-DQBE1bUQ.mjs} +17 -28
  70. package/dist/{provider-options-Df7ov0K1.d.mts → provider-options-D5ABCV_l.d.mts} +2 -2
  71. package/dist/{provider-replay-context-Bs5aWE1d.mjs → provider-replay-context-C7Bmi84a.mjs} +6 -2
  72. package/dist/{provider-transport-turn-state-Dw7OtYUs.mjs → provider-transport-turn-state-_M2kLdUE.mjs} +25 -3
  73. package/dist/{provider-types-d4XnoZMd.d.mts → provider-types-F8Mqc9Ma.d.mts} +3 -3
  74. package/dist/provider-types.d.mts +6 -6
  75. package/dist/providers.d.mts +2 -2
  76. package/dist/providers.mjs +14 -26
  77. package/dist/{reasoning-tag-text-partitioner-B6FIIBt6.mjs → reasoning-tag-text-partitioner-Ju9VpUGl.mjs} +23 -37
  78. package/dist/required-api-key-D4kn3252.mjs +9 -0
  79. package/dist/sanitize-unicode-CjDG6jJx.d.mts +5 -0
  80. package/dist/{session-affinity-Bcunsn4I.mjs → session-affinity-DA4WHv1h.mjs} +2 -6
  81. package/dist/session-resources-D1wgDQ8C.mjs +40 -0
  82. package/dist/{simple-options-BkDPMuxw.mjs → simple-options-BkKTXxhp.mjs} +7 -11
  83. package/dist/{src-H4aXcFuX.mjs → src-B0NIt2UK.mjs} +7 -4
  84. package/dist/stream-DSdzKsDK.mjs +275 -0
  85. package/dist/{stream-first-event-timeout-B9o0S4SZ.mjs → stream-first-event-timeout-D9ZmL_s9.mjs} +3 -3
  86. package/dist/{string-coerce-fsri9iCu.mjs → string-coerce-CtgOVOSv.mjs} +5 -1
  87. package/dist/{string-normalization-J9ZiLfGO.mjs → string-normalization-PN10hf6d.mjs} +1 -1
  88. package/dist/{transport-utils-CqXzku3R.mjs → text-signature-MLwfi6fq.mjs} +18 -18
  89. package/dist/{transport-stream-shared-yYhXa4kX.d.mts → transport-stream-shared-BcAKh2XH.d.mts} +6 -19
  90. package/dist/{transport-stream-shared-BU5pwY6W.mjs → transport-stream-shared-CxXXz_Dd.mjs} +171 -56
  91. package/dist/transports.d.mts +22 -23
  92. package/dist/transports.mjs +251 -495
  93. package/dist/types-BuiEBM3u.d.mts +1 -0
  94. package/dist/types-CQc6JNG4.mjs +69 -0
  95. package/dist/{types-CLLR3eB4.d.mts → types-DvzmWW8J.d.mts} +58 -6
  96. package/dist/types.d.mts +6 -6
  97. package/dist/types.mjs +5 -5
  98. package/dist/usage-CJH5D6Ea.mjs +19 -0
  99. package/dist/{validation-Cat2wQsc.d.mts → validation-B3lQt_VE.d.mts} +1 -1
  100. package/dist/{validation-BFZc40Ig.mjs → validation-DbqlIfDn.mjs} +15 -30
  101. package/dist/validation.d.mts +1 -1
  102. package/dist/validation.mjs +1 -1
  103. package/package.json +4 -4
  104. package/dist/cache-retention-0x979a5V.mjs +0 -12
  105. package/dist/event-stream-CMQfX_yr.d.mts +0 -1
  106. package/dist/github-copilot-headers-B37TB3rB.mjs +0 -30
  107. package/dist/openai-completions-CHnwIV-W.mjs +0 -188
  108. package/dist/openai-provider-client-G8Otsq2Q.mjs +0 -24
  109. package/dist/openai-responses-contracts-CLxnqS9p.mjs +0 -81
  110. package/dist/openai-responses-prompt-observer-internal-BX3QTNSv.mjs +0 -198
  111. package/dist/sanitize-unicode-BZiVbGwK.d.mts +0 -24
  112. package/dist/session-resources-CkR4WWy1.mjs +0 -21
  113. package/dist/stream-DDsCBgd-.mjs +0 -68
  114. package/dist/types-CB-_vNyI.d.mts +0 -1
  115. package/dist/types-LFWwv0cF.mjs +0 -8
@@ -1,28 +1,35 @@
1
- import { r as appendAssistantThinking } from "./event-stream-vd9UnCAU.mjs";
1
+ import { _ as runtimeContextContentToText, f as hasRuntimeContextMarker, p as isRuntimeContextMessage } from "./types-CQc6JNG4.mjs";
2
+ import { r as appendAssistantThinking } from "./event-stream-C5AbCAaZ.mjs";
2
3
  import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
3
- import { k as isImageWithMediaPayload, n as getAiTransportHost } from "./host-DwBmNMCC.mjs";
4
- import { n as isOpenAIGpt55Model, r as isOpenAIGpt56Model, t as isOpenAIGpt54MiniModel } from "./openai-reasoning-effort-C_0p3psG.mjs";
5
- import { r as uniqueStrings } from "./string-normalization-J9ZiLfGO.mjs";
6
- import { o as truncateUtf16Safe } from "./provider-error-CwT_j2v0.mjs";
7
- import { r as resolveOpenAIPromptCacheParams } from "./openai-prompt-cache-BTMs80_O.mjs";
8
- import { r as emitModelTransportDebug } from "./diagnostics-CJaB6g8J.mjs";
9
- import { i as asNonNegativeFiniteNumber } from "./base64-C1PsYcRQ.mjs";
10
- import { c as supportsModelTools, r as estimateStringChars } from "./transport-utils-CqXzku3R.mjs";
11
- import { c as shouldOmitOllamaCompatResponseFormat, n as isNativeOpenAIEndpoint, s as resolveOpenAICompletionsResponseFormat, t as detectOpenAICompletionsCompat } from "./openai-completions-compat-BJf57ZxN.mjs";
12
- import { r as resolveProviderEndpoint } from "./host-policy-wK-ay_RK.mjs";
13
- import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
14
- import { E as createToolArgumentPreviewSchedule, O as parseStreamingJson, d as iterateModelStream, j as sanitizeSurrogates, l as finalizeTerminalToolCallArguments, y as throwIfModelStreamAborted } from "./transport-stream-shared-BU5pwY6W.mjs";
15
- import { C as stripSystemPromptCacheBoundary, D as sortPromptCacheToolsByName, S as splitSystemPromptRelocatableBoundary, d as describeToolResultMediaPlaceholder, m as extractToolResultText, w as stripSystemPromptRelocatableBoundary, x as splitSystemPromptCacheBoundary } from "./simple-options-BkDPMuxw.mjs";
16
- import { C as log, D as readOpenAICompletionsReasoningBatch, E as readOpenAICompletionsContentDeltas, S as isOpenAICompletionsThinkingEnabled, T as parseOpenAICompletionsUsage, d as prepareOpenAITools, f as projectOpenAITools, g as resolveOpenAISimpleReasoningEffort, h as resolveOpenAIRequestReasoning, k as resolvePromptCacheKey, p as reconcileOpenAICompletionsToolChoice, s as getCompat, u as resolveOpenAIStrictToolFlagWithDiagnostics, v as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, w as measureUtf8AppendBytes } from "./openai-transport-params-DyFJ4cgR.mjs";
17
- import { a as tagUnresolvedTextAsCommentary, i as tagPendingCommentaryText, n as rememberPendingCommentaryTags, r as tagInterruptedTextPhases, t as clearPendingCommentaryText } from "./assistant-text-phase-C20rxWwP.mjs";
18
- import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
19
- import { t as transformProviderMessages } from "./provider-transcript-transform-DjA5Fk2P.mjs";
20
- import { a as withFirstStreamEventTimeout } from "./stream-first-event-timeout-B9o0S4SZ.mjs";
21
- import { f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-vsl-cE-n.mjs";
22
- import { isGoogleGemini3FlashModel, isGoogleGemini3ProModel } from "./internal/google-model-family.mjs";
4
+ import { s as readNonEmptyStringPreservingWhitespace, t as hasNonEmptyString } from "./string-coerce-CtgOVOSv.mjs";
5
+ import { n as asNonNegativeFiniteNumber } from "./number-coercion-V8-BhME4.mjs";
6
+ import { N as isImageWithMediaPayload, r as getAiTransportHost } from "./host-DCW52iHe.mjs";
7
+ import { _ as isOpenAIGpt54MiniModel, v as isOpenAIGpt55Model, y as isOpenAIGpt56Model } from "./openai-responses-contracts-BKu8O7l4.mjs";
8
+ import { r as uniqueStrings } from "./string-normalization-PN10hf6d.mjs";
9
+ import { o as truncateUtf16Safe } from "./provider-error-DQBE1bUQ.mjs";
10
+ import { r as resolveOpenAIPromptCacheParams } from "./openai-prompt-cache-I8YQTzf8.mjs";
11
+ import { r as emitModelTransportDebug } from "./diagnostics-Caj-4RBA.mjs";
12
+ import { c as supportsModelTools, r as estimateStringChars } from "./text-signature-MLwfi6fq.mjs";
13
+ import { i as resolveOpenAICompletionsCompat, l as shouldOmitOllamaCompatResponseFormat, n as isNativeOpenAIEndpoint, s as resolveOpenAICompletionsResponseFormat, t as detectOpenAICompletionsCompat } from "./openai-completions-compat-BdmlhD4u.mjs";
14
+ import { i as resolveProviderEndpoint, t as buildGuardedModelFetch } from "./host-policy-B3jc4Rpn.mjs";
15
+ import { i as resolveCacheRetention, r as buildCopilotDynamicHeaders } from "./cloudflare-5qSGvIUH.mjs";
16
+ import { E as createToolArgumentPreviewSchedule, O as parseStreamingJson, P as sanitizeSurrogates, S as withProviderResponseHook, _ as sanitizeNonEmptyTransportPayloadText, b as transportAbortError, c as failTransportStream, d as iterateModelStream, l as finalizeTerminalToolCallArguments, s as createWritableTransportEventStream, u as finalizeTransportStream, y as throwIfModelStreamAborted } from "./transport-stream-shared-CxXXz_Dd.mjs";
17
+ import { C as stripSystemPromptCacheBoundary, D as sortPromptCacheToolsByName, S as splitSystemPromptRelocatableBoundary, d as describeToolResultMediaPlaceholder, l as codeModeToolSurfaceObserver, m as extractToolResultText, s as prepareModelRequestBody, u as reasoningTagTextPolicy, w as stripSystemPromptRelocatableBoundary, x as splitSystemPromptCacheBoundary } from "./simple-options-BkKTXxhp.mjs";
18
+ import { C as log, D as readOpenAICompletionsReasoningBatch, E as readOpenAICompletionsContentDeltas, O as resolveOpenAIClientBaseUrl, S as isOpenAICompletionsThinkingEnabled, T as parseOpenAICompletionsUsage, a as enforceCodeModeResponsesToolSurface, d as prepareOpenAITools, f as projectOpenAITools, g as resolveOpenAISimpleReasoningEffort, h as resolveOpenAIRequestReasoning, i as buildOpenAISdkRequestOptions, k as resolvePromptCacheKey, l as resolveCodeModeResponsesVisibleToolNames, n as buildOpenAIClientHeaders, p as reconcileOpenAICompletionsToolChoice, r as buildOpenAISdkClientOptions, s as getCompat, t as assertCodeModeResponsesToolSurface, u as resolveOpenAIStrictToolFlagWithDiagnostics, v as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, w as measureUtf8AppendBytes, y as createOpenAIProviderAcceptanceHook } from "./openai-transport-params-JFsnIyto.mjs";
19
+ import { n as getEnvApiKey } from "./env-api-keys-CyX4VKGO.mjs";
20
+ import { n as transformProviderMessages, t as createAssistantOutput } from "./assistant-output-OLm-Oln0.mjs";
21
+ import { a as tagUnresolvedTextAsCommentary, i as tagPendingCommentaryText, n as rememberPendingCommentaryTags, r as tagInterruptedTextPhases, t as clearPendingCommentaryText } from "./assistant-text-phase-Bl1aDCB7.mjs";
22
+ import { t as notifyLlmRequestActivity } from "./llm-request-activity-D8f_oxHj.mjs";
23
+ import { n as resolveOpencodeSessionHeaders } from "./session-affinity-DA4WHv1h.mjs";
24
+ import "./types.mjs";
25
+ import { i as createOpenAIProviderClient, n as resolveProviderSimpleCompletionHeaders, r as resolveProviderTransportTurnState, t as filterProviderTurnHeadersForExplicitOpencodeSession } from "./provider-transport-turn-state-_M2kLdUE.mjs";
26
+ import { a as withFirstStreamEventTimeout, i as getFirstStreamEventTimeoutMs, r as getFirstStreamEventTimeoutHandler, t as createFirstStreamEventAbortController } from "./stream-first-event-timeout-D9ZmL_s9.mjs";
27
+ import { f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-DYNePiF8.mjs";
28
+ import { isGoogleGemini3ThinkingLevelModel } from "./internal/google-model-family.mjs";
23
29
  import { t as mapOpenAIStopReason } from "./openai-stop-reason-8s70vDXj.mjs";
24
- import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-B6FIIBt6.mjs";
30
+ import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-Ju9VpUGl.mjs";
25
31
  import { randomUUID } from "node:crypto";
32
+ import OpenAI from "openai";
26
33
  //#region packages/ai/src/transports/deepseek-dsml-grammar.ts
27
34
  const DEEPSEEK_DSML_MARKERS = [
28
35
  "|",
@@ -152,6 +159,34 @@ function canonicalizeMaxTokensParam(params) {
152
159
  params.merged.maxTokens = resolved;
153
160
  }
154
161
  //#endregion
162
+ //#region packages/ai/src/transports/openai-compatible-conversation-turn.ts
163
+ function hasNonEmptyContentPart(part) {
164
+ if (!part || typeof part !== "object") return false;
165
+ const record = part;
166
+ if (record.type === "text") return hasNonEmptyString(record.text);
167
+ return true;
168
+ }
169
+ function hasNonEmptyMessageContent(content) {
170
+ if (hasNonEmptyString(content)) return true;
171
+ if (!Array.isArray(content)) return false;
172
+ return content.some(hasNonEmptyContentPart);
173
+ }
174
+ /** Returns whether an OpenAI-compatible messages payload contains a usable turn. */
175
+ function hasOpenAICompatibleConversationTurn(messages) {
176
+ if (!Array.isArray(messages)) return false;
177
+ return messages.some((message) => {
178
+ if (!message || typeof message !== "object") return false;
179
+ const record = message;
180
+ if (record.role === "user") return hasNonEmptyMessageContent(record.content);
181
+ if (record.role === "assistant") {
182
+ if (hasNonEmptyMessageContent(record.content)) return true;
183
+ const toolCalls = record.tool_calls;
184
+ return Array.isArray(toolCalls) && toolCalls.some((toolCall) => toolCall && typeof toolCall === "object");
185
+ }
186
+ return false;
187
+ });
188
+ }
189
+ //#endregion
155
190
  //#region packages/ai/src/transports/openai-completions-cache-control.ts
156
191
  const shapedPayloads = /* @__PURE__ */ new WeakSet();
157
192
  function resolveCompletionsCacheControl(compat, retention, openRouterRoute) {
@@ -307,21 +342,16 @@ function createOpenAICompletionsToolCallDeltaNormalizer() {
307
342
  pendingFollowingDeltaBytes += nextDeltaBytes;
308
343
  pendingFollowingDeltas.push(delta);
309
344
  };
310
- const withoutToolCalls = (delta) => {
311
- const ordinaryDelta = { ...delta };
312
- delete ordinaryDelta.function_call;
313
- delete ordinaryDelta.tool_calls;
314
- return ordinaryDelta;
315
- };
316
345
  const hasObservableContent = (value) => {
317
346
  if (typeof value === "string") return value.length > 0;
318
347
  if (Array.isArray(value)) return value.some(hasObservableContent);
319
348
  if (isRecord(value)) return Object.entries(value).some(([field, nestedValue]) => field !== "type" && field !== "id" && field !== "index" && hasObservableContent(nestedValue));
320
349
  return false;
321
350
  };
322
- const hasOrdinaryContent = (delta) => Object.entries(delta).some(([field, value]) => field !== "role" && hasObservableContent(value));
323
351
  return (delta, finishReason) => {
324
- const ordinaryDelta = withoutToolCalls(delta);
352
+ const ordinaryDelta = { ...delta };
353
+ delete ordinaryDelta.function_call;
354
+ delete ordinaryDelta.tool_calls;
325
355
  if (delta.tool_calls && delta.tool_calls.length > 0) {
326
356
  for (const toolCall of delta.tool_calls) {
327
357
  const index = typeof toolCall.index === "number" ? toolCall.index : void 0;
@@ -353,7 +383,7 @@ function createOpenAICompletionsToolCallDeltaNormalizer() {
353
383
  }];
354
384
  const hadPendingLegacyCall = pendingLegacyToolCall !== void 0;
355
385
  const leadingDeltas = [];
356
- if (hasOrdinaryContent(ordinaryDelta)) {
386
+ if (Object.entries(ordinaryDelta).some(([field, value]) => field !== "role" && hasObservableContent(value))) {
357
387
  if (hadPendingLegacyCall) bufferFollowingDelta(ordinaryDelta);
358
388
  else leadingDeltas.push({
359
389
  delta: ordinaryDelta,
@@ -449,11 +479,6 @@ function isAzureOpenAICompatibleHost(hostname) {
449
479
  }
450
480
  //#endregion
451
481
  //#region packages/ai/src/openai-completions-messages.ts
452
- const EMPTY_TOOL_RESULT_TEXT = "(no output)";
453
- function sanitizeToolResultText(text, fallback) {
454
- const sanitized = sanitizeSurrogates(text);
455
- return sanitized.trim().length > 0 ? sanitized : fallback;
456
- }
457
482
  /** Whether replayed messages require a tools marker for proxy compatibility. */
458
483
  function hasToolCallHistory(messages) {
459
484
  return messages.some((message) => message.role === "toolResult" || message.role === "assistant" && Array.isArray(message.content) && message.content.some((block) => block.type === "toolCall"));
@@ -492,7 +517,13 @@ function convertMessages(model, context, compat, options = {}) {
492
517
  role: "assistant",
493
518
  content: "I have processed the tool results."
494
519
  });
495
- if (msg.role === "user") {
520
+ if (isRuntimeContextMessage(msg)) {
521
+ params.push({
522
+ role: model.reasoning && compat.supportsDeveloperRole ? "developer" : "system",
523
+ content: sanitizeSurrogates(runtimeContextContentToText(msg.content))
524
+ });
525
+ options.cacheOptOutIndexes?.add(params.length - 1);
526
+ } else if (msg.role === "user") {
496
527
  let userParam;
497
528
  if (typeof msg.content === "string") userParam = {
498
529
  role: "user",
@@ -519,7 +550,7 @@ function convertMessages(model, context, compat, options = {}) {
519
550
  content
520
551
  };
521
552
  }
522
- if (msg.runtimeContextCarrier === true) options.cacheOptOutIndexes?.add(params.length);
553
+ if (hasRuntimeContextMarker(msg)) options.cacheOptOutIndexes?.add(params.length);
523
554
  params.push(userParam);
524
555
  } else if (msg.role === "assistant") {
525
556
  const assistantMsg = {
@@ -586,7 +617,7 @@ function convertMessages(model, context, compat, options = {}) {
586
617
  const images = toolMsg.content.filter(isImageWithMediaPayload);
587
618
  const toolResultMsg = {
588
619
  role: "tool",
589
- content: sanitizeToolResultText(textResult, mediaPlaceholder ?? EMPTY_TOOL_RESULT_TEXT),
620
+ content: sanitizeNonEmptyTransportPayloadText(textResult, mediaPlaceholder),
590
621
  tool_call_id: toolMsg.toolCallId
591
622
  };
592
623
  if (compat.requiresToolResultName && toolMsg.toolName) toolResultMsg.name = toolMsg.toolName;
@@ -660,11 +691,9 @@ function applyDirectCompletionsReasoningAndRouting(params, model, reasoning, com
660
691
  enable_thinking: reasoningEnabled,
661
692
  preserve_thinking: true
662
693
  };
663
- else if (compat.thinkingFormat === "deepseek" && model.reasoning) {
664
- params.thinking = { type: reasoningEnabled ? "enabled" : "disabled" };
665
- if (reasoningEnabled && compat.supportsReasoningEffort && nativeEffort !== void 0) params.reasoning_effort = nativeEffort;
666
- } else if (compat.thinkingFormat === "together" && model.reasoning) {
667
- params.reasoning = { enabled: reasoningEnabled };
694
+ else if ((compat.thinkingFormat === "deepseek" || compat.thinkingFormat === "together") && model.reasoning) {
695
+ if (compat.thinkingFormat === "deepseek") params.thinking = { type: reasoningEnabled ? "enabled" : "disabled" };
696
+ else params.reasoning = { enabled: reasoningEnabled };
668
697
  if (reasoningEnabled && compat.supportsReasoningEffort && nativeEffort !== void 0) params.reasoning_effort = nativeEffort;
669
698
  } else if (model.reasoning && compat.supportsReasoningEffort && nativeEffort !== void 0) params.reasoning_effort = nativeEffort;
670
699
  if (compat.openRouterRouting) params.provider = compat.openRouterRouting;
@@ -684,9 +713,6 @@ function isGoogleOpenAICompatModel(model) {
684
713
  const endpointClass = detectOpenAICompletionsCompat(model).capabilities.endpointClass;
685
714
  return model.provider === "google" || endpointClass === "google-generative-ai" || endpointClass === "google-vertex";
686
715
  }
687
- function requiresGoogleCompatToolCallThoughtSignature(model) {
688
- return isGoogleGemini3ProModel(model.id) || isGoogleGemini3FlashModel(model.id);
689
- }
690
716
  const GOOGLE_COMPAT_THOUGHT_SIGNATURE_ELLIPSIS_RE = /[\u2026]|\.\.\./;
691
717
  const GOOGLE_COMPAT_THOUGHT_SIGNATURE_BASE64_RE = /^[A-Za-z0-9+/=]+$/;
692
718
  function hasGoogleCompatThoughtSignatureTruncationFootprint(value) {
@@ -695,17 +721,16 @@ function hasGoogleCompatThoughtSignatureTruncationFootprint(value) {
695
721
  function injectToolCallThoughtSignatures(outgoingMessages, context, model) {
696
722
  if (!isGoogleOpenAICompatModel(model)) return;
697
723
  const sigById = /* @__PURE__ */ new Map();
698
- const fallbackSig = requiresGoogleCompatToolCallThoughtSignature(model) ? GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP : void 0;
724
+ const fallbackSig = isGoogleGemini3ThinkingLevelModel(model.id) ? GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP : void 0;
699
725
  for (const msg of context.messages ?? []) {
700
726
  if (msg.role !== "assistant") continue;
701
- const source = msg;
702
- if (!Array.isArray(source.content)) continue;
703
- for (const block of source.content) {
727
+ if (!Array.isArray(msg.content)) continue;
728
+ for (const block of msg.content) {
704
729
  if (block.type !== "toolCall") continue;
705
730
  const id = block.id;
706
731
  const sig = block.thoughtSignature;
707
732
  if (typeof id === "string" && typeof sig === "string" && sig.length > 0) {
708
- const isSameRoute = source.api === model.api && source.provider === model.provider && source.model === model.id;
733
+ const isSameRoute = msg.api === model.api && msg.provider === model.provider && msg.model === model.id;
709
734
  if (!isSameRoute && !fallbackSig) continue;
710
735
  sigById.set(id, isSameRoute ? sig : fallbackSig ?? sig);
711
736
  }
@@ -738,7 +763,7 @@ const COMPLETIONS_REASONING_REPLAY_FIELDS = [
738
763
  "reasoning_text"
739
764
  ];
740
765
  function stripCompletionsReasoningReplayFields(record) {
741
- for (const field of COMPLETIONS_REASONING_REPLAY_FIELDS) if (field in record) delete record[field];
766
+ for (const field of COMPLETIONS_REASONING_REPLAY_FIELDS) delete record[field];
742
767
  }
743
768
  function sanitizeOpenRouterReasoningReplayFields(record) {
744
769
  const reasoningDetails = record.reasoning_details;
@@ -746,11 +771,10 @@ function sanitizeOpenRouterReasoningReplayFields(record) {
746
771
  if (reasoningDetails.length > 0 && typeof record.reasoning !== "string") record.reasoning = reasoningDetails;
747
772
  delete record.reasoning_details;
748
773
  } else if (reasoningDetails !== void 0 && !Array.isArray(reasoningDetails)) delete record.reasoning_details;
749
- if ("reasoning" in record && (typeof record.reasoning !== "string" || record.reasoning === "")) delete record.reasoning;
750
- if ("reasoning_content" in record && (typeof record.reasoning_content !== "string" || record.reasoning_content === "")) delete record.reasoning_content;
774
+ for (const field of ["reasoning", "reasoning_content"]) if (field in record && (typeof record[field] !== "string" || record[field] === "")) delete record[field];
751
775
  const reasoningText = record.reasoning_text;
752
776
  if (typeof reasoningText === "string" && reasoningText.length > 0 && typeof record.reasoning !== "string" && typeof record.reasoning_content !== "string") record.reasoning = reasoningText;
753
- if ("reasoning_text" in record) delete record.reasoning_text;
777
+ delete record.reasoning_text;
754
778
  }
755
779
  function sanitizeReasoningContentReplayFields(record) {
756
780
  if ("reasoning_content" in record && typeof record.reasoning_content !== "string") delete record.reasoning_content;
@@ -795,10 +819,7 @@ function getReasoningContentReplayModelIdCandidates(modelId) {
795
819
  const candidates = [finalPart];
796
820
  const colonParts = finalPart.split(":").filter(Boolean);
797
821
  if (colonParts.length > 1) candidates.push(colonParts[0] ?? "", colonParts[colonParts.length - 1] ?? "");
798
- const baseCount = candidates.length;
799
- for (let index = 0; index < baseCount; index += 1) {
800
- const candidate = candidates[index];
801
- if (typeof candidate !== "string") continue;
822
+ for (const candidate of candidates.slice()) {
802
823
  const stripped = stripReasoningContentReplayTierSuffix(candidate);
803
824
  if (stripped !== candidate) candidates.push(stripped);
804
825
  }
@@ -842,11 +863,8 @@ function isKnownOpenAICompletionsEndpoint(model) {
842
863
  if (!model.baseUrl.trim() || isNativeOpenAIEndpoint(model)) return true;
843
864
  const endpointClass = resolveProviderEndpoint(model).endpointClass;
844
865
  if (endpointClass === "openai-public" || endpointClass === "azure-openai") return true;
845
- try {
846
- return isAzureOpenAICompatibleHost(new URL(model.baseUrl).hostname.toLowerCase());
847
- } catch {
848
- return false;
849
- }
866
+ const endpoint = URL.parse(model.baseUrl);
867
+ return endpoint !== null && isAzureOpenAICompatibleHost(endpoint.hostname.toLowerCase());
850
868
  }
851
869
  function resolveOpenAICompletionsMaxTokens(model, options) {
852
870
  if (options?.maxTokens) return {
@@ -1262,8 +1280,16 @@ function parseDeepSeekDsmlInvokeArguments(body) {
1262
1280
  const name = parseDsmlNameAttribute(parameterMatch[2] ?? "");
1263
1281
  if (!name) continue;
1264
1282
  const rawValue = parameterMatch[3] ?? "";
1265
- if (rawValue.length === 0) continue;
1266
- args[name] = decodeDeepSeekDsmlText(rawValue);
1283
+ if (rawValue.length === 0) {
1284
+ const stringAttribute = Array.from((parameterMatch[2] ?? "").matchAll(/(?:^|\s)([^\s=]+)=(?:"([^"]*)"|'([^']*)'|([^\s"']+))(?=\s|$)/g)).find((attribute) => attribute[1] === "string");
1285
+ if ((stringAttribute?.[2] ?? stringAttribute?.[3] ?? stringAttribute?.[4]) !== "true") continue;
1286
+ }
1287
+ Object.defineProperty(args, name, {
1288
+ value: decodeDeepSeekDsmlText(rawValue),
1289
+ enumerable: true,
1290
+ configurable: true,
1291
+ writable: true
1292
+ });
1267
1293
  }
1268
1294
  if (Object.keys(args).length > 0) return args;
1269
1295
  const trimmed = body.trim();
@@ -1361,12 +1387,8 @@ function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
1361
1387
  function extractToolCallThoughtSignature(toolCall) {
1362
1388
  const tc = toolCall;
1363
1389
  if (!tc) return;
1364
- const fromExtra = (tc.extra_content?.google)?.thought_signature;
1365
- if (typeof fromExtra === "string" && fromExtra.length > 0) return fromExtra;
1366
- const fromFunction = tc.function?.thought_signature;
1367
- if (typeof fromFunction === "string" && fromFunction.length > 0) return fromFunction;
1368
- const fromToolCall = tc.thought_signature;
1369
- return typeof fromToolCall === "string" && fromToolCall.length > 0 ? fromToolCall : void 0;
1390
+ const extra = tc.extra_content?.google;
1391
+ return readNonEmptyStringPreservingWhitespace(extra?.thought_signature) ?? readNonEmptyStringPreservingWhitespace(tc.function?.thought_signature) ?? readNonEmptyStringPreservingWhitespace(tc.thought_signature);
1370
1392
  }
1371
1393
  async function processCompletionsStream(responseStream, output, model, stream, options) {
1372
1394
  const MAX_POST_TOOL_CALL_BUFFER_BYTES = 256e3;
@@ -1757,12 +1779,303 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1757
1779
  function shouldEmitOpenAICompletionsReasoning(model, options) {
1758
1780
  if (!model.reasoning) return false;
1759
1781
  const effort = options?.reasoningEffort ?? options?.reasoning ?? "high";
1760
- if (!effort || !isOpenAICompletionsThinkingEnabled(effort)) return false;
1761
- return true;
1782
+ return Boolean(effort) && isOpenAICompletionsThinkingEnabled(effort);
1762
1783
  }
1763
1784
  function hasOpenAICompletionsReasoningUsageActivity(rawUsage) {
1764
1785
  const reasoningTokens = rawUsage.completion_tokens_details?.reasoning_tokens;
1765
1786
  return typeof reasoningTokens === "number" && Number.isFinite(reasoningTokens) && reasoningTokens > 0;
1766
1787
  }
1767
1788
  //#endregion
1768
- export { convertMessages as a, flattenCompletionMessagesToStringContent as c, canonicalizeMaxTokensParam as d, resolveMaxTokensParam as f, buildOpenAICompletionsRequest as i, stripCompletionMessagesToRoleContent as l, shouldEmitOpenAICompletionsReasoning as n, isAzureOpenAICompatibleHost as o, createDeepSeekTextFilter as p, buildOpenAICompletionsParams as r, finalizeOpenAICompletionsToolCalls as s, processCompletionsStream as t, applyCompletionsAnthropicCacheControl as u };
1789
+ //#region packages/ai/src/transports/openai-completions-transport.ts
1790
+ function assertOpenAICompletionsPayloadHasConversationTurn(params, model) {
1791
+ const messages = params.messages;
1792
+ if (!Array.isArray(messages) || hasOpenAICompatibleConversationTurn(messages)) return;
1793
+ throw new Error(`OpenAI-compatible chat payload for ${model.provider}/${model.id} contains no non-empty user or assistant messages after compaction and transport transforms; refusing to send a system/tool-only request. Start a new user turn or repair the compacted session history.`);
1794
+ }
1795
+ const SSE_DONE_LINE_RE = /^data:[ \t]*\[DONE\][ \t]*$/i;
1796
+ const SSE_DONE_MAX_LINE_CHARS = 1024;
1797
+ function createSseDoneDetector() {
1798
+ const decoder = new TextDecoder();
1799
+ let line = "";
1800
+ let lineOverflowed = false;
1801
+ let sawDone = false;
1802
+ const finishLine = () => {
1803
+ if (!lineOverflowed && SSE_DONE_LINE_RE.test(line)) sawDone = true;
1804
+ line = "";
1805
+ lineOverflowed = false;
1806
+ };
1807
+ const observeText = (text) => {
1808
+ for (const char of text) {
1809
+ if (char === "\n" || char === "\r") {
1810
+ finishLine();
1811
+ continue;
1812
+ }
1813
+ if (!lineOverflowed && line.length < SSE_DONE_MAX_LINE_CHARS) line += char;
1814
+ else lineOverflowed = true;
1815
+ }
1816
+ };
1817
+ return {
1818
+ observe(chunk) {
1819
+ if (!sawDone) observeText(decoder.decode(chunk, { stream: true }));
1820
+ },
1821
+ finish() {
1822
+ if (sawDone) return;
1823
+ observeText(decoder.decode());
1824
+ if (line || lineOverflowed) finishLine();
1825
+ },
1826
+ sawDone: () => sawDone
1827
+ };
1828
+ }
1829
+ function buildOpenAICompletionsClientConfig(model, headers) {
1830
+ const defaultQuery = {};
1831
+ let baseURL = model.baseUrl;
1832
+ let isAzureHost = false;
1833
+ const parsed = URL.parse(model.baseUrl);
1834
+ if (parsed) {
1835
+ isAzureHost = isAzureOpenAICompatibleHost(parsed.hostname.toLowerCase());
1836
+ parsed.searchParams.forEach((value, key) => {
1837
+ if (value) defaultQuery[key] = value;
1838
+ });
1839
+ parsed.search = "";
1840
+ baseURL = parsed.toString().replace(/\/$/, "");
1841
+ }
1842
+ if (isAzureHost) {
1843
+ const apiVersionHeader = Object.keys(headers).find((key) => key.toLowerCase() === "api-version");
1844
+ if (apiVersionHeader) {
1845
+ const apiVersion = headers[apiVersionHeader]?.trim();
1846
+ delete headers[apiVersionHeader];
1847
+ if (apiVersion && !defaultQuery["api-version"]) defaultQuery["api-version"] = apiVersion;
1848
+ }
1849
+ }
1850
+ return {
1851
+ baseURL: resolveOpenAIClientBaseUrl(model, baseURL),
1852
+ defaultHeaders: headers,
1853
+ defaultQuery: Object.keys(defaultQuery).length > 0 ? defaultQuery : void 0
1854
+ };
1855
+ }
1856
+ function createDirectCompletionsEventStream(output, stream) {
1857
+ const finishedBlocks = /* @__PURE__ */ new Set();
1858
+ const contentIndices = /* @__PURE__ */ new WeakMap();
1859
+ let openTextBlock;
1860
+ let openThinkingBlock;
1861
+ const finishBlock = (block) => {
1862
+ const contentIndex = contentIndices.get(block);
1863
+ if (contentIndex === void 0 || finishedBlocks.has(block)) return;
1864
+ finishedBlocks.add(block);
1865
+ if (block.type === "text") {
1866
+ openTextBlock = void 0;
1867
+ stream.push({
1868
+ type: "text_end",
1869
+ contentIndex,
1870
+ content: block.text,
1871
+ partial: output
1872
+ });
1873
+ } else if (block.type === "thinking") {
1874
+ openThinkingBlock = void 0;
1875
+ stream.push({
1876
+ type: "thinking_end",
1877
+ contentIndex,
1878
+ content: block.thinking,
1879
+ partial: output
1880
+ });
1881
+ } else if (block.type === "toolCall") stream.push({
1882
+ type: "toolcall_end",
1883
+ contentIndex,
1884
+ toolCall: block,
1885
+ partial: output
1886
+ });
1887
+ };
1888
+ return {
1889
+ stream: { push(event) {
1890
+ if (event.type === "text_start" || event.type === "thinking_start" || event.type === "toolcall_start") {
1891
+ const block = output.content[event.contentIndex];
1892
+ if (block) {
1893
+ contentIndices.set(block, event.contentIndex);
1894
+ if (block.type === "text") openTextBlock = block;
1895
+ else if (block.type === "thinking") openThinkingBlock = block;
1896
+ }
1897
+ }
1898
+ stream.push(event);
1899
+ } },
1900
+ beforeContentBlock: (nextType) => {
1901
+ if (openThinkingBlock) finishBlock(openThinkingBlock);
1902
+ if (openTextBlock && nextType !== "toolCall") finishBlock(openTextBlock);
1903
+ },
1904
+ finish(includeToolCalls) {
1905
+ for (const block of output.content) if (block.type !== "toolCall" || includeToolCalls) finishBlock(block);
1906
+ }
1907
+ };
1908
+ }
1909
+ function createOpenAICompletionsTransportStreamFn() {
1910
+ return (model, context, options) => streamOpenAICompletionsRequest(model, context, options, "managed");
1911
+ }
1912
+ function streamOpenAICompletionsRequest(model, context, options, mode) {
1913
+ const { eventStream, stream } = createWritableTransportEventStream();
1914
+ (async () => {
1915
+ const output = createAssistantOutput(model);
1916
+ const provisionalCommentaryTags = /* @__PURE__ */ new Map();
1917
+ let firstEventAbort;
1918
+ try {
1919
+ const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
1920
+ const directEmitReasoning = Boolean(mode === "direct" && model.reasoning && options?.reasoningEffort && isOpenAICompletionsThinkingEnabled(options.reasoningEffort));
1921
+ const cacheRetention = resolveCacheRetention(options?.cacheRetention);
1922
+ const policy = mode === "direct" ? {
1923
+ mode,
1924
+ compat: resolveOpenAICompletionsCompat(model),
1925
+ cacheRetention
1926
+ } : { mode };
1927
+ const { client, sawStreamDONE } = policy.mode === "direct" ? {
1928
+ client: createDirectCompletionsClient(model, context, apiKey, resolveProviderSimpleCompletionHeaders(model, options), cacheRetention === "none" ? void 0 : options?.sessionId, policy.compat),
1929
+ sawStreamDONE: void 0
1930
+ } : createManagedCompletionsClient(model, context, options, apiKey, cacheRetention);
1931
+ let params = buildOpenAICompletionsRequest(model, context, options, policy);
1932
+ const encodeBody = prepareModelRequestBody(options);
1933
+ const nextParams = await options?.onPayload?.(params, model);
1934
+ if (nextParams !== void 0) params = nextParams;
1935
+ if (mode === "managed") {
1936
+ if (options?.openclawCodeModeToolSurface === true) {
1937
+ const visibleToolNames = resolveCodeModeResponsesVisibleToolNames(context);
1938
+ enforceCodeModeResponsesToolSurface(params, visibleToolNames, void 0, codeModeToolSurfaceObserver.get(options));
1939
+ assertCodeModeResponsesToolSurface(params, visibleToolNames);
1940
+ }
1941
+ if (getCompat(model).requiresNonEmptyUserOrAssistantMessage) assertOpenAICompletionsPayloadHasConversationTurn(params, model);
1942
+ }
1943
+ const emitReasoning = mode === "direct" ? directEmitReasoning : shouldEmitOpenAICompletionsReasoning(model, options);
1944
+ firstEventAbort = createFirstStreamEventAbortController(options?.signal);
1945
+ const requestOptions = mode === "direct" ? {
1946
+ ...await encodeBody(params),
1947
+ signal: firstEventAbort.signal,
1948
+ ...options?.timeoutMs !== void 0 ? { timeout: options.timeoutMs } : {},
1949
+ maxRetries: 0
1950
+ } : {
1951
+ ...buildOpenAISdkRequestOptions(model, firstEventAbort.signal, { timeoutMs: options?.timeoutMs }),
1952
+ ...await encodeBody(params)
1953
+ };
1954
+ const { data: responseStream, response } = await client.chat.completions.create(params, requestOptions).withResponse();
1955
+ const hookedResponseStream = withProviderResponseHook({
1956
+ stream: responseStream,
1957
+ signal: firstEventAbort.signal,
1958
+ abort: firstEventAbort.abort,
1959
+ hook: createOpenAIProviderAcceptanceHook(options, response, model),
1960
+ onReady: () => stream.push({
1961
+ type: "start",
1962
+ partial: output
1963
+ })
1964
+ });
1965
+ const directEvents = mode === "direct" ? createDirectCompletionsEventStream(output, stream) : void 0;
1966
+ try {
1967
+ await processCompletionsStream(hookedResponseStream, output, model, directEvents?.stream ?? stream, {
1968
+ ...directEvents ? {
1969
+ mode: "direct",
1970
+ beforeContentBlock: directEvents.beforeContentBlock,
1971
+ provisionalCommentaryTags
1972
+ } : { mode: "managed" },
1973
+ signal: options?.signal,
1974
+ emitReasoning,
1975
+ strictReasoningTags: reasoningTagTextPolicy.isStrict(options),
1976
+ firstEventTimeoutMs: getFirstStreamEventTimeoutMs(options),
1977
+ abortFirstEventStream: firstEventAbort.abort,
1978
+ onFirstEventTimeout: getFirstStreamEventTimeoutHandler(options),
1979
+ sawStreamDONE
1980
+ });
1981
+ if (directEvents) {
1982
+ if (options?.signal?.aborted) throw transportAbortError(options.signal);
1983
+ if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage || (output.stopReason === "aborted" ? "Request was aborted" : "Provider returned an invalid tool call"));
1984
+ }
1985
+ } catch (error) {
1986
+ directEvents?.finish(false);
1987
+ throw error;
1988
+ }
1989
+ directEvents?.finish(output.stopReason === "toolUse");
1990
+ finalizeTransportStream({
1991
+ stream,
1992
+ output,
1993
+ signal: options?.signal
1994
+ });
1995
+ } catch (error) {
1996
+ failTransportStream({
1997
+ stream,
1998
+ output,
1999
+ signal: options?.signal,
2000
+ error,
2001
+ cleanup: () => {
2002
+ if (mode === "managed") output.stopReason = options?.signal?.aborted ? "aborted" : "error";
2003
+ finalizeOpenAICompletionsToolCalls(output, { allowSilentToolCallPromotion: false });
2004
+ clearPendingCommentaryText(provisionalCommentaryTags);
2005
+ tagUnresolvedTextAsCommentary(output);
2006
+ if (mode === "direct") for (const block of output.content) {
2007
+ delete block.index;
2008
+ delete block.partialArgs;
2009
+ delete block.streamIndex;
2010
+ }
2011
+ }
2012
+ });
2013
+ } finally {
2014
+ firstEventAbort?.dispose();
2015
+ }
2016
+ })();
2017
+ return eventStream;
2018
+ }
2019
+ function createDirectCompletionsClient(model, context, apiKey, optionsHeaders, sessionId, compat) {
2020
+ if (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);
2021
+ const headers = { ...model.headers };
2022
+ if (model.provider === "github-copilot") Object.assign(headers, buildCopilotDynamicHeaders(context.messages));
2023
+ if (sessionId && compat.sessionAffinity !== "none") {
2024
+ if (compat.sessionAffinity === "openrouter") headers["x-session-id"] = sessionId;
2025
+ else {
2026
+ headers.session_id = sessionId;
2027
+ headers["x-client-request-id"] = sessionId;
2028
+ headers["x-session-affinity"] = sessionId;
2029
+ }
2030
+ }
2031
+ return createOpenAIProviderClient(model, apiKey, headers, optionsHeaders);
2032
+ }
2033
+ function createManagedCompletionsClient(model, context, options, apiKey, cacheRetention) {
2034
+ const turnState = resolveProviderTransportTurnState(model, {
2035
+ sessionId: options?.sessionId,
2036
+ turnId: randomUUID(),
2037
+ attempt: 1,
2038
+ transport: "stream"
2039
+ });
2040
+ const optionHeaders = resolveOpencodeSessionHeaders(model, options);
2041
+ const turnHeaders = filterProviderTurnHeadersForExplicitOpencodeSession(model, options, turnState?.headers);
2042
+ const doneDetector = createSseDoneDetector();
2043
+ const baseFetch = buildGuardedModelFetch(model);
2044
+ const doneDetectingFetch = async (url, init) => {
2045
+ const response = await baseFetch(url, init);
2046
+ if (!response.body || !response.ok) return response;
2047
+ if (typeof TransformStream === "undefined" || !response.body.pipeThrough) return response;
2048
+ const transformed = response.body.pipeThrough(new TransformStream({
2049
+ transform(chunk, controller) {
2050
+ doneDetector.observe(chunk);
2051
+ controller.enqueue(chunk);
2052
+ },
2053
+ flush() {
2054
+ doneDetector.finish();
2055
+ }
2056
+ }));
2057
+ return new Response(transformed, {
2058
+ headers: response.headers,
2059
+ status: response.status,
2060
+ statusText: response.statusText
2061
+ });
2062
+ };
2063
+ const clientConfig = buildOpenAICompletionsClientConfig(model, buildOpenAIClientHeaders(model, context, {
2064
+ ...turnHeaders,
2065
+ ...optionHeaders
2066
+ }, void 0, resolvePromptCacheKey(options, cacheRetention), cacheRetention));
2067
+ return {
2068
+ client: new OpenAI({
2069
+ apiKey,
2070
+ baseURL: clientConfig.baseURL,
2071
+ dangerouslyAllowBrowser: true,
2072
+ defaultHeaders: clientConfig.defaultHeaders,
2073
+ defaultQuery: clientConfig.defaultQuery,
2074
+ fetch: doneDetectingFetch,
2075
+ ...buildOpenAISdkClientOptions(model)
2076
+ }),
2077
+ sawStreamDONE: doneDetector.sawDone
2078
+ };
2079
+ }
2080
+ //#endregion
2081
+ export { flattenCompletionMessagesToStringContent as a, hasOpenAICompatibleConversationTurn as c, createDeepSeekTextFilter as d, convertMessages as i, canonicalizeMaxTokensParam as l, streamOpenAICompletionsRequest as n, stripCompletionMessagesToRoleContent as o, buildOpenAICompletionsParams as r, applyCompletionsAnthropicCacheControl as s, createOpenAICompletionsTransportStreamFn as t, resolveMaxTokensParam as u };
@@ -1,5 +1,5 @@
1
- import { M as OpenAICompletionsCompat, O as Model, l as CacheRetention } from "./types-CLLR3eB4.mjs";
2
- import "./types-CB-_vNyI.mjs";
1
+ import { N as OpenAICompletionsCompat, k as Model, l as CacheRetention } from "./types-DvzmWW8J.mjs";
2
+ import "./types-BuiEBM3u.mjs";
3
3
  //#region packages/ai/src/providers/openai-prompt-cache.d.ts
4
4
  /** Selects documented lifetime fields shared by Responses and Chat Completions. */
5
5
  declare function resolveOpenAIPromptCacheParams(model: Pick<Model, "id" | "provider" | "baseUrl">, cacheRetention: CacheRetention, compat: Required<Pick<OpenAICompletionsCompat, "supportsPromptCacheKey" | "supportsLongCacheRetention">>): {
@@ -1,4 +1,4 @@
1
- import { n as isNativeOpenAIEndpoint } from "./openai-completions-compat-BJf57ZxN.mjs";
1
+ import { n as isNativeOpenAIEndpoint } from "./openai-completions-compat-BdmlhD4u.mjs";
2
2
  //#region packages/normalization-core/src/code-points.ts
3
3
  /** Truncates to a nonnegative code-point budget; grapheme clusters may be split. */
4
4
  function truncateCodePoints(text, maxCodePoints) {
@@ -1,7 +1,7 @@
1
- import "./index-D6KsSE74.mjs";
2
- import { O as Model, a as AssistantMessage } from "./types-CLLR3eB4.mjs";
3
- import "./provider-options-Df7ov0K1.mjs";
4
- import { i as ReplayableResponseCompactionItem, r as OpenAIResponsesReasoningReplayMetadata, s as OpenAIResponsesCompactionOutput } from "./openai-responses-contracts-D1iZ0njF.mjs";
1
+ import "./index-a8e_oKnu.mjs";
2
+ import { a as AssistantMessage, k as Model } from "./types-DvzmWW8J.mjs";
3
+ import "./provider-options-D5ABCV_l.mjs";
4
+ import { i as ReplayableResponseCompactionItem, l as OpenAIResponsesCompactionOutput, r as OpenAIResponsesReasoningReplayMetadata } from "./openai-responses-contracts-Br5IIw_h.mjs";
5
5
  import "openai/resources/responses/responses.js";
6
6
  //#region packages/ai/src/transports/openai-responses-compaction-replay.d.ts
7
7
  declare function captureOpenAIResponsesCompaction(output: Pick<AssistantMessage, "providerReplay">, item: ReplayableResponseCompactionItem, boundary: number | "retained-users", model: Model, captureMetadata?: OpenAIResponsesReasoningReplayMetadata, compactedOutput?: OpenAIResponsesCompactionOutput): void;