@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.
@@ -17,6 +17,7 @@ var __copyProps = (to, from, except, desc) => {
17
17
  }
18
18
  return to;
19
19
  };
20
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
20
21
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
22
  // If the importer is in node compatibility mode or this is not an ESM
22
23
  // file that has been converted to a CommonJS file using a Babel-
@@ -35,449 +36,43 @@ __export(community_exports, {
35
36
  });
36
37
  module.exports = __toCommonJS(community_exports);
37
38
 
38
- // src/core/heuristics/engine.ts
39
- function applyRawSegmentUpdate(current, result) {
40
- if (result.rawSegment !== void 0) {
41
- return { ...current, rawSegment: result.rawSegment };
42
- }
43
- return current;
44
- }
45
- function applyParsedUpdate(current, result) {
46
- if (result.parsed !== void 0) {
47
- return { ...current, parsed: result.parsed };
48
- }
49
- return current;
50
- }
51
- function applyWarningsUpdate(current, result) {
52
- var _a, _b;
53
- if (result.warnings && result.warnings.length > 0) {
54
- const meta = (_a = current.meta) != null ? _a : {};
55
- const existingWarnings = (_b = meta.warnings) != null ? _b : [];
56
- return {
57
- ...current,
58
- meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
59
- };
60
- }
61
- return current;
62
- }
63
- function attemptReparse(current, result, reparseCount, maxReparses, parse4) {
64
- if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
65
- return { state: current, newCount: reparseCount };
66
- }
67
- try {
68
- const reparsed = parse4(result.rawSegment, current.schema);
69
- return {
70
- state: { ...current, parsed: reparsed, errors: [] },
71
- newCount: reparseCount + 1
72
- };
73
- } catch (error) {
74
- return {
75
- state: { ...current, errors: [...current.errors, error] },
76
- newCount: reparseCount + 1
77
- };
78
- }
79
- }
80
- function executePhase(ctx, heuristics, options) {
81
- var _a;
82
- let current = ctx;
83
- let reparseCount = 0;
84
- const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
85
- for (const heuristic of heuristics) {
86
- if (!heuristic.applies(current)) {
87
- continue;
88
- }
89
- const result = heuristic.run(current);
90
- current = applyRawSegmentUpdate(current, result);
91
- current = applyParsedUpdate(current, result);
92
- current = applyWarningsUpdate(current, result);
93
- const reparseResult = attemptReparse(
94
- current,
95
- result,
96
- reparseCount,
97
- maxReparses,
98
- options.parse
99
- );
100
- current = reparseResult.state;
101
- reparseCount = reparseResult.newCount;
102
- if (result.stop) {
103
- break;
104
- }
105
- }
106
- return current;
107
- }
108
- function applyHeuristicPipeline(ctx, config, options) {
109
- let current = ctx;
110
- if (config.preParse && config.preParse.length > 0) {
111
- current = executePhase(current, config.preParse, options);
112
- }
113
- if (current.parsed === null && current.errors.length === 0) {
114
- try {
115
- const parsed = options.parse(current.rawSegment, current.schema);
116
- current = { ...current, parsed, errors: [] };
117
- } catch (error) {
118
- current = { ...current, errors: [error] };
119
- }
120
- }
121
- if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
122
- current = executePhase(current, config.fallbackReparse, options);
123
- }
124
- if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
125
- current = executePhase(current, config.postParse, options);
126
- }
127
- return current;
128
- }
129
- function createIntermediateCall(toolName, rawSegment, schema) {
130
- return {
131
- toolName,
132
- schema,
133
- rawSegment,
134
- parsed: null,
135
- errors: [],
136
- meta: { originalContent: rawSegment }
137
- };
138
- }
39
+ // src/index.ts
40
+ var src_exports = {};
41
+ __export(src_exports, {
42
+ createDynamicIfThenElseSchema: () => createDynamicIfThenElseSchema,
43
+ createToolMiddleware: () => createToolMiddleware,
44
+ decodeOriginalTools: () => decodeOriginalTools,
45
+ encodeOriginalTools: () => encodeOriginalTools,
46
+ escapeRegExp: () => escapeRegExp,
47
+ extractOnErrorOption: () => extractOnErrorOption,
48
+ extractToolNamesFromOriginalTools: () => extractToolNamesFromOriginalTools,
49
+ getDebugLevel: () => getDebugLevel,
50
+ getPotentialStartIndex: () => getPotentialStartIndex,
51
+ hasInputProperty: () => hasInputProperty,
52
+ hermesToolMiddleware: () => hermesToolMiddleware,
53
+ isProtocolFactory: () => isProtocolFactory,
54
+ isTCMProtocolFactory: () => isTCMProtocolFactory,
55
+ isToolChoiceActive: () => isToolChoiceActive,
56
+ isToolResultPart: () => isToolResultPart,
57
+ jsonProtocol: () => jsonProtocol,
58
+ logParseFailure: () => logParseFailure,
59
+ logParsedChunk: () => logParsedChunk,
60
+ logParsedSummary: () => logParsedSummary,
61
+ logRawChunk: () => logRawChunk,
62
+ originalToolsSchema: () => originalToolsSchema,
63
+ toolChoiceStream: () => toolChoiceStream,
64
+ transformParams: () => transformParams,
65
+ wrapGenerate: () => wrapGenerate,
66
+ wrapStream: () => wrapStream,
67
+ xmlProtocol: () => xmlProtocol,
68
+ xmlToolMiddleware: () => xmlToolMiddleware,
69
+ yamlProtocol: () => yamlProtocol,
70
+ yamlToolMiddleware: () => yamlToolMiddleware
71
+ });
72
+ __reExport(src_exports, require("@ai-sdk-tool/rjson"));
139
73
 
