@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
@@ -1,50 +0,0 @@
1
- //#region packages/ai/src/providers/simple-options.ts
2
- function buildBaseOptions(model, options, apiKey) {
3
- const firstEventOptions = options;
4
- return {
5
- temperature: options?.temperature,
6
- maxTokens: options?.maxTokens,
7
- stop: options?.stop,
8
- signal: options?.signal,
9
- apiKey: apiKey || options?.apiKey,
10
- transport: options?.transport,
11
- cacheRetention: options?.cacheRetention,
12
- sessionId: options?.sessionId,
13
- promptCacheKey: options?.promptCacheKey,
14
- headers: options?.headers,
15
- onPayload: options?.onPayload,
16
- onResponse: options?.onResponse,
17
- timeoutMs: options?.timeoutMs,
18
- firstEventTimeoutMs: firstEventOptions?.firstEventTimeoutMs,
19
- onFirstEventTimeout: firstEventOptions?.onFirstEventTimeout,
20
- maxRetries: options?.maxRetries,
21
- maxRetryDelayMs: options?.maxRetryDelayMs,
22
- metadata: options?.metadata
23
- };
24
- }
25
- function clampMaxTokensToModel(model, requestedMaxTokens) {
26
- return requestedMaxTokens === void 0 ? void 0 : Math.max(1, Math.min(requestedMaxTokens, model.maxTokens));
27
- }
28
- function clampReasoning(effort) {
29
- return effort === "xhigh" ? "high" : effort;
30
- }
31
- function adjustMaxTokensForThinking(baseMaxTokens, modelMaxTokens, reasoningLevel, customBudgets) {
32
- const budgets = {
33
- minimal: 1024,
34
- low: 2048,
35
- medium: 8192,
36
- high: 16384,
37
- max: 32768,
38
- ...customBudgets
39
- };
40
- const minOutputTokens = 1024;
41
- let thinkingBudget = budgets[clampReasoning(reasoningLevel)];
42
- const maxTokens = baseMaxTokens === void 0 ? modelMaxTokens : Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);
43
- if (maxTokens <= thinkingBudget) thinkingBudget = Math.max(0, maxTokens - minOutputTokens);
44
- return {
45
- maxTokens,
46
- thinkingBudget
47
- };
48
- }
49
- //#endregion
50
- export { clampReasoning as i, buildBaseOptions as n, clampMaxTokensToModel as r, adjustMaxTokensForThinking as t };
@@ -1,225 +0,0 @@
1
- import { g as isRecord, n as getAiTransportHost, p as normalizeLowercaseStringOrEmpty } from "./host-Dog2WQiR.mjs";
2
- import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.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/normalization-core/src/utf16-slice.ts
69
- function isHighSurrogate(codeUnit) {
70
- return codeUnit >= 55296 && codeUnit <= 56319;
71
- }
72
- function isLowSurrogate(codeUnit) {
73
- return codeUnit >= 56320 && codeUnit <= 57343;
74
- }
75
- /** Slices a UTF-16 string without returning dangling surrogate halves at either edge. */
76
- function sliceUtf16Safe(input, start, end) {
77
- const len = input.length;
78
- let from = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
79
- let to = end === void 0 ? len : end < 0 ? Math.max(len + end, 0) : Math.min(end, len);
80
- if (to <= from) return "";
81
- if (from > 0 && from < len) {
82
- if (isLowSurrogate(input.charCodeAt(from)) && isHighSurrogate(input.charCodeAt(from - 1))) from += 1;
83
- }
84
- if (to > 0 && to < len) {
85
- if (isHighSurrogate(input.charCodeAt(to - 1)) && isLowSurrogate(input.charCodeAt(to))) to -= 1;
86
- }
87
- return input.slice(from, to);
88
- }
89
- /** Truncates a UTF-16 string without cutting a surrogate pair in half. */
90
- function truncateUtf16Safe(input, maxLen) {
91
- const limit = Math.max(0, Math.floor(maxLen));
92
- if (input.length <= limit) return input;
93
- return sliceUtf16Safe(input, 0, limit);
94
- }
95
- //#endregion
96
- //#region packages/ai/src/providers/tool-result-text.ts
97
- const PROVIDER_TOOL_RESULT_MAX_CHARS = 8e3;
98
- const IMAGE_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([
99
- "image",
100
- "image_url",
101
- "input_image"
102
- ]);
103
- const AUDIO_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([
104
- "audio",
105
- "input_audio",
106
- "output_audio"
107
- ]);
108
- const MEDIA_ONLY_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([...IMAGE_TOOL_RESULT_TYPES, ...AUDIO_TOOL_RESULT_TYPES]);
109
- 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;
110
- const MIME_KEY_CANDIDATES = [
111
- "mimeType",
112
- "mime_type",
113
- "mediaType",
114
- "media_type",
115
- "contentType",
116
- "content_type"
117
- ];
118
- const TEXTUAL_MIME_PATTERN = /^(?:text\/|application\/(?:json|ld\+json|x-ndjson|xml|javascript|x-www-form-urlencoded)|[^/]+\/[^+]+\+(?:json|xml)$)/i;
119
- const OPAQUE_OR_BINARY_FIELD_RE = /^(?:blob|buffer|bytes|encrypted_content|encrypted_stdout)$/i;
120
- function readMimeType(value) {
121
- if (!isRecord(value)) return;
122
- for (const key of MIME_KEY_CANDIDATES) {
123
- const mimeType = value[key];
124
- if (typeof mimeType === "string" && mimeType.trim().length > 0) return mimeType;
125
- }
126
- }
127
- function isBinaryMimeType(mimeType) {
128
- const normalized = mimeType.split(";", 1)[0]?.trim().toLowerCase();
129
- return normalized ? !TEXTUAL_MIME_PATTERN.test(normalized) : false;
130
- }
131
- function describeOmittedValue(value, label) {
132
- const length = typeof value === "string" ? value.length : JSON.stringify(value)?.length;
133
- return length ? `[${label} omitted: ${length} chars]` : `[${label} omitted]`;
134
- }
135
- function redactInlineDataUris(value) {
136
- return value.replace(INLINE_DATA_URI_PATTERN, (_match, prefix, uri) => `${prefix}[inline data URI: ${uri.length} chars]`);
137
- }
138
- function redactStructuredTextValue(value) {
139
- const host = getAiTransportHost();
140
- const redacted = host.redactToolPayloadText(value);
141
- const trimmed = redacted.trim();
142
- if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return redacted;
143
- try {
144
- const redactedWrapper = host.redactSecrets({ structuredTextValue: JSON.parse(redacted) });
145
- return JSON.stringify(redactedWrapper.structuredTextValue);
146
- } catch {
147
- return redacted;
148
- }
149
- }
150
- function stringifyStructuredBlock(block) {
151
- const seen = /* @__PURE__ */ new WeakSet();
152
- try {
153
- const redactedBlock = getAiTransportHost().redactSecrets({ structuredToolResult: block }).structuredToolResult;
154
- const serialized = JSON.stringify(redactedBlock, function structuredToolResultReplacer(key, value) {
155
- if (OPAQUE_OR_BINARY_FIELD_RE.test(key)) return `[omitted ${key}]`;
156
- if (key === "data") {
157
- const mimeType = readMimeType(this);
158
- if (mimeType && isBinaryMimeType(mimeType)) return describeOmittedValue(value, "binary data");
159
- }
160
- if (typeof value === "bigint") return value.toString();
161
- if (typeof value === "string") return redactInlineDataUris(redactStructuredTextValue(value));
162
- if (typeof value === "function" || typeof value === "symbol" || value === void 0) return;
163
- if (!value || typeof value !== "object") return value;
164
- if (seen.has(value)) return "[Circular]";
165
- seen.add(value);
166
- return value;
167
- });
168
- if (!serialized || serialized === "{}") return;
169
- return serialized;
170
- } catch {
171
- return;
172
- }
173
- }
174
- function truncateProviderToolText(text) {
175
- if (text.length <= PROVIDER_TOOL_RESULT_MAX_CHARS) return text;
176
- return `${truncateUtf16Safe(text, PROVIDER_TOOL_RESULT_MAX_CHARS)}\n…(truncated)…`;
177
- }
178
- /** Media metadata alone is not an attachment; provider emitters need inline bytes. */
179
- function hasMediaPayload(block) {
180
- return isRecord(block) && typeof block.data === "string" && block.data.trim().length > 0;
181
- }
182
- /** Image metadata alone is not an attachment; provider emitters need inline bytes. */
183
- function isImageWithMediaPayload(block) {
184
- return isRecord(block) && block.type === "image" && hasMediaPayload(block);
185
- }
186
- function describeToolResultMediaPlaceholder(blocks) {
187
- let hasImage = false;
188
- let hasAudio = false;
189
- for (const block of blocks) {
190
- if (!hasMediaPayload(block)) continue;
191
- const record = block;
192
- const type = typeof record.type === "string" ? record.type : void 0;
193
- const mimeType = readMimeType(record);
194
- if (type && IMAGE_TOOL_RESULT_TYPES.has(type) || mimeType?.toLowerCase().startsWith("image/")) hasImage = true;
195
- if (type && AUDIO_TOOL_RESULT_TYPES.has(type) || mimeType?.toLowerCase().startsWith("audio/")) hasAudio = true;
196
- }
197
- if (hasImage && hasAudio) return "(see attached media)";
198
- if (hasAudio) return "(see attached audio)";
199
- if (hasImage) return "(see attached image)";
200
- }
201
- function extractToolResultBlockText(block) {
202
- if (!block || typeof block !== "object") return;
203
- const record = block;
204
- if (typeof record.type === "string" && MEDIA_ONLY_TOOL_RESULT_TYPES.has(record.type)) return;
205
- if (record.type === "text") {
206
- const text = typeof record.text === "string" ? record.text : "";
207
- return text ? sanitizeSurrogates(text) : void 0;
208
- }
209
- const structured = stringifyStructuredBlock(record);
210
- return structured ? sanitizeSurrogates(truncateProviderToolText(structured)) : void 0;
211
- }
212
- function extractToolResultText(blocks) {
213
- const explicitTexts = [];
214
- const structuredTexts = [];
215
- for (const block of blocks) {
216
- const text = extractToolResultBlockText(block);
217
- if (!text) continue;
218
- if (block.type === "text") explicitTexts.push(text);
219
- else structuredTexts.push(text);
220
- }
221
- if (explicitTexts.length > 0) return sanitizeSurrogates(explicitTexts.join("\n"));
222
- return sanitizeSurrogates(truncateProviderToolText(structuredTexts.join("\n")));
223
- }
224
- //#endregion
225
- export { isImageWithMediaPayload as a, ensureSystemPromptCacheBoundary as c, stripSystemPromptCacheBoundary as d, normalizePromptCapabilityIds as f, hasMediaPayload as i, prependSystemPromptAdditionAfterCacheBoundary as l, sortPromptCacheToolsByName as m, extractToolResultBlockText as n, truncateUtf16Safe as o, normalizeStructuredPromptSection as p, extractToolResultText as r, SYSTEM_PROMPT_CACHE_BOUNDARY as s, describeToolResultMediaPlaceholder as t, splitSystemPromptCacheBoundary as u };
@@ -1,2 +0,0 @@
1
- import "./host-Dog2WQiR.mjs";
2
- export {};
@@ -1,297 +0,0 @@
1
- import { r as createAssistantMessageEventStream } from "./event-stream-D8n2uFee.mjs";
2
- import { m as normalizeOptionalString, n as getAiTransportHost } from "./host-Dog2WQiR.mjs";
3
- import { t as sanitizeSurrogates } from "./sanitize-unicode-DT5o51ur.mjs";
4
- import { o as truncateUtf16Safe } from "./tool-result-text-CTpIRbYd.mjs";
5
- import { i as parseStrictNonNegativeInteger, r as parseStrictFiniteNumber, t as asFiniteNumberInRange } from "./number-coercion-DvG7SNMg.mjs";
6
- import { parseRetryAfterHttpDateMs } from "./internal/retry-after.mjs";
7
- import { createHash } from "node:crypto";
8
- //#region packages/ai/src/transports/transport-utils.ts
9
- const MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE = "OpenClaw transport error: malformed_streaming_fragment";
10
- const NON_LATIN_RE = /[\u2E80-\u9FFF\uA000-\uA4FF\uAC00-\uD7AF\uF900-\uFAFF\uFF01-\uFF60\uFFE0-\uFFE6\u{20000}-\u{2FA1F}]/gu;
11
- const CJK_SURROGATE_HIGH_RE = /[\uD840-\uD87E][\uDC00-\uDFFF]/g;
12
- function sha256Hex(value) {
13
- return createHash("sha256").update(value).digest("hex");
14
- }
15
- function sha256HexPrefix(value, length) {
16
- return sha256Hex(value).slice(0, length);
17
- }
18
- function redactIdentifier(value, opts) {
19
- const trimmed = normalizeOptionalString(value);
20
- if (!trimmed) return "-";
21
- return `sha256:${sha256HexPrefix(trimmed, Number.isFinite(opts?.len) ? Math.max(1, Math.floor(opts?.len ?? 12)) : 12)}`;
22
- }
23
- function redactSensitiveText(text, _options) {
24
- return getAiTransportHost().redactToolPayloadText(text);
25
- }
26
- function resolveSecretSentinel(value) {
27
- return getAiTransportHost().resolveSecretSentinel(value);
28
- }
29
- function resolveModelHeaderSentinels(model) {
30
- if (!model.headers) return model;
31
- let headers;
32
- for (const [name, value] of Object.entries(model.headers)) {
33
- const resolved = resolveSecretSentinel(value);
34
- if (resolved !== value) {
35
- headers ??= { ...model.headers };
36
- headers[name] = resolved;
37
- }
38
- }
39
- return headers ? {
40
- ...model,
41
- headers
42
- } : model;
43
- }
44
- function createAbortError(message, options) {
45
- const error = new Error(message, options);
46
- error.name = "AbortError";
47
- return error;
48
- }
49
- function estimateStringChars(text) {
50
- if (!text) return 0;
51
- const nonLatinCount = (text.match(NON_LATIN_RE) ?? []).length;
52
- return (nonLatinCount === 0 ? text.length : text.length - (text.match(CJK_SURROGATE_HIGH_RE) ?? []).length) + nonLatinCount * 3;
53
- }
54
- function supportsModelTools(model) {
55
- return (model.compat && typeof model.compat === "object" ? model.compat : void 0)?.supportsTools !== false;
56
- }
57
- function isCodeModeModelVisibleToolName(name, visibleToolNames) {
58
- return visibleToolNames.has(name);
59
- }
60
- function isGoogleGemini3Model(modelId, family) {
61
- const normalized = modelId.trim().toLowerCase();
62
- const suffix = family === "pro" ? "pro" : "flash";
63
- return new RegExp(`(?:^|/)gemini-(?:3(?:\\.\\d+)?-${suffix}|${suffix}${family === "flash" ? "(?:-lite)?" : ""}-latest)(?:-|$)`).test(normalized);
64
- }
65
- function isGoogleGemini3ProModel(modelId) {
66
- return isGoogleGemini3Model(modelId, "pro");
67
- }
68
- function isGoogleGemini3FlashModel(modelId) {
69
- return isGoogleGemini3Model(modelId, "flash");
70
- }
71
- function parseRetryAfterSeconds(headers) {
72
- const retryAfterMs = headers.get("retry-after-ms");
73
- if (retryAfterMs) {
74
- const trimmed = retryAfterMs.trim();
75
- if (/^\d+(?:\.\d+)?$/.test(trimmed)) {
76
- const milliseconds = asFiniteNumberInRange(parseStrictFiniteNumber(trimmed), {
77
- min: 0,
78
- max: Number.MAX_SAFE_INTEGER
79
- });
80
- return milliseconds === void 0 ? Number.POSITIVE_INFINITY : milliseconds / 1e3;
81
- }
82
- }
83
- const retryAfter = headers.get("retry-after")?.trim();
84
- if (!retryAfter) return;
85
- if (/^\d+$/.test(retryAfter)) return parseStrictNonNegativeInteger(retryAfter) ?? Number.POSITIVE_INFINITY;
86
- const retryAt = parseRetryAfterHttpDateMs(retryAfter);
87
- return retryAt === void 0 ? void 0 : Math.max(0, (retryAt - Date.now()) / 1e3);
88
- }
89
- async function readChunkWithIdleTimeout(reader, timeoutMs, onIdleTimeout) {
90
- let timer;
91
- try {
92
- return await Promise.race([reader.read(), new Promise((_resolve, reject) => {
93
- timer = setTimeout(() => reject(onIdleTimeout?.({ chunkTimeoutMs: timeoutMs }) ?? /* @__PURE__ */ new Error("Read timed out")), timeoutMs);
94
- })]);
95
- } finally {
96
- if (timer) clearTimeout(timer);
97
- }
98
- }
99
- async function readResponseTextSnippet(response, options) {
100
- const maxBytes = options?.maxBytes ?? 8 * 1024;
101
- const maxChars = options?.maxChars ?? 200;
102
- const reader = response.body?.getReader();
103
- if (!reader) return;
104
- const chunks = [];
105
- let bytes = 0;
106
- let truncated = false;
107
- try {
108
- while (bytes < maxBytes) {
109
- const result = options?.chunkTimeoutMs ? await readChunkWithIdleTimeout(reader, options.chunkTimeoutMs, options.onIdleTimeout) : await reader.read();
110
- if (result.done) break;
111
- if (!result.value?.length) continue;
112
- const remaining = maxBytes - bytes;
113
- chunks.push(result.value.subarray(0, remaining));
114
- bytes += Math.min(result.value.length, remaining);
115
- if (result.value.length >= remaining) {
116
- truncated = true;
117
- await reader.cancel().catch(() => void 0);
118
- break;
119
- }
120
- }
121
- } catch (error) {
122
- await reader.cancel(error).catch(() => void 0);
123
- throw error;
124
- } finally {
125
- reader.releaseLock();
126
- }
127
- const merged = new Uint8Array(bytes);
128
- let offset = 0;
129
- for (const chunk of chunks) {
130
- merged.set(chunk, offset);
131
- offset += chunk.length;
132
- }
133
- const collapsed = new TextDecoder().decode(merged).replace(/\s+/g, " ").trim();
134
- if (!collapsed) return;
135
- if (collapsed.length > maxChars) return `${truncateUtf16Safe(collapsed, maxChars)}…`;
136
- return truncated ? `${collapsed}…` : collapsed;
137
- }
138
- //#endregion
139
- //#region packages/ai/src/transports/transport-stream-shared.ts
140
- const EMPTY_TOOL_RESULT_TEXT = "(no output)";
141
- function sanitizeTransportPayloadText(text) {
142
- if (typeof text !== "string") return "";
143
- return sanitizeSurrogates(text);
144
- }
145
- function sanitizeNonEmptyTransportPayloadText(text, fallback = EMPTY_TOOL_RESULT_TEXT) {
146
- const sanitized = sanitizeTransportPayloadText(text);
147
- return sanitized.trim().length > 0 ? sanitized : fallback;
148
- }
149
- function coerceTransportToolCallArguments(argumentsValue) {
150
- if (argumentsValue && typeof argumentsValue === "object" && !Array.isArray(argumentsValue)) return argumentsValue;
151
- if (typeof argumentsValue === "string") try {
152
- const parsed = JSON.parse(argumentsValue);
153
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
154
- } catch {}
155
- return {};
156
- }
157
- function mergeTransportHeaders(...headerSources) {
158
- const merged = {};
159
- for (const headers of headerSources) if (headers) Object.assign(merged, headers);
160
- return Object.keys(merged).length > 0 ? merged : void 0;
161
- }
162
- function mergeTransportMetadata(payload, metadata) {
163
- if (!metadata || Object.keys(metadata).length === 0) return payload;
164
- const existingMetadata = payload.metadata && typeof payload.metadata === "object" && !Array.isArray(payload.metadata) ? payload.metadata : void 0;
165
- return {
166
- ...payload,
167
- metadata: {
168
- ...existingMetadata,
169
- ...metadata
170
- }
171
- };
172
- }
173
- function createEmptyTransportUsage() {
174
- return {
175
- input: 0,
176
- output: 0,
177
- cacheRead: 0,
178
- cacheWrite: 0,
179
- totalTokens: 0,
180
- cost: {
181
- input: 0,
182
- output: 0,
183
- cacheRead: 0,
184
- cacheWrite: 0,
185
- total: 0
186
- }
187
- };
188
- }
189
- function createWritableTransportEventStream() {
190
- const eventStream = createAssistantMessageEventStream();
191
- return {
192
- eventStream,
193
- stream: eventStream
194
- };
195
- }
196
- /**
197
- * Abort error to surface for an aborted `signal`.
198
- *
199
- * Rethrows the caller's abort reason only when it carries a `code`, so that code
200
- * survives into `errorCode` on the persisted assistant message and consumers can
201
- * recognize an abort's origin without matching error text. A default
202
- * `abort()` reason is an uncoded DOMException that carries nothing the synthetic
203
- * error does not, so it keeps the "Request was aborted" text every transport
204
- * already emits rather than churning it.
205
- */
206
- function transportAbortError(signal) {
207
- const reason = signal?.reason;
208
- return reason instanceof Error && typeof reason.code === "string" ? reason : /* @__PURE__ */ new Error("Request was aborted");
209
- }
210
- function finalizeTransportStream(params) {
211
- const { stream, output, signal } = params;
212
- if (signal?.aborted) throw transportAbortError(signal);
213
- if (output.stopReason === "aborted" || output.stopReason === "error") throw new Error(output.errorMessage ?? "An unknown error occurred");
214
- stream.push({
215
- type: "done",
216
- reason: output.stopReason,
217
- message: output
218
- });
219
- stream.end();
220
- }
221
- const MAX_TRANSPORT_ERROR_CAUSE_DEPTH = 8;
222
- function readStringLikeProperty(value, key) {
223
- if (!value || typeof value !== "object") return;
224
- const raw = value[key];
225
- if (typeof raw === "string") return raw.trim() || void 0;
226
- if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
227
- }
228
- function readObjectProperty(value, key) {
229
- if (!value || typeof value !== "object") return;
230
- const raw = value[key];
231
- return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : void 0;
232
- }
233
- function readCauseChainErrorCode(value) {
234
- const seen = /* @__PURE__ */ new Set();
235
- let cause = readObjectProperty(value, "cause");
236
- for (let depth = 0; cause && depth < MAX_TRANSPORT_ERROR_CAUSE_DEPTH && !seen.has(cause); depth += 1) {
237
- seen.add(cause);
238
- const code = readStringLikeProperty(cause, "code");
239
- if (code) return code;
240
- cause = readObjectProperty(cause, "cause");
241
- }
242
- }
243
- function stringifyErrorBody(value) {
244
- if (typeof value === "string") return value;
245
- if (value === void 0 || value === null) return;
246
- try {
247
- return JSON.stringify(value);
248
- } catch {
249
- return;
250
- }
251
- }
252
- function stringifyTransportErrorMessage(value) {
253
- if (value instanceof Error) return value.message;
254
- const encoded = stringifyErrorBody(value);
255
- if (encoded !== void 0) return encoded;
256
- try {
257
- return String(value);
258
- } catch {
259
- return;
260
- }
261
- }
262
- function normalizeTransportErrorBody(value) {
263
- const text = stringifyErrorBody(value);
264
- if (!text?.trim()) return;
265
- const redacted = redactSensitiveText(text);
266
- return redacted.length > 500 ? `${truncateUtf16Safe(redacted, 499)}…` : redacted;
267
- }
268
- function extractTransportErrorDetails(error) {
269
- const errorObject = error && typeof error === "object" ? error : void 0;
270
- const nestedError = readObjectProperty(errorObject, "error");
271
- const errorCode = readStringLikeProperty(errorObject, "errorCode") ?? readStringLikeProperty(errorObject, "code") ?? readStringLikeProperty(nestedError, "code") ?? readCauseChainErrorCode(errorObject);
272
- const errorType = readStringLikeProperty(errorObject, "errorType") ?? readStringLikeProperty(errorObject, "type") ?? readStringLikeProperty(nestedError, "type");
273
- const errorBody = normalizeTransportErrorBody(readStringLikeProperty(errorObject, "errorBody")) ?? normalizeTransportErrorBody(readStringLikeProperty(errorObject, "body")) ?? normalizeTransportErrorBody(readObjectProperty(errorObject, "body")) ?? normalizeTransportErrorBody(nestedError);
274
- return {
275
- ...errorCode ? { errorCode } : {},
276
- ...errorType ? { errorType } : {},
277
- ...errorBody ? { errorBody } : {}
278
- };
279
- }
280
- function assignTransportErrorDetails(output, error, signal) {
281
- output.stopReason = signal?.aborted ? "aborted" : "error";
282
- output.errorMessage = stringifyTransportErrorMessage(error);
283
- Object.assign(output, extractTransportErrorDetails(error));
284
- }
285
- function failTransportStream(params) {
286
- const { stream, output, signal, error, cleanup } = params;
287
- cleanup?.();
288
- assignTransportErrorDetails(output, error, signal);
289
- stream.push({
290
- type: "error",
291
- reason: output.stopReason,
292
- error: output
293
- });
294
- stream.end();
295
- }
296
- //#endregion
297
- export { resolveSecretSentinel as C, resolveModelHeaderSentinels as S, supportsModelTools as T, isGoogleGemini3ProModel as _, failTransportStream as a, redactIdentifier as b, mergeTransportMetadata as c, transportAbortError as d, MALFORMED_STREAMING_FRAGMENT_ERROR_MESSAGE as f, isGoogleGemini3FlashModel as g, isCodeModeModelVisibleToolName as h, createWritableTransportEventStream as i, sanitizeNonEmptyTransportPayloadText as l, estimateStringChars as m, coerceTransportToolCallArguments as n, finalizeTransportStream as o, createAbortError as p, createEmptyTransportUsage as r, mergeTransportHeaders as s, assignTransportErrorDetails as t, sanitizeTransportPayloadText as u, parseRetryAfterSeconds as v, sha256Hex as w, redactSensitiveText as x, readResponseTextSnippet as y };