@ai-sdk-tool/parser 3.1.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,469 +1,8 @@
1
- // src/core/heuristics/engine.ts
2
- function applyRawSegmentUpdate(current, result) {
3
- if (result.rawSegment !== void 0) {
4
- return { ...current, rawSegment: result.rawSegment };
5
- }
6
- return current;
7
- }
8
- function applyParsedUpdate(current, result) {
9
- if (result.parsed !== void 0) {
10
- return { ...current, parsed: result.parsed };
11
- }
12
- return current;
13
- }
14
- function applyWarningsUpdate(current, result) {
15
- var _a, _b;
16
- if (result.warnings && result.warnings.length > 0) {
17
- const meta = (_a = current.meta) != null ? _a : {};
18
- const existingWarnings = (_b = meta.warnings) != null ? _b : [];
19
- return {
20
- ...current,
21
- meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
22
- };
23
- }
24
- return current;
25
- }
26
- function attemptReparse(current, result, reparseCount, maxReparses, parse4) {
27
- if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
28
- return { state: current, newCount: reparseCount };
29
- }
30
- try {
31
- const reparsed = parse4(result.rawSegment, current.schema);
32
- return {
33
- state: { ...current, parsed: reparsed, errors: [] },
34
- newCount: reparseCount + 1
35
- };
36
- } catch (error) {
37
- return {
38
- state: { ...current, errors: [...current.errors, error] },
39
- newCount: reparseCount + 1
40
- };
41
- }
42
- }
43
- function executePhase(ctx, heuristics, options) {
44
- var _a;
45
- let current = ctx;
46
- let reparseCount = 0;
47
- const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
48
- for (const heuristic of heuristics) {
49
- if (!heuristic.applies(current)) {
50
- continue;
51
- }
52
- const result = heuristic.run(current);
53
- current = applyRawSegmentUpdate(current, result);
54
- current = applyParsedUpdate(current, result);
55
- current = applyWarningsUpdate(current, result);
56
- const reparseResult = attemptReparse(
57
- current,
58
- result,
59
- reparseCount,
60
- maxReparses,
61
- options.parse
62
- );
63
- current = reparseResult.state;
64
- reparseCount = reparseResult.newCount;
65
- if (result.stop) {
66
- break;
67
- }
68
- }
69
- return current;
70
- }
71
- function applyHeuristicPipeline(ctx, config, options) {
72
- let current = ctx;
73
- if (config.preParse && config.preParse.length > 0) {
74
- current = executePhase(current, config.preParse, options);
75
- }
76
- if (current.parsed === null && current.errors.length === 0) {
77
- try {
78
- const parsed = options.parse(current.rawSegment, current.schema);
79
- current = { ...current, parsed, errors: [] };
80
- } catch (error) {
81
- current = { ...current, errors: [error] };
82
- }
83
- }
84
- if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
85
- current = executePhase(current, config.fallbackReparse, options);
86
- }
87
- if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
88
- current = executePhase(current, config.postParse, options);
89
- }
90
- return current;
91
- }
92
- function createIntermediateCall(toolName, rawSegment, schema) {
93
- return {
94
- toolName,
95
- schema,
96
- rawSegment,
97
- parsed: null,
98
- errors: [],
99
- meta: { originalContent: rawSegment }
100
- };
101
- }
102
- function mergePipelineConfigs(...configs) {
103
- var _a, _b, _c;
104
- const result = {
105
- preParse: [],
106
- fallbackReparse: [],
107
- postParse: []
108
- };
109
- for (const config of configs) {
110
- if (config.preParse) {
111
- result.preParse = [...(_a = result.preParse) != null ? _a : [], ...config.preParse];
112
- }
113
- if (config.fallbackReparse) {
114
- result.fallbackReparse = [
115
- ...(_b = result.fallbackReparse) != null ? _b : [],
116
- ...config.fallbackReparse
117
- ];
118
- }
119
- if (config.postParse) {
120
- result.postParse = [...(_c = result.postParse) != null ? _c : [], ...config.postParse];
121
- }
122
- }
123
- return result;
124
- }
1
+ // src/index.ts
2
+ export * from "@ai-sdk-tool/rjson";
125
3
 
