@openclaw/ai 2026.7.2-beta.7 → 2026.8.1-beta.2

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 (91) hide show
  1. package/dist/{anthropic-CH4UUnZr.mjs → anthropic-B6dLpq5L.mjs} +55 -203
  2. package/dist/{src-QkygScBs.mjs → anthropic-JsNA5KCu.mjs} +0 -1
  3. package/dist/anthropic-compaction-replay-8lJNKXOE.mjs +840 -0
  4. package/dist/anthropic-payload-policy-CiEuQS72.d.mts +49 -0
  5. package/dist/{api-registry-DlMgPR39.d.mts → api-registry-k3zTz0cV.d.mts} +1 -1
  6. package/dist/{azure-openai-responses-CImcwB83.mjs → azure-openai-responses-mxIOtUnn.mjs} +23 -29
  7. package/dist/diagnostics.d.mts +24 -1
  8. package/dist/diagnostics.mjs +2 -1
  9. package/dist/{event-stream-YjaPW20U.d.mts → event-stream-BP6AWT8j.d.mts} +4 -1
  10. package/dist/{event-stream-D8n2uFee.mjs → event-stream-uSMZJ3FA.mjs} +26 -5
  11. package/dist/event-stream.d.mts +1 -1
  12. package/dist/event-stream.mjs +1 -1
  13. package/dist/{google-CtSg0iTS.mjs → google-C7h2QzDX.mjs} +5 -5
  14. package/dist/{google-shared-DNBz5rcD.mjs → google-shared-B0Qr9OR7.mjs} +146 -89
  15. package/dist/google-thinking-level-C-V3tecN.mjs +9 -0
  16. package/dist/{google-vertex-31f1uS9L.mjs → google-vertex-Bhc3TjDl.mjs} +11 -7
  17. package/dist/{llm-request-activity-BjtkplhG.mjs → headers-DdOQtGuU.mjs} +9 -1
  18. package/dist/host-DTqNc7ad.mjs +466 -0
  19. package/dist/{host-B9GUmcra.d.mts → host-vWgMMhiJ.d.mts} +9 -4
  20. package/dist/index.d.mts +6 -6
  21. package/dist/index.mjs +7 -5
  22. package/dist/internal/anthropic.d.mts +29 -5
  23. package/dist/internal/anthropic.mjs +5 -5
  24. package/dist/internal/openai-responses-payload-policy.d.mts +3 -0
  25. package/dist/internal/openai-responses-payload-policy.mjs +3 -0
  26. package/dist/internal/openai.d.mts +6 -6
  27. package/dist/internal/openai.mjs +8 -7
  28. package/dist/internal/runtime.d.mts +17 -5
  29. package/dist/internal/runtime.mjs +85 -73
  30. package/dist/internal/shared.d.mts +1 -6
  31. package/dist/internal/shared.mjs +3 -5
  32. package/dist/{json-parse-BvXNt1-7.mjs → json-parse-CDnesDM_.mjs} +4 -6
  33. package/dist/{mistral-CWmpvWYh.mjs → mistral-CEWoQI_g.mjs} +45 -48
  34. package/dist/number-coercion-H9qHik3g.mjs +71 -0
  35. package/dist/openai-chatgpt-jwt-KWcgd0d_.mjs +19 -0
  36. package/dist/{openai-chatgpt-responses-B84Ibtrd.mjs → openai-chatgpt-responses-CrPmqERt.mjs} +284 -240
  37. package/dist/{openai-completions-DsOxhOD1.mjs → openai-completions-BPnt4Sml.mjs} +65 -99
  38. package/dist/{openai-completions-compat-DBWjXoMZ.d.mts → openai-completions-compat-Dt3dcawL.d.mts} +2 -2
  39. package/dist/{openai-responses-BT7A3sLu.mjs → openai-responses-DhIKtOup.mjs} +18 -41
  40. package/dist/openai-responses-contracts-CyfIkQi5.mjs +253 -0
  41. package/dist/openai-responses-contracts-XpZJxrRG.d.mts +68 -0
  42. package/dist/openai-responses-payload-policy-BDxV-W0c.mjs +206 -0
  43. package/dist/openai-responses-payload-policy-BSs371VM.d.mts +40 -0
  44. package/dist/openai-responses-prompt-observer-internal-DgNTYnRY.mjs +46 -0
  45. package/dist/{openai-responses-stream-internal-Cw5txaGW.mjs → openai-responses-shared-DXIt3iY5.mjs} +1406 -940
  46. package/dist/{openai-reasoning-compat-YgeLncHw.mjs → openai-stop-reason-BkFkqqK0.mjs} +204 -37
  47. package/dist/openai-tool-projection-CY04OcvQ.mjs +338 -0
  48. package/dist/provider-error-BUwEnjXq.mjs +429 -0
  49. package/dist/provider-error-CzNw4BWX.d.mts +12 -0
  50. package/dist/{provider-options-D8bB3z9b.d.mts → provider-options-B96RdNpH.d.mts} +9 -3
  51. package/dist/provider-transcript-transform-ePx-Bbfr.mjs +155 -0
  52. package/dist/provider-types.d.mts +31 -0
  53. package/dist/provider-types.mjs +8 -0
  54. package/dist/providers.d.mts +1 -1
  55. package/dist/providers.mjs +17 -19
  56. package/dist/{reasoning-tag-text-partitioner-CGDyLWUR.mjs → reasoning-tag-text-partitioner-rnPwX2pg.mjs} +14 -8
  57. package/dist/record-coerce-DdXsgUd_.mjs +23 -0
  58. package/dist/sanitize-unicode-BYqrYtC_.mjs +90 -0
  59. package/dist/session-resources-CkR4WWy1.mjs +21 -0
  60. package/dist/simple-options-D58D5Kvw.mjs +117 -0
  61. package/dist/src-D2H6yKkH.mjs +2 -0
  62. package/dist/{stream-first-event-timeout-BBys9hSb.mjs → stream-first-event-timeout-MK28puvq.mjs} +2 -2
  63. package/dist/string-coerce-fsri9iCu.mjs +34 -0
  64. package/dist/{tool-schema-json-projection-BwNu3nDi.mjs → tool-schema-json-projection-q5d7QX5c.mjs} +32 -7
  65. package/dist/transport-utils-DJqkxbhC.mjs +138 -0
  66. package/dist/transports.d.mts +166 -241
  67. package/dist/transports.mjs +1979 -1825
  68. package/dist/types-BDdaOVi2.mjs +6 -0
  69. package/dist/{types-bzp5k29J.d.mts → types-BHNrPS1l.d.mts} +23 -1
  70. package/dist/types.d.mts +4 -4
  71. package/dist/types.mjs +6 -4
  72. package/dist/utf16-slice-CvGodqok.mjs +29 -0
  73. package/dist/{validation-DAa_yFOM.mjs → validation-B61OhAio.mjs} +6 -6
  74. package/dist/{validation-B-j7cOYp.d.mts → validation-DT9SrFn3.d.mts} +1 -1
  75. package/dist/validation.d.mts +1 -1
  76. package/dist/validation.mjs +1 -1
  77. package/package.json +15 -1
  78. package/dist/anthropic-usage-DWU-x8MI.mjs +0 -459
  79. package/dist/error-coercion-DgxlWC0n.mjs +0 -15
  80. package/dist/headers-B_e4-1J0.mjs +0 -9
  81. package/dist/host-Dog2WQiR.mjs +0 -369
  82. package/dist/number-coercion-DvG7SNMg.mjs +0 -129
  83. package/dist/openai-chatgpt-jwt-DhAAzLkj.mjs +0 -39
  84. package/dist/openai-responses-shared-pXl6Wd8S.mjs +0 -392
  85. package/dist/openai-tool-projection-OhX64DoP.mjs +0 -215
  86. package/dist/provider-error-CAEvRjry.mjs +0 -47
  87. package/dist/sanitize-unicode-DT5o51ur.mjs +0 -26
  88. package/dist/simple-options-9lhRrN73.mjs +0 -50
  89. package/dist/tool-result-text-CTpIRbYd.mjs +0 -225
  90. package/dist/transform-messages-C8mBqZxF.mjs +0 -2
  91. package/dist/transport-stream-shared-D81p90xq.mjs +0 -297
