@openclaw/ai 2026.9.6 → 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 (99) hide show
  1. package/dist/{anthropic-DZQ_7gD1.mjs → anthropic-Cw2pgccz.mjs} +37 -66
  2. package/dist/{anthropic-payload-policy-DyfwikYJ.d.mts → anthropic-payload-policy-NIPVYXPq.d.mts} +7 -5
  3. package/dist/{anthropic-stream-reducer-D6ZI1wwj.mjs → anthropic-stream-reducer-D9MCkl8Z.mjs} +192 -261
  4. package/dist/{api-registry-C2T3lTV7.d.mts → api-registry-D-nbmSqr.d.mts} +2 -2
  5. package/dist/{azure-openai-responses-DS86GYzq.mjs → azure-openai-responses-BwT3-X8P.mjs} +22 -33
  6. package/dist/{base64-CPmadnUf.mjs → base64-C1PsYcRQ.mjs} +15 -9
  7. package/dist/{diagnostics-CH8j2wIG.mjs → diagnostics-CJaB6g8J.mjs} +3 -3
  8. package/dist/diagnostics.d.mts +4 -4
  9. package/dist/diagnostics.mjs +2 -2
  10. package/dist/{env-api-keys-bktO00EJ.mjs → env-api-keys-CyX4VKGO.mjs} +7 -5
  11. package/dist/event-stream-CMQfX_yr.d.mts +1 -0
  12. package/dist/{event-stream-CjnIZZst.d.mts → event-stream-DOPFYVqs.d.mts} +2 -2
  13. package/dist/{event-stream-D8PARQfL.mjs → event-stream-vd9UnCAU.mjs} +10 -0
  14. package/dist/event-stream.d.mts +2 -2
  15. package/dist/event-stream.mjs +1 -1
  16. package/dist/{google-BZJFjhuC.mjs → google-BfapkS_K.mjs} +8 -11
  17. package/dist/google-interactions-DW3iXzjc.mjs +574 -0
  18. package/dist/{google-messages-DB7GKkDk.mjs → google-messages-CtjVtVot.mjs} +35 -71
  19. package/dist/{google-shared-Bok4I6zB.mjs → google-shared-Y2YfotEu.mjs} +43 -47
  20. package/dist/{google-vertex-3eVNR2qW.mjs → google-vertex-Dov4kBWu.mjs} +16 -30
  21. package/dist/{host-yTvBrYM2.mjs → host-CHi3X87F.mjs} +29 -188
  22. package/dist/{host-policy-DZO3oPPk.mjs → host-policy-BOAwRg_M.mjs} +2 -14
  23. package/dist/{host-DH-Z-LDb.d.mts → host-rxlNaBwm.d.mts} +9 -3
  24. package/dist/{index-C25RT6bP.d.mts → index-D6KsSE74.d.mts} +28 -8
  25. package/dist/index.d.mts +7 -7
  26. package/dist/index.mjs +6 -6
  27. package/dist/internal/anthropic.d.mts +8 -7
  28. package/dist/internal/anthropic.mjs +5 -5
  29. package/dist/internal/openai-completions-compat.d.mts +1 -1
  30. package/dist/internal/openai-completions-compat.mjs +1 -1
  31. package/dist/internal/openai-responses-payload-policy.d.mts +1 -1
  32. package/dist/internal/openai-responses-payload-policy.mjs +2 -2
  33. package/dist/internal/openai.d.mts +31 -8
  34. package/dist/internal/openai.mjs +13 -13
  35. package/dist/internal/runtime.d.mts +31 -70
  36. package/dist/internal/runtime.mjs +10 -65
  37. package/dist/internal/shared.d.mts +14 -12
  38. package/dist/internal/shared.mjs +5 -4
  39. package/dist/internal/tool-schema.d.mts +1 -1
  40. package/dist/internal/tool-schema.mjs +2 -2
  41. package/dist/{mistral-C_13dVBn.mjs → mistral-RS6mboC-.mjs} +46 -93
  42. package/dist/{openai-chatgpt-responses-sTxPl4zM.mjs → openai-chatgpt-responses-CYbidtrn.mjs} +26 -30
  43. package/dist/{openai-completions-BO6D_hrB.mjs → openai-completions-D14ihPYk.mjs} +14 -12
  44. package/dist/{openai-completions-compat-CUollwl6.mjs → openai-completions-compat-BOVWBZDn.mjs} +3 -5
  45. package/dist/{openai-completions-compat-DfJG1wSO.d.mts → openai-completions-compat-qJjmqQ71.d.mts} +3 -3
  46. package/dist/{openai-completions-stream-BpuJ0ZOA.mjs → openai-completions-stream-CDCuw3DP.mjs} +101 -173
  47. package/dist/{openai-prompt-cache-C4RHdN4n.d.mts → openai-prompt-cache-CouErLh7.d.mts} +2 -2
  48. package/dist/{openai-prompt-cache-CjV_2IRI.mjs → openai-prompt-cache-D2V7MqR7.mjs} +1 -1
  49. package/dist/{openai-provider-client-BP8J1aeg.mjs → openai-provider-client-CwfsGBbA.mjs} +2 -2
  50. package/dist/{openai-reasoning-effort-ash8dPrd.mjs → openai-reasoning-effort-ConhwkeX.mjs} +2 -1
  51. package/dist/{openai-responses-BJ_IEoMU.mjs → openai-responses-CKCBEc2W.mjs} +12 -11
  52. package/dist/openai-responses-compaction-replay-DiYn-gFM.d.mts +12 -0
  53. package/dist/{openai-responses-compaction-window-BiNCT0bS.mjs → openai-responses-compaction-window-UNK1GDpy.mjs} +5 -5
  54. package/dist/{openai-responses-contracts-DWrfMODE.mjs → openai-responses-contracts-CLxnqS9p.mjs} +1 -1
  55. package/dist/{openai-responses-contracts-B1ENJFpI.d.mts → openai-responses-contracts-D1iZ0njF.d.mts} +4 -4
  56. package/dist/{openai-responses-prompt-observer-internal-DPHWgbBH.mjs → openai-responses-prompt-observer-internal-iAqLb4tk.mjs} +12 -12
  57. package/dist/{openai-responses-request-lifecycle-DFuyO1pQ.mjs → openai-responses-request-lifecycle-Fsag-IGZ.mjs} +1 -1
  58. package/dist/{openai-responses-shared-DvSqtJ6_.mjs → openai-responses-shared-DL4ulQn7.mjs} +312 -122
  59. package/dist/{openai-responses-terminal-usage-BNFbvY9f.d.mts → openai-responses-terminal-usage-BE7lf7nW.d.mts} +2 -2
  60. package/dist/{openai-stop-reason-Drnn_6Qj.mjs → openai-stop-reason-8s70vDXj.mjs} +2 -12
  61. package/dist/{openai-tool-schema-ynZBgqW-.d.mts → openai-tool-schema-a5ysBBga.d.mts} +0 -6
  62. package/dist/{openai-tool-schema-D4BMcj2D.mjs → openai-tool-schema-vsl-cE-n.mjs} +243 -383
  63. package/dist/{openai-transport-params-DZKOTSfH.mjs → openai-transport-params-BwlpzX-2.mjs} +60 -105
  64. package/dist/{positive-integer-BiUxrd71.mjs → positive-integer-CjN5OJbH.mjs} +1 -1
  65. package/dist/{provider-error-CRhW7lkJ.mjs → provider-error-CwT_j2v0.mjs} +43 -4
  66. package/dist/{provider-options-DZYq53lj.d.mts → provider-options-Df7ov0K1.d.mts} +2 -2
  67. package/dist/{provider-replay-context-DPr3w20a.mjs → provider-replay-context-DsyI5jOP.mjs} +1 -1
  68. package/dist/{provider-transcript-transform-BTocjCRs.mjs → provider-transcript-transform-JbFbHV8h.mjs} +17 -2
  69. package/dist/{provider-transport-turn-state-lrXEFkYr.mjs → provider-transport-turn-state-BheUi_hl.mjs} +1 -1
  70. package/dist/{provider-types-w1rEqrGP.d.mts → provider-types-d4XnoZMd.d.mts} +3 -3
  71. package/dist/provider-types.d.mts +6 -6
  72. package/dist/providers.d.mts +2 -2
  73. package/dist/providers.mjs +15 -11
  74. package/dist/{reasoning-tag-text-partitioner-Di38crhI.mjs → reasoning-tag-text-partitioner-B6FIIBt6.mjs} +47 -71
  75. package/dist/{record-coerce-DwRYMj3t.mjs → record-coerce-CNDovvft.mjs} +1 -1
  76. package/dist/simple-options-CGAkCwtM.mjs +349 -0
  77. package/dist/{src-DwGYYyZp.mjs → src-H4aXcFuX.mjs} +43 -25
  78. package/dist/{stream-CREqxHgU.mjs → stream-DDsCBgd-.mjs} +1 -7
  79. package/dist/{stream-first-event-timeout-BeptfRL6.mjs → stream-first-event-timeout-B9o0S4SZ.mjs} +1 -1
  80. package/dist/{tool-schema-json-projection-CD9c_fK8.mjs → tool-schema-json-projection-Ct8SeBeJ.mjs} +63 -23
  81. package/dist/{transport-stream-shared-B5RioB_Q.mjs → transport-stream-shared-Dh5qKJ8e.mjs} +62 -28
  82. package/dist/{transport-stream-shared-B7Z9oCYg.d.mts → transport-stream-shared-yYhXa4kX.d.mts} +12 -6
  83. package/dist/{transport-utils-03Qi0CN2.mjs → transport-utils-C-4bf2Ok.mjs} +3 -4
  84. package/dist/transports.d.mts +36 -32
  85. package/dist/transports.mjs +160 -216
  86. package/dist/types-CB-_vNyI.d.mts +1 -0
  87. package/dist/{types-qZFbaDbK.d.mts → types-CLLR3eB4.d.mts} +3 -1
  88. package/dist/types.d.mts +6 -6
  89. package/dist/types.mjs +4 -4
  90. package/dist/{validation-Dw7cb6BV.mjs → validation-BFZc40Ig.mjs} +80 -54
  91. package/dist/{validation-DhQhmt6t.d.mts → validation-Cat2wQsc.d.mts} +1 -1
  92. package/dist/validation.d.mts +1 -1
  93. package/dist/validation.mjs +1 -1
  94. package/package.json +5 -5
  95. package/dist/assistant-output-DM1JBNs1.mjs +0 -16
  96. package/dist/event-stream-C0nsgbj2.d.mts +0 -1
  97. package/dist/simple-options-np1XPuhm.mjs +0 -175
  98. package/dist/types-DTvddOfm.d.mts +0 -1
  99. package/dist/utf16-slice-CvGodqok.mjs +0 -29
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
- import "./provider-error-CRhW7lkJ.mjs";
2
+ import "./provider-error-CwT_j2v0.mjs";
3
3
  import { t as expectDefined } from "./expect-lbe3Hgrh.mjs";