126
- // src/core/heuristics/xml-defaults.ts
127
- import { parse, unwrapJsonSchema } from "@ai-sdk-tool/rxml";
128
- var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
129
- var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
130
- var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
131
- var WHITESPACE_REGEX = /\s/;
132
- var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
133
- var NAME_START_CHAR_RE = /[A-Za-z_:]/;
134
- var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
135
- var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
136
- var normalizeCloseTagsHeuristic = {
137
- id: "normalize-close-tags",
138
- phase: "pre-parse",
139
- applies: () => true,
140
- run: (ctx) => {
141
- const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
142
- if (normalized !== ctx.rawSegment) {
143
- return { rawSegment: normalized };
144
- }
145
- return {};
146
- }
147
- };
148
- var escapeInvalidLtHeuristic = {
149
- id: "escape-invalid-lt",
150
- phase: "pre-parse",
151
- applies: () => true,
152
- run: (ctx) => {
153
- const escaped = escapeInvalidLt(ctx.rawSegment);
154
- if (escaped !== ctx.rawSegment) {
155
- return { rawSegment: escaped };
156
- }
157
- return {};
158
- }
159
- };
160
- var balanceTagsHeuristic = {
161
- id: "balance-tags",
162
- phase: "fallback-reparse",
163
- applies: (ctx) => {
164
- var _a;
165
- const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
166
- const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
167
- const balanced = balanceTags(original);
168
- const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
169
- if (!hasMalformedClose && balanced.length > normalized.length) {
170
- return false;
171
- }
172
- return balanced !== normalized;
173
- },
174
- run: (ctx) => {
175
- var _a;
176
- const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
177
- const balanced = balanceTags(original);
178
- const escaped = escapeInvalidLt(balanced);
179
- return { rawSegment: escaped, reparse: true };
180
- }
181
- };
182
- var dedupeShellStringTagsHeuristic = {
183
- id: "dedupe-shell-string-tags",
184
- phase: "fallback-reparse",
185
- applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
186
- run: (ctx) => {
187
- const names = getStringPropertyNames(ctx.schema);
188
- let deduped = ctx.rawSegment;
189
- for (const key of names) {
190
- deduped = dedupeSingleTag(deduped, key);
191
- }
192
- if (deduped !== ctx.rawSegment) {
193
- return { rawSegment: deduped, reparse: true };
194
- }
195
- return {};
196
- }
197
- };
198
- var repairAgainstSchemaHeuristic = {
199
- id: "repair-against-schema",
200
- phase: "post-parse",
201
- applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
202
- run: (ctx) => {
203
- const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
204
- if (repaired !== ctx.parsed) {
205
- return { parsed: repaired };
206
- }
207
- return {};
208
- }
209
- };
210
- var defaultPipelineConfig = {
211
- preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
212
- fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
213
- postParse: [repairAgainstSchemaHeuristic]
214
- };
215
- var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
216
- function isIndexTagAt(xml, pos) {
217
- const remaining = xml.slice(pos);
218
- return INDEX_TAG_RE.test(remaining);
219
- }
220
- function escapeInvalidLt(xml) {
221
- const len = xml.length;
222
- let out = "";
223
- for (let i = 0; i < len; i += 1) {
224
- const ch = xml[i];
225
- if (ch === "<") {
226
- const next = i + 1 < len ? xml[i + 1] : "";
227
- const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
228
- const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
229
- if (!(isValidStart || isIndexTag)) {
230
- out += "&lt;";
231
- continue;
232
- }
233
- }
234
- out += ch;
235
- }
236
- return out;
237
- }
238
- function balanceTags(xml) {
239
- const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
240
- let i = 0;
241
- const len = src.length;
242
- const out = [];
243
- const stack = [];
244
- while (i < len) {
245
- const lt = src.indexOf("<", i);
246
- if (lt === -1) {
247
- out.push(src.slice(i));
248
- break;
249
- }
250
- out.push(src.slice(i, lt));
251
- if (lt + 1 >= len) {
252
- break;
253
- }
254
- const next = src[lt + 1];
255
- if (next === "!" || next === "?") {
256
- i = handleSpecialTagSegment(src, lt, out);
257
- continue;
258
- }
259
- if (next === "/") {
260
- i = handleClosingTagSegment(src, lt, out, stack);
261
- continue;
262
- }
263
- i = handleOpeningTagSegment(src, lt, out, stack);
264
- }
265
- for (let k = stack.length - 1; k >= 0; k -= 1) {
266
- out.push(`</${stack[k]}>`);
267
- }
268
- return out.join("");
269
- }
270
- function skipWs(s, p, len) {
271
- let idx = p;
272
- while (idx < len && WHITESPACE_REGEX.test(s[idx])) {
273
- idx += 1;
274
- }
275
- return idx;
276
- }
277
- function parseTagNameAt(s, p, len) {
278
- let idx = p;
279
- const start = idx;
280
- while (idx < len && NAME_CHAR_RE.test(s[idx])) {
281
- idx += 1;
282
- }
283
- return { name: s.slice(start, idx), pos: idx };
284
- }
285
- function handleSpecialTagSegment(src, lt, out) {
286
- const gt = src.indexOf(">", lt + 1);
287
- if (gt === -1) {
288
- out.push(src.slice(lt));
289
- return src.length;
290
- }
291
- out.push(src.slice(lt, gt + 1));
292
- return gt + 1;
293
- }
294
- function handleClosingTagSegment(src, lt, out, stack) {
295
- const len = src.length;
296
- let p = skipWs(src, lt + 2, len);
297
- const { name, pos } = parseTagNameAt(src, p, len);
298
- p = pos;
299
- const gt = src.indexOf(">", p);
300
- const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
301
- const idx = stack.lastIndexOf(name);
302
- if (idx !== -1) {
303
- for (let k = stack.length - 1; k > idx; k -= 1) {
304
- out.push(`</${stack[k]}>`);
305
- stack.pop();
306
- }
307
- out.push(closingText);
308
- stack.pop();
309
- }
310
- return gt === -1 ? len : gt + 1;
311
- }
312
- function handleOpeningTagSegment(src, lt, out, stack) {
313
- const len = src.length;
314
- let p = skipWs(src, lt + 1, len);
315
- const nameStart = p;
316
- const parsed = parseTagNameAt(src, p, len);
317
- p = parsed.pos;
318
- const name = src.slice(nameStart, p);
319
- const q = src.indexOf(">", p);
320
- if (q === -1) {
321
- out.push(src.slice(lt));
322
- return len;
323
- }
324
- let r = q - 1;
325
- while (r >= nameStart && WHITESPACE_REGEX.test(src[r])) {
326
- r -= 1;
327
- }
328
- const selfClosing = src[r] === "/";
329
- out.push(src.slice(lt, q + 1));
330
- if (!selfClosing && name) {
331
- stack.push(name);
332
- }
333
- return q + 1;
334
- }
335
- function extractSchemaProperties(schema) {
336
- const unwrapped = unwrapJsonSchema(schema);
337
- if (!unwrapped || typeof unwrapped !== "object") {
338
- return void 0;
339
- }
340
- return unwrapped.properties;
341
- }
342
- function shouldDeduplicateStringTags(schema) {
343
- const props = extractSchemaProperties(schema);
344
- if (!props) {
345
- return false;
346
- }
347
- const commandRaw = props.command;
348
- if (!commandRaw) {
349
- return false;
350
- }
351
- const command = unwrapJsonSchema(commandRaw);
352
- return (command == null ? void 0 : command.type) === "array";
353
- }
354
- function getStringPropertyNames(schema) {
355
- const props = extractSchemaProperties(schema);
356
- if (!props) {
357
- return [];
358
- }
359
- const names = [];
360
- for (const key of Object.keys(props)) {
361
- const prop = unwrapJsonSchema(props[key]);
362
- if ((prop == null ? void 0 : prop.type) === "string") {
363
- names.push(key);
364
- }
365
- }
366
- return names;
367
- }
368
- function escapeRegExp(s) {
369
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
370
- }
371
- function dedupeSingleTag(xml, key) {
372
- var _a, _b;
373
- const escaped = escapeRegExp(key);
374
- const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
375
- const matches = Array.from(xml.matchAll(re));
376
- if (matches.length <= 1) {
377
- return xml;
378
- }
379
- const last = matches.at(-1);
380
- let result = "";
381
- let cursor = 0;
382
- for (const m of matches) {
383
- const idx = (_a = m.index) != null ? _a : 0;
384
- result += xml.slice(cursor, idx);
385
- if (last && idx === ((_b = last.index) != null ? _b : -1)) {
386
- result += m[0];
387
- }
388
- cursor = idx + m[0].length;
389
- }
390
- result += xml.slice(cursor);
391
- return result;
392
- }
393
- function repairParsedAgainstSchema(input, schema) {
394
- if (!input || typeof input !== "object") {
395
- return input;
396
- }
397
- const properties = extractSchemaProperties(schema);
398
- if (!properties) {
399
- return input;
400
- }
401
- applySchemaProps(input, properties);
402
- return input;
403
- }
404
- function applySchemaProps(obj, properties) {
405
- for (const key of Object.keys(obj)) {
406
- const propSchema = properties[key];
407
- if (!propSchema) {
408
- continue;
409
- }
410
- const prop = unwrapJsonSchema(propSchema);
411
- if ((prop == null ? void 0 : prop.type) === "array" && prop.items) {
412
- const itemSchema = unwrapJsonSchema(prop.items);
413
- obj[key] = coerceArrayItems(obj[key], itemSchema);
414
- continue;
415
- }
416
- if ((prop == null ? void 0 : prop.type) === "object") {
417
- const val = obj[key];
418
- if (val && typeof val === "object") {
419
- obj[key] = repairParsedAgainstSchema(val, prop);
420
- }
421
- }
422
- }
423
- }
424
- function coerceArrayItems(val, itemSchema) {
425
- if (!Array.isArray(val)) {
426
- return val;
427
- }
428
- return val.map((v) => coerceArrayItem(v, itemSchema));
429
- }
430
- function coerceArrayItem(v, itemSchema) {
431
- const itemType = itemSchema == null ? void 0 : itemSchema.type;
432
- if (typeof v === "string" && itemType === "object") {
433
- const parsed = tryParseStringToSchemaObject(v, itemSchema);
434
- if (parsed !== null) {
435
- return parsed;
436
- }
437
- const fallback = extractStepStatusFromString(
438
- v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
439
- );
440
- if (fallback) {
441
- return fallback;
442
- }
443
- return v;
444
- }
445
- if (v && typeof v === "object" && itemType === "object") {
446
- return repairParsedAgainstSchema(v, itemSchema);
447
- }
448
- return v;
449
- }
450
- function tryParseStringToSchemaObject(xml, itemSchema) {
451
- try {
452
- const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
453
- const fixed = parse(normalized, itemSchema, { noChildNodes: [] });
454
- return typeof fixed === "string" ? null : fixed;
455
- } catch (e) {
456
- return null;
457
- }
458
- }
459
- function extractStepStatusFromString(normXml) {
460
- const stepMatch = normXml.match(STEP_TAG_RE);
461
- const statusMatch = normXml.match(STATUS_TAG_RE);
462
- if (stepMatch && statusMatch) {
463
- return { step: stepMatch[1], status: statusMatch[1] };
464
- }
465
- return null;
466
- }
4
+ // src/core/protocols/json-protocol.ts
5
+ import { parse as parseRJSON } from "@ai-sdk-tool/rjson";
467
6
 
468
7
  // src/core/utils/debug.ts
469
8
  var LINE_SPLIT_REGEX = /\r?\n/;
@@ -644,680 +183,15 @@ function generateId() {
644
183
  }
645
184
 
646
185
  // src/core/utils/regex.ts