140
- // src/core/heuristics/xml-defaults.ts
141
- var import_rxml = require("@ai-sdk-tool/rxml");
142
- var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
143
- var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
144
- var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
145
- var WHITESPACE_REGEX = /\s/;
146
- var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
147
- var NAME_START_CHAR_RE = /[A-Za-z_:]/;
148
- var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
149
- var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
150
- var normalizeCloseTagsHeuristic = {
151
- id: "normalize-close-tags",
152
- phase: "pre-parse",
153
- applies: () => true,
154
- run: (ctx) => {
155
- const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
156
- if (normalized !== ctx.rawSegment) {
157
- return { rawSegment: normalized };
158
- }
159
- return {};
160
- }
161
- };
162
- var escapeInvalidLtHeuristic = {
163
- id: "escape-invalid-lt",
164
- phase: "pre-parse",
165
- applies: () => true,
166
- run: (ctx) => {
167
- const escaped = escapeInvalidLt(ctx.rawSegment);
168
- if (escaped !== ctx.rawSegment) {
169
- return { rawSegment: escaped };
170
- }
171
- return {};
172
- }
173
- };
174
- var balanceTagsHeuristic = {
175
- id: "balance-tags",
176
- phase: "fallback-reparse",
177
- applies: (ctx) => {
178
- var _a;
179
- const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
180
- const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
181
- const balanced = balanceTags(original);
182
- const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
183
- if (!hasMalformedClose && balanced.length > normalized.length) {
184
- return false;
185
- }
186
- return balanced !== normalized;
187
- },
188
- run: (ctx) => {
189
- var _a;
190
- const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
191
- const balanced = balanceTags(original);
192
- const escaped = escapeInvalidLt(balanced);
193
- return { rawSegment: escaped, reparse: true };
194
- }
195
- };
196
- var dedupeShellStringTagsHeuristic = {
197
- id: "dedupe-shell-string-tags",
198
- phase: "fallback-reparse",
199
- applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
200
- run: (ctx) => {
201
- const names = getStringPropertyNames(ctx.schema);
202
- let deduped = ctx.rawSegment;
203
- for (const key of names) {
204
- deduped = dedupeSingleTag(deduped, key);
205
- }
206
- if (deduped !== ctx.rawSegment) {
207
- return { rawSegment: deduped, reparse: true };
208
- }
209
- return {};
210
- }
211
- };
212
- var repairAgainstSchemaHeuristic = {
213
- id: "repair-against-schema",
214
- phase: "post-parse",
215
- applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
216
- run: (ctx) => {
217
- const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
218
- if (repaired !== ctx.parsed) {
219
- return { parsed: repaired };
220
- }
221
- return {};
222
- }
223
- };
224
- var defaultPipelineConfig = {
225
- preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
226
- fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
227
- postParse: [repairAgainstSchemaHeuristic]
228
- };
229
- var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
230
- function isIndexTagAt(xml, pos) {
231
- const remaining = xml.slice(pos);
232
- return INDEX_TAG_RE.test(remaining);
233
- }
234
- function escapeInvalidLt(xml) {
235
- const len = xml.length;
236
- let out = "";
237
- for (let i = 0; i < len; i += 1) {
238
- const ch = xml[i];
239
- if (ch === "<") {
240
- const next = i + 1 < len ? xml[i + 1] : "";
241
- const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
242
- const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
243
- if (!(isValidStart || isIndexTag)) {
244
- out += "&lt;";
245
- continue;
246
- }
247
- }
248
- out += ch;
249
- }
250
- return out;
251
- }
252
- function balanceTags(xml) {
253
- const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
254
- let i = 0;
255
- const len = src.length;
256
- const out = [];
257
- const stack = [];
258
- while (i < len) {
259
- const lt = src.indexOf("<", i);
260
- if (lt === -1) {
261
- out.push(src.slice(i));
262
- break;
263
- }
264
- out.push(src.slice(i, lt));
265
- if (lt + 1 >= len) {
266
- break;
267
- }
268
- const next = src[lt + 1];
269
- if (next === "!" || next === "?") {
270
- i = handleSpecialTagSegment(src, lt, out);
271
- continue;
272
- }
273
- if (next === "/") {
274
- i = handleClosingTagSegment(src, lt, out, stack);
275
- continue;
276
- }
277
- i = handleOpeningTagSegment(src, lt, out, stack);
278
- }
279
- for (let k = stack.length - 1; k >= 0; k -= 1) {
280
- out.push(`</${stack[k]}>`);
281
- }
282
- return out.join("");
283
- }
284
- function skipWs(s, p, len) {
285
- let idx = p;
286
- while (idx < len && WHITESPACE_REGEX.test(s[idx])) {
287
- idx += 1;
288
- }
289
- return idx;
290
- }
291
- function parseTagNameAt(s, p, len) {
292
- let idx = p;
293
- const start = idx;
294
- while (idx < len && NAME_CHAR_RE.test(s[idx])) {
295
- idx += 1;
296
- }
297
- return { name: s.slice(start, idx), pos: idx };
298
- }
299
- function handleSpecialTagSegment(src, lt, out) {
300
- const gt = src.indexOf(">", lt + 1);
301
- if (gt === -1) {
302
- out.push(src.slice(lt));
303
- return src.length;
304
- }
305
- out.push(src.slice(lt, gt + 1));
306
- return gt + 1;
307
- }
308
- function handleClosingTagSegment(src, lt, out, stack) {
309
- const len = src.length;
310
- let p = skipWs(src, lt + 2, len);
311
- const { name, pos } = parseTagNameAt(src, p, len);
312
- p = pos;
313
- const gt = src.indexOf(">", p);
314
- const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
315
- const idx = stack.lastIndexOf(name);
316
- if (idx !== -1) {
317
- for (let k = stack.length - 1; k > idx; k -= 1) {
318
- out.push(`</${stack[k]}>`);
319
- stack.pop();
320
- }
321
- out.push(closingText);
322
- stack.pop();
323
- }
324
- return gt === -1 ? len : gt + 1;
325
- }
326
- function handleOpeningTagSegment(src, lt, out, stack) {
327
- const len = src.length;
328
- let p = skipWs(src, lt + 1, len);
329
- const nameStart = p;
330
- const parsed = parseTagNameAt(src, p, len);
331
- p = parsed.pos;
332
- const name = src.slice(nameStart, p);
333
- const q = src.indexOf(">", p);
334
- if (q === -1) {
335
- out.push(src.slice(lt));
336
- return len;
337
- }
338
- let r = q - 1;
339
- while (r >= nameStart && WHITESPACE_REGEX.test(src[r])) {
340
- r -= 1;
341
- }
342
- const selfClosing = src[r] === "/";
343
- out.push(src.slice(lt, q + 1));
344
- if (!selfClosing && name) {
345
- stack.push(name);
346
- }
347
- return q + 1;
348
- }
349
- function extractSchemaProperties(schema) {
350
- const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
351
- if (!unwrapped || typeof unwrapped !== "object") {
352
- return void 0;
353
- }
354
- return unwrapped.properties;
355
- }
356
- function shouldDeduplicateStringTags(schema) {
357
- const props = extractSchemaProperties(schema);
358
- if (!props) {
359
- return false;
360
- }
361
- const commandRaw = props.command;
362
- if (!commandRaw) {
363
- return false;
364
- }
365
- const command = (0, import_rxml.unwrapJsonSchema)(commandRaw);
366
- return (command == null ? void 0 : command.type) === "array";
367
- }
368
- function getStringPropertyNames(schema) {
369
- const props = extractSchemaProperties(schema);
370
- if (!props) {
371
- return [];
372
- }
373
- const names = [];
374
- for (const key of Object.keys(props)) {
375
- const prop = (0, import_rxml.unwrapJsonSchema)(props[key]);
376
- if ((prop == null ? void 0 : prop.type) === "string") {
377
- names.push(key);
378
- }
379
- }
380
- return names;
381
- }
382
- function escapeRegExp(s) {
383
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
384
- }
385
- function dedupeSingleTag(xml, key) {
386
- var _a, _b;
387
- const escaped = escapeRegExp(key);
388
- const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
389
- const matches = Array.from(xml.matchAll(re));
390
- if (matches.length <= 1) {
391
- return xml;
392
- }
393
- const last = matches.at(-1);
394
- let result = "";
395
- let cursor = 0;
396
- for (const m of matches) {
397
- const idx = (_a = m.index) != null ? _a : 0;
398
- result += xml.slice(cursor, idx);
399
- if (last && idx === ((_b = last.index) != null ? _b : -1)) {
400
- result += m[0];
401
- }
402
- cursor = idx + m[0].length;
403
- }
404
- result += xml.slice(cursor);
405
- return result;
406
- }
407
- function repairParsedAgainstSchema(input, schema) {
408
- if (!input || typeof input !== "object") {
409
- return input;
410
- }
411
- const properties = extractSchemaProperties(schema);
412
- if (!properties) {
413
- return input;
414
- }
415
- applySchemaProps(input, properties);
416
- return input;
417
- }
418
- function applySchemaProps(obj, properties) {
419
- for (const key of Object.keys(obj)) {
420
- const propSchema = properties[key];
421
- if (!propSchema) {
422
- continue;
423
- }
424
- const prop = (0, import_rxml.unwrapJsonSchema)(propSchema);
425
- if ((prop == null ? void 0 : prop.type) === "array" && prop.items) {
426
- const itemSchema = (0, import_rxml.unwrapJsonSchema)(prop.items);
427
- obj[key] = coerceArrayItems(obj[key], itemSchema);
428
- continue;
429
- }
430
- if ((prop == null ? void 0 : prop.type) === "object") {
431
- const val = obj[key];
432
- if (val && typeof val === "object") {
433
- obj[key] = repairParsedAgainstSchema(val, prop);
434
- }
435
- }
436
- }
437
- }
438
- function coerceArrayItems(val, itemSchema) {
439
- if (!Array.isArray(val)) {
440
- return val;
441
- }
442
- return val.map((v) => coerceArrayItem(v, itemSchema));
443
- }
444
- function coerceArrayItem(v, itemSchema) {
445
- const itemType = itemSchema == null ? void 0 : itemSchema.type;
446
- if (typeof v === "string" && itemType === "object") {
447
- const parsed = tryParseStringToSchemaObject(v, itemSchema);
448
- if (parsed !== null) {
449
- return parsed;
450
- }
451
- const fallback = extractStepStatusFromString(
452
- v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
453
- );
454
- if (fallback) {
455
- return fallback;
456
- }
457
- return v;
458
- }
459
- if (v && typeof v === "object" && itemType === "object") {
460
- return repairParsedAgainstSchema(v, itemSchema);
461
- }
462
- return v;
463
- }
464
- function tryParseStringToSchemaObject(xml, itemSchema) {
465
- try {
466
- const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
467
- const fixed = (0, import_rxml.parse)(normalized, itemSchema, { noChildNodes: [] });
468
- return typeof fixed === "string" ? null : fixed;
469
- } catch (e) {
470
- return null;
471
- }
472
- }
473
- function extractStepStatusFromString(normXml) {
474
- const stepMatch = normXml.match(STEP_TAG_RE);
475
- const statusMatch = normXml.match(STATUS_TAG_RE);
476
- if (stepMatch && statusMatch) {
477
- return { step: stepMatch[1], status: statusMatch[1] };
478
- }
479
- return null;
480
- }
74
+ // src/core/protocols/json-protocol.ts
75
+ var import_rjson = require("@ai-sdk-tool/rjson");
481
76
 
482
77
  // src/core/utils/debug.ts
