@openclaw/ai 2026.9.5 → 2026.9.7

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 (102) hide show
  1. package/dist/{anthropic-COtDvgtt.mjs → anthropic-Cw2pgccz.mjs} +59 -88
  2. package/dist/{anthropic-payload-policy-5Erq1Nzy.d.mts → anthropic-payload-policy-NIPVYXPq.d.mts} +8 -6
  3. package/dist/{anthropic-stream-reducer-BvdYYWL8.mjs → anthropic-stream-reducer-D9MCkl8Z.mjs} +194 -247
  4. package/dist/{api-registry-Ba2Cv-ut.d.mts → api-registry-D-nbmSqr.d.mts} +2 -2
  5. package/dist/{azure-openai-responses-YrgnD583.mjs → azure-openai-responses-BwT3-X8P.mjs} +22 -33
  6. package/dist/{base64-BQOzsvUH.mjs → base64-C1PsYcRQ.mjs} +22 -16
  7. package/dist/{diagnostics-Dm4bisWG.mjs → diagnostics-CJaB6g8J.mjs} +55 -10
  8. package/dist/{diagnostics-CPeq9F7y.mjs → diagnostics-DzrF1h4J.mjs} +18 -1
  9. package/dist/diagnostics.d.mts +11 -5
  10. package/dist/diagnostics.mjs +4 -4
  11. package/dist/{env-api-keys-bktO00EJ.mjs → env-api-keys-CyX4VKGO.mjs} +7 -5
  12. package/dist/event-stream-CMQfX_yr.d.mts +1 -0
  13. package/dist/{event-stream-CCoa-qSI.d.mts → event-stream-DOPFYVqs.d.mts} +2 -2
  14. package/dist/{event-stream-D8PARQfL.mjs → event-stream-vd9UnCAU.mjs} +10 -0
  15. package/dist/event-stream.d.mts +2 -2
  16. package/dist/event-stream.mjs +1 -1
  17. package/dist/{google-BuhpRO9r.mjs → google-BfapkS_K.mjs} +8 -11
  18. package/dist/google-interactions-DW3iXzjc.mjs +574 -0
  19. package/dist/{google-messages-CyWnYlh0.mjs → google-messages-CtjVtVot.mjs} +35 -71
  20. package/dist/{google-shared-BT5ZeNer.mjs → google-shared-Y2YfotEu.mjs} +43 -47
  21. package/dist/{google-vertex-C7EplRvt.mjs → google-vertex-Dov4kBWu.mjs} +16 -30
  22. package/dist/{host-B4MeUNBc.mjs → host-CHi3X87F.mjs} +64 -189
  23. package/dist/{host-policy-DUnXSx0I.mjs → host-policy-BOAwRg_M.mjs} +2 -14
  24. package/dist/{host-FZ1RA_qD.d.mts → host-rxlNaBwm.d.mts} +9 -3
  25. package/dist/{index-DaF2QbwS.d.mts → index-D6KsSE74.d.mts} +57 -9
  26. package/dist/index.d.mts +7 -7
  27. package/dist/index.mjs +7 -7
  28. package/dist/internal/anthropic.d.mts +13 -8
  29. package/dist/internal/anthropic.mjs +5 -5
  30. package/dist/internal/openai-completions-compat.d.mts +1 -1
  31. package/dist/internal/openai-completions-compat.mjs +1 -1
  32. package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
  33. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  34. package/dist/internal/openai.d.mts +46 -9
  35. package/dist/internal/openai.mjs +13 -12
  36. package/dist/internal/runtime.d.mts +31 -70
  37. package/dist/internal/runtime.mjs +11 -66
  38. package/dist/internal/shared.d.mts +16 -13
  39. package/dist/internal/shared.mjs +6 -5
  40. package/dist/internal/tool-schema.d.mts +2 -2
  41. package/dist/internal/tool-schema.mjs +2 -2
  42. package/dist/{mistral-moA-mbwl.mjs → mistral-RS6mboC-.mjs} +46 -93
  43. package/dist/{model-transport-url-DKocrEsb.d.mts → model-transport-url-C5f59L3Y.d.mts} +1 -1
  44. package/dist/{openai-chatgpt-responses-DWID3EFO.mjs → openai-chatgpt-responses-CYbidtrn.mjs} +118 -99
  45. package/dist/{openai-completions-DJ1Vm-CD.mjs → openai-completions-D14ihPYk.mjs} +14 -12
  46. package/dist/{openai-completions-compat-CkwdxTZx.mjs → openai-completions-compat-BOVWBZDn.mjs} +3 -5
  47. package/dist/{openai-completions-compat-JE7gqxb9.d.mts → openai-completions-compat-qJjmqQ71.d.mts} +3 -3
  48. package/dist/{openai-completions-stream-Bu98b0Hv.mjs → openai-completions-stream-CDCuw3DP.mjs} +124 -183
  49. package/dist/{openai-prompt-cache-CJ_xEevu.d.mts → openai-prompt-cache-CouErLh7.d.mts} +2 -2
  50. package/dist/{openai-prompt-cache-1wfaIszn.mjs → openai-prompt-cache-D2V7MqR7.mjs} +1 -1
  51. package/dist/{openai-provider-client-DPo0Hmak.mjs → openai-provider-client-CwfsGBbA.mjs} +2 -2
  52. package/dist/{openai-reasoning-effort-NlFZmfEu.mjs → openai-reasoning-effort-ConhwkeX.mjs} +14 -5
  53. package/dist/{openai-responses-BejZzQCP.mjs → openai-responses-CKCBEc2W.mjs} +12 -11
  54. package/dist/openai-responses-compaction-replay-DiYn-gFM.d.mts +12 -0
  55. package/dist/{openai-responses-compaction-window-D6P5oZP5.mjs → openai-responses-compaction-window-UNK1GDpy.mjs} +5 -5
  56. package/dist/{openai-responses-contracts-DWrfMODE.mjs → openai-responses-contracts-CLxnqS9p.mjs} +1 -1
  57. package/dist/{openai-responses-contracts-Dflvrfa8.d.mts → openai-responses-contracts-D1iZ0njF.d.mts} +4 -4
  58. package/dist/{openai-responses-prompt-observer-internal-C15_-OwV.mjs → openai-responses-prompt-observer-internal-iAqLb4tk.mjs} +16 -13
  59. package/dist/openai-responses-request-lifecycle-Fsag-IGZ.mjs +36 -0
  60. package/dist/{openai-responses-shared-CwsziD_m.mjs → openai-responses-shared-DL4ulQn7.mjs} +838 -577
  61. package/dist/{openai-responses-terminal-usage-Dl3J6zrf.d.mts → openai-responses-terminal-usage-BE7lf7nW.d.mts} +2 -2
  62. package/dist/{openai-stop-reason-Drnn_6Qj.mjs → openai-stop-reason-8s70vDXj.mjs} +2 -12
  63. package/dist/{openai-tool-schema-ynZBgqW-.d.mts → openai-tool-schema-a5ysBBga.d.mts} +0 -6
  64. package/dist/{openai-tool-schema-BO8rwyAD.mjs → openai-tool-schema-vsl-cE-n.mjs} +365 -429
  65. package/dist/{openai-transport-params-DQeuAvBl.mjs → openai-transport-params-BwlpzX-2.mjs} +61 -106
  66. package/dist/{positive-integer-DtjCkbue.mjs → positive-integer-CjN5OJbH.mjs} +1 -1
  67. package/dist/{provider-error-DDqw9Qda.mjs → provider-error-CwT_j2v0.mjs} +82 -10
  68. package/dist/{provider-error-CzNw4BWX.d.mts → provider-error-xumb1V3F.d.mts} +3 -1
  69. package/dist/{provider-options-DprLsWh9.d.mts → provider-options-Df7ov0K1.d.mts} +6 -4
  70. package/dist/{provider-replay-context-CnUSOwhr.mjs → provider-replay-context-DsyI5jOP.mjs} +1 -1
  71. package/dist/{provider-transcript-transform-BsRAhuWJ.mjs → provider-transcript-transform-JbFbHV8h.mjs} +17 -2
  72. package/dist/{provider-transport-turn-state-CkGToCD2.mjs → provider-transport-turn-state-BheUi_hl.mjs} +1 -1
  73. package/dist/{provider-types-CAKRC7N5.d.mts → provider-types-d4XnoZMd.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 +15 -11
  77. package/dist/{reasoning-tag-text-partitioner-Dy9IO8Dc.mjs → reasoning-tag-text-partitioner-B6FIIBt6.mjs} +193 -98
  78. package/dist/{record-coerce-DwRYMj3t.mjs → record-coerce-CNDovvft.mjs} +1 -1
  79. package/dist/simple-options-CGAkCwtM.mjs +349 -0
  80. package/dist/{src-DeKjbE8I.mjs → src-H4aXcFuX.mjs} +53 -26
  81. package/dist/{stream-CREqxHgU.mjs → stream-DDsCBgd-.mjs} +1 -7
  82. package/dist/{stream-first-event-timeout-C9ZadkJW.mjs → stream-first-event-timeout-B9o0S4SZ.mjs} +1 -1
  83. package/dist/{tool-schema-json-projection-CD9c_fK8.mjs → tool-schema-json-projection-Ct8SeBeJ.mjs} +63 -23
  84. package/dist/{transport-stream-shared-D-6FQSHm.mjs → transport-stream-shared-Dh5qKJ8e.mjs} +63 -37
  85. package/dist/{transport-stream-shared-BbUkFaHi.d.mts → transport-stream-shared-yYhXa4kX.d.mts} +13 -7
  86. package/dist/{transport-utils-1cyq5Y7x.mjs → transport-utils-C-4bf2Ok.mjs} +3 -4
  87. package/dist/transports.d.mts +37 -33
  88. package/dist/transports.mjs +208 -239
  89. package/dist/types-CB-_vNyI.d.mts +1 -0
  90. package/dist/{types-4_uVs5WH.d.mts → types-CLLR3eB4.d.mts} +5 -1
  91. package/dist/types.d.mts +6 -6
  92. package/dist/types.mjs +5 -5
  93. package/dist/{validation-Dw7cb6BV.mjs → validation-BFZc40Ig.mjs} +80 -54
  94. package/dist/{validation-Ctzu2DhF.d.mts → validation-Cat2wQsc.d.mts} +1 -1
  95. package/dist/validation.d.mts +1 -1
  96. package/dist/validation.mjs +1 -1
  97. package/package.json +6 -6
  98. package/dist/assistant-output-BsEkB-vU.mjs +0 -16
  99. package/dist/event-stream-DmSCpi1T.d.mts +0 -1
  100. package/dist/simple-options-C6cFWj_f.mjs +0 -175
  101. package/dist/types-DkJfb4W3.d.mts +0 -1
  102. package/dist/utf16-slice-CvGodqok.mjs +0 -29
@@ -1,27 +1,27 @@
1
- import { r as appendAssistantThinking } from "./event-stream-D8PARQfL.mjs";
2
- import { o as isRecord } from "./record-coerce-DwRYMj3t.mjs";
3
- import { n as isOpenAIGpt55Model, r as isOpenAIGpt56Model, t as isOpenAIGpt54MiniModel } from "./openai-reasoning-effort-NlFZmfEu.mjs";
1
+ import { r as appendAssistantThinking } from "./event-stream-vd9UnCAU.mjs";
2
+ import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
3
+ import { k as isImageWithMediaPayload, n as getAiTransportHost } from "./host-CHi3X87F.mjs";
4
+ import { n as isOpenAIGpt55Model, r as isOpenAIGpt56Model, t as isOpenAIGpt54MiniModel } from "./openai-reasoning-effort-ConhwkeX.mjs";
4
5
  import { r as uniqueStrings } from "./string-normalization-J9ZiLfGO.mjs";
5
- import { _ as isImageWithMediaPayload, d as describeToolResultMediaPlaceholder, m as extractToolResultText, v as sanitizeSurrogates } from "./host-B4MeUNBc.mjs";
6
- import { t as truncateUtf16Safe } from "./utf16-slice-CvGodqok.mjs";
7
- import { r as resolveOpenAIPromptCacheParams } from "./openai-prompt-cache-1wfaIszn.mjs";
8
- import { r as emitModelTransportDebug } from "./diagnostics-Dm4bisWG.mjs";
9
- import { i as asNonNegativeFiniteNumber } from "./base64-BQOzsvUH.mjs";
10
- import { c as supportsModelTools, r as estimateStringChars } from "./transport-utils-1cyq5Y7x.mjs";
11
- import { c as shouldOmitOllamaCompatResponseFormat, n as isNativeOpenAIEndpoint, s as resolveOpenAICompletionsResponseFormat, t as detectOpenAICompletionsCompat } from "./openai-completions-compat-CkwdxTZx.mjs";
12
- import { i as resolveProviderEndpoint, r as resolveOpenAIStrictToolSetting } from "./host-policy-DUnXSx0I.mjs";
6
+ import { o as truncateUtf16Safe } from "./provider-error-CwT_j2v0.mjs";
7
+ import { r as resolveOpenAIPromptCacheParams } from "./openai-prompt-cache-D2V7MqR7.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-C-4bf2Ok.mjs";
11
+ import { c as shouldOmitOllamaCompatResponseFormat, n as isNativeOpenAIEndpoint, s as resolveOpenAICompletionsResponseFormat, t as detectOpenAICompletionsCompat } from "./openai-completions-compat-BOVWBZDn.mjs";
12
+ import { r as resolveProviderEndpoint } from "./host-policy-BOAwRg_M.mjs";
13
13
  import { t as resolveCacheRetention } from "./cache-retention-0x979a5V.mjs";
14
- import { f as splitSystemPromptCacheBoundary, h as stripSystemPromptRelocatableBoundary, m as stripSystemPromptCacheBoundary, p as splitSystemPromptRelocatableBoundary, v as sortPromptCacheToolsByName } from "./simple-options-C6cFWj_f.mjs";
15
- import { A as resolvePromptCacheKey, C as isOpenAICompletionsThinkingEnabled, D as readOpenAICompletionsContentDeltas, E as parseOpenAICompletionsUsage, O as readOpenAICompletionsReasoningBatch, T as measureUtf8AppendBytes, d as prepareOpenAITools, f as projectOpenAITools, g as resolveOpenAISimpleReasoningEffort, h as resolveOpenAIRequestReasoning, j as throwIfModelStreamAborted, p as reconcileOpenAICompletionsToolChoice, s as getCompat, u as resolveOpenAIStrictToolFlagWithDiagnostics, v as GEMINI_THOUGHT_SIGNATURE_VALIDATOR_SKIP, w as log, y as createModelStreamCooperativeScheduler } from "./openai-transport-params-DQeuAvBl.mjs";
16
- import { E as parseStreamingJson, c as finalizeTerminalToolCallArguments, w as createToolArgumentPreviewSchedule } from "./transport-stream-shared-D-6FQSHm.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-Dh5qKJ8e.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-CGAkCwtM.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-BwlpzX-2.mjs";
17
17
  import { a as tagUnresolvedTextAsCommentary, i as tagPendingCommentaryText, n as rememberPendingCommentaryTags, r as tagInterruptedTextPhases, t as clearPendingCommentaryText } from "./assistant-text-phase-C20rxWwP.mjs";
18
18
  import { t as notifyLlmRequestActivity } from "./llm-request-activity-BjtkplhG.mjs";
19
- import { a as withFirstStreamEventTimeout } from "./stream-first-event-timeout-C9ZadkJW.mjs";
20
- import { t as transformProviderMessages } from "./provider-transcript-transform-BsRAhuWJ.mjs";
21
- import { f as withPreparedToolSchemaNormalization, r as normalizeOpenAIStrictToolParameters } from "./openai-tool-schema-BO8rwyAD.mjs";
19
+ import { t as transformProviderMessages } from "./provider-transcript-transform-JbFbHV8h.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
22
  import { isGoogleGemini3FlashModel, isGoogleGemini3ProModel } from "./internal/google-model-family.mjs";
23
- import { t as mapOpenAIStopReason } from "./openai-stop-reason-Drnn_6Qj.mjs";
24
- import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-Dy9IO8Dc.mjs";
23
+ import { t as mapOpenAIStopReason } from "./openai-stop-reason-8s70vDXj.mjs";
24
+ import { t as createReasoningTagTextPartitioner } from "./reasoning-tag-text-partitioner-B6FIIBt6.mjs";
25
25
  import { randomUUID } from "node:crypto";
26
26
  //#region packages/ai/src/transports/deepseek-dsml-grammar.ts
27
27
  const DEEPSEEK_DSML_MARKERS = [
@@ -30,6 +30,25 @@ const DEEPSEEK_DSML_MARKERS = [
30
30
  "||"
31
31
  ].map((bar) => `${bar}DSML${bar}`);
32
32
  const DEEPSEEK_DSML_MARKER_PATTERN = `(${DEEPSEEK_DSML_MARKERS.map((marker) => marker.replaceAll("|", "\\|")).join("|")})`;
33
+ function findEarliestDsmlToken(text, tokens, fromIndex = 0) {
34
+ let best = null;
35
+ for (const token of tokens) {
36
+ const index = text.indexOf(token, fromIndex);
37
+ if (index !== -1 && (!best || index < best.index)) best = {
38
+ index,
39
+ token
40
+ };
41
+ }
42
+ return best;
43
+ }
44
+ function longestDsmlTokenPrefixSuffixLength(text, tokens, maxTokenLength) {
45
+ const maxLength = Math.min(text.length, maxTokenLength - 1);
46
+ for (let length = maxLength; length > 0; length--) {
47
+ const suffix = text.slice(text.length - length);
48
+ if (tokens.some((token) => token.startsWith(suffix))) return length;
49
+ }
50
+ return 0;
51
+ }
33
52
  //#endregion
34
53
  //#region packages/ai/src/transports/deepseek-text-filter.ts
35
54
  /**
@@ -67,7 +86,7 @@ function createDeepSeekTextFilter() {
67
86
  if (final) closeToken = void 0;
68
87
  return output;
69
88
  }
70
- const open = findEarliestToken(buffer, DSML_OPEN_TOKENS);
89
+ const open = findEarliestDsmlToken(buffer, DSML_OPEN_TOKENS);
71
90
  if (open) {
72
91
  emit(buffer.slice(0, open.index));
73
92
  buffer = buffer.slice(open.index + open.token.length);
@@ -79,7 +98,7 @@ function createDeepSeekTextFilter() {
79
98
  buffer = "";
80
99
  return output;
81
100
  }
82
- const keep = longestDsmlOpenPrefixSuffixLength(buffer);
101
+ const keep = longestDsmlTokenPrefixSuffixLength(buffer, DSML_OPEN_TOKENS, MAX_OPEN_TOKEN_LEN);
83
102
  const emitLength = buffer.length - keep;
84
103
  if (emitLength <= 0) return output;
85
104
  emit(buffer.slice(0, emitLength));
@@ -98,25 +117,6 @@ function createDeepSeekTextFilter() {
98
117
  }
99
118
  };
100
119
  }
101
- function findEarliestToken(text, tokens) {
102
- let best = null;
103
- for (const token of tokens) {
104
- const index = text.indexOf(token);
105
- if (index !== -1 && (!best || index < best.index)) best = {
106
- index,
107
- token
108
- };
109
- }
110
- return best;
111
- }
112
- function longestDsmlOpenPrefixSuffixLength(text) {
113
- const maxLength = Math.min(text.length, MAX_OPEN_TOKEN_LEN - 1);
114
- for (let length = maxLength; length > 0; length--) {
115
- const suffix = text.slice(text.length - length);
116
- if (DSML_OPEN_TOKENS.some((token) => token.startsWith(suffix))) return length;
117
- }
118
- return 0;
119
- }
120
120
  //#endregion
121
121
  //#region packages/ai/src/transports/model-max-tokens-params.ts
122
122
  /**
@@ -255,10 +255,18 @@ function createOpenAIEncryptedToolCallReasoningTracker() {
255
255
  const firstBlocks = /* @__PURE__ */ new Map();
256
256
  const pendingDetails = /* @__PURE__ */ new Map();
257
257
  return {
258
- rememberToolCall(id, block) {
258
+ rememberToolCall(id, block, previousId = id) {
259
+ const previous = firstBlocks.get(previousId);
260
+ if (previousId !== id && previous?.block === block) {
261
+ firstBlocks.delete(previousId);
262
+ if (previous.signature && block.thoughtSignature === previous.signature) delete block.thoughtSignature;
263
+ }
259
264
  if (!id || firstBlocks.has(id)) return;
260
- firstBlocks.set(id, block);
261
265
  const pendingDetail = pendingDetails.get(id);
266
+ firstBlocks.set(id, {
267
+ block,
268
+ signature: pendingDetail
269
+ });
262
270
  if (pendingDetail) {
263
271
  block.thoughtSignature = pendingDetail;
264
272
  pendingDetails.delete(id);
@@ -270,8 +278,10 @@ function createOpenAIEncryptedToolCallReasoningTracker() {
270
278
  if (!isRecord(detail) || detail.type !== "reasoning.encrypted" || typeof detail.id !== "string" || detail.id.length === 0 || typeof detail.data !== "string" || detail.data.length === 0) continue;
271
279
  const serializedDetail = JSON.stringify(detail);
272
280
  const matchingBlock = firstBlocks.get(detail.id);
273
- if (matchingBlock) matchingBlock.thoughtSignature = serializedDetail;
274
- else pendingDetails.set(detail.id, serializedDetail);
281
+ if (matchingBlock) {
282
+ matchingBlock.signature = serializedDetail;
283
+ matchingBlock.block.thoughtSignature = serializedDetail;
284
+ } else pendingDetails.set(detail.id, serializedDetail);
275
285
  }
276
286
  }
277
287
  };
@@ -337,7 +347,7 @@ function createOpenAICompletionsToolCallDeltaNormalizer() {
337
347
  }];
338
348
  }
339
349
  const functionCall = delta.function_call;
340
- if (sawModernToolCall) return [{
350
+ if (sawModernToolCall || !functionCall && !pendingLegacyToolCall) return [{
341
351
  delta: ordinaryDelta,
342
352
  toolCalls: []
343
353
  }];
@@ -456,7 +466,7 @@ function convertMessages(model, context, compat, options = {}) {
456
466
  if (model.provider === "openai") return id.length > 40 ? truncateUtf16Safe(id, 40) : id;
457
467
  return id;
458
468
  };
459
- const transformedMessages = transformProviderMessages(context.messages, model, (id) => normalizeToolCallId(id));
469
+ const transformedMessages = transformProviderMessages(context.messages, model, normalizeToolCallId);
460
470
  let relocatableSplit;
461
471
  let systemParamIndex;
462
472
  if (context.systemPrompt) {
@@ -483,15 +493,12 @@ function convertMessages(model, context, compat, options = {}) {
483
493
  content: "I have processed the tool results."
484
494
  });
485
495
  if (msg.role === "user") {
486
- const isRuntimeContextCarrier = msg.runtimeContextCarrier === true;
487
- if (typeof msg.content === "string") {
488
- const userParam = {
489
- role: "user",
490
- content: sanitizeSurrogates(msg.content)
491
- };
492
- if (isRuntimeContextCarrier) options.cacheOptOutIndexes?.add(params.length);
493
- params.push(userParam);
494
- } else {
496
+ let userParam;
497
+ if (typeof msg.content === "string") userParam = {
498
+ role: "user",
499
+ content: sanitizeSurrogates(msg.content)
500
+ };
501
+ else {
495
502
  const content = msg.content.map((item) => {
496
503
  if (item.type === "text") return {
497
504
  type: "text",
@@ -507,13 +514,13 @@ function convertMessages(model, context, compat, options = {}) {
507
514
  };
508
515
  });
509
516
  if (content.length === 0) continue;
510
- const userParam = {
517
+ userParam = {
511
518
  role: "user",
512
519
  content
513
520
  };
514
- if (isRuntimeContextCarrier) options.cacheOptOutIndexes?.add(params.length);
515
- params.push(userParam);
516
521
  }
522
+ if (msg.runtimeContextCarrier === true) options.cacheOptOutIndexes?.add(params.length);
523
+ params.push(userParam);
517
524
  } else if (msg.role === "assistant") {
518
525
  const assistantMsg = {
519
526
  role: "assistant",
@@ -766,7 +773,9 @@ const REASONING_CONTENT_REPLAY_MODEL_IDS = /* @__PURE__ */ new Set([
766
773
  "mimo-v2-omni",
767
774
  "mimo-v2.5",
768
775
  "mimo-v2.5-pro",
769
- "mimo-v2.6-pro"
776
+ "mimo-v2.6-flash",
777
+ "mimo-v2.6-pro",
778
+ "mimo-v2.6-pro-ultraspeed"
770
779
  ]);
771
780
  const REASONING_CONTENT_REPLAY_TIER_SUFFIXES = [
772
781
  "-free",
@@ -860,19 +869,18 @@ function resolveOpenAICompletionsModelMaxTokens(model) {
860
869
  const OPENAI_COMPLETIONS_INPUT_TOKEN_SAFETY_MARGIN = 1.25;
861
870
  const OPENAI_COMPLETIONS_IMAGE_CHAR_ESTIMATE = 8e3;
862
871
  const MIN_USEFUL_OUTPUT_TOKENS = 16;
872
+ function estimateJsonChars(value, fallback) {
873
+ try {
874
+ return estimateStringChars(JSON.stringify(value));
875
+ } catch {
876
+ return fallback;
877
+ }
878
+ }
863
879
  function estimateOpenAICompletionsInputTokens(payload) {
864
880
  let adjustedChars = 0;
865
881
  adjustedChars += estimateOpenAICompletionsMessagesChars(payload.messages);
866
- if (Array.isArray(payload.tools) && payload.tools.length > 0) try {
867
- adjustedChars += estimateStringChars(JSON.stringify(payload.tools));
868
- } catch {
869
- adjustedChars += 1024;
870
- }
871
- if (payload.response_format !== void 0) try {
872
- adjustedChars += estimateStringChars(JSON.stringify(payload.response_format));
873
- } catch {
874
- adjustedChars += 256;
875
- }
882
+ if (Array.isArray(payload.tools) && payload.tools.length > 0) adjustedChars += estimateJsonChars(payload.tools, 1024);
883
+ if (payload.response_format !== void 0) adjustedChars += estimateJsonChars(payload.response_format, 256);
876
884
  return Math.ceil(adjustedChars / 4 * OPENAI_COMPLETIONS_INPUT_TOKEN_SAFETY_MARGIN);
877
885
  }
878
886
  function estimateOpenAICompletionsMessagesChars(messages) {
@@ -883,11 +891,7 @@ function estimateOpenAICompletionsMessagesChars(messages) {
883
891
  const record = message;
884
892
  adjustedChars += estimateOpenAICompletionsContentChars(record.content);
885
893
  for (const field of COMPLETIONS_REASONING_REPLAY_FIELDS) adjustedChars += estimateOpenAICompletionsContentChars(record[field]);
886
- if (record.tool_calls !== void 0) try {
887
- adjustedChars += estimateStringChars(JSON.stringify(record.tool_calls));
888
- } catch {
889
- adjustedChars += 256;
890
- }
894
+ if (record.tool_calls !== void 0) adjustedChars += estimateJsonChars(record.tool_calls, 256);
891
895
  }
892
896
  return adjustedChars;
893
897
  }
@@ -907,11 +911,7 @@ function estimateOpenAICompletionsContentChars(value) {
907
911
  adjustedChars += estimateStringChars(text);
908
912
  continue;
909
913
  }
910
- try {
911
- adjustedChars += estimateStringChars(JSON.stringify(block));
912
- } catch {
913
- adjustedChars += 256;
914
- }
914
+ adjustedChars += estimateJsonChars(block, 256);
915
915
  }
916
916
  return adjustedChars;
917
917
  }
@@ -948,7 +948,7 @@ function convertTools(tools, compat, model, mode) {
948
948
  const prepared = mode === "managed" ? prepareOpenAITools(tools) : void 0;
949
949
  const projection = prepared?.projection ?? projectOpenAITools(tools);
950
950
  const convert = () => {
951
- const strict = mode === "direct" ? compat.supportsStrictMode ? false : void 0 : resolveOpenAIStrictToolFlagWithDiagnostics(projection, resolveOpenAIStrictToolSetting(model, {
951
+ const strict = mode === "direct" ? compat.supportsStrictMode ? false : void 0 : resolveOpenAIStrictToolFlagWithDiagnostics(projection, getAiTransportHost().resolveOpenAIStrictToolSetting(model, {
952
952
  transport: "stream",
953
953
  supportsStrictMode: compat?.supportsStrictMode
954
954
  }), {
@@ -1049,6 +1049,15 @@ function buildOpenAICompletionsRequest(model, context, options, policy) {
1049
1049
  const toolChoice = reconcileOpenAICompletionsToolChoice(options.toolChoice, directToolProjection ?? projectOpenAITools([]));
1050
1050
  if (toolChoice !== void 0) params.tool_choice = toolChoice;
1051
1051
  }
1052
+ const isOpenRouter = compat.thinkingFormat === "openrouter";
1053
+ const usesBinaryOpenRouterThinking = isOpenRouter && (model.compat?.supportsReasoningEffort === false || model.compat?.supportedReasoningEfforts?.length === 0);
1054
+ const simpleReasoning = options?.reasoning;
1055
+ const requestedEffort = policy.mode === "direct" ? options?.reasoningEffort : options?.reasoningEffort ?? (simpleReasoning === "none" ? "none" : resolveOpenAISimpleReasoningEffort({
1056
+ ...model,
1057
+ compat: model.compat ?? void 0
1058
+ }, simpleReasoning)) ?? (usesBinaryOpenRouterThinking ? void 0 : "high");
1059
+ const reasoning = resolveOpenAIRequestReasoning(model, requestedEffort);
1060
+ const { effort, thinkingEnabled } = reasoning;
1052
1061
  {
1053
1062
  const maxTokenBudget = policy.mode === "direct" ? {
1054
1063
  maxTokens: options?.maxTokens,
@@ -1068,7 +1077,10 @@ function buildOpenAICompletionsRequest(model, context, options, policy) {
1068
1077
  if (clampedMaxTokens > remainingBudget) {
1069
1078
  clampedMaxTokens = remainingBudget;
1070
1079
  emitModelTransportDebug(log, `[completions] clamp_max_tokens provider=${model.provider} api=${model.api} model=${model.id} requested=${effectiveMaxTokens} output=${clampedMaxTokens} effectiveContext=${effectiveContextTokens} estimatedInput=${estimatedInputTokens}`);
1071
- if (remainingBudget < MIN_USEFUL_OUTPUT_TOKENS) log.warn(`[completions] insufficient_output_budget provider=${model.provider} api=${model.api} model=${model.id} output=${clampedMaxTokens} effectiveContext=${effectiveContextTokens} estimatedInput=${estimatedInputTokens}`);
1080
+ if (remainingBudget < MIN_USEFUL_OUTPUT_TOKENS) {
1081
+ if (model.reasoning && thinkingEnabled !== false) throw Object.assign(/* @__PURE__ */ new Error(`Context window exceeded: estimated input ${estimatedInputTokens} leaves only ${remainingBudget} output tokens within the ${effectiveContextTokens}-token context.`), { code: "context_length_exceeded" });
1082
+ log.warn(`[completions] insufficient_output_budget provider=${model.provider} api=${model.api} model=${model.id} output=${clampedMaxTokens} effectiveContext=${effectiveContextTokens} estimatedInput=${estimatedInputTokens}`);
1083
+ }
1072
1084
  }
1073
1085
  }
1074
1086
  if (policy.mode === "direct" ? options?.maxTokens : clampedMaxTokens) {
@@ -1076,15 +1088,6 @@ function buildOpenAICompletionsRequest(model, context, options, policy) {
1076
1088
  else params.max_completion_tokens = clampedMaxTokens;
1077
1089
  }
1078
1090
  }
1079
- const isOpenRouter = compat.thinkingFormat === "openrouter";
1080
- const usesBinaryOpenRouterThinking = isOpenRouter && (model.compat?.supportsReasoningEffort === false || model.compat?.supportedReasoningEfforts?.length === 0);
1081
- const simpleReasoning = options?.reasoning;
1082
- const requestedEffort = policy.mode === "direct" ? options?.reasoningEffort : options?.reasoningEffort ?? (simpleReasoning === "none" ? "none" : resolveOpenAISimpleReasoningEffort({
1083
- ...model,
1084
- compat: model.compat ?? void 0
1085
- }, simpleReasoning)) ?? (usesBinaryOpenRouterThinking ? void 0 : "high");
1086
- const reasoning = resolveOpenAIRequestReasoning(model, requestedEffort);
1087
- const { effort, thinkingEnabled } = reasoning;
1088
1091
  if (isOpenRouter && model.reasoning) {
1089
1092
  if (usesBinaryOpenRouterThinking && thinkingEnabled !== void 0) params.reasoning = { enabled: thinkingEnabled };
1090
1093
  else if (effort !== void 0) params.reasoning = { effort };
@@ -1120,6 +1123,7 @@ const DEEPSEEK_DSML_TOOL_MAX_OPEN_TOKEN_LEN = Math.max(...DEEPSEEK_DSML_TOOL_OPE
1120
1123
  const DEEPSEEK_DSML_RECOVERY_MAX_BOUNDARY_LEN = Math.max(...DEEPSEEK_DSML_TOOL_OPEN_TOKENS.map((token) => token.length + 1), ...DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES.map((token) => token.length + 2));
1121
1124
  const MAX_DSML_RECOVERY_BUFFER_BYTES = 256e3;
1122
1125
  const DEEPSEEK_DSML_SCAN_BATCH_CHARS = 65536;
1126
+ const DSML_NAME_ATTRIBUTE_RE = /\bname=("([^"]*)"|'([^']*)'|([^\s>]+))/;
1123
1127
  function createDsmlRecoverer() {
1124
1128
  let buffer = "";
1125
1129
  let bufferBytes = 0;
@@ -1138,7 +1142,7 @@ function createDsmlRecoverer() {
1138
1142
  const open = activeOpenToken ? {
1139
1143
  index: 0,
1140
1144
  token: activeOpenToken
1141
- } : findEarliestStringToken(buffer, DEEPSEEK_DSML_TOOL_OPEN_TOKENS);
1145
+ } : findEarliestDsmlToken(buffer, DEEPSEEK_DSML_TOOL_OPEN_TOKENS);
1142
1146
  if (!open) {
1143
1147
  resetBlockScan();
1144
1148
  if (final) {
@@ -1151,7 +1155,7 @@ function createDsmlRecoverer() {
1151
1155
  bufferEndsWithHighSurrogate = false;
1152
1156
  return output;
1153
1157
  }
1154
- const keep = longestDeepSeekDsmlToolOpenPrefixSuffixLength(buffer);
1158
+ const keep = longestDsmlTokenPrefixSuffixLength(buffer, DEEPSEEK_DSML_TOOL_OPEN_TOKENS, DEEPSEEK_DSML_TOOL_MAX_OPEN_TOKEN_LEN);
1155
1159
  const emitLength = buffer.length - keep;
1156
1160
  if (emitLength > 0) {
1157
1161
  const emitted = buffer.slice(0, emitLength);
@@ -1237,7 +1241,7 @@ function parseDeepSeekDsmlToolCallBlock(body) {
1237
1241
  if (invokeCloseIndex === -1) break;
1238
1242
  const invokeBody = body.slice(invokeBodyStart, invokeCloseIndex);
1239
1243
  invokeOpenRegex.lastIndex = invokeCloseIndex + invokeCloseToken.length;
1240
- const invokeName = parseXmlAttribute(openMatch[2] ?? "", "name");
1244
+ const invokeName = parseDsmlNameAttribute(openMatch[2] ?? "");
1241
1245
  if (!invokeName) continue;
1242
1246
  const parsedArguments = parseDeepSeekDsmlInvokeArguments(invokeBody);
1243
1247
  if (!parsedArguments) continue;
@@ -1255,7 +1259,7 @@ function parseDeepSeekDsmlInvokeArguments(body) {
1255
1259
  const parameterRegex = new RegExp(`<${DEEPSEEK_DSML_MARKER_PATTERN}parameter\\b([^>]*)>([\\s\\S]*?)</\\1parameter>`, "g");
1256
1260
  let parameterMatch;
1257
1261
  while ((parameterMatch = parameterRegex.exec(body)) !== null) {
1258
- const name = parseXmlAttribute(parameterMatch[2] ?? "", "name");
1262
+ const name = parseDsmlNameAttribute(parameterMatch[2] ?? "");
1259
1263
  if (!name) continue;
1260
1264
  const rawValue = parameterMatch[3] ?? "";
1261
1265
  if (rawValue.length === 0) continue;
@@ -1272,34 +1276,14 @@ function parseDeepSeekDsmlInvokeArguments(body) {
1272
1276
  }
1273
1277
  return null;
1274
1278
  }
1275
- const xmlAttributeRegexCache = /* @__PURE__ */ new Map();
1276
- function xmlAttributeRegex(name) {
1277
- const cached = xmlAttributeRegexCache.get(name);
1278
- if (cached) return cached;
1279
- const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1280
- const pattern = new RegExp(`\\b${escaped}=("([^"]*)"|'([^']*)'|([^\\s>]+))`);
1281
- xmlAttributeRegexCache.set(name, pattern);
1282
- return pattern;
1283
- }
1284
- function parseXmlAttribute(attributes, name) {
1285
- const match = xmlAttributeRegex(name).exec(attributes);
1279
+ function parseDsmlNameAttribute(attributes) {
1280
+ const match = DSML_NAME_ATTRIBUTE_RE.exec(attributes);
1286
1281
  const value = match?.[2] ?? match?.[3] ?? match?.[4];
1287
1282
  return value ? decodeDeepSeekDsmlText(value) : null;
1288
1283
  }
1289
1284
  function decodeDeepSeekDsmlText(value) {
1290
1285
  return value.replaceAll("&quot;", "\"").replaceAll("&apos;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
1291
1286
  }
1292
- function findEarliestStringToken(text, tokens, fromIndex = 0) {
1293
- let best = null;
1294
- for (const token of tokens) {
1295
- const index = text.indexOf(token, fromIndex);
1296
- if (index !== -1 && (!best || index < best.index)) best = {
1297
- index,
1298
- token
1299
- };
1300
- }
1301
- return best;
1302
- }
1303
1287
  function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
1304
1288
  while (state.offset < text.length) {
1305
1289
  if (state.invoke?.kind === "open") {
@@ -1338,9 +1322,9 @@ function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
1338
1322
  state.invoke = void 0;
1339
1323
  continue;
1340
1324
  }
1341
- const toolOpen = findEarliestStringToken(text, DEEPSEEK_DSML_TOOL_OPEN_TOKENS, state.offset);
1325
+ const toolOpen = findEarliestDsmlToken(text, DEEPSEEK_DSML_TOOL_OPEN_TOKENS, state.offset);
1342
1326
  const toolCloseIndex = text.indexOf(closeToken, state.offset);
1343
- const invokeOpen = findEarliestStringToken(text, DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES, state.offset);
1327
+ const invokeOpen = findEarliestDsmlToken(text, DEEPSEEK_DSML_INVOKE_OPEN_PREFIXES, state.offset);
1344
1328
  const next = [
1345
1329
  toolOpen ? {
1346
1330
  kind: "nested-open",
@@ -1372,14 +1356,6 @@ function scanDeepSeekDsmlToolBlock(text, closeToken, contentStartIndex, state) {
1372
1356
  }
1373
1357
  return { kind: "incomplete" };
1374
1358
  }
1375
- function longestDeepSeekDsmlToolOpenPrefixSuffixLength(text) {
1376
- const maxLength = Math.min(text.length, DEEPSEEK_DSML_TOOL_MAX_OPEN_TOKEN_LEN - 1);
1377
- for (let length = maxLength; length > 0; length -= 1) {
1378
- const suffix = text.slice(text.length - length);
1379
- if (DEEPSEEK_DSML_TOOL_OPEN_TOKENS.some((token) => token.startsWith(suffix))) return length;
1380
- }
1381
- return 0;
1382
- }
1383
1359
  //#endregion
1384
1360
  //#region packages/ai/src/transports/openai-completions-stream.ts
1385
1361
  function extractToolCallThoughtSignature(toolCall) {
@@ -1414,7 +1390,7 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1414
1390
  let isFlushingPendingPostToolCallDeltas = false;
1415
1391
  const toolCallBlocksByIndex = /* @__PURE__ */ new Map();
1416
1392
  const toolCallBlocksById = /* @__PURE__ */ new Map();
1417
- const encryptedReasoning = directMode ? createOpenAIEncryptedToolCallReasoningTracker() : void 0;
1393
+ const encryptedReasoning = createOpenAIEncryptedToolCallReasoningTracker();
1418
1394
  const toolArgumentPreviewSchedules = /* @__PURE__ */ new WeakMap();
1419
1395
  const provisionalCommentaryTags = directMode ? options.provisionalCommentaryTags : /* @__PURE__ */ new Map();
1420
1396
  const contentBlockIndices = /* @__PURE__ */ new WeakMap();
@@ -1424,29 +1400,20 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1424
1400
  let finishReason;
1425
1401
  let sawNativeToolCallDelta = false;
1426
1402
  const blockIndex = () => directMode && currentBlock && currentBlock.type !== "toolCall" ? contentBlockIndices.get(currentBlock) ?? output.content.length - 1 : output.content.length - 1;
1427
- const measureUtf8Bytes = (text) => Buffer.byteLength(text, "utf8");
1428
1403
  let chunkPushedEvent = false;
1429
1404
  const pushStreamEvent = (event) => {
1430
1405
  chunkPushedEvent = true;
1431
1406
  stream.push(event);
1432
1407
  };
1433
1408
  const queuePostToolCallDelta = (next) => {
1434
- const nextBytes = measureUtf8Bytes(next.text);
1409
+ const nextBytes = Buffer.byteLength(next.text, "utf8");
1435
1410
  if (pendingPostToolCallBytes + nextBytes > MAX_POST_TOOL_CALL_BUFFER_BYTES) throw new Error("Exceeded post-tool-call delta buffer limit");
1436
1411
  pendingPostToolCallBytes += nextBytes;
1437
1412
  const previous = pendingPostToolCallDeltas[pendingPostToolCallDeltas.length - 1];
1438
- if (!previous || previous.kind !== next.kind || previous.kind === "text" && next.kind === "text" && previous.source !== next.source) {
1413
+ if (!previous || previous.kind !== next.kind || previous.kind === "text" && next.kind === "text" && previous.source !== next.source || previous.kind === "thinking" && next.kind === "thinking" && previous.signature !== next.signature) {
1439
1414
  pendingPostToolCallDeltas.push(next);
1440
1415
  return;
1441
1416
  }
1442
- if (next.kind === "thinking" && previous.kind === "thinking") {
1443
- if (previous.signature !== next.signature) {
1444
- pendingPostToolCallDeltas.push(next);
1445
- return;
1446
- }
1447
- previous.text += next.text;
1448
- return;
1449
- }
1450
1417
  previous.text += next.text;
1451
1418
  };
1452
1419
  const appendThinkingDeltaInternal = (reasoningDelta) => {
@@ -1583,23 +1550,7 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1583
1550
  partial: output
1584
1551
  });
1585
1552
  };
1586
- const appendFilteredVisibleTextDelta = (text) => {
1587
- const recoveredParts = deepSeekToolCallRecoverer?.push(text) ?? [{
1588
- kind: "text",
1589
- text
1590
- }];
1591
- for (const recoveredPart of recoveredParts) {
1592
- if (recoveredPart.kind === "toolCall") {
1593
- appendRecoveredToolCall(recoveredPart);
1594
- continue;
1595
- }
1596
- const parts = deepSeekTextFilter?.push(recoveredPart.text) ?? [recoveredPart.text];
1597
- for (const part of parts) appendVisibleTextDelta(part);
1598
- }
1599
- };
1600
- const flushDeepSeekToolCallRecovererAtEnd = () => {
1601
- const recoveredParts = deepSeekToolCallRecoverer?.flush();
1602
- if (!recoveredParts) return;
1553
+ const appendRecoveredParts = (recoveredParts) => {
1603
1554
  for (const recoveredPart of recoveredParts) {
1604
1555
  if (recoveredPart.kind === "toolCall") {
1605
1556
  appendRecoveredToolCall(recoveredPart);
@@ -1609,19 +1560,11 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1609
1560
  for (const part of parts) appendVisibleTextDelta(part);
1610
1561
  }
1611
1562
  };
1612
- const flushDeepSeekTextFilterAtEnd = () => {
1613
- const parts = deepSeekTextFilter?.flush();
1614
- if (!parts) return;
1615
- for (const part of parts) appendVisibleTextDelta(part);
1616
- };
1617
- const appendRoutedContentDelta = (delta) => {
1618
- if (delta.kind === "text") {
1619
- appendFilteredVisibleTextDelta(delta.text);
1620
- return;
1621
- }
1622
- if (!emitReasoning) return;
1623
- if (currentBlock?.type === "toolCall" && !directMode) queuePostToolCallDelta(delta);
1624
- else appendThinkingDelta(delta);
1563
+ const appendFilteredVisibleTextDelta = (text) => {
1564
+ appendRecoveredParts(deepSeekToolCallRecoverer?.push(text) ?? [{
1565
+ kind: "text",
1566
+ text
1567
+ }]);
1625
1568
  };
1626
1569
  const appendPartitionedVisibleDelta = (delta) => {
1627
1570
  if (delta.kind === "text") appendFilteredVisibleTextDelta(delta.text);
@@ -1653,7 +1596,6 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1653
1596
  if (forceStrict || reasoningTagTextPartitioner.hasPending()) reasoningTagTextPartitioner.markStrict();
1654
1597
  if (!hasFollowingVisibleText || !reasoningTagTextPartitioner.hasPendingSyntax()) sealTextBeforeReasoning();
1655
1598
  };
1656
- const cooperativeScheduler = directMode ? void 0 : createModelStreamCooperativeScheduler(options?.signal);
1657
1599
  const guardedStream = withFirstStreamEventTimeout(responseStream, {
1658
1600
  provider: model.provider,
1659
1601
  api: model.api,
@@ -1664,13 +1606,11 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1664
1606
  onTimeout: options?.onFirstEventTimeout,
1665
1607
  hint: "The provider may be stalled while parsing the tool payload; retry with a smaller tool surface or enable OPENCLAW_DEBUG_MODEL_PAYLOAD=tools to inspect exposed tools."
1666
1608
  });
1667
- for await (const rawChunk of guardedStream) {
1609
+ const events = directMode ? guardedStream : iterateModelStream(guardedStream, options?.signal);
1610
+ for await (const rawChunk of events) {
1668
1611
  throwIfModelStreamAborted(options?.signal);
1669
1612
  chunkPushedEvent = false;
1670
- if (!rawChunk || typeof rawChunk !== "object") {
1671
- if (cooperativeScheduler) await cooperativeScheduler.afterEvent();
1672
- continue;
1673
- }
1613
+ if (!rawChunk || typeof rawChunk !== "object") continue;
1674
1614
  notifyLlmRequestActivity(options?.signal);
1675
1615
  const chunk = rawChunk;
1676
1616
  output.responseId ||= chunk.id;
@@ -1683,7 +1623,6 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1683
1623
  const choice = Array.isArray(chunk.choices) ? chunk.choices[0] : void 0;
1684
1624
  if (!choice) {
1685
1625
  emitReasoningUsageActivity(hasReasoningUsageActivity);
1686
- if (cooperativeScheduler) await cooperativeScheduler.afterEvent();
1687
1626
  continue;
1688
1627
  }
1689
1628
  const choiceUsage = choice.usage;
@@ -1700,7 +1639,6 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1700
1639
  const rawChoiceDelta = choice.delta ?? choice.message;
1701
1640
  if (!rawChoiceDelta) {
1702
1641
  emitReasoningUsageActivity(hasReasoningUsageActivity);
1703
- if (cooperativeScheduler) await cooperativeScheduler.afterEvent();
1704
1642
  continue;
1705
1643
  }
1706
1644
  for (const normalizedDelta of normalizeToolCallDeltas(rawChoiceDelta, choice.finish_reason)) {
@@ -1721,7 +1659,10 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1721
1659
  for (const routedDelta of routedDeltas) appendPartitionedVisibleDelta(routedDelta);
1722
1660
  } else {
1723
1661
  beginReasoning(contentDeltaIndex < lastVisibleTextIndex);
1724
- appendRoutedContentDelta(contentDelta);
1662
+ if (emitReasoning) {
1663
+ if (currentBlock?.type === "toolCall" && !directMode) queuePostToolCallDelta(contentDelta);
1664
+ else appendThinkingDelta(contentDelta);
1665
+ }
1725
1666
  }
1726
1667
  if (!hasReasoningThinking) appendReasoningDeltas(reasoningDeltas);
1727
1668
  const toolCallDeltas = normalizedDelta.toolCalls;
@@ -1749,7 +1690,7 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1749
1690
  partialArgs: "",
1750
1691
  ...initialSig ? { thoughtSignature: initialSig } : {}
1751
1692
  };
1752
- encryptedReasoning?.rememberToolCall(block.id, block);
1693
+ encryptedReasoning.rememberToolCall(block.id, block);
1753
1694
  toolArgumentPreviewSchedules.set(block, createToolArgumentPreviewSchedule());
1754
1695
  output.content.push(block);
1755
1696
  toolCallBlockIndices.set(block, output.content.length - 1);
@@ -1761,9 +1702,10 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1761
1702
  }
1762
1703
  if (streamIndex !== void 0 && !toolCallBlocksByIndex.has(streamIndex)) toolCallBlocksByIndex.set(streamIndex, block);
1763
1704
  if (toolCall.id) {
1705
+ const previousId = block.id;
1764
1706
  if (!directMode || !block.id) block.id = toolCall.id;
1765
1707
  toolCallBlocksById.set(toolCall.id, block);
1766
- if (block.id === toolCall.id) encryptedReasoning?.rememberToolCall(toolCall.id, block);
1708
+ if (block.id === toolCall.id) encryptedReasoning.rememberToolCall(toolCall.id, block, previousId);
1767
1709
  }
1768
1710
  currentBlock = block;
1769
1711
  const conflictingId = directMode && block.id && toolCall.id && block.id !== toolCall.id;
@@ -1783,17 +1725,16 @@ async function processCompletionsStream(responseStream, output, model, stream, o
1783
1725
  });
1784
1726
  }
1785
1727
  }
1786
- encryptedReasoning?.consumeDetails(deltaFields.reasoning_details);
1728
+ encryptedReasoning.consumeDetails(deltaFields.reasoning_details);
1787
1729
  }
1788
1730
  flushPendingPostToolCallDeltas();
1789
1731
  emitReasoningUsageActivity(hasReasoningUsageActivity);
1790
- if (cooperativeScheduler) await cooperativeScheduler.afterEvent();
1791
1732
  }
1792
1733
  throwIfModelStreamAborted(options?.signal);
1793
1734
  if (!finishReason && (directMode || options?.sawStreamDONE?.() === false)) throw new Error("Stream ended without finish_reason");
1794
1735
  flushReasoningTagTextPartitioner();
1795
- flushDeepSeekToolCallRecovererAtEnd();
1796
- flushDeepSeekTextFilterAtEnd();
1736
+ appendRecoveredParts(deepSeekToolCallRecoverer?.flush() ?? []);
1737
+ for (const part of deepSeekTextFilter?.flush() ?? []) appendVisibleTextDelta(part);
1797
1738
  currentBlock = null;
1798
1739
  flushPendingPostToolCallDeltas();
1799
1740
  finalizeOpenAICompletionsToolCalls(output, {
@@ -1,5 +1,5 @@
1
- import { M as OpenAICompletionsCompat, O as Model, l as CacheRetention } from "./types-4_uVs5WH.mjs";
2
- import "./types-DkJfb4W3.mjs";
1
+ import { M as OpenAICompletionsCompat, O as Model, l as CacheRetention } from "./types-CLLR3eB4.mjs";
2
+ import "./types-CB-_vNyI.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-CkwdxTZx.mjs";
1
+ import { n as isNativeOpenAIEndpoint } from "./openai-completions-compat-BOVWBZDn.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,5 +1,5 @@
1
- import { n as getAiTransportHost } from "./host-B4MeUNBc.mjs";
2
- import { k as resolveOpenAIClientBaseUrl } from "./openai-transport-params-DQeuAvBl.mjs";
1
+ import { n as getAiTransportHost } from "./host-CHi3X87F.mjs";
2
+ import { O as resolveOpenAIClientBaseUrl } from "./openai-transport-params-BwlpzX-2.mjs";
3
3
  import { i as resolveCloudflareBaseUrl, r as isCloudflareProvider } from "./github-copilot-headers-B37TB3rB.mjs";
4
4
  import OpenAI from "openai";
5
5
  //#region packages/ai/src/providers/openai-provider-client.ts