@openclaw/ai 2026.7.2-beta.3 → 2026.7.2-beta.5

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 (60) hide show
  1. package/README.md +6 -5
  2. package/dist/{anthropic-D7SyZQ5v.mjs → anthropic-CQVj3le6.mjs} +174 -33
  3. package/dist/{index-BoTnz8cv.d.mts → anthropic-SrGtwsJu.d.mts} +27 -1
  4. package/dist/{api-registry-DXBIXISf.d.mts → api-registry-DlMgPR39.d.mts} +1 -2
  5. package/dist/{azure-openai-responses-BkZgyZ3I.mjs → azure-openai-responses-DIYgsqFM.mjs} +7 -11
  6. package/dist/{env-api-keys-DnhYpc27.mjs → env-api-keys-DrgeBuva.mjs} +1 -1
  7. package/dist/error-coercion-DgxlWC0n.mjs +15 -0
  8. package/dist/{event-stream-BPemFrFW.d.mts → event-stream-YjaPW20U.d.mts} +1 -1
  9. package/dist/event-stream.d.mts +1 -1
  10. package/dist/{tool-schema-json-projection-BwNu3nDi.mjs → github-copilot-headers-BCoBNmL7.mjs} +48 -1
  11. package/dist/{google-C_biGbV7.mjs → google-f-A8xrae.mjs} +4 -4
  12. package/dist/{google-shared-BK-NoHl8.mjs → google-shared-J6qvYINH.mjs} +5 -4
  13. package/dist/{google-vertex-CvdzF1U7.mjs → google-vertex-D3yMVXIY.mjs} +3 -3
  14. package/dist/host-B9GUmcra.d.mts +173 -0
  15. package/dist/host-XYGZcgO8.mjs +98 -0
  16. package/dist/index-BVVgDSdq.d.mts +1 -0
  17. package/dist/index.d.mts +7 -50
  18. package/dist/index.mjs +3 -3
  19. package/dist/internal/anthropic.d.mts +15 -11
  20. package/dist/internal/anthropic.mjs +4 -4
  21. package/dist/internal/openai.d.mts +3 -280
  22. package/dist/internal/openai.mjs +5 -7
  23. package/dist/internal/runtime.d.mts +13 -34
  24. package/dist/internal/runtime.mjs +19 -11
  25. package/dist/internal/shared.d.mts +13 -8
  26. package/dist/internal/shared.mjs +2 -2
  27. package/dist/{mistral-BdrQmDWp.mjs → mistral-CKV-TOQj.mjs} +7 -6
  28. package/dist/number-coercion-DvG7SNMg.mjs +129 -0
  29. package/dist/openai-BPor_3WI.d.mts +358 -0
  30. package/dist/{openai-responses-shared-CwnGU0KW.mjs → openai-D3PD6PE-.mjs} +1890 -705
  31. package/dist/{openai-chatgpt-responses-DP63Qt01.mjs → openai-chatgpt-responses-CedIj0hk.mjs} +54 -58
  32. package/dist/{openai-completions-zLDfebnN.mjs → openai-completions-CiSutyu0.mjs} +459 -104
  33. package/dist/openai-prompt-cache-2uo_1OR1.d.mts +7 -0
  34. package/dist/openai-prompt-cache-mZTCdRPo.mjs +12 -0
  35. package/dist/prompt-cache-stability-Cwcjv_fx.d.mts +13 -0
  36. package/dist/{provider-error-LMfTEkfO.mjs → provider-error-apVOZI6G.mjs} +9 -2
  37. package/dist/providers.d.mts +3 -2
  38. package/dist/providers.mjs +10 -9
  39. package/dist/{transform-messages-eb6lxDLB.mjs → shared-CdjNZd35.mjs} +273 -161
  40. package/dist/{src-CXno1H5g.mjs → src-QkygScBs.mjs} +23 -4
  41. package/dist/stream-first-event-timeout-C3OgBjIk.mjs +12294 -0
  42. package/dist/stream-first-event-timeout-DvDeSucC.d.mts +29 -0
  43. package/dist/transport-stream-shared-BbMELSI4.mjs +297 -0
  44. package/dist/transports.d.mts +593 -0
  45. package/dist/transports.mjs +4069 -0
  46. package/dist/{types-CYORveZ7.d.mts → types-bzp5k29J.d.mts} +8 -0
  47. package/dist/types.d.mts +5 -5
  48. package/dist/types.mjs +2 -2
  49. package/dist/{validation-BX8euiDv.d.mts → validation-B-j7cOYp.d.mts} +1 -1
  50. package/dist/validation.d.mts +1 -1
  51. package/package.json +36 -11
  52. package/dist/azure-openai-responses-client-compat-C7K7QfUE.mjs +0 -62
  53. package/dist/github-copilot-headers-BsH5cqGj.mjs +0 -48
  54. package/dist/host-4t713IeR.mjs +0 -37
  55. package/dist/model-utils-1GiZ2_rr.mjs +0 -64
  56. package/dist/openai-responses-ClspWt4I.mjs +0 -136
  57. package/dist/openai-tool-projection-WHf2nuOI.mjs +0 -200
  58. package/dist/reasoning-tag-text-partitioner-BlVe67g6.mjs +0 -400
  59. package/dist/stream-first-event-timeout-RjWszj8c.mjs +0 -106
  60. package/npm-shrinkwrap.json +0 -645