483
78
  var LINE_SPLIT_REGEX = /\r?\n/;
@@ -658,652 +253,15 @@ function generateId() {
658
253
  }
659
254
 
660
255
  // src/core/utils/regex.ts
661
- function escapeRegExp2(literal) {
256
+ function escapeRegExp(literal) {
662
257
  return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
663
258
  }
664
259
 
665
- // src/core/utils/robust-json.ts
666
- var WHITESPACE_TEST_REGEX = /\s/;
667
- var WHITESPACE_REGEX2 = /^\s+/;
668
- var OBJECT_START_REGEX = /^\{/;
669
- var OBJECT_END_REGEX = /^\}/;
670
- var ARRAY_START_REGEX = /^\[/;
671
- var ARRAY_END_REGEX = /^\]/;
672
- var COMMA_REGEX = /^,/;
673
- var COLON_REGEX = /^:/;
674
- var KEYWORD_REGEX = /^(?:true|false|null)/;
675
- var NUMBER_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/;
676
- var STRING_DOUBLE_REGEX = /^"(?:[^"\\]|\\["bnrtf\\/]|\\u[0-9a-fA-F]{4})*"/;
677
- var STRING_SINGLE_REGEX = /^'((?:[^'\\]|\\['bnrtf\\/]|\\u[0-9a-fA-F]{4})*)'/;
678
- var COMMENT_SINGLE_REGEX = /^\/\/.*?(?:\r\n|\r|\n)/;
679
- var COMMENT_MULTI_REGEX = /^\/\*[\s\S]*?\*\//;
680
- var IDENTIFIER_REGEX = /^[$a-zA-Z0-9_\-+.*?!|&%^/#\\]+/;
681
- function some(array, f) {
682
- let acc = false;
683
- for (let i = 0; i < array.length; i += 1) {
684
- const result = f(array[i], i, array);
685
- acc = result === void 0 ? false : result;
686
- if (acc) {
687
- return acc;
688
- }
689
- }
690
- return acc;
691
- }
692
- function makeLexer(tokenSpecs) {
693
- return (contents) => {
694
- const tokens = [];
695
- let line = 1;
696
- let remainingContents = contents;
697
- function findToken() {
698
- const result = some(tokenSpecs, (tokenSpec) => {
699
- const m = tokenSpec.re.exec(remainingContents);
700
- if (m) {
701
- const raw = m[0];
702
- remainingContents = remainingContents.slice(raw.length);
703
- return {
704
- raw,
705
- matched: tokenSpec.f(m)
706
- // Process the match using the spec's function
707
- };
708
- }
709
- return;
710
- });
711
- return result === false ? void 0 : result;
712
- }
713
- while (remainingContents !== "") {
714
- const matched = findToken();
715
- if (!matched) {
716
- const err = new SyntaxError(
717
- `Unexpected character: ${remainingContents[0]}; input: ${remainingContents.substr(
718
- 0,
719
- 100
720
- )}`
721
- );
722
- err.line = line;
723
- throw err;
724
- }
725
- const tokenWithLine = matched.matched;
726
- tokenWithLine.line = line;
727
- line += matched.raw.replace(/[^\n]/g, "").length;
728
- tokens.push(tokenWithLine);
729
- }
730
- return tokens;
731
- };
732
- }
733
- function fStringSingle(m) {
734
- const content = m[1].replace(
735
- /([^'\\]|\\['bnrtf\\]|\\u[0-9a-fA-F]{4})/g,
736
- (mm) => {
737
- if (mm === '"') {
738
- return '\\"';
739
- }
740
- if (mm === "\\'") {
741
- return "'";
742
- }
743
- return mm;
744
- }
745
- );
746
- const match = `"${content}"`;
747
- return {
748
- type: "string",
749
- match,
750
- // The transformed, double-quoted string representation
751
- // Use JSON.parse on the transformed string to handle escape sequences correctly
752
- value: JSON.parse(match)
753
- };
754
- }
755
- function fStringDouble(m) {
756
- return {
757
- type: "string",
758
- match: m[0],
759
- // The raw matched string (including quotes)
760
- value: JSON.parse(m[0])
761
- // Use JSON.parse to handle escapes and get the value
762
- };
763
- }
764
- function fIdentifier(m) {
765
- const value = m[0];
766
- const match = '"' + value.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + // Escape backslashes and quotes
767
- '"';
768
- return {
769
- type: "string",
770
- // Treat identifiers as strings
771
- value,
772
- // The original identifier name
773
- match
774
- // The double-quoted string representation
775
- };
776
- }
777
- function fComment(m) {
778
- const match = m[0].replace(
779
- /./g,
780
- (c) => WHITESPACE_TEST_REGEX.test(c) ? c : " "
781
- );
782
- return {
783
- type: " ",
784
- // Represent comments as whitespace tokens
785
- match,
786
- // String containing original newlines and spaces for other chars
787
- value: void 0
788
- // Comments don't have a semantic value
789
- };
790
- }
791
- function fNumber(m) {
792
- return {
793
- type: "number",
794
- match: m[0],
795
- // The raw matched number string
796
- value: Number.parseFloat(m[0])
797
- // Convert string to number
798
- };
799
- }
800
- function fKeyword(m) {
801
- let value;
802
- switch (m[0]) {
803
- case "null":
804
- value = null;
805
- break;
806
- case "true":
807
- value = true;
808
- break;
809
- case "false":
810
- value = false;
811
- break;
812
- default:
813
- throw new Error(`Unexpected keyword: ${m[0]}`);
814
- }
815
- return {
816
- type: "atom",
817
- // Use 'atom' type for these literals
818
- match: m[0],
819
- // The raw matched keyword
820
- value
821
- // The corresponding JavaScript value
822
- };
823
- }
824
- function makeTokenSpecs(relaxed) {
825
- function f(type) {
826
- return (m) => {
827
- return { type, match: m[0], value: void 0 };
828
- };
829
- }
830
- let tokenSpecs = [
831
- { re: WHITESPACE_REGEX2, f: f(" ") },
832
- // Whitespace
833
- { re: OBJECT_START_REGEX, f: f("{") },
834
- // Object start
835
- { re: OBJECT_END_REGEX, f: f("}") },
836
- // Object end
837
- { re: ARRAY_START_REGEX, f: f("[") },
838
- // Array start
839
- { re: ARRAY_END_REGEX, f: f("]") },
840
- // Array end
841
- { re: COMMA_REGEX, f: f(",") },
842
- // Comma separator
843
- { re: COLON_REGEX, f: f(":") },
844
- // Key-value separator
845
- { re: KEYWORD_REGEX, f: fKeyword },
846
- // Keywords
847
- // Number: optional sign, digits, optional decimal part, optional exponent
848
- { re: NUMBER_REGEX, f: fNumber },
849
- // String: double-quoted, handles escapes
850
- { re: STRING_DOUBLE_REGEX, f: fStringDouble }
851
- ];
852
- if (relaxed) {
853
- tokenSpecs = tokenSpecs.concat([
854
- // Single-quoted strings
855
- {
856
- re: STRING_SINGLE_REGEX,
857
- f: fStringSingle
858
- },
859
- // Single-line comments (// ...)
860
- { re: COMMENT_SINGLE_REGEX, f: fComment },
861
- // Multi-line comments (/* ... */)
862
- { re: COMMENT_MULTI_REGEX, f: fComment },
863
- // Unquoted identifiers (treated as strings)
864
- // Allows letters, numbers, _, -, +, ., *, ?, !, |, &, %, ^, /, #, \
865
- { re: IDENTIFIER_REGEX, f: fIdentifier }
866
- // Note: The order matters here. Identifiers are checked after keywords/numbers.
867
- ]);
868
- }
869
- return tokenSpecs;
870
- }
871
- var lexer = makeLexer(makeTokenSpecs(true));
872
- var strictLexer = makeLexer(makeTokenSpecs(false));
873
- function previousNWSToken(tokens, index) {
874
- let currentIndex = index;
875
- for (; currentIndex >= 0; currentIndex -= 1) {
876
- if (tokens[currentIndex].type !== " ") {
877
- return currentIndex;
878
- }
879
- }
880
- return;
881
- }
882
- function stripTrailingComma(tokens) {
883
- const res = [];
884
- tokens.forEach((token, index) => {
885
- if (index > 0 && (token.type === "]" || token.type === "}")) {
886
- const prevNWSTokenIndex = previousNWSToken(res, res.length - 1);
887
- if (prevNWSTokenIndex !== void 0 && res[prevNWSTokenIndex].type === ",") {
888
- const preCommaIndex = previousNWSToken(res, prevNWSTokenIndex - 1);
889
- if (preCommaIndex !== void 0 && res[preCommaIndex].type !== "[" && res[preCommaIndex].type !== "{") {
890
- res[prevNWSTokenIndex] = {
891
- type: " ",
892
- match: " ",
893
- // Represent as a single space
894
- value: void 0,
895
- // Whitespace has no value
896
- line: res[prevNWSTokenIndex].line
897
- // Preserve original line number
898
- };
899
- }
900
- }
901
- }
902
- res.push(token);
903
- });
904
- return res;
905
- }
906
- function popToken(tokens, state) {
907
- var _a, _b;
908
- const token = tokens[state.pos];
909
- state.pos += 1;
910
- if (!token) {
911
- const lastLine = tokens.length !== 0 ? (_b = (_a = tokens.at(-1)) == null ? void 0 : _a.line) != null ? _b : 1 : 1;
912
- return { type: "eof", match: "", value: void 0, line: lastLine };
913
- }
914
- return token;
915
- }
916
- function strToken(token) {
917
- switch (token.type) {
918
- case "atom":
919
- case "string":
920
- case "number":
921
- return `${token.type} ${token.match}`;
922
- case "eof":
923
- return "end-of-file";
924
- default:
925
- return `'${token.type}'`;
926
- }
927
- }
928
- function skipColon(tokens, state) {
929
- const colon = popToken(tokens, state);
930
- if (colon.type !== ":") {
931
- const message = `Unexpected token: ${strToken(colon)}, expected ':'`;
932
- if (state.tolerant) {
933
- state.warnings.push({
934
- message,
935
- line: colon.line
936
- });
937
- state.pos -= 1;
938
- } else {
939
- const err = new SyntaxError(message);
940
- err.line = colon.line;
941
- throw err;
942
- }
943
- }
944
- }
945
- function skipPunctuation(tokens, state, valid) {
946
- const punctuation = [",", ":", "]", "}"];
947
- let token = popToken(tokens, state);
948
- while (true) {
949
- if (valid == null ? void 0 : valid.includes(token.type)) {
950
- return token;
951
- }
952
- if (token.type === "eof") {
953
- return token;
954
- }
955
- if (punctuation.includes(token.type)) {
956
- const message = `Unexpected token: ${strToken(
957
- token
958
- )}, expected '[', '{', number, string or atom`;
959
- if (state.tolerant) {
960
- state.warnings.push({
961
- message,
962
- line: token.line
963
- });
964
- token = popToken(tokens, state);
965
- } else {
966
- const err = new SyntaxError(message);
967
- err.line = token.line;
968
- throw err;
969
- }
970
- } else {
971
- return token;
972
- }
973
- }
974
- }
975
- function raiseError(state, token, message) {
976
- if (state.tolerant) {
977
- state.warnings.push({
978
- message,
979
- line: token.line
980
- });
981
- } else {
982
- const err = new SyntaxError(message);
983
- err.line = token.line;
984
- throw err;
985
- }
986
- }
987
- function raiseUnexpected(state, token, expected) {
988
- raiseError(
989
- state,
990
- token,
991
- `Unexpected token: ${strToken(token)}, expected ${expected}`
992
- );
993
- }
994
- function checkDuplicates(state, obj, token) {
995
- const key = String(token.value);
996
- if (!state.duplicate && Object.hasOwn(obj, key)) {
997
- raiseError(state, token, `Duplicate key: ${key}`);
998
- }
999
- }
1000
- function appendPair(state, obj, key, value) {
1001
- const finalValue = state.reviver ? state.reviver(key, value) : value;
1002
- if (finalValue !== void 0) {
1003
- obj[key] = finalValue;
1004
- }
1005
- }
1006
- function parsePair(tokens, state, obj) {
1007
- let token = skipPunctuation(tokens, state, [":", "string", "number", "atom"]);
1008
- let value;
1009
- if (token.type !== "string") {
1010
- raiseUnexpected(state, token, "string key");
1011
- if (state.tolerant) {
1012
- switch (token.type) {
1013
- case ":":
1014
- token = {
1015
- type: "string",
1016
- value: "null",
1017
- match: '"null"',
1018
- line: token.line
1019
- };
1020
- state.pos -= 1;
1021
- break;
1022
- case "number":
1023
- // Use number as string key
1024
- case "atom":
1025
- token = {
1026
- type: "string",
1027
- value: String(token.value),
1028
- match: `"${token.value}"`,
1029
- line: token.line
1030
- };
1031
- break;
1032
- case "[":
1033
- // Assume missing key before an array
1034
- case "{":
1035
- state.pos -= 1;
1036
- value = parseAny(tokens, state);
1037
- checkDuplicates(state, obj, {
1038
- type: "string",
1039
- value: "null",
1040
- match: '"null"',
1041
- line: token.line
1042
- });
1043
- appendPair(state, obj, "null", value);
1044
- return;
1045
- // Finished parsing this "pair"
1046
- case "eof":
1047
- return;
1048
- // Cannot recover
1049
- default:
1050
- return;
1051
- }
1052
- } else {
1053
- return;
1054
- }
1055
- }
1056
- checkDuplicates(state, obj, token);
1057
- const key = String(token.value);
1058
- skipColon(tokens, state);
1059
- value = parseAny(tokens, state);
1060
- appendPair(state, obj, key, value);
1061
- }
1062
- function parseElement(tokens, state, arr) {
1063
- const key = arr.length;
1064
- const value = parseAny(tokens, state);
1065
- arr[key] = state.reviver ? state.reviver(String(key), value) : value;
1066
- }
1067
- function parseObject(tokens, state) {
1068
- const obj = {};
1069
- return parseMany(tokens, state, obj, {
1070
- skip: [":", "}"],
1071
- // Initially skip over colon or closing brace (for empty/tolerant cases)
1072
- elementParser: parsePair,
1073
- // Use parsePair to parse each key-value element
1074
- elementName: "string key",
1075
- // Expected element type for errors
1076
- endSymbol: "}"
1077
- // The closing token for an object
1078
- });
1079
- }
1080
- function parseArray(tokens, state) {
1081
- const arr = [];
1082
- return parseMany(tokens, state, arr, {
1083
- skip: ["]"],
1084
- // Initially skip over closing bracket (for empty/tolerant cases)
1085
- elementParser: parseElement,
1086
- // Use parseElement to parse each array item
1087
- elementName: "json value",
1088
- // Expected element type for errors
1089
- endSymbol: "]"
1090
- // The closing token for an array
1091
- });
1092
- }
1093
- function handleInvalidToken(token, state, opts, result) {
1094
- raiseUnexpected(state, token, `',' or '${opts.endSymbol}'`);
1095
- if (state.tolerant) {
1096
- if (token.type === "eof") {
1097
- return result;
1098
- }
1099
- state.pos -= 1;
1100
- return null;
1101
- }
1102
- return result;
1103
- }
1104
- function handleCommaToken(params) {
1105
- const { token, tokens, state, opts, result } = params;
1106
- const nextToken = tokens[state.pos];
1107
- if (state.tolerant && nextToken && nextToken.type === opts.endSymbol) {
1108
- raiseError(state, token, `Trailing comma before '${opts.endSymbol}'`);
1109
- popToken(tokens, state);
1110
- return result;
1111
- }
1112
- opts.elementParser(tokens, state, result);
1113
- return null;
1114
- }
1115
- function parseManyInitialElement(tokens, state, result, opts) {
1116
- const token = skipPunctuation(tokens, state, opts.skip);
1117
- if (token.type === "eof") {
1118
- raiseUnexpected(state, token, `'${opts.endSymbol}' or ${opts.elementName}`);
1119
- return result;
1120
- }
1121
- if (token.type === opts.endSymbol) {
1122
- return result;
1123
- }
1124
- state.pos -= 1;
1125
- opts.elementParser(tokens, state, result);
1126
- return;
1127
- }
1128
- function parseManyProcessToken(params) {
1129
- const { token, tokens, state, opts, result } = params;
1130
- if (token.type !== opts.endSymbol && token.type !== ",") {
1131
- const handledResult = handleInvalidToken(token, state, opts, result);
1132
- if (handledResult !== null) {
1133
- return handledResult;
1134
- }
1135
- }
1136
- if (token.type === opts.endSymbol) {
1137
- return result;
1138
- }
1139
- if (token.type === ",") {
1140
- const handledResult = handleCommaToken({
1141
- token,
1142
- tokens,
1143
- state,
1144
- opts,
1145
- result
1146
- });
1147
- if (handledResult !== null) {
1148
- return handledResult;
1149
- }
1150
- return;
1151
- }
1152
- opts.elementParser(tokens, state, result);
1153
- return;
1154
- }
1155
- function parseMany(tokens, state, result, opts) {
1156
- const initialResult = parseManyInitialElement(tokens, state, result, opts);
1157
- if (initialResult !== void 0) {
1158
- return initialResult;
1159
- }
1160
- while (true) {
1161
- const token = popToken(tokens, state);
1162
- const processedResult = parseManyProcessToken({
1163
- token,
1164
- tokens,
1165
- state,
1166
- opts,
1167
- result
1168
- });
1169
- if (processedResult !== void 0) {
1170
- return processedResult;
1171
- }
1172
- }
1173
- }
1174
- function endChecks(tokens, state, ret) {
1175
- if (state.pos < tokens.length) {
1176
- if (state.tolerant) {
1177
- skipPunctuation(tokens, state);
1178
- }
1179
- if (state.pos < tokens.length) {
1180
- raiseError(
1181
- state,
1182
- tokens[state.pos],
1183
- `Unexpected token: ${strToken(tokens[state.pos])}, expected end-of-input`
1184
- );
1185
- }
1186
- }
1187
- if (state.tolerant && state.warnings.length > 0) {
1188
- const message = state.warnings.length === 1 ? state.warnings[0].message : `${state.warnings.length} parse warnings`;
1189
- const err = new SyntaxError(message);
1190
- err.line = state.warnings[0].line;
1191
- err.warnings = state.warnings;
1192
- err.obj = ret;
1193
- throw err;
1194
- }
1195
- }
1196
- function parseAny(tokens, state, end = false) {
1197
- const token = skipPunctuation(tokens, state);
1198
- let ret;
1199
- if (token.type === "eof") {
1200
- if (end) {
1201
- raiseUnexpected(state, token, "json value");
1202
- }
1203
- raiseUnexpected(state, token, "json value");
1204
- return;
1205
- }
1206
- switch (token.type) {
1207
- case "{":
1208
- ret = parseObject(tokens, state);
1209
- break;
1210
- case "[":
1211
- ret = parseArray(tokens, state);
1212
- break;
1213
- case "string":
1214
- // String literal
1215
- case "number":
1216
- // Number literal
1217
- case "atom":
1218
- ret = token.value;
1219
- break;
1220
- default:
1221
- raiseUnexpected(state, token, "json value");
1222
- if (state.tolerant) {
1223
- ret = null;
1224
- } else {
1225
- return;
1226
- }
1227
- }
1228
- if (end) {
1229
- ret = state.reviver ? state.reviver("", ret) : ret;
1230
- endChecks(tokens, state, ret);
1231
- }
1232
- return ret;
1233
- }
1234
- function normalizeParseOptions(optsOrReviver) {
1235
- var _a;
1236
- let options = {};
1237
- if (typeof optsOrReviver === "function") {
1238
- options.reviver = optsOrReviver;
1239
- } else if (optsOrReviver !== null && typeof optsOrReviver === "object") {
1240
- options = { ...optsOrReviver };
1241
- } else if (optsOrReviver !== void 0) {
1242
- throw new TypeError(
1243
- "Second argument must be a reviver function or an options object."
1244
- );
1245
- }
1246
- if (options.relaxed === void 0) {
1247
- if (options.warnings === true || options.tolerant === true) {
1248
- options.relaxed = true;
1249
- } else if (options.warnings === false && options.tolerant === false) {
1250
- options.relaxed = false;
1251
- } else {
1252
- options.relaxed = true;
1253
- }
1254
- }
1255
- options.tolerant = options.tolerant || options.warnings;
1256
- options.duplicate = (_a = options.duplicate) != null ? _a : false;
1257
- return options;
1258
- }
1259
- function createParseState(options) {
1260
- var _a, _b;
1261
- return {
1262
- pos: 0,
1263
- reviver: options.reviver,
1264
- tolerant: (_a = options.tolerant) != null ? _a : false,
1265
- duplicate: (_b = options.duplicate) != null ? _b : false,
1266
- warnings: []
1267
- };
1268
- }
1269
- function parseWithCustomParser(text, options) {
1270
- const lexerToUse = options.relaxed ? lexer : strictLexer;
1271
- let tokens = lexerToUse(text);
1272
- if (options.relaxed) {
1273
- tokens = stripTrailingComma(tokens);
1274
- }
1275
- tokens = tokens.filter((token) => token.type !== " ");
1276
- const state = createParseState(options);
1277
- return parseAny(tokens, state, true);
1278
- }
1279
- function parseWithTransform(text, options) {
1280
- let tokens = lexer(text);
1281
- tokens = stripTrailingComma(tokens);
1282
- const newtext = tokens.reduce((str, token) => str + token.match, "");
1283
- return JSON.parse(
1284
- newtext,
1285
- options.reviver
1286
- );
1287
- }
1288
- function parse2(text, optsOrReviver) {
1289
- const options = normalizeParseOptions(optsOrReviver);
1290
- if (!(options.relaxed || options.warnings || options.tolerant) && options.duplicate) {
1291
- return JSON.parse(
1292
- text,
1293
- options.reviver
1294
- );
1295
- }
1296
- if (options.warnings || options.tolerant || !options.duplicate) {
1297
- return parseWithCustomParser(text, options);
1298
- }
1299
- return parseWithTransform(text, options);
1300
- }
1301
-
1302
260
  // src/core/protocols/json-protocol.ts
1303
261
  function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
1304
262
  var _a, _b;
1305
263
  try {
1306
- const parsedToolCall = parse2(toolCallJson);
264
+ const parsedToolCall = (0, import_rjson.parse)(toolCallJson);
1307
265
  processedElements.push({
1308
266
  type: "tool-call",
1309
267
  toolCallId: generateId(),
@@ -1431,7 +389,7 @@ function emitToolCall(context) {
1431
389
  var _a, _b;
1432
390
  const { state, controller, toolCallStart, toolCallEnd, options } = context;
1433
391
  try {
1434
- const parsedToolCall = parse2(state.currentToolCallJson);
392
+ const parsedToolCall = (0, import_rjson.parse)(state.currentToolCallJson);
1435
393
  closeTextBlock(state, controller);
1436
394
  controller.enqueue({
1437
395
  type: "tool-call",
@@ -1542,8 +500,8 @@ var jsonProtocol = ({
1542
500
  text,
1543
501
  options
1544
502
  }) {
1545
- const startEsc = escapeRegExp2(toolCallStart);
1546
- const endEsc = escapeRegExp2(toolCallEnd);
503
+ const startEsc = escapeRegExp(toolCallStart);
504
+ const endEsc = escapeRegExp(toolCallEnd);
1547
505
  const toolCallRegex = new RegExp(
1548
506
  `${startEsc}([\0-\uFFFF]*?)${endEsc}`,
1549
507
  "gs"
@@ -1602,8 +560,8 @@ var jsonProtocol = ({
1602
560
  });
1603
561
  },
1604
562
  extractToolCallSegments({ text }) {
1605
- const startEsc = escapeRegExp2(toolCallStart);
1606
- const endEsc = escapeRegExp2(toolCallEnd);
563
+ const startEsc = escapeRegExp(toolCallStart);
564
+ const endEsc = escapeRegExp(toolCallEnd);
1607
565
  const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
1608
566
  const segments = [];
1609
567
  let m = regex.exec(text);
@@ -1616,98 +574,56 @@ var jsonProtocol = ({
1616
574
  });
1617
575
 
1618
576
  // src/core/protocols/protocol-interface.ts
577
+ function isProtocolFactory(protocol) {
578
+ return typeof protocol === "function";
579
+ }
1619
580
  function isTCMProtocolFactory(protocol) {
1620
581
  return typeof protocol === "function";
1621
582
  }
1622
583
 
1623
584
  // src/core/protocols/xml-protocol.ts
1624
- var import_rxml2 = require("@ai-sdk-tool/rxml");
1625
- var defaultPipelineConfig2 = defaultPipelineConfig;
1626
- var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
1627
- var WHITESPACE_REGEX3 = /\s/;
585
+ var import_rxml = require("@ai-sdk-tool/rxml");
586
+ var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
587
+ var WHITESPACE_REGEX = /\s/;
588
+ var REGEX_ESCAPE_RE = /[.*+?^${}()|[\]\\]/g;
589
+ function escapeRegExp2(value) {
590
+ return value.replace(REGEX_ESCAPE_RE, "\\$&");
591
+ }
1628
592
  function getToolSchema(tools, toolName) {
1629
593
  var _a;
1630
594
  return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1631
595
  }
1632
- function normalizeCloseTags(xml) {
1633
- return xml.replace(/<\/\s+([A-Za-z0-9_:-]+)\s*>/g, "</$1>");
1634
- }
1635
- function tryParseSecondaryXml(content, toolSchema, options) {
1636
- const balanced = balanceTags(content);
1637
- try {
1638
- let parsed = (0, import_rxml2.parse)(balanced, toolSchema, {
1639
- onError: options == null ? void 0 : options.onError,
1640
- noChildNodes: []
1641
- });
1642
- parsed = repairParsedAgainstSchema(parsed, toolSchema);
1643
- return parsed;
1644
- } catch (e) {
1645
- if (shouldDeduplicateStringTags(toolSchema)) {
1646
- const names = getStringPropertyNames(toolSchema);
1647
- let deduped = balanced;
1648
- for (const key of names) {
1649
- deduped = dedupeSingleTag(deduped, key);
1650
- }
1651
- if (deduped !== balanced) {
1652
- try {
1653
- let reparsed = (0, import_rxml2.parse)(deduped, toolSchema, {
1654
- onError: options == null ? void 0 : options.onError,
1655
- noChildNodes: []
1656
- });
1657
- reparsed = repairParsedAgainstSchema(reparsed, toolSchema);
1658
- return reparsed;
1659
- } catch (e2) {
1660
- return null;
1661
- }
1662
- }
1663
- }
1664
- return null;
1665
- }
1666
- }
1667
- function processToolCallWithPipeline(params) {
1668
- var _a;
1669
- const {
1670
- toolCall,
1671
- tools,
1672
- options,
1673
- text,
1674
- processedElements,
1675
- pipelineConfig = defaultPipelineConfig2,
1676
- maxReparses
1677
- } = params;
596
+ function processToolCall(params) {
597
+ var _a, _b;
598
+ const { toolCall, tools, options, text, processedElements, parseOptions } = params;
1678
599
  const toolSchema = getToolSchema(tools, toolCall.toolName);
1679
- const ctx = createIntermediateCall(
1680
- toolCall.toolName,
1681
- toolCall.content,
1682
- toolSchema
1683
- );
1684
- const result = applyHeuristicPipeline(ctx, pipelineConfig, {
1685
- parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
1686
- onError: options == null ? void 0 : options.onError,
1687
- maxReparses
1688
- });
1689
- if (result.parsed !== null) {
600
+ const parseConfig = {
601
+ ...parseOptions != null ? parseOptions : {},
602
+ onError: (_a = options == null ? void 0 : options.onError) != null ? _a : parseOptions == null ? void 0 : parseOptions.onError
603
+ };
604
+ try {
605
+ const parsed = (0, import_rxml.parse)(toolCall.content, toolSchema, parseConfig);
1690
606
  processedElements.push({
1691
607
  type: "tool-call",
1692
608
  toolCallId: generateId(),
1693
609
  toolName: toolCall.toolName,
1694
- input: JSON.stringify(result.parsed)
610
+ input: JSON.stringify(parsed)
1695
611
  });
1696
- } else {
612
+ } catch (error) {
1697
613
  const originalCallText = text.substring(
1698
614
  toolCall.startIndex,
1699
615
  toolCall.endIndex
1700
616
  );
1701
- (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
617
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
1702
618
  options,
1703
619
  `Could not process XML tool call: ${toolCall.toolName}`,
1704
- { toolCall: originalCallText, error: result.errors[0] }
620
+ { toolCall: originalCallText, error }
1705
621
  );
1706
622
  processedElements.push({ type: "text", text: originalCallText });
1707
623
  }
1708
624
  }
1709
625
  function handleStreamingToolCallEnd(params) {
1710
- var _a;
626
+ var _a, _b;
1711
627
  const {
1712
628
  toolContent,
1713
629
  currentToolCall,
@@ -1715,51 +631,27 @@ function handleStreamingToolCallEnd(params) {
1715
631
  options,
1716
632
  ctrl,
1717
633
  flushText,
1718
- pipelineConfig,
1719
- maxReparses
634
+ parseOptions
1720
635
  } = params;
1721
636
  const toolSchema = getToolSchema(tools, currentToolCall.name);
1722
- let parsedResult = null;
1723
- if (pipelineConfig) {
1724
- const ctx = createIntermediateCall(
1725
- currentToolCall.name,
1726
- toolContent,
1727
- toolSchema
1728
- );
1729
- const result = applyHeuristicPipeline(ctx, pipelineConfig, {
1730
- parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
1731
- onError: options == null ? void 0 : options.onError,
1732
- maxReparses
1733
- });
1734
- parsedResult = result.parsed;
1735
- } else {
1736
- try {
1737
- const primary = escapeInvalidLt(normalizeCloseTags(toolContent));
1738
- const parsed = (0, import_rxml2.parse)(primary, toolSchema, {
1739
- onError: options == null ? void 0 : options.onError,
1740
- noChildNodes: []
1741
- });
1742
- parsedResult = repairParsedAgainstSchema(parsed, toolSchema);
1743
- } catch (e) {
1744
- parsedResult = tryParseSecondaryXml(
1745
- toolContent,
1746
- toolSchema,
1747
- options != null ? options : {}
1748
- );
1749
- }
1750
- }
637
+ const parseConfig = {
638
+ ...parseOptions != null ? parseOptions : {},
639
+ onError: (_a = options == null ? void 0 : options.onError) != null ? _a : parseOptions == null ? void 0 : parseOptions.onError
640
+ };
1751
641
  flushText(ctrl);
1752
- if (parsedResult !== null) {
642
+ try {
643
+ const parsedResult = (0, import_rxml.parse)(toolContent, toolSchema, parseConfig);
1753
644
  ctrl.enqueue({
1754
645
  type: "tool-call",
1755
646
  toolCallId: generateId(),
1756
647
  toolName: currentToolCall.name,
1757
648
  input: JSON.stringify(parsedResult)
1758
649
  });
1759
- } else {
650
+ } catch (error) {
1760
651
  const original = `<${currentToolCall.name}>${toolContent}</${currentToolCall.name}>`;
1761
- (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not process streaming XML tool call", {
1762
- toolCall: original
652
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, "Could not process streaming XML tool call", {
653
+ toolCall: original,
654
+ error
1763
655
  });
1764
656
  flushText(ctrl, original);
1765
657
  }
@@ -1798,11 +690,11 @@ function consumeClosingTag(text, lt) {
1798
690
  }
1799
691
  function consumeOpenTag(text, lt) {
1800
692
  let p = lt + 1;
1801
- while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
693
+ while (p < text.length && WHITESPACE_REGEX.test(text[p])) {
1802
694
  p += 1;
1803
695
  }
1804
696
  const nameStart = p;
1805
- while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
697
+ while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
1806
698
  p += 1;
1807
699
  }
1808
700
  const name = text.slice(nameStart, p);
@@ -1811,7 +703,7 @@ function consumeOpenTag(text, lt) {
1811
703
  return null;
1812
704
  }
1813
705
  let r = q - 1;
1814
- while (r >= nameStart && WHITESPACE_REGEX3.test(text[r])) {
706
+ while (r >= nameStart && WHITESPACE_REGEX.test(text[r])) {
1815
707
  r -= 1;
1816
708
  }
1817
709
  const selfClosing = text[r] === "/";
@@ -1840,11 +732,11 @@ function nextTagToken(text, fromPos) {
1840
732
  if (next === "/") {
1841
733
  const closing = consumeClosingTag(text, lt);
1842
734
  let p = lt + 2;
1843
- while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
735
+ while (p < text.length && WHITESPACE_REGEX.test(text[p])) {
1844
736
  p += 1;
1845
737
  }
1846
738
  const nameStart = p;
1847
- while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
739
+ while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
1848
740
  p += 1;
1849
741
  }
1850
742
  const name = text.slice(nameStart, p);
@@ -1861,49 +753,90 @@ function nextTagToken(text, fromPos) {
1861
753
  nextPos: open.nextPos
1862
754
  };
1863
755
  }
756
+ function findNextToolTag(text, searchIndex, startTag, selfTag) {
757
+ const openIdx = text.indexOf(startTag, searchIndex);
758
+ const selfIdx = text.indexOf(selfTag, searchIndex);
759
+ if (openIdx === -1 && selfIdx === -1) {
760
+ return null;
761
+ }
762
+ const isSelfClosing = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx);
763
+ return {
764
+ tagStart: isSelfClosing ? selfIdx : openIdx,
765
+ isSelfClosing
766
+ };
767
+ }
768
+ function findLastCloseTagStart(segment, toolName) {
769
+ const closeTagPattern = new RegExp(
770
+ `</\\s*${escapeRegExp2(toolName)}\\s*>`,
771
+ "g"
772
+ );
773
+ let closeTagStart = -1;
774
+ let match = closeTagPattern.exec(segment);
775
+ while (match !== null) {
776
+ closeTagStart = match.index;
777
+ match = closeTagPattern.exec(segment);
778
+ }
779
+ if (closeTagStart === -1) {
780
+ return segment.lastIndexOf("<");
781
+ }
782
+ return closeTagStart;
783
+ }
784
+ function pushSelfClosingToolCall(toolCalls, toolName, text, tagStart, selfTag) {
785
+ const endIndex = tagStart + selfTag.length;
786
+ toolCalls.push({
787
+ toolName,
788
+ startIndex: tagStart,
789
+ endIndex,
790
+ content: "",
791
+ segment: text.substring(tagStart, endIndex)
792
+ });
793
+ return endIndex;
794
+ }
795
+ function appendOpenToolCallIfComplete(toolCalls, text, toolName, tagStart, startTag) {
796
+ const contentStart = tagStart + startTag.length;
797
+ const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
798
+ if (fullTagEnd === -1 || fullTagEnd <= contentStart) {
799
+ return contentStart;
800
+ }
801
+ const segment = text.substring(tagStart, fullTagEnd);
802
+ const closeTagStart = findLastCloseTagStart(segment, toolName);
803
+ const inner = closeTagStart === -1 ? segment.slice(startTag.length) : segment.slice(startTag.length, closeTagStart);
804
+ toolCalls.push({
805
+ toolName,
806
+ startIndex: tagStart,
807
+ endIndex: fullTagEnd,
808
+ content: inner,
809
+ segment
810
+ });
811
+ return fullTagEnd;
812
+ }
1864
813
  function findToolCallsForName(text, toolName) {
1865
- var _a;
1866
814
  const toolCalls = [];
815
+ const startTag = `<${toolName}>`;
816
+ const selfTag = `<${toolName}/>`;
1867
817
  let searchIndex = 0;
1868
818
  while (searchIndex < text.length) {
1869
- const startTag = `<${toolName}>`;
1870
- const selfTag = `<${toolName}/>`;
1871
- const openIdx = text.indexOf(startTag, searchIndex);
1872
- const selfIdx = text.indexOf(selfTag, searchIndex);
1873
- if (openIdx === -1 && selfIdx === -1) {
819
+ const match = findNextToolTag(text, searchIndex, startTag, selfTag);
820
+ if (match === null) {
1874
821
  break;
1875
822
  }
1876
- const tagStart = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx) ? selfIdx : openIdx;
1877
- const isSelfClosing = tagStart === selfIdx;
1878
- if (isSelfClosing) {
1879
- const endIndex = tagStart + selfTag.length;
1880
- const segment = text.substring(tagStart, endIndex);
1881
- toolCalls.push({
823
+ if (match.isSelfClosing) {
824
+ searchIndex = pushSelfClosingToolCall(
825
+ toolCalls,
1882
826
  toolName,
1883
- startIndex: tagStart,
1884
- endIndex,
1885
- content: "",
1886
- segment
1887
- });
1888
- searchIndex = endIndex;
827
+ text,
828
+ match.tagStart,
829
+ selfTag
830
+ );
1889
831
  continue;
1890
832
  }
1891
- const contentStart = tagStart + startTag.length;
1892
- const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
1893
- if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
1894
- const segment = text.substring(tagStart, fullTagEnd);
1895
- const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
1896
- toolCalls.push({
1897
- toolName,
1898
- startIndex: tagStart,
1899
- endIndex: fullTagEnd,
1900
- content: inner,
1901
- segment
1902
- });
1903
- searchIndex = fullTagEnd;
1904
- } else {
1905
- searchIndex = contentStart;
1906
- }
833
+ searchIndex = appendOpenToolCallIfComplete(
834
+ toolCalls,
835
+ text,
836
+ toolName,
837
+ match.tagStart,
838
+ startTag
839
+ );
1907
840
  }
1908
841
  return toolCalls;
1909
842
  }
@@ -1980,16 +913,20 @@ function processToolCallInBuffer(params) {
1980
913
  controller,
1981
914
  flushText,
1982
915
  setBuffer,
1983
- pipelineConfig,
1984
- maxReparses
916
+ parseOptions
1985
917
  } = params;
1986
- const endTag = `</${currentToolCall.name}>`;
1987
- const endIdx = buffer.indexOf(endTag);
1988
- if (endIdx === -1) {
918
+ const endTagPattern = new RegExp(
919
+ `</\\s*${escapeRegExp2(currentToolCall.name)}\\s*>`
920
+ );
921
+ const endMatch = endTagPattern.exec(buffer);
922
+ if (!endMatch || endMatch.index === void 0) {
1989
923
  return { buffer, currentToolCall, shouldBreak: true };
1990
924
  }
925
+ const endIdx = endMatch.index;
926
+ const endPos = endIdx + endMatch[0].length;
1991
927
  const content = buffer.substring(0, endIdx);
1992
- setBuffer(buffer.substring(endIdx + endTag.length));
928
+ const remainder = buffer.substring(endPos);
929
+ setBuffer(remainder);
1993
930
  handleStreamingToolCallEnd({
1994
931
  toolContent: content,
1995
932
  currentToolCall,
@@ -1997,11 +934,10 @@ function processToolCallInBuffer(params) {
1997
934
  options,
1998
935
  ctrl: controller,
1999
936
  flushText,
2000
- pipelineConfig,
2001
- maxReparses
937
+ parseOptions
2002
938
  });
2003
939
  return {
2004
- buffer: buffer.substring(endIdx + endTag.length),
940
+ buffer: remainder,
2005
941
  currentToolCall: null,
2006
942
  shouldBreak: false
2007
943
  };
@@ -2014,8 +950,7 @@ function processNoToolCallInBuffer(params) {
2014
950
  flushText,
2015
951
  tools,
2016
952
  options,
2017
- pipelineConfig,
2018
- maxReparses,
953
+ parseOptions,
2019
954
  setBuffer
2020
955
  } = params;
2021
956
  const {
@@ -2050,8 +985,7 @@ function processNoToolCallInBuffer(params) {
2050
985
  options,
2051
986
  ctrl: controller,
2052
987
  flushText,
2053
- pipelineConfig,
2054
- maxReparses
988
+ parseOptions
2055
989
  });
2056
990
  return {
2057
991
  buffer: newBuffer2,
@@ -2070,7 +1004,7 @@ function processNoToolCallInBuffer(params) {
2070
1004
  shouldContinue: true
2071
1005
  };
2072
1006
  }
2073
- function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, setCurrentToolCall, tools, options, toolNames, flushText, pipelineConfig, maxReparses) {
1007
+ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, setCurrentToolCall, tools, options, toolNames, flushText, parseOptions) {
2074
1008
  return (controller) => {
2075
1009
  while (true) {
2076
1010
  const currentToolCall = getCurrentToolCall();
@@ -2083,8 +1017,7 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
2083
1017
  controller,
2084
1018
  flushText,
2085
1019
  setBuffer,
2086
- pipelineConfig,
2087
- maxReparses
1020
+ parseOptions
2088
1021
  });
2089
1022
  setBuffer(result.buffer);
2090
1023
  setCurrentToolCall(result.currentToolCall);
@@ -2099,8 +1032,7 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
2099
1032
  flushText,
2100
1033
  tools,
2101
1034
  options,
2102
- pipelineConfig,
2103
- maxReparses,
1035
+ parseOptions,
2104
1036
  setBuffer
2105
1037
  });
2106
1038
  setBuffer(result.buffer);
@@ -2117,43 +1049,12 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
2117
1049
  };
2118
1050
  }
2119
1051
  var xmlProtocol = (protocolOptions) => {
2120
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2121
- let pipelineConfig = protocolOptions == null ? void 0 : protocolOptions.pipeline;
2122
- const maxReparses = protocolOptions == null ? void 0 : protocolOptions.maxReparses;
2123
- if ((protocolOptions == null ? void 0 : protocolOptions.heuristics) && protocolOptions.heuristics.length > 0) {
2124
- const heuristicsConfig = {
2125
- preParse: [],
2126
- fallbackReparse: [],
2127
- postParse: []
2128
- };
2129
- for (const h of protocolOptions.heuristics) {
2130
- if (h.phase === "pre-parse") {
2131
- (_a = heuristicsConfig.preParse) == null ? void 0 : _a.push(h);
2132
- } else if (h.phase === "fallback-reparse") {
2133
- (_b = heuristicsConfig.fallbackReparse) == null ? void 0 : _b.push(h);
2134
- } else if (h.phase === "post-parse") {
2135
- (_c = heuristicsConfig.postParse) == null ? void 0 : _c.push(h);
2136
- }
2137
- }
2138
- if (pipelineConfig) {
2139
- pipelineConfig = {
2140
- preParse: [
2141
- ...(_d = pipelineConfig.preParse) != null ? _d : [],
2142
- ...(_e = heuristicsConfig.preParse) != null ? _e : []
2143
- ],
2144
- fallbackReparse: [
2145
- ...(_f = pipelineConfig.fallbackReparse) != null ? _f : [],
2146
- ...(_g = heuristicsConfig.fallbackReparse) != null ? _g : []
2147
- ],
2148
- postParse: [
2149
- ...(_h = pipelineConfig.postParse) != null ? _h : [],
2150
- ...(_i = heuristicsConfig.postParse) != null ? _i : []
2151
- ]
2152
- };
2153
- } else {
2154
- pipelineConfig = heuristicsConfig;
2155
- }
2156
- }
1052
+ var _a;
1053
+ const parseOptions = {
1054
+ repair: true,
1055
+ noChildNodes: [],
1056
+ ...(_a = protocolOptions == null ? void 0 : protocolOptions.parseOptions) != null ? _a : {}
1057
+ };
2157
1058
  return {
2158
1059
  formatTools({ tools, toolSystemPromptTemplate }) {
2159
1060
  return toolSystemPromptTemplate(tools || []);
@@ -2167,7 +1068,7 @@ var xmlProtocol = (protocolOptions) => {
2167
1068
  args = toolCall.input;
2168
1069
  }
2169
1070
  }
2170
- return (0, import_rxml2.stringify)(toolCall.toolName, args, {
1071
+ return (0, import_rxml.stringify)(toolCall.toolName, args, {
2171
1072
  suppressEmptyNode: false,
2172
1073
  format: true,
2173
1074
  minimalEscaping: true
@@ -2188,14 +1089,13 @@ var xmlProtocol = (protocolOptions) => {
2188
1089
  text: text.substring(currentIndex, tc.startIndex)
2189
1090
  });
2190
1091
  }
2191
- processToolCallWithPipeline({
1092
+ processToolCall({
2192
1093
  toolCall: tc,
2193
1094
  tools,
2194
1095
  options,
2195
1096
  text,
2196
1097
  processedElements,
2197
- pipelineConfig,
2198
- maxReparses
1098
+ parseOptions
2199
1099
  });
2200
1100
  currentIndex = tc.endIndex;
2201
1101
  }
@@ -2236,8 +1136,7 @@ var xmlProtocol = (protocolOptions) => {
2236
1136
  options,
2237
1137
  toolNames,
2238
1138
  flushText,
2239
- pipelineConfig,
2240
- maxReparses
1139
+ parseOptions
2241
1140
  );
2242
1141
  return new TransformStream({
2243
1142
  transform(chunk, controller) {
@@ -2287,8 +1186,8 @@ var xmlProtocol = (protocolOptions) => {
2287
1186
 
2288
1187
  // src/core/protocols/yaml-protocol.ts
2289
1188
  var import_yaml = __toESM(require("yaml"), 1);
2290
- var NAME_CHAR_RE3 = /[A-Za-z0-9_:-]/;
2291
- var WHITESPACE_REGEX4 = /\s/;
1189
+ var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
1190
+ var WHITESPACE_REGEX2 = /\s/;
2292
1191
  var LEADING_WHITESPACE_RE = /^(\s*)/;
2293
1192
  function findClosingTagEnd(text, contentStart, toolName) {
2294
1193
  let pos = contentStart;
@@ -2305,11 +1204,11 @@ function findClosingTagEnd(text, contentStart, toolName) {
2305
1204
  break;
2306
1205
  }
2307
1206
  let p = ltIdx + 2;
2308
- while (p < gtIdx && WHITESPACE_REGEX4.test(text[p])) {
1207
+ while (p < gtIdx && WHITESPACE_REGEX2.test(text[p])) {
2309
1208
  p++;
2310
1209
  }
2311
1210
  const nameStart = p;
2312
- while (p < gtIdx && NAME_CHAR_RE3.test(text.charAt(p))) {
1211
+ while (p < gtIdx && NAME_CHAR_RE2.test(text.charAt(p))) {
2313
1212
  p++;
2314
1213
  }
2315
1214
  const name = text.slice(nameStart, p);
@@ -2325,11 +1224,11 @@ function findClosingTagEnd(text, contentStart, toolName) {
2325
1224
  pos = gtIdx === -1 ? text.length : gtIdx + 1;
2326
1225
  } else {
2327
1226
  let p = ltIdx + 1;
2328
- while (p < text.length && WHITESPACE_REGEX4.test(text[p])) {
1227
+ while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
2329
1228
  p++;
2330
1229
  }
2331
1230
  const nameStart = p;
2332
- while (p < text.length && NAME_CHAR_RE3.test(text.charAt(p))) {
1231
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
2333
1232
  p++;
2334
1233
  }
2335
1234
  const name = text.slice(nameStart, p);
@@ -2338,7 +1237,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
2338
1237
  break;
2339
1238
  }
2340
1239
  let r = gtIdx - 1;
2341
- while (r >= nameStart && WHITESPACE_REGEX4.test(text[r])) {
1240
+ while (r >= nameStart && WHITESPACE_REGEX2.test(text[r])) {
2342
1241
  r--;
2343
1242
  }
2344
1243
  const selfClosing = text[r] === "/";
@@ -2820,15 +1719,30 @@ function decodeOriginalTools(originalTools) {
2820
1719
  })
2821
1720
  );
2822
1721
  }
1722
+ function extractToolNamesFromOriginalTools(originalTools) {
1723
+ return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
1724
+ }
2823
1725
  function isToolChoiceActive(params) {
2824
1726
  var _a, _b, _c;
2825
1727
  const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
2826
1728
  return !!(typeof params.providerOptions === "object" && params.providerOptions !== null && typeof ((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) === "object" && toolChoice && typeof toolChoice === "object" && (toolChoice.type === "tool" || toolChoice.type === "required"));
2827
1729
  }
2828
1730
 
1731
+ // src/core/utils/type-guards.ts
1732
+ function isToolResultPart(content) {
1733
+ if (!content || typeof content !== "object") {
1734
+ return false;
1735
+ }
1736
+ const c = content;
1737
+ return c.type === "tool-result" && typeof c.toolName === "string" && typeof c.toolCallId === "string" && "output" in c;
1738
+ }
1739
+ function hasInputProperty(obj) {
1740
+ return typeof obj === "object" && obj !== null && "input" in obj;
1741
+ }
1742
+
2829
1743
  // src/generate-handler.ts
2830
1744
  var import_provider_utils = require("@ai-sdk/provider-utils");
2831
- var import_rxml3 = require("@ai-sdk-tool/rxml");
1745
+ var import_schema_coerce = require("@ai-sdk-tool/schema-coerce");
2832
1746
  function parseToolChoiceJson(text, providerOptions) {
2833
1747
  var _a;
2834
1748
  try {
@@ -2990,7 +1904,7 @@ function fixToolCallWithSchema(part, tools) {
2990
1904
  args = part.input;
2991
1905
  }
2992
1906
  const schema = (_a = tools.find((t) => t.name === part.toolName)) == null ? void 0 : _a.inputSchema;
2993
- const coerced = (0, import_rxml3.coerceBySchema)(args, schema);
1907
+ const coerced = (0, import_schema_coerce.coerceBySchema)(args, schema);
2994
1908
  return {
2995
1909
  ...part,
2996
1910
  input: JSON.stringify(coerced != null ? coerced : {})
@@ -3654,20 +2568,12 @@ function createToolMiddleware({
3654
2568
  const resolvedProtocol = isTCMProtocolFactory(protocol) ? protocol() : protocol;
3655
2569
  return {
3656
2570
  specificationVersion: "v3",
3657
- wrapStream: ({ doStream, doGenerate, params }) => {
3658
- if (isToolChoiceActive(params)) {
3659
- return toolChoiceStream({
3660
- doGenerate,
3661
- options: extractOnErrorOption(params.providerOptions)
3662
- });
3663
- }
3664
- return wrapStream({
3665
- protocol: resolvedProtocol,
3666
- doStream,
3667
- doGenerate,
3668
- params
3669
- });
3670
- },
2571
+ wrapStream: ({ doStream, doGenerate, params }) => wrapStream({
2572
+ protocol: resolvedProtocol,
2573
+ doStream,
2574
+ doGenerate,
2575
+ params
2576
+ }),
3671
2577
  wrapGenerate: async ({ doGenerate, params }) => wrapGenerate({
3672
2578
  protocol: resolvedProtocol,
3673
2579
  doGenerate,