647
- function escapeRegExp2(literal) {
186
+ function escapeRegExp(literal) {
648
187
  return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
649
188
  }
650
189
 
651
- // src/core/utils/robust-json.ts
652
- var WHITESPACE_TEST_REGEX = /\s/;
653
- var WHITESPACE_REGEX2 = /^\s+/;
654
- var OBJECT_START_REGEX = /^\{/;
655
- var OBJECT_END_REGEX = /^\}/;
656
- var ARRAY_START_REGEX = /^\[/;
657
- var ARRAY_END_REGEX = /^\]/;
658
- var COMMA_REGEX = /^,/;
659
- var COLON_REGEX = /^:/;
660
- var KEYWORD_REGEX = /^(?:true|false|null)/;
661
- var NUMBER_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/;
662
- var STRING_DOUBLE_REGEX = /^"(?:[^"\\]|\\["bnrtf\\/]|\\u[0-9a-fA-F]{4})*"/;
663
- var STRING_SINGLE_REGEX = /^'((?:[^'\\]|\\['bnrtf\\/]|\\u[0-9a-fA-F]{4})*)'/;
664
- var COMMENT_SINGLE_REGEX = /^\/\/.*?(?:\r\n|\r|\n)/;
665
- var COMMENT_MULTI_REGEX = /^\/\*[\s\S]*?\*\//;
666
- var IDENTIFIER_REGEX = /^[$a-zA-Z0-9_\-+.*?!|&%^/#\\]+/;
667
- function some(array, f) {
668
- let acc = false;
669
- for (let i = 0; i < array.length; i += 1) {
670
- const result = f(array[i], i, array);
671
- acc = result === void 0 ? false : result;
672
- if (acc) {
673
- return acc;
674
- }
675
- }
676
- return acc;
677
- }
678
- function makeLexer(tokenSpecs) {
679
- return (contents) => {
680
- const tokens = [];
681
- let line = 1;
682
- let remainingContents = contents;
683
- function findToken() {
684
- const result = some(tokenSpecs, (tokenSpec) => {
685
- const m = tokenSpec.re.exec(remainingContents);
686
- if (m) {
687
- const raw = m[0];
688
- remainingContents = remainingContents.slice(raw.length);
689
- return {
690
- raw,
691
- matched: tokenSpec.f(m)
692
- // Process the match using the spec's function
693
- };
694
- }
695
- return;
696
- });
697
- return result === false ? void 0 : result;
698
- }
699
- while (remainingContents !== "") {
700
- const matched = findToken();
701
- if (!matched) {
702
- const err = new SyntaxError(
703
- `Unexpected character: ${remainingContents[0]}; input: ${remainingContents.substr(
704
- 0,
705
- 100
706
- )}`
707
- );
708
- err.line = line;
709
- throw err;
710
- }
711
- const tokenWithLine = matched.matched;
712
- tokenWithLine.line = line;
713
- line += matched.raw.replace(/[^\n]/g, "").length;
714
- tokens.push(tokenWithLine);
715
- }
716
- return tokens;
717
- };
718
- }
719
- function fStringSingle(m) {
720
- const content = m[1].replace(
721
- /([^'\\]|\\['bnrtf\\]|\\u[0-9a-fA-F]{4})/g,
722
- (mm) => {
723
- if (mm === '"') {
724
- return '\\"';
725
- }
726
- if (mm === "\\'") {
727
- return "'";
728
- }
729
- return mm;
730
- }
731
- );
732
- const match = `"${content}"`;
733
- return {
734
- type: "string",
735
- match,
736
- // The transformed, double-quoted string representation
737
- // Use JSON.parse on the transformed string to handle escape sequences correctly
738
- value: JSON.parse(match)
739
- };
740
- }
741
- function fStringDouble(m) {
742
- return {
743
- type: "string",
744
- match: m[0],
745
- // The raw matched string (including quotes)
746
- value: JSON.parse(m[0])
747
- // Use JSON.parse to handle escapes and get the value
748
- };
749
- }
750
- function fIdentifier(m) {
751
- const value = m[0];
752
- const match = '"' + value.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + // Escape backslashes and quotes
753
- '"';
754
- return {
755
- type: "string",
756
- // Treat identifiers as strings
757
- value,
758
- // The original identifier name
759
- match
760
- // The double-quoted string representation
761
- };
762
- }
763
- function fComment(m) {
764
- const match = m[0].replace(
765
- /./g,
766
- (c) => WHITESPACE_TEST_REGEX.test(c) ? c : " "
767
- );
768
- return {
769
- type: " ",
770
- // Represent comments as whitespace tokens
771
- match,
772
- // String containing original newlines and spaces for other chars
773
- value: void 0
774
- // Comments don't have a semantic value
775
- };
776
- }
777
- function fNumber(m) {
778
- return {
779
- type: "number",
780
- match: m[0],
781
- // The raw matched number string
782
- value: Number.parseFloat(m[0])
783
- // Convert string to number
784
- };
785
- }
786
- function fKeyword(m) {
787
- let value;
788
- switch (m[0]) {
789
- case "null":
790
- value = null;
791
- break;
792
- case "true":
793
- value = true;
794
- break;
795
- case "false":
796
- value = false;
797
- break;
798
- default:
799
- throw new Error(`Unexpected keyword: ${m[0]}`);
800
- }
801
- return {
802
- type: "atom",
803
- // Use 'atom' type for these literals
804
- match: m[0],
805
- // The raw matched keyword
806
- value
807
- // The corresponding JavaScript value
808
- };
809
- }
810
- function makeTokenSpecs(relaxed) {
811
- function f(type) {
812
- return (m) => {
813
- return { type, match: m[0], value: void 0 };
814
- };
815
- }
816
- let tokenSpecs = [
817
- { re: WHITESPACE_REGEX2, f: f(" ") },
818
- // Whitespace
819
- { re: OBJECT_START_REGEX, f: f("{") },
820
- // Object start
821
- { re: OBJECT_END_REGEX, f: f("}") },
822
- // Object end
823
- { re: ARRAY_START_REGEX, f: f("[") },
824
- // Array start
825
- { re: ARRAY_END_REGEX, f: f("]") },
826
- // Array end
827
- { re: COMMA_REGEX, f: f(",") },
828
- // Comma separator
829
- { re: COLON_REGEX, f: f(":") },
830
- // Key-value separator
831
- { re: KEYWORD_REGEX, f: fKeyword },
832
- // Keywords
833
- // Number: optional sign, digits, optional decimal part, optional exponent
834
- { re: NUMBER_REGEX, f: fNumber },
835
- // String: double-quoted, handles escapes
836
- { re: STRING_DOUBLE_REGEX, f: fStringDouble }
837
- ];
838
- if (relaxed) {
839
- tokenSpecs = tokenSpecs.concat([
840
- // Single-quoted strings
841
- {
842
- re: STRING_SINGLE_REGEX,
843
- f: fStringSingle
844
- },
845
- // Single-line comments (// ...)
846
- { re: COMMENT_SINGLE_REGEX, f: fComment },
847
- // Multi-line comments (/* ... */)
848
- { re: COMMENT_MULTI_REGEX, f: fComment },
849
- // Unquoted identifiers (treated as strings)
850
- // Allows letters, numbers, _, -, +, ., *, ?, !, |, &, %, ^, /, #, \
851
- { re: IDENTIFIER_REGEX, f: fIdentifier }
852
- // Note: The order matters here. Identifiers are checked after keywords/numbers.
853
- ]);
854
- }
855
- return tokenSpecs;
856
- }
857
- var lexer = makeLexer(makeTokenSpecs(true));
858
- var strictLexer = makeLexer(makeTokenSpecs(false));
859
- function previousNWSToken(tokens, index) {
860
- let currentIndex = index;
861
- for (; currentIndex >= 0; currentIndex -= 1) {
862
- if (tokens[currentIndex].type !== " ") {
863
- return currentIndex;
864
- }
865
- }
866
- return;
867
- }
868
- function stripTrailingComma(tokens) {
869
- const res = [];
870
- tokens.forEach((token, index) => {
871
- if (index > 0 && (token.type === "]" || token.type === "}")) {
872
- const prevNWSTokenIndex = previousNWSToken(res, res.length - 1);
873
- if (prevNWSTokenIndex !== void 0 && res[prevNWSTokenIndex].type === ",") {
874
- const preCommaIndex = previousNWSToken(res, prevNWSTokenIndex - 1);
875
- if (preCommaIndex !== void 0 && res[preCommaIndex].type !== "[" && res[preCommaIndex].type !== "{") {
876
- res[prevNWSTokenIndex] = {
877
- type: " ",
878
- match: " ",
879
- // Represent as a single space
880
- value: void 0,
881
- // Whitespace has no value
882
- line: res[prevNWSTokenIndex].line
883
- // Preserve original line number
884
- };
885
- }
886
- }
887
- }
888
- res.push(token);
889
- });
890
- return res;
891
- }
892
- function transform(text) {
893
- let tokens = lexer(text);
894
- tokens = stripTrailingComma(tokens);
895
- return tokens.reduce((str, token) => str + token.match, "");
896
- }
897
- function popToken(tokens, state) {
898
- var _a, _b;
899
- const token = tokens[state.pos];
900
- state.pos += 1;
901
- if (!token) {
902
- const lastLine = tokens.length !== 0 ? (_b = (_a = tokens.at(-1)) == null ? void 0 : _a.line) != null ? _b : 1 : 1;
903
- return { type: "eof", match: "", value: void 0, line: lastLine };
904
- }
905
- return token;
906
- }
907
- function strToken(token) {
908
- switch (token.type) {
909
- case "atom":
910
- case "string":
911
- case "number":
912
- return `${token.type} ${token.match}`;
913
- case "eof":
914
- return "end-of-file";
915
- default:
916
- return `'${token.type}'`;
917
- }
918
- }
919
- function skipColon(tokens, state) {
920
- const colon = popToken(tokens, state);
921
- if (colon.type !== ":") {
922
- const message = `Unexpected token: ${strToken(colon)}, expected ':'`;
923
- if (state.tolerant) {
924
- state.warnings.push({
925
- message,
926
- line: colon.line
927
- });
928
- state.pos -= 1;
929
- } else {
930
- const err = new SyntaxError(message);
931
- err.line = colon.line;
932
- throw err;
933
- }
934
- }
935
- }
936
- function skipPunctuation(tokens, state, valid) {
937
- const punctuation = [",", ":", "]", "}"];
938
- let token = popToken(tokens, state);
939
- while (true) {
940
- if (valid == null ? void 0 : valid.includes(token.type)) {
941
- return token;
942
- }
943
- if (token.type === "eof") {
944
- return token;
945
- }
946
- if (punctuation.includes(token.type)) {
947
- const message = `Unexpected token: ${strToken(
948
- token
949
- )}, expected '[', '{', number, string or atom`;
950
- if (state.tolerant) {
951
- state.warnings.push({
952
- message,
953
- line: token.line
954
- });
955
- token = popToken(tokens, state);
956
- } else {
957
- const err = new SyntaxError(message);
958
- err.line = token.line;
959
- throw err;
960
- }
961
- } else {
962
- return token;
963
- }
964
- }
965
- }
966
- function raiseError(state, token, message) {
967
- if (state.tolerant) {
968
- state.warnings.push({
969
- message,
970
- line: token.line
971
- });
972
- } else {
973
- const err = new SyntaxError(message);
974
- err.line = token.line;
975
- throw err;
976
- }
977
- }
978
- function raiseUnexpected(state, token, expected) {
979
- raiseError(
980
- state,
981
- token,
982
- `Unexpected token: ${strToken(token)}, expected ${expected}`
983
- );
984
- }
985
- function checkDuplicates(state, obj, token) {
986
- const key = String(token.value);
987
- if (!state.duplicate && Object.hasOwn(obj, key)) {
988
- raiseError(state, token, `Duplicate key: ${key}`);
989
- }
990
- }
991
- function appendPair(state, obj, key, value) {
992
- const finalValue = state.reviver ? state.reviver(key, value) : value;
993
- if (finalValue !== void 0) {
994
- obj[key] = finalValue;
995
- }
996
- }
997
- function parsePair(tokens, state, obj) {
998
- let token = skipPunctuation(tokens, state, [":", "string", "number", "atom"]);
999
- let value;
1000
- if (token.type !== "string") {
1001
- raiseUnexpected(state, token, "string key");
1002
- if (state.tolerant) {
1003
- switch (token.type) {
1004
- case ":":
1005
- token = {
1006
- type: "string",
1007
- value: "null",
1008
- match: '"null"',
1009
- line: token.line
1010
- };
1011
- state.pos -= 1;
1012
- break;
1013
- case "number":
1014
- // Use number as string key
1015
- case "atom":
1016
- token = {
1017
- type: "string",
1018
- value: String(token.value),
1019
- match: `"${token.value}"`,
1020
- line: token.line
1021
- };
1022
- break;
1023
- case "[":
1024
- // Assume missing key before an array
1025
- case "{":
1026
- state.pos -= 1;
1027
- value = parseAny(tokens, state);
1028
- checkDuplicates(state, obj, {
1029
- type: "string",
1030
- value: "null",
1031
- match: '"null"',
1032
- line: token.line
1033
- });
1034
- appendPair(state, obj, "null", value);
1035
- return;
1036
- // Finished parsing this "pair"
1037
- case "eof":
1038
- return;
1039
- // Cannot recover
1040
- default:
1041
- return;
1042
- }
1043
- } else {
1044
- return;
1045
- }
1046
- }
1047
- checkDuplicates(state, obj, token);
1048
- const key = String(token.value);
1049
- skipColon(tokens, state);
1050
- value = parseAny(tokens, state);
1051
- appendPair(state, obj, key, value);
1052
- }
1053
- function parseElement(tokens, state, arr) {
1054
- const key = arr.length;
1055
- const value = parseAny(tokens, state);
1056
- arr[key] = state.reviver ? state.reviver(String(key), value) : value;
1057
- }
1058
- function parseObject(tokens, state) {
1059
- const obj = {};
1060
- return parseMany(tokens, state, obj, {
1061
- skip: [":", "}"],
1062
- // Initially skip over colon or closing brace (for empty/tolerant cases)
1063
- elementParser: parsePair,
1064
- // Use parsePair to parse each key-value element
1065
- elementName: "string key",
1066
- // Expected element type for errors
1067
- endSymbol: "}"
1068
- // The closing token for an object
1069
- });
1070
- }
1071
- function parseArray(tokens, state) {
1072
- const arr = [];
1073
- return parseMany(tokens, state, arr, {
1074
- skip: ["]"],
1075
- // Initially skip over closing bracket (for empty/tolerant cases)
1076
- elementParser: parseElement,
1077
- // Use parseElement to parse each array item
1078
- elementName: "json value",
1079
- // Expected element type for errors
1080
- endSymbol: "]"
1081
- // The closing token for an array
1082
- });
1083
- }
1084
- function handleInvalidToken(token, state, opts, result) {
1085
- raiseUnexpected(state, token, `',' or '${opts.endSymbol}'`);
1086
- if (state.tolerant) {
1087
- if (token.type === "eof") {
1088
- return result;
1089
- }
1090
- state.pos -= 1;
1091
- return null;
1092
- }
1093
- return result;
1094
- }
1095
- function handleCommaToken(params) {
1096
- const { token, tokens, state, opts, result } = params;
1097
- const nextToken = tokens[state.pos];
1098
- if (state.tolerant && nextToken && nextToken.type === opts.endSymbol) {
1099
- raiseError(state, token, `Trailing comma before '${opts.endSymbol}'`);
1100
- popToken(tokens, state);
1101
- return result;
1102
- }
1103
- opts.elementParser(tokens, state, result);
1104
- return null;
1105
- }
1106
- function parseManyInitialElement(tokens, state, result, opts) {
1107
- const token = skipPunctuation(tokens, state, opts.skip);
1108
- if (token.type === "eof") {
1109
- raiseUnexpected(state, token, `'${opts.endSymbol}' or ${opts.elementName}`);
1110
- return result;
1111
- }
1112
- if (token.type === opts.endSymbol) {
1113
- return result;
1114
- }
1115
- state.pos -= 1;
1116
- opts.elementParser(tokens, state, result);
1117
- return;
1118
- }
1119
- function parseManyProcessToken(params) {
1120
- const { token, tokens, state, opts, result } = params;
1121
- if (token.type !== opts.endSymbol && token.type !== ",") {
1122
- const handledResult = handleInvalidToken(token, state, opts, result);
1123
- if (handledResult !== null) {
1124
- return handledResult;
1125
- }
1126
- }
1127
- if (token.type === opts.endSymbol) {
1128
- return result;
1129
- }
1130
- if (token.type === ",") {
1131
- const handledResult = handleCommaToken({
1132
- token,
1133
- tokens,
1134
- state,
1135
- opts,
1136
- result
1137
- });
1138
- if (handledResult !== null) {
1139
- return handledResult;
1140
- }
1141
- return;
1142
- }
1143
- opts.elementParser(tokens, state, result);
1144
- return;
1145
- }
1146
- function parseMany(tokens, state, result, opts) {
1147
- const initialResult = parseManyInitialElement(tokens, state, result, opts);
1148
- if (initialResult !== void 0) {
1149
- return initialResult;
1150
- }
1151
- while (true) {
1152
- const token = popToken(tokens, state);
1153
- const processedResult = parseManyProcessToken({
1154
- token,
1155
- tokens,
1156
- state,
1157
- opts,
1158
- result
1159
- });
1160
- if (processedResult !== void 0) {
1161
- return processedResult;
1162
- }
1163
- }
1164
- }
1165
- function endChecks(tokens, state, ret) {
1166
- if (state.pos < tokens.length) {
1167
- if (state.tolerant) {
1168
- skipPunctuation(tokens, state);
1169
- }
1170
- if (state.pos < tokens.length) {
1171
- raiseError(
1172
- state,
1173
- tokens[state.pos],
1174
- `Unexpected token: ${strToken(tokens[state.pos])}, expected end-of-input`
1175
- );
1176
- }
1177
- }
1178
- if (state.tolerant && state.warnings.length > 0) {
1179
- const message = state.warnings.length === 1 ? state.warnings[0].message : `${state.warnings.length} parse warnings`;
1180
- const err = new SyntaxError(message);
1181
- err.line = state.warnings[0].line;
1182
- err.warnings = state.warnings;
1183
- err.obj = ret;
1184
- throw err;
1185
- }
1186
- }
1187
- function parseAny(tokens, state, end = false) {
1188
- const token = skipPunctuation(tokens, state);
1189
- let ret;
1190
- if (token.type === "eof") {
1191
- if (end) {
1192
- raiseUnexpected(state, token, "json value");
1193
- }
1194
- raiseUnexpected(state, token, "json value");
1195
- return;
1196
- }
1197
- switch (token.type) {
1198
- case "{":
1199
- ret = parseObject(tokens, state);
1200
- break;
1201
- case "[":
1202
- ret = parseArray(tokens, state);
1203
- break;
1204
- case "string":
1205
- // String literal
1206
- case "number":
1207
- // Number literal
1208
- case "atom":
1209
- ret = token.value;
1210
- break;
1211
- default:
1212
- raiseUnexpected(state, token, "json value");
1213
- if (state.tolerant) {
1214
- ret = null;
1215
- } else {
1216
- return;
1217
- }
1218
- }
1219
- if (end) {
1220
- ret = state.reviver ? state.reviver("", ret) : ret;
1221
- endChecks(tokens, state, ret);
1222
- }
1223
- return ret;
1224
- }
1225
- function normalizeParseOptions(optsOrReviver) {
1226
- var _a;
1227
- let options = {};
1228
- if (typeof optsOrReviver === "function") {
1229
- options.reviver = optsOrReviver;
1230
- } else if (optsOrReviver !== null && typeof optsOrReviver === "object") {
1231
- options = { ...optsOrReviver };
1232
- } else if (optsOrReviver !== void 0) {
1233
- throw new TypeError(
1234
- "Second argument must be a reviver function or an options object."
1235
- );
1236
- }
1237
- if (options.relaxed === void 0) {
1238
- if (options.warnings === true || options.tolerant === true) {
1239
- options.relaxed = true;
1240
- } else if (options.warnings === false && options.tolerant === false) {
1241
- options.relaxed = false;
1242
- } else {
1243
- options.relaxed = true;
1244
- }
1245
- }
1246
- options.tolerant = options.tolerant || options.warnings;
1247
- options.duplicate = (_a = options.duplicate) != null ? _a : false;
1248
- return options;
1249
- }
1250
- function createParseState(options) {
1251
- var _a, _b;
1252
- return {
1253
- pos: 0,
1254
- reviver: options.reviver,
1255
- tolerant: (_a = options.tolerant) != null ? _a : false,
1256
- duplicate: (_b = options.duplicate) != null ? _b : false,
1257
- warnings: []
1258
- };
1259
- }
1260
- function parseWithCustomParser(text, options) {
1261
- const lexerToUse = options.relaxed ? lexer : strictLexer;
1262
- let tokens = lexerToUse(text);
1263
- if (options.relaxed) {
1264
- tokens = stripTrailingComma(tokens);
1265
- }
1266
- tokens = tokens.filter((token) => token.type !== " ");
1267
- const state = createParseState(options);
1268
- return parseAny(tokens, state, true);
1269
- }
1270
- function parseWithTransform(text, options) {
1271
- let tokens = lexer(text);
1272
- tokens = stripTrailingComma(tokens);
1273
- const newtext = tokens.reduce((str, token) => str + token.match, "");
1274
- return JSON.parse(
1275
- newtext,
1276
- options.reviver
1277
- );
1278
- }
1279
- function parse2(text, optsOrReviver) {
1280
- const options = normalizeParseOptions(optsOrReviver);
1281
- if (!(options.relaxed || options.warnings || options.tolerant) && options.duplicate) {
1282
- return JSON.parse(
1283
- text,
1284
- options.reviver
1285
- );
1286
- }
1287
- if (options.warnings || options.tolerant || !options.duplicate) {
1288
- return parseWithCustomParser(text, options);
1289
- }
1290
- return parseWithTransform(text, options);
1291
- }
1292
- function stringifyPair(obj, key) {
1293
- return `${JSON.stringify(key)}:${stringify(obj[key])}`;
1294
- }
1295
- function stringify(obj) {
1296
- const type = typeof obj;
1297
- if (type === "string" || type === "number" || type === "boolean" || obj === null) {
1298
- return JSON.stringify(obj);
1299
- }
1300
- if (type === "undefined") {
1301
- return "null";
1302
- }
1303
- if (Array.isArray(obj)) {
1304
- const elements = obj.map(stringify).join(",");
1305
- return `[${elements}]`;
1306
- }
1307
- if (type === "object") {
1308
- const keys = Object.keys(obj);
1309
- keys.sort();
1310
- const pairs = keys.map((key) => stringifyPair(obj, key)).join(",");
1311
- return `{${pairs}}`;
1312
- }
1313
- return "null";
1314
- }
1315
-
1316
190
  // src/core/protocols/json-protocol.ts
1317
191
  function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
1318
192
  var _a, _b;
1319
193
  try {
1320
- const parsedToolCall = parse2(toolCallJson);
194
+ const parsedToolCall = parseRJSON(toolCallJson);
1321
195
  processedElements.push({
1322
196
  type: "tool-call",
1323
197
  toolCallId: generateId(),
@@ -1445,7 +319,7 @@ function emitToolCall(context) {
1445
319
  var _a, _b;
1446
320
  const { state, controller, toolCallStart, toolCallEnd, options } = context;
1447
321
  try {
1448
- const parsedToolCall = parse2(state.currentToolCallJson);
322
+ const parsedToolCall = parseRJSON(state.currentToolCallJson);
1449
323
  closeTextBlock(state, controller);
1450
324
  controller.enqueue({
1451
325
  type: "tool-call",
@@ -1556,8 +430,8 @@ var jsonProtocol = ({
1556
430
  text,
1557
431
  options
1558
432
  }) {
1559
- const startEsc = escapeRegExp2(toolCallStart);
1560
- const endEsc = escapeRegExp2(toolCallEnd);
433
+ const startEsc = escapeRegExp(toolCallStart);
434
+ const endEsc = escapeRegExp(toolCallEnd);
1561
435
  const toolCallRegex = new RegExp(
1562
436
  `${startEsc}([\0-\uFFFF]*?)${endEsc}`,
1563
437
  "gs"
@@ -1616,8 +490,8 @@ var jsonProtocol = ({
1616
490
  });
1617
491
  },
1618
492
  extractToolCallSegments({ text }) {
1619
- const startEsc = escapeRegExp2(toolCallStart);
1620
- const endEsc = escapeRegExp2(toolCallEnd);
493
+ const startEsc = escapeRegExp(toolCallStart);
494
+ const endEsc = escapeRegExp(toolCallEnd);
1621
495
  const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
1622
496
  const segments = [];
1623
497
  let m = regex.exec(text);
@@ -1638,93 +512,48 @@ function isTCMProtocolFactory(protocol) {
1638
512
  }
1639
513
 
1640
514
  // src/core/protocols/xml-protocol.ts
1641
- import { extractRawInner, parse as parse3, stringify as stringify2 } from "@ai-sdk-tool/rxml";
1642
- var defaultPipelineConfig2 = defaultPipelineConfig;
1643
- var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
1644
- var WHITESPACE_REGEX3 = /\s/;
515
+ import { parse, stringify } from "@ai-sdk-tool/rxml";
516
+ var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
517
+ var WHITESPACE_REGEX = /\s/;
518
+ var REGEX_ESCAPE_RE = /[.*+?^${}()|[\]\\]/g;
519
+ function escapeRegExp2(value) {
520
+ return value.replace(REGEX_ESCAPE_RE, "\\$&");
521
+ }
1645
522
  function getToolSchema(tools, toolName) {
1646
523
  var _a;
1647
524
  return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1648
525
  }
1649
- function normalizeCloseTags(xml) {
1650
- return xml.replace(/<\/\s+([A-Za-z0-9_:-]+)\s*>/g, "</$1>");
1651
- }
1652
- function tryParseSecondaryXml(content, toolSchema, options) {
1653
- const balanced = balanceTags(content);
1654
- try {
1655
- let parsed = parse3(balanced, toolSchema, {
1656
- onError: options == null ? void 0 : options.onError,
1657
- noChildNodes: []
1658
- });
1659
- parsed = repairParsedAgainstSchema(parsed, toolSchema);
1660
- return parsed;
1661
- } catch (e) {
1662
- if (shouldDeduplicateStringTags(toolSchema)) {
1663
- const names = getStringPropertyNames(toolSchema);
1664
- let deduped = balanced;
1665
- for (const key of names) {
1666
- deduped = dedupeSingleTag(deduped, key);
1667
- }
1668
- if (deduped !== balanced) {
1669
- try {
1670
- let reparsed = parse3(deduped, toolSchema, {
1671
- onError: options == null ? void 0 : options.onError,
1672
- noChildNodes: []
1673
- });
1674
- reparsed = repairParsedAgainstSchema(reparsed, toolSchema);
1675
- return reparsed;
1676
- } catch (e2) {
1677
- return null;
1678
- }
1679
- }
1680
- }
1681
- return null;
1682
- }
1683
- }
1684
- function processToolCallWithPipeline(params) {
1685
- var _a;
1686
- const {
1687
- toolCall,
1688
- tools,
1689
- options,
1690
- text,
1691
- processedElements,
1692
- pipelineConfig = defaultPipelineConfig2,
1693
- maxReparses
1694
- } = params;
526
+ function processToolCall(params) {
527
+ var _a, _b;
528
+ const { toolCall, tools, options, text, processedElements, parseOptions } = params;
1695
529
  const toolSchema = getToolSchema(tools, toolCall.toolName);
1696
- const ctx = createIntermediateCall(
1697
- toolCall.toolName,
1698
- toolCall.content,
1699
- toolSchema
1700
- );
1701
- const result = applyHeuristicPipeline(ctx, pipelineConfig, {
1702
- parse: (xml, schema) => parse3(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
1703
- onError: options == null ? void 0 : options.onError,
1704
- maxReparses
1705
- });
1706
- if (result.parsed !== null) {
530
+ const parseConfig = {
531
+ ...parseOptions != null ? parseOptions : {},
532
+ onError: (_a = options == null ? void 0 : options.onError) != null ? _a : parseOptions == null ? void 0 : parseOptions.onError
533
+ };
534
+ try {
535
+ const parsed = parse(toolCall.content, toolSchema, parseConfig);
1707
536
  processedElements.push({
1708
537
  type: "tool-call",
1709
538
  toolCallId: generateId(),
1710
539
  toolName: toolCall.toolName,
1711
- input: JSON.stringify(result.parsed)
540
+ input: JSON.stringify(parsed)
1712
541
  });
1713
- } else {
542
+ } catch (error) {
1714
543
  const originalCallText = text.substring(
1715
544
  toolCall.startIndex,
1716
545
  toolCall.endIndex
1717
546
  );
1718
- (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
547
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
1719
548
  options,
1720
549
  `Could not process XML tool call: ${toolCall.toolName}`,
1721
- { toolCall: originalCallText, error: result.errors[0] }
550
+ { toolCall: originalCallText, error }
1722
551
  );
1723
552
  processedElements.push({ type: "text", text: originalCallText });
1724
553
  }
1725
554
  }
1726
555
  function handleStreamingToolCallEnd(params) {
1727
- var _a;
556
+ var _a, _b;
1728
557
  const {
1729
558
  toolContent,
1730
559
  currentToolCall,
@@ -1732,51 +561,27 @@ function handleStreamingToolCallEnd(params) {
1732
561
  options,
1733
562
  ctrl,
1734
563
  flushText,
1735
- pipelineConfig,
1736
- maxReparses
564
+ parseOptions
1737
565
  } = params;
1738
566
  const toolSchema = getToolSchema(tools, currentToolCall.name);
1739
- let parsedResult = null;
1740
- if (pipelineConfig) {
1741
- const ctx = createIntermediateCall(
1742
- currentToolCall.name,
1743
- toolContent,
1744
- toolSchema
1745
- );
1746
- const result = applyHeuristicPipeline(ctx, pipelineConfig, {
1747
- parse: (xml, schema) => parse3(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
1748
- onError: options == null ? void 0 : options.onError,
1749
- maxReparses
1750
- });
1751
- parsedResult = result.parsed;
1752
- } else {
1753
- try {
1754
- const primary = escapeInvalidLt(normalizeCloseTags(toolContent));
1755
- const parsed = parse3(primary, toolSchema, {
1756
- onError: options == null ? void 0 : options.onError,
1757
- noChildNodes: []
1758
- });
1759
- parsedResult = repairParsedAgainstSchema(parsed, toolSchema);
1760
- } catch (e) {
1761
- parsedResult = tryParseSecondaryXml(
1762
- toolContent,
1763
- toolSchema,
1764
- options != null ? options : {}
1765
- );
1766
- }
1767
- }
567
+ const parseConfig = {
568
+ ...parseOptions != null ? parseOptions : {},
569
+ onError: (_a = options == null ? void 0 : options.onError) != null ? _a : parseOptions == null ? void 0 : parseOptions.onError
570
+ };
1768
571
  flushText(ctrl);
1769
- if (parsedResult !== null) {
572
+ try {
573
+ const parsedResult = parse(toolContent, toolSchema, parseConfig);
1770
574
  ctrl.enqueue({
1771
575
  type: "tool-call",
1772
576
  toolCallId: generateId(),
1773
577
  toolName: currentToolCall.name,
1774
578
  input: JSON.stringify(parsedResult)
1775
579
  });
1776
- } else {
580
+ } catch (error) {
1777
581
  const original = `<${currentToolCall.name}>${toolContent}</${currentToolCall.name}>`;
1778
- (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not process streaming XML tool call", {
1779
- toolCall: original
582
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, "Could not process streaming XML tool call", {
583
+ toolCall: original,
584
+ error
1780
585
  });
1781
586
  flushText(ctrl, original);
1782
587
  }
@@ -1815,11 +620,11 @@ function consumeClosingTag(text, lt) {
1815
620
  }
1816
621
  function consumeOpenTag(text, lt) {
1817
622
  let p = lt + 1;
1818
- while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
623
+ while (p < text.length && WHITESPACE_REGEX.test(text[p])) {
1819
624
  p += 1;
1820
625
  }
1821
626
  const nameStart = p;
1822
- while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
627
+ while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
1823
628
  p += 1;
1824
629
  }
1825
630
  const name = text.slice(nameStart, p);
@@ -1828,7 +633,7 @@ function consumeOpenTag(text, lt) {
1828
633
  return null;
1829
634
  }
1830
635
  let r = q - 1;
1831
- while (r >= nameStart && WHITESPACE_REGEX3.test(text[r])) {
636
+ while (r >= nameStart && WHITESPACE_REGEX.test(text[r])) {
1832
637
  r -= 1;
1833
638
  }
1834
639
  const selfClosing = text[r] === "/";
@@ -1857,11 +662,11 @@ function nextTagToken(text, fromPos) {
1857
662
  if (next === "/") {
1858
663
  const closing = consumeClosingTag(text, lt);
1859
664
  let p = lt + 2;
1860
- while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
665
+ while (p < text.length && WHITESPACE_REGEX.test(text[p])) {
1861
666
  p += 1;
1862
667
  }
1863
668
  const nameStart = p;
1864
- while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
669
+ while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
1865
670
  p += 1;
1866
671
  }
1867
672
  const name = text.slice(nameStart, p);
@@ -1878,49 +683,90 @@ function nextTagToken(text, fromPos) {
1878
683
  nextPos: open.nextPos
1879
684
  };
1880
685
  }
686
+ function findNextToolTag(text, searchIndex, startTag, selfTag) {
687
+ const openIdx = text.indexOf(startTag, searchIndex);
688
+ const selfIdx = text.indexOf(selfTag, searchIndex);
689
+ if (openIdx === -1 && selfIdx === -1) {
690
+ return null;
691
+ }
692
+ const isSelfClosing = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx);
693
+ return {
694
+ tagStart: isSelfClosing ? selfIdx : openIdx,
695
+ isSelfClosing
696
+ };
697
+ }
698
+ function findLastCloseTagStart(segment, toolName) {
699
+ const closeTagPattern = new RegExp(
700
+ `</\\s*${escapeRegExp2(toolName)}\\s*>`,
701
+ "g"
702
+ );
703
+ let closeTagStart = -1;
704
+ let match = closeTagPattern.exec(segment);
705
+ while (match !== null) {
706
+ closeTagStart = match.index;
707
+ match = closeTagPattern.exec(segment);
708
+ }
709
+ if (closeTagStart === -1) {
710
+ return segment.lastIndexOf("<");
711
+ }
712
+ return closeTagStart;
713
+ }
714
+ function pushSelfClosingToolCall(toolCalls, toolName, text, tagStart, selfTag) {
715
+ const endIndex = tagStart + selfTag.length;
716
+ toolCalls.push({
717
+ toolName,
718
+ startIndex: tagStart,
719
+ endIndex,
720
+ content: "",
721
+ segment: text.substring(tagStart, endIndex)
722
+ });
723
+ return endIndex;
724
+ }
725
+ function appendOpenToolCallIfComplete(toolCalls, text, toolName, tagStart, startTag) {
726
+ const contentStart = tagStart + startTag.length;
727
+ const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
728
+ if (fullTagEnd === -1 || fullTagEnd <= contentStart) {
729
+ return contentStart;
730
+ }
731
+ const segment = text.substring(tagStart, fullTagEnd);
732
+ const closeTagStart = findLastCloseTagStart(segment, toolName);
733
+ const inner = closeTagStart === -1 ? segment.slice(startTag.length) : segment.slice(startTag.length, closeTagStart);
734
+ toolCalls.push({
735
+ toolName,
736
+ startIndex: tagStart,
737
+ endIndex: fullTagEnd,
738
+ content: inner,
739
+ segment
740
+ });
741
+ return fullTagEnd;
742
+ }
1881
743
  function findToolCallsForName(text, toolName) {
1882
- var _a;
1883
744
  const toolCalls = [];
745
+ const startTag = `<${toolName}>`;
746
+ const selfTag = `<${toolName}/>`;
1884
747
  let searchIndex = 0;
1885
748
  while (searchIndex < text.length) {
1886
- const startTag = `<${toolName}>`;
1887
- const selfTag = `<${toolName}/>`;
1888
- const openIdx = text.indexOf(startTag, searchIndex);
1889
- const selfIdx = text.indexOf(selfTag, searchIndex);
1890
- if (openIdx === -1 && selfIdx === -1) {
749
+ const match = findNextToolTag(text, searchIndex, startTag, selfTag);
750
+ if (match === null) {
1891
751
  break;
1892
752
  }
1893
- const tagStart = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx) ? selfIdx : openIdx;
1894
- const isSelfClosing = tagStart === selfIdx;
1895
- if (isSelfClosing) {
1896
- const endIndex = tagStart + selfTag.length;
1897
- const segment = text.substring(tagStart, endIndex);
1898
- toolCalls.push({
753
+ if (match.isSelfClosing) {
754
+ searchIndex = pushSelfClosingToolCall(
755
+ toolCalls,
1899
756
  toolName,
1900
- startIndex: tagStart,
1901
- endIndex,
1902
- content: "",
1903
- segment
1904
- });
1905
- searchIndex = endIndex;
757
+ text,
758
+ match.tagStart,
759
+ selfTag
760
+ );
1906
761
  continue;
1907
762
  }
1908
- const contentStart = tagStart + startTag.length;
1909
- const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
1910
- if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
1911
- const segment = text.substring(tagStart, fullTagEnd);
1912
- const inner = (_a = extractRawInner(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
1913
- toolCalls.push({
1914
- toolName,
1915
- startIndex: tagStart,
1916
- endIndex: fullTagEnd,
1917
- content: inner,
1918
- segment
1919
- });
1920
- searchIndex = fullTagEnd;
1921
- } else {
1922
- searchIndex = contentStart;
1923
- }
763
+ searchIndex = appendOpenToolCallIfComplete(
764
+ toolCalls,
765
+ text,
766
+ toolName,
767
+ match.tagStart,
768
+ startTag
769
+ );
1924
770
  }
1925
771
  return toolCalls;
1926
772
  }
@@ -1997,16 +843,20 @@ function processToolCallInBuffer(params) {
1997
843
  controller,
1998
844
  flushText,
1999
845
  setBuffer,
2000
- pipelineConfig,
2001
- maxReparses
846
+ parseOptions
2002
847
  } = params;
2003
- const endTag = `</${currentToolCall.name}>`;
2004
- const endIdx = buffer.indexOf(endTag);
2005
- if (endIdx === -1) {
848
+ const endTagPattern = new RegExp(
849
+ `</\\s*${escapeRegExp2(currentToolCall.name)}\\s*>`
850
+ );
851
+ const endMatch = endTagPattern.exec(buffer);
852
+ if (!endMatch || endMatch.index === void 0) {
2006
853
  return { buffer, currentToolCall, shouldBreak: true };
2007
854
  }
855
+ const endIdx = endMatch.index;
856
+ const endPos = endIdx + endMatch[0].length;
2008
857
  const content = buffer.substring(0, endIdx);
2009
- setBuffer(buffer.substring(endIdx + endTag.length));
858
+ const remainder = buffer.substring(endPos);
859
+ setBuffer(remainder);
2010
860
  handleStreamingToolCallEnd({
2011
861
  toolContent: content,
2012
862
  currentToolCall,
@@ -2014,11 +864,10 @@ function processToolCallInBuffer(params) {
2014
864
  options,
2015
865
  ctrl: controller,
2016
866
  flushText,
2017
- pipelineConfig,
2018
- maxReparses
867
+ parseOptions
2019
868
  });
2020
869
  return {
2021
- buffer: buffer.substring(endIdx + endTag.length),
870
+ buffer: remainder,
2022
871
  currentToolCall: null,
2023
872
  shouldBreak: false
2024
873
  };
@@ -2031,8 +880,7 @@ function processNoToolCallInBuffer(params) {
2031
880
  flushText,
2032
881
  tools,
2033
882
  options,
2034
- pipelineConfig,
2035
- maxReparses,
883
+ parseOptions,
2036
884
  setBuffer
2037
885
  } = params;
2038
886
  const {
@@ -2067,8 +915,7 @@ function processNoToolCallInBuffer(params) {
2067
915
  options,
2068
916
  ctrl: controller,
2069
917
  flushText,
2070
- pipelineConfig,
2071
- maxReparses
918
+ parseOptions
2072
919
  });
2073
920
  return {
2074
921
  buffer: newBuffer2,
@@ -2087,7 +934,7 @@ function processNoToolCallInBuffer(params) {
2087
934
  shouldContinue: true
2088
935
  };
2089
936
  }
2090
- function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, setCurrentToolCall, tools, options, toolNames, flushText, pipelineConfig, maxReparses) {
937
+ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, setCurrentToolCall, tools, options, toolNames, flushText, parseOptions) {
2091
938
  return (controller) => {
2092
939
  while (true) {
2093
940
  const currentToolCall = getCurrentToolCall();
@@ -2100,8 +947,7 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
2100
947
  controller,
2101
948
  flushText,
2102
949
  setBuffer,
2103
- pipelineConfig,
2104
- maxReparses
950
+ parseOptions
2105
951
  });
2106
952
  setBuffer(result.buffer);
2107
953
  setCurrentToolCall(result.currentToolCall);
@@ -2116,8 +962,7 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
2116
962
  flushText,
2117
963
  tools,
2118
964
  options,
2119
- pipelineConfig,
2120
- maxReparses,
965
+ parseOptions,
2121
966
  setBuffer
2122
967
  });
2123
968
  setBuffer(result.buffer);
@@ -2134,43 +979,12 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
2134
979
  };
2135
980
  }
2136
981
  var xmlProtocol = (protocolOptions) => {
2137
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2138
- let pipelineConfig = protocolOptions == null ? void 0 : protocolOptions.pipeline;
2139
- const maxReparses = protocolOptions == null ? void 0 : protocolOptions.maxReparses;
2140
- if ((protocolOptions == null ? void 0 : protocolOptions.heuristics) && protocolOptions.heuristics.length > 0) {
2141
- const heuristicsConfig = {
2142
- preParse: [],
2143
- fallbackReparse: [],
2144
- postParse: []
2145
- };
2146
- for (const h of protocolOptions.heuristics) {
2147
- if (h.phase === "pre-parse") {
2148
- (_a = heuristicsConfig.preParse) == null ? void 0 : _a.push(h);
2149
- } else if (h.phase === "fallback-reparse") {
2150
- (_b = heuristicsConfig.fallbackReparse) == null ? void 0 : _b.push(h);
2151
- } else if (h.phase === "post-parse") {
2152
- (_c = heuristicsConfig.postParse) == null ? void 0 : _c.push(h);
2153
- }
2154
- }
2155
- if (pipelineConfig) {
2156
- pipelineConfig = {
2157
- preParse: [
2158
- ...(_d = pipelineConfig.preParse) != null ? _d : [],
2159
- ...(_e = heuristicsConfig.preParse) != null ? _e : []
2160
- ],
2161
- fallbackReparse: [
2162
- ...(_f = pipelineConfig.fallbackReparse) != null ? _f : [],
2163
- ...(_g = heuristicsConfig.fallbackReparse) != null ? _g : []
2164
- ],
2165
- postParse: [
2166
- ...(_h = pipelineConfig.postParse) != null ? _h : [],
2167
- ...(_i = heuristicsConfig.postParse) != null ? _i : []
2168
- ]
2169
- };
2170
- } else {
2171
- pipelineConfig = heuristicsConfig;
2172
- }
2173
- }
982
+ var _a;
983
+ const parseOptions = {
984
+ repair: true,
985
+ noChildNodes: [],
986
+ ...(_a = protocolOptions == null ? void 0 : protocolOptions.parseOptions) != null ? _a : {}
987
+ };
2174
988
  return {
2175
989
  formatTools({ tools, toolSystemPromptTemplate }) {
2176
990
  return toolSystemPromptTemplate(tools || []);
@@ -2184,7 +998,7 @@ var xmlProtocol = (protocolOptions) => {
2184
998
  args = toolCall.input;
2185
999
  }
2186
1000
  }
2187
- return stringify2(toolCall.toolName, args, {
1001
+ return stringify(toolCall.toolName, args, {
2188
1002
  suppressEmptyNode: false,
2189
1003
  format: true,
2190
1004
  minimalEscaping: true
@@ -2205,14 +1019,13 @@ var xmlProtocol = (protocolOptions) => {
2205
1019
  text: text.substring(currentIndex, tc.startIndex)
2206
1020
  });
2207
1021
  }
2208
- processToolCallWithPipeline({
1022
+ processToolCall({
2209
1023
  toolCall: tc,
2210
1024
  tools,
2211
1025
  options,
2212
1026
  text,
2213
1027
  processedElements,
2214
- pipelineConfig,
2215
- maxReparses
1028
+ parseOptions
2216
1029
  });
2217
1030
  currentIndex = tc.endIndex;
2218
1031
  }
@@ -2253,8 +1066,7 @@ var xmlProtocol = (protocolOptions) => {
2253
1066
  options,
2254
1067
  toolNames,
2255
1068
  flushText,
2256
- pipelineConfig,
2257
- maxReparses
1069
+ parseOptions
2258
1070
  );
2259
1071
  return new TransformStream({
2260
1072
  transform(chunk, controller) {
@@ -2304,8 +1116,8 @@ var xmlProtocol = (protocolOptions) => {
2304
1116
 
2305
1117
  // src/core/protocols/yaml-protocol.ts
2306
1118
  import YAML from "yaml";
2307
- var NAME_CHAR_RE3 = /[A-Za-z0-9_:-]/;
2308
- var WHITESPACE_REGEX4 = /\s/;
1119
+ var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
1120
+ var WHITESPACE_REGEX2 = /\s/;
2309
1121
  var LEADING_WHITESPACE_RE = /^(\s*)/;
2310
1122
  function findClosingTagEnd(text, contentStart, toolName) {
2311
1123
  let pos = contentStart;
@@ -2322,11 +1134,11 @@ function findClosingTagEnd(text, contentStart, toolName) {
2322
1134
  break;
2323
1135
  }
2324
1136
  let p = ltIdx + 2;
2325
- while (p < gtIdx && WHITESPACE_REGEX4.test(text[p])) {
1137
+ while (p < gtIdx && WHITESPACE_REGEX2.test(text[p])) {
2326
1138
  p++;
2327
1139
  }
2328
1140
  const nameStart = p;
2329
- while (p < gtIdx && NAME_CHAR_RE3.test(text.charAt(p))) {
1141
+ while (p < gtIdx && NAME_CHAR_RE2.test(text.charAt(p))) {
2330
1142
  p++;
2331
1143
  }
2332
1144
  const name = text.slice(nameStart, p);
@@ -2342,11 +1154,11 @@ function findClosingTagEnd(text, contentStart, toolName) {
2342
1154
  pos = gtIdx === -1 ? text.length : gtIdx + 1;
2343
1155
  } else {
2344
1156
  let p = ltIdx + 1;
2345
- while (p < text.length && WHITESPACE_REGEX4.test(text[p])) {
1157
+ while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
2346
1158
  p++;
2347
1159
  }
2348
1160
  const nameStart = p;
2349
- while (p < text.length && NAME_CHAR_RE3.test(text.charAt(p))) {
1161
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
2350
1162
  p++;
2351
1163
  }
2352
1164
  const name = text.slice(nameStart, p);
@@ -2355,7 +1167,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
2355
1167
  break;
2356
1168
  }
2357
1169
  let r = gtIdx - 1;
2358
- while (r >= nameStart && WHITESPACE_REGEX4.test(text[r])) {
1170
+ while (r >= nameStart && WHITESPACE_REGEX2.test(text[r])) {
2359
1171
  r--;
2360
1172
  }
2361
1173
  const selfClosing = text[r] === "/";
@@ -2860,7 +1672,7 @@ function hasInputProperty(obj) {
2860
1672
 
2861
1673
  // src/generate-handler.ts
2862
1674
  import { generateId as generateId2 } from "@ai-sdk/provider-utils";
2863
- import { coerceBySchema } from "@ai-sdk-tool/rxml";
1675
+ import { coerceBySchema } from "@ai-sdk-tool/schema-coerce";
2864
1676
  function parseToolChoiceJson(text, providerOptions) {
2865
1677
  var _a;
2866
1678
  try {
@@ -3686,20 +2498,12 @@ function createToolMiddleware({
3686
2498
  const resolvedProtocol = isTCMProtocolFactory(protocol) ? protocol() : protocol;
3687
2499
  return {
3688
2500
  specificationVersion: "v3",
3689
- wrapStream: ({ doStream, doGenerate, params }) => {
3690
- if (isToolChoiceActive(params)) {
3691
- return toolChoiceStream({
3692
- doGenerate,
3693
- options: extractOnErrorOption(params.providerOptions)
3694
- });
3695
- }
3696
- return wrapStream({
3697
- protocol: resolvedProtocol,
3698
- doStream,
3699
- doGenerate,
3700
- params
3701
- });
3702
- },
2501
+ wrapStream: ({ doStream, doGenerate, params }) => wrapStream({
2502
+ protocol: resolvedProtocol,
2503
+ doStream,
2504
+ doGenerate,
2505
+ params
2506
+ }),
3703
2507
  wrapGenerate: async ({ doGenerate, params }) => wrapGenerate({
3704
2508
  protocol: resolvedProtocol,
3705
2509
  doGenerate,
@@ -3733,25 +2537,13 @@ var yamlToolMiddleware = createToolMiddleware({
3733
2537
  });
3734
2538
 
3735
2539
  export {
3736
- applyHeuristicPipeline,
3737
- createIntermediateCall,
3738
- mergePipelineConfigs,
3739
- normalizeCloseTagsHeuristic,
3740
- escapeInvalidLtHeuristic,
3741
- balanceTagsHeuristic,
3742
- dedupeShellStringTagsHeuristic,
3743
- repairAgainstSchemaHeuristic,
3744
- defaultPipelineConfig,
3745
2540
  getDebugLevel,
3746
2541
  logParseFailure,
3747
2542
  logRawChunk,
3748
2543
  logParsedChunk,
3749
2544
  logParsedSummary,
3750
2545
  getPotentialStartIndex,
3751
- escapeRegExp2 as escapeRegExp,
3752
- transform,
3753
- parse2 as parse,
3754
- stringify,
2546
+ escapeRegExp,
3755
2547
  jsonProtocol,
3756
2548
  isProtocolFactory,
3757
2549
  isTCMProtocolFactory,
@@ -3775,4 +2567,4 @@ export {
3775
2567
  xmlToolMiddleware,
3776
2568
  yamlToolMiddleware
3777
2569
  };
3778
- //# sourceMappingURL=chunk-TQT6XSP7.js.map
2570
+ //# sourceMappingURL=chunk-PIUBQRFC.js.map