@ai-sdk-tool/parser 3.0.0 → 3.1.0
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.
- package/README.md +7 -9
- package/dist/{v6.cjs → chunk-JVQVEA3K.js} +1874 -1793
- package/dist/chunk-JVQVEA3K.js.map +1 -0
- package/dist/community.cjs +308 -284
- package/dist/community.cjs.map +1 -1
- package/dist/community.d.cts +0 -14
- package/dist/community.d.ts +0 -14
- package/dist/community.js +9 -10
- package/dist/community.js.map +1 -1
- package/dist/index.cjs +325 -294
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +152 -18
- package/dist/index.d.ts +152 -18
- package/dist/index.js +24 -21
- package/package.json +3 -17
- package/dist/chunk-DFOXAWP6.js +0 -1
- package/dist/chunk-DFOXAWP6.js.map +0 -1
- package/dist/chunk-NOYHOQOL.js +0 -2489
- package/dist/chunk-NOYHOQOL.js.map +0 -1
- package/dist/chunk-QPJA5CS6.js +0 -1289
- package/dist/chunk-QPJA5CS6.js.map +0 -1
- package/dist/tool-call-protocol-Bn2CBcD-.d.cts +0 -84
- package/dist/tool-call-protocol-Bn2CBcD-.d.ts +0 -84
- package/dist/v5.cjs +0 -2816
- package/dist/v5.cjs.map +0 -1
- package/dist/v5.d.cts +0 -14
- package/dist/v5.d.ts +0 -14
- package/dist/v5.js +0 -476
- package/dist/v5.js.map +0 -1
- package/dist/v6.cjs.map +0 -1
- package/dist/v6.d.cts +0 -16
- package/dist/v6.d.ts +0 -16
- package/dist/v6.js +0 -16
- package/dist/v6.js.map +0 -1
|
@@ -1,1644 +1,1652 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/v6/index.ts
|
|
31
|
-
var v6_exports = {};
|
|
32
|
-
__export(v6_exports, {
|
|
33
|
-
createToolMiddleware: () => createToolMiddleware,
|
|
34
|
-
gemmaToolMiddleware: () => gemmaToolMiddleware,
|
|
35
|
-
hermesToolMiddleware: () => hermesToolMiddleware,
|
|
36
|
-
morphXmlToolMiddleware: () => morphXmlToolMiddleware,
|
|
37
|
-
orchestratorToolMiddleware: () => orchestratorToolMiddleware
|
|
38
|
-
});
|
|
39
|
-
module.exports = __toCommonJS(v6_exports);
|
|
40
|
-
|
|
41
|
-
// src/core/utils/debug.ts
|
|
42
|
-
var LINE_SPLIT_REGEX = /\r?\n/;
|
|
43
|
-
function normalizeBooleanString(value) {
|
|
44
|
-
const normalized = value.trim().toLowerCase();
|
|
45
|
-
if (normalized === "1" || normalized === "true" || normalized === "yes") {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
if (normalized === "0" || normalized === "false" || normalized === "no") {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
function getDebugLevel() {
|
|
54
|
-
const envVal = typeof process !== "undefined" && process.env && process.env.DEBUG_PARSER_MW || "off";
|
|
55
|
-
const envLower = String(envVal).toLowerCase();
|
|
56
|
-
if (envLower === "stream" || envLower === "parse" || envLower === "off") {
|
|
57
|
-
return envLower;
|
|
58
|
-
}
|
|
59
|
-
const boolEnv = normalizeBooleanString(envLower);
|
|
60
|
-
if (boolEnv === true) {
|
|
61
|
-
return "stream";
|
|
62
|
-
}
|
|
63
|
-
if (envLower === "2") {
|
|
64
|
-
return "parse";
|
|
65
|
-
}
|
|
66
|
-
return "off";
|
|
67
|
-
}
|
|
68
|
-
function color(code) {
|
|
69
|
-
return (text) => `\x1B[${code}m${text}\x1B[0m`;
|
|
70
|
-
}
|
|
71
|
-
var ANSI_GRAY = 90;
|
|
72
|
-
var ANSI_YELLOW = 33;
|
|
73
|
-
var ANSI_CYAN = 36;
|
|
74
|
-
var ANSI_BG_BLUE = 44;
|
|
75
|
-
var ANSI_BG_GREEN = 42;
|
|
76
|
-
var ANSI_INVERSE = 7;
|
|
77
|
-
var ANSI_UNDERLINE = 4;
|
|
78
|
-
var ANSI_BOLD = 1;
|
|
79
|
-
var cGray = color(ANSI_GRAY);
|
|
80
|
-
var cYellow = color(ANSI_YELLOW);
|
|
81
|
-
var cCyan = color(ANSI_CYAN);
|
|
82
|
-
var cBgBlue = color(ANSI_BG_BLUE);
|
|
83
|
-
var cBgGreen = color(ANSI_BG_GREEN);
|
|
84
|
-
var cInverse = color(ANSI_INVERSE);
|
|
85
|
-
var cUnderline = color(ANSI_UNDERLINE);
|
|
86
|
-
var cBold = color(ANSI_BOLD);
|
|
87
|
-
var MAX_SNIPPET_LENGTH = 800;
|
|
88
|
-
function safeStringify(value) {
|
|
89
|
-
try {
|
|
90
|
-
return `
|
|
91
|
-
${typeof value === "string" ? value : JSON.stringify(value, null, 2)}`;
|
|
92
|
-
} catch (e) {
|
|
93
|
-
return String(value);
|
|
1
|
+
// src/core/heuristics/engine.ts
|
|
2
|
+
function applyRawSegmentUpdate(current, result) {
|
|
3
|
+
if (result.rawSegment !== void 0) {
|
|
4
|
+
return { ...current, rawSegment: result.rawSegment };
|
|
94
5
|
}
|
|
6
|
+
return current;
|
|
95
7
|
}
|
|
96
|
-
function
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
${error.stack}` : "";
|
|
100
|
-
return `
|
|
101
|
-
${error.name}: ${error.message}${stack}`;
|
|
8
|
+
function applyParsedUpdate(current, result) {
|
|
9
|
+
if (result.parsed !== void 0) {
|
|
10
|
+
return { ...current, parsed: result.parsed };
|
|
102
11
|
}
|
|
103
|
-
return
|
|
12
|
+
return current;
|
|
104
13
|
}
|
|
105
|
-
function
|
|
106
|
-
|
|
107
|
-
|
|
14
|
+
function applyWarningsUpdate(current, result) {
|
|
15
|
+
var _a, _b;
|
|
16
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
17
|
+
const meta = (_a = current.meta) != null ? _a : {};
|
|
18
|
+
const existingWarnings = (_b = meta.warnings) != null ? _b : [];
|
|
19
|
+
return {
|
|
20
|
+
...current,
|
|
21
|
+
meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
|
|
22
|
+
};
|
|
108
23
|
}
|
|
109
|
-
return
|
|
110
|
-
\u2026[truncated ${snippet.length - MAX_SNIPPET_LENGTH} chars]`;
|
|
24
|
+
return current;
|
|
111
25
|
}
|
|
112
|
-
function
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
snippet,
|
|
116
|
-
error
|
|
117
|
-
}) {
|
|
118
|
-
if (getDebugLevel() !== "parse") {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
const label = cBgBlue(`[${phase}]`);
|
|
122
|
-
console.log(cGray("[debug:mw:fail]"), label, cYellow(reason));
|
|
123
|
-
if (snippet) {
|
|
124
|
-
const formatted = truncateSnippet(snippet);
|
|
125
|
-
console.log(cGray("[debug:mw:fail:snippet]"), formatted);
|
|
26
|
+
function attemptReparse(current, result, reparseCount, maxReparses, parse4) {
|
|
27
|
+
if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
|
|
28
|
+
return { state: current, newCount: reparseCount };
|
|
126
29
|
}
|
|
127
|
-
|
|
128
|
-
|
|
30
|
+
try {
|
|
31
|
+
const reparsed = parse4(result.rawSegment, current.schema);
|
|
32
|
+
return {
|
|
33
|
+
state: { ...current, parsed: reparsed, errors: [] },
|
|
34
|
+
newCount: reparseCount + 1
|
|
35
|
+
};
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return {
|
|
38
|
+
state: { ...current, errors: [...current.errors, error] },
|
|
39
|
+
newCount: reparseCount + 1
|
|
40
|
+
};
|
|
129
41
|
}
|
|
130
42
|
}
|
|
131
|
-
function
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
43
|
+
function executePhase(ctx, heuristics, options) {
|
|
44
|
+
var _a;
|
|
45
|
+
let current = ctx;
|
|
46
|
+
let reparseCount = 0;
|
|
47
|
+
const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
|
|
48
|
+
for (const heuristic of heuristics) {
|
|
49
|
+
if (!heuristic.applies(current)) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const result = heuristic.run(current);
|
|
53
|
+
current = applyRawSegmentUpdate(current, result);
|
|
54
|
+
current = applyParsedUpdate(current, result);
|
|
55
|
+
current = applyWarningsUpdate(current, result);
|
|
56
|
+
const reparseResult = attemptReparse(
|
|
57
|
+
current,
|
|
58
|
+
result,
|
|
59
|
+
reparseCount,
|
|
60
|
+
maxReparses,
|
|
61
|
+
options.parse
|
|
62
|
+
);
|
|
63
|
+
current = reparseResult.state;
|
|
64
|
+
reparseCount = reparseResult.newCount;
|
|
65
|
+
if (result.stop) {
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
155
68
|
}
|
|
156
|
-
return
|
|
69
|
+
return current;
|
|
157
70
|
}
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (style === "underline") {
|
|
163
|
-
return cUnderline;
|
|
71
|
+
function applyHeuristicPipeline(ctx, config, options) {
|
|
72
|
+
let current = ctx;
|
|
73
|
+
if (config.preParse && config.preParse.length > 0) {
|
|
74
|
+
current = executePhase(current, config.preParse, options);
|
|
164
75
|
}
|
|
165
|
-
if (
|
|
166
|
-
|
|
76
|
+
if (current.parsed === null && current.errors.length === 0) {
|
|
77
|
+
try {
|
|
78
|
+
const parsed = options.parse(current.rawSegment, current.schema);
|
|
79
|
+
current = { ...current, parsed, errors: [] };
|
|
80
|
+
} catch (error) {
|
|
81
|
+
current = { ...current, errors: [error] };
|
|
82
|
+
}
|
|
167
83
|
}
|
|
168
|
-
if (
|
|
169
|
-
|
|
84
|
+
if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
|
|
85
|
+
current = executePhase(current, config.fallbackReparse, options);
|
|
170
86
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
function renderHighlightedText(originalText, style, highlight) {
|
|
174
|
-
if (style === "bg" || style === "inverse" || style === "underline" || style === "bold") {
|
|
175
|
-
return originalText.split(LINE_SPLIT_REGEX).map((line) => line.length ? highlight(line) : line).join("\n");
|
|
87
|
+
if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
|
|
88
|
+
current = executePhase(current, config.postParse, options);
|
|
176
89
|
}
|
|
177
|
-
return
|
|
90
|
+
return current;
|
|
178
91
|
}
|
|
179
|
-
function
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
${rendered}`);
|
|
189
|
-
}
|
|
190
|
-
if (toolCalls.length > 0) {
|
|
191
|
-
const styledSummary = safeStringify(toolCalls).split(LINE_SPLIT_REGEX).map((line) => line.length ? cBgBlue(line) : line).join("\n");
|
|
192
|
-
console.log(cGray("[debug:mw:summary]"), styledSummary);
|
|
193
|
-
}
|
|
92
|
+
function createIntermediateCall(toolName, rawSegment, schema) {
|
|
93
|
+
return {
|
|
94
|
+
toolName,
|
|
95
|
+
schema,
|
|
96
|
+
rawSegment,
|
|
97
|
+
parsed: null,
|
|
98
|
+
errors: [],
|
|
99
|
+
meta: { originalContent: rawSegment }
|
|
100
|
+
};
|
|
194
101
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
102
|
+
function mergePipelineConfigs(...configs) {
|
|
103
|
+
var _a, _b, _c;
|
|
104
|
+
const result = {
|
|
105
|
+
preParse: [],
|
|
106
|
+
fallbackReparse: [],
|
|
107
|
+
postParse: []
|
|
108
|
+
};
|
|
109
|
+
for (const config of configs) {
|
|
110
|
+
if (config.preParse) {
|
|
111
|
+
result.preParse = [...(_a = result.preParse) != null ? _a : [], ...config.preParse];
|
|
112
|
+
}
|
|
113
|
+
if (config.fallbackReparse) {
|
|
114
|
+
result.fallbackReparse = [
|
|
115
|
+
...(_b = result.fallbackReparse) != null ? _b : [],
|
|
116
|
+
...config.fallbackReparse
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
if (config.postParse) {
|
|
120
|
+
result.postParse = [...(_c = result.postParse) != null ? _c : [], ...config.postParse];
|
|
209
121
|
}
|
|
210
122
|
}
|
|
211
|
-
return
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// src/core/utils/id.ts
|
|
215
|
-
function generateId() {
|
|
216
|
-
return Math.random().toString(36).substring(2, 15);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// src/core/utils/regex.ts
|
|
220
|
-
function escapeRegExp(literal) {
|
|
221
|
-
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
123
|
+
return result;
|
|
222
124
|
}
|
|
223
125
|
|
|
224
|
-
// src/core/
|
|
225
|
-
|
|
226
|
-
var
|
|
227
|
-
var
|
|
228
|
-
var
|
|
229
|
-
var
|
|
230
|
-
var
|
|
231
|
-
var
|
|
232
|
-
var
|
|
233
|
-
var
|
|
234
|
-
var
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
for (let i = 0; i < array.length; i += 1) {
|
|
243
|
-
const result = f(array[i], i, array);
|
|
244
|
-
acc = result === void 0 ? false : result;
|
|
245
|
-
if (acc) {
|
|
246
|
-
return acc;
|
|
126
|
+
// src/core/heuristics/xml-defaults.ts
|
|
127
|
+
import { parse, unwrapJsonSchema } from "@ai-sdk-tool/rxml";
|
|
128
|
+
var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
129
|
+
var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
130
|
+
var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
|
|
131
|
+
var WHITESPACE_REGEX = /\s/;
|
|
132
|
+
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
133
|
+
var NAME_START_CHAR_RE = /[A-Za-z_:]/;
|
|
134
|
+
var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
|
|
135
|
+
var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
|
|
136
|
+
var normalizeCloseTagsHeuristic = {
|
|
137
|
+
id: "normalize-close-tags",
|
|
138
|
+
phase: "pre-parse",
|
|
139
|
+
applies: () => true,
|
|
140
|
+
run: (ctx) => {
|
|
141
|
+
const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
|
|
142
|
+
if (normalized !== ctx.rawSegment) {
|
|
143
|
+
return { rawSegment: normalized };
|
|
247
144
|
}
|
|
145
|
+
return {};
|
|
248
146
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const m = tokenSpec.re.exec(remainingContents);
|
|
259
|
-
if (m) {
|
|
260
|
-
const raw = m[0];
|
|
261
|
-
remainingContents = remainingContents.slice(raw.length);
|
|
262
|
-
return {
|
|
263
|
-
raw,
|
|
264
|
-
matched: tokenSpec.f(m)
|
|
265
|
-
// Process the match using the spec's function
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
return;
|
|
269
|
-
});
|
|
270
|
-
return result === false ? void 0 : result;
|
|
147
|
+
};
|
|
148
|
+
var escapeInvalidLtHeuristic = {
|
|
149
|
+
id: "escape-invalid-lt",
|
|
150
|
+
phase: "pre-parse",
|
|
151
|
+
applies: () => true,
|
|
152
|
+
run: (ctx) => {
|
|
153
|
+
const escaped = escapeInvalidLt(ctx.rawSegment);
|
|
154
|
+
if (escaped !== ctx.rawSegment) {
|
|
155
|
+
return { rawSegment: escaped };
|
|
271
156
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
line += matched.raw.replace(/[^\n]/g, "").length;
|
|
287
|
-
tokens.push(tokenWithLine);
|
|
157
|
+
return {};
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
var balanceTagsHeuristic = {
|
|
161
|
+
id: "balance-tags",
|
|
162
|
+
phase: "fallback-reparse",
|
|
163
|
+
applies: (ctx) => {
|
|
164
|
+
var _a;
|
|
165
|
+
const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
|
|
166
|
+
const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
|
|
167
|
+
const balanced = balanceTags(original);
|
|
168
|
+
const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
|
|
169
|
+
if (!hasMalformedClose && balanced.length > normalized.length) {
|
|
170
|
+
return false;
|
|
288
171
|
}
|
|
289
|
-
return
|
|
290
|
-
}
|
|
172
|
+
return balanced !== normalized;
|
|
173
|
+
},
|
|
174
|
+
run: (ctx) => {
|
|
175
|
+
var _a;
|
|
176
|
+
const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
|
|
177
|
+
const balanced = balanceTags(original);
|
|
178
|
+
const escaped = escapeInvalidLt(balanced);
|
|
179
|
+
return { rawSegment: escaped, reparse: true };
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
var dedupeShellStringTagsHeuristic = {
|
|
183
|
+
id: "dedupe-shell-string-tags",
|
|
184
|
+
phase: "fallback-reparse",
|
|
185
|
+
applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
|
|
186
|
+
run: (ctx) => {
|
|
187
|
+
const names = getStringPropertyNames(ctx.schema);
|
|
188
|
+
let deduped = ctx.rawSegment;
|
|
189
|
+
for (const key of names) {
|
|
190
|
+
deduped = dedupeSingleTag(deduped, key);
|
|
191
|
+
}
|
|
192
|
+
if (deduped !== ctx.rawSegment) {
|
|
193
|
+
return { rawSegment: deduped, reparse: true };
|
|
194
|
+
}
|
|
195
|
+
return {};
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
var repairAgainstSchemaHeuristic = {
|
|
199
|
+
id: "repair-against-schema",
|
|
200
|
+
phase: "post-parse",
|
|
201
|
+
applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
|
|
202
|
+
run: (ctx) => {
|
|
203
|
+
const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
|
|
204
|
+
if (repaired !== ctx.parsed) {
|
|
205
|
+
return { parsed: repaired };
|
|
206
|
+
}
|
|
207
|
+
return {};
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
var defaultPipelineConfig = {
|
|
211
|
+
preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
|
|
212
|
+
fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
|
|
213
|
+
postParse: [repairAgainstSchemaHeuristic]
|
|
214
|
+
};
|
|
215
|
+
var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
|
|
216
|
+
function isIndexTagAt(xml, pos) {
|
|
217
|
+
const remaining = xml.slice(pos);
|
|
218
|
+
return INDEX_TAG_RE.test(remaining);
|
|
291
219
|
}
|
|
292
|
-
function
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
220
|
+
function escapeInvalidLt(xml) {
|
|
221
|
+
const len = xml.length;
|
|
222
|
+
let out = "";
|
|
223
|
+
for (let i = 0; i < len; i += 1) {
|
|
224
|
+
const ch = xml[i];
|
|
225
|
+
if (ch === "<") {
|
|
226
|
+
const next = i + 1 < len ? xml[i + 1] : "";
|
|
227
|
+
const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
|
|
228
|
+
const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
|
|
229
|
+
if (!(isValidStart || isIndexTag)) {
|
|
230
|
+
out += "<";
|
|
231
|
+
continue;
|
|
301
232
|
}
|
|
302
|
-
return mm;
|
|
303
233
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
return
|
|
307
|
-
type: "string",
|
|
308
|
-
match,
|
|
309
|
-
// The transformed, double-quoted string representation
|
|
310
|
-
// Use JSON.parse on the transformed string to handle escape sequences correctly
|
|
311
|
-
value: JSON.parse(match)
|
|
312
|
-
};
|
|
234
|
+
out += ch;
|
|
235
|
+
}
|
|
236
|
+
return out;
|
|
313
237
|
}
|
|
314
|
-
function
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
238
|
+
function balanceTags(xml) {
|
|
239
|
+
const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
|
|
240
|
+
let i = 0;
|
|
241
|
+
const len = src.length;
|
|
242
|
+
const out = [];
|
|
243
|
+
const stack = [];
|
|
244
|
+
while (i < len) {
|
|
245
|
+
const lt = src.indexOf("<", i);
|
|
246
|
+
if (lt === -1) {
|
|
247
|
+
out.push(src.slice(i));
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
out.push(src.slice(i, lt));
|
|
251
|
+
if (lt + 1 >= len) {
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
const next = src[lt + 1];
|
|
255
|
+
if (next === "!" || next === "?") {
|
|
256
|
+
i = handleSpecialTagSegment(src, lt, out);
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (next === "/") {
|
|
260
|
+
i = handleClosingTagSegment(src, lt, out, stack);
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
i = handleOpeningTagSegment(src, lt, out, stack);
|
|
264
|
+
}
|
|
265
|
+
for (let k = stack.length - 1; k >= 0; k -= 1) {
|
|
266
|
+
out.push(`</${stack[k]}>`);
|
|
267
|
+
}
|
|
268
|
+
return out.join("");
|
|
322
269
|
}
|
|
323
|
-
function
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
// Treat identifiers as strings
|
|
330
|
-
value,
|
|
331
|
-
// The original identifier name
|
|
332
|
-
match
|
|
333
|
-
// The double-quoted string representation
|
|
334
|
-
};
|
|
270
|
+
function skipWs(s, p, len) {
|
|
271
|
+
let idx = p;
|
|
272
|
+
while (idx < len && WHITESPACE_REGEX.test(s[idx])) {
|
|
273
|
+
idx += 1;
|
|
274
|
+
}
|
|
275
|
+
return idx;
|
|
335
276
|
}
|
|
336
|
-
function
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
277
|
+
function parseTagNameAt(s, p, len) {
|
|
278
|
+
let idx = p;
|
|
279
|
+
const start = idx;
|
|
280
|
+
while (idx < len && NAME_CHAR_RE.test(s[idx])) {
|
|
281
|
+
idx += 1;
|
|
282
|
+
}
|
|
283
|
+
return { name: s.slice(start, idx), pos: idx };
|
|
284
|
+
}
|
|
285
|
+
function handleSpecialTagSegment(src, lt, out) {
|
|
286
|
+
const gt = src.indexOf(">", lt + 1);
|
|
287
|
+
if (gt === -1) {
|
|
288
|
+
out.push(src.slice(lt));
|
|
289
|
+
return src.length;
|
|
290
|
+
}
|
|
291
|
+
out.push(src.slice(lt, gt + 1));
|
|
292
|
+
return gt + 1;
|
|
293
|
+
}
|
|
294
|
+
function handleClosingTagSegment(src, lt, out, stack) {
|
|
295
|
+
const len = src.length;
|
|
296
|
+
let p = skipWs(src, lt + 2, len);
|
|
297
|
+
const { name, pos } = parseTagNameAt(src, p, len);
|
|
298
|
+
p = pos;
|
|
299
|
+
const gt = src.indexOf(">", p);
|
|
300
|
+
const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
|
|
301
|
+
const idx = stack.lastIndexOf(name);
|
|
302
|
+
if (idx !== -1) {
|
|
303
|
+
for (let k = stack.length - 1; k > idx; k -= 1) {
|
|
304
|
+
out.push(`</${stack[k]}>`);
|
|
305
|
+
stack.pop();
|
|
306
|
+
}
|
|
307
|
+
out.push(closingText);
|
|
308
|
+
stack.pop();
|
|
309
|
+
}
|
|
310
|
+
return gt === -1 ? len : gt + 1;
|
|
349
311
|
}
|
|
350
|
-
function
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
312
|
+
function handleOpeningTagSegment(src, lt, out, stack) {
|
|
313
|
+
const len = src.length;
|
|
314
|
+
let p = skipWs(src, lt + 1, len);
|
|
315
|
+
const nameStart = p;
|
|
316
|
+
const parsed = parseTagNameAt(src, p, len);
|
|
317
|
+
p = parsed.pos;
|
|
318
|
+
const name = src.slice(nameStart, p);
|
|
319
|
+
const q = src.indexOf(">", p);
|
|
320
|
+
if (q === -1) {
|
|
321
|
+
out.push(src.slice(lt));
|
|
322
|
+
return len;
|
|
323
|
+
}
|
|
324
|
+
let r = q - 1;
|
|
325
|
+
while (r >= nameStart && WHITESPACE_REGEX.test(src[r])) {
|
|
326
|
+
r -= 1;
|
|
327
|
+
}
|
|
328
|
+
const selfClosing = src[r] === "/";
|
|
329
|
+
out.push(src.slice(lt, q + 1));
|
|
330
|
+
if (!selfClosing && name) {
|
|
331
|
+
stack.push(name);
|
|
332
|
+
}
|
|
333
|
+
return q + 1;
|
|
358
334
|
}
|
|
359
|
-
function
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
value = null;
|
|
364
|
-
break;
|
|
365
|
-
case "true":
|
|
366
|
-
value = true;
|
|
367
|
-
break;
|
|
368
|
-
case "false":
|
|
369
|
-
value = false;
|
|
370
|
-
break;
|
|
371
|
-
default:
|
|
372
|
-
throw new Error(`Unexpected keyword: ${m[0]}`);
|
|
335
|
+
function shouldDeduplicateStringTags(schema) {
|
|
336
|
+
const unwrapped = unwrapJsonSchema(schema);
|
|
337
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
338
|
+
return false;
|
|
373
339
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
340
|
+
const props = unwrapped.properties;
|
|
341
|
+
if (!props) {
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
const commandRaw = props.command;
|
|
345
|
+
if (!commandRaw) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
const command = unwrapJsonSchema(commandRaw);
|
|
349
|
+
return (command == null ? void 0 : command.type) === "array";
|
|
382
350
|
}
|
|
383
|
-
function
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
};
|
|
351
|
+
function getStringPropertyNames(schema) {
|
|
352
|
+
const unwrapped = unwrapJsonSchema(schema);
|
|
353
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
354
|
+
return [];
|
|
388
355
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
{ re: OBJECT_START_REGEX, f: f("{") },
|
|
393
|
-
// Object start
|
|
394
|
-
{ re: OBJECT_END_REGEX, f: f("}") },
|
|
395
|
-
// Object end
|
|
396
|
-
{ re: ARRAY_START_REGEX, f: f("[") },
|
|
397
|
-
// Array start
|
|
398
|
-
{ re: ARRAY_END_REGEX, f: f("]") },
|
|
399
|
-
// Array end
|
|
400
|
-
{ re: COMMA_REGEX, f: f(",") },
|
|
401
|
-
// Comma separator
|
|
402
|
-
{ re: COLON_REGEX, f: f(":") },
|
|
403
|
-
// Key-value separator
|
|
404
|
-
{ re: KEYWORD_REGEX, f: fKeyword },
|
|
405
|
-
// Keywords
|
|
406
|
-
// Number: optional sign, digits, optional decimal part, optional exponent
|
|
407
|
-
{ re: NUMBER_REGEX, f: fNumber },
|
|
408
|
-
// String: double-quoted, handles escapes
|
|
409
|
-
{ re: STRING_DOUBLE_REGEX, f: fStringDouble }
|
|
410
|
-
];
|
|
411
|
-
if (relaxed) {
|
|
412
|
-
tokenSpecs = tokenSpecs.concat([
|
|
413
|
-
// Single-quoted strings
|
|
414
|
-
{
|
|
415
|
-
re: STRING_SINGLE_REGEX,
|
|
416
|
-
f: fStringSingle
|
|
417
|
-
},
|
|
418
|
-
// Single-line comments (// ...)
|
|
419
|
-
{ re: COMMENT_SINGLE_REGEX, f: fComment },
|
|
420
|
-
// Multi-line comments (/* ... */)
|
|
421
|
-
{ re: COMMENT_MULTI_REGEX, f: fComment },
|
|
422
|
-
// Unquoted identifiers (treated as strings)
|
|
423
|
-
// Allows letters, numbers, _, -, +, ., *, ?, !, |, &, %, ^, /, #, \
|
|
424
|
-
{ re: IDENTIFIER_REGEX, f: fIdentifier }
|
|
425
|
-
// Note: The order matters here. Identifiers are checked after keywords/numbers.
|
|
426
|
-
]);
|
|
356
|
+
const props = unwrapped.properties;
|
|
357
|
+
if (!props) {
|
|
358
|
+
return [];
|
|
427
359
|
}
|
|
428
|
-
|
|
360
|
+
const names = [];
|
|
361
|
+
for (const key of Object.keys(props)) {
|
|
362
|
+
const prop = unwrapJsonSchema(
|
|
363
|
+
props[key]
|
|
364
|
+
);
|
|
365
|
+
const type = prop.type;
|
|
366
|
+
if (type === "string") {
|
|
367
|
+
names.push(key);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return names;
|
|
429
371
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
372
|
+
function escapeRegExp(s) {
|
|
373
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
374
|
+
}
|
|
375
|
+
function dedupeSingleTag(xml, key) {
|
|
376
|
+
var _a, _b;
|
|
377
|
+
const escaped = escapeRegExp(key);
|
|
378
|
+
const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
|
|
379
|
+
const matches = Array.from(xml.matchAll(re));
|
|
380
|
+
if (matches.length <= 1) {
|
|
381
|
+
return xml;
|
|
382
|
+
}
|
|
383
|
+
const last = matches.at(-1);
|
|
384
|
+
let result = "";
|
|
385
|
+
let cursor = 0;
|
|
386
|
+
for (const m of matches) {
|
|
387
|
+
const idx = (_a = m.index) != null ? _a : 0;
|
|
388
|
+
result += xml.slice(cursor, idx);
|
|
389
|
+
if (last && idx === ((_b = last.index) != null ? _b : -1)) {
|
|
390
|
+
result += m[0];
|
|
437
391
|
}
|
|
392
|
+
cursor = idx + m[0].length;
|
|
438
393
|
}
|
|
439
|
-
|
|
394
|
+
result += xml.slice(cursor);
|
|
395
|
+
return result;
|
|
440
396
|
}
|
|
441
|
-
function
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
397
|
+
function repairParsedAgainstSchema(input, schema) {
|
|
398
|
+
if (!input || typeof input !== "object") {
|
|
399
|
+
return input;
|
|
400
|
+
}
|
|
401
|
+
const unwrapped = unwrapJsonSchema(schema);
|
|
402
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
403
|
+
return input;
|
|
404
|
+
}
|
|
405
|
+
const properties = unwrapped.properties;
|
|
406
|
+
if (!properties) {
|
|
407
|
+
return input;
|
|
408
|
+
}
|
|
409
|
+
applySchemaProps(input, properties);
|
|
410
|
+
return input;
|
|
411
|
+
}
|
|
412
|
+
function applySchemaProps(obj, properties) {
|
|
413
|
+
for (const key of Object.keys(obj)) {
|
|
414
|
+
const propSchema = properties[key];
|
|
415
|
+
if (!propSchema) {
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
const prop = unwrapJsonSchema(propSchema);
|
|
419
|
+
const propType = prop.type;
|
|
420
|
+
if (propType === "array" && prop.items) {
|
|
421
|
+
const itemSchemaRaw = prop.items;
|
|
422
|
+
const itemSchema = unwrapJsonSchema(itemSchemaRaw);
|
|
423
|
+
obj[key] = coerceArrayItems(obj[key], itemSchema);
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
if (propType === "object") {
|
|
427
|
+
const val = obj[key];
|
|
428
|
+
if (val && typeof val === "object") {
|
|
429
|
+
obj[key] = repairParsedAgainstSchema(val, prop);
|
|
459
430
|
}
|
|
460
431
|
}
|
|
461
|
-
|
|
462
|
-
});
|
|
463
|
-
return res;
|
|
432
|
+
}
|
|
464
433
|
}
|
|
465
|
-
function
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
state.pos += 1;
|
|
469
|
-
if (!token) {
|
|
470
|
-
const lastLine = tokens.length !== 0 ? (_b = (_a = tokens.at(-1)) == null ? void 0 : _a.line) != null ? _b : 1 : 1;
|
|
471
|
-
return { type: "eof", match: "", value: void 0, line: lastLine };
|
|
434
|
+
function coerceArrayItems(val, itemSchema) {
|
|
435
|
+
if (!Array.isArray(val)) {
|
|
436
|
+
return val;
|
|
472
437
|
}
|
|
473
|
-
return
|
|
438
|
+
return val.map((v) => coerceArrayItem(v, itemSchema));
|
|
474
439
|
}
|
|
475
|
-
function
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
return
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
440
|
+
function coerceArrayItem(v, itemSchema) {
|
|
441
|
+
const itemType = itemSchema == null ? void 0 : itemSchema.type;
|
|
442
|
+
if (typeof v === "string" && itemType === "object") {
|
|
443
|
+
const parsed = tryParseStringToSchemaObject(v, itemSchema);
|
|
444
|
+
if (parsed !== null) {
|
|
445
|
+
return parsed;
|
|
446
|
+
}
|
|
447
|
+
const fallback = extractStepStatusFromString(
|
|
448
|
+
v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
|
|
449
|
+
);
|
|
450
|
+
if (fallback) {
|
|
451
|
+
return fallback;
|
|
452
|
+
}
|
|
453
|
+
return v;
|
|
454
|
+
}
|
|
455
|
+
if (v && typeof v === "object" && itemType === "object") {
|
|
456
|
+
return repairParsedAgainstSchema(v, itemSchema);
|
|
457
|
+
}
|
|
458
|
+
return v;
|
|
459
|
+
}
|
|
460
|
+
function tryParseStringToSchemaObject(xml, itemSchema) {
|
|
461
|
+
try {
|
|
462
|
+
const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
|
|
463
|
+
const fixed = parse(normalized, itemSchema, { noChildNodes: [] });
|
|
464
|
+
return typeof fixed === "string" ? null : fixed;
|
|
465
|
+
} catch (e) {
|
|
466
|
+
return null;
|
|
485
467
|
}
|
|
486
468
|
}
|
|
487
|
-
function
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
state.warnings.push({
|
|
493
|
-
message,
|
|
494
|
-
line: colon.line
|
|
495
|
-
});
|
|
496
|
-
state.pos -= 1;
|
|
497
|
-
} else {
|
|
498
|
-
const err = new SyntaxError(message);
|
|
499
|
-
err.line = colon.line;
|
|
500
|
-
throw err;
|
|
501
|
-
}
|
|
469
|
+
function extractStepStatusFromString(normXml) {
|
|
470
|
+
const stepMatch = normXml.match(STEP_TAG_RE);
|
|
471
|
+
const statusMatch = normXml.match(STATUS_TAG_RE);
|
|
472
|
+
if (stepMatch && statusMatch) {
|
|
473
|
+
return { step: stepMatch[1], status: statusMatch[1] };
|
|
502
474
|
}
|
|
475
|
+
return null;
|
|
503
476
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
if (punctuation.includes(token.type)) {
|
|
515
|
-
const message = `Unexpected token: ${strToken(
|
|
516
|
-
token
|
|
517
|
-
)}, expected '[', '{', number, string or atom`;
|
|
518
|
-
if (state.tolerant) {
|
|
519
|
-
state.warnings.push({
|
|
520
|
-
message,
|
|
521
|
-
line: token.line
|
|
522
|
-
});
|
|
523
|
-
token = popToken(tokens, state);
|
|
524
|
-
} else {
|
|
525
|
-
const err = new SyntaxError(message);
|
|
526
|
-
err.line = token.line;
|
|
527
|
-
throw err;
|
|
528
|
-
}
|
|
529
|
-
} else {
|
|
530
|
-
return token;
|
|
531
|
-
}
|
|
477
|
+
|
|
478
|
+
// src/core/utils/debug.ts
|
|
479
|
+
var LINE_SPLIT_REGEX = /\r?\n/;
|
|
480
|
+
function normalizeBooleanString(value) {
|
|
481
|
+
const normalized = value.trim().toLowerCase();
|
|
482
|
+
if (normalized === "1" || normalized === "true" || normalized === "yes") {
|
|
483
|
+
return true;
|
|
484
|
+
}
|
|
485
|
+
if (normalized === "0" || normalized === "false" || normalized === "no") {
|
|
486
|
+
return false;
|
|
532
487
|
}
|
|
488
|
+
return;
|
|
533
489
|
}
|
|
534
|
-
function
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
throw err;
|
|
490
|
+
function getDebugLevel() {
|
|
491
|
+
const envVal = typeof process !== "undefined" && process.env && process.env.DEBUG_PARSER_MW || "off";
|
|
492
|
+
const envLower = String(envVal).toLowerCase();
|
|
493
|
+
if (envLower === "stream" || envLower === "parse" || envLower === "off") {
|
|
494
|
+
return envLower;
|
|
495
|
+
}
|
|
496
|
+
const boolEnv = normalizeBooleanString(envLower);
|
|
497
|
+
if (boolEnv === true) {
|
|
498
|
+
return "stream";
|
|
544
499
|
}
|
|
500
|
+
if (envLower === "2") {
|
|
501
|
+
return "parse";
|
|
502
|
+
}
|
|
503
|
+
return "off";
|
|
545
504
|
}
|
|
546
|
-
function
|
|
547
|
-
|
|
548
|
-
state,
|
|
549
|
-
token,
|
|
550
|
-
`Unexpected token: ${strToken(token)}, expected ${expected}`
|
|
551
|
-
);
|
|
505
|
+
function color(code) {
|
|
506
|
+
return (text) => `\x1B[${code}m${text}\x1B[0m`;
|
|
552
507
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
508
|
+
var ANSI_GRAY = 90;
|
|
509
|
+
var ANSI_YELLOW = 33;
|
|
510
|
+
var ANSI_CYAN = 36;
|
|
511
|
+
var ANSI_BG_BLUE = 44;
|
|
512
|
+
var ANSI_BG_GREEN = 42;
|
|
513
|
+
var ANSI_INVERSE = 7;
|
|
514
|
+
var ANSI_UNDERLINE = 4;
|
|
515
|
+
var ANSI_BOLD = 1;
|
|
516
|
+
var cGray = color(ANSI_GRAY);
|
|
517
|
+
var cYellow = color(ANSI_YELLOW);
|
|
518
|
+
var cCyan = color(ANSI_CYAN);
|
|
519
|
+
var cBgBlue = color(ANSI_BG_BLUE);
|
|
520
|
+
var cBgGreen = color(ANSI_BG_GREEN);
|
|
521
|
+
var cInverse = color(ANSI_INVERSE);
|
|
522
|
+
var cUnderline = color(ANSI_UNDERLINE);
|
|
523
|
+
var cBold = color(ANSI_BOLD);
|
|
524
|
+
var MAX_SNIPPET_LENGTH = 800;
|
|
525
|
+
function safeStringify(value) {
|
|
526
|
+
try {
|
|
527
|
+
return `
|
|
528
|
+
${typeof value === "string" ? value : JSON.stringify(value, null, 2)}`;
|
|
529
|
+
} catch (e) {
|
|
530
|
+
return String(value);
|
|
557
531
|
}
|
|
558
532
|
}
|
|
559
|
-
function
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
533
|
+
function formatError(error) {
|
|
534
|
+
if (error instanceof Error) {
|
|
535
|
+
const stack = error.stack ? `
|
|
536
|
+
${error.stack}` : "";
|
|
537
|
+
return `
|
|
538
|
+
${error.name}: ${error.message}${stack}`;
|
|
563
539
|
}
|
|
540
|
+
return safeStringify(error);
|
|
564
541
|
}
|
|
565
|
-
function
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
if (token.type !== "string") {
|
|
569
|
-
raiseUnexpected(state, token, "string key");
|
|
570
|
-
if (state.tolerant) {
|
|
571
|
-
switch (token.type) {
|
|
572
|
-
case ":":
|
|
573
|
-
token = {
|
|
574
|
-
type: "string",
|
|
575
|
-
value: "null",
|
|
576
|
-
match: '"null"',
|
|
577
|
-
line: token.line
|
|
578
|
-
};
|
|
579
|
-
state.pos -= 1;
|
|
580
|
-
break;
|
|
581
|
-
case "number":
|
|
582
|
-
// Use number as string key
|
|
583
|
-
case "atom":
|
|
584
|
-
token = {
|
|
585
|
-
type: "string",
|
|
586
|
-
value: String(token.value),
|
|
587
|
-
match: `"${token.value}"`,
|
|
588
|
-
line: token.line
|
|
589
|
-
};
|
|
590
|
-
break;
|
|
591
|
-
case "[":
|
|
592
|
-
// Assume missing key before an array
|
|
593
|
-
case "{":
|
|
594
|
-
state.pos -= 1;
|
|
595
|
-
value = parseAny(tokens, state);
|
|
596
|
-
checkDuplicates(state, obj, {
|
|
597
|
-
type: "string",
|
|
598
|
-
value: "null",
|
|
599
|
-
match: '"null"',
|
|
600
|
-
line: token.line
|
|
601
|
-
});
|
|
602
|
-
appendPair(state, obj, "null", value);
|
|
603
|
-
return;
|
|
604
|
-
// Finished parsing this "pair"
|
|
605
|
-
case "eof":
|
|
606
|
-
return;
|
|
607
|
-
// Cannot recover
|
|
608
|
-
default:
|
|
609
|
-
return;
|
|
610
|
-
}
|
|
611
|
-
} else {
|
|
612
|
-
return;
|
|
613
|
-
}
|
|
542
|
+
function truncateSnippet(snippet) {
|
|
543
|
+
if (snippet.length <= MAX_SNIPPET_LENGTH) {
|
|
544
|
+
return snippet;
|
|
614
545
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
skipColon(tokens, state);
|
|
618
|
-
value = parseAny(tokens, state);
|
|
619
|
-
appendPair(state, obj, key, value);
|
|
546
|
+
return `${snippet.slice(0, MAX_SNIPPET_LENGTH)}
|
|
547
|
+
\u2026[truncated ${snippet.length - MAX_SNIPPET_LENGTH} chars]`;
|
|
620
548
|
}
|
|
621
|
-
function
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
549
|
+
function logParseFailure({
|
|
550
|
+
phase,
|
|
551
|
+
reason,
|
|
552
|
+
snippet,
|
|
553
|
+
error
|
|
554
|
+
}) {
|
|
555
|
+
if (getDebugLevel() !== "parse") {
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
const label = cBgBlue(`[${phase}]`);
|
|
559
|
+
console.log(cGray("[debug:mw:fail]"), label, cYellow(reason));
|
|
560
|
+
if (snippet) {
|
|
561
|
+
const formatted = truncateSnippet(snippet);
|
|
562
|
+
console.log(cGray("[debug:mw:fail:snippet]"), formatted);
|
|
563
|
+
}
|
|
564
|
+
if (error) {
|
|
565
|
+
console.log(cGray("[debug:mw:fail:error]"), cCyan(formatError(error)));
|
|
566
|
+
}
|
|
625
567
|
}
|
|
626
|
-
function
|
|
627
|
-
|
|
628
|
-
return parseMany(tokens, state, obj, {
|
|
629
|
-
skip: [":", "}"],
|
|
630
|
-
// Initially skip over colon or closing brace (for empty/tolerant cases)
|
|
631
|
-
elementParser: parsePair,
|
|
632
|
-
// Use parsePair to parse each key-value element
|
|
633
|
-
elementName: "string key",
|
|
634
|
-
// Expected element type for errors
|
|
635
|
-
endSymbol: "}"
|
|
636
|
-
// The closing token for an object
|
|
637
|
-
});
|
|
568
|
+
function logRawChunk(part) {
|
|
569
|
+
console.log(cGray("[debug:mw:raw]"), cYellow(safeStringify(part)));
|
|
638
570
|
}
|
|
639
|
-
function
|
|
640
|
-
|
|
641
|
-
return parseMany(tokens, state, arr, {
|
|
642
|
-
skip: ["]"],
|
|
643
|
-
// Initially skip over closing bracket (for empty/tolerant cases)
|
|
644
|
-
elementParser: parseElement,
|
|
645
|
-
// Use parseElement to parse each array item
|
|
646
|
-
elementName: "json value",
|
|
647
|
-
// Expected element type for errors
|
|
648
|
-
endSymbol: "]"
|
|
649
|
-
// The closing token for an array
|
|
650
|
-
});
|
|
571
|
+
function logParsedChunk(part) {
|
|
572
|
+
console.log(cGray("[debug:mw:out]"), cCyan(safeStringify(part)));
|
|
651
573
|
}
|
|
652
|
-
function
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
return
|
|
574
|
+
function getHighlightStyle() {
|
|
575
|
+
const envVal = typeof process !== "undefined" && process.env && process.env.DEBUG_PARSER_MW_STYLE || "bg";
|
|
576
|
+
const normalized = String(envVal).trim().toLowerCase();
|
|
577
|
+
if (normalized === "inverse" || normalized === "invert") {
|
|
578
|
+
return "inverse";
|
|
579
|
+
}
|
|
580
|
+
if (normalized === "underline" || normalized === "ul") {
|
|
581
|
+
return "underline";
|
|
582
|
+
}
|
|
583
|
+
if (normalized === "bold") {
|
|
584
|
+
return "bold";
|
|
660
585
|
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
function handleCommaToken(params) {
|
|
664
|
-
const { token, tokens, state, opts, result } = params;
|
|
665
|
-
const nextToken = tokens[state.pos];
|
|
666
|
-
if (state.tolerant && nextToken && nextToken.type === opts.endSymbol) {
|
|
667
|
-
raiseError(state, token, `Trailing comma before '${opts.endSymbol}'`);
|
|
668
|
-
popToken(tokens, state);
|
|
669
|
-
return result;
|
|
586
|
+
if (normalized === "bg" || normalized === "background") {
|
|
587
|
+
return "bg";
|
|
670
588
|
}
|
|
671
|
-
|
|
672
|
-
|
|
589
|
+
const asBool = normalizeBooleanString(normalized);
|
|
590
|
+
if (asBool === true) {
|
|
591
|
+
return "bg";
|
|
592
|
+
}
|
|
593
|
+
return "bg";
|
|
673
594
|
}
|
|
674
|
-
function
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
raiseUnexpected(state, token, `'${opts.endSymbol}' or ${opts.elementName}`);
|
|
678
|
-
return result;
|
|
595
|
+
function getHighlightFunction(style) {
|
|
596
|
+
if (style === "inverse") {
|
|
597
|
+
return cInverse;
|
|
679
598
|
}
|
|
680
|
-
if (
|
|
681
|
-
return
|
|
599
|
+
if (style === "underline") {
|
|
600
|
+
return cUnderline;
|
|
682
601
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
return;
|
|
686
|
-
}
|
|
687
|
-
function parseManyProcessToken(params) {
|
|
688
|
-
const { token, tokens, state, opts, result } = params;
|
|
689
|
-
if (token.type !== opts.endSymbol && token.type !== ",") {
|
|
690
|
-
const handledResult = handleInvalidToken(token, state, opts, result);
|
|
691
|
-
if (handledResult !== null) {
|
|
692
|
-
return handledResult;
|
|
693
|
-
}
|
|
602
|
+
if (style === "bold") {
|
|
603
|
+
return cBold;
|
|
694
604
|
}
|
|
695
|
-
if (
|
|
696
|
-
return
|
|
605
|
+
if (style === "bg") {
|
|
606
|
+
return cBgGreen;
|
|
697
607
|
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
opts,
|
|
704
|
-
result
|
|
705
|
-
});
|
|
706
|
-
if (handledResult !== null) {
|
|
707
|
-
return handledResult;
|
|
708
|
-
}
|
|
709
|
-
return;
|
|
608
|
+
return cYellow;
|
|
609
|
+
}
|
|
610
|
+
function renderHighlightedText(originalText, style, highlight) {
|
|
611
|
+
if (style === "bg" || style === "inverse" || style === "underline" || style === "bold") {
|
|
612
|
+
return originalText.split(LINE_SPLIT_REGEX).map((line) => line.length ? highlight(line) : line).join("\n");
|
|
710
613
|
}
|
|
711
|
-
|
|
712
|
-
return;
|
|
614
|
+
return highlight(originalText);
|
|
713
615
|
}
|
|
714
|
-
function
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
616
|
+
function logParsedSummary({
|
|
617
|
+
toolCalls,
|
|
618
|
+
originalText
|
|
619
|
+
}) {
|
|
620
|
+
if (originalText) {
|
|
621
|
+
const style = getHighlightStyle();
|
|
622
|
+
const highlight = getHighlightFunction(style);
|
|
623
|
+
const rendered = renderHighlightedText(originalText, style, highlight);
|
|
624
|
+
console.log(cGray("[debug:mw:origin]"), `
|
|
625
|
+
${rendered}`);
|
|
718
626
|
}
|
|
719
|
-
|
|
720
|
-
const
|
|
721
|
-
|
|
722
|
-
token,
|
|
723
|
-
tokens,
|
|
724
|
-
state,
|
|
725
|
-
opts,
|
|
726
|
-
result
|
|
727
|
-
});
|
|
728
|
-
if (processedResult !== void 0) {
|
|
729
|
-
return processedResult;
|
|
730
|
-
}
|
|
627
|
+
if (toolCalls.length > 0) {
|
|
628
|
+
const styledSummary = safeStringify(toolCalls).split(LINE_SPLIT_REGEX).map((line) => line.length ? cBgBlue(line) : line).join("\n");
|
|
629
|
+
console.log(cGray("[debug:mw:summary]"), styledSummary);
|
|
731
630
|
}
|
|
732
631
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
if (state.pos < tokens.length) {
|
|
739
|
-
raiseError(
|
|
740
|
-
state,
|
|
741
|
-
tokens[state.pos],
|
|
742
|
-
`Unexpected token: ${strToken(tokens[state.pos])}, expected end-of-input`
|
|
743
|
-
);
|
|
744
|
-
}
|
|
632
|
+
|
|
633
|
+
// src/core/utils/get-potential-start-index.ts
|
|
634
|
+
function getPotentialStartIndex(text, searchedText) {
|
|
635
|
+
if (searchedText.length === 0) {
|
|
636
|
+
return null;
|
|
745
637
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
638
|
+
const directIndex = text.indexOf(searchedText);
|
|
639
|
+
if (directIndex !== -1) {
|
|
640
|
+
return directIndex;
|
|
641
|
+
}
|
|
642
|
+
for (let i = text.length - 1; i >= 0; i -= 1) {
|
|
643
|
+
const suffix = text.substring(i);
|
|
644
|
+
if (searchedText.startsWith(suffix)) {
|
|
645
|
+
return i;
|
|
646
|
+
}
|
|
753
647
|
}
|
|
648
|
+
return null;
|
|
754
649
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
650
|
+
|
|
651
|
+
// src/core/utils/id.ts
|
|
652
|
+
function generateId() {
|
|
653
|
+
return Math.random().toString(36).substring(2, 15);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// src/core/utils/regex.ts
|
|
657
|
+
function escapeRegExp2(literal) {
|
|
658
|
+
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// src/core/utils/robust-json.ts
|
|
662
|
+
var WHITESPACE_TEST_REGEX = /\s/;
|
|
663
|
+
var WHITESPACE_REGEX2 = /^\s+/;
|
|
664
|
+
var OBJECT_START_REGEX = /^\{/;
|
|
665
|
+
var OBJECT_END_REGEX = /^\}/;
|
|
666
|
+
var ARRAY_START_REGEX = /^\[/;
|
|
667
|
+
var ARRAY_END_REGEX = /^\]/;
|
|
668
|
+
var COMMA_REGEX = /^,/;
|
|
669
|
+
var COLON_REGEX = /^:/;
|
|
670
|
+
var KEYWORD_REGEX = /^(?:true|false|null)/;
|
|
671
|
+
var NUMBER_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/;
|
|
672
|
+
var STRING_DOUBLE_REGEX = /^"(?:[^"\\]|\\["bnrtf\\/]|\\u[0-9a-fA-F]{4})*"/;
|
|
673
|
+
var STRING_SINGLE_REGEX = /^'((?:[^'\\]|\\['bnrtf\\/]|\\u[0-9a-fA-F]{4})*)'/;
|
|
674
|
+
var COMMENT_SINGLE_REGEX = /^\/\/.*?(?:\r\n|\r|\n)/;
|
|
675
|
+
var COMMENT_MULTI_REGEX = /^\/\*[\s\S]*?\*\//;
|
|
676
|
+
var IDENTIFIER_REGEX = /^[$a-zA-Z0-9_\-+.*?!|&%^/#\\]+/;
|
|
677
|
+
function some(array, f) {
|
|
678
|
+
let acc = false;
|
|
679
|
+
for (let i = 0; i < array.length; i += 1) {
|
|
680
|
+
const result = f(array[i], i, array);
|
|
681
|
+
acc = result === void 0 ? false : result;
|
|
682
|
+
if (acc) {
|
|
683
|
+
return acc;
|
|
761
684
|
}
|
|
762
|
-
raiseUnexpected(state, token, "json value");
|
|
763
|
-
return;
|
|
764
685
|
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
686
|
+
return acc;
|
|
687
|
+
}
|
|
688
|
+
function makeLexer(tokenSpecs) {
|
|
689
|
+
return (contents) => {
|
|
690
|
+
const tokens = [];
|
|
691
|
+
let line = 1;
|
|
692
|
+
let remainingContents = contents;
|
|
693
|
+
function findToken() {
|
|
694
|
+
const result = some(tokenSpecs, (tokenSpec) => {
|
|
695
|
+
const m = tokenSpec.re.exec(remainingContents);
|
|
696
|
+
if (m) {
|
|
697
|
+
const raw = m[0];
|
|
698
|
+
remainingContents = remainingContents.slice(raw.length);
|
|
699
|
+
return {
|
|
700
|
+
raw,
|
|
701
|
+
matched: tokenSpec.f(m)
|
|
702
|
+
// Process the match using the spec's function
|
|
703
|
+
};
|
|
704
|
+
}
|
|
784
705
|
return;
|
|
706
|
+
});
|
|
707
|
+
return result === false ? void 0 : result;
|
|
708
|
+
}
|
|
709
|
+
while (remainingContents !== "") {
|
|
710
|
+
const matched = findToken();
|
|
711
|
+
if (!matched) {
|
|
712
|
+
const err = new SyntaxError(
|
|
713
|
+
`Unexpected character: ${remainingContents[0]}; input: ${remainingContents.substr(
|
|
714
|
+
0,
|
|
715
|
+
100
|
|
716
|
+
)}`
|
|
717
|
+
);
|
|
718
|
+
err.line = line;
|
|
719
|
+
throw err;
|
|
785
720
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
721
|
+
const tokenWithLine = matched.matched;
|
|
722
|
+
tokenWithLine.line = line;
|
|
723
|
+
line += matched.raw.replace(/[^\n]/g, "").length;
|
|
724
|
+
tokens.push(tokenWithLine);
|
|
725
|
+
}
|
|
726
|
+
return tokens;
|
|
727
|
+
};
|
|
792
728
|
}
|
|
793
|
-
function
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
}
|
|
805
|
-
if (options.relaxed === void 0) {
|
|
806
|
-
if (options.warnings === true || options.tolerant === true) {
|
|
807
|
-
options.relaxed = true;
|
|
808
|
-
} else if (options.warnings === false && options.tolerant === false) {
|
|
809
|
-
options.relaxed = false;
|
|
810
|
-
} else {
|
|
811
|
-
options.relaxed = true;
|
|
729
|
+
function fStringSingle(m) {
|
|
730
|
+
const content = m[1].replace(
|
|
731
|
+
/([^'\\]|\\['bnrtf\\]|\\u[0-9a-fA-F]{4})/g,
|
|
732
|
+
(mm) => {
|
|
733
|
+
if (mm === '"') {
|
|
734
|
+
return '\\"';
|
|
735
|
+
}
|
|
736
|
+
if (mm === "\\'") {
|
|
737
|
+
return "'";
|
|
738
|
+
}
|
|
739
|
+
return mm;
|
|
812
740
|
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
741
|
+
);
|
|
742
|
+
const match = `"${content}"`;
|
|
743
|
+
return {
|
|
744
|
+
type: "string",
|
|
745
|
+
match,
|
|
746
|
+
// The transformed, double-quoted string representation
|
|
747
|
+
// Use JSON.parse on the transformed string to handle escape sequences correctly
|
|
748
|
+
value: JSON.parse(match)
|
|
749
|
+
};
|
|
817
750
|
}
|
|
818
|
-
function
|
|
819
|
-
var _a, _b;
|
|
751
|
+
function fStringDouble(m) {
|
|
820
752
|
return {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
753
|
+
type: "string",
|
|
754
|
+
match: m[0],
|
|
755
|
+
// The raw matched string (including quotes)
|
|
756
|
+
value: JSON.parse(m[0])
|
|
757
|
+
// Use JSON.parse to handle escapes and get the value
|
|
826
758
|
};
|
|
827
759
|
}
|
|
828
|
-
function
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
760
|
+
function fIdentifier(m) {
|
|
761
|
+
const value = m[0];
|
|
762
|
+
const match = '"' + value.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + // Escape backslashes and quotes
|
|
763
|
+
'"';
|
|
764
|
+
return {
|
|
765
|
+
type: "string",
|
|
766
|
+
// Treat identifiers as strings
|
|
767
|
+
value,
|
|
768
|
+
// The original identifier name
|
|
769
|
+
match
|
|
770
|
+
// The double-quoted string representation
|
|
771
|
+
};
|
|
837
772
|
}
|
|
838
|
-
function
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
return JSON.parse(
|
|
843
|
-
newtext,
|
|
844
|
-
options.reviver
|
|
773
|
+
function fComment(m) {
|
|
774
|
+
const match = m[0].replace(
|
|
775
|
+
/./g,
|
|
776
|
+
(c) => WHITESPACE_TEST_REGEX.test(c) ? c : " "
|
|
845
777
|
);
|
|
778
|
+
return {
|
|
779
|
+
type: " ",
|
|
780
|
+
// Represent comments as whitespace tokens
|
|
781
|
+
match,
|
|
782
|
+
// String containing original newlines and spaces for other chars
|
|
783
|
+
value: void 0
|
|
784
|
+
// Comments don't have a semantic value
|
|
785
|
+
};
|
|
846
786
|
}
|
|
847
|
-
function
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
}
|
|
855
|
-
if (options.warnings || options.tolerant || !options.duplicate) {
|
|
856
|
-
return parseWithCustomParser(text, options);
|
|
857
|
-
}
|
|
858
|
-
return parseWithTransform(text, options);
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
// src/core/protocols/json-mix-protocol.ts
|
|
862
|
-
function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
|
|
863
|
-
var _a, _b;
|
|
864
|
-
try {
|
|
865
|
-
const parsedToolCall = parse(toolCallJson);
|
|
866
|
-
processedElements.push({
|
|
867
|
-
type: "tool-call",
|
|
868
|
-
toolCallId: generateId(),
|
|
869
|
-
toolName: parsedToolCall.name,
|
|
870
|
-
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
871
|
-
});
|
|
872
|
-
} catch (error) {
|
|
873
|
-
logParseFailure({
|
|
874
|
-
phase: "generated-text",
|
|
875
|
-
reason: "Failed to parse tool call JSON segment",
|
|
876
|
-
snippet: fullMatch,
|
|
877
|
-
error
|
|
878
|
-
});
|
|
879
|
-
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
880
|
-
options,
|
|
881
|
-
"Could not process JSON tool call, keeping original text.",
|
|
882
|
-
{ toolCall: fullMatch, error }
|
|
883
|
-
);
|
|
884
|
-
processedElements.push({ type: "text", text: fullMatch });
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
function addTextSegment(text, processedElements) {
|
|
888
|
-
if (text.trim()) {
|
|
889
|
-
processedElements.push({ type: "text", text });
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
function processMatchedToolCall(context) {
|
|
893
|
-
const { match, text, currentIndex, processedElements, options } = context;
|
|
894
|
-
const startIndex = match.index;
|
|
895
|
-
const toolCallJson = match[1];
|
|
896
|
-
if (startIndex > currentIndex) {
|
|
897
|
-
const textSegment = text.substring(currentIndex, startIndex);
|
|
898
|
-
addTextSegment(textSegment, processedElements);
|
|
899
|
-
}
|
|
900
|
-
if (toolCallJson) {
|
|
901
|
-
processToolCallJson(toolCallJson, match[0], processedElements, options);
|
|
902
|
-
}
|
|
903
|
-
return startIndex + match[0].length;
|
|
904
|
-
}
|
|
905
|
-
function flushBuffer(state, controller, toolCallStart) {
|
|
906
|
-
if (state.buffer.length === 0) {
|
|
907
|
-
return;
|
|
908
|
-
}
|
|
909
|
-
if (!state.currentTextId) {
|
|
910
|
-
state.currentTextId = generateId();
|
|
911
|
-
controller.enqueue({
|
|
912
|
-
type: "text-start",
|
|
913
|
-
id: state.currentTextId
|
|
914
|
-
});
|
|
915
|
-
state.hasEmittedTextStart = true;
|
|
916
|
-
}
|
|
917
|
-
const deltaContent = state.isInsideToolCall ? `${toolCallStart}${state.buffer}` : state.buffer;
|
|
918
|
-
controller.enqueue({
|
|
919
|
-
type: "text-delta",
|
|
920
|
-
id: state.currentTextId,
|
|
921
|
-
textDelta: deltaContent,
|
|
922
|
-
delta: deltaContent
|
|
923
|
-
});
|
|
924
|
-
state.buffer = "";
|
|
787
|
+
function fNumber(m) {
|
|
788
|
+
return {
|
|
789
|
+
type: "number",
|
|
790
|
+
match: m[0],
|
|
791
|
+
// The raw matched number string
|
|
792
|
+
value: Number.parseFloat(m[0])
|
|
793
|
+
// Convert string to number
|
|
794
|
+
};
|
|
925
795
|
}
|
|
926
|
-
function
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
796
|
+
function fKeyword(m) {
|
|
797
|
+
let value;
|
|
798
|
+
switch (m[0]) {
|
|
799
|
+
case "null":
|
|
800
|
+
value = null;
|
|
801
|
+
break;
|
|
802
|
+
case "true":
|
|
803
|
+
value = true;
|
|
804
|
+
break;
|
|
805
|
+
case "false":
|
|
806
|
+
value = false;
|
|
807
|
+
break;
|
|
808
|
+
default:
|
|
809
|
+
throw new Error(`Unexpected keyword: ${m[0]}`);
|
|
934
810
|
}
|
|
811
|
+
return {
|
|
812
|
+
type: "atom",
|
|
813
|
+
// Use 'atom' type for these literals
|
|
814
|
+
match: m[0],
|
|
815
|
+
// The raw matched keyword
|
|
816
|
+
value
|
|
817
|
+
// The corresponding JavaScript value
|
|
818
|
+
};
|
|
935
819
|
}
|
|
936
|
-
function
|
|
937
|
-
|
|
938
|
-
return
|
|
820
|
+
function makeTokenSpecs(relaxed) {
|
|
821
|
+
function f(type) {
|
|
822
|
+
return (m) => {
|
|
823
|
+
return { type, match: m[0], value: void 0 };
|
|
824
|
+
};
|
|
939
825
|
}
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
826
|
+
let tokenSpecs = [
|
|
827
|
+
{ re: WHITESPACE_REGEX2, f: f(" ") },
|
|
828
|
+
// Whitespace
|
|
829
|
+
{ re: OBJECT_START_REGEX, f: f("{") },
|
|
830
|
+
// Object start
|
|
831
|
+
{ re: OBJECT_END_REGEX, f: f("}") },
|
|
832
|
+
// Object end
|
|
833
|
+
{ re: ARRAY_START_REGEX, f: f("[") },
|
|
834
|
+
// Array start
|
|
835
|
+
{ re: ARRAY_END_REGEX, f: f("]") },
|
|
836
|
+
// Array end
|
|
837
|
+
{ re: COMMA_REGEX, f: f(",") },
|
|
838
|
+
// Comma separator
|
|
839
|
+
{ re: COLON_REGEX, f: f(":") },
|
|
840
|
+
// Key-value separator
|
|
841
|
+
{ re: KEYWORD_REGEX, f: fKeyword },
|
|
842
|
+
// Keywords
|
|
843
|
+
// Number: optional sign, digits, optional decimal part, optional exponent
|
|
844
|
+
{ re: NUMBER_REGEX, f: fNumber },
|
|
845
|
+
// String: double-quoted, handles escapes
|
|
846
|
+
{ re: STRING_DOUBLE_REGEX, f: fStringDouble }
|
|
847
|
+
];
|
|
848
|
+
if (relaxed) {
|
|
849
|
+
tokenSpecs = tokenSpecs.concat([
|
|
850
|
+
// Single-quoted strings
|
|
851
|
+
{
|
|
852
|
+
re: STRING_SINGLE_REGEX,
|
|
853
|
+
f: fStringSingle
|
|
854
|
+
},
|
|
855
|
+
// Single-line comments (// ...)
|
|
856
|
+
{ re: COMMENT_SINGLE_REGEX, f: fComment },
|
|
857
|
+
// Multi-line comments (/* ... */)
|
|
858
|
+
{ re: COMMENT_MULTI_REGEX, f: fComment },
|
|
859
|
+
// Unquoted identifiers (treated as strings)
|
|
860
|
+
// Allows letters, numbers, _, -, +, ., *, ?, !, |, &, %, ^, /, #, \
|
|
861
|
+
{ re: IDENTIFIER_REGEX, f: fIdentifier }
|
|
862
|
+
// Note: The order matters here. Identifiers are checked after keywords/numbers.
|
|
863
|
+
]);
|
|
966
864
|
}
|
|
967
|
-
|
|
968
|
-
emitIncompleteToolCall(state, controller, toolCallStart);
|
|
969
|
-
controller.enqueue(chunk);
|
|
865
|
+
return tokenSpecs;
|
|
970
866
|
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
if (
|
|
977
|
-
|
|
978
|
-
controller.enqueue({
|
|
979
|
-
type: "text-start",
|
|
980
|
-
id: state.currentTextId
|
|
981
|
-
});
|
|
982
|
-
state.hasEmittedTextStart = true;
|
|
867
|
+
var lexer = makeLexer(makeTokenSpecs(true));
|
|
868
|
+
var strictLexer = makeLexer(makeTokenSpecs(false));
|
|
869
|
+
function previousNWSToken(tokens, index) {
|
|
870
|
+
let currentIndex = index;
|
|
871
|
+
for (; currentIndex >= 0; currentIndex -= 1) {
|
|
872
|
+
if (tokens[currentIndex].type !== " ") {
|
|
873
|
+
return currentIndex;
|
|
983
874
|
}
|
|
984
|
-
controller.enqueue({
|
|
985
|
-
type: "text-delta",
|
|
986
|
-
id: state.currentTextId,
|
|
987
|
-
textDelta: text,
|
|
988
|
-
delta: text
|
|
989
|
-
});
|
|
990
875
|
}
|
|
876
|
+
return;
|
|
991
877
|
}
|
|
992
|
-
function
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
});
|
|
1011
|
-
const errorId = generateId();
|
|
1012
|
-
const errorContent = `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`;
|
|
1013
|
-
controller.enqueue({
|
|
1014
|
-
type: "text-start",
|
|
1015
|
-
id: errorId
|
|
1016
|
-
});
|
|
1017
|
-
controller.enqueue({
|
|
1018
|
-
type: "text-delta",
|
|
1019
|
-
id: errorId,
|
|
1020
|
-
textDelta: errorContent,
|
|
1021
|
-
delta: errorContent
|
|
1022
|
-
});
|
|
1023
|
-
controller.enqueue({
|
|
1024
|
-
type: "text-end",
|
|
1025
|
-
id: errorId
|
|
1026
|
-
});
|
|
1027
|
-
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
1028
|
-
options,
|
|
1029
|
-
"Could not process streaming JSON tool call; emitting original text.",
|
|
1030
|
-
{
|
|
1031
|
-
toolCall: errorContent
|
|
878
|
+
function stripTrailingComma(tokens) {
|
|
879
|
+
const res = [];
|
|
880
|
+
tokens.forEach((token, index) => {
|
|
881
|
+
if (index > 0 && (token.type === "]" || token.type === "}")) {
|
|
882
|
+
const prevNWSTokenIndex = previousNWSToken(res, res.length - 1);
|
|
883
|
+
if (prevNWSTokenIndex !== void 0 && res[prevNWSTokenIndex].type === ",") {
|
|
884
|
+
const preCommaIndex = previousNWSToken(res, prevNWSTokenIndex - 1);
|
|
885
|
+
if (preCommaIndex !== void 0 && res[preCommaIndex].type !== "[" && res[preCommaIndex].type !== "{") {
|
|
886
|
+
res[prevNWSTokenIndex] = {
|
|
887
|
+
type: " ",
|
|
888
|
+
match: " ",
|
|
889
|
+
// Represent as a single space
|
|
890
|
+
value: void 0,
|
|
891
|
+
// Whitespace has no value
|
|
892
|
+
line: res[prevNWSTokenIndex].line
|
|
893
|
+
// Preserve original line number
|
|
894
|
+
};
|
|
895
|
+
}
|
|
1032
896
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
897
|
+
}
|
|
898
|
+
res.push(token);
|
|
899
|
+
});
|
|
900
|
+
return res;
|
|
1035
901
|
}
|
|
1036
|
-
function
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
state.currentToolCallJson = "";
|
|
1041
|
-
state.isInsideToolCall = false;
|
|
1042
|
-
} else {
|
|
1043
|
-
state.currentToolCallJson = "";
|
|
1044
|
-
state.isInsideToolCall = true;
|
|
1045
|
-
}
|
|
902
|
+
function transform(text) {
|
|
903
|
+
let tokens = lexer(text);
|
|
904
|
+
tokens = stripTrailingComma(tokens);
|
|
905
|
+
return tokens.reduce((str, token) => str + token.match, "");
|
|
1046
906
|
}
|
|
1047
|
-
function
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
const tag = state.isInsideToolCall ? toolCallEnd : toolCallStart;
|
|
1055
|
-
if (startIndex + tag.length > state.buffer.length) {
|
|
1056
|
-
break;
|
|
1057
|
-
}
|
|
1058
|
-
publishText(state.buffer.slice(0, startIndex), state, controller);
|
|
1059
|
-
state.buffer = state.buffer.slice(startIndex + tag.length);
|
|
1060
|
-
processTagMatch(context);
|
|
1061
|
-
startIndex = getPotentialStartIndex(
|
|
1062
|
-
state.buffer,
|
|
1063
|
-
state.isInsideToolCall ? toolCallEnd : toolCallStart
|
|
1064
|
-
);
|
|
907
|
+
function popToken(tokens, state) {
|
|
908
|
+
var _a, _b;
|
|
909
|
+
const token = tokens[state.pos];
|
|
910
|
+
state.pos += 1;
|
|
911
|
+
if (!token) {
|
|
912
|
+
const lastLine = tokens.length !== 0 ? (_b = (_a = tokens.at(-1)) == null ? void 0 : _a.line) != null ? _b : 1 : 1;
|
|
913
|
+
return { type: "eof", match: "", value: void 0, line: lastLine };
|
|
1065
914
|
}
|
|
915
|
+
return token;
|
|
1066
916
|
}
|
|
1067
|
-
function
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
state.buffer = "";
|
|
917
|
+
function strToken(token) {
|
|
918
|
+
switch (token.type) {
|
|
919
|
+
case "atom":
|
|
920
|
+
case "string":
|
|
921
|
+
case "number":
|
|
922
|
+
return `${token.type} ${token.match}`;
|
|
923
|
+
case "eof":
|
|
924
|
+
return "end-of-file";
|
|
925
|
+
default:
|
|
926
|
+
return `'${token.type}'`;
|
|
1078
927
|
}
|
|
1079
928
|
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
name: tool.name,
|
|
1089
|
-
description: tool.type === "function" && typeof tool.description === "string" ? tool.description : void 0,
|
|
1090
|
-
parameters: tool.inputSchema
|
|
1091
|
-
}));
|
|
1092
|
-
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
1093
|
-
},
|
|
1094
|
-
formatToolCall(toolCall) {
|
|
1095
|
-
let args = {};
|
|
1096
|
-
try {
|
|
1097
|
-
args = JSON.parse(toolCall.input);
|
|
1098
|
-
} catch (e) {
|
|
1099
|
-
args = toolCall.input;
|
|
1100
|
-
}
|
|
1101
|
-
return `${toolCallStart}${JSON.stringify({
|
|
1102
|
-
name: toolCall.toolName,
|
|
1103
|
-
arguments: args
|
|
1104
|
-
})}${toolCallEnd}`;
|
|
1105
|
-
},
|
|
1106
|
-
formatToolResponse(toolResult) {
|
|
1107
|
-
return `${toolResponseStart}${JSON.stringify({
|
|
1108
|
-
toolName: toolResult.toolName,
|
|
1109
|
-
result: toolResult.result
|
|
1110
|
-
})}${toolResponseEnd}`;
|
|
1111
|
-
},
|
|
1112
|
-
parseGeneratedText({ text, options }) {
|
|
1113
|
-
const startEsc = escapeRegExp(toolCallStart);
|
|
1114
|
-
const endEsc = escapeRegExp(toolCallEnd);
|
|
1115
|
-
const toolCallRegex = new RegExp(
|
|
1116
|
-
`${startEsc}([\0-\uFFFF]*?)${endEsc}`,
|
|
1117
|
-
"gs"
|
|
1118
|
-
);
|
|
1119
|
-
const processedElements = [];
|
|
1120
|
-
let currentIndex = 0;
|
|
1121
|
-
let match = toolCallRegex.exec(text);
|
|
1122
|
-
while (match !== null) {
|
|
1123
|
-
currentIndex = processMatchedToolCall({
|
|
1124
|
-
match,
|
|
1125
|
-
text,
|
|
1126
|
-
currentIndex,
|
|
1127
|
-
processedElements,
|
|
1128
|
-
options
|
|
929
|
+
function skipColon(tokens, state) {
|
|
930
|
+
const colon = popToken(tokens, state);
|
|
931
|
+
if (colon.type !== ":") {
|
|
932
|
+
const message = `Unexpected token: ${strToken(colon)}, expected ':'`;
|
|
933
|
+
if (state.tolerant) {
|
|
934
|
+
state.warnings.push({
|
|
935
|
+
message,
|
|
936
|
+
line: colon.line
|
|
1129
937
|
});
|
|
1130
|
-
|
|
938
|
+
state.pos -= 1;
|
|
939
|
+
} else {
|
|
940
|
+
const err = new SyntaxError(message);
|
|
941
|
+
err.line = colon.line;
|
|
942
|
+
throw err;
|
|
1131
943
|
}
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
function skipPunctuation(tokens, state, valid) {
|
|
947
|
+
const punctuation = [",", ":", "]", "}"];
|
|
948
|
+
let token = popToken(tokens, state);
|
|
949
|
+
while (true) {
|
|
950
|
+
if (valid == null ? void 0 : valid.includes(token.type)) {
|
|
951
|
+
return token;
|
|
1135
952
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
}
|
|
1157
|
-
const textContent = (_b = (_a = chunk.textDelta) != null ? _a : chunk.delta) != null ? _b : "";
|
|
1158
|
-
state.buffer += textContent;
|
|
1159
|
-
processBufferTags({
|
|
1160
|
-
state,
|
|
1161
|
-
controller,
|
|
1162
|
-
toolCallStart,
|
|
1163
|
-
toolCallEnd,
|
|
1164
|
-
options
|
|
1165
|
-
});
|
|
1166
|
-
handlePartialTag(state, controller, toolCallStart);
|
|
1167
|
-
}
|
|
1168
|
-
});
|
|
1169
|
-
},
|
|
1170
|
-
extractToolCallSegments({ text }) {
|
|
1171
|
-
const startEsc = escapeRegExp(toolCallStart);
|
|
1172
|
-
const endEsc = escapeRegExp(toolCallEnd);
|
|
1173
|
-
const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
|
|
1174
|
-
const segments = [];
|
|
1175
|
-
let m = regex.exec(text);
|
|
1176
|
-
while (m != null) {
|
|
1177
|
-
segments.push(m[0]);
|
|
1178
|
-
m = regex.exec(text);
|
|
953
|
+
if (token.type === "eof") {
|
|
954
|
+
return token;
|
|
955
|
+
}
|
|
956
|
+
if (punctuation.includes(token.type)) {
|
|
957
|
+
const message = `Unexpected token: ${strToken(
|
|
958
|
+
token
|
|
959
|
+
)}, expected '[', '{', number, string or atom`;
|
|
960
|
+
if (state.tolerant) {
|
|
961
|
+
state.warnings.push({
|
|
962
|
+
message,
|
|
963
|
+
line: token.line
|
|
964
|
+
});
|
|
965
|
+
token = popToken(tokens, state);
|
|
966
|
+
} else {
|
|
967
|
+
const err = new SyntaxError(message);
|
|
968
|
+
err.line = token.line;
|
|
969
|
+
throw err;
|
|
970
|
+
}
|
|
971
|
+
} else {
|
|
972
|
+
return token;
|
|
1179
973
|
}
|
|
1180
|
-
return segments;
|
|
1181
|
-
}
|
|
1182
|
-
});
|
|
1183
|
-
|
|
1184
|
-
// src/core/protocols/morph-xml-protocol.ts
|
|
1185
|
-
var import_rxml2 = require("@ai-sdk-tool/rxml");
|
|
1186
|
-
|
|
1187
|
-
// src/core/heuristics/engine.ts
|
|
1188
|
-
function applyRawSegmentUpdate(current, result) {
|
|
1189
|
-
if (result.rawSegment !== void 0) {
|
|
1190
|
-
return { ...current, rawSegment: result.rawSegment };
|
|
1191
974
|
}
|
|
1192
|
-
return current;
|
|
1193
975
|
}
|
|
1194
|
-
function
|
|
1195
|
-
if (
|
|
1196
|
-
|
|
976
|
+
function raiseError(state, token, message) {
|
|
977
|
+
if (state.tolerant) {
|
|
978
|
+
state.warnings.push({
|
|
979
|
+
message,
|
|
980
|
+
line: token.line
|
|
981
|
+
});
|
|
982
|
+
} else {
|
|
983
|
+
const err = new SyntaxError(message);
|
|
984
|
+
err.line = token.line;
|
|
985
|
+
throw err;
|
|
1197
986
|
}
|
|
1198
|
-
return current;
|
|
1199
987
|
}
|
|
1200
|
-
function
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
...current,
|
|
1207
|
-
meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
|
|
1208
|
-
};
|
|
1209
|
-
}
|
|
1210
|
-
return current;
|
|
988
|
+
function raiseUnexpected(state, token, expected) {
|
|
989
|
+
raiseError(
|
|
990
|
+
state,
|
|
991
|
+
token,
|
|
992
|
+
`Unexpected token: ${strToken(token)}, expected ${expected}`
|
|
993
|
+
);
|
|
1211
994
|
}
|
|
1212
|
-
function
|
|
1213
|
-
|
|
1214
|
-
|
|
995
|
+
function checkDuplicates(state, obj, token) {
|
|
996
|
+
const key = String(token.value);
|
|
997
|
+
if (!state.duplicate && Object.hasOwn(obj, key)) {
|
|
998
|
+
raiseError(state, token, `Duplicate key: ${key}`);
|
|
1215
999
|
}
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
};
|
|
1222
|
-
} catch (error) {
|
|
1223
|
-
return {
|
|
1224
|
-
state: { ...current, errors: [...current.errors, error] },
|
|
1225
|
-
newCount: reparseCount + 1
|
|
1226
|
-
};
|
|
1000
|
+
}
|
|
1001
|
+
function appendPair(state, obj, key, value) {
|
|
1002
|
+
const finalValue = state.reviver ? state.reviver(key, value) : value;
|
|
1003
|
+
if (finalValue !== void 0) {
|
|
1004
|
+
obj[key] = finalValue;
|
|
1227
1005
|
}
|
|
1228
1006
|
}
|
|
1229
|
-
function
|
|
1230
|
-
|
|
1231
|
-
let
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1007
|
+
function parsePair(tokens, state, obj) {
|
|
1008
|
+
let token = skipPunctuation(tokens, state, [":", "string", "number", "atom"]);
|
|
1009
|
+
let value;
|
|
1010
|
+
if (token.type !== "string") {
|
|
1011
|
+
raiseUnexpected(state, token, "string key");
|
|
1012
|
+
if (state.tolerant) {
|
|
1013
|
+
switch (token.type) {
|
|
1014
|
+
case ":":
|
|
1015
|
+
token = {
|
|
1016
|
+
type: "string",
|
|
1017
|
+
value: "null",
|
|
1018
|
+
match: '"null"',
|
|
1019
|
+
line: token.line
|
|
1020
|
+
};
|
|
1021
|
+
state.pos -= 1;
|
|
1022
|
+
break;
|
|
1023
|
+
case "number":
|
|
1024
|
+
// Use number as string key
|
|
1025
|
+
case "atom":
|
|
1026
|
+
token = {
|
|
1027
|
+
type: "string",
|
|
1028
|
+
value: String(token.value),
|
|
1029
|
+
match: `"${token.value}"`,
|
|
1030
|
+
line: token.line
|
|
1031
|
+
};
|
|
1032
|
+
break;
|
|
1033
|
+
case "[":
|
|
1034
|
+
// Assume missing key before an array
|
|
1035
|
+
case "{":
|
|
1036
|
+
state.pos -= 1;
|
|
1037
|
+
value = parseAny(tokens, state);
|
|
1038
|
+
checkDuplicates(state, obj, {
|
|
1039
|
+
type: "string",
|
|
1040
|
+
value: "null",
|
|
1041
|
+
match: '"null"',
|
|
1042
|
+
line: token.line
|
|
1043
|
+
});
|
|
1044
|
+
appendPair(state, obj, "null", value);
|
|
1045
|
+
return;
|
|
1046
|
+
// Finished parsing this "pair"
|
|
1047
|
+
case "eof":
|
|
1048
|
+
return;
|
|
1049
|
+
// Cannot recover
|
|
1050
|
+
default:
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
} else {
|
|
1054
|
+
return;
|
|
1253
1055
|
}
|
|
1254
1056
|
}
|
|
1255
|
-
|
|
1057
|
+
checkDuplicates(state, obj, token);
|
|
1058
|
+
const key = String(token.value);
|
|
1059
|
+
skipColon(tokens, state);
|
|
1060
|
+
value = parseAny(tokens, state);
|
|
1061
|
+
appendPair(state, obj, key, value);
|
|
1256
1062
|
}
|
|
1257
|
-
function
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1063
|
+
function parseElement(tokens, state, arr) {
|
|
1064
|
+
const key = arr.length;
|
|
1065
|
+
const value = parseAny(tokens, state);
|
|
1066
|
+
arr[key] = state.reviver ? state.reviver(String(key), value) : value;
|
|
1067
|
+
}
|
|
1068
|
+
function parseObject(tokens, state) {
|
|
1069
|
+
const obj = {};
|
|
1070
|
+
return parseMany(tokens, state, obj, {
|
|
1071
|
+
skip: [":", "}"],
|
|
1072
|
+
// Initially skip over colon or closing brace (for empty/tolerant cases)
|
|
1073
|
+
elementParser: parsePair,
|
|
1074
|
+
// Use parsePair to parse each key-value element
|
|
1075
|
+
elementName: "string key",
|
|
1076
|
+
// Expected element type for errors
|
|
1077
|
+
endSymbol: "}"
|
|
1078
|
+
// The closing token for an object
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
function parseArray(tokens, state) {
|
|
1082
|
+
const arr = [];
|
|
1083
|
+
return parseMany(tokens, state, arr, {
|
|
1084
|
+
skip: ["]"],
|
|
1085
|
+
// Initially skip over closing bracket (for empty/tolerant cases)
|
|
1086
|
+
elementParser: parseElement,
|
|
1087
|
+
// Use parseElement to parse each array item
|
|
1088
|
+
elementName: "json value",
|
|
1089
|
+
// Expected element type for errors
|
|
1090
|
+
endSymbol: "]"
|
|
1091
|
+
// The closing token for an array
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
function handleInvalidToken(token, state, opts, result) {
|
|
1095
|
+
raiseUnexpected(state, token, `',' or '${opts.endSymbol}'`);
|
|
1096
|
+
if (state.tolerant) {
|
|
1097
|
+
if (token.type === "eof") {
|
|
1098
|
+
return result;
|
|
1268
1099
|
}
|
|
1100
|
+
state.pos -= 1;
|
|
1101
|
+
return null;
|
|
1269
1102
|
}
|
|
1270
|
-
|
|
1271
|
-
current = executePhase(current, config.fallbackReparse, options);
|
|
1272
|
-
}
|
|
1273
|
-
if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
|
|
1274
|
-
current = executePhase(current, config.postParse, options);
|
|
1275
|
-
}
|
|
1276
|
-
return current;
|
|
1103
|
+
return result;
|
|
1277
1104
|
}
|
|
1278
|
-
function
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1105
|
+
function handleCommaToken(params) {
|
|
1106
|
+
const { token, tokens, state, opts, result } = params;
|
|
1107
|
+
const nextToken = tokens[state.pos];
|
|
1108
|
+
if (state.tolerant && nextToken && nextToken.type === opts.endSymbol) {
|
|
1109
|
+
raiseError(state, token, `Trailing comma before '${opts.endSymbol}'`);
|
|
1110
|
+
popToken(tokens, state);
|
|
1111
|
+
return result;
|
|
1112
|
+
}
|
|
1113
|
+
opts.elementParser(tokens, state, result);
|
|
1114
|
+
return null;
|
|
1287
1115
|
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
const
|
|
1305
|
-
if (
|
|
1306
|
-
return
|
|
1116
|
+
function parseManyInitialElement(tokens, state, result, opts) {
|
|
1117
|
+
const token = skipPunctuation(tokens, state, opts.skip);
|
|
1118
|
+
if (token.type === "eof") {
|
|
1119
|
+
raiseUnexpected(state, token, `'${opts.endSymbol}' or ${opts.elementName}`);
|
|
1120
|
+
return result;
|
|
1121
|
+
}
|
|
1122
|
+
if (token.type === opts.endSymbol) {
|
|
1123
|
+
return result;
|
|
1124
|
+
}
|
|
1125
|
+
state.pos -= 1;
|
|
1126
|
+
opts.elementParser(tokens, state, result);
|
|
1127
|
+
return;
|
|
1128
|
+
}
|
|
1129
|
+
function parseManyProcessToken(params) {
|
|
1130
|
+
const { token, tokens, state, opts, result } = params;
|
|
1131
|
+
if (token.type !== opts.endSymbol && token.type !== ",") {
|
|
1132
|
+
const handledResult = handleInvalidToken(token, state, opts, result);
|
|
1133
|
+
if (handledResult !== null) {
|
|
1134
|
+
return handledResult;
|
|
1307
1135
|
}
|
|
1308
|
-
return {};
|
|
1309
1136
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1137
|
+
if (token.type === opts.endSymbol) {
|
|
1138
|
+
return result;
|
|
1139
|
+
}
|
|
1140
|
+
if (token.type === ",") {
|
|
1141
|
+
const handledResult = handleCommaToken({
|
|
1142
|
+
token,
|
|
1143
|
+
tokens,
|
|
1144
|
+
state,
|
|
1145
|
+
opts,
|
|
1146
|
+
result
|
|
1147
|
+
});
|
|
1148
|
+
if (handledResult !== null) {
|
|
1149
|
+
return handledResult;
|
|
1319
1150
|
}
|
|
1320
|
-
return
|
|
1151
|
+
return;
|
|
1321
1152
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
const
|
|
1332
|
-
|
|
1333
|
-
|
|
1153
|
+
opts.elementParser(tokens, state, result);
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
function parseMany(tokens, state, result, opts) {
|
|
1157
|
+
const initialResult = parseManyInitialElement(tokens, state, result, opts);
|
|
1158
|
+
if (initialResult !== void 0) {
|
|
1159
|
+
return initialResult;
|
|
1160
|
+
}
|
|
1161
|
+
while (true) {
|
|
1162
|
+
const token = popToken(tokens, state);
|
|
1163
|
+
const processedResult = parseManyProcessToken({
|
|
1164
|
+
token,
|
|
1165
|
+
tokens,
|
|
1166
|
+
state,
|
|
1167
|
+
opts,
|
|
1168
|
+
result
|
|
1169
|
+
});
|
|
1170
|
+
if (processedResult !== void 0) {
|
|
1171
|
+
return processedResult;
|
|
1334
1172
|
}
|
|
1335
|
-
return balanced !== normalized;
|
|
1336
|
-
},
|
|
1337
|
-
run: (ctx) => {
|
|
1338
|
-
var _a;
|
|
1339
|
-
const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
|
|
1340
|
-
const balanced = balanceTags(original);
|
|
1341
|
-
const escaped = escapeInvalidLt(balanced);
|
|
1342
|
-
return { rawSegment: escaped, reparse: true };
|
|
1343
1173
|
}
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
run: (ctx) => {
|
|
1350
|
-
const names = getStringPropertyNames(ctx.schema);
|
|
1351
|
-
let deduped = ctx.rawSegment;
|
|
1352
|
-
for (const key of names) {
|
|
1353
|
-
deduped = dedupeSingleTag(deduped, key);
|
|
1174
|
+
}
|
|
1175
|
+
function endChecks(tokens, state, ret) {
|
|
1176
|
+
if (state.pos < tokens.length) {
|
|
1177
|
+
if (state.tolerant) {
|
|
1178
|
+
skipPunctuation(tokens, state);
|
|
1354
1179
|
}
|
|
1355
|
-
if (
|
|
1356
|
-
|
|
1180
|
+
if (state.pos < tokens.length) {
|
|
1181
|
+
raiseError(
|
|
1182
|
+
state,
|
|
1183
|
+
tokens[state.pos],
|
|
1184
|
+
`Unexpected token: ${strToken(tokens[state.pos])}, expected end-of-input`
|
|
1185
|
+
);
|
|
1357
1186
|
}
|
|
1358
|
-
return {};
|
|
1359
1187
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
if (repaired !== ctx.parsed) {
|
|
1368
|
-
return { parsed: repaired };
|
|
1369
|
-
}
|
|
1370
|
-
return {};
|
|
1188
|
+
if (state.tolerant && state.warnings.length > 0) {
|
|
1189
|
+
const message = state.warnings.length === 1 ? state.warnings[0].message : `${state.warnings.length} parse warnings`;
|
|
1190
|
+
const err = new SyntaxError(message);
|
|
1191
|
+
err.line = state.warnings[0].line;
|
|
1192
|
+
err.warnings = state.warnings;
|
|
1193
|
+
err.obj = ret;
|
|
1194
|
+
throw err;
|
|
1371
1195
|
}
|
|
1372
|
-
};
|
|
1373
|
-
var defaultPipelineConfig = {
|
|
1374
|
-
preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
|
|
1375
|
-
fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
|
|
1376
|
-
postParse: [repairAgainstSchemaHeuristic]
|
|
1377
|
-
};
|
|
1378
|
-
var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
|
|
1379
|
-
function isIndexTagAt(xml, pos) {
|
|
1380
|
-
const remaining = xml.slice(pos);
|
|
1381
|
-
return INDEX_TAG_RE.test(remaining);
|
|
1382
1196
|
}
|
|
1383
|
-
function
|
|
1384
|
-
const
|
|
1385
|
-
let
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
const next = i + 1 < len ? xml[i + 1] : "";
|
|
1390
|
-
const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
|
|
1391
|
-
const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
|
|
1392
|
-
if (!(isValidStart || isIndexTag)) {
|
|
1393
|
-
out += "<";
|
|
1394
|
-
continue;
|
|
1395
|
-
}
|
|
1197
|
+
function parseAny(tokens, state, end = false) {
|
|
1198
|
+
const token = skipPunctuation(tokens, state);
|
|
1199
|
+
let ret;
|
|
1200
|
+
if (token.type === "eof") {
|
|
1201
|
+
if (end) {
|
|
1202
|
+
raiseUnexpected(state, token, "json value");
|
|
1396
1203
|
}
|
|
1397
|
-
|
|
1204
|
+
raiseUnexpected(state, token, "json value");
|
|
1205
|
+
return;
|
|
1398
1206
|
}
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
|
|
1403
|
-
let i = 0;
|
|
1404
|
-
const len = src.length;
|
|
1405
|
-
const out = [];
|
|
1406
|
-
const stack = [];
|
|
1407
|
-
while (i < len) {
|
|
1408
|
-
const lt = src.indexOf("<", i);
|
|
1409
|
-
if (lt === -1) {
|
|
1410
|
-
out.push(src.slice(i));
|
|
1207
|
+
switch (token.type) {
|
|
1208
|
+
case "{":
|
|
1209
|
+
ret = parseObject(tokens, state);
|
|
1411
1210
|
break;
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
if (lt + 1 >= len) {
|
|
1211
|
+
case "[":
|
|
1212
|
+
ret = parseArray(tokens, state);
|
|
1415
1213
|
break;
|
|
1214
|
+
case "string":
|
|
1215
|
+
// String literal
|
|
1216
|
+
case "number":
|
|
1217
|
+
// Number literal
|
|
1218
|
+
case "atom":
|
|
1219
|
+
ret = token.value;
|
|
1220
|
+
break;
|
|
1221
|
+
default:
|
|
1222
|
+
raiseUnexpected(state, token, "json value");
|
|
1223
|
+
if (state.tolerant) {
|
|
1224
|
+
ret = null;
|
|
1225
|
+
} else {
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
if (end) {
|
|
1230
|
+
ret = state.reviver ? state.reviver("", ret) : ret;
|
|
1231
|
+
endChecks(tokens, state, ret);
|
|
1232
|
+
}
|
|
1233
|
+
return ret;
|
|
1234
|
+
}
|
|
1235
|
+
function normalizeParseOptions(optsOrReviver) {
|
|
1236
|
+
var _a;
|
|
1237
|
+
let options = {};
|
|
1238
|
+
if (typeof optsOrReviver === "function") {
|
|
1239
|
+
options.reviver = optsOrReviver;
|
|
1240
|
+
} else if (optsOrReviver !== null && typeof optsOrReviver === "object") {
|
|
1241
|
+
options = { ...optsOrReviver };
|
|
1242
|
+
} else if (optsOrReviver !== void 0) {
|
|
1243
|
+
throw new TypeError(
|
|
1244
|
+
"Second argument must be a reviver function or an options object."
|
|
1245
|
+
);
|
|
1246
|
+
}
|
|
1247
|
+
if (options.relaxed === void 0) {
|
|
1248
|
+
if (options.warnings === true || options.tolerant === true) {
|
|
1249
|
+
options.relaxed = true;
|
|
1250
|
+
} else if (options.warnings === false && options.tolerant === false) {
|
|
1251
|
+
options.relaxed = false;
|
|
1252
|
+
} else {
|
|
1253
|
+
options.relaxed = true;
|
|
1416
1254
|
}
|
|
1417
|
-
const next = src[lt + 1];
|
|
1418
|
-
if (next === "!" || next === "?") {
|
|
1419
|
-
i = handleSpecialTagSegment(src, lt, out);
|
|
1420
|
-
continue;
|
|
1421
|
-
}
|
|
1422
|
-
if (next === "/") {
|
|
1423
|
-
i = handleClosingTagSegment(src, lt, out, stack);
|
|
1424
|
-
continue;
|
|
1425
|
-
}
|
|
1426
|
-
i = handleOpeningTagSegment(src, lt, out, stack);
|
|
1427
1255
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1256
|
+
options.tolerant = options.tolerant || options.warnings;
|
|
1257
|
+
options.duplicate = (_a = options.duplicate) != null ? _a : false;
|
|
1258
|
+
return options;
|
|
1259
|
+
}
|
|
1260
|
+
function createParseState(options) {
|
|
1261
|
+
var _a, _b;
|
|
1262
|
+
return {
|
|
1263
|
+
pos: 0,
|
|
1264
|
+
reviver: options.reviver,
|
|
1265
|
+
tolerant: (_a = options.tolerant) != null ? _a : false,
|
|
1266
|
+
duplicate: (_b = options.duplicate) != null ? _b : false,
|
|
1267
|
+
warnings: []
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
function parseWithCustomParser(text, options) {
|
|
1271
|
+
const lexerToUse = options.relaxed ? lexer : strictLexer;
|
|
1272
|
+
let tokens = lexerToUse(text);
|
|
1273
|
+
if (options.relaxed) {
|
|
1274
|
+
tokens = stripTrailingComma(tokens);
|
|
1275
|
+
}
|
|
1276
|
+
tokens = tokens.filter((token) => token.type !== " ");
|
|
1277
|
+
const state = createParseState(options);
|
|
1278
|
+
return parseAny(tokens, state, true);
|
|
1279
|
+
}
|
|
1280
|
+
function parseWithTransform(text, options) {
|
|
1281
|
+
let tokens = lexer(text);
|
|
1282
|
+
tokens = stripTrailingComma(tokens);
|
|
1283
|
+
const newtext = tokens.reduce((str, token) => str + token.match, "");
|
|
1284
|
+
return JSON.parse(
|
|
1285
|
+
newtext,
|
|
1286
|
+
options.reviver
|
|
1287
|
+
);
|
|
1288
|
+
}
|
|
1289
|
+
function parse2(text, optsOrReviver) {
|
|
1290
|
+
const options = normalizeParseOptions(optsOrReviver);
|
|
1291
|
+
if (!(options.relaxed || options.warnings || options.tolerant) && options.duplicate) {
|
|
1292
|
+
return JSON.parse(
|
|
1293
|
+
text,
|
|
1294
|
+
options.reviver
|
|
1295
|
+
);
|
|
1430
1296
|
}
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
function skipWs(s, p, len) {
|
|
1434
|
-
let idx = p;
|
|
1435
|
-
while (idx < len && WHITESPACE_REGEX2.test(s[idx])) {
|
|
1436
|
-
idx += 1;
|
|
1297
|
+
if (options.warnings || options.tolerant || !options.duplicate) {
|
|
1298
|
+
return parseWithCustomParser(text, options);
|
|
1437
1299
|
}
|
|
1438
|
-
return
|
|
1300
|
+
return parseWithTransform(text, options);
|
|
1439
1301
|
}
|
|
1440
|
-
function
|
|
1441
|
-
|
|
1442
|
-
const start = idx;
|
|
1443
|
-
while (idx < len && NAME_CHAR_RE.test(s[idx])) {
|
|
1444
|
-
idx += 1;
|
|
1445
|
-
}
|
|
1446
|
-
return { name: s.slice(start, idx), pos: idx };
|
|
1302
|
+
function stringifyPair(obj, key) {
|
|
1303
|
+
return `${JSON.stringify(key)}:${stringify(obj[key])}`;
|
|
1447
1304
|
}
|
|
1448
|
-
function
|
|
1449
|
-
const
|
|
1450
|
-
if (
|
|
1451
|
-
|
|
1452
|
-
return src.length;
|
|
1305
|
+
function stringify(obj) {
|
|
1306
|
+
const type = typeof obj;
|
|
1307
|
+
if (type === "string" || type === "number" || type === "boolean" || obj === null) {
|
|
1308
|
+
return JSON.stringify(obj);
|
|
1453
1309
|
}
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
}
|
|
1457
|
-
function handleClosingTagSegment(src, lt, out, stack) {
|
|
1458
|
-
const len = src.length;
|
|
1459
|
-
let p = skipWs(src, lt + 2, len);
|
|
1460
|
-
const { name, pos } = parseTagNameAt(src, p, len);
|
|
1461
|
-
p = pos;
|
|
1462
|
-
const gt = src.indexOf(">", p);
|
|
1463
|
-
const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
|
|
1464
|
-
const idx = stack.lastIndexOf(name);
|
|
1465
|
-
if (idx !== -1) {
|
|
1466
|
-
for (let k = stack.length - 1; k > idx; k -= 1) {
|
|
1467
|
-
out.push(`</${stack[k]}>`);
|
|
1468
|
-
stack.pop();
|
|
1469
|
-
}
|
|
1470
|
-
out.push(closingText);
|
|
1471
|
-
stack.pop();
|
|
1310
|
+
if (type === "undefined") {
|
|
1311
|
+
return "null";
|
|
1472
1312
|
}
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
const len = src.length;
|
|
1477
|
-
let p = skipWs(src, lt + 1, len);
|
|
1478
|
-
const nameStart = p;
|
|
1479
|
-
const parsed = parseTagNameAt(src, p, len);
|
|
1480
|
-
p = parsed.pos;
|
|
1481
|
-
const name = src.slice(nameStart, p);
|
|
1482
|
-
const q = src.indexOf(">", p);
|
|
1483
|
-
if (q === -1) {
|
|
1484
|
-
out.push(src.slice(lt));
|
|
1485
|
-
return len;
|
|
1313
|
+
if (Array.isArray(obj)) {
|
|
1314
|
+
const elements = obj.map(stringify).join(",");
|
|
1315
|
+
return `[${elements}]`;
|
|
1486
1316
|
}
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1317
|
+
if (type === "object") {
|
|
1318
|
+
const keys = Object.keys(obj);
|
|
1319
|
+
keys.sort();
|
|
1320
|
+
const pairs = keys.map((key) => stringifyPair(obj, key)).join(",");
|
|
1321
|
+
return `{${pairs}}`;
|
|
1490
1322
|
}
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1323
|
+
return "null";
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
// src/core/protocols/json-protocol.ts
|
|
1327
|
+
function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
|
|
1328
|
+
var _a, _b;
|
|
1329
|
+
try {
|
|
1330
|
+
const parsedToolCall = parse2(toolCallJson);
|
|
1331
|
+
processedElements.push({
|
|
1332
|
+
type: "tool-call",
|
|
1333
|
+
toolCallId: generateId(),
|
|
1334
|
+
toolName: parsedToolCall.name,
|
|
1335
|
+
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1336
|
+
});
|
|
1337
|
+
} catch (error) {
|
|
1338
|
+
logParseFailure({
|
|
1339
|
+
phase: "generated-text",
|
|
1340
|
+
reason: "Failed to parse tool call JSON segment",
|
|
1341
|
+
snippet: fullMatch,
|
|
1342
|
+
error
|
|
1343
|
+
});
|
|
1344
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
1345
|
+
options,
|
|
1346
|
+
"Could not process JSON tool call, keeping original text.",
|
|
1347
|
+
{ toolCall: fullMatch, error }
|
|
1348
|
+
);
|
|
1349
|
+
processedElements.push({ type: "text", text: fullMatch });
|
|
1495
1350
|
}
|
|
1496
|
-
return q + 1;
|
|
1497
1351
|
}
|
|
1498
|
-
function
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
return false;
|
|
1352
|
+
function addTextSegment(text, processedElements) {
|
|
1353
|
+
if (text.trim()) {
|
|
1354
|
+
processedElements.push({ type: "text", text });
|
|
1502
1355
|
}
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1356
|
+
}
|
|
1357
|
+
function processMatchedToolCall(context) {
|
|
1358
|
+
const { match, text, currentIndex, processedElements, options } = context;
|
|
1359
|
+
const startIndex = match.index;
|
|
1360
|
+
const toolCallJson = match[1];
|
|
1361
|
+
if (startIndex > currentIndex) {
|
|
1362
|
+
const textSegment = text.substring(currentIndex, startIndex);
|
|
1363
|
+
addTextSegment(textSegment, processedElements);
|
|
1506
1364
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
return false;
|
|
1365
|
+
if (toolCallJson) {
|
|
1366
|
+
processToolCallJson(toolCallJson, match[0], processedElements, options);
|
|
1510
1367
|
}
|
|
1511
|
-
|
|
1512
|
-
return (command == null ? void 0 : command.type) === "array";
|
|
1368
|
+
return startIndex + match[0].length;
|
|
1513
1369
|
}
|
|
1514
|
-
function
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
return [];
|
|
1370
|
+
function flushBuffer(state, controller, toolCallStart) {
|
|
1371
|
+
if (state.buffer.length === 0) {
|
|
1372
|
+
return;
|
|
1518
1373
|
}
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1374
|
+
if (!state.currentTextId) {
|
|
1375
|
+
state.currentTextId = generateId();
|
|
1376
|
+
controller.enqueue({
|
|
1377
|
+
type: "text-start",
|
|
1378
|
+
id: state.currentTextId
|
|
1379
|
+
});
|
|
1380
|
+
state.hasEmittedTextStart = true;
|
|
1522
1381
|
}
|
|
1523
|
-
const
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1382
|
+
const deltaContent = state.isInsideToolCall ? `${toolCallStart}${state.buffer}` : state.buffer;
|
|
1383
|
+
controller.enqueue({
|
|
1384
|
+
type: "text-delta",
|
|
1385
|
+
id: state.currentTextId,
|
|
1386
|
+
delta: deltaContent
|
|
1387
|
+
});
|
|
1388
|
+
state.buffer = "";
|
|
1389
|
+
}
|
|
1390
|
+
function closeTextBlock(state, controller) {
|
|
1391
|
+
if (state.currentTextId && state.hasEmittedTextStart) {
|
|
1392
|
+
controller.enqueue({
|
|
1393
|
+
type: "text-end",
|
|
1394
|
+
id: state.currentTextId
|
|
1395
|
+
});
|
|
1396
|
+
state.currentTextId = null;
|
|
1397
|
+
state.hasEmittedTextStart = false;
|
|
1532
1398
|
}
|
|
1533
|
-
return names;
|
|
1534
1399
|
}
|
|
1535
|
-
function
|
|
1536
|
-
|
|
1400
|
+
function emitIncompleteToolCall(state, controller, toolCallStart) {
|
|
1401
|
+
if (!state.currentToolCallJson) {
|
|
1402
|
+
return;
|
|
1403
|
+
}
|
|
1404
|
+
logParseFailure({
|
|
1405
|
+
phase: "stream",
|
|
1406
|
+
reason: "Incomplete streaming tool call segment emitted as text",
|
|
1407
|
+
snippet: `${toolCallStart}${state.currentToolCallJson}`
|
|
1408
|
+
});
|
|
1409
|
+
const errorId = generateId();
|
|
1410
|
+
const errorContent = `${toolCallStart}${state.currentToolCallJson}`;
|
|
1411
|
+
controller.enqueue({
|
|
1412
|
+
type: "text-start",
|
|
1413
|
+
id: errorId
|
|
1414
|
+
});
|
|
1415
|
+
controller.enqueue({
|
|
1416
|
+
type: "text-delta",
|
|
1417
|
+
id: errorId,
|
|
1418
|
+
delta: errorContent
|
|
1419
|
+
});
|
|
1420
|
+
controller.enqueue({
|
|
1421
|
+
type: "text-end",
|
|
1422
|
+
id: errorId
|
|
1423
|
+
});
|
|
1424
|
+
state.currentToolCallJson = "";
|
|
1537
1425
|
}
|
|
1538
|
-
function
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
|
|
1542
|
-
const matches = Array.from(xml.matchAll(re));
|
|
1543
|
-
if (matches.length <= 1) {
|
|
1544
|
-
return xml;
|
|
1426
|
+
function handleFinishChunk(state, controller, toolCallStart, chunk) {
|
|
1427
|
+
if (state.buffer.length > 0) {
|
|
1428
|
+
flushBuffer(state, controller, toolCallStart);
|
|
1545
1429
|
}
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1430
|
+
closeTextBlock(state, controller);
|
|
1431
|
+
emitIncompleteToolCall(state, controller, toolCallStart);
|
|
1432
|
+
controller.enqueue(chunk);
|
|
1433
|
+
}
|
|
1434
|
+
function publishText(text, state, controller) {
|
|
1435
|
+
if (state.isInsideToolCall) {
|
|
1436
|
+
closeTextBlock(state, controller);
|
|
1437
|
+
state.currentToolCallJson += text;
|
|
1438
|
+
} else if (text.length > 0) {
|
|
1439
|
+
if (!state.currentTextId) {
|
|
1440
|
+
state.currentTextId = generateId();
|
|
1441
|
+
controller.enqueue({
|
|
1442
|
+
type: "text-start",
|
|
1443
|
+
id: state.currentTextId
|
|
1444
|
+
});
|
|
1445
|
+
state.hasEmittedTextStart = true;
|
|
1554
1446
|
}
|
|
1555
|
-
|
|
1447
|
+
controller.enqueue({
|
|
1448
|
+
type: "text-delta",
|
|
1449
|
+
id: state.currentTextId,
|
|
1450
|
+
delta: text
|
|
1451
|
+
});
|
|
1556
1452
|
}
|
|
1557
|
-
result += xml.slice(cursor);
|
|
1558
|
-
return result;
|
|
1559
1453
|
}
|
|
1560
|
-
function
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1454
|
+
function emitToolCall(context) {
|
|
1455
|
+
var _a, _b;
|
|
1456
|
+
const { state, controller, toolCallStart, toolCallEnd, options } = context;
|
|
1457
|
+
try {
|
|
1458
|
+
const parsedToolCall = parse2(state.currentToolCallJson);
|
|
1459
|
+
closeTextBlock(state, controller);
|
|
1460
|
+
controller.enqueue({
|
|
1461
|
+
type: "tool-call",
|
|
1462
|
+
toolCallId: generateId(),
|
|
1463
|
+
toolName: parsedToolCall.name,
|
|
1464
|
+
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1465
|
+
});
|
|
1466
|
+
} catch (error) {
|
|
1467
|
+
logParseFailure({
|
|
1468
|
+
phase: "stream",
|
|
1469
|
+
reason: "Failed to parse streaming tool call JSON segment",
|
|
1470
|
+
snippet: `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`,
|
|
1471
|
+
error
|
|
1472
|
+
});
|
|
1473
|
+
const errorId = generateId();
|
|
1474
|
+
const errorContent = `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`;
|
|
1475
|
+
controller.enqueue({
|
|
1476
|
+
type: "text-start",
|
|
1477
|
+
id: errorId
|
|
1478
|
+
});
|
|
1479
|
+
controller.enqueue({
|
|
1480
|
+
type: "text-delta",
|
|
1481
|
+
id: errorId,
|
|
1482
|
+
delta: errorContent
|
|
1483
|
+
});
|
|
1484
|
+
controller.enqueue({
|
|
1485
|
+
type: "text-end",
|
|
1486
|
+
id: errorId
|
|
1487
|
+
});
|
|
1488
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
1489
|
+
options,
|
|
1490
|
+
"Could not process streaming JSON tool call; emitting original text.",
|
|
1491
|
+
{
|
|
1492
|
+
toolCall: errorContent
|
|
1493
|
+
}
|
|
1494
|
+
);
|
|
1567
1495
|
}
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1496
|
+
}
|
|
1497
|
+
function processTagMatch(context) {
|
|
1498
|
+
const { state } = context;
|
|
1499
|
+
if (state.isInsideToolCall) {
|
|
1500
|
+
emitToolCall(context);
|
|
1501
|
+
state.currentToolCallJson = "";
|
|
1502
|
+
state.isInsideToolCall = false;
|
|
1503
|
+
} else {
|
|
1504
|
+
state.currentToolCallJson = "";
|
|
1505
|
+
state.isInsideToolCall = true;
|
|
1571
1506
|
}
|
|
1572
|
-
applySchemaProps(input, properties);
|
|
1573
|
-
return input;
|
|
1574
1507
|
}
|
|
1575
|
-
function
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
const
|
|
1583
|
-
if (
|
|
1584
|
-
|
|
1585
|
-
const itemSchema = (0, import_rxml.unwrapJsonSchema)(itemSchemaRaw);
|
|
1586
|
-
obj[key] = coerceArrayItems(obj[key], itemSchema);
|
|
1587
|
-
continue;
|
|
1588
|
-
}
|
|
1589
|
-
if (propType === "object") {
|
|
1590
|
-
const val = obj[key];
|
|
1591
|
-
if (val && typeof val === "object") {
|
|
1592
|
-
obj[key] = repairParsedAgainstSchema(val, prop);
|
|
1593
|
-
}
|
|
1508
|
+
function processBufferTags(context) {
|
|
1509
|
+
const { state, controller, toolCallStart, toolCallEnd } = context;
|
|
1510
|
+
let startIndex = getPotentialStartIndex(
|
|
1511
|
+
state.buffer,
|
|
1512
|
+
state.isInsideToolCall ? toolCallEnd : toolCallStart
|
|
1513
|
+
);
|
|
1514
|
+
while (startIndex != null) {
|
|
1515
|
+
const tag = state.isInsideToolCall ? toolCallEnd : toolCallStart;
|
|
1516
|
+
if (startIndex + tag.length > state.buffer.length) {
|
|
1517
|
+
break;
|
|
1594
1518
|
}
|
|
1519
|
+
publishText(state.buffer.slice(0, startIndex), state, controller);
|
|
1520
|
+
state.buffer = state.buffer.slice(startIndex + tag.length);
|
|
1521
|
+
processTagMatch(context);
|
|
1522
|
+
startIndex = getPotentialStartIndex(
|
|
1523
|
+
state.buffer,
|
|
1524
|
+
state.isInsideToolCall ? toolCallEnd : toolCallStart
|
|
1525
|
+
);
|
|
1595
1526
|
}
|
|
1596
1527
|
}
|
|
1597
|
-
function
|
|
1598
|
-
if (
|
|
1599
|
-
return
|
|
1528
|
+
function handlePartialTag(state, controller, toolCallStart) {
|
|
1529
|
+
if (state.isInsideToolCall) {
|
|
1530
|
+
return;
|
|
1531
|
+
}
|
|
1532
|
+
const potentialIndex = getPotentialStartIndex(state.buffer, toolCallStart);
|
|
1533
|
+
if (potentialIndex != null && potentialIndex + toolCallStart.length > state.buffer.length) {
|
|
1534
|
+
publishText(state.buffer.slice(0, potentialIndex), state, controller);
|
|
1535
|
+
state.buffer = state.buffer.slice(potentialIndex);
|
|
1536
|
+
} else {
|
|
1537
|
+
publishText(state.buffer, state, controller);
|
|
1538
|
+
state.buffer = "";
|
|
1600
1539
|
}
|
|
1601
|
-
return val.map((v) => coerceArrayItem(v, itemSchema));
|
|
1602
1540
|
}
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1541
|
+
var jsonProtocol = ({
|
|
1542
|
+
toolCallStart = "<tool_call>",
|
|
1543
|
+
toolCallEnd = "</tool_call>"
|
|
1544
|
+
} = {}) => ({
|
|
1545
|
+
formatTools({
|
|
1546
|
+
tools,
|
|
1547
|
+
toolSystemPromptTemplate
|
|
1548
|
+
}) {
|
|
1549
|
+
return toolSystemPromptTemplate(tools || []);
|
|
1550
|
+
},
|
|
1551
|
+
formatToolCall(toolCall) {
|
|
1552
|
+
let args = {};
|
|
1553
|
+
try {
|
|
1554
|
+
args = JSON.parse(toolCall.input);
|
|
1555
|
+
} catch (e) {
|
|
1556
|
+
args = toolCall.input;
|
|
1609
1557
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1558
|
+
return `${toolCallStart}${JSON.stringify({
|
|
1559
|
+
name: toolCall.toolName,
|
|
1560
|
+
arguments: args
|
|
1561
|
+
})}${toolCallEnd}`;
|
|
1562
|
+
},
|
|
1563
|
+
parseGeneratedText({
|
|
1564
|
+
text,
|
|
1565
|
+
options
|
|
1566
|
+
}) {
|
|
1567
|
+
const startEsc = escapeRegExp2(toolCallStart);
|
|
1568
|
+
const endEsc = escapeRegExp2(toolCallEnd);
|
|
1569
|
+
const toolCallRegex = new RegExp(
|
|
1570
|
+
`${startEsc}([\0-\uFFFF]*?)${endEsc}`,
|
|
1571
|
+
"gs"
|
|
1612
1572
|
);
|
|
1613
|
-
|
|
1614
|
-
|
|
1573
|
+
const processedElements = [];
|
|
1574
|
+
let currentIndex = 0;
|
|
1575
|
+
let match = toolCallRegex.exec(text);
|
|
1576
|
+
while (match !== null) {
|
|
1577
|
+
currentIndex = processMatchedToolCall({
|
|
1578
|
+
match,
|
|
1579
|
+
text,
|
|
1580
|
+
currentIndex,
|
|
1581
|
+
processedElements,
|
|
1582
|
+
options
|
|
1583
|
+
});
|
|
1584
|
+
match = toolCallRegex.exec(text);
|
|
1615
1585
|
}
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
const
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1586
|
+
if (currentIndex < text.length) {
|
|
1587
|
+
const remainingText = text.substring(currentIndex);
|
|
1588
|
+
addTextSegment(remainingText, processedElements);
|
|
1589
|
+
}
|
|
1590
|
+
return processedElements;
|
|
1591
|
+
},
|
|
1592
|
+
createStreamParser({
|
|
1593
|
+
options
|
|
1594
|
+
}) {
|
|
1595
|
+
const state = {
|
|
1596
|
+
isInsideToolCall: false,
|
|
1597
|
+
buffer: "",
|
|
1598
|
+
currentToolCallJson: "",
|
|
1599
|
+
currentTextId: null,
|
|
1600
|
+
hasEmittedTextStart: false
|
|
1601
|
+
};
|
|
1602
|
+
return new TransformStream({
|
|
1603
|
+
transform(chunk, controller) {
|
|
1604
|
+
var _a;
|
|
1605
|
+
if (chunk.type === "finish") {
|
|
1606
|
+
handleFinishChunk(state, controller, toolCallStart, chunk);
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1609
|
+
if (chunk.type !== "text-delta") {
|
|
1610
|
+
controller.enqueue(chunk);
|
|
1611
|
+
return;
|
|
1612
|
+
}
|
|
1613
|
+
const textContent = (_a = chunk.delta) != null ? _a : "";
|
|
1614
|
+
state.buffer += textContent;
|
|
1615
|
+
processBufferTags({
|
|
1616
|
+
state,
|
|
1617
|
+
controller,
|
|
1618
|
+
toolCallStart,
|
|
1619
|
+
toolCallEnd,
|
|
1620
|
+
options
|
|
1621
|
+
});
|
|
1622
|
+
handlePartialTag(state, controller, toolCallStart);
|
|
1623
|
+
}
|
|
1624
|
+
});
|
|
1625
|
+
},
|
|
1626
|
+
extractToolCallSegments({ text }) {
|
|
1627
|
+
const startEsc = escapeRegExp2(toolCallStart);
|
|
1628
|
+
const endEsc = escapeRegExp2(toolCallEnd);
|
|
1629
|
+
const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
|
|
1630
|
+
const segments = [];
|
|
1631
|
+
let m = regex.exec(text);
|
|
1632
|
+
while (m != null) {
|
|
1633
|
+
segments.push(m[0]);
|
|
1634
|
+
m = regex.exec(text);
|
|
1635
|
+
}
|
|
1636
|
+
return segments;
|
|
1630
1637
|
}
|
|
1638
|
+
});
|
|
1639
|
+
|
|
1640
|
+
// src/core/protocols/protocol-interface.ts
|
|
1641
|
+
function isProtocolFactory(protocol) {
|
|
1642
|
+
return typeof protocol === "function";
|
|
1631
1643
|
}
|
|
1632
|
-
function
|
|
1633
|
-
|
|
1634
|
-
const statusMatch = normXml.match(STATUS_TAG_RE);
|
|
1635
|
-
if (stepMatch && statusMatch) {
|
|
1636
|
-
return { step: stepMatch[1], status: statusMatch[1] };
|
|
1637
|
-
}
|
|
1638
|
-
return null;
|
|
1644
|
+
function isTCMProtocolFactory(protocol) {
|
|
1645
|
+
return typeof protocol === "function";
|
|
1639
1646
|
}
|
|
1640
1647
|
|
|
1641
|
-
// src/core/protocols/
|
|
1648
|
+
// src/core/protocols/xml-protocol.ts
|
|
1649
|
+
import { extractRawInner, parse as parse3, stringify as stringify2 } from "@ai-sdk-tool/rxml";
|
|
1642
1650
|
var defaultPipelineConfig2 = defaultPipelineConfig;
|
|
1643
1651
|
var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
|
|
1644
1652
|
var WHITESPACE_REGEX3 = /\s/;
|
|
@@ -1652,7 +1660,7 @@ function normalizeCloseTags(xml) {
|
|
|
1652
1660
|
function tryParseSecondaryXml(content, toolSchema, options) {
|
|
1653
1661
|
const balanced = balanceTags(content);
|
|
1654
1662
|
try {
|
|
1655
|
-
let parsed = (
|
|
1663
|
+
let parsed = parse3(balanced, toolSchema, {
|
|
1656
1664
|
onError: options == null ? void 0 : options.onError,
|
|
1657
1665
|
noChildNodes: []
|
|
1658
1666
|
});
|
|
@@ -1667,7 +1675,7 @@ function tryParseSecondaryXml(content, toolSchema, options) {
|
|
|
1667
1675
|
}
|
|
1668
1676
|
if (deduped !== balanced) {
|
|
1669
1677
|
try {
|
|
1670
|
-
let reparsed = (
|
|
1678
|
+
let reparsed = parse3(deduped, toolSchema, {
|
|
1671
1679
|
onError: options == null ? void 0 : options.onError,
|
|
1672
1680
|
noChildNodes: []
|
|
1673
1681
|
});
|
|
@@ -1699,7 +1707,7 @@ function processToolCallWithPipeline(params) {
|
|
|
1699
1707
|
toolSchema
|
|
1700
1708
|
);
|
|
1701
1709
|
const result = applyHeuristicPipeline(ctx, pipelineConfig, {
|
|
1702
|
-
parse: (xml, schema) => (
|
|
1710
|
+
parse: (xml, schema) => parse3(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
|
|
1703
1711
|
onError: options == null ? void 0 : options.onError,
|
|
1704
1712
|
maxReparses
|
|
1705
1713
|
});
|
|
@@ -1744,7 +1752,7 @@ function handleStreamingToolCallEnd(params) {
|
|
|
1744
1752
|
toolSchema
|
|
1745
1753
|
);
|
|
1746
1754
|
const result = applyHeuristicPipeline(ctx, pipelineConfig, {
|
|
1747
|
-
parse: (xml, schema) => (
|
|
1755
|
+
parse: (xml, schema) => parse3(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
|
|
1748
1756
|
onError: options == null ? void 0 : options.onError,
|
|
1749
1757
|
maxReparses
|
|
1750
1758
|
});
|
|
@@ -1752,7 +1760,7 @@ function handleStreamingToolCallEnd(params) {
|
|
|
1752
1760
|
} else {
|
|
1753
1761
|
try {
|
|
1754
1762
|
const primary = escapeInvalidLt(normalizeCloseTags(toolContent));
|
|
1755
|
-
const parsed = (
|
|
1763
|
+
const parsed = parse3(primary, toolSchema, {
|
|
1756
1764
|
onError: options == null ? void 0 : options.onError,
|
|
1757
1765
|
noChildNodes: []
|
|
1758
1766
|
});
|
|
@@ -1909,7 +1917,7 @@ function findToolCallsForName(text, toolName) {
|
|
|
1909
1917
|
const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
|
|
1910
1918
|
if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
|
|
1911
1919
|
const segment = text.substring(tagStart, fullTagEnd);
|
|
1912
|
-
const inner = (_a =
|
|
1920
|
+
const inner = (_a = extractRawInner(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
|
|
1913
1921
|
toolCalls.push({
|
|
1914
1922
|
toolName,
|
|
1915
1923
|
startIndex: tagStart,
|
|
@@ -1972,7 +1980,6 @@ function createFlushTextHandler(getCurrentTextId, setCurrentTextId, getHasEmitte
|
|
|
1972
1980
|
controller.enqueue({
|
|
1973
1981
|
type: "text-delta",
|
|
1974
1982
|
id: getCurrentTextId(),
|
|
1975
|
-
textDelta: content,
|
|
1976
1983
|
delta: content
|
|
1977
1984
|
});
|
|
1978
1985
|
}
|
|
@@ -2134,7 +2141,7 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
|
|
|
2134
2141
|
}
|
|
2135
2142
|
};
|
|
2136
2143
|
}
|
|
2137
|
-
var
|
|
2144
|
+
var xmlProtocol = (protocolOptions) => {
|
|
2138
2145
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
2139
2146
|
let pipelineConfig = protocolOptions == null ? void 0 : protocolOptions.pipeline;
|
|
2140
2147
|
const maxReparses = protocolOptions == null ? void 0 : protocolOptions.maxReparses;
|
|
@@ -2174,12 +2181,7 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2174
2181
|
}
|
|
2175
2182
|
return {
|
|
2176
2183
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
2177
|
-
|
|
2178
|
-
name: tool.name,
|
|
2179
|
-
description: tool.description,
|
|
2180
|
-
parameters: (0, import_rxml2.unwrapJsonSchema)(tool.inputSchema)
|
|
2181
|
-
}));
|
|
2182
|
-
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
2184
|
+
return toolSystemPromptTemplate(tools || []);
|
|
2183
2185
|
},
|
|
2184
2186
|
formatToolCall(toolCall) {
|
|
2185
2187
|
let args = {};
|
|
@@ -2188,26 +2190,11 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2188
2190
|
} catch (e) {
|
|
2189
2191
|
args = toolCall.input;
|
|
2190
2192
|
}
|
|
2191
|
-
return (
|
|
2193
|
+
return stringify2(toolCall.toolName, args, {
|
|
2192
2194
|
suppressEmptyNode: false,
|
|
2193
2195
|
format: false
|
|
2194
2196
|
});
|
|
2195
2197
|
},
|
|
2196
|
-
formatToolResponse(toolResult) {
|
|
2197
|
-
let result = toolResult.result;
|
|
2198
|
-
if (result && typeof result === "object" && "type" in result && result.type === "json" && "value" in result) {
|
|
2199
|
-
result = result.value;
|
|
2200
|
-
}
|
|
2201
|
-
const xml = (0, import_rxml2.stringify)(
|
|
2202
|
-
"tool_response",
|
|
2203
|
-
{
|
|
2204
|
-
tool_name: toolResult.toolName,
|
|
2205
|
-
result
|
|
2206
|
-
},
|
|
2207
|
-
{ declaration: false }
|
|
2208
|
-
);
|
|
2209
|
-
return xml;
|
|
2210
|
-
},
|
|
2211
2198
|
parseGeneratedText({ text, tools, options }) {
|
|
2212
2199
|
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
2213
2200
|
if (toolNames.length === 0) {
|
|
@@ -2276,7 +2263,7 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2276
2263
|
);
|
|
2277
2264
|
return new TransformStream({
|
|
2278
2265
|
transform(chunk, controller) {
|
|
2279
|
-
var _a2
|
|
2266
|
+
var _a2;
|
|
2280
2267
|
if (chunk.type !== "text-delta") {
|
|
2281
2268
|
if (buffer) {
|
|
2282
2269
|
flushText(controller, buffer);
|
|
@@ -2285,7 +2272,7 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2285
2272
|
controller.enqueue(chunk);
|
|
2286
2273
|
return;
|
|
2287
2274
|
}
|
|
2288
|
-
const textContent = (
|
|
2275
|
+
const textContent = (_a2 = chunk.delta) != null ? _a2 : "";
|
|
2289
2276
|
buffer += textContent;
|
|
2290
2277
|
processBuffer(controller);
|
|
2291
2278
|
},
|
|
@@ -2320,9 +2307,8 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2320
2307
|
};
|
|
2321
2308
|
};
|
|
2322
2309
|
|
|
2323
|
-
// src/core/protocols/yaml-
|
|
2324
|
-
|
|
2325
|
-
var import_yaml = __toESM(require("yaml"), 1);
|
|
2310
|
+
// src/core/protocols/yaml-protocol.ts
|
|
2311
|
+
import YAML from "yaml";
|
|
2326
2312
|
var NAME_CHAR_RE3 = /[A-Za-z0-9_:-]/;
|
|
2327
2313
|
var WHITESPACE_REGEX4 = /\s/;
|
|
2328
2314
|
var LEADING_WHITESPACE_RE = /^(\s*)/;
|
|
@@ -2469,7 +2455,7 @@ function parseYamlContent(yamlContent, options) {
|
|
|
2469
2455
|
normalized = lines.map((line) => line.slice(minIndent)).join("\n");
|
|
2470
2456
|
}
|
|
2471
2457
|
try {
|
|
2472
|
-
const doc =
|
|
2458
|
+
const doc = YAML.parseDocument(normalized);
|
|
2473
2459
|
if (doc.errors && doc.errors.length > 0) {
|
|
2474
2460
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "YAML parse error", {
|
|
2475
2461
|
errors: doc.errors.map((e) => e.message)
|
|
@@ -2542,7 +2528,6 @@ function createFlushTextHandler2(getCurrentTextId, setCurrentTextId, getHasEmitt
|
|
|
2542
2528
|
controller.enqueue({
|
|
2543
2529
|
type: "text-delta",
|
|
2544
2530
|
id: getCurrentTextId(),
|
|
2545
|
-
textDelta: content,
|
|
2546
2531
|
delta: content
|
|
2547
2532
|
});
|
|
2548
2533
|
}
|
|
@@ -2590,15 +2575,10 @@ function findEarliestToolTag2(buffer, toolNames) {
|
|
|
2590
2575
|
tagLength: bestTagLength
|
|
2591
2576
|
};
|
|
2592
2577
|
}
|
|
2593
|
-
var
|
|
2578
|
+
var yamlProtocol = (_protocolOptions) => {
|
|
2594
2579
|
return {
|
|
2595
2580
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
2596
|
-
|
|
2597
|
-
name: tool.name,
|
|
2598
|
-
description: tool.description,
|
|
2599
|
-
parameters: (0, import_rxml3.unwrapJsonSchema)(tool.inputSchema)
|
|
2600
|
-
}));
|
|
2601
|
-
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
2581
|
+
return toolSystemPromptTemplate(tools || []);
|
|
2602
2582
|
},
|
|
2603
2583
|
formatToolCall(toolCall) {
|
|
2604
2584
|
let args = {};
|
|
@@ -2607,25 +2587,10 @@ var yamlXmlProtocol = (_protocolOptions) => {
|
|
|
2607
2587
|
} catch (e) {
|
|
2608
2588
|
args = { value: toolCall.input };
|
|
2609
2589
|
}
|
|
2610
|
-
const yamlContent =
|
|
2590
|
+
const yamlContent = YAML.stringify(args);
|
|
2611
2591
|
return `<${toolCall.toolName}>
|
|
2612
2592
|
${yamlContent}</${toolCall.toolName}>`;
|
|
2613
2593
|
},
|
|
2614
|
-
formatToolResponse(toolResult) {
|
|
2615
|
-
let result = toolResult.result;
|
|
2616
|
-
if (result && typeof result === "object" && "type" in result && result.type === "json" && "value" in result) {
|
|
2617
|
-
result = result.value;
|
|
2618
|
-
}
|
|
2619
|
-
const xml = (0, import_rxml3.stringify)(
|
|
2620
|
-
"tool_response",
|
|
2621
|
-
{
|
|
2622
|
-
tool_name: toolResult.toolName,
|
|
2623
|
-
result
|
|
2624
|
-
},
|
|
2625
|
-
{ declaration: false }
|
|
2626
|
-
);
|
|
2627
|
-
return xml;
|
|
2628
|
-
},
|
|
2629
2594
|
parseGeneratedText({ text, tools, options }) {
|
|
2630
2595
|
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
2631
2596
|
if (toolNames.length === 0) {
|
|
@@ -2739,7 +2704,7 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2739
2704
|
};
|
|
2740
2705
|
return new TransformStream({
|
|
2741
2706
|
transform(chunk, controller) {
|
|
2742
|
-
var _a
|
|
2707
|
+
var _a;
|
|
2743
2708
|
if (chunk.type !== "text-delta") {
|
|
2744
2709
|
if (buffer) {
|
|
2745
2710
|
flushText(controller, buffer);
|
|
@@ -2748,7 +2713,7 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2748
2713
|
controller.enqueue(chunk);
|
|
2749
2714
|
return;
|
|
2750
2715
|
}
|
|
2751
|
-
const textContent = (
|
|
2716
|
+
const textContent = (_a = chunk.delta) != null ? _a : "";
|
|
2752
2717
|
buffer += textContent;
|
|
2753
2718
|
processBuffer(controller);
|
|
2754
2719
|
},
|
|
@@ -2784,48 +2749,62 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2784
2749
|
}
|
|
2785
2750
|
};
|
|
2786
2751
|
};
|
|
2787
|
-
function orchestratorSystemPromptTemplate(tools, includeMultilineExample = true) {
|
|
2788
|
-
const multilineExample = includeMultilineExample ? `
|
|
2789
|
-
|
|
2790
|
-
For multiline values, use YAML's literal block syntax:
|
|
2791
|
-
<write_file>
|
|
2792
|
-
file_path: /tmp/example.txt
|
|
2793
|
-
contents: |
|
|
2794
|
-
First line
|
|
2795
|
-
Second line
|
|
2796
|
-
Third line
|
|
2797
|
-
</write_file>` : "";
|
|
2798
|
-
return `# Tools
|
|
2799
|
-
|
|
2800
|
-
You may call one or more functions to assist with the user query.
|
|
2801
|
-
|
|
2802
|
-
You are provided with function signatures within <tools></tools> XML tags:
|
|
2803
|
-
<tools>${tools}</tools>
|
|
2804
|
-
|
|
2805
|
-
# Format
|
|
2806
|
-
|
|
2807
|
-
Use exactly one XML element whose tag name is the function name.
|
|
2808
|
-
Inside the XML element, specify parameters using YAML syntax (key: value pairs).
|
|
2809
|
-
|
|
2810
|
-
# Example
|
|
2811
|
-
<get_weather>
|
|
2812
|
-
location: New York
|
|
2813
|
-
unit: celsius
|
|
2814
|
-
</get_weather>${multilineExample}
|
|
2815
|
-
|
|
2816
|
-
# Rules
|
|
2817
|
-
- Parameter names and values must follow the schema exactly.
|
|
2818
|
-
- Use proper YAML syntax for values (strings, numbers, booleans, arrays, objects).
|
|
2819
|
-
- Each required parameter must appear once.
|
|
2820
|
-
- Do not add functions or parameters not in the schema.
|
|
2821
|
-
- After calling a tool, you will receive a response. Use this result to answer the user.
|
|
2822
|
-
- Do NOT ask clarifying questions. Use reasonable defaults for optional parameters.
|
|
2823
|
-
- If a task requires multiple function calls, make ALL of them at once.`;
|
|
2824
|
-
}
|
|
2825
2752
|
|
|
2826
|
-
// src/core/
|
|
2827
|
-
function
|
|
2828
|
-
|
|
2753
|
+
// src/core/utils/dynamic-tool-schema.ts
|
|
2754
|
+
function createDynamicIfThenElseSchema(tools) {
|
|
2755
|
+
let currentSchema = {};
|
|
2756
|
+
const toolNames = [];
|
|
2757
|
+
for (let i = tools.length - 1; i >= 0; i -= 1) {
|
|
2758
|
+
const tool = tools[i];
|
|
2759
|
+
if (tool.type === "provider") {
|
|
2760
|
+
throw new Error(
|
|
2761
|
+
"Provider tools are not supported by this middleware. Please use function tools."
|
|
2762
|
+
);
|
|
2763
|
+
}
|
|
2764
|
+
toolNames.unshift(tool.name);
|
|
2765
|
+
const toolCondition = {
|
|
2766
|
+
if: {
|
|
2767
|
+
properties: {
|
|
2768
|
+
name: {
|
|
2769
|
+
const: tool.name
|
|
2770
|
+
}
|
|
2771
|
+
},
|
|
2772
|
+
required: ["name"]
|
|
2773
|
+
},
|
|
2774
|
+
// biome-ignore lint/suspicious/noThenProperty: JSON Schema uses 'then' as a keyword
|
|
2775
|
+
then: {
|
|
2776
|
+
properties: {
|
|
2777
|
+
name: {
|
|
2778
|
+
const: tool.name
|
|
2779
|
+
},
|
|
2780
|
+
arguments: tool.inputSchema
|
|
2781
|
+
},
|
|
2782
|
+
required: ["name", "arguments"]
|
|
2783
|
+
}
|
|
2784
|
+
};
|
|
2785
|
+
if (Object.keys(currentSchema).length > 0) {
|
|
2786
|
+
toolCondition.else = currentSchema;
|
|
2787
|
+
}
|
|
2788
|
+
currentSchema = toolCondition;
|
|
2789
|
+
}
|
|
2790
|
+
return {
|
|
2791
|
+
type: "object",
|
|
2792
|
+
// Explicitly specify type as "object"
|
|
2793
|
+
properties: {
|
|
2794
|
+
name: {
|
|
2795
|
+
type: "string",
|
|
2796
|
+
description: "Name of the tool to call",
|
|
2797
|
+
enum: toolNames
|
|
2798
|
+
},
|
|
2799
|
+
arguments: {
|
|
2800
|
+
type: "object",
|
|
2801
|
+
// By default, arguments is also specified as object type
|
|
2802
|
+
description: "Argument object to be passed to the tool"
|
|
2803
|
+
}
|
|
2804
|
+
},
|
|
2805
|
+
required: ["name", "arguments"],
|
|
2806
|
+
...currentSchema
|
|
2807
|
+
};
|
|
2829
2808
|
}
|
|
2830
2809
|
|
|
2831
2810
|
// src/core/utils/on-error.ts
|
|
@@ -2861,15 +2840,31 @@ function decodeOriginalTools(originalTools) {
|
|
|
2861
2840
|
})
|
|
2862
2841
|
);
|
|
2863
2842
|
}
|
|
2843
|
+
function extractToolNamesFromOriginalTools(originalTools) {
|
|
2844
|
+
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
2845
|
+
}
|
|
2864
2846
|
function isToolChoiceActive(params) {
|
|
2865
2847
|
var _a, _b, _c;
|
|
2866
2848
|
const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
|
|
2867
2849
|
return !!(typeof params.providerOptions === "object" && params.providerOptions !== null && typeof ((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) === "object" && toolChoice && typeof toolChoice === "object" && (toolChoice.type === "tool" || toolChoice.type === "required"));
|
|
2868
2850
|
}
|
|
2869
2851
|
|
|
2870
|
-
// src/
|
|
2871
|
-
|
|
2872
|
-
|
|
2852
|
+
// src/core/utils/type-guards.ts
|
|
2853
|
+
function isToolCallContent(content) {
|
|
2854
|
+
return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
|
|
2855
|
+
(typeof content.input === "string" || typeof content.input === "object");
|
|
2856
|
+
}
|
|
2857
|
+
function isToolResultPart(content) {
|
|
2858
|
+
const c = content;
|
|
2859
|
+
return !!c && c.type === "tool-result" && typeof c.toolName === "string" && typeof c.toolCallId === "string" && "output" in c;
|
|
2860
|
+
}
|
|
2861
|
+
function hasInputProperty(obj) {
|
|
2862
|
+
return typeof obj === "object" && obj !== null && "input" in obj;
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2865
|
+
// src/generate-handler.ts
|
|
2866
|
+
import { generateId as generateId2 } from "@ai-sdk/provider-utils";
|
|
2867
|
+
import { coerceBySchema } from "@ai-sdk-tool/rxml";
|
|
2873
2868
|
function parseToolChoiceJson(text, providerOptions) {
|
|
2874
2869
|
var _a;
|
|
2875
2870
|
try {
|
|
@@ -2913,7 +2908,7 @@ async function handleToolChoice(doGenerate, params) {
|
|
|
2913
2908
|
}
|
|
2914
2909
|
const toolCall = {
|
|
2915
2910
|
type: "tool-call",
|
|
2916
|
-
toolCallId: (
|
|
2911
|
+
toolCallId: generateId2(),
|
|
2917
2912
|
toolName: parsed.name || "unknown",
|
|
2918
2913
|
input: JSON.stringify(parsed.arguments || {})
|
|
2919
2914
|
};
|
|
@@ -3032,80 +3027,207 @@ function fixToolCallWithSchema(part, tools) {
|
|
|
3032
3027
|
args = tc.input;
|
|
3033
3028
|
}
|
|
3034
3029
|
const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
|
|
3035
|
-
const coerced =
|
|
3030
|
+
const coerced = coerceBySchema(args, schema);
|
|
3036
3031
|
return {
|
|
3037
3032
|
...part,
|
|
3038
3033
|
input: JSON.stringify(coerced != null ? coerced : {})
|
|
3039
3034
|
};
|
|
3040
3035
|
}
|
|
3041
3036
|
|
|
3042
|
-
// src/
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
return {
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3037
|
+
// src/core/prompts/hermes-system-prompt.ts
|
|
3038
|
+
function hermesSystemPromptTemplate(tools) {
|
|
3039
|
+
const toolsJson = JSON.stringify(tools);
|
|
3040
|
+
return `You are a function calling AI model.
|
|
3041
|
+
You are provided with function signatures within <tools></tools> XML tags.
|
|
3042
|
+
You may call one or more functions to assist with the user query.
|
|
3043
|
+
Don't make assumptions about what values to plug into functions.
|
|
3044
|
+
Here are the available tools: <tools>${toolsJson}</tools>
|
|
3045
|
+
Use the following pydantic model json schema for each tool call you will make: {"title": "FunctionCall", "type": "object", "properties": {"arguments": {"title": "Arguments", "type": "object"}, "name": {"title": "Name", "type": "string"}}, "required": ["arguments", "name"]}
|
|
3046
|
+
For each function call return a json object with function name and arguments within <tool_call></tool_call> XML tags as follows:
|
|
3047
|
+
<tool_call>
|
|
3048
|
+
{"name": "<function-name>", "arguments": <args-dict>}
|
|
3049
|
+
</tool_call>`;
|
|
3050
|
+
}
|
|
3051
|
+
|
|
3052
|
+
// src/core/prompts/tool-response.ts
|
|
3053
|
+
function unwrapToolResult(result) {
|
|
3054
|
+
var _a, _b;
|
|
3055
|
+
switch (result.type) {
|
|
3056
|
+
case "text":
|
|
3057
|
+
return (_a = result.value) != null ? _a : "";
|
|
3058
|
+
case "json":
|
|
3059
|
+
return result.value;
|
|
3060
|
+
case "execution-denied": {
|
|
3061
|
+
const reason = result.reason;
|
|
3062
|
+
return reason ? `[Execution Denied: ${reason}]` : "[Execution Denied]";
|
|
3063
|
+
}
|
|
3064
|
+
case "error-text":
|
|
3065
|
+
return `[Error: ${(_b = result.value) != null ? _b : ""}]`;
|
|
3066
|
+
case "error-json":
|
|
3067
|
+
return `[Error: ${JSON.stringify(result.value)}]`;
|
|
3068
|
+
case "content": {
|
|
3069
|
+
return result.value.map((part) => {
|
|
3070
|
+
var _a2;
|
|
3071
|
+
const contentPart = part;
|
|
3072
|
+
switch (contentPart.type) {
|
|
3073
|
+
case "text":
|
|
3074
|
+
return (_a2 = contentPart.text) != null ? _a2 : "";
|
|
3075
|
+
case "image-data":
|
|
3076
|
+
return `[Image: ${contentPart.mediaType}]`;
|
|
3077
|
+
case "image-url":
|
|
3078
|
+
return `[Image URL: ${contentPart.url}]`;
|
|
3079
|
+
case "image-file-id": {
|
|
3080
|
+
const fileId = contentPart.fileId;
|
|
3081
|
+
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
3082
|
+
return `[Image ID: ${displayId}]`;
|
|
3083
|
+
}
|
|
3084
|
+
case "file-data": {
|
|
3085
|
+
const filePart = contentPart;
|
|
3086
|
+
if (filePart.filename) {
|
|
3087
|
+
return `[File: ${filePart.filename} (${filePart.mediaType})]`;
|
|
3088
|
+
}
|
|
3089
|
+
return `[File: ${filePart.mediaType}]`;
|
|
3090
|
+
}
|
|
3091
|
+
case "file-url":
|
|
3092
|
+
return `[File URL: ${contentPart.url}]`;
|
|
3093
|
+
case "file-id": {
|
|
3094
|
+
const fileId = contentPart.fileId;
|
|
3095
|
+
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
3096
|
+
return `[File ID: ${displayId}]`;
|
|
3097
|
+
}
|
|
3098
|
+
case "media":
|
|
3099
|
+
return `[Media: ${contentPart.mediaType}]`;
|
|
3100
|
+
case "custom":
|
|
3101
|
+
return "[Custom content]";
|
|
3102
|
+
default:
|
|
3103
|
+
return "[Unknown content]";
|
|
3104
|
+
}
|
|
3105
|
+
}).join("\n");
|
|
3106
|
+
}
|
|
3107
|
+
default: {
|
|
3108
|
+
const _exhaustive = result;
|
|
3109
|
+
return _exhaustive;
|
|
3110
|
+
}
|
|
3079
3111
|
}
|
|
3080
3112
|
}
|
|
3081
|
-
function
|
|
3082
|
-
const
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3113
|
+
function formatToolResponseAsJsonInXml(toolResult) {
|
|
3114
|
+
const unwrappedResult = unwrapToolResult(toolResult.output);
|
|
3115
|
+
return `<tool_response>${JSON.stringify({
|
|
3116
|
+
toolName: toolResult.toolName,
|
|
3117
|
+
result: unwrappedResult
|
|
3118
|
+
})}</tool_response>`;
|
|
3119
|
+
}
|
|
3120
|
+
function formatToolResponseAsXml(toolResult) {
|
|
3121
|
+
const unwrappedResult = unwrapToolResult(toolResult.output);
|
|
3122
|
+
const toolNameXml = `<tool_name>${toolResult.toolName}</tool_name>`;
|
|
3123
|
+
const resultLines = formatXmlNode("result", unwrappedResult, 1);
|
|
3124
|
+
return [
|
|
3125
|
+
"<tool_response>",
|
|
3126
|
+
` ${toolNameXml}`,
|
|
3127
|
+
...resultLines,
|
|
3128
|
+
"</tool_response>"
|
|
3129
|
+
].join("\n");
|
|
3130
|
+
}
|
|
3131
|
+
function formatXmlNode(tagName, value, depth) {
|
|
3132
|
+
const indent = " ".repeat(depth);
|
|
3133
|
+
if (value === null || value === void 0) {
|
|
3134
|
+
return [`${indent}<${tagName}></${tagName}>`];
|
|
3135
|
+
}
|
|
3136
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
3137
|
+
return [`${indent}<${tagName}>${String(value)}</${tagName}>`];
|
|
3138
|
+
}
|
|
3139
|
+
if (Array.isArray(value)) {
|
|
3140
|
+
if (value.length === 0) {
|
|
3141
|
+
return [`${indent}<${tagName}></${tagName}>`];
|
|
3104
3142
|
}
|
|
3105
|
-
|
|
3106
|
-
|
|
3143
|
+
const lines2 = [`${indent}<${tagName}>`];
|
|
3144
|
+
for (const item of value) {
|
|
3145
|
+
lines2.push(...formatXmlNode("item", item, depth + 1));
|
|
3146
|
+
}
|
|
3147
|
+
lines2.push(`${indent}</${tagName}>`);
|
|
3148
|
+
return lines2;
|
|
3149
|
+
}
|
|
3150
|
+
const entries = Object.entries(value);
|
|
3151
|
+
if (entries.length === 0) {
|
|
3152
|
+
return [`${indent}<${tagName}></${tagName}>`];
|
|
3107
3153
|
}
|
|
3154
|
+
const lines = [`${indent}<${tagName}>`];
|
|
3155
|
+
for (const [key, entryValue] of entries) {
|
|
3156
|
+
lines.push(...formatXmlNode(key, entryValue, depth + 1));
|
|
3157
|
+
}
|
|
3158
|
+
lines.push(`${indent}</${tagName}>`);
|
|
3159
|
+
return lines;
|
|
3160
|
+
}
|
|
3161
|
+
|
|
3162
|
+
// src/core/prompts/xml-system-prompt.ts
|
|
3163
|
+
function xmlSystemPromptTemplate(tools) {
|
|
3164
|
+
const toolsJson = JSON.stringify(tools);
|
|
3165
|
+
return `# Tools
|
|
3166
|
+
|
|
3167
|
+
You may call one or more functions to assist with the user query.
|
|
3168
|
+
|
|
3169
|
+
You are provided with function signatures within <tools></tools> XML tags:
|
|
3170
|
+
<tools>${toolsJson}</tools>
|
|
3171
|
+
|
|
3172
|
+
# Rules
|
|
3173
|
+
- Use exactly one XML element whose tag name is the function name.
|
|
3174
|
+
- Put each parameter as a child element.
|
|
3175
|
+
- Values must follow the schema exactly (numbers, arrays, objects, enums \u2192 copy as-is).
|
|
3176
|
+
- Do not add or remove functions or parameters.
|
|
3177
|
+
- Each required parameter must appear once.
|
|
3178
|
+
- Output nothing before or after the function call.
|
|
3179
|
+
- After calling a tool, you will receive a response in the format: <tool_response><tool_name>NAME</tool_name><result>RESULT</result></tool_response>. Use this result to answer the user.
|
|
3180
|
+
|
|
3181
|
+
# Example
|
|
3182
|
+
<get_weather>
|
|
3183
|
+
<location>New York</location>
|
|
3184
|
+
<unit>celsius</unit>
|
|
3185
|
+
</get_weather>`;
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
// src/core/prompts/yaml-system-prompt.ts
|
|
3189
|
+
function yamlSystemPromptTemplate(tools, includeMultilineExample = true) {
|
|
3190
|
+
const toolsJson = JSON.stringify(tools);
|
|
3191
|
+
const multilineExample = includeMultilineExample ? `
|
|
3192
|
+
|
|
3193
|
+
For multiline values, use YAML's literal block syntax:
|
|
3194
|
+
<write_file>
|
|
3195
|
+
file_path: /tmp/example.txt
|
|
3196
|
+
contents: |
|
|
3197
|
+
First line
|
|
3198
|
+
Second line
|
|
3199
|
+
Third line
|
|
3200
|
+
</write_file>` : "";
|
|
3201
|
+
return `# Tools
|
|
3202
|
+
|
|
3203
|
+
You may call one or more functions to assist with the user query.
|
|
3204
|
+
|
|
3205
|
+
You are provided with function signatures within <tools></tools> XML tags:
|
|
3206
|
+
<tools>${toolsJson}</tools>
|
|
3207
|
+
|
|
3208
|
+
# Format
|
|
3209
|
+
|
|
3210
|
+
Use exactly one XML element whose tag name is the function name.
|
|
3211
|
+
Inside the XML element, specify parameters using YAML syntax (key: value pairs).
|
|
3212
|
+
|
|
3213
|
+
# Example
|
|
3214
|
+
<get_weather>
|
|
3215
|
+
location: New York
|
|
3216
|
+
unit: celsius
|
|
3217
|
+
</get_weather>${multilineExample}
|
|
3218
|
+
|
|
3219
|
+
# Rules
|
|
3220
|
+
- Parameter names and values must follow the schema exactly.
|
|
3221
|
+
- Use proper YAML syntax for values (strings, numbers, booleans, arrays, objects).
|
|
3222
|
+
- Each required parameter must appear once.
|
|
3223
|
+
- Do not add functions or parameters not in the schema.
|
|
3224
|
+
- After calling a tool, you will receive a response. Use this result to answer the user.
|
|
3225
|
+
- Do NOT ask clarifying questions. Use reasonable defaults for optional parameters.
|
|
3226
|
+
- If a task requires multiple function calls, make ALL of them at once.`;
|
|
3108
3227
|
}
|
|
3228
|
+
|
|
3229
|
+
// src/stream-handler.ts
|
|
3230
|
+
import { generateId as generateId3 } from "@ai-sdk/provider-utils";
|
|
3109
3231
|
async function wrapStream({
|
|
3110
3232
|
protocol,
|
|
3111
3233
|
doStream,
|
|
@@ -3129,23 +3251,24 @@ async function wrapStream({
|
|
|
3129
3251
|
...((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) || {}
|
|
3130
3252
|
};
|
|
3131
3253
|
const coreStream = stream.pipeThrough(
|
|
3132
|
-
new TransformStream(
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3254
|
+
new TransformStream(
|
|
3255
|
+
{
|
|
3256
|
+
transform(part, controller) {
|
|
3257
|
+
if (debugLevel === "stream") {
|
|
3258
|
+
logRawChunk(part);
|
|
3259
|
+
}
|
|
3260
|
+
controller.enqueue(part);
|
|
3136
3261
|
}
|
|
3137
|
-
controller.enqueue(mapV3PartToCore(part));
|
|
3138
3262
|
}
|
|
3139
|
-
|
|
3263
|
+
)
|
|
3140
3264
|
).pipeThrough(protocol.createStreamParser({ tools, options }));
|
|
3141
3265
|
const v3Stream = coreStream.pipeThrough(
|
|
3142
3266
|
new TransformStream({
|
|
3143
3267
|
transform(part, controller) {
|
|
3144
|
-
const v3Part = mapCorePartToV3(part);
|
|
3145
3268
|
if (debugLevel === "stream") {
|
|
3146
|
-
logParsedChunk(
|
|
3269
|
+
logParsedChunk(part);
|
|
3147
3270
|
}
|
|
3148
|
-
controller.enqueue(
|
|
3271
|
+
controller.enqueue(part);
|
|
3149
3272
|
}
|
|
3150
3273
|
})
|
|
3151
3274
|
);
|
|
@@ -3180,7 +3303,7 @@ async function toolChoiceStream({
|
|
|
3180
3303
|
start(controller) {
|
|
3181
3304
|
controller.enqueue({
|
|
3182
3305
|
type: "tool-call",
|
|
3183
|
-
toolCallId: (
|
|
3306
|
+
toolCallId: generateId3(),
|
|
3184
3307
|
toolName: toolJson.name || "unknown",
|
|
3185
3308
|
input: JSON.stringify(toolJson.arguments || {})
|
|
3186
3309
|
});
|
|
@@ -3202,70 +3325,7 @@ async function toolChoiceStream({
|
|
|
3202
3325
|
};
|
|
3203
3326
|
}
|
|
3204
3327
|
|
|
3205
|
-
// src/
|
|
3206
|
-
function createDynamicIfThenElseSchema(tools) {
|
|
3207
|
-
let currentSchema = {};
|
|
3208
|
-
const toolNames = [];
|
|
3209
|
-
for (let i = tools.length - 1; i >= 0; i -= 1) {
|
|
3210
|
-
const tool = tools[i];
|
|
3211
|
-
if (tool.type === "provider") {
|
|
3212
|
-
throw new Error(
|
|
3213
|
-
"Provider tools are not supported by this middleware. Please use function tools."
|
|
3214
|
-
);
|
|
3215
|
-
}
|
|
3216
|
-
toolNames.unshift(tool.name);
|
|
3217
|
-
const toolCondition = {
|
|
3218
|
-
if: {
|
|
3219
|
-
properties: {
|
|
3220
|
-
name: {
|
|
3221
|
-
const: tool.name
|
|
3222
|
-
}
|
|
3223
|
-
},
|
|
3224
|
-
required: ["name"]
|
|
3225
|
-
},
|
|
3226
|
-
// biome-ignore lint/suspicious/noThenProperty: JSON Schema uses 'then' as a keyword
|
|
3227
|
-
then: {
|
|
3228
|
-
properties: {
|
|
3229
|
-
name: {
|
|
3230
|
-
const: tool.name
|
|
3231
|
-
},
|
|
3232
|
-
arguments: tool.inputSchema
|
|
3233
|
-
},
|
|
3234
|
-
required: ["name", "arguments"]
|
|
3235
|
-
}
|
|
3236
|
-
};
|
|
3237
|
-
if (Object.keys(currentSchema).length > 0) {
|
|
3238
|
-
toolCondition.else = currentSchema;
|
|
3239
|
-
}
|
|
3240
|
-
currentSchema = toolCondition;
|
|
3241
|
-
}
|
|
3242
|
-
return {
|
|
3243
|
-
type: "object",
|
|
3244
|
-
// Explicitly specify type as "object"
|
|
3245
|
-
properties: {
|
|
3246
|
-
name: {
|
|
3247
|
-
type: "string",
|
|
3248
|
-
description: "Name of the tool to call",
|
|
3249
|
-
enum: toolNames
|
|
3250
|
-
},
|
|
3251
|
-
arguments: {
|
|
3252
|
-
type: "object",
|
|
3253
|
-
// By default, arguments is also specified as object type
|
|
3254
|
-
description: "Argument object to be passed to the tool"
|
|
3255
|
-
}
|
|
3256
|
-
},
|
|
3257
|
-
required: ["name", "arguments"],
|
|
3258
|
-
...currentSchema
|
|
3259
|
-
};
|
|
3260
|
-
}
|
|
3261
|
-
|
|
3262
|
-
// src/core/utils/type-guards.ts
|
|
3263
|
-
function isToolCallContent(content) {
|
|
3264
|
-
return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
|
|
3265
|
-
(typeof content.input === "string" || typeof content.input === "object");
|
|
3266
|
-
}
|
|
3267
|
-
|
|
3268
|
-
// src/v6/transform-handler.ts
|
|
3328
|
+
// src/transform-handler.ts
|
|
3269
3329
|
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
3270
3330
|
const systemIndex = processedPrompt.findIndex((m) => m.role === "system");
|
|
3271
3331
|
if (systemIndex !== -1) {
|
|
@@ -3408,10 +3468,11 @@ function transformParams({
|
|
|
3408
3468
|
params,
|
|
3409
3469
|
protocol,
|
|
3410
3470
|
toolSystemPromptTemplate,
|
|
3471
|
+
toolResponsePromptTemplate,
|
|
3411
3472
|
placement = "first"
|
|
3412
3473
|
}) {
|
|
3413
|
-
var _a, _b, _c, _d
|
|
3414
|
-
const resolvedProtocol =
|
|
3474
|
+
var _a, _b, _c, _d;
|
|
3475
|
+
const resolvedProtocol = isTCMProtocolFactory(protocol) ? protocol() : protocol;
|
|
3415
3476
|
const functionTools = ((_a = params.tools) != null ? _a : []).filter(
|
|
3416
3477
|
(t) => t.type === "function"
|
|
3417
3478
|
);
|
|
@@ -3419,9 +3480,18 @@ function transformParams({
|
|
|
3419
3480
|
tools: functionTools,
|
|
3420
3481
|
toolSystemPromptTemplate
|
|
3421
3482
|
});
|
|
3483
|
+
let normalizedPrompt;
|
|
3484
|
+
if (Array.isArray(params.prompt)) {
|
|
3485
|
+
normalizedPrompt = params.prompt;
|
|
3486
|
+
} else if (params.prompt) {
|
|
3487
|
+
normalizedPrompt = [params.prompt];
|
|
3488
|
+
} else {
|
|
3489
|
+
normalizedPrompt = [];
|
|
3490
|
+
}
|
|
3422
3491
|
const processedPrompt = convertToolPrompt(
|
|
3423
|
-
|
|
3492
|
+
normalizedPrompt,
|
|
3424
3493
|
resolvedProtocol,
|
|
3494
|
+
toolResponsePromptTemplate,
|
|
3425
3495
|
extractOnErrorOption(params.providerOptions)
|
|
3426
3496
|
);
|
|
3427
3497
|
const finalPrompt = buildFinalPrompt(
|
|
@@ -3434,15 +3504,15 @@ function transformParams({
|
|
|
3434
3504
|
finalPrompt,
|
|
3435
3505
|
functionTools
|
|
3436
3506
|
);
|
|
3437
|
-
if (((
|
|
3507
|
+
if (((_b = params.toolChoice) == null ? void 0 : _b.type) === "none") {
|
|
3438
3508
|
throw new Error(
|
|
3439
3509
|
"The 'none' toolChoice type is not supported by this middleware. Please use 'auto', 'required', or specify a tool name."
|
|
3440
3510
|
);
|
|
3441
3511
|
}
|
|
3442
|
-
if (((
|
|
3512
|
+
if (((_c = params.toolChoice) == null ? void 0 : _c.type) === "tool") {
|
|
3443
3513
|
return handleToolChoiceTool(params, baseReturnParams);
|
|
3444
3514
|
}
|
|
3445
|
-
if (((
|
|
3515
|
+
if (((_d = params.toolChoice) == null ? void 0 : _d.type) === "required") {
|
|
3446
3516
|
return handleToolChoiceRequired(params, baseReturnParams, functionTools);
|
|
3447
3517
|
}
|
|
3448
3518
|
return baseReturnParams;
|
|
@@ -3481,25 +3551,28 @@ function processAssistantContent(content, resolvedProtocol, providerOptions) {
|
|
|
3481
3551
|
}
|
|
3482
3552
|
] : newContent;
|
|
3483
3553
|
}
|
|
3484
|
-
function
|
|
3554
|
+
function formatApprovalResponse(part) {
|
|
3555
|
+
const status = part.approved ? "Approved" : "Denied";
|
|
3556
|
+
const reason = part.reason ? `: ${part.reason}` : "";
|
|
3557
|
+
return `[Tool Approval ${status}${reason}]`;
|
|
3558
|
+
}
|
|
3559
|
+
function processToolMessage(toolResults, approvalResponses, toolResponsePromptTemplate) {
|
|
3560
|
+
const resultTexts = toolResults.map((toolResult) => {
|
|
3561
|
+
return toolResponsePromptTemplate(toolResult);
|
|
3562
|
+
});
|
|
3563
|
+
const approvalTexts = approvalResponses.map(formatApprovalResponse);
|
|
3564
|
+
const allTexts = [...resultTexts, ...approvalTexts];
|
|
3485
3565
|
return {
|
|
3486
3566
|
role: "user",
|
|
3487
3567
|
content: [
|
|
3488
3568
|
{
|
|
3489
3569
|
type: "text",
|
|
3490
|
-
text:
|
|
3491
|
-
var _a, _b;
|
|
3492
|
-
const tr = toolResult;
|
|
3493
|
-
return resolvedProtocol.formatToolResponse({
|
|
3494
|
-
...toolResult,
|
|
3495
|
-
result: (_b = (_a = tr.result) != null ? _a : tr.content) != null ? _b : tr.output
|
|
3496
|
-
});
|
|
3497
|
-
}).join("\n")
|
|
3570
|
+
text: allTexts.join("\n")
|
|
3498
3571
|
}
|
|
3499
3572
|
]
|
|
3500
3573
|
};
|
|
3501
3574
|
}
|
|
3502
|
-
function processMessage(message, resolvedProtocol, providerOptions) {
|
|
3575
|
+
function processMessage(message, resolvedProtocol, providerOptions, toolResponsePromptTemplate) {
|
|
3503
3576
|
if (message.role === "assistant") {
|
|
3504
3577
|
const condensedContent = processAssistantContent(
|
|
3505
3578
|
message.content,
|
|
@@ -3512,10 +3585,23 @@ function processMessage(message, resolvedProtocol, providerOptions) {
|
|
|
3512
3585
|
};
|
|
3513
3586
|
}
|
|
3514
3587
|
if (message.role === "tool") {
|
|
3515
|
-
const
|
|
3588
|
+
const toolContent = message.content;
|
|
3589
|
+
const toolResultParts = toolContent.filter(
|
|
3516
3590
|
(part) => part.type === "tool-result"
|
|
3517
3591
|
);
|
|
3518
|
-
|
|
3592
|
+
const approvalResponseParts = toolContent.filter(
|
|
3593
|
+
(part) => part.type === "tool-approval-response"
|
|
3594
|
+
);
|
|
3595
|
+
if (!toolResponsePromptTemplate) {
|
|
3596
|
+
throw new Error(
|
|
3597
|
+
'toolResponsePromptTemplate is required when processing messages with role "tool". This parameter is optional for other roles but is required here so tool-result content can be converted into a prompt. Ensure your middleware or transform configuration passes a toolResponsePromptTemplate when tool message processing is enabled.'
|
|
3598
|
+
);
|
|
3599
|
+
}
|
|
3600
|
+
return processToolMessage(
|
|
3601
|
+
toolResultParts,
|
|
3602
|
+
approvalResponseParts,
|
|
3603
|
+
toolResponsePromptTemplate
|
|
3604
|
+
);
|
|
3519
3605
|
}
|
|
3520
3606
|
return message;
|
|
3521
3607
|
}
|
|
@@ -3578,22 +3664,28 @@ ${currentContent}` }]
|
|
|
3578
3664
|
}
|
|
3579
3665
|
return processedPrompt;
|
|
3580
3666
|
}
|
|
3581
|
-
function convertToolPrompt(prompt, resolvedProtocol, providerOptions) {
|
|
3667
|
+
function convertToolPrompt(prompt, resolvedProtocol, toolResponsePromptTemplate, providerOptions) {
|
|
3582
3668
|
let processedPrompt = prompt.map(
|
|
3583
|
-
(message) => processMessage(
|
|
3669
|
+
(message) => processMessage(
|
|
3670
|
+
message,
|
|
3671
|
+
resolvedProtocol,
|
|
3672
|
+
providerOptions,
|
|
3673
|
+
toolResponsePromptTemplate
|
|
3674
|
+
)
|
|
3584
3675
|
);
|
|
3585
3676
|
processedPrompt = condenseTextContent(processedPrompt);
|
|
3586
3677
|
processedPrompt = mergeConsecutiveUserMessages(processedPrompt);
|
|
3587
3678
|
return processedPrompt;
|
|
3588
3679
|
}
|
|
3589
3680
|
|
|
3590
|
-
// src/
|
|
3681
|
+
// src/tool-call-middleware.ts
|
|
3591
3682
|
function createToolMiddleware({
|
|
3592
3683
|
protocol,
|
|
3593
3684
|
toolSystemPromptTemplate,
|
|
3685
|
+
toolResponsePromptTemplate,
|
|
3594
3686
|
placement = "last"
|
|
3595
3687
|
}) {
|
|
3596
|
-
const resolvedProtocol =
|
|
3688
|
+
const resolvedProtocol = isTCMProtocolFactory(protocol) ? protocol() : protocol;
|
|
3597
3689
|
return {
|
|
3598
3690
|
specificationVersion: "v3",
|
|
3599
3691
|
wrapStream: ({ doStream, doGenerate, params }) => {
|
|
@@ -3618,83 +3710,72 @@ function createToolMiddleware({
|
|
|
3618
3710
|
transformParams: async ({ params }) => transformParams({
|
|
3619
3711
|
protocol: resolvedProtocol,
|
|
3620
3712
|
toolSystemPromptTemplate,
|
|
3713
|
+
toolResponsePromptTemplate,
|
|
3621
3714
|
placement,
|
|
3622
3715
|
params
|
|
3623
3716
|
})
|
|
3624
3717
|
};
|
|
3625
3718
|
}
|
|
3626
3719
|
|
|
3627
|
-
// src/
|
|
3628
|
-
var gemmaToolMiddleware = createToolMiddleware({
|
|
3629
|
-
protocol: jsonMixProtocol({
|
|
3630
|
-
toolCallStart: "```tool_call\n",
|
|
3631
|
-
toolCallEnd: "\n```",
|
|
3632
|
-
toolResponseStart: "```tool_response\n",
|
|
3633
|
-
toolResponseEnd: "\n```"
|
|
3634
|
-
}),
|
|
3635
|
-
toolSystemPromptTemplate(tools) {
|
|
3636
|
-
return `You have access to functions. If you decide to invoke any of the function(s),
|
|
3637
|
-
you MUST put it in the format of markdown code fence block with the language name of tool_call , e.g.
|
|
3638
|
-
\`\`\`tool_call
|
|
3639
|
-
{'name': <function-name>, 'arguments': <args-dict>}
|
|
3640
|
-
\`\`\`
|
|
3641
|
-
You SHOULD NOT include any other text in the response if you call a function
|
|
3642
|
-
${tools}`;
|
|
3643
|
-
}
|
|
3644
|
-
});
|
|
3720
|
+
// src/preconfigured-middleware.ts
|
|
3645
3721
|
var hermesToolMiddleware = createToolMiddleware({
|
|
3646
|
-
protocol:
|
|
3647
|
-
toolSystemPromptTemplate
|
|
3648
|
-
|
|
3649
|
-
You are provided with function signatures within <tools></tools> XML tags.
|
|
3650
|
-
You may call one or more functions to assist with the user query.
|
|
3651
|
-
Don't make assumptions about what values to plug into functions.
|
|
3652
|
-
Here are the available tools: <tools>${tools}</tools>
|
|
3653
|
-
Use the following pydantic model json schema for each tool call you will make: {"title": "FunctionCall", "type": "object", "properties": {"arguments": {"title": "Arguments", "type": "object"}, "name": {"title": "Name", "type": "string"}}, "required": ["arguments", "name"]}
|
|
3654
|
-
For each function call return a json object with function name and arguments within <tool_call></tool_call> XML tags as follows:
|
|
3655
|
-
<tool_call>
|
|
3656
|
-
{"name": "<function-name>", "arguments": <args-dict>}
|
|
3657
|
-
</tool_call>`;
|
|
3658
|
-
}
|
|
3722
|
+
protocol: jsonProtocol({}),
|
|
3723
|
+
toolSystemPromptTemplate: hermesSystemPromptTemplate,
|
|
3724
|
+
toolResponsePromptTemplate: formatToolResponseAsJsonInXml
|
|
3659
3725
|
});
|
|
3660
|
-
var
|
|
3661
|
-
protocol:
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
return `# Tools
|
|
3665
|
-
|
|
3666
|
-
You may call one or more functions to assist with the user query.
|
|
3667
|
-
|
|
3668
|
-
You are provided with function signatures within <tools></tools> XML tags:
|
|
3669
|
-
<tools>${tools}</tools>
|
|
3670
|
-
|
|
3671
|
-
# Rules
|
|
3672
|
-
- Use exactly one XML element whose tag name is the function name.
|
|
3673
|
-
- Put each parameter as a child element.
|
|
3674
|
-
- Values must follow the schema exactly (numbers, arrays, objects, enums \u2192 copy as-is).
|
|
3675
|
-
- Do not add or remove functions or parameters.
|
|
3676
|
-
- Each required parameter must appear once.
|
|
3677
|
-
- Output nothing before or after the function call.
|
|
3678
|
-
- After calling a tool, you will receive a response in the format: <tool_response><tool_name>NAME</tool_name><result>RESULT</result></tool_response>. Use this result to answer the user.
|
|
3679
|
-
|
|
3680
|
-
# Example
|
|
3681
|
-
<get_weather>
|
|
3682
|
-
<location>New York</location>
|
|
3683
|
-
<unit>celsius</unit>
|
|
3684
|
-
</get_weather>`;
|
|
3685
|
-
}
|
|
3726
|
+
var xmlToolMiddleware = createToolMiddleware({
|
|
3727
|
+
protocol: xmlProtocol({}),
|
|
3728
|
+
toolSystemPromptTemplate: xmlSystemPromptTemplate,
|
|
3729
|
+
toolResponsePromptTemplate: formatToolResponseAsXml
|
|
3686
3730
|
});
|
|
3687
|
-
var
|
|
3688
|
-
protocol:
|
|
3689
|
-
|
|
3690
|
-
|
|
3731
|
+
var yamlToolMiddleware = createToolMiddleware({
|
|
3732
|
+
protocol: yamlProtocol({}),
|
|
3733
|
+
toolSystemPromptTemplate: yamlSystemPromptTemplate,
|
|
3734
|
+
toolResponsePromptTemplate: formatToolResponseAsXml
|
|
3691
3735
|
});
|
|
3692
|
-
|
|
3693
|
-
|
|
3736
|
+
|
|
3737
|
+
export {
|
|
3738
|
+
applyHeuristicPipeline,
|
|
3739
|
+
createIntermediateCall,
|
|
3740
|
+
mergePipelineConfigs,
|
|
3741
|
+
normalizeCloseTagsHeuristic,
|
|
3742
|
+
escapeInvalidLtHeuristic,
|
|
3743
|
+
balanceTagsHeuristic,
|
|
3744
|
+
dedupeShellStringTagsHeuristic,
|
|
3745
|
+
repairAgainstSchemaHeuristic,
|
|
3746
|
+
defaultPipelineConfig,
|
|
3747
|
+
getDebugLevel,
|
|
3748
|
+
logParseFailure,
|
|
3749
|
+
logRawChunk,
|
|
3750
|
+
logParsedChunk,
|
|
3751
|
+
logParsedSummary,
|
|
3752
|
+
getPotentialStartIndex,
|
|
3753
|
+
escapeRegExp2 as escapeRegExp,
|
|
3754
|
+
transform,
|
|
3755
|
+
parse2 as parse,
|
|
3756
|
+
stringify,
|
|
3757
|
+
jsonProtocol,
|
|
3758
|
+
isProtocolFactory,
|
|
3759
|
+
isTCMProtocolFactory,
|
|
3760
|
+
xmlProtocol,
|
|
3761
|
+
yamlProtocol,
|
|
3762
|
+
createDynamicIfThenElseSchema,
|
|
3763
|
+
extractOnErrorOption,
|
|
3764
|
+
originalToolsSchema,
|
|
3765
|
+
encodeOriginalTools,
|
|
3766
|
+
decodeOriginalTools,
|
|
3767
|
+
extractToolNamesFromOriginalTools,
|
|
3768
|
+
isToolChoiceActive,
|
|
3769
|
+
isToolCallContent,
|
|
3770
|
+
isToolResultPart,
|
|
3771
|
+
hasInputProperty,
|
|
3772
|
+
wrapGenerate,
|
|
3773
|
+
wrapStream,
|
|
3774
|
+
toolChoiceStream,
|
|
3775
|
+
transformParams,
|
|
3694
3776
|
createToolMiddleware,
|
|
3695
|
-
gemmaToolMiddleware,
|
|
3696
3777
|
hermesToolMiddleware,
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
}
|
|
3700
|
-
//# sourceMappingURL=
|
|
3778
|
+
xmlToolMiddleware,
|
|
3779
|
+
yamlToolMiddleware
|
|
3780
|
+
};
|
|
3781
|
+
//# sourceMappingURL=chunk-JVQVEA3K.js.map
|