@@ -0,0 +1,8 @@
1
+ //#region packages/ai/src/provider-types.ts
2
+ const PROVIDER_CONTEXT_HANDOFF = Symbol("providerContextHandoff");
3
+ /** Resolves provider-only context without widening the canonical call contract. */
4
+ async function resolveProviderContext(context, options) {
5
+ return options?.[PROVIDER_CONTEXT_HANDOFF]?.() ?? context;
6
+ }
7
+ //#endregion
8
+ export { PROVIDER_CONTEXT_HANDOFF, resolveProviderContext };
@@ -1,4 +1,4 @@
1
- import { n as ApiRegistry } from "./api-registry-DlMgPR39.mjs";
1
+ import { n as ApiRegistry } from "./api-registry-k3zTz0cV.mjs";
2
2
  import { n as clampOpenAIPromptCacheKey, t as OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH } from "./openai-prompt-cache-2uo_1OR1.mjs";
3
3
 
4
4
  //#region packages/ai/src/providers/register-builtins.d.ts
@@ -1,15 +1,14 @@
1
- import { t as AssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
1
+ import { t as AssistantMessageEventStream } from "./event-stream-uSMZJ3FA.mjs";
2
+ import { n as projectProviderError } from "./provider-error-BUwEnjXq.mjs";
2
3
  import { n as clampOpenAIPromptCacheKey, t as OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH } from "./openai-prompt-cache-mZTCdRPo.mjs";
3
4
  //#region packages/ai/src/providers/register-builtins.ts
4
5
  /** Source id used for built-in API provider registrations. */
5
6
  const BUILT_IN_API_PROVIDER_SOURCE_ID = "core:built-in";
6
- function forwardStream(target, source) {
7
- (async () => {
8
- for await (const event of source) target.push(event);
9
- target.end();
10
- })();
7
+ async function forwardStream(target, source) {
8
+ for await (const event of source) target.push(event);
9
+ target.end();
11
10
  }
12
- function createLazyLoadErrorMessage(model, error) {
11
+ function createLazyLoadErrorMessage(model, error, signal) {
13
12
  return {
14
13
  role: "assistant",
15
14
  content: [],
@@ -30,8 +29,7 @@ function createLazyLoadErrorMessage(model, error) {
30
29
  total: 0
31
30
  }
32
31
  },
33
- stopReason: "error",
34
- errorMessage: error instanceof Error ? error.message : String(error),
32
+ ...projectProviderError(error, signal),
35
33
  timestamp: Date.now()
36
34
  };
37
35
  }
@@ -39,10 +37,10 @@ function createLazyStream(load, select) {
39
37
  return (model, context, options) => {
40
38
  const outer = new AssistantMessageEventStream();
41
39
  load().then((streams) => forwardStream(outer, select(streams)(model, context, options))).catch((error) => {
42
- const message = createLazyLoadErrorMessage(model, error);
40
+ const message = createLazyLoadErrorMessage(model, error, options?.signal);
43
41
  outer.push({
44
42
  type: "error",
45
- reason: "error",
43
+ reason: message.stopReason,
46
44
  error: message
47
45
  });
48
46
  outer.end(message);
@@ -64,35 +62,35 @@ function createLazyRegistration(api, importModule, select) {
64
62
  };
65
63
  }
66
64
  const registerBuiltIns = [
67
- createLazyRegistration("anthropic-messages", () => import("./anthropic-CH4UUnZr.mjs").then((n) => n.t), (module) => ({
65
+ createLazyRegistration("anthropic-messages", () => import("./anthropic-B6dLpq5L.mjs").then((n) => n.t), (module) => ({
68
66
  stream: module.streamAnthropic,
69
67
  streamSimple: module.streamSimpleAnthropic
70
68
  })),
71
- createLazyRegistration("openai-completions", () => import("./openai-completions-DsOxhOD1.mjs").then((n) => n.t), (module) => ({
69
+ createLazyRegistration("openai-completions", () => import("./openai-completions-BPnt4Sml.mjs").then((n) => n.t), (module) => ({
72
70
  stream: module.streamOpenAICompletions,
73
71
  streamSimple: module.streamSimpleOpenAICompletions
74
72
  })),
75
- createLazyRegistration("mistral-conversations", () => import("./mistral-CWmpvWYh.mjs"), (module) => ({
73
+ createLazyRegistration("mistral-conversations", () => import("./mistral-CEWoQI_g.mjs"), (module) => ({
76
74
  stream: module.streamMistral,
77
75
  streamSimple: module.streamSimpleMistral
78
76
  })),
79
- createLazyRegistration("openai-responses", () => import("./openai-responses-BT7A3sLu.mjs").then((n) => n.t), (module) => ({
77
+ createLazyRegistration("openai-responses", () => import("./openai-responses-DhIKtOup.mjs").then((n) => n.t), (module) => ({
80
78
  stream: module.streamOpenAIResponses,
81
79
  streamSimple: module.streamSimpleOpenAIResponses
82
80
  })),
83
- createLazyRegistration("azure-openai-responses", () => import("./azure-openai-responses-CImcwB83.mjs"), (module) => ({
81
+ createLazyRegistration("azure-openai-responses", () => import("./azure-openai-responses-mxIOtUnn.mjs"), (module) => ({
84
82
  stream: module.streamAzureOpenAIResponses,
85
83
  streamSimple: module.streamSimpleAzureOpenAIResponses
86
84
  })),
87
- createLazyRegistration("openai-chatgpt-responses", () => import("./openai-chatgpt-responses-B84Ibtrd.mjs"), (module) => ({
85
+ createLazyRegistration("openai-chatgpt-responses", () => import("./openai-chatgpt-responses-CrPmqERt.mjs"), (module) => ({
88
86
  stream: module.streamOpenAICodexResponses,
89
87
  streamSimple: module.streamSimpleOpenAICodexResponses
90
88
  })),
91
- createLazyRegistration("google-generative-ai", () => import("./google-CtSg0iTS.mjs"), (module) => ({
89
+ createLazyRegistration("google-generative-ai", () => import("./google-C7h2QzDX.mjs"), (module) => ({
92
90
  stream: module.streamGoogle,
93
91
  streamSimple: module.streamSimpleGoogle
94
92
  })),
95
- createLazyRegistration("google-vertex", () => import("./google-vertex-31f1uS9L.mjs"), (module) => ({
93
+ createLazyRegistration("google-vertex", () => import("./google-vertex-Bhc3TjDl.mjs"), (module) => ({
96
94
  stream: module.streamGoogleVertex,
97
95
  streamSimple: module.streamSimpleGoogleVertex
98
96
  }))
@@ -11573,6 +11573,7 @@ const REASONING_TAG_NAMES = [
11573
11573
  "thinking",
11574
11574
  "thought",
11575
11575
  "reasoning",
11576
+ "internal",
11576
11577
  "antthinking",
11577
11578
  "antml:think",
11578
11579
  "antml:thinking",
@@ -11645,7 +11646,8 @@ function parseReasoningTagAt(text, start, final) {
11645
11646
  index: start,
11646
11647
  text: text.slice(start, end),
11647
11648
  isClose,
11648
- isSelfClosing: !isClose && lastSignificant === "/"
11649
+ isSelfClosing: !isClose && lastSignificant === "/",
11650
+ isPrivate: partialName === "internal"
11649
11651
  }
11650
11652
  };
11651
11653
  }
@@ -11748,16 +11750,18 @@ function reduceReasoningText(text, codeSpans, state, options) {
11748
11750
  index: scannedTag.index + start,
11749
11751
  isClose: scannedTag.isClose,
11750
11752
  isSelfClosing: scannedTag.isSelfClosing,
11753
+ isPrivate: scannedTag.isPrivate,
11751
11754
  text: scannedTag.text
11752
11755
  };
11753
11756
  if (!isInsideCode(tag.index, codeSpans)) tags.push(tag);
11754
11757
  }
11755
- const hasCloseAfter = [];
11758
+ const mustParseRemainder = [];
11756
11759
  if (options.scope === "leading") {
11757
- let seenClose = false;
11760
+ let mustParse = false;
11758
11761
  for (let index = tags.length - 1; index >= 0; index -= 1) {
11759
- hasCloseAfter[index] = seenClose;
11760
- seenClose ||= tags[index]?.isClose === true;
11762
+ mustParse ||= tags[index]?.isPrivate === true;
11763
+ mustParseRemainder[index] = mustParse;
11764
+ mustParse ||= tags[index]?.isClose === true;
11761
11765
  }
11762
11766
  }
11763
11767
  let cursor = start;
@@ -11777,17 +11781,19 @@ function reduceReasoningText(text, codeSpans, state, options) {
11777
11781
  continue;
11778
11782
  }
11779
11783
  if (!tag.isClose) {
11780
- if (state.depth === 0 && options.scope === "leading" && state.visibleEver && !hasCloseAfter[tagIndex]) {
11784
+ if (state.depth === 0 && options.scope === "leading" && state.visibleEver && !mustParseRemainder[tagIndex]) {
11781
11785
  emit("text", text.slice(tag.index));
11782
11786
  cursor = text.length;
11783
11787
  break;
11784
11788
  }
11785
11789
  if (state.depth === 0) state.pending = {
11786
11790
  content: "",
11791
+ containsPrivate: tag.isPrivate,
11787
11792
  openTag: tag.text,
11788
11793
  protectedClose: false,
11789
11794
  visibleBefore: state.visibleEver
11790
11795
  };
11796
+ else if (state.pending) state.pending.containsPrivate ||= tag.isPrivate;
11791
11797
  state.depth += 1;
11792
11798
  cursor = tagEnd;
11793
11799
  continue;
@@ -11795,7 +11801,7 @@ function reduceReasoningText(text, codeSpans, state, options) {
11795
11801
  if (state.depth > 0) {
11796
11802
  state.depth -= 1;
11797
11803
  if (state.depth === 0 && state.pending) {
11798
- emit("thinking", state.pending.content);
11804
+ if (!state.pending.containsPrivate) emit("thinking", state.pending.content);
11799
11805
  state.pending = void 0;
11800
11806
  } else if (state.pending) state.pending.protectedClose = true;
11801
11807
  cursor = tagEnd;
@@ -11815,7 +11821,7 @@ function reduceReasoningText(text, codeSpans, state, options) {
11815
11821
  append(text.slice(cursor));
11816
11822
  if (options.final && state.depth > 0 && state.pending) {
11817
11823
  const pending = state.pending;
11818
- if (options.mode === "static-preserve" || options.mode === "static-strict" && !pending.visibleBefore && !pending.protectedClose || options.mode === "visible" && !pending.protectedClose) emit("text", options.mode === "visible" && pending.visibleBefore ? pending.openTag + pending.content : pending.content);
11824
+ if (!pending.containsPrivate) if (options.mode === "static-preserve" || options.mode === "static-strict" && !pending.visibleBefore && !pending.protectedClose || options.mode === "visible" && !pending.protectedClose) emit("text", options.mode === "visible" && pending.visibleBefore ? pending.openTag + pending.content : pending.content);
11819
11825
  else emit("thinking", pending.content);
11820
11826
  state.depth = 0;
11821
11827
  state.pending = void 0;
@@ -0,0 +1,23 @@
1
+ //#region packages/normalization-core/src/record-coerce.ts
2
+ /** Type guard for non-array object records at browser-safe boundaries. */
3
+ function isRecord(value) {
4
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5
+ }
6
+ /** Returns a non-array record or undefined. */
7
+ function asOptionalRecord(value) {
8
+ return isRecord(value) ? value : void 0;
9
+ }
10
+ /** Returns a non-array record or a fresh ordinary empty record. */
11
+ function asNonArrayRecord(value) {
12
+ return asOptionalRecord(value) ?? {};
13
+ }
14
+ /** Returns a non-array record or null. */
15
+ function asNullableRecord(value) {
16
+ return isRecord(value) ? value : null;
17
+ }
18
+ /** Returns any object-backed record, including arrays, or undefined. */
19
+ function asOptionalObjectRecord(value) {
20
+ return value && typeof value === "object" ? value : void 0;
21
+ }
22
+ //#endregion
23
+ export { isRecord as a, asOptionalRecord as i, asNullableRecord as n, asOptionalObjectRecord as r, asNonArrayRecord as t };
@@ -0,0 +1,90 @@
1
+ import { a as requiresClaudeMandatoryAdaptiveThinking, l as resolveClaudeNativeThinkingLevelMap } from "./anthropic-JsNA5KCu.mjs";
2
+ import "./src-D2H6yKkH.mjs";
3
+ //#region packages/ai/src/model-utils.ts
4
+ /** Calculates and stores model cost fields from token usage and per-million pricing. */
5
+ function calculateCost(model, usage) {
6
+ const cacheWrite1h = Math.min(usage.cacheWrite, Math.max(0, usage.cacheWrite1h ?? 0));
7
+ const cacheWrite5m = usage.cacheWrite - cacheWrite1h;
8
+ usage.cost.input = model.cost.input / 1e6 * usage.input;
9
+ usage.cost.output = model.cost.output / 1e6 * usage.output;
10
+ usage.cost.cacheRead = model.cost.cacheRead / 1e6 * usage.cacheRead;
11
+ usage.cost.cacheWrite = (model.cost.cacheWrite * cacheWrite5m + model.cost.input * 2 * cacheWrite1h) / 1e6;
12
+ usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
13
+ return usage.cost;
14
+ }
15
+ /** Replaces the catalog estimate when the provider reports an authoritative billed total. */
16
+ function applyProviderReportedUsageCost(usage, reportedCost) {
17
+ if (typeof reportedCost !== "number" || !Number.isFinite(reportedCost) || reportedCost < 0) return;
18
+ usage.cost.total = reportedCost;
19
+ usage.cost.totalOrigin = "provider-billed";
20
+ }
21
+ const EXTENDED_THINKING_LEVELS = [
22
+ "off",
23
+ "minimal",
24
+ "low",
25
+ "medium",
26
+ "high",
27
+ "xhigh",
28
+ "max"
29
+ ];
30
+ function resolveThinkingLevelMap(model) {
31
+ return model.api === "anthropic-messages" ? resolveClaudeNativeThinkingLevelMap(model) ?? model.thinkingLevelMap : model.thinkingLevelMap;
32
+ }
33
+ /** Returns thinking levels exposed by a reasoning-capable model. */
34
+ function getSupportedThinkingLevels(model) {
35
+ const mandatoryAdaptiveContract = model.api === "anthropic-messages" && requiresClaudeMandatoryAdaptiveThinking(model);
36
+ if (!model.reasoning && !mandatoryAdaptiveContract) return ["off"];
37
+ const thinkingLevelMap = resolveThinkingLevelMap(model);
38
+ return EXTENDED_THINKING_LEVELS.filter((level) => {
39
+ const mapped = thinkingLevelMap?.[level];
40
+ if (mapped === null) return false;
41
+ if (level === "xhigh" || level === "max") return mapped !== void 0;
42
+ return true;
43
+ });
44
+ }
45
+ /** Clamps a requested thinking level to the closest supported level for a model. */
46
+ function clampThinkingLevel(model, level) {
47
+ const availableLevels = getSupportedThinkingLevels(model);
48
+ if (availableLevels.includes(level)) return level;
49
+ const requestedIndex = EXTENDED_THINKING_LEVELS.indexOf(level);
50
+ if (requestedIndex === -1) return availableLevels[0] ?? "off";
51
+ const thinkingLevelMap = resolveThinkingLevelMap(model);
52
+ if ((level === "xhigh" || level === "max") && thinkingLevelMap?.[level] === null) {
53
+ for (const candidate of EXTENDED_THINKING_LEVELS.slice(0, requestedIndex).toReversed()) if (availableLevels.includes(candidate)) return candidate;
54
+ }
55
+ for (const candidate of EXTENDED_THINKING_LEVELS.slice(requestedIndex)) if (availableLevels.includes(candidate)) return candidate;
56
+ for (const candidate of EXTENDED_THINKING_LEVELS.slice(0, requestedIndex).toReversed()) if (availableLevels.includes(candidate)) return candidate;
57
+ return availableLevels[0] ?? "off";
58
+ }
59
+ /** Compares model identity by provider and id. */
60
+ function modelsAreEqual(a, b) {
61
+ if (!a || !b) return false;
62
+ return a.id === b.id && a.provider === b.provider;
63
+ }
64
+ //#endregion
65
+ //#region packages/ai/src/utils/sanitize-unicode.ts
66
+ /**
67
+ * Removes unpaired Unicode surrogate characters from a string.
68
+ *
69
+ * Unpaired surrogates (high surrogates 0xD800-0xDBFF without matching low surrogates 0xDC00-0xDFFF,
70
+ * or vice versa) cause JSON serialization errors in many API providers.
71
+ *
72
+ * Valid emoji and other characters outside the Basic Multilingual Plane use properly paired
73
+ * surrogates and will NOT be affected by this function.
74
+ *
75
+ * @param text - The text to sanitize
76
+ * @returns The sanitized text with unpaired surrogates removed
77
+ *
78
+ * @example
79
+ * // Valid emoji (properly paired surrogates) are preserved
80
+ * sanitizeSurrogates("Hello 🙈 World") // => "Hello 🙈 World"
81
+ *
82
+ * // Unpaired high surrogate is removed
83
+ * const unpaired = String.fromCharCode(0xD83D); // high surrogate without low
84
+ * sanitizeSurrogates(`Text ${unpaired} here`) // => "Text here"
85
+ */
86
+ function sanitizeSurrogates(text) {
87
+ return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
88
+ }
89
+ //#endregion
90
+ export { getSupportedThinkingLevels as a, clampThinkingLevel as i, applyProviderReportedUsageCost as n, modelsAreEqual as o, calculateCost as r, sanitizeSurrogates as t };
@@ -0,0 +1,21 @@
1
+ //#region packages/ai/src/session-resources.ts
2
+ const sessionResourceCleanups = /* @__PURE__ */ new Set();
3
+ /** Registers a session-resource cleanup hook and returns an unregister function. */
4
+ function registerSessionResourceCleanup(cleanup) {
5
+ sessionResourceCleanups.add(cleanup);
6
+ return () => {
7
+ sessionResourceCleanups.delete(cleanup);
8
+ };
9
+ }
10
+ /** Runs all registered cleanup hooks, aggregating failures after every hook has run. */
11
+ function cleanupSessionResources(sessionId) {
12
+ const errors = [];
13
+ for (const cleanup of sessionResourceCleanups) try {
14
+ cleanup(sessionId);
15
+ } catch (error) {
16
+ errors.push(error);
17
+ }
18
+ if (errors.length > 0) throw new AggregateError(errors, "Failed to cleanup session resources");
19
+ }
20
+ //#endregion
21
+ export { registerSessionResourceCleanup as n, cleanupSessionResources as t };
@@ -0,0 +1,117 @@
1
+ import { n as normalizeLowercaseStringOrEmpty } from "./string-coerce-fsri9iCu.mjs";
2
+ import { t as sanitizeSurrogates } from "./sanitize-unicode-BYqrYtC_.mjs";
3
+ //#region packages/ai/src/utils/prompt-cache-stability.ts
4
+ /**
5
+ * Prompt-cache normalization helpers. They keep generated prompt sections
6
+ * deterministic across platform newlines, trailing whitespace, and input
7
+ * ordering.
8
+ */
9
+ /** Canonicalizes provider tool order without relying on host locale settings. */
10
+ function sortPromptCacheToolsByName(tools) {
11
+ const compareText = (left, right) => {
12
+ const leftText = left ?? "";
13
+ const rightText = right ?? "";
14
+ return leftText < rightText ? -1 : leftText > rightText ? 1 : 0;
15
+ };
16
+ return tools.toSorted((left, right) => compareText(left.wireName ?? left.name, right.wireName ?? right.name) || compareText(left.description, right.description));
17
+ }
18
+ /** Normalize structured prompt text before hashing or snapshot comparison. */
19
+ function normalizeStructuredPromptSection(text) {
20
+ return sanitizeSurrogates(text).replace(/\r\n?/g, "\n").replace(/[ \t]+$/gm, "").trim();
21
+ }
22
+ /** Normalize, de-dupe, and sort capability ids for stable prompt payloads. */
23
+ function normalizePromptCapabilityIds(capabilities) {
24
+ const seen = /* @__PURE__ */ new Set();
25
+ const normalized = [];
26
+ for (const capability of capabilities) {
27
+ const value = normalizeLowercaseStringOrEmpty(normalizeStructuredPromptSection(capability));
28
+ if (!value || seen.has(value)) continue;
29
+ seen.add(value);
30
+ normalized.push(value);
31
+ }
32
+ return normalized.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
+ function stripSystemPromptCacheBoundary(text) {
43
+ return text.replaceAll(SYSTEM_PROMPT_CACHE_BOUNDARY, "\n");
44
+ }
45
+ function ensureSystemPromptCacheBoundary(systemPrompt) {
46
+ if (systemPrompt.trim().length === 0) return systemPrompt;
47
+ return systemPrompt.includes("\n<!-- OPENCLAW_CACHE_BOUNDARY -->\n") ? systemPrompt : `${systemPrompt}${SYSTEM_PROMPT_CACHE_BOUNDARY}`;
48
+ }
49
+ function splitSystemPromptCacheBoundary(text) {
50
+ const boundaryIndex = text.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
51
+ if (boundaryIndex === -1) return;
52
+ return {
53
+ stablePrefix: text.slice(0, boundaryIndex).trimEnd(),
54
+ dynamicSuffix: text.slice(boundaryIndex + 34).trimStart()
55
+ };
56
+ }
57
+ function prependSystemPromptAdditionAfterCacheBoundary(params) {
58
+ const systemPromptAddition = typeof params.systemPromptAddition === "string" ? normalizeStructuredPromptSection(params.systemPromptAddition) : "";
59
+ if (!systemPromptAddition) return params.systemPrompt;
60
+ if (params.systemPrompt.trim().length === 0) return systemPromptAddition;
61
+ const split = splitSystemPromptCacheBoundary(params.systemPrompt);
62
+ if (!split) return `${systemPromptAddition}\n\n${params.systemPrompt}`;
63
+ const dynamicSuffix = split.dynamicSuffix ? normalizeStructuredPromptSection(split.dynamicSuffix) : "";
64
+ if (!dynamicSuffix) return `${split.stablePrefix}${SYSTEM_PROMPT_CACHE_BOUNDARY}${systemPromptAddition}`;
65
+ return `${split.stablePrefix}${SYSTEM_PROMPT_CACHE_BOUNDARY}${systemPromptAddition}\n\n${dynamicSuffix}`;
66
+ }
67
+ //#endregion
68
+ //#region packages/ai/src/providers/simple-options.ts
69
+ function buildBaseOptions(model, options, apiKey) {
70
+ const firstEventOptions = options;
71
+ return {
72
+ temperature: options?.temperature,
73
+ maxTokens: options?.maxTokens,
74
+ stop: options?.stop,
75
+ signal: options?.signal,
76
+ apiKey: apiKey || options?.apiKey,
77
+ transport: options?.transport,
78
+ cacheRetention: options?.cacheRetention,
79
+ sessionId: options?.sessionId,
80
+ promptCacheKey: options?.promptCacheKey,
81
+ headers: options?.headers,
82
+ onPayload: options?.onPayload,
83
+ onResponse: options?.onResponse,
84
+ timeoutMs: options?.timeoutMs,
85
+ firstEventTimeoutMs: firstEventOptions?.firstEventTimeoutMs,
86
+ onFirstEventTimeout: firstEventOptions?.onFirstEventTimeout,
87
+ maxRetries: options?.maxRetries,
88
+ maxRetryDelayMs: options?.maxRetryDelayMs,
89
+ metadata: options?.metadata
90
+ };
91
+ }
92
+ function clampMaxTokensToModel(model, requestedMaxTokens) {
93
+ return requestedMaxTokens === void 0 ? void 0 : Math.max(1, Math.min(requestedMaxTokens, model.maxTokens));
94
+ }
95
+ function clampReasoning(effort) {
96
+ return effort === "xhigh" ? "high" : effort;
97
+ }
98
+ function adjustMaxTokensForThinking(baseMaxTokens, modelMaxTokens, reasoningLevel, customBudgets) {
99
+ const budgets = {
100
+ minimal: 1024,
101
+ low: 2048,
102
+ medium: 8192,
103
+ high: 16384,
104
+ max: 32768,
105
+ ...customBudgets
106
+ };
107
+ const minOutputTokens = 1024;
108
+ let thinkingBudget = budgets[clampReasoning(reasoningLevel)];
109
+ const maxTokens = baseMaxTokens === void 0 ? modelMaxTokens : Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);
110
+ if (maxTokens <= thinkingBudget) thinkingBudget = Math.max(0, maxTokens - minOutputTokens);
111
+ return {
112
+ maxTokens,
113
+ thinkingBudget
114
+ };
115
+ }
116
+ //#endregion
117
+ export { SYSTEM_PROMPT_CACHE_BOUNDARY as a, splitSystemPromptCacheBoundary as c, normalizeStructuredPromptSection as d, sortPromptCacheToolsByName as f, clampReasoning as i, stripSystemPromptCacheBoundary as l, buildBaseOptions as n, ensureSystemPromptCacheBoundary as o, clampMaxTokensToModel as r, prependSystemPromptAdditionAfterCacheBoundary as s, adjustMaxTokensForThinking as t, normalizePromptCapabilityIds as u };
@@ -0,0 +1,2 @@
1
+ import "./validation-B61OhAio.mjs";
2
+ export {};
@@ -1,4 +1,4 @@
1
- import { n as clampTimerTimeoutMs } from "./number-coercion-DvG7SNMg.mjs";
1
+ import { i as clampTimerTimeoutMs } from "./number-coercion-H9qHik3g.mjs";
2
2
  //#region packages/ai/src/utils/stream-first-event-timeout.ts
3
3
  function getFirstStreamEventTimeoutMs(options) {
4
4
  return options?.firstEventTimeoutMs;
@@ -57,8 +57,8 @@ function withFirstStreamEventTimeout(stream, context) {
57
57
  timer = setTimeout(() => {
58
58
  const timeoutError = createFirstStreamEventTimeoutError(timeoutContext);
59
59
  timeoutContext.onTimeout?.(timeoutError);
60
- timeoutContext.abort?.(timeoutError);
61
60
  reject(timeoutError);
61
+ timeoutContext.abort?.(timeoutError);
62
62
  }, timeoutMs);
63
63
  timer.unref?.();
64
64
  iterator.next().then(resolve, reject);
@@ -0,0 +1,34 @@
1
+ //#region packages/normalization-core/src/string-coerce.ts
2
+ /** Reads a value only when it is already a string, preserving whitespace. */
3
+ function readStringValue(value) {
4
+ return typeof value === "string" ? value : void 0;
5
+ }
6
+ /** Trims string input and returns null for non-strings or empty strings. */
7
+ function normalizeNullableString(value) {
8
+ if (typeof value !== "string") return null;
9
+ const trimmed = value.trim();
10
+ return trimmed ? trimmed : null;
11
+ }
12
+ /** Trims string input and returns undefined for non-strings or empty strings. */
13
+ function normalizeOptionalString(value) {
14
+ return normalizeNullableString(value) ?? void 0;
15
+ }
16
+ /** Stringifies primitive ids/flags before applying optional string normalization. */
17
+ function normalizeStringifiedOptionalString(value) {
18
+ if (typeof value === "string") return normalizeOptionalString(value);
19
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return normalizeOptionalString(String(value));
20
+ }
21
+ /** Lowercases a normalized optional string. */
22
+ function normalizeOptionalLowercaseString(value) {
23
+ return normalizeOptionalString(value)?.toLowerCase();
24
+ }
25
+ /** Lowercases a normalized string or returns an empty string when absent. */
26
+ function normalizeLowercaseStringOrEmpty(value) {
27
+ return normalizeOptionalLowercaseString(value) ?? "";
28
+ }
29
+ /** Type guard for strings that remain non-empty after trimming. */
30
+ function hasNonEmptyString(value) {
31
+ return normalizeOptionalString(value) !== void 0;
32
+ }
33
+ //#endregion
34
+ export { normalizeOptionalString as a, normalizeOptionalLowercaseString as i, normalizeLowercaseStringOrEmpty as n, normalizeStringifiedOptionalString as o, normalizeNullableString as r, readStringValue as s, hasNonEmptyString as t };
@@ -1,4 +1,32 @@
1
+ import { n as getAiTransportHost } from "./host-DTqNc7ad.mjs";
2
+ import { a as isRecord } from "./record-coerce-DdXsgUd_.mjs";
1
3
  import { types } from "node:util";
4
+ //#region packages/ai/src/transports/host-policy.ts
5
+ function buildGuardedModelFetch(model, timeoutMs, options) {
6
+ const host = getAiTransportHost();
7
+ if (options !== void 0) return host.buildModelFetch(model, timeoutMs, options) ?? globalThis.fetch;
8
+ if (timeoutMs !== void 0) return host.buildModelFetch(model, timeoutMs) ?? globalThis.fetch;
9
+ return host.buildModelFetch(model) ?? globalThis.fetch;
10
+ }
11
+ function resolveProviderEndpoint(baseUrl) {
12
+ return { endpointClass: getAiTransportHost().resolveProviderEndpointClass(baseUrl) };
13
+ }
14
+ function resolveProviderRequestCapabilities(input) {
15
+ return getAiTransportHost().resolveProviderRequestCapabilities(input);
16
+ }
17
+ function resolveProviderRequestPolicyConfig(input) {
18
+ return { headers: getAiTransportHost().resolveProviderRequestHeaders(input) };
19
+ }
20
+ function resolveModelRequestTimeoutMs(model, timeoutMs) {
21
+ return timeoutMs ?? getAiTransportHost().resolveModelRequestTimeoutMs(model);
22
+ }
23
+ function resolveOpenAIStrictToolSetting(model, options) {
24
+ return getAiTransportHost().resolveOpenAIStrictToolSetting(model, options);
25
+ }
26
+ function transformTransportMessages(messages, model, normalizeToolCallId, options) {
27
+ return getAiTransportHost().transformTransportMessages(messages, model, normalizeToolCallId, options);
28
+ }
29
+ //#endregion
2
30
  //#region packages/ai/src/providers/tool-schema-json-projection.ts
3
31
  function isJsonValue(value) {
4
32
  if (value === null) return true;
@@ -12,9 +40,6 @@ function isJsonValue(value) {
12
40
  default: return false;
13
41
  }
14
42
  }
15
- function isJsonObject(value) {
16
- return value !== null && typeof value === "object" && !Array.isArray(value);
17
- }
18
43
  function isNonFiniteNumberValue(value) {
19
44
  if (typeof value === "number") return !Number.isFinite(value);
20
45
  if (value === null || typeof value !== "object" || !types.isNumberObject(value)) return false;
@@ -68,12 +93,12 @@ const schemaMapKeywords = /* @__PURE__ */ new Set([
68
93
  ]);
69
94
  function findDynamicSchemaKeywordViolations(schema, path) {
70
95
  if (Array.isArray(schema)) return schema.flatMap((entry, index) => findDynamicSchemaKeywordViolations(entry, `${path}[${index}]`));
71
- if (!isJsonObject(schema)) return [];
96
+ if (!isRecord(schema)) return [];
72
97
  const violations = [];
73
98
  for (const key of ["$dynamicRef", "$dynamicAnchor"]) if (key in schema) violations.push(`${path}.${key}`);
74
99
  for (const [key, value] of Object.entries(schema)) {
75
100
  if (!value || typeof value !== "object") continue;
76
- if (schemaMapKeywords.has(key) && isJsonObject(value)) for (const [schemaName, childSchema] of Object.entries(value)) violations.push(...findDynamicSchemaKeywordViolations(childSchema, `${path}.${key}.${schemaName}`));
101
+ if (schemaMapKeywords.has(key) && isRecord(value)) for (const [schemaName, childSchema] of Object.entries(value)) violations.push(...findDynamicSchemaKeywordViolations(childSchema, `${path}.${key}.${schemaName}`));
77
102
  else violations.push(...findDynamicSchemaKeywordViolations(value, `${path}.${key}`));
78
103
  }
79
104
  return violations;
@@ -82,7 +107,7 @@ function findDynamicSchemaKeywordViolations(schema, path) {
82
107
  function projectRuntimeToolInputSchema(schema, path = "parameters") {
83
108
  const projection = serializeToolInputSchema(schema, path);
84
109
  const violations = [...projection.violations];
85
- if (!isJsonObject(projection.schema)) violations.push(`${path} must be a JSON object schema`);
110
+ if (!isRecord(projection.schema)) violations.push(`${path} must be a JSON object schema`);
86
111
  else if (projection.schema.type !== void 0 && projection.schema.type !== "object") violations.push(`${path}.type must be "object"`);
87
112
  violations.push(...findDynamicSchemaKeywordViolations(projection.schema, path));
88
113
  return {
@@ -91,4 +116,4 @@ function projectRuntimeToolInputSchema(schema, path = "parameters") {
91
116
  };
92
117
  }
93
118
  //#endregion
94
- export { projectRuntimeToolInputSchema as t };
119
+ export { resolveProviderEndpoint as a, transformTransportMessages as c, resolveOpenAIStrictToolSetting as i, buildGuardedModelFetch as n, resolveProviderRequestCapabilities as o, resolveModelRequestTimeoutMs as r, resolveProviderRequestPolicyConfig as s, projectRuntimeToolInputSchema as t };