4
4
  //#region node_modules/.pnpm/mdast-util-to-string@4.0.0/node_modules/mdast-util-to-string/lib/index.js
5
5
  /**
@@ -11657,7 +11657,7 @@ function scanReasoningTags(text, final = true) {
11657
11657
  }
11658
11658
  return { tags };
11659
11659
  }
11660
- function parseReasoningTagAt(text, start, final) {
11660
+ function parseReasoningTagName(text, start) {
11661
11661
  let cursor = skipTagWhitespace(text, start + 1);
11662
11662
  let isClose = false;
11663
11663
  if (text.charAt(cursor) === "/") {
@@ -11667,17 +11667,27 @@ function parseReasoningTagAt(text, start, final) {
11667
11667
  const nameStart = cursor;
11668
11668
  while (cursor < text.length && isTagNameCharacter(text.charCodeAt(cursor))) cursor += 1;
11669
11669
  const partialName = text.slice(nameStart, cursor).toLowerCase();
11670
- if (!partialName) return cursor === text.length && !final ? { kind: "pending" } : invalidTag(text, start);
11670
+ if (!partialName) return { kind: cursor === text.length ? "pending" : "invalid" };
11671
11671
  if (!REASONING_TAG_NAME_SET.has(partialName)) {
11672
11672
  const canBecomeKnown = REASONING_TAG_NAMES.some((name) => name.startsWith(partialName));
11673
- return cursor === text.length && !final && canBecomeKnown ? { kind: "pending" } : invalidTag(text, start);
11673
+ return { kind: cursor === text.length && canBecomeKnown ? "pending" : "invalid" };
11674
11674
  }
11675
- if (cursor === text.length) return final ? invalidTag(text, start) : { kind: "pending" };
11675
+ if (cursor === text.length) return { kind: "pending" };
11676
11676
  const boundary = text.charAt(cursor);
11677
- if (!isTagWhitespace(boundary) && boundary !== "/" && boundary !== ">") return invalidTag(text, start);
11677
+ if (!isTagWhitespace(boundary) && boundary !== "/" && boundary !== ">") return { kind: "invalid" };
11678
+ return {
11679
+ kind: "name",
11680
+ end: cursor,
11681
+ isClose,
11682
+ isPrivate: partialName === "internal"
11683
+ };
11684
+ }
11685
+ function parseReasoningTagAt(text, start, final) {
11686
+ const name = parseReasoningTagName(text, start);
11687
+ if (name.kind !== "name") return name.kind === "pending" && !final ? { kind: "pending" } : invalidTag(text, start);
11678
11688
  let quote;
11679
11689
  let lastSignificant = "";
11680
- for (; cursor < text.length; cursor += 1) {
11690
+ for (let cursor = name.end; cursor < text.length; cursor += 1) {
11681
11691
  const char = text.charAt(cursor);
11682
11692
  if (quote) {
11683
11693
  if (char === quote) quote = void 0;
@@ -11695,9 +11705,9 @@ function parseReasoningTagAt(text, start, final) {
11695
11705
  tag: {
11696
11706
  index: start,
11697
11707
  text: text.slice(start, end),
11698
- isClose,
11699
- isSelfClosing: !isClose && lastSignificant === "/",
11700
- isPrivate: partialName === "internal"
11708
+ isClose: name.isClose,
11709
+ isSelfClosing: !name.isClose && lastSignificant === "/",
11710
+ isPrivate: name.isPrivate
11701
11711
  }
11702
11712
  };
11703
11713
  }
@@ -11729,6 +11739,14 @@ function findNextLineEnding(text, start) {
11729
11739
  if (carriageReturn === -1) return lineFeed;
11730
11740
  return lineFeed === -1 ? carriageReturn : Math.min(carriageReturn, lineFeed);
11731
11741
  }
11742
+ function appendMarkdownSource(source, start, token, value) {
11743
+ const extra = value.length - (token.end.offset - token.start.offset);
11744
+ for (let cursor = start + source.offsets.length; cursor < token.end.offset; cursor += 1) {
11745
+ const consumed = cursor - token.start.offset;
11746
+ source.offsets.push(source.value.length + (consumed > 0 ? consumed + extra : 0));
11747
+ }
11748
+ source.value += value;
11749
+ }
11732
11750
  function captureInlineSources(text, sources) {
11733
11751
  const observe = function(token) {
11734
11752
  const start = this.stack.findLast((entry) => entry.type === "inlineCode")?.position?.start.offset;
@@ -11753,13 +11771,7 @@ function captureInlineSources(text, sources) {
11753
11771
  };
11754
11772
  sources.set(start, source);
11755
11773
  }
11756
- const value = this.sliceSerialize(token);
11757
- const extra = value.length - (token.end.offset - token.start.offset);
11758
- for (let cursor = start + source.offsets.length; cursor < token.end.offset; cursor += 1) {
11759
- const consumed = cursor - token.start.offset;
11760
- source.offsets.push(source.value.length + (consumed > 0 ? consumed + extra : 0));
11761
- }
11762
- source.value += value;
11774
+ appendMarkdownSource(source, start, token, this.sliceSerialize(token));
11763
11775
  };
11764
11776
  return { enter: {
11765
11777
  codeTextData(token) {
@@ -11786,13 +11798,7 @@ function captureIndentedSources(text, sources, observeInlineLineEnding) {
11786
11798
  };
11787
11799
  sources.set(start, source);
11788
11800
  }
11789
- const value = this.sliceSerialize(token);
11790
- const extra = value.length - (token.end.offset - token.start.offset);
11791
- for (let cursor = start + source.offsets.length; cursor < token.end.offset; cursor += 1) {
11792
- const consumed = cursor - token.start.offset;
11793
- source.offsets.push(source.value.length + (consumed > 0 ? consumed + extra : 0));
11794
- }
11795
- source.value += value;
11801
+ appendMarkdownSource(source, start, token, this.sliceSerialize(token));
11796
11802
  };
11797
11803
  return { enter: {
11798
11804
  codeFlowValue(token) {
@@ -12020,18 +12026,6 @@ function endsBlankBlock(text) {
12020
12026
  while (text[cursor] === " " || text[cursor] === " ") cursor -= 1;
12021
12027
  return text[cursor] === "\n" || text[cursor] === "\r";
12022
12028
  }
12023
- function reasoningTagNameStatus(text) {
12024
- let cursor = skipTagWhitespace(text, 1);
12025
- if (text.charAt(cursor) === "/") cursor = skipTagWhitespace(text, cursor + 1);
12026
- const start = cursor;
12027
- while (cursor < text.length && isTagNameCharacter(text.charCodeAt(cursor))) cursor += 1;
12028
- const name = text.slice(start, cursor).toLowerCase();
12029
- if (!name) return cursor === text.length ? "partial" : "invalid";
12030
- if (!REASONING_TAG_NAME_SET.has(name)) return REASONING_TAG_NAMES.some((known) => known.startsWith(name)) && cursor === text.length ? "partial" : "invalid";
12031
- if (cursor === text.length) return "partial";
12032
- const boundary = text.charAt(cursor);
12033
- return isTagWhitespace(boundary) || boundary === "/" || boundary === ">" ? "resolved" : "invalid";
12034
- }
12035
12029
  function advancePendingTagProbe(probe, text) {
12036
12030
  for (const char of text) {
12037
12031
  if (probe.quote) {
@@ -12067,6 +12061,15 @@ function createReasoningTagTextPartitioner() {
12067
12061
  let nonFinalOpenEndedCode = false;
12068
12062
  let nonFinalRetainStart = 0;
12069
12063
  let nonFinalCloseReparseUsed = false;
12064
+ const startPendingTagProbe = (start, end) => {
12065
+ pendingTagProbe = {
12066
+ nameResolved: false,
12067
+ resolved: false,
12068
+ scannedThrough: end,
12069
+ start
12070
+ };
12071
+ advancePendingTagProbe(pendingTagProbe, source.slice(start + 1, end));
12072
+ };
12070
12073
  const compactCommittedSource = (retainStart) => {
12071
12074
  source = source.slice(retainStart);
12072
12075
  endedBlankBlock = endsBlankBlock(source);
@@ -12109,15 +12112,7 @@ function createReasoningTagTextPartitioner() {
12109
12112
  }));
12110
12113
  emitted = reduceEnd;
12111
12114
  fastPathCheckedThrough = reduceEnd;
12112
- if (scan.pendingStart !== void 0) {
12113
- pendingTagProbe = {
12114
- nameResolved: false,
12115
- resolved: false,
12116
- scannedThrough: limit,
12117
- start: reduceEnd
12118
- };
12119
- advancePendingTagProbe(pendingTagProbe, source.slice(reduceEnd + 1, limit));
12120
- }
12115
+ if (scan.pendingStart !== void 0) startPendingTagProbe(reduceEnd, limit);
12121
12116
  holdStart = reduction.depth > 0 || scan.pendingStart !== void 0 ? emitted : void 0;
12122
12117
  return;
12123
12118
  }
@@ -12151,8 +12146,7 @@ function createReasoningTagTextPartitioner() {
12151
12146
  emitted = end;
12152
12147
  }
12153
12148
  if (special === -1) return;
12154
- const tail = source.slice(special, limit);
12155
- const parsed = parseReasoningTagAt(tail, 0, false);
12149
+ const parsed = parseReasoningTagAt(source.slice(special, limit), 0, false);
12156
12150
  if (parsed.kind === "invalid") {
12157
12151
  merge(output, [{
12158
12152
  kind: "text",
@@ -12164,13 +12158,7 @@ function createReasoningTagTextPartitioner() {
12164
12158
  }
12165
12159
  holdStart = special;
12166
12160
  if (parsed.kind === "pending") {
12167
- pendingTagProbe = {
12168
- nameResolved: false,
12169
- resolved: false,
12170
- scannedThrough: limit,
12171
- start: special
12172
- };
12173
- advancePendingTagProbe(pendingTagProbe, tail.slice(1));
12161
+ startPendingTagProbe(special, limit);
12174
12162
  return;
12175
12163
  }
12176
12164
  if (/[\r\n]/u.test(source.slice(blockStart, special))) return;
@@ -12203,13 +12191,7 @@ function createReasoningTagTextPartitioner() {
12203
12191
  fastPathCheckedThrough = reduceEnd;
12204
12192
  if (pendingAt !== void 0) {
12205
12193
  holdStart = reduceEnd;
12206
- pendingTagProbe = {
12207
- nameResolved: false,
12208
- resolved: false,
12209
- scannedThrough: limit,
12210
- start: reduceEnd
12211
- };
12212
- advancePendingTagProbe(pendingTagProbe, source.slice(reduceEnd + 1, limit));
12194
+ startPendingTagProbe(reduceEnd, limit);
12213
12195
  } else holdStart = reduction.depth > 0 ? emitted : void 0;
12214
12196
  }
12215
12197
  };
@@ -12243,13 +12225,7 @@ function createReasoningTagTextPartitioner() {
12243
12225
  pendingTagProbe = void 0;
12244
12226
  const pendingStart = scanReasoningTags(held, false).pendingStart;
12245
12227
  if (pendingStart !== void 0) {
12246
- pendingTagProbe = {
12247
- nameResolved: false,
12248
- resolved: false,
12249
- scannedThrough: end,
12250
- start: holdStart + pendingStart
12251
- };
12252
- advancePendingTagProbe(pendingTagProbe, held.slice(pendingStart + 1));
12228
+ startPendingTagProbe(holdStart + pendingStart, end);
12253
12229
  return false;
12254
12230
  }
12255
12231
  }
@@ -12301,9 +12277,9 @@ function createReasoningTagTextPartitioner() {
12301
12277
  advancePendingTagProbe(pendingTagProbe, source.slice(pendingTagProbe.scannedThrough));
12302
12278
  pendingTagProbe.scannedThrough = source.length;
12303
12279
  if (!pendingTagProbe.nameResolved) {
12304
- const status = reasoningTagNameStatus(source.slice(pendingTagProbe.start));
12305
- pendingTagProbe.nameResolved = status === "resolved";
12306
- pendingTagProbe.resolved ||= status === "invalid";
12280
+ const name = parseReasoningTagName(source, pendingTagProbe.start);
12281
+ pendingTagProbe.nameResolved = name.kind === "name";
12282
+ pendingTagProbe.resolved ||= name.kind === "invalid";
12307
12283
  }
12308
12284
  }
12309
12285
  if (pendingTagProbe?.resolved && holdStart !== void 0) {
@@ -5,7 +5,7 @@ function isRecord(value) {
5
5
  }
6
6
  /** Coerces object-like values to records, falling back to an empty record. */