@@ -1,200 +0,0 @@
1
- import { f as isRecord } from "./transform-messages-eb6lxDLB.mjs";
2
- import { t as projectRuntimeToolInputSchema } from "./tool-schema-json-projection-BwNu3nDi.mjs";
3
- //#region packages/ai/src/providers/openai-prompt-cache.ts
4
- /** Maximum prompt cache key length accepted by OpenAI-compatible request metadata. */
5
- const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
6
- /** Truncates a prompt cache key by Unicode code point count. */
7
- function clampOpenAIPromptCacheKey(key) {
8
- if (key === void 0) return;
9
- const chars = Array.from(key);
10
- if (chars.length <= 64) return key;
11
- return chars.slice(0, 64).join("");
12
- }
13
- //#endregion
14
- //#region packages/ai/src/providers/openai-tool-projection.ts
15
- function unreadableToolDiagnostic(toolIndex) {
16
- return {
17
- toolIndex,
18
- violations: [`tool[${toolIndex}] is unreadable`]
19
- };
20
- }
21
- /** Snapshots direct/custom tool descriptors before OpenAI payload construction. */
22
- function projectOpenAITools(tools) {
23
- let inputToolCount;
24
- try {
25
- inputToolCount = tools.length;
26
- } catch {
27
- return {
28
- inputToolCount: 0,
29
- tools: [],
30
- diagnostics: [unreadableToolDiagnostic(0)]
31
- };
32
- }
33
- const projectedTools = [];
34
- const diagnostics = [];
35
- for (let toolIndex = 0; toolIndex < inputToolCount; toolIndex += 1) {
36
- let tool;
37
- try {
38
- const candidate = tools[toolIndex];
39
- if (!candidate) {
40
- diagnostics.push(unreadableToolDiagnostic(toolIndex));
41
- continue;
42
- }
43
- tool = candidate;
44
- } catch {
45
- diagnostics.push(unreadableToolDiagnostic(toolIndex));
46
- continue;
47
- }
48
- let name;
49
- try {
50
- name = tool.name;
51
- } catch {
52
- diagnostics.push({
53
- toolIndex,
54
- violations: [`tool[${toolIndex}].name is unreadable`]
55
- });
56
- continue;
57
- }
58
- if (typeof name !== "string" || !name) {
59
- diagnostics.push({
60
- toolIndex,
61
- violations: [`tool[${toolIndex}].name is empty`]
62
- });
63
- continue;
64
- }
65
- let parameters;
66
- try {
67
- parameters = tool.parameters;
68
- } catch {
69
- diagnostics.push({
70
- toolIndex,
71
- toolName: name,
72
- violations: [`${name}.parameters is unreadable`]
73
- });
74
- continue;
75
- }
76
- const schemaProjection = projectRuntimeToolInputSchema(parameters ?? {}, `${name}.parameters`);
77
- if (!isRecord(schemaProjection.schema) || schemaProjection.violations.length > 0) {
78
- diagnostics.push({
79
- toolIndex,
80
- toolName: name,
81
- violations: schemaProjection.violations.length > 0 ? schemaProjection.violations : [`${name}.parameters must be a JSON object schema`]
82
- });
83
- continue;
84
- }
85
- let descriptionValue;
86
- try {
87
- descriptionValue = tool.description;
88
- } catch {}
89
- const description = typeof descriptionValue === "string" ? descriptionValue : void 0;
90
- projectedTools.push({
91
- toolIndex,
92
- name,
93
- ...description !== void 0 ? { description } : {},
94
- parameters: schemaProjection.schema
95
- });
96
- }
97
- return {
98
- inputToolCount,
99
- tools: projectedTools,
100
- diagnostics
101
- };
102
- }
103
- function requireProjectedFunction(name, projection, choiceLabel) {
104
- if (!projection.tools.some((tool) => tool.name === name)) throw new Error(`${choiceLabel} requested unavailable tool "${name}" after schema conversion`);
105
- }
106
- /** Keeps Responses tool choices aligned with surviving function schemas. */
107
- function reconcileOpenAIResponsesToolChoice(choice, projection) {
108
- if (choice === "auto") return projection.tools.length > 0 ? choice : void 0;
109
- if (choice === "required") {
110
- if (projection.tools.length === 0) throw new Error("OpenAI Responses tool_choice requires a tool, but no tools survived schema conversion");
111
- return choice;
112
- }
113
- if (choice === "none" || !isRecord(choice)) return choice;
114
- const choiceType = choice.type;
115
- if (choiceType === "function") {
116
- const functionName = choice.name;
117
- if (typeof functionName !== "string") return choice;
118
- requireProjectedFunction(functionName, projection, "OpenAI Responses tool_choice");
119
- return {
120
- type: "function",
121
- name: functionName
122
- };
123
- }
124
- if (choiceType !== "allowed_tools") return choice;
125
- const mode = choice.mode;
126
- const tools = choice.tools;
127
- if (mode !== "auto" && mode !== "required" || !Array.isArray(tools)) return choice;
128
- const normalizedAllowedTools = [];
129
- for (const tool of tools) {
130
- if (!isRecord(tool) || tool.type !== "function") {
131
- normalizedAllowedTools.push(tool);
132
- continue;
133
- }
134
- const functionName = tool.name;
135
- if (typeof functionName === "string" && projection.tools.some((projectedTool) => projectedTool.name === functionName)) normalizedAllowedTools.push({
136
- type: "function",
137
- name: functionName
138
- });
139
- }
140
- if (normalizedAllowedTools.length === 0) {
141
- if (mode === "auto") return "none";
142
- throw new Error("OpenAI Responses tool_choice requires a tool, but no allowed tools survived schema conversion");
143
- }
144
- return {
145
- type: "allowed_tools",
146
- mode,
147
- tools: normalizedAllowedTools
148
- };
149
- }
150
- /** Keeps Chat Completions tool choices aligned with surviving function schemas. */
151
- function reconcileOpenAICompletionsToolChoice(choice, projection) {
152
- if (choice === "auto") return projection.tools.length > 0 ? choice : void 0;
153
- if (choice === "required") {
154
- if (projection.tools.length === 0) throw new Error("OpenAI Chat Completions tool_choice requires a tool, but no tools survived schema conversion");
155
- return choice;
156
- }
157
- if (choice === "none" || !isRecord(choice)) return choice;
158
- const choiceType = choice.type;
159
- if (choiceType === "custom") throw new Error("OpenAI Chat Completions custom tool_choice is unsupported because this adapter emits function tools only");
160
- if (choiceType === "function") {
161
- const functionChoice = choice.function;
162
- if (!isRecord(functionChoice)) return choice;
163
- const functionName = functionChoice.name;
164
- if (typeof functionName !== "string") return choice;
165
- requireProjectedFunction(functionName, projection, "OpenAI Chat Completions tool_choice");
166
- return {
167
- type: "function",
168
- function: { name: functionName }
169
- };
170
- }
171
- if (choiceType !== "allowed_tools") return choice;
172
- const allowedConfig = choice.allowed_tools;
173
- if (!isRecord(allowedConfig)) return choice;
174
- const mode = allowedConfig.mode;
175
- const tools = allowedConfig.tools;
176
- if (mode !== "auto" && mode !== "required" || !Array.isArray(tools)) return choice;
177
- const normalizedAllowedTools = [];
178
- for (const tool of tools) {
179
- if (!isRecord(tool) || tool.type !== "function") continue;
180
- const functionChoice = tool.function;
181
- const functionName = isRecord(functionChoice) ? functionChoice.name : void 0;
182
- if (typeof functionName === "string" && projection.tools.some((projectedTool) => projectedTool.name === functionName)) normalizedAllowedTools.push({
183
- type: "function",
184
- function: { name: functionName }
185
- });
186
- }
187
- if (normalizedAllowedTools.length === 0) {
188
- if (mode === "auto") return "none";
189
- throw new Error("OpenAI Chat Completions tool_choice requires a tool, but no allowed tools survived schema conversion");
190
- }
191
- return {
192
- type: "allowed_tools",
193
- allowed_tools: {
194
- mode,
195
- tools: normalizedAllowedTools
196
- }
197
- };
198
- }
199
- //#endregion
200
- export { clampOpenAIPromptCacheKey as a, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH as i, reconcileOpenAICompletionsToolChoice as n, reconcileOpenAIResponsesToolChoice as r, projectOpenAITools as t };
@@ -1,400 +0,0 @@
1
- //#region packages/markdown-core/src/fences.ts
2
- /** Scans fenced-code spans incrementally so chunking can carry an open fence forward. */
3
- function scanFenceSpans(buffer, state) {
4
- const spans = [];
5
- const startsAtLineStart = state?.atLineStart ?? true;
6
- let open = state?.open ? {
7
- ...state.open,
8
- start: 0
9
- } : void 0;
10
- let offset = 0;
11
- while (offset <= buffer.length) {
12
- const nextNewline = buffer.indexOf("\n", offset);
13
- const lineEnd = nextNewline === -1 ? buffer.length : nextNewline;
14
- const line = buffer.slice(offset, lineEnd).replace(/\r$/, "");
15
- const match = line.match(/^( {0,3})(`{3,}|~{3,})(.*)$/);
16
- if (match && (offset > 0 || startsAtLineStart)) {
17
- const [, indent, marker, trailing] = match;
18
- if (indent === void 0 || marker === void 0 || trailing === void 0) {
19
- if (nextNewline === -1) break;
20
- offset = nextNewline + 1;
21
- continue;
22
- }
23
- const markerChar = marker.charAt(0);
24
- const markerLen = marker.length;
25
- if (!open) open = {
26
- start: offset,
27
- markerChar,
28
- markerLen,
29
- openLine: line,
30
- marker,
31
- indent
32
- };
33
- else if (open.markerChar === markerChar && markerLen >= open.markerLen && /^[ \t]*$/.test(trailing)) {
34
- const end = lineEnd;
35
- spans.push({
36
- start: open.start,
37
- end,
38
- openLine: open.openLine,
39
- marker: open.marker,
40
- indent: open.indent
41
- });
42
- open = void 0;
43
- }
44
- }
45
- if (nextNewline === -1) break;
46
- offset = nextNewline + 1;
47
- }
48
- if (open) spans.push({
49
- start: open.start,
50
- end: buffer.length,
51
- openLine: open.openLine,
52
- marker: open.marker,
53
- indent: open.indent
54
- });
55
- return {
56
- spans,
57
- state: {
58
- atLineStart: buffer.length === 0 ? startsAtLineStart : buffer.endsWith("\n"),
59
- ...open ? { open: {
60
- markerChar: open.markerChar,
61
- markerLen: open.markerLen,
62
- openLine: open.openLine,
63
- marker: open.marker,
64
- indent: open.indent
65
- } } : {}
66
- }
67
- };
68
- }
69
- //#endregion
70
- //#region packages/markdown-core/src/code-spans.ts
71
- /** Creates the carry-forward state used when scanning inline code across chunks. */
72
- function createInlineCodeState() {
73
- return {
74
- open: false,
75
- ticks: 0
76
- };
77
- }
78
- /** Builds a lookup for fenced and inline code spans while preserving scanner state. */
79
- function buildCodeSpanIndex(text, inlineState, fenceState) {
80
- const { spans: fenceSpans, state: nextFenceState } = scanFenceSpans(text, fenceState);
81
- const { spans: inlineSpans, state: nextInlineState } = parseInlineCodeSpans(text, fenceSpans, inlineState ? {
82
- open: inlineState.open,
83
- ticks: inlineState.ticks
84
- } : createInlineCodeState());
85
- return {
86
- inlineState: nextInlineState,
87
- fenceState: nextFenceState,
88
- isInside: (index) => isInsideFenceSpan(index, fenceSpans) || isInsideInlineSpan(index, inlineSpans)
89
- };
90
- }
91
- function parseInlineCodeSpans(text, fenceSpans, initialState) {
92
- const spans = [];
93
- let open = initialState.open;
94
- let ticks = initialState.ticks;
95
- let openStart = open ? 0 : -1;
96
- let i = 0;
97
- while (i < text.length) {
98
- const fence = findFenceSpanAtInclusive(fenceSpans, i);
99
- if (fence) {
100
- i = fence.end;
101
- continue;
102
- }
103
- if (text[i] !== "`") {
104
- i += 1;
105
- continue;
106
- }
107
- const runStart = i;
108
- let runLength = 0;
109
- while (i < text.length && text[i] === "`") {
110
- runLength += 1;
111
- i += 1;
112
- }
113
- if (!open) {
114
- open = true;
115
- ticks = runLength;
116
- openStart = runStart;
117
- continue;
118
- }
119
- if (runLength === ticks) {
120
- spans.push([openStart, i]);
121
- open = false;
122
- ticks = 0;
123
- openStart = -1;
124
- }
125
- }
126
- if (open) spans.push([openStart, text.length]);
127
- return {
128
- spans,
129
- state: {
130
- open,
131
- ticks
132
- }
133
- };
134
- }
135
- function findFenceSpanAtInclusive(spans, index) {
136
- return spans.find((span) => index >= span.start && index < span.end);
137
- }
138
- function isInsideFenceSpan(index, spans) {
139
- return spans.some((span) => index >= span.start && index < span.end);
140
- }
141
- function isInsideInlineSpan(index, spans) {
142
- return spans.some(([start, end]) => index >= start && index < end);
143
- }
144
- //#endregion
145
- //#region packages/ai/src/utils/reasoning-tag-text-partitioner.ts
146
- const REASONING_TAG_RE = /<\s*(\/?)\s*(?:(?:antml:|mm:)?(?:think(?:ing)?|thought|reasoning)|antthinking)\b[^<>]*>/gi;
147
- const REASONING_TAG_NAMES = [
148
- "think",
149
- "thinking",
150
- "thought",
151
- "reasoning",
152
- "antthinking",
153
- "antml:think",
154
- "antml:thinking",
155
- "antml:thought",
156
- "antml:reasoning",
157
- "mm:think",
158
- "mm:thinking",
159
- "mm:thought",
160
- "mm:reasoning"
161
- ];
162
- function createReasoningTagTextPartitioner() {
163
- let buffer = "";
164
- let reasoningDepth = 0;
165
- let strictMode = false;
166
- let emittedVisibleText = false;
167
- let inlineCodeState = createInlineCodeState();
168
- let fenceState;
169
- let hiddenInlineCodeState = createInlineCodeState();
170
- let hiddenFenceState;
171
- let recoverableOpenTagText;
172
- const consume = (final, recoverFullUnclosed) => {
173
- const output = [];
174
- const emit = (kind, text) => {
175
- if (!text) return;
176
- if (kind === "text" && text.trim().length > 0) emittedVisibleText = true;
177
- if (kind === "text") {
178
- const nextCode = buildCodeSpanIndex(text, inlineCodeState, fenceState);
179
- inlineCodeState = nextCode.inlineState;
180
- fenceState = nextCode.fenceState;
181
- } else {
182
- const nextCode = buildCodeSpanIndex(text, hiddenInlineCodeState, hiddenFenceState);
183
- hiddenInlineCodeState = nextCode.inlineState;
184
- hiddenFenceState = nextCode.fenceState;
185
- }
186
- const previous = output[output.length - 1];
187
- if (previous?.kind === kind) {
188
- previous.text += text;
189
- return;
190
- }
191
- output.push({
192
- kind,
193
- text
194
- });
195
- };
196
- while (buffer) {
197
- const activeInlineCodeState = reasoningDepth === 0 ? inlineCodeState : hiddenInlineCodeState;
198
- const activeFenceState = reasoningDepth === 0 ? fenceState : hiddenFenceState;
199
- const codeSpans = buildCodeSpanIndex(buffer, activeInlineCodeState, activeFenceState);
200
- const hasUnclosedCode = reasoningDepth === 0 && Boolean(codeSpans.inlineState.open || codeSpans.fenceState.open);
201
- const hasRawReasoning = hasRawReasoningTag(buffer);
202
- const tag = findNextReasoningTag(buffer, (index) => final && hasUnclosedCode && hasRawReasoning ? false : codeSpans.isInside(index));
203
- if (!tag) {
204
- if (final) {
205
- const recoverAsText = reasoningDepth > 0 && recoverFullUnclosed && !hasRawReasoningCloseTag(buffer);
206
- const recoveredText = recoverAsText && recoverableOpenTagText ? recoverableOpenTagText + buffer : buffer;
207
- emit(reasoningDepth > 0 && !recoverAsText ? "thinking" : "text", recoveredText);
208
- buffer = "";
209
- reasoningDepth = 0;
210
- recoverableOpenTagText = void 0;
211
- return output;
212
- }
213
- if (reasoningDepth > 0 && recoverFullUnclosed && (!emittedVisibleText || recoverableOpenTagText)) return output;
214
- if (hasUnclosedCode && hasRawReasoning) {
215
- const openCodeIndex = inlineCodeState.open || fenceState?.open ? 0 : findOpenCodeContextStart(buffer);
216
- if (openCodeIndex !== -1) {
217
- emit("text", buffer.slice(0, openCodeIndex));
218
- buffer = buffer.slice(openCodeIndex);
219
- return output;
220
- }
221
- }
222
- const trailingFenceStart = findTrailingFenceFragmentStart(buffer, activeInlineCodeState, activeFenceState);
223
- if (trailingFenceStart !== -1) {
224
- emit(reasoningDepth > 0 ? "thinking" : "text", buffer.slice(0, trailingFenceStart));
225
- buffer = buffer.slice(trailingFenceStart);
226
- return output;
227
- }
228
- const keepFrom = reasoningTagPrefixSuffixIndex(buffer, (index) => codeSpans.isInside(index));
229
- if (keepFrom === -1) {
230
- emit(reasoningDepth > 0 ? "thinking" : "text", buffer);
231
- buffer = "";
232
- return output;
233
- }
234
- if (reasoningDepth === 0 && keepFrom > 0 && buffer.slice(0, keepFrom).trim().length > 0 && isReasoningCloseTagPrefix(buffer.slice(keepFrom))) return output;
235
- if (keepFrom > 0) {
236
- emit(reasoningDepth > 0 ? "thinking" : "text", buffer.slice(0, keepFrom));
237
- buffer = buffer.slice(keepFrom);
238
- }
239
- return output;
240
- }
241
- const beforeTag = buffer.slice(0, tag.index);
242
- const afterTag = buffer.slice(tag.index + tag.text.length);
243
- if (tag.isClose && reasoningDepth === 0) {
244
- if (recoverFullUnclosed && beforeTag.trim().length > 0 && afterTag.trim().length > 0) {
245
- emit("text", beforeTag + tag.text);
246
- buffer = afterTag;
247
- continue;
248
- }
249
- if (beforeTag.trim().length > 0 && afterTag.trim().length === 0 && !final) return output;
250
- if (beforeTag.trim().length === 0 || afterTag.trim().length === 0) emit("text", beforeTag);
251
- buffer = afterTag;
252
- continue;
253
- }
254
- emit(reasoningDepth > 0 ? "thinking" : "text", buffer.slice(0, tag.index));
255
- buffer = afterTag;
256
- if (tag.isClose) {
257
- reasoningDepth = Math.max(0, reasoningDepth - 1);
258
- if (reasoningDepth === 0) {
259
- recoverableOpenTagText = void 0;
260
- hiddenInlineCodeState = createInlineCodeState();
261
- hiddenFenceState = void 0;
262
- }
263
- } else {
264
- if (reasoningDepth === 0) {
265
- recoverableOpenTagText = recoverFullUnclosed && emittedVisibleText ? tag.text : void 0;
266
- hiddenInlineCodeState = createInlineCodeState();
267
- hiddenFenceState = void 0;
268
- }
269
- reasoningDepth += 1;
270
- }
271
- }
272
- return output;
273
- };
274
- return {
275
- markStrict() {
276
- strictMode = true;
277
- },
278
- push(chunk) {
279
- strictMode = true;
280
- buffer += chunk;
281
- return consume(false, false);
282
- },
283
- pushVisible(chunk) {
284
- buffer += chunk;
285
- return consume(false, true);
286
- },
287
- flush() {
288
- return consume(true, !strictMode);
289
- },
290
- hasPending() {
291
- return buffer.length > 0 || reasoningDepth > 0;
292
- },
293
- isInsideReasoning() {
294
- return reasoningDepth > 0;
295
- }
296
- };
297
- }
298
- function hasRawReasoningTag(text) {
299
- REASONING_TAG_RE.lastIndex = 0;
300
- return REASONING_TAG_RE.test(text);
301
- }
302
- function hasRawReasoningCloseTag(text) {
303
- REASONING_TAG_RE.lastIndex = 0;
304
- for (;;) {
305
- const match = REASONING_TAG_RE.exec(text);
306
- if (!match) return false;
307
- if (match[1] === "/") return true;
308
- }
309
- }
310
- function findNextReasoningTag(text, isIndexInsideCode) {
311
- REASONING_TAG_RE.lastIndex = 0;
312
- for (;;) {
313
- const match = REASONING_TAG_RE.exec(text);
314
- if (!match) return null;
315
- if (!isIndexInsideCode(match.index)) return {
316
- index: match.index,
317
- text: match[0],
318
- isClose: match[1] === "/"
319
- };
320
- }
321
- }
322
- function reasoningTagPrefixSuffixIndex(text, isIndexInsideCode) {
323
- for (let index = text.lastIndexOf("<"); index >= 0;) {
324
- if (!isIndexInsideCode(index) && isReasoningTagPrefix(text.slice(index))) return index;
325
- if (index === 0) break;
326
- index = text.lastIndexOf("<", index - 1);
327
- }
328
- return -1;
329
- }
330
- function isReasoningTagPrefix(text) {
331
- const name = normalizeReasoningTagPrefixName(text);
332
- return REASONING_TAG_NAMES.some((tagName) => {
333
- if (tagName.startsWith(name)) return true;
334
- if (!name.startsWith(tagName)) return false;
335
- const rest = name.slice(tagName.length);
336
- return rest.length === 0 || /^[\s/>]/.test(rest);
337
- });
338
- }
339
- function isReasoningCloseTagPrefix(text) {
340
- return text.replace(/^<\s*/, "<").replace(/^<\s*\//, "</").replace(/^<\/\s*/, "</").toLowerCase().startsWith("</") && isReasoningTagPrefix(text);
341
- }
342
- function normalizeReasoningTagPrefixName(text) {
343
- const normalized = text.replace(/^<\s*/, "<").replace(/^<\s*\//, "</").replace(/^<\/\s*/, "</").toLowerCase();
344
- return (normalized.startsWith("</") ? normalized.slice(2) : normalized.slice(1)).trimStart();
345
- }
346
- function findOpenCodeContextStart(text) {
347
- const fence = findOpenFenceStart(text);
348
- const inline = findOpenInlineCodeStart(text);
349
- if (fence === -1) return inline;
350
- if (inline === -1) return fence;
351
- return Math.min(fence, inline);
352
- }
353
- function findOpenInlineCodeStart(text) {
354
- let openStart = -1;
355
- let openTicks = 0;
356
- let index = 0;
357
- while (index < text.length) {
358
- if (text.charAt(index) !== "`") {
359
- index += 1;
360
- continue;
361
- }
362
- const runStart = index;
363
- let runLength = 0;
364
- while (index < text.length && text.charAt(index) === "`") {
365
- runLength += 1;
366
- index += 1;
367
- }
368
- if (openStart === -1) {
369
- openStart = runStart;
370
- openTicks = runLength;
371
- } else if (runLength === openTicks) {
372
- openStart = -1;
373
- openTicks = 0;
374
- }
375
- }
376
- return openStart;
377
- }
378
- function findOpenFenceStart(text) {
379
- const fenceRe = /(^|\n)(```|~~~)[^\n]*(?:\n|$)/g;
380
- let open = null;
381
- for (const match of text.matchAll(fenceRe)) {
382
- const prefix = match.at(1);
383
- const marker = match.at(2);
384
- if (prefix === void 0 || marker === void 0) continue;
385
- const index = (match.index ?? 0) + prefix.length;
386
- if (open !== null && open.marker === marker) open = null;
387
- else if (!open) open = {
388
- marker,
389
- index
390
- };
391
- }
392
- return open?.index ?? -1;
393
- }
394
- function findTrailingFenceFragmentStart(text, inlineState, fenceState) {
395
- if (inlineState.open || fenceState?.open) return -1;
396
- const lineStart = Math.max(text.lastIndexOf("\n") + 1, 0);
397
- return text.slice(lineStart).match(/^( {0,3})(`{1,2}|~{1,2})$/) ? lineStart : -1;
398
- }
399
- //#endregion
400
- export { createReasoningTagTextPartitioner as t };
@@ -1,106 +0,0 @@
1
- //#region packages/normalization-core/src/number-coercion.ts
2
- /** Returns a number only when the input is already finite. */
3
- function asFiniteNumber(value) {
4
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
5
- }
6
- /** Conservative upper bound for Node timer delays. */
7
- const MAX_TIMER_TIMEOUT_MS = 2147e6;
8
- /** Clamps finite millisecond values into the Node-safe timer range. */
9
- function clampTimerTimeoutMs(valueMs, minMs = 1) {
10
- const value = asFiniteNumber(valueMs);
11
- if (value === void 0) return;
12
- return Math.min(Math.max(Math.floor(value), Math.max(1, Math.floor(minMs))), MAX_TIMER_TIMEOUT_MS);
13
- }
14
- /** Resolves arbitrary timeout input with fallback and minimum timer bounds. */
15
- function resolveTimerTimeoutMs(valueMs, fallbackMs, minMs = 1) {
16
- const value = asFiniteNumber(valueMs) ?? asFiniteNumber(fallbackMs);
17
- const min = Math.max(0, Math.floor(minMs));
18
- if (value === void 0) return min;
19
- return Math.min(Math.max(Math.floor(value), min), MAX_TIMER_TIMEOUT_MS);
20
- }
21
- //#endregion
22
- //#region packages/ai/src/utils/stream-first-event-timeout.ts
23
- function getFirstStreamEventTimeoutMs(options) {
24
- return options?.firstEventTimeoutMs;
25
- }
26
- function getFirstStreamEventTimeoutHandler(options) {
27
- return options?.onFirstEventTimeout;
28
- }
29
- function formatOptionalField(name, value) {
30
- return value ? ` ${name}=${value}` : "";
31
- }
32
- function createFirstStreamEventTimeoutError(context) {
33
- const stage = context.stage ? `${context.stage} ` : "";
34
- const details = [
35
- formatOptionalField("provider", context.provider),
36
- formatOptionalField("api", context.api),
37
- formatOptionalField("model", context.model)
38
- ].join("");
39
- return /* @__PURE__ */ new Error(`${stage}HTTP stream opened but did not deliver a first SSE event within ${context.timeoutMs}ms after streaming headers (first-event timeout).${details}` + (context.hint ? ` ${context.hint}` : ""));
40
- }
41
- function createFirstStreamEventAbortController(parentSignal) {
42
- const controller = new AbortController();
43
- const abortFromParent = () => {
44
- if (!controller.signal.aborted) controller.abort(parentSignal?.reason);
45
- };
46
- if (parentSignal?.aborted) abortFromParent();
47
- else parentSignal?.addEventListener("abort", abortFromParent, { once: true });
48
- return {
49
- signal: controller.signal,
50
- abort(reason) {
51
- if (!controller.signal.aborted) controller.abort(reason);
52
- },
53
- dispose() {
54
- parentSignal?.removeEventListener("abort", abortFromParent);
55
- }
56
- };
57
- }
58
- function withFirstStreamEventTimeout(stream, context) {
59
- const timeoutMs = clampTimerTimeoutMs(context.timeoutMs);
60
- if (timeoutMs === void 0 || context.timeoutMs <= 0) return stream;
61
- const timeoutContext = {
62
- ...context,
63
- timeoutMs
64
- };
65
- return { async *[Symbol.asyncIterator]() {
66
- const iterator = stream[Symbol.asyncIterator]();
67
- let timer;
68
- let completed = false;
69
- const clear = () => {
70
- if (timer) {
71
- clearTimeout(timer);
72
- timer = void 0;
73
- }
74
- };
75
- try {
76
- const first = await new Promise((resolve, reject) => {
77
- timer = setTimeout(() => {
78
- const timeoutError = createFirstStreamEventTimeoutError(timeoutContext);
79
- timeoutContext.onTimeout?.(timeoutError);
80
- timeoutContext.abort?.(timeoutError);
81
- reject(timeoutError);
82
- }, timeoutMs);
83
- timer.unref?.();
84
- iterator.next().then(resolve, reject);
85
- }).finally(clear);
86
- if (first.done) {
87
- completed = true;
88
- return;
89
- }
90
- yield first.value;
91
- for (;;) {
92
- const next = await iterator.next();
93
- if (next.done) {
94
- completed = true;
95
- return;
96
- }
97
- yield next.value;
98
- }
99
- } finally {
100
- clear();
101
- if (!completed) iterator.return?.().catch(() => void 0);
102
- }
103
- } };
104
- }
105
- //#endregion
106
- export { withFirstStreamEventTimeout as a, getFirstStreamEventTimeoutMs as i, createFirstStreamEventTimeoutError as n, clampTimerTimeoutMs as o, getFirstStreamEventTimeoutHandler as r, resolveTimerTimeoutMs as s, createFirstStreamEventAbortController as t };