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