@ai-sdk-tool/parser 3.1.3 → 3.2.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/dist/{chunk-3KQVEBKO.js → chunk-DCK5APVO.js} +499 -738
- package/dist/chunk-DCK5APVO.js.map +1 -0
- package/dist/community.cjs +500 -739
- package/dist/community.cjs.map +1 -1
- package/dist/community.js +1 -1
- package/dist/index.cjs +500 -748
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -64
- package/dist/index.d.ts +8 -64
- package/dist/index.js +1 -19
- package/package.json +5 -3
- package/dist/chunk-3KQVEBKO.js.map +0 -1
package/dist/community.cjs
CHANGED
|
@@ -39,17 +39,11 @@ module.exports = __toCommonJS(community_exports);
|
|
|
39
39
|
// src/index.ts
|
|
40
40
|
var src_exports = {};
|
|
41
41
|
__export(src_exports, {
|
|
42
|
-
applyHeuristicPipeline: () => applyHeuristicPipeline,
|
|
43
|
-
balanceTagsHeuristic: () => balanceTagsHeuristic,
|
|
44
42
|
createDynamicIfThenElseSchema: () => createDynamicIfThenElseSchema,
|
|
45
|
-
createIntermediateCall: () => createIntermediateCall,
|
|
46
43
|
createToolMiddleware: () => createToolMiddleware,
|
|
47
44
|
decodeOriginalTools: () => decodeOriginalTools,
|
|
48
|
-
dedupeShellStringTagsHeuristic: () => dedupeShellStringTagsHeuristic,
|
|
49
|
-
defaultPipelineConfig: () => defaultPipelineConfig,
|
|
50
45
|
encodeOriginalTools: () => encodeOriginalTools,
|
|
51
|
-
|
|
52
|
-
escapeRegExp: () => escapeRegExp2,
|
|
46
|
+
escapeRegExp: () => escapeRegExp,
|
|
53
47
|
extractOnErrorOption: () => extractOnErrorOption,
|
|
54
48
|
extractToolNamesFromOriginalTools: () => extractToolNamesFromOriginalTools,
|
|
55
49
|
getDebugLevel: () => getDebugLevel,
|
|
@@ -65,10 +59,7 @@ __export(src_exports, {
|
|
|
65
59
|
logParsedChunk: () => logParsedChunk,
|
|
66
60
|
logParsedSummary: () => logParsedSummary,
|
|
67
61
|
logRawChunk: () => logRawChunk,
|
|
68
|
-
mergePipelineConfigs: () => mergePipelineConfigs,
|
|
69
|
-
normalizeCloseTagsHeuristic: () => normalizeCloseTagsHeuristic,
|
|
70
62
|
originalToolsSchema: () => originalToolsSchema,
|
|
71
|
-
repairAgainstSchemaHeuristic: () => repairAgainstSchemaHeuristic,
|
|
72
63
|
toolChoiceStream: () => toolChoiceStream,
|
|
73
64
|
transformParams: () => transformParams,
|
|
74
65
|
wrapGenerate: () => wrapGenerate,
|
|
@@ -80,473 +71,6 @@ __export(src_exports, {
|
|
|
80
71
|
});
|
|
81
72
|
__reExport(src_exports, require("@ai-sdk-tool/rjson"));
|
|
82
73
|
|
|
83
|
-
// src/core/heuristics/engine.ts
|
|
84
|
-
function applyRawSegmentUpdate(current, result) {
|
|
85
|
-
if (result.rawSegment !== void 0) {
|
|
86
|
-
return { ...current, rawSegment: result.rawSegment };
|
|
87
|
-
}
|
|
88
|
-
return current;
|
|
89
|
-
}
|
|
90
|
-
function applyParsedUpdate(current, result) {
|
|
91
|
-
if (result.parsed !== void 0) {
|
|
92
|
-
return { ...current, parsed: result.parsed };
|
|
93
|
-
}
|
|
94
|
-
return current;
|
|
95
|
-
}
|
|
96
|
-
function applyWarningsUpdate(current, result) {
|
|
97
|
-
var _a, _b;
|
|
98
|
-
if (result.warnings && result.warnings.length > 0) {
|
|
99
|
-
const meta = (_a = current.meta) != null ? _a : {};
|
|
100
|
-
const existingWarnings = (_b = meta.warnings) != null ? _b : [];
|
|
101
|
-
return {
|
|
102
|
-
...current,
|
|
103
|
-
meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
return current;
|
|
107
|
-
}
|
|
108
|
-
function attemptReparse(current, result, reparseCount, maxReparses, parse3) {
|
|
109
|
-
if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
|
|
110
|
-
return { state: current, newCount: reparseCount };
|
|
111
|
-
}
|
|
112
|
-
try {
|
|
113
|
-
const reparsed = parse3(result.rawSegment, current.schema);
|
|
114
|
-
return {
|
|
115
|
-
state: { ...current, parsed: reparsed, errors: [] },
|
|
116
|
-
newCount: reparseCount + 1
|
|
117
|
-
};
|
|
118
|
-
} catch (error) {
|
|
119
|
-
return {
|
|
120
|
-
state: { ...current, errors: [...current.errors, error] },
|
|
121
|
-
newCount: reparseCount + 1
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
function executePhase(ctx, heuristics, options) {
|
|
126
|
-
var _a;
|
|
127
|
-
let current = ctx;
|
|
128
|
-
let reparseCount = 0;
|
|
129
|
-
const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
|
|
130
|
-
for (const heuristic of heuristics) {
|
|
131
|
-
if (!heuristic.applies(current)) {
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
const result = heuristic.run(current);
|
|
135
|
-
current = applyRawSegmentUpdate(current, result);
|
|
136
|
-
current = applyParsedUpdate(current, result);
|
|
137
|
-
current = applyWarningsUpdate(current, result);
|
|
138
|
-
const reparseResult = attemptReparse(
|
|
139
|
-
current,
|
|
140
|
-
result,
|
|
141
|
-
reparseCount,
|
|
142
|
-
maxReparses,
|
|
143
|
-
options.parse
|
|
144
|
-
);
|
|
145
|
-
current = reparseResult.state;
|
|
146
|
-
reparseCount = reparseResult.newCount;
|
|
147
|
-
if (result.stop) {
|
|
148
|
-
break;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return current;
|
|
152
|
-
}
|
|
153
|
-
function applyHeuristicPipeline(ctx, config, options) {
|
|
154
|
-
let current = ctx;
|
|
155
|
-
if (config.preParse && config.preParse.length > 0) {
|
|
156
|
-
current = executePhase(current, config.preParse, options);
|
|
157
|
-
}
|
|
158
|
-
if (current.parsed === null && current.errors.length === 0) {
|
|
159
|
-
try {
|
|
160
|
-
const parsed = options.parse(current.rawSegment, current.schema);
|
|
161
|
-
current = { ...current, parsed, errors: [] };
|
|
162
|
-
} catch (error) {
|
|
163
|
-
current = { ...current, errors: [error] };
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
|
|
167
|
-
current = executePhase(current, config.fallbackReparse, options);
|
|
168
|
-
}
|
|
169
|
-
if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
|
|
170
|
-
current = executePhase(current, config.postParse, options);
|
|
171
|
-
}
|
|
172
|
-
return current;
|
|
173
|
-
}
|
|
174
|
-
function createIntermediateCall(toolName, rawSegment, schema) {
|
|
175
|
-
return {
|
|
176
|
-
toolName,
|
|
177
|
-
schema,
|
|
178
|
-
rawSegment,
|
|
179
|
-
parsed: null,
|
|
180
|
-
errors: [],
|
|
181
|
-
meta: { originalContent: rawSegment }
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
function mergePipelineConfigs(...configs) {
|
|
185
|
-
var _a, _b, _c;
|
|
186
|
-
const result = {
|
|
187
|
-
preParse: [],
|
|
188
|
-
fallbackReparse: [],
|
|
189
|
-
postParse: []
|
|
190
|
-
};
|
|
191
|
-
for (const config of configs) {
|
|
192
|
-
if (config.preParse) {
|
|
193
|
-
result.preParse = [...(_a = result.preParse) != null ? _a : [], ...config.preParse];
|
|
194
|
-
}
|
|
195
|
-
if (config.fallbackReparse) {
|
|
196
|
-
result.fallbackReparse = [
|
|
197
|
-
...(_b = result.fallbackReparse) != null ? _b : [],
|
|
198
|
-
...config.fallbackReparse
|
|
199
|
-
];
|
|
200
|
-
}
|
|
201
|
-
if (config.postParse) {
|
|
202
|
-
result.postParse = [...(_c = result.postParse) != null ? _c : [], ...config.postParse];
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return result;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// src/core/heuristics/xml-defaults.ts
|
|
209
|
-
var import_rxml = require("@ai-sdk-tool/rxml");
|
|
210
|
-
var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
211
|
-
var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
212
|
-
var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
|
|
213
|
-
var WHITESPACE_REGEX = /\s/;
|
|
214
|
-
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
215
|
-
var NAME_START_CHAR_RE = /[A-Za-z_:]/;
|
|
216
|
-
var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
|
|
217
|
-
var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
|
|
218
|
-
var normalizeCloseTagsHeuristic = {
|
|
219
|
-
id: "normalize-close-tags",
|
|
220
|
-
phase: "pre-parse",
|
|
221
|
-
applies: () => true,
|
|
222
|
-
run: (ctx) => {
|
|
223
|
-
const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
|
|
224
|
-
if (normalized !== ctx.rawSegment) {
|
|
225
|
-
return { rawSegment: normalized };
|
|
226
|
-
}
|
|
227
|
-
return {};
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
var escapeInvalidLtHeuristic = {
|
|
231
|
-
id: "escape-invalid-lt",
|
|
232
|
-
phase: "pre-parse",
|
|
233
|
-
applies: () => true,
|
|
234
|
-
run: (ctx) => {
|
|
235
|
-
const escaped = escapeInvalidLt(ctx.rawSegment);
|
|
236
|
-
if (escaped !== ctx.rawSegment) {
|
|
237
|
-
return { rawSegment: escaped };
|
|
238
|
-
}
|
|
239
|
-
return {};
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
var balanceTagsHeuristic = {
|
|
243
|
-
id: "balance-tags",
|
|
244
|
-
phase: "fallback-reparse",
|
|
245
|
-
applies: (ctx) => {
|
|
246
|
-
var _a;
|
|
247
|
-
const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
|
|
248
|
-
const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
|
|
249
|
-
const balanced = balanceTags(original);
|
|
250
|
-
const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
|
|
251
|
-
if (!hasMalformedClose && balanced.length > normalized.length) {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
return balanced !== normalized;
|
|
255
|
-
},
|
|
256
|
-
run: (ctx) => {
|
|
257
|
-
var _a;
|
|
258
|
-
const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
|
|
259
|
-
const balanced = balanceTags(original);
|
|
260
|
-
const escaped = escapeInvalidLt(balanced);
|
|
261
|
-
return { rawSegment: escaped, reparse: true };
|
|
262
|
-
}
|
|
263
|
-
};
|
|
264
|
-
var dedupeShellStringTagsHeuristic = {
|
|
265
|
-
id: "dedupe-shell-string-tags",
|
|
266
|
-
phase: "fallback-reparse",
|
|
267
|
-
applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
|
|
268
|
-
run: (ctx) => {
|
|
269
|
-
const names = getStringPropertyNames(ctx.schema);
|
|
270
|
-
let deduped = ctx.rawSegment;
|
|
271
|
-
for (const key of names) {
|
|
272
|
-
deduped = dedupeSingleTag(deduped, key);
|
|
273
|
-
}
|
|
274
|
-
if (deduped !== ctx.rawSegment) {
|
|
275
|
-
return { rawSegment: deduped, reparse: true };
|
|
276
|
-
}
|
|
277
|
-
return {};
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
var repairAgainstSchemaHeuristic = {
|
|
281
|
-
id: "repair-against-schema",
|
|
282
|
-
phase: "post-parse",
|
|
283
|
-
applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
|
|
284
|
-
run: (ctx) => {
|
|
285
|
-
const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
|
|
286
|
-
if (repaired !== ctx.parsed) {
|
|
287
|
-
return { parsed: repaired };
|
|
288
|
-
}
|
|
289
|
-
return {};
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
var defaultPipelineConfig = {
|
|
293
|
-
preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
|
|
294
|
-
fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
|
|
295
|
-
postParse: [repairAgainstSchemaHeuristic]
|
|
296
|
-
};
|
|
297
|
-
var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
|
|
298
|
-
function isIndexTagAt(xml, pos) {
|
|
299
|
-
const remaining = xml.slice(pos);
|
|
300
|
-
return INDEX_TAG_RE.test(remaining);
|
|
301
|
-
}
|
|
302
|
-
function escapeInvalidLt(xml) {
|
|
303
|
-
const len = xml.length;
|
|
304
|
-
let out = "";
|
|
305
|
-
for (let i = 0; i < len; i += 1) {
|
|
306
|
-
const ch = xml[i];
|
|
307
|
-
if (ch === "<") {
|
|
308
|
-
const next = i + 1 < len ? xml[i + 1] : "";
|
|
309
|
-
const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
|
|
310
|
-
const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
|
|
311
|
-
if (!(isValidStart || isIndexTag)) {
|
|
312
|
-
out += "<";
|
|
313
|
-
continue;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
out += ch;
|
|
317
|
-
}
|
|
318
|
-
return out;
|
|
319
|
-
}
|
|
320
|
-
function balanceTags(xml) {
|
|
321
|
-
const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
|
|
322
|
-
let i = 0;
|
|
323
|
-
const len = src.length;
|
|
324
|
-
const out = [];
|
|
325
|
-
const stack = [];
|
|
326
|
-
while (i < len) {
|
|
327
|
-
const lt = src.indexOf("<", i);
|
|
328
|
-
if (lt === -1) {
|
|
329
|
-
out.push(src.slice(i));
|
|
330
|
-
break;
|
|
331
|
-
}
|
|
332
|
-
out.push(src.slice(i, lt));
|
|
333
|
-
if (lt + 1 >= len) {
|
|
334
|
-
break;
|
|
335
|
-
}
|
|
336
|
-
const next = src[lt + 1];
|
|
337
|
-
if (next === "!" || next === "?") {
|
|
338
|
-
i = handleSpecialTagSegment(src, lt, out);
|
|
339
|
-
continue;
|
|
340
|
-
}
|
|
341
|
-
if (next === "/") {
|
|
342
|
-
i = handleClosingTagSegment(src, lt, out, stack);
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
i = handleOpeningTagSegment(src, lt, out, stack);
|
|
346
|
-
}
|
|
347
|
-
for (let k = stack.length - 1; k >= 0; k -= 1) {
|
|
348
|
-
out.push(`</${stack[k]}>`);
|
|
349
|
-
}
|
|
350
|
-
return out.join("");
|
|
351
|
-
}
|
|
352
|
-
function skipWs(s, p, len) {
|
|
353
|
-
let idx = p;
|
|
354
|
-
while (idx < len && WHITESPACE_REGEX.test(s[idx])) {
|
|
355
|
-
idx += 1;
|
|
356
|
-
}
|
|
357
|
-
return idx;
|
|
358
|
-
}
|
|
359
|
-
function parseTagNameAt(s, p, len) {
|
|
360
|
-
let idx = p;
|
|
361
|
-
const start = idx;
|
|
362
|
-
while (idx < len && NAME_CHAR_RE.test(s[idx])) {
|
|
363
|
-
idx += 1;
|
|
364
|
-
}
|
|
365
|
-
return { name: s.slice(start, idx), pos: idx };
|
|
366
|
-
}
|
|
367
|
-
function handleSpecialTagSegment(src, lt, out) {
|
|
368
|
-
const gt = src.indexOf(">", lt + 1);
|
|
369
|
-
if (gt === -1) {
|
|
370
|
-
out.push(src.slice(lt));
|
|
371
|
-
return src.length;
|
|
372
|
-
}
|
|
373
|
-
out.push(src.slice(lt, gt + 1));
|
|
374
|
-
return gt + 1;
|
|
375
|
-
}
|
|
376
|
-
function handleClosingTagSegment(src, lt, out, stack) {
|
|
377
|
-
const len = src.length;
|
|
378
|
-
let p = skipWs(src, lt + 2, len);
|
|
379
|
-
const { name, pos } = parseTagNameAt(src, p, len);
|
|
380
|
-
p = pos;
|
|
381
|
-
const gt = src.indexOf(">", p);
|
|
382
|
-
const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
|
|
383
|
-
const idx = stack.lastIndexOf(name);
|
|
384
|
-
if (idx !== -1) {
|
|
385
|
-
for (let k = stack.length - 1; k > idx; k -= 1) {
|
|
386
|
-
out.push(`</${stack[k]}>`);
|
|
387
|
-
stack.pop();
|
|
388
|
-
}
|
|
389
|
-
out.push(closingText);
|
|
390
|
-
stack.pop();
|
|
391
|
-
}
|
|
392
|
-
return gt === -1 ? len : gt + 1;
|
|
393
|
-
}
|
|
394
|
-
function handleOpeningTagSegment(src, lt, out, stack) {
|
|
395
|
-
const len = src.length;
|
|
396
|
-
let p = skipWs(src, lt + 1, len);
|
|
397
|
-
const nameStart = p;
|
|
398
|
-
const parsed = parseTagNameAt(src, p, len);
|
|
399
|
-
p = parsed.pos;
|
|
400
|
-
const name = src.slice(nameStart, p);
|
|
401
|
-
const q = src.indexOf(">", p);
|
|
402
|
-
if (q === -1) {
|
|
403
|
-
out.push(src.slice(lt));
|
|
404
|
-
return len;
|
|
405
|
-
}
|
|
406
|
-
let r = q - 1;
|
|
407
|
-
while (r >= nameStart && WHITESPACE_REGEX.test(src[r])) {
|
|
408
|
-
r -= 1;
|
|
409
|
-
}
|
|
410
|
-
const selfClosing = src[r] === "/";
|
|
411
|
-
out.push(src.slice(lt, q + 1));
|
|
412
|
-
if (!selfClosing && name) {
|
|
413
|
-
stack.push(name);
|
|
414
|
-
}
|
|
415
|
-
return q + 1;
|
|
416
|
-
}
|
|
417
|
-
function extractSchemaProperties(schema) {
|
|
418
|
-
const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
|
|
419
|
-
if (!unwrapped || typeof unwrapped !== "object") {
|
|
420
|
-
return void 0;
|
|
421
|
-
}
|
|
422
|
-
return unwrapped.properties;
|
|
423
|
-
}
|
|
424
|
-
function shouldDeduplicateStringTags(schema) {
|
|
425
|
-
const props = extractSchemaProperties(schema);
|
|
426
|
-
if (!props) {
|
|
427
|
-
return false;
|
|
428
|
-
}
|
|
429
|
-
const commandRaw = props.command;
|
|
430
|
-
if (!commandRaw) {
|
|
431
|
-
return false;
|
|
432
|
-
}
|
|
433
|
-
const command = (0, import_rxml.unwrapJsonSchema)(commandRaw);
|
|
434
|
-
return (command == null ? void 0 : command.type) === "array";
|
|
435
|
-
}
|
|
436
|
-
function getStringPropertyNames(schema) {
|
|
437
|
-
const props = extractSchemaProperties(schema);
|
|
438
|
-
if (!props) {
|
|
439
|
-
return [];
|
|
440
|
-
}
|
|
441
|
-
const names = [];
|
|
442
|
-
for (const key of Object.keys(props)) {
|
|
443
|
-
const prop = (0, import_rxml.unwrapJsonSchema)(props[key]);
|
|
444
|
-
if ((prop == null ? void 0 : prop.type) === "string") {
|
|
445
|
-
names.push(key);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
return names;
|
|
449
|
-
}
|
|
450
|
-
function escapeRegExp(s) {
|
|
451
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
452
|
-
}
|
|
453
|
-
function dedupeSingleTag(xml, key) {
|
|
454
|
-
var _a, _b;
|
|
455
|
-
const escaped = escapeRegExp(key);
|
|
456
|
-
const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
|
|
457
|
-
const matches = Array.from(xml.matchAll(re));
|
|
458
|
-
if (matches.length <= 1) {
|
|
459
|
-
return xml;
|
|
460
|
-
}
|
|
461
|
-
const last = matches.at(-1);
|
|
462
|
-
let result = "";
|
|
463
|
-
let cursor = 0;
|
|
464
|
-
for (const m of matches) {
|
|
465
|
-
const idx = (_a = m.index) != null ? _a : 0;
|
|
466
|
-
result += xml.slice(cursor, idx);
|
|
467
|
-
if (last && idx === ((_b = last.index) != null ? _b : -1)) {
|
|
468
|
-
result += m[0];
|
|
469
|
-
}
|
|
470
|
-
cursor = idx + m[0].length;
|
|
471
|
-
}
|
|
472
|
-
result += xml.slice(cursor);
|
|
473
|
-
return result;
|
|
474
|
-
}
|
|
475
|
-
function repairParsedAgainstSchema(input, schema) {
|
|
476
|
-
if (!input || typeof input !== "object") {
|
|
477
|
-
return input;
|
|
478
|
-
}
|
|
479
|
-
const properties = extractSchemaProperties(schema);
|
|
480
|
-
if (!properties) {
|
|
481
|
-
return input;
|
|
482
|
-
}
|
|
483
|
-
applySchemaProps(input, properties);
|
|
484
|
-
return input;
|
|
485
|
-
}
|
|
486
|
-
function applySchemaProps(obj, properties) {
|
|
487
|
-
for (const key of Object.keys(obj)) {
|
|
488
|
-
const propSchema = properties[key];
|
|
489
|
-
if (!propSchema) {
|
|
490
|
-
continue;
|
|
491
|
-
}
|
|
492
|
-
const prop = (0, import_rxml.unwrapJsonSchema)(propSchema);
|
|
493
|
-
if ((prop == null ? void 0 : prop.type) === "array" && prop.items) {
|
|
494
|
-
const itemSchema = (0, import_rxml.unwrapJsonSchema)(prop.items);
|
|
495
|
-
obj[key] = coerceArrayItems(obj[key], itemSchema);
|
|
496
|
-
continue;
|
|
497
|
-
}
|
|
498
|
-
if ((prop == null ? void 0 : prop.type) === "object") {
|
|
499
|
-
const val = obj[key];
|
|
500
|
-
if (val && typeof val === "object") {
|
|
501
|
-
obj[key] = repairParsedAgainstSchema(val, prop);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
function coerceArrayItems(val, itemSchema) {
|
|
507
|
-
if (!Array.isArray(val)) {
|
|
508
|
-
return val;
|
|
509
|
-
}
|
|
510
|
-
return val.map((v) => coerceArrayItem(v, itemSchema));
|
|
511
|
-
}
|
|
512
|
-
function coerceArrayItem(v, itemSchema) {
|
|
513
|
-
const itemType = itemSchema == null ? void 0 : itemSchema.type;
|
|
514
|
-
if (typeof v === "string" && itemType === "object") {
|
|
515
|
-
const parsed = tryParseStringToSchemaObject(v, itemSchema);
|
|
516
|
-
if (parsed !== null) {
|
|
517
|
-
return parsed;
|
|
518
|
-
}
|
|
519
|
-
const fallback = extractStepStatusFromString(
|
|
520
|
-
v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
|
|
521
|
-
);
|
|
522
|
-
if (fallback) {
|
|
523
|
-
return fallback;
|
|
524
|
-
}
|
|
525
|
-
return v;
|
|
526
|
-
}
|
|
527
|
-
if (v && typeof v === "object" && itemType === "object") {
|
|
528
|
-
return repairParsedAgainstSchema(v, itemSchema);
|
|
529
|
-
}
|
|
530
|
-
return v;
|
|
531
|
-
}
|
|
532
|
-
function tryParseStringToSchemaObject(xml, itemSchema) {
|
|
533
|
-
try {
|
|
534
|
-
const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
|
|
535
|
-
const fixed = (0, import_rxml.parse)(normalized, itemSchema, { noChildNodes: [] });
|
|
536
|
-
return typeof fixed === "string" ? null : fixed;
|
|
537
|
-
} catch (e) {
|
|
538
|
-
return null;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
function extractStepStatusFromString(normXml) {
|
|
542
|
-
const stepMatch = normXml.match(STEP_TAG_RE);
|
|
543
|
-
const statusMatch = normXml.match(STATUS_TAG_RE);
|
|
544
|
-
if (stepMatch && statusMatch) {
|
|
545
|
-
return { step: stepMatch[1], status: statusMatch[1] };
|
|
546
|
-
}
|
|
547
|
-
return null;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
74
|
// src/core/protocols/json-protocol.ts
|
|
551
75
|
var import_rjson = require("@ai-sdk-tool/rjson");
|
|
552
76
|
|
|
@@ -729,7 +253,7 @@ function generateId() {
|
|
|
729
253
|
}
|
|
730
254
|
|
|
731
255
|
// src/core/utils/regex.ts
|
|
732
|
-
function
|
|
256
|
+
function escapeRegExp(literal) {
|
|
733
257
|
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
734
258
|
}
|
|
735
259
|
|
|
@@ -976,8 +500,8 @@ var jsonProtocol = ({
|
|
|
976
500
|
text,
|
|
977
501
|
options
|
|
978
502
|
}) {
|
|
979
|
-
const startEsc =
|
|
980
|
-
const endEsc =
|
|
503
|
+
const startEsc = escapeRegExp(toolCallStart);
|
|
504
|
+
const endEsc = escapeRegExp(toolCallEnd);
|
|
981
505
|
const toolCallRegex = new RegExp(
|
|
982
506
|
`${startEsc}([\0-\uFFFF]*?)${endEsc}`,
|
|
983
507
|
"gs"
|
|
@@ -1036,8 +560,8 @@ var jsonProtocol = ({
|
|
|
1036
560
|
});
|
|
1037
561
|
},
|
|
1038
562
|
extractToolCallSegments({ text }) {
|
|
1039
|
-
const startEsc =
|
|
1040
|
-
const endEsc =
|
|
563
|
+
const startEsc = escapeRegExp(toolCallStart);
|
|
564
|
+
const endEsc = escapeRegExp(toolCallEnd);
|
|
1041
565
|
const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
|
|
1042
566
|
const segments = [];
|
|
1043
567
|
let m = regex.exec(text);
|
|
@@ -1058,93 +582,44 @@ function isTCMProtocolFactory(protocol) {
|
|
|
1058
582
|
}
|
|
1059
583
|
|
|
1060
584
|
// src/core/protocols/xml-protocol.ts
|
|
1061
|
-
var
|
|
1062
|
-
var
|
|
1063
|
-
var
|
|
1064
|
-
var WHITESPACE_REGEX2 = /\s/;
|
|
585
|
+
var import_rxml = require("@ai-sdk-tool/rxml");
|
|
586
|
+
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
587
|
+
var WHITESPACE_REGEX = /\s/;
|
|
1065
588
|
function getToolSchema(tools, toolName) {
|
|
1066
589
|
var _a;
|
|
1067
590
|
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
1068
591
|
}
|
|
1069
|
-
function
|
|
1070
|
-
|
|
1071
|
-
}
|
|
1072
|
-
function tryParseSecondaryXml(content, toolSchema, options) {
|
|
1073
|
-
const balanced = balanceTags(content);
|
|
1074
|
-
try {
|
|
1075
|
-
let parsed = (0, import_rxml2.parse)(balanced, toolSchema, {
|
|
1076
|
-
onError: options == null ? void 0 : options.onError,
|
|
1077
|
-
noChildNodes: []
|
|
1078
|
-
});
|
|
1079
|
-
parsed = repairParsedAgainstSchema(parsed, toolSchema);
|
|
1080
|
-
return parsed;
|
|
1081
|
-
} catch (e) {
|
|
1082
|
-
if (shouldDeduplicateStringTags(toolSchema)) {
|
|
1083
|
-
const names = getStringPropertyNames(toolSchema);
|
|
1084
|
-
let deduped = balanced;
|
|
1085
|
-
for (const key of names) {
|
|
1086
|
-
deduped = dedupeSingleTag(deduped, key);
|
|
1087
|
-
}
|
|
1088
|
-
if (deduped !== balanced) {
|
|
1089
|
-
try {
|
|
1090
|
-
let reparsed = (0, import_rxml2.parse)(deduped, toolSchema, {
|
|
1091
|
-
onError: options == null ? void 0 : options.onError,
|
|
1092
|
-
noChildNodes: []
|
|
1093
|
-
});
|
|
1094
|
-
reparsed = repairParsedAgainstSchema(reparsed, toolSchema);
|
|
1095
|
-
return reparsed;
|
|
1096
|
-
} catch (e2) {
|
|
1097
|
-
return null;
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
return null;
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
function processToolCallWithPipeline(params) {
|
|
1105
|
-
var _a;
|
|
1106
|
-
const {
|
|
1107
|
-
toolCall,
|
|
1108
|
-
tools,
|
|
1109
|
-
options,
|
|
1110
|
-
text,
|
|
1111
|
-
processedElements,
|
|
1112
|
-
pipelineConfig = defaultPipelineConfig2,
|
|
1113
|
-
maxReparses
|
|
1114
|
-
} = params;
|
|
592
|
+
function processToolCall(params) {
|
|
593
|
+
var _a, _b;
|
|
594
|
+
const { toolCall, tools, options, text, processedElements, parseOptions } = params;
|
|
1115
595
|
const toolSchema = getToolSchema(tools, toolCall.toolName);
|
|
1116
|
-
const
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
|
|
1123
|
-
onError: options == null ? void 0 : options.onError,
|
|
1124
|
-
maxReparses
|
|
1125
|
-
});
|
|
1126
|
-
if (result.parsed !== null) {
|
|
596
|
+
const parseConfig = {
|
|
597
|
+
...parseOptions != null ? parseOptions : {},
|
|
598
|
+
onError: (_a = options == null ? void 0 : options.onError) != null ? _a : parseOptions == null ? void 0 : parseOptions.onError
|
|
599
|
+
};
|
|
600
|
+
try {
|
|
601
|
+
const parsed = (0, import_rxml.parse)(toolCall.content, toolSchema, parseConfig);
|
|
1127
602
|
processedElements.push({
|
|
1128
603
|
type: "tool-call",
|
|
1129
604
|
toolCallId: generateId(),
|
|
1130
605
|
toolName: toolCall.toolName,
|
|
1131
|
-
input: JSON.stringify(
|
|
606
|
+
input: JSON.stringify(parsed)
|
|
1132
607
|
});
|
|
1133
|
-
}
|
|
608
|
+
} catch (error) {
|
|
1134
609
|
const originalCallText = text.substring(
|
|
1135
610
|
toolCall.startIndex,
|
|
1136
611
|
toolCall.endIndex
|
|
1137
612
|
);
|
|
1138
|
-
(
|
|
613
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
1139
614
|
options,
|
|
1140
615
|
`Could not process XML tool call: ${toolCall.toolName}`,
|
|
1141
|
-
{ toolCall: originalCallText, error
|
|
616
|
+
{ toolCall: originalCallText, error }
|
|
1142
617
|
);
|
|
1143
618
|
processedElements.push({ type: "text", text: originalCallText });
|
|
1144
619
|
}
|
|
1145
620
|
}
|
|
1146
621
|
function handleStreamingToolCallEnd(params) {
|
|
1147
|
-
var _a;
|
|
622
|
+
var _a, _b;
|
|
1148
623
|
const {
|
|
1149
624
|
toolContent,
|
|
1150
625
|
currentToolCall,
|
|
@@ -1152,51 +627,27 @@ function handleStreamingToolCallEnd(params) {
|
|
|
1152
627
|
options,
|
|
1153
628
|
ctrl,
|
|
1154
629
|
flushText,
|
|
1155
|
-
|
|
1156
|
-
maxReparses
|
|
630
|
+
parseOptions
|
|
1157
631
|
} = params;
|
|
1158
632
|
const toolSchema = getToolSchema(tools, currentToolCall.name);
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
toolContent,
|
|
1164
|
-
toolSchema
|
|
1165
|
-
);
|
|
1166
|
-
const result = applyHeuristicPipeline(ctx, pipelineConfig, {
|
|
1167
|
-
parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
|
|
1168
|
-
onError: options == null ? void 0 : options.onError,
|
|
1169
|
-
maxReparses
|
|
1170
|
-
});
|
|
1171
|
-
parsedResult = result.parsed;
|
|
1172
|
-
} else {
|
|
1173
|
-
try {
|
|
1174
|
-
const primary = escapeInvalidLt(normalizeCloseTags(toolContent));
|
|
1175
|
-
const parsed = (0, import_rxml2.parse)(primary, toolSchema, {
|
|
1176
|
-
onError: options == null ? void 0 : options.onError,
|
|
1177
|
-
noChildNodes: []
|
|
1178
|
-
});
|
|
1179
|
-
parsedResult = repairParsedAgainstSchema(parsed, toolSchema);
|
|
1180
|
-
} catch (e) {
|
|
1181
|
-
parsedResult = tryParseSecondaryXml(
|
|
1182
|
-
toolContent,
|
|
1183
|
-
toolSchema,
|
|
1184
|
-
options != null ? options : {}
|
|
1185
|
-
);
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
633
|
+
const parseConfig = {
|
|
634
|
+
...parseOptions != null ? parseOptions : {},
|
|
635
|
+
onError: (_a = options == null ? void 0 : options.onError) != null ? _a : parseOptions == null ? void 0 : parseOptions.onError
|
|
636
|
+
};
|
|
1188
637
|
flushText(ctrl);
|
|
1189
|
-
|
|
638
|
+
try {
|
|
639
|
+
const parsedResult = (0, import_rxml.parse)(toolContent, toolSchema, parseConfig);
|
|
1190
640
|
ctrl.enqueue({
|
|
1191
641
|
type: "tool-call",
|
|
1192
642
|
toolCallId: generateId(),
|
|
1193
643
|
toolName: currentToolCall.name,
|
|
1194
644
|
input: JSON.stringify(parsedResult)
|
|
1195
645
|
});
|
|
1196
|
-
}
|
|
646
|
+
} catch (error) {
|
|
1197
647
|
const original = `<${currentToolCall.name}>${toolContent}</${currentToolCall.name}>`;
|
|
1198
|
-
(
|
|
1199
|
-
toolCall: original
|
|
648
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, "Could not process streaming XML tool call", {
|
|
649
|
+
toolCall: original,
|
|
650
|
+
error
|
|
1200
651
|
});
|
|
1201
652
|
flushText(ctrl, original);
|
|
1202
653
|
}
|
|
@@ -1235,11 +686,11 @@ function consumeClosingTag(text, lt) {
|
|
|
1235
686
|
}
|
|
1236
687
|
function consumeOpenTag(text, lt) {
|
|
1237
688
|
let p = lt + 1;
|
|
1238
|
-
while (p < text.length &&
|
|
689
|
+
while (p < text.length && WHITESPACE_REGEX.test(text[p])) {
|
|
1239
690
|
p += 1;
|
|
1240
691
|
}
|
|
1241
692
|
const nameStart = p;
|
|
1242
|
-
while (p < text.length &&
|
|
693
|
+
while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
|
|
1243
694
|
p += 1;
|
|
1244
695
|
}
|
|
1245
696
|
const name = text.slice(nameStart, p);
|
|
@@ -1248,7 +699,7 @@ function consumeOpenTag(text, lt) {
|
|
|
1248
699
|
return null;
|
|
1249
700
|
}
|
|
1250
701
|
let r = q - 1;
|
|
1251
|
-
while (r >= nameStart &&
|
|
702
|
+
while (r >= nameStart && WHITESPACE_REGEX.test(text[r])) {
|
|
1252
703
|
r -= 1;
|
|
1253
704
|
}
|
|
1254
705
|
const selfClosing = text[r] === "/";
|
|
@@ -1277,11 +728,11 @@ function nextTagToken(text, fromPos) {
|
|
|
1277
728
|
if (next === "/") {
|
|
1278
729
|
const closing = consumeClosingTag(text, lt);
|
|
1279
730
|
let p = lt + 2;
|
|
1280
|
-
while (p < text.length &&
|
|
731
|
+
while (p < text.length && WHITESPACE_REGEX.test(text[p])) {
|
|
1281
732
|
p += 1;
|
|
1282
733
|
}
|
|
1283
734
|
const nameStart = p;
|
|
1284
|
-
while (p < text.length &&
|
|
735
|
+
while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
|
|
1285
736
|
p += 1;
|
|
1286
737
|
}
|
|
1287
738
|
const name = text.slice(nameStart, p);
|
|
@@ -1298,49 +749,111 @@ function nextTagToken(text, fromPos) {
|
|
|
1298
749
|
nextPos: open.nextPos
|
|
1299
750
|
};
|
|
1300
751
|
}
|
|
752
|
+
function findNextToolTag(text, searchIndex, toolName) {
|
|
753
|
+
var _a, _b;
|
|
754
|
+
const startTag = `<${toolName}>`;
|
|
755
|
+
const openIdx = text.indexOf(startTag, searchIndex);
|
|
756
|
+
const selfMatch = findSelfClosingTag(text, toolName, searchIndex);
|
|
757
|
+
const selfIdx = (_a = selfMatch == null ? void 0 : selfMatch.index) != null ? _a : -1;
|
|
758
|
+
if (openIdx === -1 && selfIdx === -1) {
|
|
759
|
+
return null;
|
|
760
|
+
}
|
|
761
|
+
const isSelfClosing = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx);
|
|
762
|
+
return {
|
|
763
|
+
tagStart: isSelfClosing ? selfIdx : openIdx,
|
|
764
|
+
isSelfClosing,
|
|
765
|
+
tagLength: isSelfClosing ? (_b = selfMatch == null ? void 0 : selfMatch.length) != null ? _b : 0 : startTag.length
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
function findLastCloseTagStart(segment, toolName) {
|
|
769
|
+
const closeTagPattern = new RegExp(
|
|
770
|
+
`</\\s*${escapeRegExp(toolName)}\\s*>`,
|
|
771
|
+
"g"
|
|
772
|
+
);
|
|
773
|
+
let closeTagStart = -1;
|
|
774
|
+
let match = closeTagPattern.exec(segment);
|
|
775
|
+
while (match !== null) {
|
|
776
|
+
closeTagStart = match.index;
|
|
777
|
+
match = closeTagPattern.exec(segment);
|
|
778
|
+
}
|
|
779
|
+
if (closeTagStart === -1) {
|
|
780
|
+
return segment.lastIndexOf("<");
|
|
781
|
+
}
|
|
782
|
+
return closeTagStart;
|
|
783
|
+
}
|
|
784
|
+
function pushSelfClosingToolCall(toolCalls, toolName, text, tagStart, tagLength) {
|
|
785
|
+
const endIndex = tagStart + tagLength;
|
|
786
|
+
toolCalls.push({
|
|
787
|
+
toolName,
|
|
788
|
+
startIndex: tagStart,
|
|
789
|
+
endIndex,
|
|
790
|
+
content: "",
|
|
791
|
+
segment: text.substring(tagStart, endIndex)
|
|
792
|
+
});
|
|
793
|
+
return endIndex;
|
|
794
|
+
}
|
|
795
|
+
var selfClosingTagCache = /* @__PURE__ */ new Map();
|
|
796
|
+
function getSelfClosingTagPattern(toolName) {
|
|
797
|
+
let pattern = selfClosingTagCache.get(toolName);
|
|
798
|
+
if (!pattern) {
|
|
799
|
+
pattern = new RegExp(`<\\s*${escapeRegExp(toolName)}\\s*/>`, "g");
|
|
800
|
+
selfClosingTagCache.set(toolName, pattern);
|
|
801
|
+
}
|
|
802
|
+
return pattern;
|
|
803
|
+
}
|
|
804
|
+
function findSelfClosingTag(text, toolName, fromIndex) {
|
|
805
|
+
const pattern = getSelfClosingTagPattern(toolName);
|
|
806
|
+
pattern.lastIndex = fromIndex;
|
|
807
|
+
const match = pattern.exec(text);
|
|
808
|
+
if (!match || match.index === void 0) {
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
return { index: match.index, length: match[0].length };
|
|
812
|
+
}
|
|
813
|
+
function appendOpenToolCallIfComplete(toolCalls, text, toolName, tagStart, startTag) {
|
|
814
|
+
const contentStart = tagStart + startTag.length;
|
|
815
|
+
const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
|
|
816
|
+
if (fullTagEnd === -1 || fullTagEnd <= contentStart) {
|
|
817
|
+
return contentStart;
|
|
818
|
+
}
|
|
819
|
+
const segment = text.substring(tagStart, fullTagEnd);
|
|
820
|
+
const closeTagStart = findLastCloseTagStart(segment, toolName);
|
|
821
|
+
const inner = closeTagStart === -1 ? segment.slice(startTag.length) : segment.slice(startTag.length, closeTagStart);
|
|
822
|
+
toolCalls.push({
|
|
823
|
+
toolName,
|
|
824
|
+
startIndex: tagStart,
|
|
825
|
+
endIndex: fullTagEnd,
|
|
826
|
+
content: inner,
|
|
827
|
+
segment
|
|
828
|
+
});
|
|
829
|
+
return fullTagEnd;
|
|
830
|
+
}
|
|
1301
831
|
function findToolCallsForName(text, toolName) {
|
|
1302
|
-
var _a;
|
|
1303
832
|
const toolCalls = [];
|
|
833
|
+
const startTag = `<${toolName}>`;
|
|
1304
834
|
let searchIndex = 0;
|
|
1305
835
|
while (searchIndex < text.length) {
|
|
1306
|
-
const
|
|
1307
|
-
|
|
1308
|
-
const openIdx = text.indexOf(startTag, searchIndex);
|
|
1309
|
-
const selfIdx = text.indexOf(selfTag, searchIndex);
|
|
1310
|
-
if (openIdx === -1 && selfIdx === -1) {
|
|
836
|
+
const match = findNextToolTag(text, searchIndex, toolName);
|
|
837
|
+
if (match === null) {
|
|
1311
838
|
break;
|
|
1312
839
|
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
const endIndex = tagStart + selfTag.length;
|
|
1317
|
-
const segment = text.substring(tagStart, endIndex);
|
|
1318
|
-
toolCalls.push({
|
|
840
|
+
if (match.isSelfClosing) {
|
|
841
|
+
searchIndex = pushSelfClosingToolCall(
|
|
842
|
+
toolCalls,
|
|
1319
843
|
toolName,
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
});
|
|
1325
|
-
searchIndex = endIndex;
|
|
844
|
+
text,
|
|
845
|
+
match.tagStart,
|
|
846
|
+
match.tagLength
|
|
847
|
+
);
|
|
1326
848
|
continue;
|
|
1327
849
|
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
startIndex: tagStart,
|
|
1336
|
-
endIndex: fullTagEnd,
|
|
1337
|
-
content: inner,
|
|
1338
|
-
segment
|
|
1339
|
-
});
|
|
1340
|
-
searchIndex = fullTagEnd;
|
|
1341
|
-
} else {
|
|
1342
|
-
searchIndex = contentStart;
|
|
1343
|
-
}
|
|
850
|
+
searchIndex = appendOpenToolCallIfComplete(
|
|
851
|
+
toolCalls,
|
|
852
|
+
text,
|
|
853
|
+
toolName,
|
|
854
|
+
match.tagStart,
|
|
855
|
+
startTag
|
|
856
|
+
);
|
|
1344
857
|
}
|
|
1345
858
|
return toolCalls;
|
|
1346
859
|
}
|
|
@@ -1353,28 +866,114 @@ function findToolCalls(text, toolNames) {
|
|
|
1353
866
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
1354
867
|
}
|
|
1355
868
|
function findEarliestToolTag(buffer, toolNames) {
|
|
869
|
+
var _a, _b;
|
|
1356
870
|
let bestIndex = -1;
|
|
1357
871
|
let bestName = "";
|
|
1358
872
|
let bestSelfClosing = false;
|
|
873
|
+
let bestTagLength = 0;
|
|
1359
874
|
if (toolNames.length > 0) {
|
|
1360
875
|
for (const name of toolNames) {
|
|
1361
876
|
const openTag = `<${name}>`;
|
|
1362
|
-
const selfTag = `<${name}/>`;
|
|
1363
877
|
const idxOpen = buffer.indexOf(openTag);
|
|
1364
|
-
const
|
|
878
|
+
const selfMatch = findSelfClosingTag(buffer, name, 0);
|
|
879
|
+
const idxSelf = (_a = selfMatch == null ? void 0 : selfMatch.index) != null ? _a : -1;
|
|
1365
880
|
if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
|
|
1366
881
|
bestIndex = idxOpen;
|
|
1367
882
|
bestName = name;
|
|
1368
883
|
bestSelfClosing = false;
|
|
884
|
+
bestTagLength = openTag.length;
|
|
1369
885
|
}
|
|
1370
886
|
if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
|
|
1371
887
|
bestIndex = idxSelf;
|
|
1372
888
|
bestName = name;
|
|
1373
889
|
bestSelfClosing = true;
|
|
890
|
+
bestTagLength = (_b = selfMatch == null ? void 0 : selfMatch.length) != null ? _b : 0;
|
|
1374
891
|
}
|
|
1375
892
|
}
|
|
1376
893
|
}
|
|
1377
|
-
return {
|
|
894
|
+
return {
|
|
895
|
+
index: bestIndex,
|
|
896
|
+
name: bestName,
|
|
897
|
+
selfClosing: bestSelfClosing,
|
|
898
|
+
tagLength: bestTagLength
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
function isOpenTagPrefix(suffix, toolName) {
|
|
902
|
+
return `${toolName}>`.startsWith(suffix);
|
|
903
|
+
}
|
|
904
|
+
function consumeWhitespace(text, index) {
|
|
905
|
+
let i = index;
|
|
906
|
+
while (i < text.length && WHITESPACE_REGEX.test(text.charAt(i))) {
|
|
907
|
+
i += 1;
|
|
908
|
+
}
|
|
909
|
+
return i;
|
|
910
|
+
}
|
|
911
|
+
function consumeToolNamePrefix(text, index, toolName) {
|
|
912
|
+
let i = index;
|
|
913
|
+
let nameIndex = 0;
|
|
914
|
+
while (i < text.length && nameIndex < toolName.length) {
|
|
915
|
+
if (text.charAt(i) !== toolName.charAt(nameIndex)) {
|
|
916
|
+
return { index: i, done: false, valid: false };
|
|
917
|
+
}
|
|
918
|
+
i += 1;
|
|
919
|
+
nameIndex += 1;
|
|
920
|
+
}
|
|
921
|
+
return { index: i, done: nameIndex === toolName.length, valid: true };
|
|
922
|
+
}
|
|
923
|
+
function isSelfClosingSuffixRemainder(text, index) {
|
|
924
|
+
if (text.charAt(index) !== "/") {
|
|
925
|
+
return false;
|
|
926
|
+
}
|
|
927
|
+
if (index + 1 >= text.length) {
|
|
928
|
+
return true;
|
|
929
|
+
}
|
|
930
|
+
return index + 1 === text.length - 1 && text.charAt(index + 1) === ">";
|
|
931
|
+
}
|
|
932
|
+
function isSelfClosingTagPrefix(suffix, toolName) {
|
|
933
|
+
let i = consumeWhitespace(suffix, 0);
|
|
934
|
+
if (i >= suffix.length) {
|
|
935
|
+
return true;
|
|
936
|
+
}
|
|
937
|
+
const nameRemainder = suffix.slice(i);
|
|
938
|
+
if (toolName.startsWith(nameRemainder)) {
|
|
939
|
+
return true;
|
|
940
|
+
}
|
|
941
|
+
const nameResult = consumeToolNamePrefix(suffix, i, toolName);
|
|
942
|
+
if (!nameResult.valid) {
|
|
943
|
+
return false;
|
|
944
|
+
}
|
|
945
|
+
i = nameResult.index;
|
|
946
|
+
if (i >= suffix.length) {
|
|
947
|
+
return true;
|
|
948
|
+
}
|
|
949
|
+
if (!nameResult.done) {
|
|
950
|
+
return false;
|
|
951
|
+
}
|
|
952
|
+
i = consumeWhitespace(suffix, i);
|
|
953
|
+
if (i >= suffix.length) {
|
|
954
|
+
return true;
|
|
955
|
+
}
|
|
956
|
+
return isSelfClosingSuffixRemainder(suffix, i);
|
|
957
|
+
}
|
|
958
|
+
function findPotentialToolTagStart(buffer, toolNames) {
|
|
959
|
+
if (toolNames.length === 0 || buffer.length === 0) {
|
|
960
|
+
return -1;
|
|
961
|
+
}
|
|
962
|
+
const lastGt = buffer.lastIndexOf(">");
|
|
963
|
+
const offset = lastGt === -1 ? 0 : lastGt + 1;
|
|
964
|
+
const trailing = buffer.slice(offset);
|
|
965
|
+
for (let i = trailing.length - 1; i >= 0; i -= 1) {
|
|
966
|
+
if (trailing.charAt(i) !== "<") {
|
|
967
|
+
continue;
|
|
968
|
+
}
|
|
969
|
+
const suffix = trailing.slice(i + 1);
|
|
970
|
+
for (const name of toolNames) {
|
|
971
|
+
if (isOpenTagPrefix(suffix, name) || isSelfClosingTagPrefix(suffix, name)) {
|
|
972
|
+
return offset + i;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
return -1;
|
|
1378
977
|
}
|
|
1379
978
|
function createFlushTextHandler(getCurrentTextId, setCurrentTextId, getHasEmittedTextStart, setHasEmittedTextStart) {
|
|
1380
979
|
return (controller, text) => {
|
|
@@ -1417,16 +1016,20 @@ function processToolCallInBuffer(params) {
|
|
|
1417
1016
|
controller,
|
|
1418
1017
|
flushText,
|
|
1419
1018
|
setBuffer,
|
|
1420
|
-
|
|
1421
|
-
maxReparses
|
|
1019
|
+
parseOptions
|
|
1422
1020
|
} = params;
|
|
1423
|
-
const
|
|
1424
|
-
|
|
1425
|
-
|
|
1021
|
+
const endTagPattern = new RegExp(
|
|
1022
|
+
`</\\s*${escapeRegExp(currentToolCall.name)}\\s*>`
|
|
1023
|
+
);
|
|
1024
|
+
const endMatch = endTagPattern.exec(buffer);
|
|
1025
|
+
if (!endMatch || endMatch.index === void 0) {
|
|
1426
1026
|
return { buffer, currentToolCall, shouldBreak: true };
|
|
1427
1027
|
}
|
|
1028
|
+
const endIdx = endMatch.index;
|
|
1029
|
+
const endPos = endIdx + endMatch[0].length;
|
|
1428
1030
|
const content = buffer.substring(0, endIdx);
|
|
1429
|
-
|
|
1031
|
+
const remainder = buffer.substring(endPos);
|
|
1032
|
+
setBuffer(remainder);
|
|
1430
1033
|
handleStreamingToolCallEnd({
|
|
1431
1034
|
toolContent: content,
|
|
1432
1035
|
currentToolCall,
|
|
@@ -1434,11 +1037,10 @@ function processToolCallInBuffer(params) {
|
|
|
1434
1037
|
options,
|
|
1435
1038
|
ctrl: controller,
|
|
1436
1039
|
flushText,
|
|
1437
|
-
|
|
1438
|
-
maxReparses
|
|
1040
|
+
parseOptions
|
|
1439
1041
|
});
|
|
1440
1042
|
return {
|
|
1441
|
-
buffer:
|
|
1043
|
+
buffer: remainder,
|
|
1442
1044
|
currentToolCall: null,
|
|
1443
1045
|
shouldBreak: false
|
|
1444
1046
|
};
|
|
@@ -1451,25 +1053,28 @@ function processNoToolCallInBuffer(params) {
|
|
|
1451
1053
|
flushText,
|
|
1452
1054
|
tools,
|
|
1453
1055
|
options,
|
|
1454
|
-
|
|
1455
|
-
maxReparses,
|
|
1056
|
+
parseOptions,
|
|
1456
1057
|
setBuffer
|
|
1457
1058
|
} = params;
|
|
1458
1059
|
const {
|
|
1459
1060
|
index: earliestStartTagIndex,
|
|
1460
1061
|
name: earliestToolName,
|
|
1461
|
-
selfClosing
|
|
1062
|
+
selfClosing,
|
|
1063
|
+
tagLength
|
|
1462
1064
|
} = findEarliestToolTag(buffer, toolNames);
|
|
1463
1065
|
if (earliestStartTagIndex === -1) {
|
|
1464
|
-
const
|
|
1465
|
-
const
|
|
1466
|
-
|
|
1066
|
+
const potentialStart = findPotentialToolTagStart(buffer, toolNames);
|
|
1067
|
+
const safeLen = Math.max(
|
|
1068
|
+
0,
|
|
1069
|
+
potentialStart === -1 ? buffer.length : potentialStart
|
|
1070
|
+
);
|
|
1071
|
+
const remaining = buffer.slice(safeLen);
|
|
1467
1072
|
if (safeLen > 0) {
|
|
1468
1073
|
flushText(controller, buffer.slice(0, safeLen));
|
|
1469
|
-
setBuffer(
|
|
1074
|
+
setBuffer(remaining);
|
|
1470
1075
|
}
|
|
1471
1076
|
return {
|
|
1472
|
-
buffer:
|
|
1077
|
+
buffer: remaining,
|
|
1473
1078
|
currentToolCall: null,
|
|
1474
1079
|
shouldBreak: true,
|
|
1475
1080
|
shouldContinue: false
|
|
@@ -1477,8 +1082,7 @@ function processNoToolCallInBuffer(params) {
|
|
|
1477
1082
|
}
|
|
1478
1083
|
flushText(controller, buffer.substring(0, earliestStartTagIndex));
|
|
1479
1084
|
if (selfClosing) {
|
|
1480
|
-
const
|
|
1481
|
-
const newBuffer2 = buffer.substring(earliestStartTagIndex + selfTag.length);
|
|
1085
|
+
const newBuffer2 = buffer.substring(earliestStartTagIndex + tagLength);
|
|
1482
1086
|
setBuffer(newBuffer2);
|
|
1483
1087
|
handleStreamingToolCallEnd({
|
|
1484
1088
|
toolContent: "",
|
|
@@ -1487,8 +1091,7 @@ function processNoToolCallInBuffer(params) {
|
|
|
1487
1091
|
options,
|
|
1488
1092
|
ctrl: controller,
|
|
1489
1093
|
flushText,
|
|
1490
|
-
|
|
1491
|
-
maxReparses
|
|
1094
|
+
parseOptions
|
|
1492
1095
|
});
|
|
1493
1096
|
return {
|
|
1494
1097
|
buffer: newBuffer2,
|
|
@@ -1507,7 +1110,7 @@ function processNoToolCallInBuffer(params) {
|
|
|
1507
1110
|
shouldContinue: true
|
|
1508
1111
|
};
|
|
1509
1112
|
}
|
|
1510
|
-
function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, setCurrentToolCall, tools, options, toolNames, flushText,
|
|
1113
|
+
function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, setCurrentToolCall, tools, options, toolNames, flushText, parseOptions) {
|
|
1511
1114
|
return (controller) => {
|
|
1512
1115
|
while (true) {
|
|
1513
1116
|
const currentToolCall = getCurrentToolCall();
|
|
@@ -1520,8 +1123,7 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
|
|
|
1520
1123
|
controller,
|
|
1521
1124
|
flushText,
|
|
1522
1125
|
setBuffer,
|
|
1523
|
-
|
|
1524
|
-
maxReparses
|
|
1126
|
+
parseOptions
|
|
1525
1127
|
});
|
|
1526
1128
|
setBuffer(result.buffer);
|
|
1527
1129
|
setCurrentToolCall(result.currentToolCall);
|
|
@@ -1536,8 +1138,7 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
|
|
|
1536
1138
|
flushText,
|
|
1537
1139
|
tools,
|
|
1538
1140
|
options,
|
|
1539
|
-
|
|
1540
|
-
maxReparses,
|
|
1141
|
+
parseOptions,
|
|
1541
1142
|
setBuffer
|
|
1542
1143
|
});
|
|
1543
1144
|
setBuffer(result.buffer);
|
|
@@ -1554,43 +1155,12 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
|
|
|
1554
1155
|
};
|
|
1555
1156
|
}
|
|
1556
1157
|
var xmlProtocol = (protocolOptions) => {
|
|
1557
|
-
var _a
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
fallbackReparse: [],
|
|
1564
|
-
postParse: []
|
|
1565
|
-
};
|
|
1566
|
-
for (const h of protocolOptions.heuristics) {
|
|
1567
|
-
if (h.phase === "pre-parse") {
|
|
1568
|
-
(_a = heuristicsConfig.preParse) == null ? void 0 : _a.push(h);
|
|
1569
|
-
} else if (h.phase === "fallback-reparse") {
|
|
1570
|
-
(_b = heuristicsConfig.fallbackReparse) == null ? void 0 : _b.push(h);
|
|
1571
|
-
} else if (h.phase === "post-parse") {
|
|
1572
|
-
(_c = heuristicsConfig.postParse) == null ? void 0 : _c.push(h);
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
if (pipelineConfig) {
|
|
1576
|
-
pipelineConfig = {
|
|
1577
|
-
preParse: [
|
|
1578
|
-
...(_d = pipelineConfig.preParse) != null ? _d : [],
|
|
1579
|
-
...(_e = heuristicsConfig.preParse) != null ? _e : []
|
|
1580
|
-
],
|
|
1581
|
-
fallbackReparse: [
|
|
1582
|
-
...(_f = pipelineConfig.fallbackReparse) != null ? _f : [],
|
|
1583
|
-
...(_g = heuristicsConfig.fallbackReparse) != null ? _g : []
|
|
1584
|
-
],
|
|
1585
|
-
postParse: [
|
|
1586
|
-
...(_h = pipelineConfig.postParse) != null ? _h : [],
|
|
1587
|
-
...(_i = heuristicsConfig.postParse) != null ? _i : []
|
|
1588
|
-
]
|
|
1589
|
-
};
|
|
1590
|
-
} else {
|
|
1591
|
-
pipelineConfig = heuristicsConfig;
|
|
1592
|
-
}
|
|
1593
|
-
}
|
|
1158
|
+
var _a;
|
|
1159
|
+
const parseOptions = {
|
|
1160
|
+
repair: true,
|
|
1161
|
+
noChildNodes: [],
|
|
1162
|
+
...(_a = protocolOptions == null ? void 0 : protocolOptions.parseOptions) != null ? _a : {}
|
|
1163
|
+
};
|
|
1594
1164
|
return {
|
|
1595
1165
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1596
1166
|
return toolSystemPromptTemplate(tools || []);
|
|
@@ -1604,7 +1174,7 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
1604
1174
|
args = toolCall.input;
|
|
1605
1175
|
}
|
|
1606
1176
|
}
|
|
1607
|
-
return (0,
|
|
1177
|
+
return (0, import_rxml.stringify)(toolCall.toolName, args, {
|
|
1608
1178
|
suppressEmptyNode: false,
|
|
1609
1179
|
format: true,
|
|
1610
1180
|
minimalEscaping: true
|
|
@@ -1625,14 +1195,13 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
1625
1195
|
text: text.substring(currentIndex, tc.startIndex)
|
|
1626
1196
|
});
|
|
1627
1197
|
}
|
|
1628
|
-
|
|
1198
|
+
processToolCall({
|
|
1629
1199
|
toolCall: tc,
|
|
1630
1200
|
tools,
|
|
1631
1201
|
options,
|
|
1632
1202
|
text,
|
|
1633
1203
|
processedElements,
|
|
1634
|
-
|
|
1635
|
-
maxReparses
|
|
1204
|
+
parseOptions
|
|
1636
1205
|
});
|
|
1637
1206
|
currentIndex = tc.endIndex;
|
|
1638
1207
|
}
|
|
@@ -1673,8 +1242,7 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
1673
1242
|
options,
|
|
1674
1243
|
toolNames,
|
|
1675
1244
|
flushText,
|
|
1676
|
-
|
|
1677
|
-
maxReparses
|
|
1245
|
+
parseOptions
|
|
1678
1246
|
);
|
|
1679
1247
|
return new TransformStream({
|
|
1680
1248
|
transform(chunk, controller) {
|
|
@@ -1724,8 +1292,8 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
1724
1292
|
|
|
1725
1293
|
// src/core/protocols/yaml-protocol.ts
|
|
1726
1294
|
var import_yaml = __toESM(require("yaml"), 1);
|
|
1727
|
-
var
|
|
1728
|
-
var
|
|
1295
|
+
var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
|
|
1296
|
+
var WHITESPACE_REGEX2 = /\s/;
|
|
1729
1297
|
var LEADING_WHITESPACE_RE = /^(\s*)/;
|
|
1730
1298
|
function findClosingTagEnd(text, contentStart, toolName) {
|
|
1731
1299
|
let pos = contentStart;
|
|
@@ -1742,11 +1310,11 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
1742
1310
|
break;
|
|
1743
1311
|
}
|
|
1744
1312
|
let p = ltIdx + 2;
|
|
1745
|
-
while (p < gtIdx &&
|
|
1313
|
+
while (p < gtIdx && WHITESPACE_REGEX2.test(text[p])) {
|
|
1746
1314
|
p++;
|
|
1747
1315
|
}
|
|
1748
1316
|
const nameStart = p;
|
|
1749
|
-
while (p < gtIdx &&
|
|
1317
|
+
while (p < gtIdx && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
1750
1318
|
p++;
|
|
1751
1319
|
}
|
|
1752
1320
|
const name = text.slice(nameStart, p);
|
|
@@ -1762,11 +1330,11 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
1762
1330
|
pos = gtIdx === -1 ? text.length : gtIdx + 1;
|
|
1763
1331
|
} else {
|
|
1764
1332
|
let p = ltIdx + 1;
|
|
1765
|
-
while (p < text.length &&
|
|
1333
|
+
while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
|
|
1766
1334
|
p++;
|
|
1767
1335
|
}
|
|
1768
1336
|
const nameStart = p;
|
|
1769
|
-
while (p < text.length &&
|
|
1337
|
+
while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
1770
1338
|
p++;
|
|
1771
1339
|
}
|
|
1772
1340
|
const name = text.slice(nameStart, p);
|
|
@@ -1775,7 +1343,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
1775
1343
|
break;
|
|
1776
1344
|
}
|
|
1777
1345
|
let r = gtIdx - 1;
|
|
1778
|
-
while (r >= nameStart &&
|
|
1346
|
+
while (r >= nameStart && WHITESPACE_REGEX2.test(text[r])) {
|
|
1779
1347
|
r--;
|
|
1780
1348
|
}
|
|
1781
1349
|
const selfClosing = text[r] === "/";
|
|
@@ -2280,7 +1848,7 @@ function hasInputProperty(obj) {
|
|
|
2280
1848
|
|
|
2281
1849
|
// src/generate-handler.ts
|
|
2282
1850
|
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
2283
|
-
var
|
|
1851
|
+
var import_schema_coerce = require("@ai-sdk-tool/schema-coerce");
|
|
2284
1852
|
function parseToolChoiceJson(text, providerOptions) {
|
|
2285
1853
|
var _a;
|
|
2286
1854
|
try {
|
|
@@ -2442,7 +2010,7 @@ function fixToolCallWithSchema(part, tools) {
|
|
|
2442
2010
|
args = part.input;
|
|
2443
2011
|
}
|
|
2444
2012
|
const schema = (_a = tools.find((t) => t.name === part.toolName)) == null ? void 0 : _a.inputSchema;
|
|
2445
|
-
const coerced = (0,
|
|
2013
|
+
const coerced = (0, import_schema_coerce.coerceBySchema)(args, schema);
|
|
2446
2014
|
return {
|
|
2447
2015
|
...part,
|
|
2448
2016
|
input: JSON.stringify(coerced != null ? coerced : {})
|
|
@@ -2575,29 +2143,230 @@ function formatXmlNode(tagName, value, depth) {
|
|
|
2575
2143
|
}
|
|
2576
2144
|
|
|
2577
2145
|
// src/core/prompts/xml-system-prompt.ts
|
|
2146
|
+
var import_dedent = __toESM(require("dedent"), 1);
|
|
2578
2147
|
function xmlSystemPromptTemplate(tools) {
|
|
2579
|
-
const
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
You may call one or more functions to assist with the user query.
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
-
|
|
2593
|
-
-
|
|
2594
|
-
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2148
|
+
const toolsText = renderToolsForXmlPrompt(tools);
|
|
2149
|
+
const header = import_dedent.default`
|
|
2150
|
+
# Tools
|
|
2151
|
+
You may call one or more functions to assist with the user query.
|
|
2152
|
+
`;
|
|
2153
|
+
const definitions = [
|
|
2154
|
+
"You have access to the following functions:",
|
|
2155
|
+
"<tools>",
|
|
2156
|
+
toolsText,
|
|
2157
|
+
"</tools>"
|
|
2158
|
+
].join("\n");
|
|
2159
|
+
const rules = import_dedent.default`
|
|
2160
|
+
<rules>
|
|
2161
|
+
- Use exactly one XML element whose tag name is the function name.
|
|
2162
|
+
- Put each parameter as a child element.
|
|
2163
|
+
- Values must follow the schema exactly (numbers, arrays, objects, enums → copy as-is).
|
|
2164
|
+
- Do not add or remove functions or parameters.
|
|
2165
|
+
- Each required parameter must appear once.
|
|
2166
|
+
- Output nothing before or after the function call.
|
|
2167
|
+
- It is also possible to call multiple types of functions in one turn or to call a single function multiple times.
|
|
2168
|
+
</rules>
|
|
2169
|
+
`;
|
|
2170
|
+
const examples = import_dedent.default`
|
|
2171
|
+
For each function call, output the function name and parameter in the following format:
|
|
2172
|
+
<example_function_name>
|
|
2173
|
+
<example_parameter_1>value_1</example_parameter_1>
|
|
2174
|
+
<example_parameter_2>This is the value for the second parameter
|
|
2175
|
+
that can span
|
|
2176
|
+
multiple lines</example_parameter_2>
|
|
2177
|
+
</example_function_name>
|
|
2178
|
+
`;
|
|
2179
|
+
return [header, definitions, rules, examples].join("\n\n");
|
|
2180
|
+
}
|
|
2181
|
+
var INDENT = " ";
|
|
2182
|
+
function renderToolsForXmlPrompt(tools) {
|
|
2183
|
+
if (!tools.length) {
|
|
2184
|
+
return "none";
|
|
2185
|
+
}
|
|
2186
|
+
return tools.map(renderToolForXmlPrompt).join("\n\n");
|
|
2187
|
+
}
|
|
2188
|
+
function renderToolForXmlPrompt(tool) {
|
|
2189
|
+
const lines = [`name: ${tool.name}`];
|
|
2190
|
+
if (tool.description) {
|
|
2191
|
+
lines.push(`description: ${tool.description}`);
|
|
2192
|
+
}
|
|
2193
|
+
lines.push("parameters:");
|
|
2194
|
+
const normalizedSchema = normalizeSchema(tool.inputSchema);
|
|
2195
|
+
lines.push(...renderParametersSummary(normalizedSchema, 1));
|
|
2196
|
+
lines.push(`schema: ${stringifySchema(normalizedSchema)}`);
|
|
2197
|
+
return lines.join("\n");
|
|
2198
|
+
}
|
|
2199
|
+
function normalizeSchema(schema) {
|
|
2200
|
+
if (typeof schema === "string") {
|
|
2201
|
+
try {
|
|
2202
|
+
return JSON.parse(schema);
|
|
2203
|
+
} catch (e) {
|
|
2204
|
+
return { type: "string", const: schema };
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
return schema;
|
|
2208
|
+
}
|
|
2209
|
+
function renderParametersSummary(schema, indentLevel) {
|
|
2210
|
+
var _a, _b;
|
|
2211
|
+
const indent = INDENT.repeat(indentLevel);
|
|
2212
|
+
if (schema === void 0 || schema === null) {
|
|
2213
|
+
return [`${indent}(none)`];
|
|
2214
|
+
}
|
|
2215
|
+
if (schema === true) {
|
|
2216
|
+
return [`${indent}(any)`];
|
|
2217
|
+
}
|
|
2218
|
+
if (schema === false) {
|
|
2219
|
+
return [`${indent}(no valid parameters)`];
|
|
2220
|
+
}
|
|
2221
|
+
if (typeof schema !== "object") {
|
|
2222
|
+
return [`${indent}- value (${String(schema)})`];
|
|
2223
|
+
}
|
|
2224
|
+
const schemaType = [];
|
|
2225
|
+
if (Array.isArray(schema.type)) {
|
|
2226
|
+
schemaType.push(...schema.type);
|
|
2227
|
+
} else if (schema.type) {
|
|
2228
|
+
schemaType.push(schema.type);
|
|
2229
|
+
}
|
|
2230
|
+
const isObjectLike = schemaType.includes("object") || !!schema.properties;
|
|
2231
|
+
if (isObjectLike) {
|
|
2232
|
+
const properties = (_a = schema.properties) != null ? _a : {};
|
|
2233
|
+
const requiredSet = new Set((_b = schema.required) != null ? _b : []);
|
|
2234
|
+
const propertyNames = Object.keys(properties).sort();
|
|
2235
|
+
if (propertyNames.length === 0) {
|
|
2236
|
+
return [`${indent}(no named parameters)`];
|
|
2237
|
+
}
|
|
2238
|
+
const lines = [];
|
|
2239
|
+
for (const propName of propertyNames) {
|
|
2240
|
+
const propSchema = properties[propName];
|
|
2241
|
+
lines.push(
|
|
2242
|
+
renderPropertySummaryLine({
|
|
2243
|
+
indent,
|
|
2244
|
+
propName,
|
|
2245
|
+
propSchema,
|
|
2246
|
+
required: requiredSet.has(propName)
|
|
2247
|
+
})
|
|
2248
|
+
);
|
|
2249
|
+
}
|
|
2250
|
+
return lines.length ? lines : [`${indent}(no parameters)`];
|
|
2251
|
+
}
|
|
2252
|
+
return [`${indent}- value (${summarizeType(schema)})`];
|
|
2253
|
+
}
|
|
2254
|
+
function renderPropertySummaryLine({
|
|
2255
|
+
indent,
|
|
2256
|
+
propName,
|
|
2257
|
+
propSchema,
|
|
2258
|
+
required
|
|
2259
|
+
}) {
|
|
2260
|
+
const typeLabel = summarizeType(propSchema);
|
|
2261
|
+
const requiredLabel = required ? "required" : "optional";
|
|
2262
|
+
const extras = collectPropertyExtras(propSchema);
|
|
2263
|
+
const extraText = extras.length ? ` - ${extras.join("; ")}` : "";
|
|
2264
|
+
return `${indent}- ${propName} (${typeLabel}, ${requiredLabel})${extraText}`;
|
|
2265
|
+
}
|
|
2266
|
+
function collectPropertyExtras(propSchema) {
|
|
2267
|
+
if (!propSchema || typeof propSchema !== "object") {
|
|
2268
|
+
return [];
|
|
2269
|
+
}
|
|
2270
|
+
const extras = [];
|
|
2271
|
+
if (propSchema.enum) {
|
|
2272
|
+
extras.push(`enum: ${formatEnumForSummary(propSchema.enum)}`);
|
|
2273
|
+
}
|
|
2274
|
+
if (propSchema.default !== void 0) {
|
|
2275
|
+
extras.push(`default: ${formatValue(propSchema.default)}`);
|
|
2276
|
+
}
|
|
2277
|
+
if (propSchema.description) {
|
|
2278
|
+
extras.push(propSchema.description);
|
|
2279
|
+
}
|
|
2280
|
+
return extras;
|
|
2281
|
+
}
|
|
2282
|
+
function summarizeType(schema) {
|
|
2283
|
+
var _a;
|
|
2284
|
+
if (schema === void 0 || schema === null) {
|
|
2285
|
+
return "unknown";
|
|
2286
|
+
}
|
|
2287
|
+
if (schema === true) {
|
|
2288
|
+
return "any";
|
|
2289
|
+
}
|
|
2290
|
+
if (schema === false) {
|
|
2291
|
+
return "never";
|
|
2292
|
+
}
|
|
2293
|
+
if (typeof schema !== "object") {
|
|
2294
|
+
return String(schema);
|
|
2295
|
+
}
|
|
2296
|
+
const schemaType = schema.type;
|
|
2297
|
+
let baseType = "";
|
|
2298
|
+
if (Array.isArray(schemaType) && schemaType.length) {
|
|
2299
|
+
baseType = schemaType.join(" | ");
|
|
2300
|
+
} else if (typeof schemaType === "string") {
|
|
2301
|
+
baseType = schemaType;
|
|
2302
|
+
} else if (schema.enum) {
|
|
2303
|
+
const inferred = Array.from(
|
|
2304
|
+
new Set(schema.enum.map((value) => typeof value))
|
|
2305
|
+
);
|
|
2306
|
+
if (inferred.length === 1) {
|
|
2307
|
+
baseType = (_a = inferred[0]) != null ? _a : "";
|
|
2308
|
+
}
|
|
2309
|
+
} else if (schema.const !== void 0) {
|
|
2310
|
+
baseType = typeof schema.const;
|
|
2311
|
+
}
|
|
2312
|
+
if (!baseType) {
|
|
2313
|
+
baseType = "any";
|
|
2314
|
+
}
|
|
2315
|
+
if (baseType === "array" && schema.items) {
|
|
2316
|
+
const itemType = Array.isArray(schema.items) ? schema.items.map((item) => summarizeType(item)).join(" | ") : summarizeType(schema.items);
|
|
2317
|
+
return `array<${itemType}>`;
|
|
2318
|
+
}
|
|
2319
|
+
if (baseType === "string" && schema.format) {
|
|
2320
|
+
return `string (${schema.format})`;
|
|
2321
|
+
}
|
|
2322
|
+
return baseType;
|
|
2323
|
+
}
|
|
2324
|
+
var ENUM_MAX_INLINE = 6;
|
|
2325
|
+
var ENUM_PREVIEW_LIMIT = 5;
|
|
2326
|
+
function formatEnumForSummary(values) {
|
|
2327
|
+
if (values.length <= ENUM_MAX_INLINE) {
|
|
2328
|
+
return formatValue(values);
|
|
2329
|
+
}
|
|
2330
|
+
const preview = values.slice(0, ENUM_PREVIEW_LIMIT).map((value) => formatValue(value));
|
|
2331
|
+
return `[${preview.join(", ")}, ... (${values.length} total)]`;
|
|
2332
|
+
}
|
|
2333
|
+
function formatValue(value) {
|
|
2334
|
+
if (typeof value === "string") {
|
|
2335
|
+
return JSON.stringify(value);
|
|
2336
|
+
}
|
|
2337
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
2338
|
+
return String(value);
|
|
2339
|
+
}
|
|
2340
|
+
if (value === null) {
|
|
2341
|
+
return "null";
|
|
2342
|
+
}
|
|
2343
|
+
if (Array.isArray(value)) {
|
|
2344
|
+
return `[${value.map(formatValue).join(", ")}]`;
|
|
2345
|
+
}
|
|
2346
|
+
return JSON.stringify(value);
|
|
2347
|
+
}
|
|
2348
|
+
function stringifySchema(schema) {
|
|
2349
|
+
if (schema === void 0) {
|
|
2350
|
+
return "null";
|
|
2351
|
+
}
|
|
2352
|
+
return JSON.stringify(stripSchemaKeys(schema));
|
|
2353
|
+
}
|
|
2354
|
+
function stripSchemaKeys(value) {
|
|
2355
|
+
if (Array.isArray(value)) {
|
|
2356
|
+
return value.map((entry) => stripSchemaKeys(entry));
|
|
2357
|
+
}
|
|
2358
|
+
if (value && typeof value === "object") {
|
|
2359
|
+
const record = value;
|
|
2360
|
+
const cleaned = {};
|
|
2361
|
+
for (const [key, entry] of Object.entries(record)) {
|
|
2362
|
+
if (key === "$schema") {
|
|
2363
|
+
continue;
|
|
2364
|
+
}
|
|
2365
|
+
cleaned[key] = stripSchemaKeys(entry);
|
|
2366
|
+
}
|
|
2367
|
+
return cleaned;
|
|
2368
|
+
}
|
|
2369
|
+
return value;
|
|
2601
2370
|
}
|
|
2602
2371
|
|
|
2603
2372
|
// src/core/prompts/yaml-system-prompt.ts
|
|
@@ -3106,20 +2875,12 @@ function createToolMiddleware({
|
|
|
3106
2875
|
const resolvedProtocol = isTCMProtocolFactory(protocol) ? protocol() : protocol;
|
|
3107
2876
|
return {
|
|
3108
2877
|
specificationVersion: "v3",
|
|
3109
|
-
wrapStream: ({ doStream, doGenerate, params }) => {
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
}
|
|
3116
|
-
return wrapStream({
|
|
3117
|
-
protocol: resolvedProtocol,
|
|
3118
|
-
doStream,
|
|
3119
|
-
doGenerate,
|
|
3120
|
-
params
|
|
3121
|
-
});
|
|
3122
|
-
},
|
|
2878
|
+
wrapStream: ({ doStream, doGenerate, params }) => wrapStream({
|
|
2879
|
+
protocol: resolvedProtocol,
|
|
2880
|
+
doStream,
|
|
2881
|
+
doGenerate,
|
|
2882
|
+
params
|
|
2883
|
+
}),
|
|
3123
2884
|
wrapGenerate: async ({ doGenerate, params }) => wrapGenerate({
|
|
3124
2885
|
protocol: resolvedProtocol,
|
|
3125
2886
|
doGenerate,
|