7
7
  function asRecord(value) {
8
- return typeof value === "object" && value !== null ? value : {};
8
+ return asOptionalObjectRecord(value) ?? {};
9
9
  }
10
10
  /** Reads a field only when it exists as a string. */
11
11
  function readStringField(record, key) {
@@ -0,0 +1,349 @@
1
+ import { o as isRecord } from "./record-coerce-CNDovvft.mjs";
2
+ import { O as hasMediaPayload, n as getAiTransportHost } from "./host-CHi3X87F.mjs";
3
+ import { n as normalizeLowercaseStringOrEmpty } from "./string-coerce-fsri9iCu.mjs";
4
+ import { o as truncateUtf16Safe } from "./provider-error-CwT_j2v0.mjs";
5
+ import { i as copyProviderAcceptanceObserver, j as sanitizeSurrogates } from "./transport-stream-shared-Dh5qKJ8e.mjs";
6
+ //#region packages/ai/src/utils/prompt-cache-stability.ts
7
+ /**
8
+ * Prompt-cache normalization helpers. They keep generated prompt sections
9
+ * deterministic across platform newlines, trailing whitespace, and input
10
+ * ordering.
11
+ */
12
+ /** Canonicalizes provider tool order without relying on host locale settings. */
13
+ function sortPromptCacheToolsByName(tools) {
14
+ const compareText = (left, right) => {
15
+ const leftText = left ?? "";
16
+ const rightText = right ?? "";
17
+ return leftText < rightText ? -1 : leftText > rightText ? 1 : 0;
18
+ };
19
+ return tools.toSorted((left, right) => compareText(left.wireName ?? left.name, right.wireName ?? right.name) || compareText(left.description, right.description));
20
+ }
21
+ /** Normalize structured prompt text before hashing or snapshot comparison. */
22
+ function normalizeStructuredPromptSection(text) {
23
+ return sanitizeSurrogates(text).replace(/\r\n?/g, "\n").replace(/[ \t]+$/gm, "").trim();
24
+ }
25
+ /** Normalize, de-dupe, and sort capability ids for stable prompt payloads. */
26
+ function normalizePromptCapabilityIds(capabilities) {
27
+ const seen = /* @__PURE__ */ new Set();
28
+ for (const capability of capabilities) {
29
+ const value = normalizeLowercaseStringOrEmpty(normalizeStructuredPromptSection(capability));
30
+ if (value) seen.add(value);
31
+ }
32
+ return [...seen].toSorted((left, right) => left.localeCompare(right));
33
+ }
34
+ //#endregion
35
+ //#region packages/ai/src/utils/system-prompt-cache-boundary.ts
36
+ /**
37
+ * System prompt cache-boundary helpers.
38
+ *
39
+ * Keeps stable prompt prefixes separate from dynamic runtime additions for provider prompt caching.
40
+ */
41
+ const SYSTEM_PROMPT_CACHE_BOUNDARY = "\n<!-- OPENCLAW_CACHE_BOUNDARY -->\n";
42
+ /** Producer-delimited Runtime facts; instructions must remain outside this region. */
43
+ const SYSTEM_PROMPT_RELOCATABLE_BOUNDARY = "\n<!-- OPENCLAW-RELOCATABLE-BOUNDARY -->\n";
44
+ const SYSTEM_PROMPT_RELOCATABLE_BOUNDARY_END = "\n<!-- /OPENCLAW-RELOCATABLE-BOUNDARY -->";
45
+ function stripSystemPromptCacheBoundary(text) {
46
+ return stripSystemPromptRelocatableBoundary(text.replaceAll(SYSTEM_PROMPT_CACHE_BOUNDARY, "\n").replaceAll(SYSTEM_PROMPT_CACHE_BOUNDARY.trim(), ""));
47
+ }
48
+ /** Reject ambiguous markers from workspace or hook text instead of moving instructions. */
49
+ function splitSystemPromptRelocatableBoundary(text) {
50
+ const opening = SYSTEM_PROMPT_RELOCATABLE_BOUNDARY.trim();
51
+ const closing = SYSTEM_PROMPT_RELOCATABLE_BOUNDARY_END.trim();
52
+ const start = text.indexOf(opening);
53
+ const end = text.indexOf(closing);
54
+ if (start === -1 || end < start || text.includes(opening, start + 38) || text.includes(closing, end + 39)) return;
55
+ return {
56
+ remainingPrompt: [text.slice(0, start).trimEnd(), text.slice(end + 39).trimStart()].filter(Boolean).join("\n"),
57
+ relocatable: text.slice(start + 38, end).trim()
58
+ };
59
+ }
60
+ function ensureSystemPromptCacheBoundary(systemPrompt) {
61
+ if (systemPrompt.trim().length === 0) return systemPrompt;
62
+ return systemPrompt.includes("\n<!-- OPENCLAW_CACHE_BOUNDARY -->\n") ? systemPrompt : `${systemPrompt}${SYSTEM_PROMPT_CACHE_BOUNDARY}`;
63
+ }
64
+ function splitSystemPromptCacheBoundary(text) {
65
+ const boundaryIndex = text.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
66
+ if (boundaryIndex === -1) return;
67
+ return {
68
+ stablePrefix: text.slice(0, boundaryIndex).trimEnd(),
69
+ dynamicSuffix: text.slice(boundaryIndex + 34).trimStart()
70
+ };
71
+ }
72
+ /** Keep explicit cache breakpoints while removing relocation metadata. */
73
+ function stripSystemPromptRelocatableBoundary(text) {
74
+ return text.replaceAll(SYSTEM_PROMPT_RELOCATABLE_BOUNDARY, "\n").replaceAll(SYSTEM_PROMPT_RELOCATABLE_BOUNDARY_END, "").replaceAll(SYSTEM_PROMPT_RELOCATABLE_BOUNDARY.trim(), "").replaceAll(SYSTEM_PROMPT_RELOCATABLE_BOUNDARY_END.trim(), "");
75
+ }
76
+ function prependSystemPromptAdditionAfterCacheBoundary(params) {
77
+ const systemPromptAddition = typeof params.systemPromptAddition === "string" ? normalizeStructuredPromptSection(params.systemPromptAddition) : "";
78
+ if (!systemPromptAddition) return params.systemPrompt;
79
+ if (params.systemPrompt.trim().length === 0) return systemPromptAddition;
80
+ const split = splitSystemPromptCacheBoundary(params.systemPrompt);
81
+ if (!split) return `${systemPromptAddition}\n\n${params.systemPrompt}`;
82
+ const dynamicSuffix = split.dynamicSuffix ? normalizeStructuredPromptSection(split.dynamicSuffix) : "";
83
+ if (!dynamicSuffix) return `${split.stablePrefix}${SYSTEM_PROMPT_CACHE_BOUNDARY}${systemPromptAddition}`;
84
+ return `${split.stablePrefix}${SYSTEM_PROMPT_CACHE_BOUNDARY}${systemPromptAddition}\n\n${dynamicSuffix}`;
85
+ }
86
+ //#endregion
87
+ //#region packages/ai/src/providers/tool-result-text.ts
88
+ const STRUCTURED_TOOL_RESULT_MAX_CHARS = 8e3;
89
+ const IMAGE_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([
90
+ "image",
91
+ "image_url",
92
+ "input_image"
93
+ ]);
94
+ const AUDIO_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([
95
+ "audio",
96
+ "input_audio",
97
+ "output_audio"
98
+ ]);
99
+ const MEDIA_ONLY_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([...IMAGE_TOOL_RESULT_TYPES, ...AUDIO_TOOL_RESULT_TYPES]);
100
+ const INLINE_DATA_URI_PATTERN = /(^|[^A-Za-z0-9_])data:([a-z][a-z0-9.+-]*\/[a-z0-9.+-]+(?:;[a-z0-9.+-]+=[^,;"'\s]+|;base64)*,[^\s"'<>)]+)/gi;
101
+ const MIME_KEY_CANDIDATES = [
102
+ "mimeType",
103
+ "mime_type",
104
+ "mediaType",
105
+ "media_type",
106
+ "contentType",
107
+ "content_type"
108
+ ];
109
+ const TEXTUAL_MIME_PATTERN = /^(?:text\/|application\/(?:json|ld\+json|x-ndjson|xml|javascript|x-www-form-urlencoded)|[^/]+\/[^+]+\+(?:json|xml)$)/i;
110
+ const OPAQUE_OR_BINARY_FIELD_RE = /^(?:blob|buffer|bytes|encrypted_content|encrypted_stdout)$/i;
111
+ function readMimeType(value) {
112
+ if (!isRecord(value)) return;
113
+ for (const key of MIME_KEY_CANDIDATES) {
114
+ const mimeType = value[key];
115
+ if (typeof mimeType === "string" && mimeType.trim().length > 0) return mimeType;
116
+ }
117
+ }
118
+ function isBinaryMimeType(mimeType) {
119
+ const normalized = mimeType.split(";", 1)[0]?.trim().toLowerCase();
120
+ return normalized ? !TEXTUAL_MIME_PATTERN.test(normalized) : false;
121
+ }
122
+ function describeOmittedValue(value, label) {
123
+ const length = typeof value === "string" ? value.length : JSON.stringify(value)?.length;
124
+ return length ? `[${label} omitted: ${length} chars]` : `[${label} omitted]`;
125
+ }
126
+ function redactInlineDataUris(value) {
127
+ return value.replace(INLINE_DATA_URI_PATTERN, (_match, prefix, uri) => `${prefix}[inline data URI: ${uri.length} chars]`);
128
+ }
129
+ function stringifyStructuredBlock(block) {
130
+ const seen = /* @__PURE__ */ new WeakSet();
131
+ try {
132
+ const host = getAiTransportHost();
133
+ const redactedBlock = host.redactModelVisibleSecrets({ structuredToolResult: block }).structuredToolResult;
134
+ const serialized = JSON.stringify(redactedBlock, function structuredToolResultReplacer(key, value) {
135
+ if (OPAQUE_OR_BINARY_FIELD_RE.test(key)) return `[omitted ${key}]`;
136
+ if (key === "data") {
137
+ const mimeType = readMimeType(this);
138
+ if (mimeType && isBinaryMimeType(mimeType)) return describeOmittedValue(value, "binary data");
139
+ }
140
+ if (typeof value === "bigint") return value.toString();
141
+ if (typeof value === "string") return redactInlineDataUris(host.redactModelVisibleSecrets(value));
142
+ if (typeof value === "function" || typeof value === "symbol" || value === void 0) return;
143
+ if (!value || typeof value !== "object") return value;
144
+ if (seen.has(value)) return "[Circular]";
145
+ seen.add(value);
146
+ return value;
147
+ });
148
+ if (!serialized || serialized === "{}") return;
149
+ return serialized;
150
+ } catch {
151
+ return;
152
+ }
153
+ }
154
+ function truncateStructuredToolText(text) {
155
+ if (text.length <= STRUCTURED_TOOL_RESULT_MAX_CHARS) return text;
156
+ return `${truncateUtf16Safe(text, STRUCTURED_TOOL_RESULT_MAX_CHARS)}\n…(truncated)…`;
157
+ }
158
+ function classifyToolResultMedia(blocks) {
159
+ let hasImage = false;
160
+ let hasAudio = false;
161
+ for (const block of blocks) {
162
+ if (!hasMediaPayload(block) || block.type === "text") continue;
163
+ const type = typeof block.type === "string" ? block.type : void 0;
164
+ const mimeType = readMimeType(block)?.toLowerCase();
165
+ hasImage ||= Boolean(type && IMAGE_TOOL_RESULT_TYPES.has(type) || mimeType?.startsWith("image/"));
166
+ hasAudio ||= Boolean(type && AUDIO_TOOL_RESULT_TYPES.has(type) || mimeType?.startsWith("audio/"));
167
+ }
168
+ return {
169
+ hasImage,
170
+ hasAudio
171
+ };
172
+ }
173
+ function describeToolResultMediaPlaceholder(blocks) {
174
+ const { hasImage, hasAudio } = classifyToolResultMedia(blocks);
175
+ if (hasImage && hasAudio) return "(see attached media)";
176
+ if (hasAudio) return "(see attached audio)";
177
+ return hasImage ? "(see attached image)" : void 0;
178
+ }
179
+ function extractToolResultBlockText(block) {
180
+ if (!block || typeof block !== "object") return;
181
+ const record = block;
182
+ if (typeof record.type === "string" && MEDIA_ONLY_TOOL_RESULT_TYPES.has(record.type)) return;
183
+ if (record.type === "text") {
184
+ const text = typeof record.text === "string" ? record.text : "";
185
+ return text ? sanitizeSurrogates(text) : void 0;
186
+ }
187
+ const structured = stringifyStructuredBlock(record);
188
+ return structured ? sanitizeSurrogates(truncateStructuredToolText(structured)) : void 0;
189
+ }
190
+ function extractToolResultText(blocks, options) {
191
+ const explicitTexts = [];
192
+ const structuredBlocks = [];
193
+ for (const block of blocks) {
194
+ if (!block || typeof block !== "object") continue;
195
+ if (block.type === "text") {
196
+ const text = extractToolResultBlockText(block);
197
+ if (text) explicitTexts.push(text);
198
+ } else structuredBlocks.push(block);
199
+ }
200
+ if (explicitTexts.length > 0 && !options?.includeStructured) return explicitTexts.join("\n");
201
+ const structuredTexts = [];
202
+ for (const block of structuredBlocks) {
203
+ const text = extractToolResultBlockText(block);
204
+ if (text) structuredTexts.push(text);
205
+ }
206
+ if (explicitTexts.length > 0) {
207
+ if (structuredTexts.length > 0) explicitTexts.push(truncateStructuredToolText(structuredTexts.join("\n")));
208
+ return explicitTexts.join("\n");
209
+ }
210
+ return truncateStructuredToolText(structuredTexts.join("\n"));
211
+ }
212
+ /** Describe media that cannot be represented on the target provider wire. */
213
+ function describeUnsupportedToolResultMedia(blocks, support) {
214
+ const { hasImage, hasAudio } = classifyToolResultMedia(blocks);
215
+ const omittedImage = hasImage && !support.images;
216
+ const omittedAudio = hasAudio && !support.audio;
217
+ if (omittedImage && omittedAudio) return "[unsupported tool-result media omitted]";
218
+ if (omittedAudio) return "[unsupported tool-result audio omitted]";
219
+ return omittedImage ? "[unsupported tool-result image omitted]" : void 0;
220
+ }
221
+ function formatToolResultText(params) {
222
+ const body = params.text.trim() ? `${params.text}${params.omittedMediaPlaceholder ? `\n${params.omittedMediaPlaceholder}` : ""}` : params.omittedMediaPlaceholder ?? params.mediaPlaceholder ?? "(no tool output)";
223
+ return `${params.isError ? "[tool error] " : ""}${body}`;
224
+ }
225
+ //#endregion
226
+ //#region packages/ai/src/provider-options.ts
227
+ const CODE_MODE_TOOL_SURFACE_OBSERVER = Symbol("openaiCodeModeToolSurfaceObserver");
228
+ const CODE_MODE_TOOL_SURFACE_COLLECTOR = Symbol("openaiCodeModeToolSurfaceCollector");
229
+ const STRICT_REASONING_TAG_TEXT = Symbol("openaiStrictReasoningTagText");
230
+ function markStrictReasoningTagText(options) {
231
+ Reflect.set(options, STRICT_REASONING_TAG_TEXT, true);
232
+ }
233
+ function isStrictReasoningTagText(options) {
234
+ return options ? Reflect.get(options, STRICT_REASONING_TAG_TEXT) === true : false;
235
+ }
236
+ const codeModeToolSurfaceObserver = {
237
+ set(options, observer, collector) {
238
+ Reflect.set(options, CODE_MODE_TOOL_SURFACE_OBSERVER, observer);
239
+ if (collector) Reflect.set(options, CODE_MODE_TOOL_SURFACE_COLLECTOR, collector);
240
+ },
241
+ get(options) {
242
+ if (!options) return;
243
+ const observer = Reflect.get(options, CODE_MODE_TOOL_SURFACE_OBSERVER);
244
+ return typeof observer === "function" ? (observation) => observer(observation) : void 0;
245
+ },
246
+ getCollector(options) {
247
+ if (!options) return;
248
+ const collector = Reflect.get(options, CODE_MODE_TOOL_SURFACE_COLLECTOR);
249
+ return typeof collector === "function" ? (observation) => collector(observation) : void 0;
250
+ }
251
+ };
252
+ /** Internal output policy for callers that must not recover ambiguous reasoning as visible text. */
253
+ const reasoningTagTextPolicy = {
254
+ markStrict: markStrictReasoningTagText,
255
+ isStrict: isStrictReasoningTagText,
256
+ copy(source, target) {
257
+ if (isStrictReasoningTagText(source)) markStrictReasoningTagText(target);
258
+ }
259
+ };
260
+ //#endregion
261
+ //#region packages/ai/src/transports/model-request-body.ts
262
+ const REQUEST_BODY = Symbol("modelRequestBody");
263
+ /** Call-local state survives option spreads; no payload is cached across requests. */
264
+ function modelRequestBodyState(options, inheritFrom) {
265
+ let state = Reflect.get(options, REQUEST_BODY) ?? (inheritFrom && Reflect.get(inheritFrom, REQUEST_BODY));
266
+ if (!state) state = {};
267
+ Reflect.set(options, REQUEST_BODY, state);
268
+ return state;
269
+ }
270
+ function serializeModelRequestBody(payload) {
271
+ const json = JSON.stringify(payload);
272
+ return {
273
+ body: new TextEncoder().encode(json),
274
+ stream: json !== void 0 && JSON.parse(json)?.stream === true
275
+ };
276
+ }
277
+ const encodedBodyStreams = /* @__PURE__ */ new WeakMap();
278
+ function encodedModelRequestBodyStream(body) {
279
+ return typeof body === "object" && body !== null ? encodedBodyStreams.get(body) : void 0;
280
+ }
281
+ /** SDK RequestOptions.body overrides encoding while the original params retain stream metadata. */
282
+ function prepareModelRequestBody(options) {
283
+ const state = options ? modelRequestBodyState(options) : {};
284
+ state.enabled = true;
285
+ return async (payload) => {
286
+ const encoded = state.encode ? await state.encode(payload) : serializeModelRequestBody(payload);
287
+ state.onBytes?.(encoded.body.byteLength);
288
+ encodedBodyStreams.set(encoded.body, encoded.stream);
289
+ return {
290
+ body: encoded.body,
291
+ headers: { "content-type": "application/json" }
292
+ };
293
+ };
294
+ }
295
+ //#endregion
296
+ //#region packages/ai/src/providers/simple-options.ts
297
+ function buildBaseOptions(model, options, apiKey) {
298
+ const firstEventOptions = options;
299
+ const baseOptions = {
300
+ temperature: options?.temperature,
301
+ ...options?.serviceTier ? { serviceTier: options.serviceTier } : {},
302
+ maxTokens: options?.maxTokens,
303
+ responseFormat: options?.responseFormat,
304
+ stop: options?.stop,
305
+ signal: options?.signal,
306
+ apiKey: apiKey || options?.apiKey,
307
+ transport: options?.transport,
308
+ cacheRetention: options?.cacheRetention,
309
+ sessionId: options?.sessionId,
310
+ promptCacheKey: options?.promptCacheKey,
311
+ headers: options?.headers,
312
+ onPayload: options?.onPayload,
313
+ onResponse: options?.onResponse,
314
+ timeoutMs: options?.timeoutMs,
315
+ firstEventTimeoutMs: firstEventOptions?.firstEventTimeoutMs,
316
+ onFirstEventTimeout: firstEventOptions?.onFirstEventTimeout,
317
+ maxRetryDelayMs: options?.maxRetryDelayMs,
318
+ metadata: options?.metadata
319
+ };
320
+ reasoningTagTextPolicy.copy(options, baseOptions);
321
+ modelRequestBodyState(baseOptions, options);
322
+ return copyProviderAcceptanceObserver(options, baseOptions);
323
+ }
324
+ function clampMaxTokensToModel(model, requestedMaxTokens) {
325
+ return requestedMaxTokens === void 0 ? void 0 : Math.max(1, Math.min(requestedMaxTokens, model.maxTokens ?? requestedMaxTokens));
326
+ }
327
+ function clampReasoning(effort) {
328
+ return effort === "xhigh" ? "high" : effort;
329
+ }
330
+ function adjustMaxTokensForThinking(baseMaxTokens, modelMaxTokens, reasoningLevel, customBudgets) {
331
+ const budgets = {
332
+ minimal: 1024,
333
+ low: 2048,
334
+ medium: 8192,
335
+ high: 16384,
336
+ max: 32768,
337
+ ...customBudgets
338
+ };
339
+ const minOutputTokens = 1024;
340
+ let thinkingBudget = budgets[clampReasoning(reasoningLevel)];
341
+ const maxTokens = baseMaxTokens === void 0 ? modelMaxTokens : Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);
342
+ if (maxTokens <= thinkingBudget) thinkingBudget = Math.max(0, maxTokens - minOutputTokens);
343
+ return {
344
+ maxTokens,
345
+ thinkingBudget
346
+ };
347
+ }
348
+ //#endregion
349
+ export { stripSystemPromptCacheBoundary as C, sortPromptCacheToolsByName as D, normalizeStructuredPromptSection as E, splitSystemPromptRelocatableBoundary as S, normalizePromptCapabilityIds as T, SYSTEM_PROMPT_RELOCATABLE_BOUNDARY as _, encodedModelRequestBodyStream as a, prependSystemPromptAdditionAfterCacheBoundary as b, serializeModelRequestBody as c, describeToolResultMediaPlaceholder as d, describeUnsupportedToolResultMedia as f, SYSTEM_PROMPT_CACHE_BOUNDARY as g, formatToolResultText as h, clampReasoning as i, codeModeToolSurfaceObserver as l, extractToolResultText as m, buildBaseOptions as n, modelRequestBodyState as o, extractToolResultBlockText as p, clampMaxTokensToModel as r, prepareModelRequestBody as s, adjustMaxTokensForThinking as t, reasoningTagTextPolicy as u, SYSTEM_PROMPT_RELOCATABLE_BOUNDARY_END as v, stripSystemPromptRelocatableBoundary as w, splitSystemPromptCacheBoundary as x, ensureSystemPromptCacheBoundary as y };