@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/index.cjs CHANGED
@@ -31,17 +31,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/index.ts
32
32
  var src_exports = {};
33
33
  __export(src_exports, {
34
- applyHeuristicPipeline: () => applyHeuristicPipeline,
35
- balanceTagsHeuristic: () => balanceTagsHeuristic,
36
34
  createDynamicIfThenElseSchema: () => createDynamicIfThenElseSchema,
37
- createIntermediateCall: () => createIntermediateCall,
38
35
  createToolMiddleware: () => createToolMiddleware,
39
36
  decodeOriginalTools: () => decodeOriginalTools,
40
- dedupeShellStringTagsHeuristic: () => dedupeShellStringTagsHeuristic,
41
- defaultPipelineConfig: () => defaultPipelineConfig,
42
37
  encodeOriginalTools: () => encodeOriginalTools,
43
- escapeInvalidLtHeuristic: () => escapeInvalidLtHeuristic,
44
- escapeRegExp: () => escapeRegExp2,
38
+ escapeRegExp: () => escapeRegExp,
45
39
  extractOnErrorOption: () => extractOnErrorOption,
46
40
  extractToolNamesFromOriginalTools: () => extractToolNamesFromOriginalTools,
47
41
  getDebugLevel: () => getDebugLevel,
@@ -57,10 +51,7 @@ __export(src_exports, {
57
51
  logParsedChunk: () => logParsedChunk,
58
52
  logParsedSummary: () => logParsedSummary,
59
53
  logRawChunk: () => logRawChunk,
60
- mergePipelineConfigs: () => mergePipelineConfigs,
61
- normalizeCloseTagsHeuristic: () => normalizeCloseTagsHeuristic,
62
54
  originalToolsSchema: () => originalToolsSchema,
63
- repairAgainstSchemaHeuristic: () => repairAgainstSchemaHeuristic,
64
55
  toolChoiceStream: () => toolChoiceStream,
65
56
  transformParams: () => transformParams,
66
57
  wrapGenerate: () => wrapGenerate,
@@ -73,473 +64,6 @@ __export(src_exports, {
73
64
  module.exports = __toCommonJS(src_exports);
74
65
  __reExport(src_exports, require("@ai-sdk-tool/rjson"), module.exports);
75
66
 
76
- // src/core/heuristics/engine.ts
77
- function applyRawSegmentUpdate(current, result) {
78
- if (result.rawSegment !== void 0) {
79
- return { ...current, rawSegment: result.rawSegment };
80
- }
81
- return current;
82
- }
83
- function applyParsedUpdate(current, result) {
84
- if (result.parsed !== void 0) {
85
- return { ...current, parsed: result.parsed };
86
- }
87
- return current;
88
- }
89
- function applyWarningsUpdate(current, result) {
90
- var _a, _b;
91
- if (result.warnings && result.warnings.length > 0) {
92
- const meta = (_a = current.meta) != null ? _a : {};
93
- const existingWarnings = (_b = meta.warnings) != null ? _b : [];
94
- return {
95
- ...current,
96
- meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
97
- };
98
- }
99
- return current;
100
- }
101
- function attemptReparse(current, result, reparseCount, maxReparses, parse3) {
102
- if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
103
- return { state: current, newCount: reparseCount };
104
- }
105
- try {
106
- const reparsed = parse3(result.rawSegment, current.schema);
107
- return {
108
- state: { ...current, parsed: reparsed, errors: [] },
109
- newCount: reparseCount + 1
110
- };
111
- } catch (error) {
112
- return {
113
- state: { ...current, errors: [...current.errors, error] },
114
- newCount: reparseCount + 1
115
- };
116
- }
117
- }
118
- function executePhase(ctx, heuristics, options) {
119
- var _a;
120
- let current = ctx;
121
- let reparseCount = 0;
122
- const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
123
- for (const heuristic of heuristics) {
124
- if (!heuristic.applies(current)) {
125
- continue;
126
- }
127
- const result = heuristic.run(current);
128
- current = applyRawSegmentUpdate(current, result);
129
- current = applyParsedUpdate(current, result);
130
- current = applyWarningsUpdate(current, result);
131
- const reparseResult = attemptReparse(
132
- current,
133
- result,
134
- reparseCount,
135
- maxReparses,
136
- options.parse
137
- );
138
- current = reparseResult.state;
139
- reparseCount = reparseResult.newCount;
140
- if (result.stop) {
141
- break;
142
- }
143
- }
144
- return current;
145
- }
146
- function applyHeuristicPipeline(ctx, config, options) {
147
- let current = ctx;
148
- if (config.preParse && config.preParse.length > 0) {
149
- current = executePhase(current, config.preParse, options);
150
- }
151
- if (current.parsed === null && current.errors.length === 0) {
152
- try {
153
- const parsed = options.parse(current.rawSegment, current.schema);
154
- current = { ...current, parsed, errors: [] };
155
- } catch (error) {
156
- current = { ...current, errors: [error] };
157
- }
158
- }
159
- if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
160
- current = executePhase(current, config.fallbackReparse, options);
161
- }
162
- if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
163
- current = executePhase(current, config.postParse, options);
164
- }
165
- return current;
166
- }
167
- function createIntermediateCall(toolName, rawSegment, schema) {
168
- return {
169
- toolName,
170
- schema,
171
- rawSegment,
172
- parsed: null,
173
- errors: [],
174
- meta: { originalContent: rawSegment }
175
- };
176
- }
177
- function mergePipelineConfigs(...configs) {
178
- var _a, _b, _c;
179
- const result = {
180
- preParse: [],
181
- fallbackReparse: [],
182
- postParse: []
183
- };
184
- for (const config of configs) {
185
- if (config.preParse) {
186
- result.preParse = [...(_a = result.preParse) != null ? _a : [], ...config.preParse];
187
- }
188
- if (config.fallbackReparse) {
189
- result.fallbackReparse = [
190
- ...(_b = result.fallbackReparse) != null ? _b : [],
191
- ...config.fallbackReparse
192
- ];
193
- }
194
- if (config.postParse) {
195
- result.postParse = [...(_c = result.postParse) != null ? _c : [], ...config.postParse];
196
- }
197
- }
198
- return result;
199
- }
200
-
201
- // src/core/heuristics/xml-defaults.ts
202
- var import_rxml = require("@ai-sdk-tool/rxml");
203
- var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
204
- var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
205
- var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
206
- var WHITESPACE_REGEX = /\s/;
207
- var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
208
- var NAME_START_CHAR_RE = /[A-Za-z_:]/;
209
- var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
210
- var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
211
- var normalizeCloseTagsHeuristic = {
212
- id: "normalize-close-tags",
213
- phase: "pre-parse",
214
- applies: () => true,
215
- run: (ctx) => {
216
- const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
217
- if (normalized !== ctx.rawSegment) {
218
- return { rawSegment: normalized };
219
- }
220
- return {};
221
- }
222
- };
223
- var escapeInvalidLtHeuristic = {
224
- id: "escape-invalid-lt",
225
- phase: "pre-parse",
226
- applies: () => true,
227
- run: (ctx) => {
228
- const escaped = escapeInvalidLt(ctx.rawSegment);
229
- if (escaped !== ctx.rawSegment) {
230
- return { rawSegment: escaped };
231
- }
232
- return {};
233
- }
234
- };
235
- var balanceTagsHeuristic = {
236
- id: "balance-tags",
237
- phase: "fallback-reparse",
238
- applies: (ctx) => {
239
- var _a;
240
- const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
241
- const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
242
- const balanced = balanceTags(original);
243
- const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
244
- if (!hasMalformedClose && balanced.length > normalized.length) {
245
- return false;
246
- }
247
- return balanced !== normalized;
248
- },
249
- run: (ctx) => {
250
- var _a;
251
- const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
252
- const balanced = balanceTags(original);
253
- const escaped = escapeInvalidLt(balanced);
254
- return { rawSegment: escaped, reparse: true };
255
- }
256
- };
257
- var dedupeShellStringTagsHeuristic = {
258
- id: "dedupe-shell-string-tags",
259
- phase: "fallback-reparse",
260
- applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
261
- run: (ctx) => {
262
- const names = getStringPropertyNames(ctx.schema);
263
- let deduped = ctx.rawSegment;
264
- for (const key of names) {
265
- deduped = dedupeSingleTag(deduped, key);
266
- }
267
- if (deduped !== ctx.rawSegment) {
268
- return { rawSegment: deduped, reparse: true };
269
- }
270
- return {};
271
- }
272
- };
273
- var repairAgainstSchemaHeuristic = {
274
- id: "repair-against-schema",
275
- phase: "post-parse",
276
- applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
277
- run: (ctx) => {
278
- const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
279
- if (repaired !== ctx.parsed) {
280
- return { parsed: repaired };
281
- }
282
- return {};
283
- }
284
- };
285
- var defaultPipelineConfig = {
286
- preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
287
- fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
288
- postParse: [repairAgainstSchemaHeuristic]
289
- };
290
- var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
291
- function isIndexTagAt(xml, pos) {
292
- const remaining = xml.slice(pos);
293
- return INDEX_TAG_RE.test(remaining);
294
- }
295
- function escapeInvalidLt(xml) {
296
- const len = xml.length;
297
- let out = "";
298
- for (let i = 0; i < len; i += 1) {
299
- const ch = xml[i];
300
- if (ch === "<") {
301
- const next = i + 1 < len ? xml[i + 1] : "";
302
- const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
303
- const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
304
- if (!(isValidStart || isIndexTag)) {
305
- out += "&lt;";
306
- continue;
307
- }
308
- }
309
- out += ch;
310
- }
311
- return out;
312
- }
313
- function balanceTags(xml) {
314
- const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
315
- let i = 0;
316
- const len = src.length;
317
- const out = [];
318
- const stack = [];
319
- while (i < len) {
320
- const lt = src.indexOf("<", i);
321
- if (lt === -1) {
322
- out.push(src.slice(i));
323
- break;
324
- }
325
- out.push(src.slice(i, lt));
326
- if (lt + 1 >= len) {
327
- break;
328
- }
329
- const next = src[lt + 1];
330
- if (next === "!" || next === "?") {
331
- i = handleSpecialTagSegment(src, lt, out);
332
- continue;
333
- }
334
- if (next === "/") {
335
- i = handleClosingTagSegment(src, lt, out, stack);
336
- continue;
337
- }
338
- i = handleOpeningTagSegment(src, lt, out, stack);
339
- }
340
- for (let k = stack.length - 1; k >= 0; k -= 1) {
341
- out.push(`</${stack[k]}>`);
342
- }
343
- return out.join("");
344
- }
345
- function skipWs(s, p, len) {
346
- let idx = p;
347
- while (idx < len && WHITESPACE_REGEX.test(s[idx])) {
348
- idx += 1;
349
- }
350
- return idx;
351
- }
352
- function parseTagNameAt(s, p, len) {
353
- let idx = p;
354
- const start = idx;
355
- while (idx < len && NAME_CHAR_RE.test(s[idx])) {
356
- idx += 1;
357
- }
358
- return { name: s.slice(start, idx), pos: idx };
359
- }
360
- function handleSpecialTagSegment(src, lt, out) {
361
- const gt = src.indexOf(">", lt + 1);
362
- if (gt === -1) {
363
- out.push(src.slice(lt));
364
- return src.length;
365
- }
366
- out.push(src.slice(lt, gt + 1));
367
- return gt + 1;
368
- }
369
- function handleClosingTagSegment(src, lt, out, stack) {
370
- const len = src.length;
371
- let p = skipWs(src, lt + 2, len);
372
- const { name, pos } = parseTagNameAt(src, p, len);
373
- p = pos;
374
- const gt = src.indexOf(">", p);
375
- const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
376
- const idx = stack.lastIndexOf(name);
377
- if (idx !== -1) {
378
- for (let k = stack.length - 1; k > idx; k -= 1) {
379
- out.push(`</${stack[k]}>`);
380
- stack.pop();
381
- }
382
- out.push(closingText);
383
- stack.pop();
384
- }
385
- return gt === -1 ? len : gt + 1;
386
- }
387
- function handleOpeningTagSegment(src, lt, out, stack) {
388
- const len = src.length;
389
- let p = skipWs(src, lt + 1, len);
390
- const nameStart = p;
391
- const parsed = parseTagNameAt(src, p, len);
392
- p = parsed.pos;
393
- const name = src.slice(nameStart, p);
394
- const q = src.indexOf(">", p);
395
- if (q === -1) {
396
- out.push(src.slice(lt));
397
- return len;
398
- }
399
- let r = q - 1;
400
- while (r >= nameStart && WHITESPACE_REGEX.test(src[r])) {
401
- r -= 1;
402
- }
403
- const selfClosing = src[r] === "/";
404
- out.push(src.slice(lt, q + 1));
405
- if (!selfClosing && name) {
406
- stack.push(name);
407
- }
408
- return q + 1;
409
- }
410
- function extractSchemaProperties(schema) {
411
- const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
412
- if (!unwrapped || typeof unwrapped !== "object") {
413
- return void 0;
414
- }
415
- return unwrapped.properties;
416
- }
417
- function shouldDeduplicateStringTags(schema) {
418
- const props = extractSchemaProperties(schema);
419
- if (!props) {
420
- return false;
421
- }
422
- const commandRaw = props.command;
423
- if (!commandRaw) {
424
- return false;
425
- }
426
- const command = (0, import_rxml.unwrapJsonSchema)(commandRaw);
427
- return (command == null ? void 0 : command.type) === "array";
428
- }
429
- function getStringPropertyNames(schema) {
430
- const props = extractSchemaProperties(schema);
431
- if (!props) {
432
- return [];
433
- }
434
- const names = [];
435
- for (const key of Object.keys(props)) {
436
- const prop = (0, import_rxml.unwrapJsonSchema)(props[key]);
437
- if ((prop == null ? void 0 : prop.type) === "string") {
438
- names.push(key);
439
- }
440
- }
441
- return names;
442
- }
443
- function escapeRegExp(s) {
444
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
445
- }
446
- function dedupeSingleTag(xml, key) {
447
- var _a, _b;
448
- const escaped = escapeRegExp(key);
449
- const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
450
- const matches = Array.from(xml.matchAll(re));
451
- if (matches.length <= 1) {
452
- return xml;
453
- }
454
- const last = matches.at(-1);
455
- let result = "";
456
- let cursor = 0;
457
- for (const m of matches) {
458
- const idx = (_a = m.index) != null ? _a : 0;
459
- result += xml.slice(cursor, idx);
460
- if (last && idx === ((_b = last.index) != null ? _b : -1)) {
461
- result += m[0];
462
- }
463
- cursor = idx + m[0].length;
464
- }
465
- result += xml.slice(cursor);
466
- return result;
467
- }
468
- function repairParsedAgainstSchema(input, schema) {
469
- if (!input || typeof input !== "object") {
470
- return input;
471
- }
472
- const properties = extractSchemaProperties(schema);
473
- if (!properties) {
474
- return input;
475
- }
476
- applySchemaProps(input, properties);
477
- return input;
478
- }
479
- function applySchemaProps(obj, properties) {
480
- for (const key of Object.keys(obj)) {
481
- const propSchema = properties[key];
482
- if (!propSchema) {
483
- continue;
484
- }
485
- const prop = (0, import_rxml.unwrapJsonSchema)(propSchema);
486
- if ((prop == null ? void 0 : prop.type) === "array" && prop.items) {
487
- const itemSchema = (0, import_rxml.unwrapJsonSchema)(prop.items);
488
- obj[key] = coerceArrayItems(obj[key], itemSchema);
489
- continue;
490
- }
491
- if ((prop == null ? void 0 : prop.type) === "object") {
492
- const val = obj[key];
493
- if (val && typeof val === "object") {
494
- obj[key] = repairParsedAgainstSchema(val, prop);
495
- }
496
- }
497
- }
498
- }
499
- function coerceArrayItems(val, itemSchema) {
500
- if (!Array.isArray(val)) {
501
- return val;
502
- }
503
- return val.map((v) => coerceArrayItem(v, itemSchema));
504
- }
505
- function coerceArrayItem(v, itemSchema) {
506
- const itemType = itemSchema == null ? void 0 : itemSchema.type;
507
- if (typeof v === "string" && itemType === "object") {
508
- const parsed = tryParseStringToSchemaObject(v, itemSchema);
509
- if (parsed !== null) {
510
- return parsed;
511
- }
512
- const fallback = extractStepStatusFromString(
513
- v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
514
- );
515
- if (fallback) {
516
- return fallback;
517
- }
518
- return v;
519
- }
520
- if (v && typeof v === "object" && itemType === "object") {
521
- return repairParsedAgainstSchema(v, itemSchema);
522
- }
523
- return v;
524
- }
525
- function tryParseStringToSchemaObject(xml, itemSchema) {
526
- try {
527
- const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
528
- const fixed = (0, import_rxml.parse)(normalized, itemSchema, { noChildNodes: [] });
529
- return typeof fixed === "string" ? null : fixed;
530
- } catch (e) {
531
- return null;
532
- }
533
- }
534
- function extractStepStatusFromString(normXml) {
535
- const stepMatch = normXml.match(STEP_TAG_RE);
536
- const statusMatch = normXml.match(STATUS_TAG_RE);
537
- if (stepMatch && statusMatch) {
538
- return { step: stepMatch[1], status: statusMatch[1] };
539
- }
540
- return null;
541
- }
542
-
543
67
  // src/core/protocols/json-protocol.ts
544
68
  var import_rjson = require("@ai-sdk-tool/rjson");
545
69
 
@@ -722,7 +246,7 @@ function generateId() {
722
246
  }
723
247
 
724
248
  // src/core/utils/regex.ts
725
- function escapeRegExp2(literal) {
249
+ function escapeRegExp(literal) {
726
250
  return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
727
251
  }
728
252
 
@@ -969,8 +493,8 @@ var jsonProtocol = ({
969
493
  text,
970
494
  options
971
495
  }) {
972
- const startEsc = escapeRegExp2(toolCallStart);
973
- const endEsc = escapeRegExp2(toolCallEnd);
496
+ const startEsc = escapeRegExp(toolCallStart);
497
+ const endEsc = escapeRegExp(toolCallEnd);
974
498
  const toolCallRegex = new RegExp(
975
499
  `${startEsc}([\0-\uFFFF]*?)${endEsc}`,
976
500
  "gs"
@@ -1029,8 +553,8 @@ var jsonProtocol = ({
1029
553
  });
1030
554
  },
1031
555
  extractToolCallSegments({ text }) {
1032
- const startEsc = escapeRegExp2(toolCallStart);
1033
- const endEsc = escapeRegExp2(toolCallEnd);
556
+ const startEsc = escapeRegExp(toolCallStart);
557
+ const endEsc = escapeRegExp(toolCallEnd);
1034
558
  const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
1035
559
  const segments = [];
1036
560
  let m = regex.exec(text);
@@ -1051,93 +575,44 @@ function isTCMProtocolFactory(protocol) {
1051
575
  }
1052
576
 
1053
577
  // src/core/protocols/xml-protocol.ts
1054
- var import_rxml2 = require("@ai-sdk-tool/rxml");
1055
- var defaultPipelineConfig2 = defaultPipelineConfig;
1056
- var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
1057
- var WHITESPACE_REGEX2 = /\s/;
578
+ var import_rxml = require("@ai-sdk-tool/rxml");
579
+ var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
580
+ var WHITESPACE_REGEX = /\s/;
1058
581
  function getToolSchema(tools, toolName) {
1059
582
  var _a;
1060
583
  return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1061
584
  }
1062
- function normalizeCloseTags(xml) {
1063
- return xml.replace(/<\/\s+([A-Za-z0-9_:-]+)\s*>/g, "</$1>");
1064
- }
1065
- function tryParseSecondaryXml(content, toolSchema, options) {
1066
- const balanced = balanceTags(content);
1067
- try {
1068
- let parsed = (0, import_rxml2.parse)(balanced, toolSchema, {
1069
- onError: options == null ? void 0 : options.onError,
1070
- noChildNodes: []
1071
- });
1072
- parsed = repairParsedAgainstSchema(parsed, toolSchema);
1073
- return parsed;
1074
- } catch (e) {
1075
- if (shouldDeduplicateStringTags(toolSchema)) {
1076
- const names = getStringPropertyNames(toolSchema);
1077
- let deduped = balanced;
1078
- for (const key of names) {
1079
- deduped = dedupeSingleTag(deduped, key);
1080
- }
1081
- if (deduped !== balanced) {
1082
- try {
1083
- let reparsed = (0, import_rxml2.parse)(deduped, toolSchema, {
1084
- onError: options == null ? void 0 : options.onError,
1085
- noChildNodes: []
1086
- });
1087
- reparsed = repairParsedAgainstSchema(reparsed, toolSchema);
1088
- return reparsed;
1089
- } catch (e2) {
1090
- return null;
1091
- }
1092
- }
1093
- }
1094
- return null;
1095
- }
1096
- }
1097
- function processToolCallWithPipeline(params) {
1098
- var _a;
1099
- const {
1100
- toolCall,
1101
- tools,
1102
- options,
1103
- text,
1104
- processedElements,
1105
- pipelineConfig = defaultPipelineConfig2,
1106
- maxReparses
1107
- } = params;
585
+ function processToolCall(params) {
586
+ var _a, _b;
587
+ const { toolCall, tools, options, text, processedElements, parseOptions } = params;
1108
588
  const toolSchema = getToolSchema(tools, toolCall.toolName);
1109
- const ctx = createIntermediateCall(
1110
- toolCall.toolName,
1111
- toolCall.content,
1112
- toolSchema
1113
- );
1114
- const result = applyHeuristicPipeline(ctx, pipelineConfig, {
1115
- parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
1116
- onError: options == null ? void 0 : options.onError,
1117
- maxReparses
1118
- });
1119
- if (result.parsed !== null) {
589
+ const parseConfig = {
590
+ ...parseOptions != null ? parseOptions : {},
591
+ onError: (_a = options == null ? void 0 : options.onError) != null ? _a : parseOptions == null ? void 0 : parseOptions.onError
592
+ };
593
+ try {
594
+ const parsed = (0, import_rxml.parse)(toolCall.content, toolSchema, parseConfig);
1120
595
  processedElements.push({
1121
596
  type: "tool-call",
1122
597
  toolCallId: generateId(),
1123
598
  toolName: toolCall.toolName,
1124
- input: JSON.stringify(result.parsed)
599
+ input: JSON.stringify(parsed)
1125
600
  });
1126
- } else {
601
+ } catch (error) {
1127
602
  const originalCallText = text.substring(
1128
603
  toolCall.startIndex,
1129
604
  toolCall.endIndex
1130
605
  );
1131
- (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
606
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
1132
607
  options,
1133
608
  `Could not process XML tool call: ${toolCall.toolName}`,
1134
- { toolCall: originalCallText, error: result.errors[0] }
609
+ { toolCall: originalCallText, error }
1135
610
  );
1136
611
  processedElements.push({ type: "text", text: originalCallText });
1137
612
  }
1138
613
  }
1139
614
  function handleStreamingToolCallEnd(params) {
1140
- var _a;
615
+ var _a, _b;
1141
616
  const {
1142
617
  toolContent,
1143
618
  currentToolCall,
@@ -1145,51 +620,27 @@ function handleStreamingToolCallEnd(params) {
1145
620
  options,
1146
621
  ctrl,
1147
622
  flushText,
1148
- pipelineConfig,
1149
- maxReparses
623
+ parseOptions
1150
624
  } = params;
1151
625
  const toolSchema = getToolSchema(tools, currentToolCall.name);
1152
- let parsedResult = null;
1153
- if (pipelineConfig) {
1154
- const ctx = createIntermediateCall(
1155
- currentToolCall.name,
1156
- toolContent,
1157
- toolSchema
1158
- );
1159
- const result = applyHeuristicPipeline(ctx, pipelineConfig, {
1160
- parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
1161
- onError: options == null ? void 0 : options.onError,
1162
- maxReparses
1163
- });
1164
- parsedResult = result.parsed;
1165
- } else {
1166
- try {
1167
- const primary = escapeInvalidLt(normalizeCloseTags(toolContent));
1168
- const parsed = (0, import_rxml2.parse)(primary, toolSchema, {
1169
- onError: options == null ? void 0 : options.onError,
1170
- noChildNodes: []
1171
- });
1172
- parsedResult = repairParsedAgainstSchema(parsed, toolSchema);
1173
- } catch (e) {
1174
- parsedResult = tryParseSecondaryXml(
1175
- toolContent,
1176
- toolSchema,
1177
- options != null ? options : {}
1178
- );
1179
- }
1180
- }
626
+ const parseConfig = {
627
+ ...parseOptions != null ? parseOptions : {},
628
+ onError: (_a = options == null ? void 0 : options.onError) != null ? _a : parseOptions == null ? void 0 : parseOptions.onError
629
+ };
1181
630
  flushText(ctrl);
1182
- if (parsedResult !== null) {
631
+ try {
632
+ const parsedResult = (0, import_rxml.parse)(toolContent, toolSchema, parseConfig);
1183
633
  ctrl.enqueue({
1184
634
  type: "tool-call",
1185
635
  toolCallId: generateId(),
1186
636
  toolName: currentToolCall.name,
1187
637
  input: JSON.stringify(parsedResult)
1188
638
  });
1189
- } else {
639
+ } catch (error) {
1190
640
  const original = `<${currentToolCall.name}>${toolContent}</${currentToolCall.name}>`;
1191
- (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not process streaming XML tool call", {
1192
- toolCall: original
641
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, "Could not process streaming XML tool call", {
642
+ toolCall: original,
643
+ error
1193
644
  });
1194
645
  flushText(ctrl, original);
1195
646
  }
@@ -1228,11 +679,11 @@ function consumeClosingTag(text, lt) {
1228
679
  }
1229
680
  function consumeOpenTag(text, lt) {
1230
681
  let p = lt + 1;
1231
- while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
682
+ while (p < text.length && WHITESPACE_REGEX.test(text[p])) {
1232
683
  p += 1;
1233
684
  }
1234
685
  const nameStart = p;
1235
- while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
686
+ while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
1236
687
  p += 1;
1237
688
  }
1238
689
  const name = text.slice(nameStart, p);
@@ -1241,7 +692,7 @@ function consumeOpenTag(text, lt) {
1241
692
  return null;
1242
693
  }
1243
694
  let r = q - 1;
1244
- while (r >= nameStart && WHITESPACE_REGEX2.test(text[r])) {
695
+ while (r >= nameStart && WHITESPACE_REGEX.test(text[r])) {
1245
696
  r -= 1;
1246
697
  }
1247
698
  const selfClosing = text[r] === "/";
@@ -1270,11 +721,11 @@ function nextTagToken(text, fromPos) {
1270
721
  if (next === "/") {
1271
722
  const closing = consumeClosingTag(text, lt);
1272
723
  let p = lt + 2;
1273
- while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
724
+ while (p < text.length && WHITESPACE_REGEX.test(text[p])) {
1274
725
  p += 1;
1275
726
  }
1276
727
  const nameStart = p;
1277
- while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
728
+ while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
1278
729
  p += 1;
1279
730
  }
1280
731
  const name = text.slice(nameStart, p);
@@ -1291,49 +742,111 @@ function nextTagToken(text, fromPos) {
1291
742
  nextPos: open.nextPos
1292
743
  };
1293
744
  }
745
+ function findNextToolTag(text, searchIndex, toolName) {
746
+ var _a, _b;
747
+ const startTag = `<${toolName}>`;
748
+ const openIdx = text.indexOf(startTag, searchIndex);
749
+ const selfMatch = findSelfClosingTag(text, toolName, searchIndex);
750
+ const selfIdx = (_a = selfMatch == null ? void 0 : selfMatch.index) != null ? _a : -1;
751
+ if (openIdx === -1 && selfIdx === -1) {
752
+ return null;
753
+ }
754
+ const isSelfClosing = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx);
755
+ return {
756
+ tagStart: isSelfClosing ? selfIdx : openIdx,
757
+ isSelfClosing,
758
+ tagLength: isSelfClosing ? (_b = selfMatch == null ? void 0 : selfMatch.length) != null ? _b : 0 : startTag.length
759
+ };
760
+ }
761
+ function findLastCloseTagStart(segment, toolName) {
762
+ const closeTagPattern = new RegExp(
763
+ `</\\s*${escapeRegExp(toolName)}\\s*>`,
764
+ "g"
765
+ );
766
+ let closeTagStart = -1;
767
+ let match = closeTagPattern.exec(segment);
768
+ while (match !== null) {
769
+ closeTagStart = match.index;
770
+ match = closeTagPattern.exec(segment);
771
+ }
772
+ if (closeTagStart === -1) {
773
+ return segment.lastIndexOf("<");
774
+ }
775
+ return closeTagStart;
776
+ }
777
+ function pushSelfClosingToolCall(toolCalls, toolName, text, tagStart, tagLength) {
778
+ const endIndex = tagStart + tagLength;
779
+ toolCalls.push({
780
+ toolName,
781
+ startIndex: tagStart,
782
+ endIndex,
783
+ content: "",
784
+ segment: text.substring(tagStart, endIndex)
785
+ });
786
+ return endIndex;
787
+ }
788
+ var selfClosingTagCache = /* @__PURE__ */ new Map();
789
+ function getSelfClosingTagPattern(toolName) {
790
+ let pattern = selfClosingTagCache.get(toolName);
791
+ if (!pattern) {
792
+ pattern = new RegExp(`<\\s*${escapeRegExp(toolName)}\\s*/>`, "g");
793
+ selfClosingTagCache.set(toolName, pattern);
794
+ }
795
+ return pattern;
796
+ }
797
+ function findSelfClosingTag(text, toolName, fromIndex) {
798
+ const pattern = getSelfClosingTagPattern(toolName);
799
+ pattern.lastIndex = fromIndex;
800
+ const match = pattern.exec(text);
801
+ if (!match || match.index === void 0) {
802
+ return null;
803
+ }
804
+ return { index: match.index, length: match[0].length };
805
+ }
806
+ function appendOpenToolCallIfComplete(toolCalls, text, toolName, tagStart, startTag) {
807
+ const contentStart = tagStart + startTag.length;
808
+ const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
809
+ if (fullTagEnd === -1 || fullTagEnd <= contentStart) {
810
+ return contentStart;
811
+ }
812
+ const segment = text.substring(tagStart, fullTagEnd);
813
+ const closeTagStart = findLastCloseTagStart(segment, toolName);
814
+ const inner = closeTagStart === -1 ? segment.slice(startTag.length) : segment.slice(startTag.length, closeTagStart);
815
+ toolCalls.push({
816
+ toolName,
817
+ startIndex: tagStart,
818
+ endIndex: fullTagEnd,
819
+ content: inner,
820
+ segment
821
+ });
822
+ return fullTagEnd;
823
+ }
1294
824
  function findToolCallsForName(text, toolName) {
1295
- var _a;
1296
825
  const toolCalls = [];
826
+ const startTag = `<${toolName}>`;
1297
827
  let searchIndex = 0;
1298
828
  while (searchIndex < text.length) {
1299
- const startTag = `<${toolName}>`;
1300
- const selfTag = `<${toolName}/>`;
1301
- const openIdx = text.indexOf(startTag, searchIndex);
1302
- const selfIdx = text.indexOf(selfTag, searchIndex);
1303
- if (openIdx === -1 && selfIdx === -1) {
829
+ const match = findNextToolTag(text, searchIndex, toolName);
830
+ if (match === null) {
1304
831
  break;
1305
832
  }
1306
- const tagStart = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx) ? selfIdx : openIdx;
1307
- const isSelfClosing = tagStart === selfIdx;
1308
- if (isSelfClosing) {
1309
- const endIndex = tagStart + selfTag.length;
1310
- const segment = text.substring(tagStart, endIndex);
1311
- toolCalls.push({
833
+ if (match.isSelfClosing) {
834
+ searchIndex = pushSelfClosingToolCall(
835
+ toolCalls,
1312
836
  toolName,
1313
- startIndex: tagStart,
1314
- endIndex,
1315
- content: "",
1316
- segment
1317
- });
1318
- searchIndex = endIndex;
837
+ text,
838
+ match.tagStart,
839
+ match.tagLength
840
+ );
1319
841
  continue;
1320
842
  }
1321
- const contentStart = tagStart + startTag.length;
1322
- const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
1323
- if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
1324
- const segment = text.substring(tagStart, fullTagEnd);
1325
- const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
1326
- toolCalls.push({
1327
- toolName,
1328
- startIndex: tagStart,
1329
- endIndex: fullTagEnd,
1330
- content: inner,
1331
- segment
1332
- });
1333
- searchIndex = fullTagEnd;
1334
- } else {
1335
- searchIndex = contentStart;
1336
- }
843
+ searchIndex = appendOpenToolCallIfComplete(
844
+ toolCalls,
845
+ text,
846
+ toolName,
847
+ match.tagStart,
848
+ startTag
849
+ );
1337
850
  }
1338
851
  return toolCalls;
1339
852
  }
@@ -1346,28 +859,114 @@ function findToolCalls(text, toolNames) {
1346
859
  return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
1347
860
  }
1348
861
  function findEarliestToolTag(buffer, toolNames) {
862
+ var _a, _b;
1349
863
  let bestIndex = -1;
1350
864
  let bestName = "";
1351
865
  let bestSelfClosing = false;
866
+ let bestTagLength = 0;
1352
867
  if (toolNames.length > 0) {
1353
868
  for (const name of toolNames) {
1354
869
  const openTag = `<${name}>`;
1355
- const selfTag = `<${name}/>`;
1356
870
  const idxOpen = buffer.indexOf(openTag);
1357
- const idxSelf = buffer.indexOf(selfTag);
871
+ const selfMatch = findSelfClosingTag(buffer, name, 0);
872
+ const idxSelf = (_a = selfMatch == null ? void 0 : selfMatch.index) != null ? _a : -1;
1358
873
  if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
1359
874
  bestIndex = idxOpen;
1360
875
  bestName = name;
1361
876
  bestSelfClosing = false;
877
+ bestTagLength = openTag.length;
1362
878
  }
1363
879
  if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
1364
880
  bestIndex = idxSelf;
1365
881
  bestName = name;
1366
882
  bestSelfClosing = true;
883
+ bestTagLength = (_b = selfMatch == null ? void 0 : selfMatch.length) != null ? _b : 0;
1367
884
  }
1368
885
  }
1369
886
  }
1370
- return { index: bestIndex, name: bestName, selfClosing: bestSelfClosing };
887
+ return {
888
+ index: bestIndex,
889
+ name: bestName,
890
+ selfClosing: bestSelfClosing,
891
+ tagLength: bestTagLength
892
+ };
893
+ }
894
+ function isOpenTagPrefix(suffix, toolName) {
895
+ return `${toolName}>`.startsWith(suffix);
896
+ }
897
+ function consumeWhitespace(text, index) {
898
+ let i = index;
899
+ while (i < text.length && WHITESPACE_REGEX.test(text.charAt(i))) {
900
+ i += 1;
901
+ }
902
+ return i;
903
+ }
904
+ function consumeToolNamePrefix(text, index, toolName) {
905
+ let i = index;
906
+ let nameIndex = 0;
907
+ while (i < text.length && nameIndex < toolName.length) {
908
+ if (text.charAt(i) !== toolName.charAt(nameIndex)) {
909
+ return { index: i, done: false, valid: false };
910
+ }
911
+ i += 1;
912
+ nameIndex += 1;
913
+ }
914
+ return { index: i, done: nameIndex === toolName.length, valid: true };
915
+ }
916
+ function isSelfClosingSuffixRemainder(text, index) {
917
+ if (text.charAt(index) !== "/") {
918
+ return false;
919
+ }
920
+ if (index + 1 >= text.length) {
921
+ return true;
922
+ }
923
+ return index + 1 === text.length - 1 && text.charAt(index + 1) === ">";
924
+ }
925
+ function isSelfClosingTagPrefix(suffix, toolName) {
926
+ let i = consumeWhitespace(suffix, 0);
927
+ if (i >= suffix.length) {
928
+ return true;
929
+ }
930
+ const nameRemainder = suffix.slice(i);
931
+ if (toolName.startsWith(nameRemainder)) {
932
+ return true;
933
+ }
934
+ const nameResult = consumeToolNamePrefix(suffix, i, toolName);
935
+ if (!nameResult.valid) {
936
+ return false;
937
+ }
938
+ i = nameResult.index;
939
+ if (i >= suffix.length) {
940
+ return true;
941
+ }
942
+ if (!nameResult.done) {
943
+ return false;
944
+ }
945
+ i = consumeWhitespace(suffix, i);
946
+ if (i >= suffix.length) {
947
+ return true;
948
+ }
949
+ return isSelfClosingSuffixRemainder(suffix, i);
950
+ }
951
+ function findPotentialToolTagStart(buffer, toolNames) {
952
+ if (toolNames.length === 0 || buffer.length === 0) {
953
+ return -1;
954
+ }
955
+ const lastGt = buffer.lastIndexOf(">");
956
+ const offset = lastGt === -1 ? 0 : lastGt + 1;
957
+ const trailing = buffer.slice(offset);
958
+ for (let i = trailing.length - 1; i >= 0; i -= 1) {
959
+ if (trailing.charAt(i) !== "<") {
960
+ continue;
961
+ }
962
+ const suffix = trailing.slice(i + 1);
963
+ for (const name of toolNames) {
964
+ if (isOpenTagPrefix(suffix, name) || isSelfClosingTagPrefix(suffix, name)) {
965
+ return offset + i;
966
+ }
967
+ }
968
+ }
969
+ return -1;
1371
970
  }
1372
971
  function createFlushTextHandler(getCurrentTextId, setCurrentTextId, getHasEmittedTextStart, setHasEmittedTextStart) {
1373
972
  return (controller, text) => {
@@ -1410,16 +1009,20 @@ function processToolCallInBuffer(params) {
1410
1009
  controller,
1411
1010
  flushText,
1412
1011
  setBuffer,
1413
- pipelineConfig,
1414
- maxReparses
1012
+ parseOptions
1415
1013
  } = params;
1416
- const endTag = `</${currentToolCall.name}>`;
1417
- const endIdx = buffer.indexOf(endTag);
1418
- if (endIdx === -1) {
1014
+ const endTagPattern = new RegExp(
1015
+ `</\\s*${escapeRegExp(currentToolCall.name)}\\s*>`
1016
+ );
1017
+ const endMatch = endTagPattern.exec(buffer);
1018
+ if (!endMatch || endMatch.index === void 0) {
1419
1019
  return { buffer, currentToolCall, shouldBreak: true };
1420
1020
  }
1021
+ const endIdx = endMatch.index;
1022
+ const endPos = endIdx + endMatch[0].length;
1421
1023
  const content = buffer.substring(0, endIdx);
1422
- setBuffer(buffer.substring(endIdx + endTag.length));
1024
+ const remainder = buffer.substring(endPos);
1025
+ setBuffer(remainder);
1423
1026
  handleStreamingToolCallEnd({
1424
1027
  toolContent: content,
1425
1028
  currentToolCall,
@@ -1427,11 +1030,10 @@ function processToolCallInBuffer(params) {
1427
1030
  options,
1428
1031
  ctrl: controller,
1429
1032
  flushText,
1430
- pipelineConfig,
1431
- maxReparses
1033
+ parseOptions
1432
1034
  });
1433
1035
  return {
1434
- buffer: buffer.substring(endIdx + endTag.length),
1036
+ buffer: remainder,
1435
1037
  currentToolCall: null,
1436
1038
  shouldBreak: false
1437
1039
  };
@@ -1444,25 +1046,28 @@ function processNoToolCallInBuffer(params) {
1444
1046
  flushText,
1445
1047
  tools,
1446
1048
  options,
1447
- pipelineConfig,
1448
- maxReparses,
1049
+ parseOptions,
1449
1050
  setBuffer
1450
1051
  } = params;
1451
1052
  const {
1452
1053
  index: earliestStartTagIndex,
1453
1054
  name: earliestToolName,
1454
- selfClosing
1055
+ selfClosing,
1056
+ tagLength
1455
1057
  } = findEarliestToolTag(buffer, toolNames);
1456
1058
  if (earliestStartTagIndex === -1) {
1457
- const maxTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
1458
- const tail = Math.max(0, maxTagLen - 1);
1459
- const safeLen = Math.max(0, buffer.length - tail);
1059
+ const potentialStart = findPotentialToolTagStart(buffer, toolNames);
1060
+ const safeLen = Math.max(
1061
+ 0,
1062
+ potentialStart === -1 ? buffer.length : potentialStart
1063
+ );
1064
+ const remaining = buffer.slice(safeLen);
1460
1065
  if (safeLen > 0) {
1461
1066
  flushText(controller, buffer.slice(0, safeLen));
1462
- setBuffer(buffer.slice(safeLen));
1067
+ setBuffer(remaining);
1463
1068
  }
1464
1069
  return {
1465
- buffer: buffer.slice(safeLen),
1070
+ buffer: remaining,
1466
1071
  currentToolCall: null,
1467
1072
  shouldBreak: true,
1468
1073
  shouldContinue: false
@@ -1470,8 +1075,7 @@ function processNoToolCallInBuffer(params) {
1470
1075
  }
1471
1076
  flushText(controller, buffer.substring(0, earliestStartTagIndex));
1472
1077
  if (selfClosing) {
1473
- const selfTag = `<${earliestToolName}/>`;
1474
- const newBuffer2 = buffer.substring(earliestStartTagIndex + selfTag.length);
1078
+ const newBuffer2 = buffer.substring(earliestStartTagIndex + tagLength);
1475
1079
  setBuffer(newBuffer2);
1476
1080
  handleStreamingToolCallEnd({
1477
1081
  toolContent: "",
@@ -1480,8 +1084,7 @@ function processNoToolCallInBuffer(params) {
1480
1084
  options,
1481
1085
  ctrl: controller,
1482
1086
  flushText,
1483
- pipelineConfig,
1484
- maxReparses
1087
+ parseOptions
1485
1088
  });
1486
1089
  return {
1487
1090
  buffer: newBuffer2,
@@ -1500,7 +1103,7 @@ function processNoToolCallInBuffer(params) {
1500
1103
  shouldContinue: true
1501
1104
  };
1502
1105
  }
1503
- function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, setCurrentToolCall, tools, options, toolNames, flushText, pipelineConfig, maxReparses) {
1106
+ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, setCurrentToolCall, tools, options, toolNames, flushText, parseOptions) {
1504
1107
  return (controller) => {
1505
1108
  while (true) {
1506
1109
  const currentToolCall = getCurrentToolCall();
@@ -1513,8 +1116,7 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
1513
1116
  controller,
1514
1117
  flushText,
1515
1118
  setBuffer,
1516
- pipelineConfig,
1517
- maxReparses
1119
+ parseOptions
1518
1120
  });
1519
1121
  setBuffer(result.buffer);
1520
1122
  setCurrentToolCall(result.currentToolCall);
@@ -1529,8 +1131,7 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
1529
1131
  flushText,
1530
1132
  tools,
1531
1133
  options,
1532
- pipelineConfig,
1533
- maxReparses,
1134
+ parseOptions,
1534
1135
  setBuffer
1535
1136
  });
1536
1137
  setBuffer(result.buffer);
@@ -1547,43 +1148,12 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
1547
1148
  };
1548
1149
  }
1549
1150
  var xmlProtocol = (protocolOptions) => {
1550
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1551
- let pipelineConfig = protocolOptions == null ? void 0 : protocolOptions.pipeline;
1552
- const maxReparses = protocolOptions == null ? void 0 : protocolOptions.maxReparses;
1553
- if ((protocolOptions == null ? void 0 : protocolOptions.heuristics) && protocolOptions.heuristics.length > 0) {
1554
- const heuristicsConfig = {
1555
- preParse: [],
1556
- fallbackReparse: [],
1557
- postParse: []
1558
- };
1559
- for (const h of protocolOptions.heuristics) {
1560
- if (h.phase === "pre-parse") {
1561
- (_a = heuristicsConfig.preParse) == null ? void 0 : _a.push(h);
1562
- } else if (h.phase === "fallback-reparse") {
1563
- (_b = heuristicsConfig.fallbackReparse) == null ? void 0 : _b.push(h);
1564
- } else if (h.phase === "post-parse") {
1565
- (_c = heuristicsConfig.postParse) == null ? void 0 : _c.push(h);
1566
- }
1567
- }
1568
- if (pipelineConfig) {
1569
- pipelineConfig = {
1570
- preParse: [
1571
- ...(_d = pipelineConfig.preParse) != null ? _d : [],
1572
- ...(_e = heuristicsConfig.preParse) != null ? _e : []
1573
- ],
1574
- fallbackReparse: [
1575
- ...(_f = pipelineConfig.fallbackReparse) != null ? _f : [],
1576
- ...(_g = heuristicsConfig.fallbackReparse) != null ? _g : []
1577
- ],
1578
- postParse: [
1579
- ...(_h = pipelineConfig.postParse) != null ? _h : [],
1580
- ...(_i = heuristicsConfig.postParse) != null ? _i : []
1581
- ]
1582
- };
1583
- } else {
1584
- pipelineConfig = heuristicsConfig;
1585
- }
1586
- }
1151
+ var _a;
1152
+ const parseOptions = {
1153
+ repair: true,
1154
+ noChildNodes: [],
1155
+ ...(_a = protocolOptions == null ? void 0 : protocolOptions.parseOptions) != null ? _a : {}
1156
+ };
1587
1157
  return {
1588
1158
  formatTools({ tools, toolSystemPromptTemplate }) {
1589
1159
  return toolSystemPromptTemplate(tools || []);
@@ -1597,7 +1167,7 @@ var xmlProtocol = (protocolOptions) => {
1597
1167
  args = toolCall.input;
1598
1168
  }
1599
1169
  }
1600
- return (0, import_rxml2.stringify)(toolCall.toolName, args, {
1170
+ return (0, import_rxml.stringify)(toolCall.toolName, args, {
1601
1171
  suppressEmptyNode: false,
1602
1172
  format: true,
1603
1173
  minimalEscaping: true
@@ -1618,14 +1188,13 @@ var xmlProtocol = (protocolOptions) => {
1618
1188
  text: text.substring(currentIndex, tc.startIndex)
1619
1189
  });
1620
1190
  }
1621
- processToolCallWithPipeline({
1191
+ processToolCall({
1622
1192
  toolCall: tc,
1623
1193
  tools,
1624
1194
  options,
1625
1195
  text,
1626
1196
  processedElements,
1627
- pipelineConfig,
1628
- maxReparses
1197
+ parseOptions
1629
1198
  });
1630
1199
  currentIndex = tc.endIndex;
1631
1200
  }
@@ -1666,8 +1235,7 @@ var xmlProtocol = (protocolOptions) => {
1666
1235
  options,
1667
1236
  toolNames,
1668
1237
  flushText,
1669
- pipelineConfig,
1670
- maxReparses
1238
+ parseOptions
1671
1239
  );
1672
1240
  return new TransformStream({
1673
1241
  transform(chunk, controller) {
@@ -1717,8 +1285,8 @@ var xmlProtocol = (protocolOptions) => {
1717
1285
 
1718
1286
  // src/core/protocols/yaml-protocol.ts
1719
1287
  var import_yaml = __toESM(require("yaml"), 1);
1720
- var NAME_CHAR_RE3 = /[A-Za-z0-9_:-]/;
1721
- var WHITESPACE_REGEX3 = /\s/;
1288
+ var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
1289
+ var WHITESPACE_REGEX2 = /\s/;
1722
1290
  var LEADING_WHITESPACE_RE = /^(\s*)/;
1723
1291
  function findClosingTagEnd(text, contentStart, toolName) {
1724
1292
  let pos = contentStart;
@@ -1735,11 +1303,11 @@ function findClosingTagEnd(text, contentStart, toolName) {
1735
1303
  break;
1736
1304
  }
1737
1305
  let p = ltIdx + 2;
1738
- while (p < gtIdx && WHITESPACE_REGEX3.test(text[p])) {
1306
+ while (p < gtIdx && WHITESPACE_REGEX2.test(text[p])) {
1739
1307
  p++;
1740
1308
  }
1741
1309
  const nameStart = p;
1742
- while (p < gtIdx && NAME_CHAR_RE3.test(text.charAt(p))) {
1310
+ while (p < gtIdx && NAME_CHAR_RE2.test(text.charAt(p))) {
1743
1311
  p++;
1744
1312
  }
1745
1313
  const name = text.slice(nameStart, p);
@@ -1755,11 +1323,11 @@ function findClosingTagEnd(text, contentStart, toolName) {
1755
1323
  pos = gtIdx === -1 ? text.length : gtIdx + 1;
1756
1324
  } else {
1757
1325
  let p = ltIdx + 1;
1758
- while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
1326
+ while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
1759
1327
  p++;
1760
1328
  }
1761
1329
  const nameStart = p;
1762
- while (p < text.length && NAME_CHAR_RE3.test(text.charAt(p))) {
1330
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
1763
1331
  p++;
1764
1332
  }
1765
1333
  const name = text.slice(nameStart, p);
@@ -1768,7 +1336,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
1768
1336
  break;
1769
1337
  }
1770
1338
  let r = gtIdx - 1;
1771
- while (r >= nameStart && WHITESPACE_REGEX3.test(text[r])) {
1339
+ while (r >= nameStart && WHITESPACE_REGEX2.test(text[r])) {
1772
1340
  r--;
1773
1341
  }
1774
1342
  const selfClosing = text[r] === "/";
@@ -2273,7 +1841,7 @@ function hasInputProperty(obj) {
2273
1841
 
2274
1842
  // src/generate-handler.ts
2275
1843
  var import_provider_utils = require("@ai-sdk/provider-utils");
2276
- var import_rxml3 = require("@ai-sdk-tool/rxml");
1844
+ var import_schema_coerce = require("@ai-sdk-tool/schema-coerce");
2277
1845
  function parseToolChoiceJson(text, providerOptions) {
2278
1846
  var _a;
2279
1847
  try {
@@ -2435,7 +2003,7 @@ function fixToolCallWithSchema(part, tools) {
2435
2003
  args = part.input;
2436
2004
  }
2437
2005
  const schema = (_a = tools.find((t) => t.name === part.toolName)) == null ? void 0 : _a.inputSchema;
2438
- const coerced = (0, import_rxml3.coerceBySchema)(args, schema);
2006
+ const coerced = (0, import_schema_coerce.coerceBySchema)(args, schema);
2439
2007
  return {
2440
2008
  ...part,
2441
2009
  input: JSON.stringify(coerced != null ? coerced : {})
@@ -2568,29 +2136,230 @@ function formatXmlNode(tagName, value, depth) {
2568
2136
  }
2569
2137
 
2570
2138
  // src/core/prompts/xml-system-prompt.ts
2139
+ var import_dedent = __toESM(require("dedent"), 1);
2571
2140
  function xmlSystemPromptTemplate(tools) {
2572
- const toolsJson = JSON.stringify(tools);
2573
- return `# Tools
2574
-
2575
- You may call one or more functions to assist with the user query.
2576
-
2577
- You are provided with function signatures within <tools></tools> XML tags:
2578
- <tools>${toolsJson}</tools>
2579
-
2580
- # Rules
2581
- - Use exactly one XML element whose tag name is the function name.
2582
- - Put each parameter as a child element.
2583
- - Values must follow the schema exactly (numbers, arrays, objects, enums \u2192 copy as-is).
2584
- - Do not add or remove functions or parameters.
2585
- - Each required parameter must appear once.
2586
- - Output nothing before or after the function call.
2587
- - 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.
2588
-
2589
- # Example
2590
- <get_weather>
2591
- <location>New York</location>
2592
- <unit>celsius</unit>
2593
- </get_weather>`;
2141
+ const toolsText = renderToolsForXmlPrompt(tools);
2142
+ const header = import_dedent.default`
2143
+ # Tools
2144
+ You may call one or more functions to assist with the user query.
2145
+ `;
2146
+ const definitions = [
2147
+ "You have access to the following functions:",
2148
+ "<tools>",
2149
+ toolsText,
2150
+ "</tools>"
2151
+ ].join("\n");
2152
+ const rules = import_dedent.default`
2153
+ <rules>
2154
+ - Use exactly one XML element whose tag name is the function name.
2155
+ - Put each parameter as a child element.
2156
+ - Values must follow the schema exactly (numbers, arrays, objects, enums copy as-is).
2157
+ - Do not add or remove functions or parameters.
2158
+ - Each required parameter must appear once.
2159
+ - Output nothing before or after the function call.
2160
+ - It is also possible to call multiple types of functions in one turn or to call a single function multiple times.
2161
+ </rules>
2162
+ `;
2163
+ const examples = import_dedent.default`
2164
+ For each function call, output the function name and parameter in the following format:
2165
+ <example_function_name>
2166
+ <example_parameter_1>value_1</example_parameter_1>
2167
+ <example_parameter_2>This is the value for the second parameter
2168
+ that can span
2169
+ multiple lines</example_parameter_2>
2170
+ </example_function_name>
2171
+ `;
2172
+ return [header, definitions, rules, examples].join("\n\n");
2173
+ }
2174
+ var INDENT = " ";
2175
+ function renderToolsForXmlPrompt(tools) {
2176
+ if (!tools.length) {
2177
+ return "none";
2178
+ }
2179
+ return tools.map(renderToolForXmlPrompt).join("\n\n");
2180
+ }
2181
+ function renderToolForXmlPrompt(tool) {
2182
+ const lines = [`name: ${tool.name}`];
2183
+ if (tool.description) {
2184
+ lines.push(`description: ${tool.description}`);
2185
+ }
2186
+ lines.push("parameters:");
2187
+ const normalizedSchema = normalizeSchema(tool.inputSchema);
2188
+ lines.push(...renderParametersSummary(normalizedSchema, 1));
2189
+ lines.push(`schema: ${stringifySchema(normalizedSchema)}`);
2190
+ return lines.join("\n");
2191
+ }
2192
+ function normalizeSchema(schema) {
2193
+ if (typeof schema === "string") {
2194
+ try {
2195
+ return JSON.parse(schema);
2196
+ } catch (e) {
2197
+ return { type: "string", const: schema };
2198
+ }
2199
+ }
2200
+ return schema;
2201
+ }
2202
+ function renderParametersSummary(schema, indentLevel) {
2203
+ var _a, _b;
2204
+ const indent = INDENT.repeat(indentLevel);
2205
+ if (schema === void 0 || schema === null) {
2206
+ return [`${indent}(none)`];
2207
+ }
2208
+ if (schema === true) {
2209
+ return [`${indent}(any)`];
2210
+ }
2211
+ if (schema === false) {
2212
+ return [`${indent}(no valid parameters)`];
2213
+ }
2214
+ if (typeof schema !== "object") {
2215
+ return [`${indent}- value (${String(schema)})`];
2216
+ }
2217
+ const schemaType = [];
2218
+ if (Array.isArray(schema.type)) {
2219
+ schemaType.push(...schema.type);
2220
+ } else if (schema.type) {
2221
+ schemaType.push(schema.type);
2222
+ }
2223
+ const isObjectLike = schemaType.includes("object") || !!schema.properties;
2224
+ if (isObjectLike) {
2225
+ const properties = (_a = schema.properties) != null ? _a : {};
2226
+ const requiredSet = new Set((_b = schema.required) != null ? _b : []);
2227
+ const propertyNames = Object.keys(properties).sort();
2228
+ if (propertyNames.length === 0) {
2229
+ return [`${indent}(no named parameters)`];
2230
+ }
2231
+ const lines = [];
2232
+ for (const propName of propertyNames) {
2233
+ const propSchema = properties[propName];
2234
+ lines.push(
2235
+ renderPropertySummaryLine({
2236
+ indent,
2237
+ propName,
2238
+ propSchema,
2239
+ required: requiredSet.has(propName)
2240
+ })
2241
+ );
2242
+ }
2243
+ return lines.length ? lines : [`${indent}(no parameters)`];
2244
+ }
2245
+ return [`${indent}- value (${summarizeType(schema)})`];
2246
+ }
2247
+ function renderPropertySummaryLine({
2248
+ indent,
2249
+ propName,
2250
+ propSchema,
2251
+ required
2252
+ }) {
2253
+ const typeLabel = summarizeType(propSchema);
2254
+ const requiredLabel = required ? "required" : "optional";
2255
+ const extras = collectPropertyExtras(propSchema);
2256
+ const extraText = extras.length ? ` - ${extras.join("; ")}` : "";
2257
+ return `${indent}- ${propName} (${typeLabel}, ${requiredLabel})${extraText}`;
2258
+ }
2259
+ function collectPropertyExtras(propSchema) {
2260
+ if (!propSchema || typeof propSchema !== "object") {
2261
+ return [];
2262
+ }
2263
+ const extras = [];
2264
+ if (propSchema.enum) {
2265
+ extras.push(`enum: ${formatEnumForSummary(propSchema.enum)}`);
2266
+ }
2267
+ if (propSchema.default !== void 0) {
2268
+ extras.push(`default: ${formatValue(propSchema.default)}`);
2269
+ }
2270
+ if (propSchema.description) {
2271
+ extras.push(propSchema.description);
2272
+ }
2273
+ return extras;
2274
+ }
2275
+ function summarizeType(schema) {
2276
+ var _a;
2277
+ if (schema === void 0 || schema === null) {
2278
+ return "unknown";
2279
+ }
2280
+ if (schema === true) {
2281
+ return "any";
2282
+ }
2283
+ if (schema === false) {
2284
+ return "never";
2285
+ }
2286
+ if (typeof schema !== "object") {
2287
+ return String(schema);
2288
+ }
2289
+ const schemaType = schema.type;
2290
+ let baseType = "";
2291
+ if (Array.isArray(schemaType) && schemaType.length) {
2292
+ baseType = schemaType.join(" | ");
2293
+ } else if (typeof schemaType === "string") {
2294
+ baseType = schemaType;
2295
+ } else if (schema.enum) {
2296
+ const inferred = Array.from(
2297
+ new Set(schema.enum.map((value) => typeof value))
2298
+ );
2299
+ if (inferred.length === 1) {
2300
+ baseType = (_a = inferred[0]) != null ? _a : "";
2301
+ }
2302
+ } else if (schema.const !== void 0) {
2303
+ baseType = typeof schema.const;
2304
+ }
2305
+ if (!baseType) {
2306
+ baseType = "any";
2307
+ }
2308
+ if (baseType === "array" && schema.items) {
2309
+ const itemType = Array.isArray(schema.items) ? schema.items.map((item) => summarizeType(item)).join(" | ") : summarizeType(schema.items);
2310
+ return `array<${itemType}>`;
2311
+ }
2312
+ if (baseType === "string" && schema.format) {
2313
+ return `string (${schema.format})`;
2314
+ }
2315
+ return baseType;
2316
+ }
2317
+ var ENUM_MAX_INLINE = 6;
2318
+ var ENUM_PREVIEW_LIMIT = 5;
2319
+ function formatEnumForSummary(values) {
2320
+ if (values.length <= ENUM_MAX_INLINE) {
2321
+ return formatValue(values);
2322
+ }
2323
+ const preview = values.slice(0, ENUM_PREVIEW_LIMIT).map((value) => formatValue(value));
2324
+ return `[${preview.join(", ")}, ... (${values.length} total)]`;
2325
+ }
2326
+ function formatValue(value) {
2327
+ if (typeof value === "string") {
2328
+ return JSON.stringify(value);
2329
+ }
2330
+ if (typeof value === "number" || typeof value === "boolean") {
2331
+ return String(value);
2332
+ }
2333
+ if (value === null) {
2334
+ return "null";
2335
+ }
2336
+ if (Array.isArray(value)) {
2337
+ return `[${value.map(formatValue).join(", ")}]`;
2338
+ }
2339
+ return JSON.stringify(value);
2340
+ }
2341
+ function stringifySchema(schema) {
2342
+ if (schema === void 0) {
2343
+ return "null";
2344
+ }
2345
+ return JSON.stringify(stripSchemaKeys(schema));
2346
+ }
2347
+ function stripSchemaKeys(value) {
2348
+ if (Array.isArray(value)) {
2349
+ return value.map((entry) => stripSchemaKeys(entry));
2350
+ }
2351
+ if (value && typeof value === "object") {
2352
+ const record = value;
2353
+ const cleaned = {};
2354
+ for (const [key, entry] of Object.entries(record)) {
2355
+ if (key === "$schema") {
2356
+ continue;
2357
+ }
2358
+ cleaned[key] = stripSchemaKeys(entry);
2359
+ }
2360
+ return cleaned;
2361
+ }
2362
+ return value;
2594
2363
  }
2595
2364
 
2596
2365
  // src/core/prompts/yaml-system-prompt.ts
@@ -3099,20 +2868,12 @@ function createToolMiddleware({
3099
2868
  const resolvedProtocol = isTCMProtocolFactory(protocol) ? protocol() : protocol;
3100
2869
  return {
3101
2870
  specificationVersion: "v3",
3102
- wrapStream: ({ doStream, doGenerate, params }) => {
3103
- if (isToolChoiceActive(params)) {
3104
- return toolChoiceStream({
3105
- doGenerate,
3106
- options: extractOnErrorOption(params.providerOptions)
3107
- });
3108
- }
3109
- return wrapStream({
3110
- protocol: resolvedProtocol,
3111
- doStream,
3112
- doGenerate,
3113
- params
3114
- });
3115
- },
2871
+ wrapStream: ({ doStream, doGenerate, params }) => wrapStream({
2872
+ protocol: resolvedProtocol,
2873
+ doStream,
2874
+ doGenerate,
2875
+ params
2876
+ }),
3116
2877
  wrapGenerate: async ({ doGenerate, params }) => wrapGenerate({
3117
2878
  protocol: resolvedProtocol,
3118
2879
  doGenerate,
@@ -3146,16 +2907,10 @@ var yamlToolMiddleware = createToolMiddleware({
3146
2907
  });
3147
2908
  // Annotate the CommonJS export names for ESM import in node:
3148
2909
  0 && (module.exports = {
3149
- applyHeuristicPipeline,
3150
- balanceTagsHeuristic,
3151
2910
  createDynamicIfThenElseSchema,
3152
- createIntermediateCall,
3153
2911
  createToolMiddleware,
3154
2912
  decodeOriginalTools,
3155
- dedupeShellStringTagsHeuristic,
3156
- defaultPipelineConfig,
3157
2913
  encodeOriginalTools,
3158
- escapeInvalidLtHeuristic,
3159
2914
  escapeRegExp,
3160
2915
  extractOnErrorOption,
3161
2916
  extractToolNamesFromOriginalTools,
@@ -3172,10 +2927,7 @@ var yamlToolMiddleware = createToolMiddleware({
3172
2927
  logParsedChunk,
3173
2928
  logParsedSummary,
3174
2929
  logRawChunk,
3175
- mergePipelineConfigs,
3176
- normalizeCloseTagsHeuristic,
3177
2930
  originalToolsSchema,
3178
- repairAgainstSchemaHeuristic,
3179
2931
  toolChoiceStream,
3180
2932
  transformParams,
3181
2933
  wrapGenerate,