@ai-sdk-tool/parser 3.0.0-canary.3 → 3.0.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.
package/dist/v5.cjs ADDED
@@ -0,0 +1,2816 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/v5/index.ts
21
+ var v5_exports = {};
22
+ __export(v5_exports, {
23
+ createToolMiddleware: () => createToolMiddlewareV5,
24
+ gemmaToolMiddleware: () => gemmaToolMiddleware,
25
+ hermesToolMiddleware: () => hermesToolMiddleware,
26
+ morphXmlToolMiddleware: () => morphXmlToolMiddleware
27
+ });
28
+ module.exports = __toCommonJS(v5_exports);
29
+
30
+ // src/core/utils/debug.ts
31
+ function normalizeBooleanString(value) {
32
+ const normalized = value.trim().toLowerCase();
33
+ if (normalized === "1" || normalized === "true" || normalized === "yes") {
34
+ return true;
35
+ }
36
+ if (normalized === "0" || normalized === "false" || normalized === "no") {
37
+ return false;
38
+ }
39
+ return;
40
+ }
41
+ function getDebugLevel() {
42
+ const envVal = typeof process !== "undefined" && process.env && process.env.DEBUG_PARSER_MW || "off";
43
+ const envLower = String(envVal).toLowerCase();
44
+ if (envLower === "stream" || envLower === "parse" || envLower === "off") {
45
+ return envLower;
46
+ }
47
+ const boolEnv = normalizeBooleanString(envLower);
48
+ if (boolEnv === true) {
49
+ return "stream";
50
+ }
51
+ if (envLower === "2") {
52
+ return "parse";
53
+ }
54
+ return "off";
55
+ }
56
+ function color(code) {
57
+ return (text) => `\x1B[${code}m${text}\x1B[0m`;
58
+ }
59
+ var ANSI_GRAY = 90;
60
+ var ANSI_YELLOW = 33;
61
+ var ANSI_CYAN = 36;
62
+ var ANSI_BG_BLUE = 44;
63
+ var ANSI_BG_GREEN = 42;
64
+ var ANSI_INVERSE = 7;
65
+ var ANSI_UNDERLINE = 4;
66
+ var ANSI_BOLD = 1;
67
+ var cGray = color(ANSI_GRAY);
68
+ var cYellow = color(ANSI_YELLOW);
69
+ var cCyan = color(ANSI_CYAN);
70
+ var cBgBlue = color(ANSI_BG_BLUE);
71
+ var cBgGreen = color(ANSI_BG_GREEN);
72
+ var cInverse = color(ANSI_INVERSE);
73
+ var cUnderline = color(ANSI_UNDERLINE);
74
+ var cBold = color(ANSI_BOLD);
75
+ var MAX_SNIPPET_LENGTH = 800;
76
+ function safeStringify(value) {
77
+ try {
78
+ return `
79
+ ${typeof value === "string" ? value : JSON.stringify(value, null, 2)}`;
80
+ } catch (e) {
81
+ return String(value);
82
+ }
83
+ }
84
+ function formatError(error) {
85
+ if (error instanceof Error) {
86
+ const stack = error.stack ? `
87
+ ${error.stack}` : "";
88
+ return `
89
+ ${error.name}: ${error.message}${stack}`;
90
+ }
91
+ return safeStringify(error);
92
+ }
93
+ function truncateSnippet(snippet) {
94
+ if (snippet.length <= MAX_SNIPPET_LENGTH) {
95
+ return snippet;
96
+ }
97
+ return `${snippet.slice(0, MAX_SNIPPET_LENGTH)}
98
+ \u2026[truncated ${snippet.length - MAX_SNIPPET_LENGTH} chars]`;
99
+ }
100
+ function logParseFailure({
101
+ phase,
102
+ reason,
103
+ snippet,
104
+ error
105
+ }) {
106
+ if (getDebugLevel() !== "parse") {
107
+ return;
108
+ }
109
+ const label = cBgBlue(`[${phase}]`);
110
+ console.log(cGray("[debug:mw:fail]"), label, cYellow(reason));
111
+ if (snippet) {
112
+ const formatted = truncateSnippet(snippet);
113
+ console.log(cGray("[debug:mw:fail:snippet]"), formatted);
114
+ }
115
+ if (error) {
116
+ console.log(cGray("[debug:mw:fail:error]"), cCyan(formatError(error)));
117
+ }
118
+ }
119
+
120
+ // src/core/utils/get-potential-start-index.ts
121
+ function getPotentialStartIndex(text, searchedText) {
122
+ if (searchedText.length === 0) {
123
+ return null;
124
+ }
125
+ const directIndex = text.indexOf(searchedText);
126
+ if (directIndex !== -1) {
127
+ return directIndex;
128
+ }
129
+ for (let i = text.length - 1; i >= 0; i -= 1) {
130
+ const suffix = text.substring(i);
131
+ if (searchedText.startsWith(suffix)) {
132
+ return i;
133
+ }
134
+ }
135
+ return null;
136
+ }
137
+
138
+ // src/core/utils/id.ts
139
+ function generateId() {
140
+ return Math.random().toString(36).substring(2, 15);
141
+ }
142
+
143
+ // src/core/utils/regex.ts
144
+ function escapeRegExp(literal) {
145
+ return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
146
+ }
147
+
148
+ // src/core/utils/robust-json.ts
149
+ var WHITESPACE_TEST_REGEX = /\s/;
150
+ var WHITESPACE_REGEX = /^\s+/;
151
+ var OBJECT_START_REGEX = /^\{/;
152
+ var OBJECT_END_REGEX = /^\}/;
153
+ var ARRAY_START_REGEX = /^\[/;
154
+ var ARRAY_END_REGEX = /^\]/;
155
+ var COMMA_REGEX = /^,/;
156
+ var COLON_REGEX = /^:/;
157
+ var KEYWORD_REGEX = /^(?:true|false|null)/;
158
+ var NUMBER_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/;
159
+ var STRING_DOUBLE_REGEX = /^"(?:[^"\\]|\\["bnrtf\\/]|\\u[0-9a-fA-F]{4})*"/;
160
+ var STRING_SINGLE_REGEX = /^'((?:[^'\\]|\\['bnrtf\\/]|\\u[0-9a-fA-F]{4})*)'/;
161
+ var COMMENT_SINGLE_REGEX = /^\/\/.*?(?:\r\n|\r|\n)/;
162
+ var COMMENT_MULTI_REGEX = /^\/\*[\s\S]*?\*\//;
163
+ var IDENTIFIER_REGEX = /^[$a-zA-Z0-9_\-+.*?!|&%^/#\\]+/;
164
+ function some(array, f) {
165
+ let acc = false;
166
+ for (let i = 0; i < array.length; i += 1) {
167
+ const result = f(array[i], i, array);
168
+ acc = result === void 0 ? false : result;
169
+ if (acc) {
170
+ return acc;
171
+ }
172
+ }
173
+ return acc;
174
+ }
175
+ function makeLexer(tokenSpecs) {
176
+ return (contents) => {
177
+ const tokens = [];
178
+ let line = 1;
179
+ let remainingContents = contents;
180
+ function findToken() {
181
+ const result = some(tokenSpecs, (tokenSpec) => {
182
+ const m = tokenSpec.re.exec(remainingContents);
183
+ if (m) {
184
+ const raw = m[0];
185
+ remainingContents = remainingContents.slice(raw.length);
186
+ return {
187
+ raw,
188
+ matched: tokenSpec.f(m)
189
+ // Process the match using the spec's function
190
+ };
191
+ }
192
+ return;
193
+ });
194
+ return result === false ? void 0 : result;
195
+ }
196
+ while (remainingContents !== "") {
197
+ const matched = findToken();
198
+ if (!matched) {
199
+ const err = new SyntaxError(
200
+ `Unexpected character: ${remainingContents[0]}; input: ${remainingContents.substr(
201
+ 0,
202
+ 100
203
+ )}`
204
+ );
205
+ err.line = line;
206
+ throw err;
207
+ }
208
+ const tokenWithLine = matched.matched;
209
+ tokenWithLine.line = line;
210
+ line += matched.raw.replace(/[^\n]/g, "").length;
211
+ tokens.push(tokenWithLine);
212
+ }
213
+ return tokens;
214
+ };
215
+ }
216
+ function fStringSingle(m) {
217
+ const content = m[1].replace(
218
+ /([^'\\]|\\['bnrtf\\]|\\u[0-9a-fA-F]{4})/g,
219
+ (mm) => {
220
+ if (mm === '"') {
221
+ return '\\"';
222
+ }
223
+ if (mm === "\\'") {
224
+ return "'";
225
+ }
226
+ return mm;
227
+ }
228
+ );
229
+ const match = `"${content}"`;
230
+ return {
231
+ type: "string",
232
+ match,
233
+ // The transformed, double-quoted string representation
234
+ // Use JSON.parse on the transformed string to handle escape sequences correctly
235
+ value: JSON.parse(match)
236
+ };
237
+ }
238
+ function fStringDouble(m) {
239
+ return {
240
+ type: "string",
241
+ match: m[0],
242
+ // The raw matched string (including quotes)
243
+ value: JSON.parse(m[0])
244
+ // Use JSON.parse to handle escapes and get the value
245
+ };
246
+ }
247
+ function fIdentifier(m) {
248
+ const value = m[0];
249
+ const match = '"' + value.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + // Escape backslashes and quotes
250
+ '"';
251
+ return {
252
+ type: "string",
253
+ // Treat identifiers as strings
254
+ value,
255
+ // The original identifier name
256
+ match
257
+ // The double-quoted string representation
258
+ };
259
+ }
260
+ function fComment(m) {
261
+ const match = m[0].replace(
262
+ /./g,
263
+ (c) => WHITESPACE_TEST_REGEX.test(c) ? c : " "
264
+ );
265
+ return {
266
+ type: " ",
267
+ // Represent comments as whitespace tokens
268
+ match,
269
+ // String containing original newlines and spaces for other chars
270
+ value: void 0
271
+ // Comments don't have a semantic value
272
+ };
273
+ }
274
+ function fNumber(m) {
275
+ return {
276
+ type: "number",
277
+ match: m[0],
278
+ // The raw matched number string
279
+ value: Number.parseFloat(m[0])
280
+ // Convert string to number
281
+ };
282
+ }
283
+ function fKeyword(m) {
284
+ let value;
285
+ switch (m[0]) {
286
+ case "null":
287
+ value = null;
288
+ break;
289
+ case "true":
290
+ value = true;
291
+ break;
292
+ case "false":
293
+ value = false;
294
+ break;
295
+ default:
296
+ throw new Error(`Unexpected keyword: ${m[0]}`);
297
+ }
298
+ return {
299
+ type: "atom",
300
+ // Use 'atom' type for these literals
301
+ match: m[0],
302
+ // The raw matched keyword
303
+ value
304
+ // The corresponding JavaScript value
305
+ };
306
+ }
307
+ function makeTokenSpecs(relaxed) {
308
+ function f(type) {
309
+ return (m) => {
310
+ return { type, match: m[0], value: void 0 };
311
+ };
312
+ }
313
+ let tokenSpecs = [
314
+ { re: WHITESPACE_REGEX, f: f(" ") },
315
+ // Whitespace
316
+ { re: OBJECT_START_REGEX, f: f("{") },
317
+ // Object start
318
+ { re: OBJECT_END_REGEX, f: f("}") },
319
+ // Object end
320
+ { re: ARRAY_START_REGEX, f: f("[") },
321
+ // Array start
322
+ { re: ARRAY_END_REGEX, f: f("]") },
323
+ // Array end
324
+ { re: COMMA_REGEX, f: f(",") },
325
+ // Comma separator
326
+ { re: COLON_REGEX, f: f(":") },
327
+ // Key-value separator
328
+ { re: KEYWORD_REGEX, f: fKeyword },
329
+ // Keywords
330
+ // Number: optional sign, digits, optional decimal part, optional exponent
331
+ { re: NUMBER_REGEX, f: fNumber },
332
+ // String: double-quoted, handles escapes
333
+ { re: STRING_DOUBLE_REGEX, f: fStringDouble }
334
+ ];
335
+ if (relaxed) {
336
+ tokenSpecs = tokenSpecs.concat([
337
+ // Single-quoted strings
338
+ {
339
+ re: STRING_SINGLE_REGEX,
340
+ f: fStringSingle
341
+ },
342
+ // Single-line comments (// ...)
343
+ { re: COMMENT_SINGLE_REGEX, f: fComment },
344
+ // Multi-line comments (/* ... */)
345
+ { re: COMMENT_MULTI_REGEX, f: fComment },
346
+ // Unquoted identifiers (treated as strings)
347
+ // Allows letters, numbers, _, -, +, ., *, ?, !, |, &, %, ^, /, #, \
348
+ { re: IDENTIFIER_REGEX, f: fIdentifier }
349
+ // Note: The order matters here. Identifiers are checked after keywords/numbers.
350
+ ]);
351
+ }
352
+ return tokenSpecs;
353
+ }
354
+ var lexer = makeLexer(makeTokenSpecs(true));
355
+ var strictLexer = makeLexer(makeTokenSpecs(false));
356
+ function previousNWSToken(tokens, index) {
357
+ let currentIndex = index;
358
+ for (; currentIndex >= 0; currentIndex -= 1) {
359
+ if (tokens[currentIndex].type !== " ") {
360
+ return currentIndex;
361
+ }
362
+ }
363
+ return;
364
+ }
365
+ function stripTrailingComma(tokens) {
366
+ const res = [];
367
+ tokens.forEach((token, index) => {
368
+ if (index > 0 && (token.type === "]" || token.type === "}")) {
369
+ const prevNWSTokenIndex = previousNWSToken(res, res.length - 1);
370
+ if (prevNWSTokenIndex !== void 0 && res[prevNWSTokenIndex].type === ",") {
371
+ const preCommaIndex = previousNWSToken(res, prevNWSTokenIndex - 1);
372
+ if (preCommaIndex !== void 0 && res[preCommaIndex].type !== "[" && res[preCommaIndex].type !== "{") {
373
+ res[prevNWSTokenIndex] = {
374
+ type: " ",
375
+ match: " ",
376
+ // Represent as a single space
377
+ value: void 0,
378
+ // Whitespace has no value
379
+ line: res[prevNWSTokenIndex].line
380
+ // Preserve original line number
381
+ };
382
+ }
383
+ }
384
+ }
385
+ res.push(token);
386
+ });
387
+ return res;
388
+ }
389
+ function popToken(tokens, state) {
390
+ var _a, _b;
391
+ const token = tokens[state.pos];
392
+ state.pos += 1;
393
+ if (!token) {
394
+ const lastLine = tokens.length !== 0 ? (_b = (_a = tokens.at(-1)) == null ? void 0 : _a.line) != null ? _b : 1 : 1;
395
+ return { type: "eof", match: "", value: void 0, line: lastLine };
396
+ }
397
+ return token;
398
+ }
399
+ function strToken(token) {
400
+ switch (token.type) {
401
+ case "atom":
402
+ case "string":
403
+ case "number":
404
+ return `${token.type} ${token.match}`;
405
+ case "eof":
406
+ return "end-of-file";
407
+ default:
408
+ return `'${token.type}'`;
409
+ }
410
+ }
411
+ function skipColon(tokens, state) {
412
+ const colon = popToken(tokens, state);
413
+ if (colon.type !== ":") {
414
+ const message = `Unexpected token: ${strToken(colon)}, expected ':'`;
415
+ if (state.tolerant) {
416
+ state.warnings.push({
417
+ message,
418
+ line: colon.line
419
+ });
420
+ state.pos -= 1;
421
+ } else {
422
+ const err = new SyntaxError(message);
423
+ err.line = colon.line;
424
+ throw err;
425
+ }
426
+ }
427
+ }
428
+ function skipPunctuation(tokens, state, valid) {
429
+ const punctuation = [",", ":", "]", "}"];
430
+ let token = popToken(tokens, state);
431
+ while (true) {
432
+ if (valid == null ? void 0 : valid.includes(token.type)) {
433
+ return token;
434
+ }
435
+ if (token.type === "eof") {
436
+ return token;
437
+ }
438
+ if (punctuation.includes(token.type)) {
439
+ const message = `Unexpected token: ${strToken(
440
+ token
441
+ )}, expected '[', '{', number, string or atom`;
442
+ if (state.tolerant) {
443
+ state.warnings.push({
444
+ message,
445
+ line: token.line
446
+ });
447
+ token = popToken(tokens, state);
448
+ } else {
449
+ const err = new SyntaxError(message);
450
+ err.line = token.line;
451
+ throw err;
452
+ }
453
+ } else {
454
+ return token;
455
+ }
456
+ }
457
+ }
458
+ function raiseError(state, token, message) {
459
+ if (state.tolerant) {
460
+ state.warnings.push({
461
+ message,
462
+ line: token.line
463
+ });
464
+ } else {
465
+ const err = new SyntaxError(message);
466
+ err.line = token.line;
467
+ throw err;
468
+ }
469
+ }
470
+ function raiseUnexpected(state, token, expected) {
471
+ raiseError(
472
+ state,
473
+ token,
474
+ `Unexpected token: ${strToken(token)}, expected ${expected}`
475
+ );
476
+ }
477
+ function checkDuplicates(state, obj, token) {
478
+ const key = String(token.value);
479
+ if (!state.duplicate && Object.hasOwn(obj, key)) {
480
+ raiseError(state, token, `Duplicate key: ${key}`);
481
+ }
482
+ }
483
+ function appendPair(state, obj, key, value) {
484
+ const finalValue = state.reviver ? state.reviver(key, value) : value;
485
+ if (finalValue !== void 0) {
486
+ obj[key] = finalValue;
487
+ }
488
+ }
489
+ function parsePair(tokens, state, obj) {
490
+ let token = skipPunctuation(tokens, state, [":", "string", "number", "atom"]);
491
+ let value;
492
+ if (token.type !== "string") {
493
+ raiseUnexpected(state, token, "string key");
494
+ if (state.tolerant) {
495
+ switch (token.type) {
496
+ case ":":
497
+ token = {
498
+ type: "string",
499
+ value: "null",
500
+ match: '"null"',
501
+ line: token.line
502
+ };
503
+ state.pos -= 1;
504
+ break;
505
+ case "number":
506
+ // Use number as string key
507
+ case "atom":
508
+ token = {
509
+ type: "string",
510
+ value: String(token.value),
511
+ match: `"${token.value}"`,
512
+ line: token.line
513
+ };
514
+ break;
515
+ case "[":
516
+ // Assume missing key before an array
517
+ case "{":
518
+ state.pos -= 1;
519
+ value = parseAny(tokens, state);
520
+ checkDuplicates(state, obj, {
521
+ type: "string",
522
+ value: "null",
523
+ match: '"null"',
524
+ line: token.line
525
+ });
526
+ appendPair(state, obj, "null", value);
527
+ return;
528
+ // Finished parsing this "pair"
529
+ case "eof":
530
+ return;
531
+ // Cannot recover
532
+ default:
533
+ return;
534
+ }
535
+ } else {
536
+ return;
537
+ }
538
+ }
539
+ checkDuplicates(state, obj, token);
540
+ const key = String(token.value);
541
+ skipColon(tokens, state);
542
+ value = parseAny(tokens, state);
543
+ appendPair(state, obj, key, value);
544
+ }
545
+ function parseElement(tokens, state, arr) {
546
+ const key = arr.length;
547
+ const value = parseAny(tokens, state);
548
+ arr[key] = state.reviver ? state.reviver(String(key), value) : value;
549
+ }
550
+ function parseObject(tokens, state) {
551
+ const obj = {};
552
+ return parseMany(tokens, state, obj, {
553
+ skip: [":", "}"],
554
+ // Initially skip over colon or closing brace (for empty/tolerant cases)
555
+ elementParser: parsePair,
556
+ // Use parsePair to parse each key-value element
557
+ elementName: "string key",
558
+ // Expected element type for errors
559
+ endSymbol: "}"
560
+ // The closing token for an object
561
+ });
562
+ }
563
+ function parseArray(tokens, state) {
564
+ const arr = [];
565
+ return parseMany(tokens, state, arr, {
566
+ skip: ["]"],
567
+ // Initially skip over closing bracket (for empty/tolerant cases)
568
+ elementParser: parseElement,
569
+ // Use parseElement to parse each array item
570
+ elementName: "json value",
571
+ // Expected element type for errors
572
+ endSymbol: "]"
573
+ // The closing token for an array
574
+ });
575
+ }
576
+ function handleInvalidToken(token, state, opts, result) {
577
+ raiseUnexpected(state, token, `',' or '${opts.endSymbol}'`);
578
+ if (state.tolerant) {
579
+ if (token.type === "eof") {
580
+ return result;
581
+ }
582
+ state.pos -= 1;
583
+ return null;
584
+ }
585
+ return result;
586
+ }
587
+ function handleCommaToken(params) {
588
+ const { token, tokens, state, opts, result } = params;
589
+ const nextToken = tokens[state.pos];
590
+ if (state.tolerant && nextToken && nextToken.type === opts.endSymbol) {
591
+ raiseError(state, token, `Trailing comma before '${opts.endSymbol}'`);
592
+ popToken(tokens, state);
593
+ return result;
594
+ }
595
+ opts.elementParser(tokens, state, result);
596
+ return null;
597
+ }
598
+ function parseManyInitialElement(tokens, state, result, opts) {
599
+ const token = skipPunctuation(tokens, state, opts.skip);
600
+ if (token.type === "eof") {
601
+ raiseUnexpected(state, token, `'${opts.endSymbol}' or ${opts.elementName}`);
602
+ return result;
603
+ }
604
+ if (token.type === opts.endSymbol) {
605
+ return result;
606
+ }
607
+ state.pos -= 1;
608
+ opts.elementParser(tokens, state, result);
609
+ return;
610
+ }
611
+ function parseManyProcessToken(params) {
612
+ const { token, tokens, state, opts, result } = params;
613
+ if (token.type !== opts.endSymbol && token.type !== ",") {
614
+ const handledResult = handleInvalidToken(token, state, opts, result);
615
+ if (handledResult !== null) {
616
+ return handledResult;
617
+ }
618
+ }
619
+ if (token.type === opts.endSymbol) {
620
+ return result;
621
+ }
622
+ if (token.type === ",") {
623
+ const handledResult = handleCommaToken({
624
+ token,
625
+ tokens,
626
+ state,
627
+ opts,
628
+ result
629
+ });
630
+ if (handledResult !== null) {
631
+ return handledResult;
632
+ }
633
+ return;
634
+ }
635
+ opts.elementParser(tokens, state, result);
636
+ return;
637
+ }
638
+ function parseMany(tokens, state, result, opts) {
639
+ const initialResult = parseManyInitialElement(tokens, state, result, opts);
640
+ if (initialResult !== void 0) {
641
+ return initialResult;
642
+ }
643
+ while (true) {
644
+ const token = popToken(tokens, state);
645
+ const processedResult = parseManyProcessToken({
646
+ token,
647
+ tokens,
648
+ state,
649
+ opts,
650
+ result
651
+ });
652
+ if (processedResult !== void 0) {
653
+ return processedResult;
654
+ }
655
+ }
656
+ }
657
+ function endChecks(tokens, state, ret) {
658
+ if (state.pos < tokens.length) {
659
+ if (state.tolerant) {
660
+ skipPunctuation(tokens, state);
661
+ }
662
+ if (state.pos < tokens.length) {
663
+ raiseError(
664
+ state,
665
+ tokens[state.pos],
666
+ `Unexpected token: ${strToken(tokens[state.pos])}, expected end-of-input`
667
+ );
668
+ }
669
+ }
670
+ if (state.tolerant && state.warnings.length > 0) {
671
+ const message = state.warnings.length === 1 ? state.warnings[0].message : `${state.warnings.length} parse warnings`;
672
+ const err = new SyntaxError(message);
673
+ err.line = state.warnings[0].line;
674
+ err.warnings = state.warnings;
675
+ err.obj = ret;
676
+ throw err;
677
+ }
678
+ }
679
+ function parseAny(tokens, state, end = false) {
680
+ const token = skipPunctuation(tokens, state);
681
+ let ret;
682
+ if (token.type === "eof") {
683
+ if (end) {
684
+ raiseUnexpected(state, token, "json value");
685
+ }
686
+ raiseUnexpected(state, token, "json value");
687
+ return;
688
+ }
689
+ switch (token.type) {
690
+ case "{":
691
+ ret = parseObject(tokens, state);
692
+ break;
693
+ case "[":
694
+ ret = parseArray(tokens, state);
695
+ break;
696
+ case "string":
697
+ // String literal
698
+ case "number":
699
+ // Number literal
700
+ case "atom":
701
+ ret = token.value;
702
+ break;
703
+ default:
704
+ raiseUnexpected(state, token, "json value");
705
+ if (state.tolerant) {
706
+ ret = null;
707
+ } else {
708
+ return;
709
+ }
710
+ }
711
+ if (end) {
712
+ ret = state.reviver ? state.reviver("", ret) : ret;
713
+ endChecks(tokens, state, ret);
714
+ }
715
+ return ret;
716
+ }
717
+ function normalizeParseOptions(optsOrReviver) {
718
+ var _a;
719
+ let options = {};
720
+ if (typeof optsOrReviver === "function") {
721
+ options.reviver = optsOrReviver;
722
+ } else if (optsOrReviver !== null && typeof optsOrReviver === "object") {
723
+ options = { ...optsOrReviver };
724
+ } else if (optsOrReviver !== void 0) {
725
+ throw new TypeError(
726
+ "Second argument must be a reviver function or an options object."
727
+ );
728
+ }
729
+ if (options.relaxed === void 0) {
730
+ if (options.warnings === true || options.tolerant === true) {
731
+ options.relaxed = true;
732
+ } else if (options.warnings === false && options.tolerant === false) {
733
+ options.relaxed = false;
734
+ } else {
735
+ options.relaxed = true;
736
+ }
737
+ }
738
+ options.tolerant = options.tolerant || options.warnings;
739
+ options.duplicate = (_a = options.duplicate) != null ? _a : false;
740
+ return options;
741
+ }
742
+ function createParseState(options) {
743
+ var _a, _b;
744
+ return {
745
+ pos: 0,
746
+ reviver: options.reviver,
747
+ tolerant: (_a = options.tolerant) != null ? _a : false,
748
+ duplicate: (_b = options.duplicate) != null ? _b : false,
749
+ warnings: []
750
+ };
751
+ }
752
+ function parseWithCustomParser(text, options) {
753
+ const lexerToUse = options.relaxed ? lexer : strictLexer;
754
+ let tokens = lexerToUse(text);
755
+ if (options.relaxed) {
756
+ tokens = stripTrailingComma(tokens);
757
+ }
758
+ tokens = tokens.filter((token) => token.type !== " ");
759
+ const state = createParseState(options);
760
+ return parseAny(tokens, state, true);
761
+ }
762
+ function parseWithTransform(text, options) {
763
+ let tokens = lexer(text);
764
+ tokens = stripTrailingComma(tokens);
765
+ const newtext = tokens.reduce((str, token) => str + token.match, "");
766
+ return JSON.parse(
767
+ newtext,
768
+ options.reviver
769
+ );
770
+ }
771
+ function parse(text, optsOrReviver) {
772
+ const options = normalizeParseOptions(optsOrReviver);
773
+ if (!(options.relaxed || options.warnings || options.tolerant) && options.duplicate) {
774
+ return JSON.parse(
775
+ text,
776
+ options.reviver
777
+ );
778
+ }
779
+ if (options.warnings || options.tolerant || !options.duplicate) {
780
+ return parseWithCustomParser(text, options);
781
+ }
782
+ return parseWithTransform(text, options);
783
+ }
784
+
785
+ // src/core/protocols/json-mix-protocol.ts
786
+ function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
787
+ var _a, _b;
788
+ try {
789
+ const parsedToolCall = parse(toolCallJson);
790
+ processedElements.push({
791
+ type: "tool-call",
792
+ toolCallId: generateId(),
793
+ toolName: parsedToolCall.name,
794
+ input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
795
+ });
796
+ } catch (error) {
797
+ logParseFailure({
798
+ phase: "generated-text",
799
+ reason: "Failed to parse tool call JSON segment",
800
+ snippet: fullMatch,
801
+ error
802
+ });
803
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
804
+ options,
805
+ "Could not process JSON tool call, keeping original text.",
806
+ { toolCall: fullMatch, error }
807
+ );
808
+ processedElements.push({ type: "text", text: fullMatch });
809
+ }
810
+ }
811
+ function addTextSegment(text, processedElements) {
812
+ if (text.trim()) {
813
+ processedElements.push({ type: "text", text });
814
+ }
815
+ }
816
+ function processMatchedToolCall(context) {
817
+ const { match, text, currentIndex, processedElements, options } = context;
818
+ const startIndex = match.index;
819
+ const toolCallJson = match[1];
820
+ if (startIndex > currentIndex) {
821
+ const textSegment = text.substring(currentIndex, startIndex);
822
+ addTextSegment(textSegment, processedElements);
823
+ }
824
+ if (toolCallJson) {
825
+ processToolCallJson(toolCallJson, match[0], processedElements, options);
826
+ }
827
+ return startIndex + match[0].length;
828
+ }
829
+ function flushBuffer(state, controller, toolCallStart) {
830
+ if (state.buffer.length === 0) {
831
+ return;
832
+ }
833
+ if (!state.currentTextId) {
834
+ state.currentTextId = generateId();
835
+ controller.enqueue({
836
+ type: "text-start",
837
+ id: state.currentTextId
838
+ });
839
+ state.hasEmittedTextStart = true;
840
+ }
841
+ const deltaContent = state.isInsideToolCall ? `${toolCallStart}${state.buffer}` : state.buffer;
842
+ controller.enqueue({
843
+ type: "text-delta",
844
+ id: state.currentTextId,
845
+ textDelta: deltaContent,
846
+ delta: deltaContent
847
+ });
848
+ state.buffer = "";
849
+ }
850
+ function closeTextBlock(state, controller) {
851
+ if (state.currentTextId && state.hasEmittedTextStart) {
852
+ controller.enqueue({
853
+ type: "text-end",
854
+ id: state.currentTextId
855
+ });
856
+ state.currentTextId = null;
857
+ state.hasEmittedTextStart = false;
858
+ }
859
+ }
860
+ function emitIncompleteToolCall(state, controller, toolCallStart) {
861
+ if (!state.currentToolCallJson) {
862
+ return;
863
+ }
864
+ logParseFailure({
865
+ phase: "stream",
866
+ reason: "Incomplete streaming tool call segment emitted as text",
867
+ snippet: `${toolCallStart}${state.currentToolCallJson}`
868
+ });
869
+ const errorId = generateId();
870
+ const errorContent = `${toolCallStart}${state.currentToolCallJson}`;
871
+ controller.enqueue({
872
+ type: "text-start",
873
+ id: errorId
874
+ });
875
+ controller.enqueue({
876
+ type: "text-delta",
877
+ id: errorId,
878
+ textDelta: errorContent,
879
+ delta: errorContent
880
+ });
881
+ controller.enqueue({
882
+ type: "text-end",
883
+ id: errorId
884
+ });
885
+ state.currentToolCallJson = "";
886
+ }
887
+ function handleFinishChunk(state, controller, toolCallStart, chunk) {
888
+ if (state.buffer.length > 0) {
889
+ flushBuffer(state, controller, toolCallStart);
890
+ }
891
+ closeTextBlock(state, controller);
892
+ emitIncompleteToolCall(state, controller, toolCallStart);
893
+ controller.enqueue(chunk);
894
+ }
895
+ function publishText(text, state, controller) {
896
+ if (state.isInsideToolCall) {
897
+ closeTextBlock(state, controller);
898
+ state.currentToolCallJson += text;
899
+ } else if (text.length > 0) {
900
+ if (!state.currentTextId) {
901
+ state.currentTextId = generateId();
902
+ controller.enqueue({
903
+ type: "text-start",
904
+ id: state.currentTextId
905
+ });
906
+ state.hasEmittedTextStart = true;
907
+ }
908
+ controller.enqueue({
909
+ type: "text-delta",
910
+ id: state.currentTextId,
911
+ textDelta: text,
912
+ delta: text
913
+ });
914
+ }
915
+ }
916
+ function emitToolCall(context) {
917
+ var _a, _b;
918
+ const { state, controller, toolCallStart, toolCallEnd, options } = context;
919
+ try {
920
+ const parsedToolCall = parse(state.currentToolCallJson);
921
+ closeTextBlock(state, controller);
922
+ controller.enqueue({
923
+ type: "tool-call",
924
+ toolCallId: generateId(),
925
+ toolName: parsedToolCall.name,
926
+ input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
927
+ });
928
+ } catch (error) {
929
+ logParseFailure({
930
+ phase: "stream",
931
+ reason: "Failed to parse streaming tool call JSON segment",
932
+ snippet: `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`,
933
+ error
934
+ });
935
+ const errorId = generateId();
936
+ const errorContent = `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`;
937
+ controller.enqueue({
938
+ type: "text-start",
939
+ id: errorId
940
+ });
941
+ controller.enqueue({
942
+ type: "text-delta",
943
+ id: errorId,
944
+ textDelta: errorContent,
945
+ delta: errorContent
946
+ });
947
+ controller.enqueue({
948
+ type: "text-end",
949
+ id: errorId
950
+ });
951
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
952
+ options,
953
+ "Could not process streaming JSON tool call; emitting original text.",
954
+ {
955
+ toolCall: errorContent
956
+ }
957
+ );
958
+ }
959
+ }
960
+ function processTagMatch(context) {
961
+ const { state } = context;
962
+ if (state.isInsideToolCall) {
963
+ emitToolCall(context);
964
+ state.currentToolCallJson = "";
965
+ state.isInsideToolCall = false;
966
+ } else {
967
+ state.currentToolCallJson = "";
968
+ state.isInsideToolCall = true;
969
+ }
970
+ }
971
+ function processBufferTags(context) {
972
+ const { state, controller, toolCallStart, toolCallEnd } = context;
973
+ let startIndex = getPotentialStartIndex(
974
+ state.buffer,
975
+ state.isInsideToolCall ? toolCallEnd : toolCallStart
976
+ );
977
+ while (startIndex != null) {
978
+ const tag = state.isInsideToolCall ? toolCallEnd : toolCallStart;
979
+ if (startIndex + tag.length > state.buffer.length) {
980
+ break;
981
+ }
982
+ publishText(state.buffer.slice(0, startIndex), state, controller);
983
+ state.buffer = state.buffer.slice(startIndex + tag.length);
984
+ processTagMatch(context);
985
+ startIndex = getPotentialStartIndex(
986
+ state.buffer,
987
+ state.isInsideToolCall ? toolCallEnd : toolCallStart
988
+ );
989
+ }
990
+ }
991
+ function handlePartialTag(state, controller, toolCallStart) {
992
+ if (state.isInsideToolCall) {
993
+ return;
994
+ }
995
+ const potentialIndex = getPotentialStartIndex(state.buffer, toolCallStart);
996
+ if (potentialIndex != null && potentialIndex + toolCallStart.length > state.buffer.length) {
997
+ publishText(state.buffer.slice(0, potentialIndex), state, controller);
998
+ state.buffer = state.buffer.slice(potentialIndex);
999
+ } else {
1000
+ publishText(state.buffer, state, controller);
1001
+ state.buffer = "";
1002
+ }
1003
+ }
1004
+ var jsonMixProtocol = ({
1005
+ toolCallStart = "<tool_call>",
1006
+ toolCallEnd = "</tool_call>",
1007
+ toolResponseStart = "<tool_response>",
1008
+ toolResponseEnd = "</tool_response>"
1009
+ } = {}) => ({
1010
+ formatTools({ tools, toolSystemPromptTemplate }) {
1011
+ const toolsForPrompt = (tools || []).filter((tool) => tool.type === "function").map((tool) => ({
1012
+ name: tool.name,
1013
+ description: tool.type === "function" && typeof tool.description === "string" ? tool.description : void 0,
1014
+ parameters: tool.inputSchema
1015
+ }));
1016
+ return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
1017
+ },
1018
+ formatToolCall(toolCall) {
1019
+ let args = {};
1020
+ try {
1021
+ args = JSON.parse(toolCall.input);
1022
+ } catch (e) {
1023
+ args = toolCall.input;
1024
+ }
1025
+ return `${toolCallStart}${JSON.stringify({
1026
+ name: toolCall.toolName,
1027
+ arguments: args
1028
+ })}${toolCallEnd}`;
1029
+ },
1030
+ formatToolResponse(toolResult) {
1031
+ return `${toolResponseStart}${JSON.stringify({
1032
+ toolName: toolResult.toolName,
1033
+ result: toolResult.result
1034
+ })}${toolResponseEnd}`;
1035
+ },
1036
+ parseGeneratedText({ text, options }) {
1037
+ const startEsc = escapeRegExp(toolCallStart);
1038
+ const endEsc = escapeRegExp(toolCallEnd);
1039
+ const toolCallRegex = new RegExp(
1040
+ `${startEsc}([\0-\uFFFF]*?)${endEsc}`,
1041
+ "gs"
1042
+ );
1043
+ const processedElements = [];
1044
+ let currentIndex = 0;
1045
+ let match = toolCallRegex.exec(text);
1046
+ while (match !== null) {
1047
+ currentIndex = processMatchedToolCall({
1048
+ match,
1049
+ text,
1050
+ currentIndex,
1051
+ processedElements,
1052
+ options
1053
+ });
1054
+ match = toolCallRegex.exec(text);
1055
+ }
1056
+ if (currentIndex < text.length) {
1057
+ const remainingText = text.substring(currentIndex);
1058
+ addTextSegment(remainingText, processedElements);
1059
+ }
1060
+ return processedElements;
1061
+ },
1062
+ createStreamParser({ options }) {
1063
+ const state = {
1064
+ isInsideToolCall: false,
1065
+ buffer: "",
1066
+ currentToolCallJson: "",
1067
+ currentTextId: null,
1068
+ hasEmittedTextStart: false
1069
+ };
1070
+ return new TransformStream({
1071
+ transform(chunk, controller) {
1072
+ var _a, _b;
1073
+ if (chunk.type === "finish") {
1074
+ handleFinishChunk(state, controller, toolCallStart, chunk);
1075
+ return;
1076
+ }
1077
+ if (chunk.type !== "text-delta") {
1078
+ controller.enqueue(chunk);
1079
+ return;
1080
+ }
1081
+ const textContent = (_b = (_a = chunk.textDelta) != null ? _a : chunk.delta) != null ? _b : "";
1082
+ state.buffer += textContent;
1083
+ processBufferTags({
1084
+ state,
1085
+ controller,
1086
+ toolCallStart,
1087
+ toolCallEnd,
1088
+ options
1089
+ });
1090
+ handlePartialTag(state, controller, toolCallStart);
1091
+ }
1092
+ });
1093
+ },
1094
+ extractToolCallSegments({ text }) {
1095
+ const startEsc = escapeRegExp(toolCallStart);
1096
+ const endEsc = escapeRegExp(toolCallEnd);
1097
+ const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
1098
+ const segments = [];
1099
+ let m = regex.exec(text);
1100
+ while (m != null) {
1101
+ segments.push(m[0]);
1102
+ m = regex.exec(text);
1103
+ }
1104
+ return segments;
1105
+ }
1106
+ });
1107
+
1108
+ // src/core/protocols/morph-xml-protocol.ts
1109
+ var import_rxml2 = require("@ai-sdk-tool/rxml");
1110
+
1111
+ // src/core/heuristics/engine.ts
1112
+ function applyRawSegmentUpdate(current, result) {
1113
+ if (result.rawSegment !== void 0) {
1114
+ return { ...current, rawSegment: result.rawSegment };
1115
+ }
1116
+ return current;
1117
+ }
1118
+ function applyParsedUpdate(current, result) {
1119
+ if (result.parsed !== void 0) {
1120
+ return { ...current, parsed: result.parsed };
1121
+ }
1122
+ return current;
1123
+ }
1124
+ function applyWarningsUpdate(current, result) {
1125
+ var _a, _b;
1126
+ if (result.warnings && result.warnings.length > 0) {
1127
+ const meta = (_a = current.meta) != null ? _a : {};
1128
+ const existingWarnings = (_b = meta.warnings) != null ? _b : [];
1129
+ return {
1130
+ ...current,
1131
+ meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
1132
+ };
1133
+ }
1134
+ return current;
1135
+ }
1136
+ function attemptReparse(current, result, reparseCount, maxReparses, parse4) {
1137
+ if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
1138
+ return { state: current, newCount: reparseCount };
1139
+ }
1140
+ try {
1141
+ const reparsed = parse4(result.rawSegment, current.schema);
1142
+ return {
1143
+ state: { ...current, parsed: reparsed, errors: [] },
1144
+ newCount: reparseCount + 1
1145
+ };
1146
+ } catch (error) {
1147
+ return {
1148
+ state: { ...current, errors: [...current.errors, error] },
1149
+ newCount: reparseCount + 1
1150
+ };
1151
+ }
1152
+ }
1153
+ function executePhase(ctx, heuristics, options) {
1154
+ var _a;
1155
+ let current = ctx;
1156
+ let reparseCount = 0;
1157
+ const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
1158
+ for (const heuristic of heuristics) {
1159
+ if (!heuristic.applies(current)) {
1160
+ continue;
1161
+ }
1162
+ const result = heuristic.run(current);
1163
+ current = applyRawSegmentUpdate(current, result);
1164
+ current = applyParsedUpdate(current, result);
1165
+ current = applyWarningsUpdate(current, result);
1166
+ const reparseResult = attemptReparse(
1167
+ current,
1168
+ result,
1169
+ reparseCount,
1170
+ maxReparses,
1171
+ options.parse
1172
+ );
1173
+ current = reparseResult.state;
1174
+ reparseCount = reparseResult.newCount;
1175
+ if (result.stop) {
1176
+ break;
1177
+ }
1178
+ }
1179
+ return current;
1180
+ }
1181
+ function applyHeuristicPipeline(ctx, config, options) {
1182
+ let current = ctx;
1183
+ if (config.preParse && config.preParse.length > 0) {
1184
+ current = executePhase(current, config.preParse, options);
1185
+ }
1186
+ if (current.parsed === null && current.errors.length === 0) {
1187
+ try {
1188
+ const parsed = options.parse(current.rawSegment, current.schema);
1189
+ current = { ...current, parsed, errors: [] };
1190
+ } catch (error) {
1191
+ current = { ...current, errors: [error] };
1192
+ }
1193
+ }
1194
+ if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
1195
+ current = executePhase(current, config.fallbackReparse, options);
1196
+ }
1197
+ if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
1198
+ current = executePhase(current, config.postParse, options);
1199
+ }
1200
+ return current;
1201
+ }
1202
+ function createIntermediateCall(toolName, rawSegment, schema) {
1203
+ return {
1204
+ toolName,
1205
+ schema,
1206
+ rawSegment,
1207
+ parsed: null,
1208
+ errors: [],
1209
+ meta: { originalContent: rawSegment }
1210
+ };
1211
+ }
1212
+
1213
+ // src/core/heuristics/xml-defaults.ts
1214
+ var import_rxml = require("@ai-sdk-tool/rxml");
1215
+ var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
1216
+ var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
1217
+ var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
1218
+ var WHITESPACE_REGEX2 = /\s/;
1219
+ var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
1220
+ var NAME_START_CHAR_RE = /[A-Za-z_:]/;
1221
+ var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
1222
+ var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
1223
+ var normalizeCloseTagsHeuristic = {
1224
+ id: "normalize-close-tags",
1225
+ phase: "pre-parse",
1226
+ applies: () => true,
1227
+ run: (ctx) => {
1228
+ const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
1229
+ if (normalized !== ctx.rawSegment) {
1230
+ return { rawSegment: normalized };
1231
+ }
1232
+ return {};
1233
+ }
1234
+ };
1235
+ var escapeInvalidLtHeuristic = {
1236
+ id: "escape-invalid-lt",
1237
+ phase: "pre-parse",
1238
+ applies: () => true,
1239
+ run: (ctx) => {
1240
+ const escaped = escapeInvalidLt(ctx.rawSegment);
1241
+ if (escaped !== ctx.rawSegment) {
1242
+ return { rawSegment: escaped };
1243
+ }
1244
+ return {};
1245
+ }
1246
+ };
1247
+ var balanceTagsHeuristic = {
1248
+ id: "balance-tags",
1249
+ phase: "fallback-reparse",
1250
+ applies: (ctx) => {
1251
+ var _a;
1252
+ const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
1253
+ const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
1254
+ const balanced = balanceTags(original);
1255
+ const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
1256
+ if (!hasMalformedClose && balanced.length > normalized.length) {
1257
+ return false;
1258
+ }
1259
+ return balanced !== normalized;
1260
+ },
1261
+ run: (ctx) => {
1262
+ var _a;
1263
+ const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
1264
+ const balanced = balanceTags(original);
1265
+ const escaped = escapeInvalidLt(balanced);
1266
+ return { rawSegment: escaped, reparse: true };
1267
+ }
1268
+ };
1269
+ var dedupeShellStringTagsHeuristic = {
1270
+ id: "dedupe-shell-string-tags",
1271
+ phase: "fallback-reparse",
1272
+ applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
1273
+ run: (ctx) => {
1274
+ const names = getStringPropertyNames(ctx.schema);
1275
+ let deduped = ctx.rawSegment;
1276
+ for (const key of names) {
1277
+ deduped = dedupeSingleTag(deduped, key);
1278
+ }
1279
+ if (deduped !== ctx.rawSegment) {
1280
+ return { rawSegment: deduped, reparse: true };
1281
+ }
1282
+ return {};
1283
+ }
1284
+ };
1285
+ var repairAgainstSchemaHeuristic = {
1286
+ id: "repair-against-schema",
1287
+ phase: "post-parse",
1288
+ applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
1289
+ run: (ctx) => {
1290
+ const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
1291
+ if (repaired !== ctx.parsed) {
1292
+ return { parsed: repaired };
1293
+ }
1294
+ return {};
1295
+ }
1296
+ };
1297
+ var defaultPipelineConfig = {
1298
+ preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
1299
+ fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
1300
+ postParse: [repairAgainstSchemaHeuristic]
1301
+ };
1302
+ var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
1303
+ function isIndexTagAt(xml, pos) {
1304
+ const remaining = xml.slice(pos);
1305
+ return INDEX_TAG_RE.test(remaining);
1306
+ }
1307
+ function escapeInvalidLt(xml) {
1308
+ const len = xml.length;
1309
+ let out = "";
1310
+ for (let i = 0; i < len; i += 1) {
1311
+ const ch = xml[i];
1312
+ if (ch === "<") {
1313
+ const next = i + 1 < len ? xml[i + 1] : "";
1314
+ const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
1315
+ const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
1316
+ if (!(isValidStart || isIndexTag)) {
1317
+ out += "&lt;";
1318
+ continue;
1319
+ }
1320
+ }
1321
+ out += ch;
1322
+ }
1323
+ return out;
1324
+ }
1325
+ function balanceTags(xml) {
1326
+ const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
1327
+ let i = 0;
1328
+ const len = src.length;
1329
+ const out = [];
1330
+ const stack = [];
1331
+ while (i < len) {
1332
+ const lt = src.indexOf("<", i);
1333
+ if (lt === -1) {
1334
+ out.push(src.slice(i));
1335
+ break;
1336
+ }
1337
+ out.push(src.slice(i, lt));
1338
+ if (lt + 1 >= len) {
1339
+ break;
1340
+ }
1341
+ const next = src[lt + 1];
1342
+ if (next === "!" || next === "?") {
1343
+ i = handleSpecialTagSegment(src, lt, out);
1344
+ continue;
1345
+ }
1346
+ if (next === "/") {
1347
+ i = handleClosingTagSegment(src, lt, out, stack);
1348
+ continue;
1349
+ }
1350
+ i = handleOpeningTagSegment(src, lt, out, stack);
1351
+ }
1352
+ for (let k = stack.length - 1; k >= 0; k -= 1) {
1353
+ out.push(`</${stack[k]}>`);
1354
+ }
1355
+ return out.join("");
1356
+ }
1357
+ function skipWs(s, p, len) {
1358
+ let idx = p;
1359
+ while (idx < len && WHITESPACE_REGEX2.test(s[idx])) {
1360
+ idx += 1;
1361
+ }
1362
+ return idx;
1363
+ }
1364
+ function parseTagNameAt(s, p, len) {
1365
+ let idx = p;
1366
+ const start = idx;
1367
+ while (idx < len && NAME_CHAR_RE.test(s[idx])) {
1368
+ idx += 1;
1369
+ }
1370
+ return { name: s.slice(start, idx), pos: idx };
1371
+ }
1372
+ function handleSpecialTagSegment(src, lt, out) {
1373
+ const gt = src.indexOf(">", lt + 1);
1374
+ if (gt === -1) {
1375
+ out.push(src.slice(lt));
1376
+ return src.length;
1377
+ }
1378
+ out.push(src.slice(lt, gt + 1));
1379
+ return gt + 1;
1380
+ }
1381
+ function handleClosingTagSegment(src, lt, out, stack) {
1382
+ const len = src.length;
1383
+ let p = skipWs(src, lt + 2, len);
1384
+ const { name, pos } = parseTagNameAt(src, p, len);
1385
+ p = pos;
1386
+ const gt = src.indexOf(">", p);
1387
+ const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
1388
+ const idx = stack.lastIndexOf(name);
1389
+ if (idx !== -1) {
1390
+ for (let k = stack.length - 1; k > idx; k -= 1) {
1391
+ out.push(`</${stack[k]}>`);
1392
+ stack.pop();
1393
+ }
1394
+ out.push(closingText);
1395
+ stack.pop();
1396
+ }
1397
+ return gt === -1 ? len : gt + 1;
1398
+ }
1399
+ function handleOpeningTagSegment(src, lt, out, stack) {
1400
+ const len = src.length;
1401
+ let p = skipWs(src, lt + 1, len);
1402
+ const nameStart = p;
1403
+ const parsed = parseTagNameAt(src, p, len);
1404
+ p = parsed.pos;
1405
+ const name = src.slice(nameStart, p);
1406
+ const q = src.indexOf(">", p);
1407
+ if (q === -1) {
1408
+ out.push(src.slice(lt));
1409
+ return len;
1410
+ }
1411
+ let r = q - 1;
1412
+ while (r >= nameStart && WHITESPACE_REGEX2.test(src[r])) {
1413
+ r -= 1;
1414
+ }
1415
+ const selfClosing = src[r] === "/";
1416
+ out.push(src.slice(lt, q + 1));
1417
+ if (!selfClosing && name) {
1418
+ stack.push(name);
1419
+ }
1420
+ return q + 1;
1421
+ }
1422
+ function shouldDeduplicateStringTags(schema) {
1423
+ const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
1424
+ if (!unwrapped || typeof unwrapped !== "object") {
1425
+ return false;
1426
+ }
1427
+ const props = unwrapped.properties;
1428
+ if (!props) {
1429
+ return false;
1430
+ }
1431
+ const commandRaw = props.command;
1432
+ if (!commandRaw) {
1433
+ return false;
1434
+ }
1435
+ const command = (0, import_rxml.unwrapJsonSchema)(commandRaw);
1436
+ return (command == null ? void 0 : command.type) === "array";
1437
+ }
1438
+ function getStringPropertyNames(schema) {
1439
+ const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
1440
+ if (!unwrapped || typeof unwrapped !== "object") {
1441
+ return [];
1442
+ }
1443
+ const props = unwrapped.properties;
1444
+ if (!props) {
1445
+ return [];
1446
+ }
1447
+ const names = [];
1448
+ for (const key of Object.keys(props)) {
1449
+ const prop = (0, import_rxml.unwrapJsonSchema)(
1450
+ props[key]
1451
+ );
1452
+ const type = prop.type;
1453
+ if (type === "string") {
1454
+ names.push(key);
1455
+ }
1456
+ }
1457
+ return names;
1458
+ }
1459
+ function escapeRegExp2(s) {
1460
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1461
+ }
1462
+ function dedupeSingleTag(xml, key) {
1463
+ var _a, _b;
1464
+ const escaped = escapeRegExp2(key);
1465
+ const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
1466
+ const matches = Array.from(xml.matchAll(re));
1467
+ if (matches.length <= 1) {
1468
+ return xml;
1469
+ }
1470
+ const last = matches.at(-1);
1471
+ let result = "";
1472
+ let cursor = 0;
1473
+ for (const m of matches) {
1474
+ const idx = (_a = m.index) != null ? _a : 0;
1475
+ result += xml.slice(cursor, idx);
1476
+ if (last && idx === ((_b = last.index) != null ? _b : -1)) {
1477
+ result += m[0];
1478
+ }
1479
+ cursor = idx + m[0].length;
1480
+ }
1481
+ result += xml.slice(cursor);
1482
+ return result;
1483
+ }
1484
+ function repairParsedAgainstSchema(input, schema) {
1485
+ if (!input || typeof input !== "object") {
1486
+ return input;
1487
+ }
1488
+ const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
1489
+ if (!unwrapped || typeof unwrapped !== "object") {
1490
+ return input;
1491
+ }
1492
+ const properties = unwrapped.properties;
1493
+ if (!properties) {
1494
+ return input;
1495
+ }
1496
+ applySchemaProps(input, properties);
1497
+ return input;
1498
+ }
1499
+ function applySchemaProps(obj, properties) {
1500
+ for (const key of Object.keys(obj)) {
1501
+ const propSchema = properties[key];
1502
+ if (!propSchema) {
1503
+ continue;
1504
+ }
1505
+ const prop = (0, import_rxml.unwrapJsonSchema)(propSchema);
1506
+ const propType = prop.type;
1507
+ if (propType === "array" && prop.items) {
1508
+ const itemSchemaRaw = prop.items;
1509
+ const itemSchema = (0, import_rxml.unwrapJsonSchema)(itemSchemaRaw);
1510
+ obj[key] = coerceArrayItems(obj[key], itemSchema);
1511
+ continue;
1512
+ }
1513
+ if (propType === "object") {
1514
+ const val = obj[key];
1515
+ if (val && typeof val === "object") {
1516
+ obj[key] = repairParsedAgainstSchema(val, prop);
1517
+ }
1518
+ }
1519
+ }
1520
+ }
1521
+ function coerceArrayItems(val, itemSchema) {
1522
+ if (!Array.isArray(val)) {
1523
+ return val;
1524
+ }
1525
+ return val.map((v) => coerceArrayItem(v, itemSchema));
1526
+ }
1527
+ function coerceArrayItem(v, itemSchema) {
1528
+ const itemType = itemSchema == null ? void 0 : itemSchema.type;
1529
+ if (typeof v === "string" && itemType === "object") {
1530
+ const parsed = tryParseStringToSchemaObject(v, itemSchema);
1531
+ if (parsed !== null) {
1532
+ return parsed;
1533
+ }
1534
+ const fallback = extractStepStatusFromString(
1535
+ v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
1536
+ );
1537
+ if (fallback) {
1538
+ return fallback;
1539
+ }
1540
+ return v;
1541
+ }
1542
+ if (v && typeof v === "object" && itemType === "object") {
1543
+ return repairParsedAgainstSchema(v, itemSchema);
1544
+ }
1545
+ return v;
1546
+ }
1547
+ function tryParseStringToSchemaObject(xml, itemSchema) {
1548
+ try {
1549
+ const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
1550
+ const fixed = (0, import_rxml.parse)(normalized, itemSchema, { noChildNodes: [] });
1551
+ return typeof fixed === "string" ? null : fixed;
1552
+ } catch (e) {
1553
+ return null;
1554
+ }
1555
+ }
1556
+ function extractStepStatusFromString(normXml) {
1557
+ const stepMatch = normXml.match(STEP_TAG_RE);
1558
+ const statusMatch = normXml.match(STATUS_TAG_RE);
1559
+ if (stepMatch && statusMatch) {
1560
+ return { step: stepMatch[1], status: statusMatch[1] };
1561
+ }
1562
+ return null;
1563
+ }
1564
+
1565
+ // src/core/protocols/morph-xml-protocol.ts
1566
+ var defaultPipelineConfig2 = defaultPipelineConfig;
1567
+ var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
1568
+ var WHITESPACE_REGEX3 = /\s/;
1569
+ function getToolSchema(tools, toolName) {
1570
+ var _a;
1571
+ return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1572
+ }
1573
+ function normalizeCloseTags(xml) {
1574
+ return xml.replace(/<\/\s+([A-Za-z0-9_:-]+)\s*>/g, "</$1>");
1575
+ }
1576
+ function tryParseSecondaryXml(content, toolSchema, options) {
1577
+ const balanced = balanceTags(content);
1578
+ try {
1579
+ let parsed = (0, import_rxml2.parse)(balanced, toolSchema, {
1580
+ onError: options == null ? void 0 : options.onError,
1581
+ noChildNodes: []
1582
+ });
1583
+ parsed = repairParsedAgainstSchema(parsed, toolSchema);
1584
+ return parsed;
1585
+ } catch (e) {
1586
+ if (shouldDeduplicateStringTags(toolSchema)) {
1587
+ const names = getStringPropertyNames(toolSchema);
1588
+ let deduped = balanced;
1589
+ for (const key of names) {
1590
+ deduped = dedupeSingleTag(deduped, key);
1591
+ }
1592
+ if (deduped !== balanced) {
1593
+ try {
1594
+ let reparsed = (0, import_rxml2.parse)(deduped, toolSchema, {
1595
+ onError: options == null ? void 0 : options.onError,
1596
+ noChildNodes: []
1597
+ });
1598
+ reparsed = repairParsedAgainstSchema(reparsed, toolSchema);
1599
+ return reparsed;
1600
+ } catch (e2) {
1601
+ return null;
1602
+ }
1603
+ }
1604
+ }
1605
+ return null;
1606
+ }
1607
+ }
1608
+ function processToolCallWithPipeline(params) {
1609
+ var _a;
1610
+ const {
1611
+ toolCall,
1612
+ tools,
1613
+ options,
1614
+ text,
1615
+ processedElements,
1616
+ pipelineConfig = defaultPipelineConfig2,
1617
+ maxReparses
1618
+ } = params;
1619
+ const toolSchema = getToolSchema(tools, toolCall.toolName);
1620
+ const ctx = createIntermediateCall(
1621
+ toolCall.toolName,
1622
+ toolCall.content,
1623
+ toolSchema
1624
+ );
1625
+ const result = applyHeuristicPipeline(ctx, pipelineConfig, {
1626
+ parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
1627
+ onError: options == null ? void 0 : options.onError,
1628
+ maxReparses
1629
+ });
1630
+ if (result.parsed !== null) {
1631
+ processedElements.push({
1632
+ type: "tool-call",
1633
+ toolCallId: generateId(),
1634
+ toolName: toolCall.toolName,
1635
+ input: JSON.stringify(result.parsed)
1636
+ });
1637
+ } else {
1638
+ const originalCallText = text.substring(
1639
+ toolCall.startIndex,
1640
+ toolCall.endIndex
1641
+ );
1642
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
1643
+ options,
1644
+ `Could not process XML tool call: ${toolCall.toolName}`,
1645
+ { toolCall: originalCallText, error: result.errors[0] }
1646
+ );
1647
+ processedElements.push({ type: "text", text: originalCallText });
1648
+ }
1649
+ }
1650
+ function handleStreamingToolCallEnd(params) {
1651
+ var _a;
1652
+ const {
1653
+ toolContent,
1654
+ currentToolCall,
1655
+ tools,
1656
+ options,
1657
+ ctrl,
1658
+ flushText,
1659
+ pipelineConfig,
1660
+ maxReparses
1661
+ } = params;
1662
+ const toolSchema = getToolSchema(tools, currentToolCall.name);
1663
+ let parsedResult = null;
1664
+ if (pipelineConfig) {
1665
+ const ctx = createIntermediateCall(
1666
+ currentToolCall.name,
1667
+ toolContent,
1668
+ toolSchema
1669
+ );
1670
+ const result = applyHeuristicPipeline(ctx, pipelineConfig, {
1671
+ parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
1672
+ onError: options == null ? void 0 : options.onError,
1673
+ maxReparses
1674
+ });
1675
+ parsedResult = result.parsed;
1676
+ } else {
1677
+ try {
1678
+ const primary = escapeInvalidLt(normalizeCloseTags(toolContent));
1679
+ const parsed = (0, import_rxml2.parse)(primary, toolSchema, {
1680
+ onError: options == null ? void 0 : options.onError,
1681
+ noChildNodes: []
1682
+ });
1683
+ parsedResult = repairParsedAgainstSchema(parsed, toolSchema);
1684
+ } catch (e) {
1685
+ parsedResult = tryParseSecondaryXml(
1686
+ toolContent,
1687
+ toolSchema,
1688
+ options != null ? options : {}
1689
+ );
1690
+ }
1691
+ }
1692
+ flushText(ctrl);
1693
+ if (parsedResult !== null) {
1694
+ ctrl.enqueue({
1695
+ type: "tool-call",
1696
+ toolCallId: generateId(),
1697
+ toolName: currentToolCall.name,
1698
+ input: JSON.stringify(parsedResult)
1699
+ });
1700
+ } else {
1701
+ const original = `<${currentToolCall.name}>${toolContent}</${currentToolCall.name}>`;
1702
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not process streaming XML tool call", {
1703
+ toolCall: original
1704
+ });
1705
+ flushText(ctrl, original);
1706
+ }
1707
+ }
1708
+ function findClosingTagEndFlexible(text, contentStart, toolName) {
1709
+ let pos = contentStart;
1710
+ let depth = 1;
1711
+ while (pos < text.length) {
1712
+ const tok = nextTagToken(text, pos);
1713
+ if (tok.kind === "eof") {
1714
+ break;
1715
+ }
1716
+ const result = updateDepthWithToken(tok, toolName, depth);
1717
+ depth = result.depth;
1718
+ if (result.closedAt !== void 0) {
1719
+ return result.closedAt;
1720
+ }
1721
+ pos = tok.nextPos;
1722
+ }
1723
+ return -1;
1724
+ }
1725
+ function skipSpecialSegment(text, lt) {
1726
+ const next = text[lt + 1];
1727
+ if (next === "!" || next === "?") {
1728
+ const gt = text.indexOf(">", lt + 1);
1729
+ if (gt !== -1) {
1730
+ return gt + 1;
1731
+ }
1732
+ }
1733
+ return null;
1734
+ }
1735
+ function consumeClosingTag(text, lt) {
1736
+ const gt = text.indexOf(">", lt + 1);
1737
+ const endPos = gt === -1 ? text.length : gt + 1;
1738
+ return { matched: false, endPos };
1739
+ }
1740
+ function consumeOpenTag(text, lt) {
1741
+ let p = lt + 1;
1742
+ while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
1743
+ p += 1;
1744
+ }
1745
+ const nameStart = p;
1746
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
1747
+ p += 1;
1748
+ }
1749
+ const name = text.slice(nameStart, p);
1750
+ const q = text.indexOf(">", p);
1751
+ if (q === -1) {
1752
+ return null;
1753
+ }
1754
+ let r = q - 1;
1755
+ while (r >= nameStart && WHITESPACE_REGEX3.test(text[r])) {
1756
+ r -= 1;
1757
+ }
1758
+ const selfClosing = text[r] === "/";
1759
+ return { name, selfClosing, nextPos: q + 1 };
1760
+ }
1761
+ function updateDepthWithToken(tok, toolName, depth) {
1762
+ if (tok.kind === "close" && tok.name === toolName) {
1763
+ const newDepth = depth - 1;
1764
+ return newDepth === 0 ? { depth: newDepth, closedAt: tok.nextPos } : { depth: newDepth };
1765
+ }
1766
+ if (tok.kind === "open" && tok.name === toolName && !tok.selfClosing) {
1767
+ return { depth: depth + 1 };
1768
+ }
1769
+ return { depth };
1770
+ }
1771
+ function nextTagToken(text, fromPos) {
1772
+ const lt = text.indexOf("<", fromPos);
1773
+ if (lt === -1 || lt + 1 >= text.length) {
1774
+ return { kind: "eof", nextPos: text.length };
1775
+ }
1776
+ const next = text[lt + 1];
1777
+ const specialEnd = skipSpecialSegment(text, lt);
1778
+ if (specialEnd !== null) {
1779
+ return { kind: "special", nextPos: specialEnd };
1780
+ }
1781
+ if (next === "/") {
1782
+ const closing = consumeClosingTag(text, lt);
1783
+ let p = lt + 2;
1784
+ while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
1785
+ p += 1;
1786
+ }
1787
+ const nameStart = p;
1788
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
1789
+ p += 1;
1790
+ }
1791
+ const name = text.slice(nameStart, p);
1792
+ return { kind: "close", name, nextPos: closing.endPos };
1793
+ }
1794
+ const open = consumeOpenTag(text, lt);
1795
+ if (open === null) {
1796
+ return { kind: "eof", nextPos: text.length };
1797
+ }
1798
+ return {
1799
+ kind: "open",
1800
+ name: open.name,
1801
+ selfClosing: open.selfClosing,
1802
+ nextPos: open.nextPos
1803
+ };
1804
+ }
1805
+ function findToolCallsForName(text, toolName) {
1806
+ var _a;
1807
+ const toolCalls = [];
1808
+ let searchIndex = 0;
1809
+ while (searchIndex < text.length) {
1810
+ const startTag = `<${toolName}>`;
1811
+ const selfTag = `<${toolName}/>`;
1812
+ const openIdx = text.indexOf(startTag, searchIndex);
1813
+ const selfIdx = text.indexOf(selfTag, searchIndex);
1814
+ if (openIdx === -1 && selfIdx === -1) {
1815
+ break;
1816
+ }
1817
+ const tagStart = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx) ? selfIdx : openIdx;
1818
+ const isSelfClosing = tagStart === selfIdx;
1819
+ if (isSelfClosing) {
1820
+ const endIndex = tagStart + selfTag.length;
1821
+ const segment = text.substring(tagStart, endIndex);
1822
+ toolCalls.push({
1823
+ toolName,
1824
+ startIndex: tagStart,
1825
+ endIndex,
1826
+ content: "",
1827
+ segment
1828
+ });
1829
+ searchIndex = endIndex;
1830
+ continue;
1831
+ }
1832
+ const contentStart = tagStart + startTag.length;
1833
+ const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
1834
+ if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
1835
+ const segment = text.substring(tagStart, fullTagEnd);
1836
+ const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
1837
+ toolCalls.push({
1838
+ toolName,
1839
+ startIndex: tagStart,
1840
+ endIndex: fullTagEnd,
1841
+ content: inner,
1842
+ segment
1843
+ });
1844
+ searchIndex = fullTagEnd;
1845
+ } else {
1846
+ searchIndex = contentStart;
1847
+ }
1848
+ }
1849
+ return toolCalls;
1850
+ }
1851
+ function findToolCalls(text, toolNames) {
1852
+ const toolCalls = [];
1853
+ for (const toolName of toolNames) {
1854
+ const calls = findToolCallsForName(text, toolName);
1855
+ toolCalls.push(...calls);
1856
+ }
1857
+ return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
1858
+ }
1859
+ function findEarliestToolTag(buffer, toolNames) {
1860
+ let bestIndex = -1;
1861
+ let bestName = "";
1862
+ let bestSelfClosing = false;
1863
+ if (toolNames.length > 0) {
1864
+ for (const name of toolNames) {
1865
+ const openTag = `<${name}>`;
1866
+ const selfTag = `<${name}/>`;
1867
+ const idxOpen = buffer.indexOf(openTag);
1868
+ const idxSelf = buffer.indexOf(selfTag);
1869
+ if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
1870
+ bestIndex = idxOpen;
1871
+ bestName = name;
1872
+ bestSelfClosing = false;
1873
+ }
1874
+ if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
1875
+ bestIndex = idxSelf;
1876
+ bestName = name;
1877
+ bestSelfClosing = true;
1878
+ }
1879
+ }
1880
+ }
1881
+ return { index: bestIndex, name: bestName, selfClosing: bestSelfClosing };
1882
+ }
1883
+ function createFlushTextHandler(getCurrentTextId, setCurrentTextId, getHasEmittedTextStart, setHasEmittedTextStart) {
1884
+ return (controller, text) => {
1885
+ const content = text;
1886
+ if (content) {
1887
+ if (!getCurrentTextId()) {
1888
+ const newId = generateId();
1889
+ setCurrentTextId(newId);
1890
+ controller.enqueue({
1891
+ type: "text-start",
1892
+ id: newId
1893
+ });
1894
+ setHasEmittedTextStart(true);
1895
+ }
1896
+ controller.enqueue({
1897
+ type: "text-delta",
1898
+ id: getCurrentTextId(),
1899
+ textDelta: content,
1900
+ delta: content
1901
+ });
1902
+ }
1903
+ const currentTextId = getCurrentTextId();
1904
+ if (currentTextId && !text) {
1905
+ if (getHasEmittedTextStart()) {
1906
+ controller.enqueue({
1907
+ type: "text-end",
1908
+ id: currentTextId
1909
+ });
1910
+ setHasEmittedTextStart(false);
1911
+ }
1912
+ setCurrentTextId(null);
1913
+ }
1914
+ };
1915
+ }
1916
+ function processToolCallInBuffer(params) {
1917
+ const {
1918
+ buffer,
1919
+ currentToolCall,
1920
+ tools,
1921
+ options,
1922
+ controller,
1923
+ flushText,
1924
+ setBuffer,
1925
+ pipelineConfig,
1926
+ maxReparses
1927
+ } = params;
1928
+ const endTag = `</${currentToolCall.name}>`;
1929
+ const endIdx = buffer.indexOf(endTag);
1930
+ if (endIdx === -1) {
1931
+ return { buffer, currentToolCall, shouldBreak: true };
1932
+ }
1933
+ const content = buffer.substring(0, endIdx);
1934
+ setBuffer(buffer.substring(endIdx + endTag.length));
1935
+ handleStreamingToolCallEnd({
1936
+ toolContent: content,
1937
+ currentToolCall,
1938
+ tools,
1939
+ options,
1940
+ ctrl: controller,
1941
+ flushText,
1942
+ pipelineConfig,
1943
+ maxReparses
1944
+ });
1945
+ return {
1946
+ buffer: buffer.substring(endIdx + endTag.length),
1947
+ currentToolCall: null,
1948
+ shouldBreak: false
1949
+ };
1950
+ }
1951
+ function processNoToolCallInBuffer(params) {
1952
+ const {
1953
+ buffer,
1954
+ toolNames,
1955
+ controller,
1956
+ flushText,
1957
+ tools,
1958
+ options,
1959
+ pipelineConfig,
1960
+ maxReparses,
1961
+ setBuffer
1962
+ } = params;
1963
+ const {
1964
+ index: earliestStartTagIndex,
1965
+ name: earliestToolName,
1966
+ selfClosing
1967
+ } = findEarliestToolTag(buffer, toolNames);
1968
+ if (earliestStartTagIndex === -1) {
1969
+ const maxTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
1970
+ const tail = Math.max(0, maxTagLen - 1);
1971
+ const safeLen = Math.max(0, buffer.length - tail);
1972
+ if (safeLen > 0) {
1973
+ flushText(controller, buffer.slice(0, safeLen));
1974
+ setBuffer(buffer.slice(safeLen));
1975
+ }
1976
+ return {
1977
+ buffer: buffer.slice(safeLen),
1978
+ currentToolCall: null,
1979
+ shouldBreak: true,
1980
+ shouldContinue: false
1981
+ };
1982
+ }
1983
+ flushText(controller, buffer.substring(0, earliestStartTagIndex));
1984
+ if (selfClosing) {
1985
+ const selfTag = `<${earliestToolName}/>`;
1986
+ const newBuffer2 = buffer.substring(earliestStartTagIndex + selfTag.length);
1987
+ setBuffer(newBuffer2);
1988
+ handleStreamingToolCallEnd({
1989
+ toolContent: "",
1990
+ currentToolCall: { name: earliestToolName, content: "" },
1991
+ tools,
1992
+ options,
1993
+ ctrl: controller,
1994
+ flushText,
1995
+ pipelineConfig,
1996
+ maxReparses
1997
+ });
1998
+ return {
1999
+ buffer: newBuffer2,
2000
+ currentToolCall: null,
2001
+ shouldBreak: false,
2002
+ shouldContinue: false
2003
+ };
2004
+ }
2005
+ const startTag = `<${earliestToolName}>`;
2006
+ const newBuffer = buffer.substring(earliestStartTagIndex + startTag.length);
2007
+ setBuffer(newBuffer);
2008
+ return {
2009
+ buffer: newBuffer,
2010
+ currentToolCall: { name: earliestToolName, content: "" },
2011
+ shouldBreak: false,
2012
+ shouldContinue: true
2013
+ };
2014
+ }
2015
+ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, setCurrentToolCall, tools, options, toolNames, flushText, pipelineConfig, maxReparses) {
2016
+ return (controller) => {
2017
+ while (true) {
2018
+ const currentToolCall = getCurrentToolCall();
2019
+ if (currentToolCall) {
2020
+ const result = processToolCallInBuffer({
2021
+ buffer: getBuffer(),
2022
+ currentToolCall,
2023
+ tools,
2024
+ options,
2025
+ controller,
2026
+ flushText,
2027
+ setBuffer,
2028
+ pipelineConfig,
2029
+ maxReparses
2030
+ });
2031
+ setBuffer(result.buffer);
2032
+ setCurrentToolCall(result.currentToolCall);
2033
+ if (result.shouldBreak) {
2034
+ break;
2035
+ }
2036
+ } else {
2037
+ const result = processNoToolCallInBuffer({
2038
+ buffer: getBuffer(),
2039
+ toolNames,
2040
+ controller,
2041
+ flushText,
2042
+ tools,
2043
+ options,
2044
+ pipelineConfig,
2045
+ maxReparses,
2046
+ setBuffer
2047
+ });
2048
+ setBuffer(result.buffer);
2049
+ setCurrentToolCall(result.currentToolCall);
2050
+ if (result.shouldBreak) {
2051
+ break;
2052
+ }
2053
+ if (result.shouldContinue) {
2054
+ continue;
2055
+ }
2056
+ break;
2057
+ }
2058
+ }
2059
+ };
2060
+ }
2061
+ var morphXmlProtocol = (protocolOptions) => {
2062
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2063
+ let pipelineConfig = protocolOptions == null ? void 0 : protocolOptions.pipeline;
2064
+ const maxReparses = protocolOptions == null ? void 0 : protocolOptions.maxReparses;
2065
+ if ((protocolOptions == null ? void 0 : protocolOptions.heuristics) && protocolOptions.heuristics.length > 0) {
2066
+ const heuristicsConfig = {
2067
+ preParse: [],
2068
+ fallbackReparse: [],
2069
+ postParse: []
2070
+ };
2071
+ for (const h of protocolOptions.heuristics) {
2072
+ if (h.phase === "pre-parse") {
2073
+ (_a = heuristicsConfig.preParse) == null ? void 0 : _a.push(h);
2074
+ } else if (h.phase === "fallback-reparse") {
2075
+ (_b = heuristicsConfig.fallbackReparse) == null ? void 0 : _b.push(h);
2076
+ } else if (h.phase === "post-parse") {
2077
+ (_c = heuristicsConfig.postParse) == null ? void 0 : _c.push(h);
2078
+ }
2079
+ }
2080
+ if (pipelineConfig) {
2081
+ pipelineConfig = {
2082
+ preParse: [
2083
+ ...(_d = pipelineConfig.preParse) != null ? _d : [],
2084
+ ...(_e = heuristicsConfig.preParse) != null ? _e : []
2085
+ ],
2086
+ fallbackReparse: [
2087
+ ...(_f = pipelineConfig.fallbackReparse) != null ? _f : [],
2088
+ ...(_g = heuristicsConfig.fallbackReparse) != null ? _g : []
2089
+ ],
2090
+ postParse: [
2091
+ ...(_h = pipelineConfig.postParse) != null ? _h : [],
2092
+ ...(_i = heuristicsConfig.postParse) != null ? _i : []
2093
+ ]
2094
+ };
2095
+ } else {
2096
+ pipelineConfig = heuristicsConfig;
2097
+ }
2098
+ }
2099
+ return {
2100
+ formatTools({ tools, toolSystemPromptTemplate }) {
2101
+ const toolsForPrompt = (tools || []).map((tool) => ({
2102
+ name: tool.name,
2103
+ description: tool.description,
2104
+ parameters: (0, import_rxml2.unwrapJsonSchema)(tool.inputSchema)
2105
+ }));
2106
+ return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
2107
+ },
2108
+ formatToolCall(toolCall) {
2109
+ let args = {};
2110
+ try {
2111
+ args = JSON.parse(toolCall.input);
2112
+ } catch (e) {
2113
+ args = toolCall.input;
2114
+ }
2115
+ return (0, import_rxml2.stringify)(toolCall.toolName, args, {
2116
+ suppressEmptyNode: false,
2117
+ format: false
2118
+ });
2119
+ },
2120
+ formatToolResponse(toolResult) {
2121
+ let result = toolResult.result;
2122
+ if (result && typeof result === "object" && "type" in result && result.type === "json" && "value" in result) {
2123
+ result = result.value;
2124
+ }
2125
+ const xml = (0, import_rxml2.stringify)(
2126
+ "tool_response",
2127
+ {
2128
+ tool_name: toolResult.toolName,
2129
+ result
2130
+ },
2131
+ { declaration: false }
2132
+ );
2133
+ return xml;
2134
+ },
2135
+ parseGeneratedText({ text, tools, options }) {
2136
+ const toolNames = tools.map((t) => t.name).filter(Boolean);
2137
+ if (toolNames.length === 0) {
2138
+ return [{ type: "text", text }];
2139
+ }
2140
+ const processedElements = [];
2141
+ let currentIndex = 0;
2142
+ const toolCalls = findToolCalls(text, toolNames);
2143
+ for (const tc of toolCalls) {
2144
+ if (tc.startIndex > currentIndex) {
2145
+ processedElements.push({
2146
+ type: "text",
2147
+ text: text.substring(currentIndex, tc.startIndex)
2148
+ });
2149
+ }
2150
+ processToolCallWithPipeline({
2151
+ toolCall: tc,
2152
+ tools,
2153
+ options,
2154
+ text,
2155
+ processedElements,
2156
+ pipelineConfig,
2157
+ maxReparses
2158
+ });
2159
+ currentIndex = tc.endIndex;
2160
+ }
2161
+ if (currentIndex < text.length) {
2162
+ processedElements.push({
2163
+ type: "text",
2164
+ text: text.substring(currentIndex)
2165
+ });
2166
+ }
2167
+ return processedElements;
2168
+ },
2169
+ createStreamParser({ tools, options }) {
2170
+ const toolNames = tools.map((t) => t.name).filter(Boolean);
2171
+ let buffer = "";
2172
+ let currentToolCall = null;
2173
+ let currentTextId = null;
2174
+ let hasEmittedTextStart = false;
2175
+ const flushText = createFlushTextHandler(
2176
+ () => currentTextId,
2177
+ (newId) => {
2178
+ currentTextId = newId;
2179
+ },
2180
+ () => hasEmittedTextStart,
2181
+ (value) => {
2182
+ hasEmittedTextStart = value;
2183
+ }
2184
+ );
2185
+ const processBuffer = createProcessBufferHandler(
2186
+ () => buffer,
2187
+ (newBuffer) => {
2188
+ buffer = newBuffer;
2189
+ },
2190
+ () => currentToolCall,
2191
+ (newToolCall) => {
2192
+ currentToolCall = newToolCall;
2193
+ },
2194
+ tools,
2195
+ options,
2196
+ toolNames,
2197
+ flushText,
2198
+ pipelineConfig,
2199
+ maxReparses
2200
+ );
2201
+ return new TransformStream({
2202
+ transform(chunk, controller) {
2203
+ var _a2, _b2;
2204
+ if (chunk.type !== "text-delta") {
2205
+ if (buffer) {
2206
+ flushText(controller, buffer);
2207
+ buffer = "";
2208
+ }
2209
+ controller.enqueue(chunk);
2210
+ return;
2211
+ }
2212
+ const textContent = (_b2 = (_a2 = chunk.textDelta) != null ? _a2 : chunk.delta) != null ? _b2 : "";
2213
+ buffer += textContent;
2214
+ processBuffer(controller);
2215
+ },
2216
+ flush(controller) {
2217
+ if (currentToolCall) {
2218
+ const unfinishedContent = `<${currentToolCall.name}>${currentToolCall.content || ""}${buffer}`;
2219
+ flushText(controller, unfinishedContent);
2220
+ buffer = "";
2221
+ currentToolCall = null;
2222
+ } else if (buffer) {
2223
+ flushText(controller, buffer);
2224
+ buffer = "";
2225
+ }
2226
+ if (currentTextId && hasEmittedTextStart) {
2227
+ controller.enqueue({
2228
+ type: "text-end",
2229
+ id: currentTextId
2230
+ });
2231
+ hasEmittedTextStart = false;
2232
+ currentTextId = null;
2233
+ }
2234
+ }
2235
+ });
2236
+ },
2237
+ extractToolCallSegments({ text, tools }) {
2238
+ const toolNames = tools.map((t) => t.name).filter(Boolean);
2239
+ if (toolNames.length === 0) {
2240
+ return [];
2241
+ }
2242
+ return findToolCalls(text, toolNames).map((tc) => tc.segment);
2243
+ }
2244
+ };
2245
+ };
2246
+
2247
+ // src/core/protocols/tool-call-protocol.ts
2248
+ function isProtocolFactory(protocol) {
2249
+ return typeof protocol === "function";
2250
+ }
2251
+
2252
+ // src/v5/generate-handler.ts
2253
+ var import_rxml3 = require("@ai-sdk-tool/rxml");
2254
+
2255
+ // src/core/utils/on-error.ts
2256
+ function extractOnErrorOption(providerOptions) {
2257
+ var _a;
2258
+ if (providerOptions && typeof providerOptions === "object") {
2259
+ const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
2260
+ return onError ? { onError } : void 0;
2261
+ }
2262
+ return;
2263
+ }
2264
+
2265
+ // src/core/utils/provider-options.ts
2266
+ var originalToolsSchema = {
2267
+ encode: encodeOriginalTools,
2268
+ decode: decodeOriginalTools
2269
+ };
2270
+ function encodeOriginalTools(tools) {
2271
+ return (tools == null ? void 0 : tools.map((t) => ({
2272
+ name: t.name,
2273
+ inputSchema: JSON.stringify(t.inputSchema)
2274
+ }))) || [];
2275
+ }
2276
+ function decodeOriginalTools(originalTools) {
2277
+ if (!originalTools) {
2278
+ return [];
2279
+ }
2280
+ return originalTools.map(
2281
+ (t) => ({
2282
+ type: "function",
2283
+ name: t.name,
2284
+ inputSchema: JSON.parse(t.inputSchema)
2285
+ })
2286
+ );
2287
+ }
2288
+
2289
+ // src/v5/generate-handler.ts
2290
+ function parseContent(content, protocol, tools, providerOptions) {
2291
+ const parsed = content.flatMap((contentItem) => {
2292
+ if (contentItem.type !== "text") {
2293
+ return [contentItem];
2294
+ }
2295
+ return protocol.parseGeneratedText({
2296
+ text: contentItem.text,
2297
+ tools,
2298
+ options: {
2299
+ ...extractOnErrorOption(providerOptions),
2300
+ ...(providerOptions == null ? void 0 : providerOptions.toolCallMiddleware) || {}
2301
+ }
2302
+ });
2303
+ });
2304
+ return parsed.map((part) => {
2305
+ var _a, _b;
2306
+ if (part.type !== "tool-call") {
2307
+ return part;
2308
+ }
2309
+ const tc = part;
2310
+ let args = {};
2311
+ if (typeof tc.input === "string") {
2312
+ try {
2313
+ args = JSON.parse(tc.input);
2314
+ } catch (e) {
2315
+ return part;
2316
+ }
2317
+ } else {
2318
+ args = (_a = tc.input) != null ? _a : {};
2319
+ }
2320
+ const schema = (_b = tools.find(
2321
+ (t) => t.name === tc.toolName
2322
+ )) == null ? void 0 : _b.inputSchema;
2323
+ const coerced = (0, import_rxml3.coerceBySchema)(args, schema);
2324
+ return {
2325
+ ...part,
2326
+ input: coerced != null ? coerced : {}
2327
+ };
2328
+ });
2329
+ }
2330
+ async function wrapGenerateV5({
2331
+ protocol,
2332
+ doGenerate,
2333
+ params
2334
+ }) {
2335
+ var _a, _b;
2336
+ const tools = originalToolsSchema.decode(
2337
+ (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
2338
+ );
2339
+ const result = await doGenerate();
2340
+ if (!result.content || result.content.length === 0) {
2341
+ return result;
2342
+ }
2343
+ const newContent = parseContent(
2344
+ result.content,
2345
+ protocol,
2346
+ tools,
2347
+ params.providerOptions
2348
+ );
2349
+ return {
2350
+ ...result,
2351
+ content: newContent
2352
+ };
2353
+ }
2354
+
2355
+ // src/v5/stream-handler.ts
2356
+ function processPartToV2(p, state, controller) {
2357
+ const partAny = p;
2358
+ const partId = partAny.id || partAny.toolCallId || generateId();
2359
+ switch (p.type) {
2360
+ case "text-delta": {
2361
+ if (!state.textStarted.has(partId)) {
2362
+ controller.enqueue({ type: "text-start", id: partId });
2363
+ state.textStarted.add(partId);
2364
+ }
2365
+ controller.enqueue({
2366
+ type: "text-delta",
2367
+ id: partId,
2368
+ delta: p.textDelta
2369
+ });
2370
+ break;
2371
+ }
2372
+ case "tool-call": {
2373
+ const v2Id = p.toolCallId || `call-${state.callCount++}`;
2374
+ if (!state.toolStarted.has(v2Id)) {
2375
+ controller.enqueue({
2376
+ type: "tool-input-start",
2377
+ id: v2Id,
2378
+ toolName: p.toolName
2379
+ });
2380
+ state.toolStarted.add(v2Id);
2381
+ }
2382
+ controller.enqueue({
2383
+ type: "tool-call",
2384
+ toolCallId: v2Id,
2385
+ toolName: p.toolName,
2386
+ input: typeof p.input === "string" ? JSON.parse(p.input) : p.input
2387
+ });
2388
+ break;
2389
+ }
2390
+ case "finish": {
2391
+ for (const id of state.textStarted) {
2392
+ controller.enqueue({ type: "text-end", id });
2393
+ }
2394
+ state.textStarted.clear();
2395
+ controller.enqueue(p);
2396
+ break;
2397
+ }
2398
+ default: {
2399
+ controller.enqueue(p);
2400
+ }
2401
+ }
2402
+ }
2403
+ function createV5Transformer() {
2404
+ const state = {
2405
+ textStarted: /* @__PURE__ */ new Set(),
2406
+ toolStarted: /* @__PURE__ */ new Set(),
2407
+ callCount: 0
2408
+ };
2409
+ return new TransformStream({
2410
+ transform(part, controller) {
2411
+ processPartToV2(part, state, controller);
2412
+ }
2413
+ });
2414
+ }
2415
+ async function wrapStreamV5({
2416
+ protocol,
2417
+ doStream,
2418
+ params
2419
+ }) {
2420
+ var _a, _b, _c;
2421
+ const tools = originalToolsSchema.decode(
2422
+ (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
2423
+ );
2424
+ const options = ((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) || {};
2425
+ const { stream } = await doStream();
2426
+ const coreInput = stream.pipeThrough(
2427
+ new TransformStream({
2428
+ transform(part, controller) {
2429
+ const p = part;
2430
+ if (p.type === "text-delta") {
2431
+ controller.enqueue({
2432
+ type: "text-delta",
2433
+ id: p.id,
2434
+ textDelta: p.delta || p.textDelta || ""
2435
+ });
2436
+ } else {
2437
+ controller.enqueue(p);
2438
+ }
2439
+ }
2440
+ })
2441
+ );
2442
+ const parsedStream = coreInput.pipeThrough(
2443
+ protocol.createStreamParser({
2444
+ tools,
2445
+ options
2446
+ })
2447
+ );
2448
+ return {
2449
+ stream: parsedStream.pipeThrough(createV5Transformer())
2450
+ };
2451
+ }
2452
+
2453
+ // src/core/utils/dynamic-tool-schema.ts
2454
+ function createDynamicIfThenElseSchema(tools) {
2455
+ let currentSchema = {};
2456
+ const toolNames = [];
2457
+ for (let i = tools.length - 1; i >= 0; i -= 1) {
2458
+ const tool = tools[i];
2459
+ if (tool.type === "provider") {
2460
+ throw new Error(
2461
+ "Provider tools are not supported by this middleware. Please use function tools."
2462
+ );
2463
+ }
2464
+ toolNames.unshift(tool.name);
2465
+ const toolCondition = {
2466
+ if: {
2467
+ properties: {
2468
+ name: {
2469
+ const: tool.name
2470
+ }
2471
+ },
2472
+ required: ["name"]
2473
+ },
2474
+ // biome-ignore lint/suspicious/noThenProperty: JSON Schema uses 'then' as a keyword
2475
+ then: {
2476
+ properties: {
2477
+ name: {
2478
+ const: tool.name
2479
+ },
2480
+ arguments: tool.inputSchema
2481
+ },
2482
+ required: ["name", "arguments"]
2483
+ }
2484
+ };
2485
+ if (Object.keys(currentSchema).length > 0) {
2486
+ toolCondition.else = currentSchema;
2487
+ }
2488
+ currentSchema = toolCondition;
2489
+ }
2490
+ return {
2491
+ type: "object",
2492
+ // Explicitly specify type as "object"
2493
+ properties: {
2494
+ name: {
2495
+ type: "string",
2496
+ description: "Name of the tool to call",
2497
+ enum: toolNames
2498
+ },
2499
+ arguments: {
2500
+ type: "object",
2501
+ // By default, arguments is also specified as object type
2502
+ description: "Argument object to be passed to the tool"
2503
+ }
2504
+ },
2505
+ required: ["name", "arguments"],
2506
+ ...currentSchema
2507
+ };
2508
+ }
2509
+
2510
+ // src/core/utils/type-guards.ts
2511
+ function isToolCallContent(content) {
2512
+ return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
2513
+ (typeof content.input === "string" || typeof content.input === "object");
2514
+ }
2515
+
2516
+ // src/v5/transform-handler.ts
2517
+ function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
2518
+ const systemIndex = processedPrompt.findIndex((m) => m.role === "system");
2519
+ if (systemIndex !== -1) {
2520
+ const existing = processedPrompt[systemIndex].content;
2521
+ let existingText = "";
2522
+ if (typeof existing === "string") {
2523
+ existingText = existing;
2524
+ } else if (Array.isArray(existing)) {
2525
+ existingText = existing.map((p) => {
2526
+ var _a;
2527
+ return (p == null ? void 0 : p.type) === "text" ? (_a = p.text) != null ? _a : "" : "";
2528
+ }).filter(Boolean).join("\n");
2529
+ } else {
2530
+ existingText = String(existing != null ? existing : "");
2531
+ }
2532
+ const mergedContent = placement === "first" ? `${systemPrompt}
2533
+
2534
+ ${existingText}` : `${existingText}
2535
+
2536
+ ${systemPrompt}`;
2537
+ return processedPrompt.map(
2538
+ (m, idx) => idx === systemIndex ? {
2539
+ ...m,
2540
+ content: mergedContent
2541
+ } : m
2542
+ );
2543
+ }
2544
+ if (placement === "first") {
2545
+ return [
2546
+ {
2547
+ role: "system",
2548
+ content: systemPrompt
2549
+ },
2550
+ ...processedPrompt
2551
+ ];
2552
+ }
2553
+ return [
2554
+ ...processedPrompt,
2555
+ {
2556
+ role: "system",
2557
+ content: systemPrompt
2558
+ }
2559
+ ];
2560
+ }
2561
+ function processAssistantContent(content, resolvedProtocol, providerOptions) {
2562
+ var _a;
2563
+ const newContent = [];
2564
+ for (const item of content) {
2565
+ if (isToolCallContent(item)) {
2566
+ newContent.push({
2567
+ type: "text",
2568
+ text: resolvedProtocol.formatToolCall(item)
2569
+ });
2570
+ } else if (item.type === "text") {
2571
+ newContent.push(item);
2572
+ } else if (item.type === "reasoning") {
2573
+ newContent.push(item);
2574
+ } else {
2575
+ const options = extractOnErrorOption(providerOptions);
2576
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
2577
+ options,
2578
+ "tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
2579
+ { content: item }
2580
+ );
2581
+ newContent.push({
2582
+ type: "text",
2583
+ text: JSON.stringify(item)
2584
+ });
2585
+ }
2586
+ }
2587
+ const onlyText = newContent.every((c) => c.type === "text");
2588
+ return onlyText ? [
2589
+ {
2590
+ type: "text",
2591
+ text: newContent.map((c) => c.text).join("\n")
2592
+ }
2593
+ ] : newContent;
2594
+ }
2595
+ function processMessage(message, resolvedProtocol, providerOptions) {
2596
+ if (message.role === "assistant") {
2597
+ const content = Array.isArray(message.content) ? message.content : [{ type: "text", text: message.content }];
2598
+ const condensedContent = processAssistantContent(
2599
+ content,
2600
+ resolvedProtocol,
2601
+ providerOptions
2602
+ );
2603
+ return {
2604
+ ...message,
2605
+ content: condensedContent
2606
+ };
2607
+ }
2608
+ if (message.role === "tool") {
2609
+ const toolResultParts = message.content.filter(
2610
+ (part) => part.type === "tool-result"
2611
+ );
2612
+ return {
2613
+ role: "user",
2614
+ content: [
2615
+ {
2616
+ type: "text",
2617
+ text: toolResultParts.map(
2618
+ (toolResult) => {
2619
+ var _a, _b;
2620
+ return resolvedProtocol.formatToolResponse({
2621
+ ...toolResult,
2622
+ result: (_b = (_a = toolResult.result) != null ? _a : toolResult.content) != null ? _b : toolResult.output
2623
+ });
2624
+ }
2625
+ ).join("\n")
2626
+ }
2627
+ ]
2628
+ };
2629
+ }
2630
+ return message;
2631
+ }
2632
+ function transformParamsV5({
2633
+ params,
2634
+ protocol,
2635
+ toolSystemPromptTemplate,
2636
+ placement = "first"
2637
+ }) {
2638
+ var _a, _b, _c, _d, _e;
2639
+ const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
2640
+ const functionTools = ((_a = params.tools) != null ? _a : []).filter(
2641
+ (t) => t.type === "function"
2642
+ );
2643
+ const systemPrompt = resolvedProtocol.formatTools({
2644
+ tools: functionTools,
2645
+ toolSystemPromptTemplate
2646
+ });
2647
+ const prompt = (_b = params.prompt) != null ? _b : [];
2648
+ const processedPrompt = prompt.map(
2649
+ (message) => processMessage(
2650
+ message,
2651
+ resolvedProtocol,
2652
+ extractOnErrorOption(params.providerOptions)
2653
+ )
2654
+ );
2655
+ const finalPrompt = buildFinalPrompt(
2656
+ systemPrompt,
2657
+ processedPrompt,
2658
+ placement
2659
+ );
2660
+ const baseReturnParams = {
2661
+ ...params,
2662
+ prompt: finalPrompt,
2663
+ tools: [],
2664
+ toolChoice: void 0,
2665
+ providerOptions: {
2666
+ ...params.providerOptions || {},
2667
+ toolCallMiddleware: {
2668
+ ...((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) || {},
2669
+ originalTools: originalToolsSchema.encode(functionTools)
2670
+ }
2671
+ }
2672
+ };
2673
+ if (((_d = params.toolChoice) == null ? void 0 : _d.type) === "tool") {
2674
+ const selectedToolName = params.toolChoice.toolName;
2675
+ const selectedTool = functionTools.find(
2676
+ (t) => t.name === selectedToolName
2677
+ );
2678
+ if (selectedTool) {
2679
+ return {
2680
+ ...baseReturnParams,
2681
+ responseFormat: {
2682
+ type: "json",
2683
+ schema: {
2684
+ type: "object",
2685
+ properties: {
2686
+ name: { const: selectedTool.name },
2687
+ arguments: selectedTool.inputSchema
2688
+ },
2689
+ required: ["name", "arguments"]
2690
+ }
2691
+ },
2692
+ providerOptions: {
2693
+ ...baseReturnParams.providerOptions,
2694
+ toolCallMiddleware: {
2695
+ ...baseReturnParams.providerOptions.toolCallMiddleware,
2696
+ toolChoice: params.toolChoice
2697
+ }
2698
+ }
2699
+ };
2700
+ }
2701
+ }
2702
+ if (((_e = params.toolChoice) == null ? void 0 : _e.type) === "required") {
2703
+ return {
2704
+ ...baseReturnParams,
2705
+ responseFormat: {
2706
+ type: "json",
2707
+ schema: createDynamicIfThenElseSchema(functionTools)
2708
+ },
2709
+ providerOptions: {
2710
+ ...baseReturnParams.providerOptions,
2711
+ toolCallMiddleware: {
2712
+ ...baseReturnParams.providerOptions.toolCallMiddleware,
2713
+ toolChoice: { type: "required" }
2714
+ }
2715
+ }
2716
+ };
2717
+ }
2718
+ return baseReturnParams;
2719
+ }
2720
+
2721
+ // src/v5/tool-call-middleware.ts
2722
+ function createToolMiddlewareV5({
2723
+ protocol,
2724
+ toolSystemPromptTemplate,
2725
+ placement = "last"
2726
+ }) {
2727
+ const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
2728
+ return {
2729
+ middlewareVersion: "v2",
2730
+ wrapStream: (args) => wrapStreamV5({
2731
+ protocol: resolvedProtocol,
2732
+ doStream: args.doStream,
2733
+ params: args.params
2734
+ }),
2735
+ wrapGenerate: (args) => wrapGenerateV5({
2736
+ protocol: resolvedProtocol,
2737
+ doGenerate: args.doGenerate,
2738
+ params: args.params
2739
+ }),
2740
+ transformParams: (args) => transformParamsV5({
2741
+ params: args.params,
2742
+ protocol: resolvedProtocol,
2743
+ toolSystemPromptTemplate,
2744
+ placement
2745
+ })
2746
+ };
2747
+ }
2748
+
2749
+ // src/v5/index.ts
2750
+ var gemmaToolMiddleware = createToolMiddlewareV5({
2751
+ protocol: jsonMixProtocol({
2752
+ toolCallStart: "```tool_call\n",
2753
+ toolCallEnd: "\n```",
2754
+ toolResponseStart: "```tool_response\n",
2755
+ toolResponseEnd: "\n```"
2756
+ }),
2757
+ toolSystemPromptTemplate(tools) {
2758
+ return `You have access to functions. If you decide to invoke any of the function(s),
2759
+ you MUST put it in the format of markdown code fence block with the language name of tool_call , e.g.
2760
+ \`\`\`tool_call
2761
+ {'name': <function-name>, 'arguments': <args-dict>}
2762
+ \`\`\`
2763
+ You SHOULD NOT include any other text in the response if you call a function
2764
+ ${tools}`;
2765
+ }
2766
+ });
2767
+ var hermesToolMiddleware = createToolMiddlewareV5({
2768
+ protocol: jsonMixProtocol,
2769
+ toolSystemPromptTemplate(tools) {
2770
+ return `You are a function calling AI model.
2771
+ You are provided with function signatures within <tools></tools> XML tags.
2772
+ You may call one or more functions to assist with the user query.
2773
+ Don't make assumptions about what values to plug into functions.
2774
+ Here are the available tools: <tools>${tools}</tools>
2775
+ Use the following pydantic model json schema for each tool call you will make: {"title": "FunctionCall", "type": "object", "properties": {"arguments": {"title": "Arguments", "type": "object"}, "name": {"title": "Name", "type": "string"}}, "required": ["arguments", "name"]}
2776
+ For each function call return a json object with function name and arguments within <tool_call></tool_call> XML tags as follows:
2777
+ <tool_call>
2778
+ {"name": "<function-name>", "arguments": <args-dict>}
2779
+ </tool_call>`;
2780
+ }
2781
+ });
2782
+ var morphXmlToolMiddleware = createToolMiddlewareV5({
2783
+ protocol: morphXmlProtocol,
2784
+ placement: "last",
2785
+ toolSystemPromptTemplate(tools) {
2786
+ return `# Tools
2787
+
2788
+ You may call one or more functions to assist with the user query.
2789
+
2790
+ You are provided with function signatures within <tools></tools> XML tags:
2791
+ <tools>${tools}</tools>
2792
+
2793
+ # Rules
2794
+ - Use exactly one XML element whose tag name is the function name.
2795
+ - Put each parameter as a child element.
2796
+ - Values must follow the schema exactly (numbers, arrays, objects, enums \u2192 copy as-is).
2797
+ - Do not add or remove functions or parameters.
2798
+ - Each required parameter must appear once.
2799
+ - Output nothing before or after the function call.
2800
+ - After calling a tool, you will receive a response in the format: <tool_response><tool_name>NAME</tool_name><result>RESULT</result></tool_response>. Use this result to answer the user.
2801
+
2802
+ # Example
2803
+ <get_weather>
2804
+ <location>New York</location>
2805
+ <unit>celsius</unit>
2806
+ </get_weather>`;
2807
+ }
2808
+ });
2809
+ // Annotate the CommonJS export names for ESM import in node:
2810
+ 0 && (module.exports = {
2811
+ createToolMiddleware,
2812
+ gemmaToolMiddleware,
2813
+ hermesToolMiddleware,
2814
+ morphXmlToolMiddleware
2815
+ });
2816
+ //# sourceMappingURL=v5.cjs.map