@ai-sdk-tool/parser 4.1.19 → 4.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-AELRIRO2.js → chunk-GAJX7HXU.js} +629 -103
- package/dist/chunk-GAJX7HXU.js.map +1 -0
- package/dist/{chunk-TLZV6QE3.js → chunk-NU2CVJEB.js} +2 -2
- package/dist/community.cjs +627 -101
- package/dist/community.cjs.map +1 -1
- package/dist/community.js +2 -2
- package/dist/index.cjs +632 -106
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/rxml.js +1 -1
- package/package.json +11 -11
- package/dist/chunk-AELRIRO2.js.map +0 -1
- /package/dist/{chunk-TLZV6QE3.js.map → chunk-NU2CVJEB.js.map} +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
parse as parse2,
|
|
6
6
|
stringify,
|
|
7
7
|
unescapeXml
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-NU2CVJEB.js";
|
|
9
9
|
import {
|
|
10
10
|
parse
|
|
11
11
|
} from "./chunk-KLP3RUJ2.js";
|
|
@@ -482,13 +482,312 @@ function shouldEmitRawToolCallTextOnError(options) {
|
|
|
482
482
|
}
|
|
483
483
|
|
|
484
484
|
// src/core/protocols/hermes-protocol.ts
|
|
485
|
+
var RJSON_IDENTIFIER_CHAR_REGEX = /[$a-zA-Z0-9_\-+.*?!|&%^/#\\]/;
|
|
486
|
+
var RJSON_NUMBER_TOKEN_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
487
|
+
function validateNonEmptyDelimiters(toolCallStart, toolCallEnd) {
|
|
488
|
+
if (toolCallStart.length === 0) {
|
|
489
|
+
throw new TypeError("hermesProtocol toolCallStart must not be empty");
|
|
490
|
+
}
|
|
491
|
+
if (toolCallEnd.length === 0) {
|
|
492
|
+
throw new TypeError("hermesProtocol toolCallEnd must not be empty");
|
|
493
|
+
}
|
|
494
|
+
return {};
|
|
495
|
+
}
|
|
496
|
+
function isRjsonIdentifierChar(ch) {
|
|
497
|
+
return ch != null && RJSON_IDENTIFIER_CHAR_REGEX.test(ch);
|
|
498
|
+
}
|
|
499
|
+
function isRjsonPropertyLikeDelimiter(startTag) {
|
|
500
|
+
const key = startTag.endsWith(":") ? startTag.slice(0, -1) : "";
|
|
501
|
+
return key.length > 0 && [...key].every((ch) => isRjsonIdentifierChar(ch));
|
|
502
|
+
}
|
|
503
|
+
function previousRjsonToken(json, index, minIndex = 0) {
|
|
504
|
+
let start = index - 1;
|
|
505
|
+
while (start >= minIndex && isRjsonIdentifierChar(json[start])) {
|
|
506
|
+
start -= 1;
|
|
507
|
+
}
|
|
508
|
+
return json.slice(start + 1, index);
|
|
509
|
+
}
|
|
510
|
+
function previousTokenAllowsComment(json, index, minIndex = 0) {
|
|
511
|
+
const previous = previousRjsonToken(json, index, minIndex);
|
|
512
|
+
if (previous.length === 0) {
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
return RJSON_NUMBER_TOKEN_REGEX.test(previous) || previous === "true" || previous === "false" || previous === "null";
|
|
516
|
+
}
|
|
517
|
+
function startsRjsonComment(json, index, minIndex = 0) {
|
|
518
|
+
if (!(json[index] === "/" && json[index + 1] === "/" || json[index] === "/" && json[index + 1] === "*")) {
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
if (index > minIndex && isRjsonIdentifierChar(json[index - 1])) {
|
|
522
|
+
return previousTokenAllowsComment(json, index, minIndex);
|
|
523
|
+
}
|
|
524
|
+
return true;
|
|
525
|
+
}
|
|
526
|
+
function hasNestedStartBoundary(segment, startIndex) {
|
|
527
|
+
const previous = segment[startIndex - 1];
|
|
528
|
+
return previous == null || WHITESPACE_JSON_REGEX.test(previous) || previous === "}";
|
|
529
|
+
}
|
|
530
|
+
function isLikelyNestedToolCallStart(segment, startIndex, startTag) {
|
|
531
|
+
if (isRjsonPropertyLikeDelimiter(startTag)) {
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
const jsonStart = skipJsonWhitespace(segment, startIndex + startTag.length);
|
|
535
|
+
return segment[jsonStart] === "{" && hasNestedStartBoundary(segment, startIndex);
|
|
536
|
+
}
|
|
537
|
+
function findToolCallBoundaryOutsideRjsonSyntax(text, scanFrom, startTag, endTag) {
|
|
538
|
+
let quote = null;
|
|
539
|
+
let esc = false;
|
|
540
|
+
let inLineComment = false;
|
|
541
|
+
let inBlockComment = false;
|
|
542
|
+
let lineCommentSawEndTag = false;
|
|
543
|
+
let blockCommentSawEndTag = false;
|
|
544
|
+
let nestedStartIndex = null;
|
|
545
|
+
for (let index = scanFrom; index < text.length; index += 1) {
|
|
546
|
+
const ch = text[index];
|
|
547
|
+
if (esc) {
|
|
548
|
+
esc = false;
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
551
|
+
if (quote !== null) {
|
|
552
|
+
if (ch === "\\") {
|
|
553
|
+
esc = true;
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
if (ch === quote) {
|
|
557
|
+
quote = null;
|
|
558
|
+
}
|
|
559
|
+
continue;
|
|
560
|
+
}
|
|
561
|
+
if (inLineComment) {
|
|
562
|
+
if (ch === "\n" || ch === "\r") {
|
|
563
|
+
inLineComment = false;
|
|
564
|
+
lineCommentSawEndTag = false;
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
if (text.startsWith(endTag, index)) {
|
|
568
|
+
lineCommentSawEndTag = true;
|
|
569
|
+
index += endTag.length - 1;
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
if (lineCommentSawEndTag && text.startsWith(startTag, index) && text[skipJsonWhitespace(text, index + startTag.length)] === "{") {
|
|
573
|
+
nestedStartIndex = index;
|
|
574
|
+
inLineComment = false;
|
|
575
|
+
lineCommentSawEndTag = false;
|
|
576
|
+
index += startTag.length - 1;
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
if (inBlockComment) {
|
|
582
|
+
if (ch === "*" && text[index + 1] === "/") {
|
|
583
|
+
inBlockComment = false;
|
|
584
|
+
blockCommentSawEndTag = false;
|
|
585
|
+
index += 1;
|
|
586
|
+
continue;
|
|
587
|
+
}
|
|
588
|
+
if (text.startsWith(endTag, index)) {
|
|
589
|
+
blockCommentSawEndTag = true;
|
|
590
|
+
index += endTag.length - 1;
|
|
591
|
+
continue;
|
|
592
|
+
}
|
|
593
|
+
if (blockCommentSawEndTag && text.startsWith(startTag, index) && text[skipJsonWhitespace(text, index + startTag.length)] === "{") {
|
|
594
|
+
nestedStartIndex = index;
|
|
595
|
+
inBlockComment = false;
|
|
596
|
+
blockCommentSawEndTag = false;
|
|
597
|
+
index += startTag.length - 1;
|
|
598
|
+
continue;
|
|
599
|
+
}
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
if (startsRjsonComment(text, index, scanFrom)) {
|
|
603
|
+
if (text[index + 1] === "/") {
|
|
604
|
+
inLineComment = true;
|
|
605
|
+
lineCommentSawEndTag = false;
|
|
606
|
+
index += 1;
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
if (text[index + 1] === "*") {
|
|
610
|
+
inBlockComment = true;
|
|
611
|
+
blockCommentSawEndTag = false;
|
|
612
|
+
index += 1;
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (text.startsWith(endTag, index)) {
|
|
617
|
+
return nestedStartIndex == null ? { kind: "end", endIdx: index } : { kind: "nested", endIdx: index, nestedStartIndex };
|
|
618
|
+
}
|
|
619
|
+
if (nestedStartIndex == null && text.startsWith(startTag, index) && isLikelyNestedToolCallStart(text, index, startTag)) {
|
|
620
|
+
nestedStartIndex = index;
|
|
621
|
+
index += startTag.length - 1;
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
if (ch === '"' || ch === "'") {
|
|
625
|
+
quote = ch;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return null;
|
|
629
|
+
}
|
|
630
|
+
function findNextToolCallSpan(text, searchFrom, startTag, endTag) {
|
|
631
|
+
const startIdx = text.indexOf(startTag, searchFrom);
|
|
632
|
+
if (startIdx === -1) {
|
|
633
|
+
return null;
|
|
634
|
+
}
|
|
635
|
+
const jsonStart = startIdx + startTag.length;
|
|
636
|
+
const boundary = findToolCallBoundaryOutsideRjsonSyntax(
|
|
637
|
+
text,
|
|
638
|
+
jsonStart,
|
|
639
|
+
startTag,
|
|
640
|
+
endTag
|
|
641
|
+
);
|
|
642
|
+
if (boundary == null) {
|
|
643
|
+
return { startIdx, found: false };
|
|
644
|
+
}
|
|
645
|
+
if (boundary.kind === "nested") {
|
|
646
|
+
return { startIdx, found: false };
|
|
647
|
+
}
|
|
648
|
+
return { startIdx, found: true, jsonStart, endIdx: boundary.endIdx };
|
|
649
|
+
}
|
|
485
650
|
function canonicalizeToolInput(argumentsValue) {
|
|
486
651
|
return JSON.stringify(argumentsValue != null ? argumentsValue : {});
|
|
487
652
|
}
|
|
653
|
+
var CHAR_CODE_BACKSLASH = 92;
|
|
654
|
+
var CHAR_CODE_QUOTE = 34;
|
|
655
|
+
var CHAR_CODE_LF = 10;
|
|
656
|
+
var CHAR_CODE_CR = 13;
|
|
657
|
+
var CHAR_CODE_TAB = 9;
|
|
658
|
+
var CHAR_CODE_SLASH = 47;
|
|
659
|
+
var CHAR_CODE_STAR = 42;
|
|
660
|
+
var CHAR_CODE_CONTROL_UPPER = 31;
|
|
661
|
+
var CHAR_CODE_SINGLE_QUOTE = 39;
|
|
662
|
+
function hasControlCharInString(json) {
|
|
663
|
+
let quote = null;
|
|
664
|
+
let esc = false;
|
|
665
|
+
for (let i = 0; i < json.length; i += 1) {
|
|
666
|
+
const code = json.charCodeAt(i);
|
|
667
|
+
if (esc) {
|
|
668
|
+
esc = false;
|
|
669
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
670
|
+
return true;
|
|
671
|
+
}
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
if (quote !== null && code === CHAR_CODE_BACKSLASH) {
|
|
675
|
+
esc = true;
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
if (quote !== null) {
|
|
679
|
+
if (code === quote) {
|
|
680
|
+
quote = null;
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
683
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
684
|
+
return true;
|
|
685
|
+
}
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_SLASH) {
|
|
689
|
+
i += 2;
|
|
690
|
+
while (i < json.length && json.charCodeAt(i) !== CHAR_CODE_LF && json.charCodeAt(i) !== CHAR_CODE_CR) {
|
|
691
|
+
i += 1;
|
|
692
|
+
}
|
|
693
|
+
continue;
|
|
694
|
+
}
|
|
695
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_STAR) {
|
|
696
|
+
i += 2;
|
|
697
|
+
while (i + 1 < json.length && !(json.charCodeAt(i) === CHAR_CODE_STAR && json.charCodeAt(i + 1) === CHAR_CODE_SLASH)) {
|
|
698
|
+
i += 1;
|
|
699
|
+
}
|
|
700
|
+
i += 1;
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
if (code === CHAR_CODE_QUOTE || code === CHAR_CODE_SINGLE_QUOTE) {
|
|
704
|
+
quote = code;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
709
|
+
function normalizeJsonStringCtrl(json) {
|
|
710
|
+
if (!hasControlCharInString(json)) {
|
|
711
|
+
return json;
|
|
712
|
+
}
|
|
713
|
+
const parts = [];
|
|
714
|
+
let chunkStart = 0;
|
|
715
|
+
let quote = null;
|
|
716
|
+
let esc = false;
|
|
717
|
+
const flushUpTo = (end) => {
|
|
718
|
+
if (chunkStart < end) {
|
|
719
|
+
parts.push(json.slice(chunkStart, end));
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
const escapeForCode = (code) => {
|
|
723
|
+
switch (code) {
|
|
724
|
+
case CHAR_CODE_LF:
|
|
725
|
+
return "\\n";
|
|
726
|
+
case CHAR_CODE_CR:
|
|
727
|
+
return "\\r";
|
|
728
|
+
case CHAR_CODE_TAB:
|
|
729
|
+
return "\\t";
|
|
730
|
+
default:
|
|
731
|
+
return `\\u${code.toString(16).padStart(4, "0")}`;
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
for (let i = 0; i < json.length; i += 1) {
|
|
735
|
+
const code = json.charCodeAt(i);
|
|
736
|
+
if (esc) {
|
|
737
|
+
esc = false;
|
|
738
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
739
|
+
flushUpTo(i - 1);
|
|
740
|
+
parts.push(escapeForCode(code));
|
|
741
|
+
chunkStart = i + 1;
|
|
742
|
+
}
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
745
|
+
if (quote !== null && code === CHAR_CODE_BACKSLASH) {
|
|
746
|
+
esc = true;
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
749
|
+
if (quote !== null) {
|
|
750
|
+
if (code === quote) {
|
|
751
|
+
quote = null;
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
754
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
755
|
+
flushUpTo(i);
|
|
756
|
+
parts.push(escapeForCode(code));
|
|
757
|
+
chunkStart = i + 1;
|
|
758
|
+
}
|
|
759
|
+
continue;
|
|
760
|
+
}
|
|
761
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_SLASH) {
|
|
762
|
+
i += 2;
|
|
763
|
+
while (i < json.length && json.charCodeAt(i) !== CHAR_CODE_LF && json.charCodeAt(i) !== CHAR_CODE_CR) {
|
|
764
|
+
i += 1;
|
|
765
|
+
}
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_STAR) {
|
|
769
|
+
i += 2;
|
|
770
|
+
while (i + 1 < json.length && !(json.charCodeAt(i) === CHAR_CODE_STAR && json.charCodeAt(i + 1) === CHAR_CODE_SLASH)) {
|
|
771
|
+
i += 1;
|
|
772
|
+
}
|
|
773
|
+
i += 1;
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
if (code === CHAR_CODE_QUOTE || code === CHAR_CODE_SINGLE_QUOTE) {
|
|
777
|
+
quote = code;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if (chunkStart < json.length) {
|
|
781
|
+
parts.push(json.slice(chunkStart));
|
|
782
|
+
}
|
|
783
|
+
return parts.join("");
|
|
784
|
+
}
|
|
488
785
|
function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
|
|
489
786
|
var _a;
|
|
490
787
|
try {
|
|
491
|
-
const parsedToolCall = parse(
|
|
788
|
+
const parsedToolCall = parse(
|
|
789
|
+
normalizeJsonStringCtrl(toolCallJson)
|
|
790
|
+
);
|
|
492
791
|
processedElements.push({
|
|
493
792
|
type: "tool-call",
|
|
494
793
|
toolCallId: generateToolCallId(),
|
|
@@ -496,6 +795,8 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
496
795
|
input: canonicalizeToolInput(parsedToolCall.arguments)
|
|
497
796
|
});
|
|
498
797
|
} catch (error) {
|
|
798
|
+
const salvagedToolName = extractStreamingToolCallProgress(toolCallJson).toolName;
|
|
799
|
+
const salvagedToolCallId = generateToolCallId();
|
|
499
800
|
logParseFailure({
|
|
500
801
|
phase: "generated-text",
|
|
501
802
|
reason: "Failed to parse tool call JSON segment",
|
|
@@ -505,24 +806,17 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
505
806
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
506
807
|
options,
|
|
507
808
|
"Could not process JSON tool call, keeping original text.",
|
|
508
|
-
{
|
|
809
|
+
{
|
|
810
|
+
toolCall: fullMatch,
|
|
811
|
+
error,
|
|
812
|
+
toolName: salvagedToolName,
|
|
813
|
+
toolCallId: salvagedToolCallId,
|
|
814
|
+
dropReason: "malformed-tool-call-body"
|
|
815
|
+
}
|
|
509
816
|
);
|
|
510
817
|
processedElements.push({ type: "text", text: fullMatch });
|
|
511
818
|
}
|
|
512
819
|
}
|
|
513
|
-
function processMatchedToolCall(context) {
|
|
514
|
-
const { match, text, currentIndex, processedElements, options } = context;
|
|
515
|
-
const startIndex = match.index;
|
|
516
|
-
const toolCallJson = match[1];
|
|
517
|
-
if (startIndex > currentIndex) {
|
|
518
|
-
const textSegment = text.slice(currentIndex, startIndex);
|
|
519
|
-
addTextSegment(textSegment, processedElements);
|
|
520
|
-
}
|
|
521
|
-
if (toolCallJson) {
|
|
522
|
-
processToolCallJson(toolCallJson, match[0], processedElements, options);
|
|
523
|
-
}
|
|
524
|
-
return startIndex + match[0].length;
|
|
525
|
-
}
|
|
526
820
|
var WHITESPACE_JSON_REGEX = /\s/;
|
|
527
821
|
function skipJsonWhitespace(text, fromIndex) {
|
|
528
822
|
let index = fromIndex;
|
|
@@ -789,7 +1083,9 @@ function canonicalizeArgumentsProgressInput(progress, toolName, tools) {
|
|
|
789
1083
|
return void 0;
|
|
790
1084
|
}
|
|
791
1085
|
try {
|
|
792
|
-
const parsedArguments = parse(
|
|
1086
|
+
const parsedArguments = parse(
|
|
1087
|
+
normalizeJsonStringCtrl(progress.argumentsText)
|
|
1088
|
+
);
|
|
793
1089
|
return stringifyToolInputWithSchema({
|
|
794
1090
|
toolName,
|
|
795
1091
|
args: parsedArguments,
|
|
@@ -849,14 +1145,16 @@ function closeTextBlock(state, controller) {
|
|
|
849
1145
|
}
|
|
850
1146
|
}
|
|
851
1147
|
function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer, tools, options) {
|
|
852
|
-
var _a;
|
|
1148
|
+
var _a, _b, _c, _d;
|
|
853
1149
|
if (!state.currentToolCallJson && trailingBuffer.length === 0) {
|
|
854
1150
|
state.isInsideToolCall = false;
|
|
855
1151
|
return;
|
|
856
1152
|
}
|
|
857
1153
|
if (state.currentToolCallJson) {
|
|
858
1154
|
try {
|
|
859
|
-
const parsedToolCall = parse(
|
|
1155
|
+
const parsedToolCall = parse(
|
|
1156
|
+
normalizeJsonStringCtrl(state.currentToolCallJson)
|
|
1157
|
+
);
|
|
860
1158
|
emitToolCallFromParsed(state, controller, parsedToolCall, tools);
|
|
861
1159
|
state.currentToolCallJson = "";
|
|
862
1160
|
state.isInsideToolCall = false;
|
|
@@ -888,11 +1186,19 @@ function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer
|
|
|
888
1186
|
id: errorId
|
|
889
1187
|
});
|
|
890
1188
|
}
|
|
1189
|
+
const streamingToolCallId = (_b = (_a = state.activeToolInput) == null ? void 0 : _a.id) != null ? _b : generateToolCallId();
|
|
1190
|
+
const streamingToolName = (_c = state.activeToolInput) == null ? void 0 : _c.toolName;
|
|
891
1191
|
closeToolInput(state, controller);
|
|
892
|
-
|
|
1192
|
+
const toolName = streamingToolName != null ? streamingToolName : state.currentToolCallJson ? extractStreamingToolCallProgress(state.currentToolCallJson).toolName : void 0;
|
|
1193
|
+
(_d = options == null ? void 0 : options.onError) == null ? void 0 : _d.call(
|
|
893
1194
|
options,
|
|
894
1195
|
shouldEmitRawFallback ? "Could not complete streaming JSON tool call at finish; emitting original text." : "Could not complete streaming JSON tool call at finish.",
|
|
895
|
-
{
|
|
1196
|
+
{
|
|
1197
|
+
toolCall: errorContent,
|
|
1198
|
+
toolCallId: streamingToolCallId,
|
|
1199
|
+
toolName,
|
|
1200
|
+
dropReason: "unfinished-tool-call"
|
|
1201
|
+
}
|
|
896
1202
|
);
|
|
897
1203
|
state.currentToolCallJson = "";
|
|
898
1204
|
state.isInsideToolCall = false;
|
|
@@ -937,14 +1243,18 @@ function publishText(text, state, controller, tools) {
|
|
|
937
1243
|
}
|
|
938
1244
|
}
|
|
939
1245
|
function emitToolCall(context) {
|
|
940
|
-
var _a;
|
|
1246
|
+
var _a, _b, _c, _d, _e;
|
|
941
1247
|
const { state, controller, toolCallStart, toolCallEnd, options, tools } = context;
|
|
942
1248
|
try {
|
|
943
|
-
const parsedToolCall = parse(
|
|
1249
|
+
const parsedToolCall = parse(
|
|
1250
|
+
normalizeJsonStringCtrl(state.currentToolCallJson)
|
|
1251
|
+
);
|
|
944
1252
|
emitToolCallFromParsed(state, controller, parsedToolCall, tools);
|
|
945
1253
|
} catch (error) {
|
|
946
1254
|
const errorContent = `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`;
|
|
947
1255
|
const shouldEmitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
1256
|
+
const streamingToolCallId = (_b = (_a = state.activeToolInput) == null ? void 0 : _a.id) != null ? _b : generateToolCallId();
|
|
1257
|
+
const streamingToolName = (_d = (_c = state.activeToolInput) == null ? void 0 : _c.toolName) != null ? _d : extractStreamingToolCallProgress(state.currentToolCallJson).toolName;
|
|
948
1258
|
logParseFailure({
|
|
949
1259
|
phase: "stream",
|
|
950
1260
|
reason: "Failed to parse streaming tool call JSON segment",
|
|
@@ -968,11 +1278,15 @@ function emitToolCall(context) {
|
|
|
968
1278
|
});
|
|
969
1279
|
}
|
|
970
1280
|
closeToolInput(state, controller);
|
|
971
|
-
(
|
|
1281
|
+
(_e = options == null ? void 0 : options.onError) == null ? void 0 : _e.call(
|
|
972
1282
|
options,
|
|
973
1283
|
shouldEmitRawFallback ? "Could not process streaming JSON tool call; emitting original text." : "Could not process streaming JSON tool call.",
|
|
974
1284
|
{
|
|
975
|
-
toolCall: errorContent
|
|
1285
|
+
toolCall: errorContent,
|
|
1286
|
+
error,
|
|
1287
|
+
toolCallId: streamingToolCallId,
|
|
1288
|
+
toolName: streamingToolName,
|
|
1289
|
+
dropReason: "malformed-tool-call-body"
|
|
976
1290
|
}
|
|
977
1291
|
);
|
|
978
1292
|
}
|
|
@@ -989,24 +1303,118 @@ function processTagMatch(context) {
|
|
|
989
1303
|
state.activeToolInput = null;
|
|
990
1304
|
}
|
|
991
1305
|
}
|
|
992
|
-
function
|
|
1306
|
+
function recoverNestedStreamingToolCall(options) {
|
|
1307
|
+
var _a, _b, _c, _d;
|
|
1308
|
+
const { context, jsonSoFar, nestedStartIndex, startIndex, tag } = options;
|
|
1309
|
+
const {
|
|
1310
|
+
state,
|
|
1311
|
+
controller,
|
|
1312
|
+
toolCallStart,
|
|
1313
|
+
toolCallEnd,
|
|
1314
|
+
options: parserOptions
|
|
1315
|
+
} = context;
|
|
1316
|
+
const droppedToolCall = `${toolCallStart}${jsonSoFar.slice(
|
|
1317
|
+
0,
|
|
1318
|
+
nestedStartIndex
|
|
1319
|
+
)}`;
|
|
1320
|
+
const shouldEmitRawFallback = shouldEmitRawToolCallTextOnError(parserOptions);
|
|
1321
|
+
const streamingToolCallId = (_a = state.activeToolInput) == null ? void 0 : _a.id;
|
|
1322
|
+
const streamingToolName = (_c = (_b = state.activeToolInput) == null ? void 0 : _b.toolName) != null ? _c : extractStreamingToolCallProgress(jsonSoFar.slice(0, nestedStartIndex)).toolName;
|
|
1323
|
+
logParseFailure({
|
|
1324
|
+
phase: "stream",
|
|
1325
|
+
reason: "Abandoning malformed streaming tool call before nested start tag",
|
|
1326
|
+
snippet: droppedToolCall
|
|
1327
|
+
});
|
|
1328
|
+
if (shouldEmitRawFallback) {
|
|
1329
|
+
const errorId = generateId();
|
|
1330
|
+
controller.enqueue({
|
|
1331
|
+
type: "text-start",
|
|
1332
|
+
id: errorId
|
|
1333
|
+
});
|
|
1334
|
+
controller.enqueue({
|
|
1335
|
+
type: "text-delta",
|
|
1336
|
+
id: errorId,
|
|
1337
|
+
delta: droppedToolCall
|
|
1338
|
+
});
|
|
1339
|
+
controller.enqueue({
|
|
1340
|
+
type: "text-end",
|
|
1341
|
+
id: errorId
|
|
1342
|
+
});
|
|
1343
|
+
}
|
|
1344
|
+
closeToolInput(state, controller);
|
|
1345
|
+
(_d = parserOptions == null ? void 0 : parserOptions.onError) == null ? void 0 : _d.call(
|
|
1346
|
+
parserOptions,
|
|
1347
|
+
shouldEmitRawFallback ? "Could not process malformed streaming JSON tool call before nested start; emitting original text." : "Could not process malformed streaming JSON tool call before nested start.",
|
|
1348
|
+
{
|
|
1349
|
+
toolCall: droppedToolCall,
|
|
1350
|
+
toolCallId: streamingToolCallId,
|
|
1351
|
+
toolName: streamingToolName,
|
|
1352
|
+
dropReason: "malformed-nested-tool-call"
|
|
1353
|
+
}
|
|
1354
|
+
);
|
|
1355
|
+
state.currentToolCallJson = "";
|
|
1356
|
+
state.isInsideToolCall = false;
|
|
1357
|
+
state.buffer = jsonSoFar.slice(nestedStartIndex) + toolCallEnd + state.buffer.slice(startIndex + tag.length);
|
|
1358
|
+
return getPotentialStartIndex(state.buffer, toolCallStart);
|
|
1359
|
+
}
|
|
1360
|
+
function processInsideToolCallBoundary(context) {
|
|
993
1361
|
const { state, controller, toolCallStart, toolCallEnd, tools } = context;
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1362
|
+
const currentLength = state.currentToolCallJson.length;
|
|
1363
|
+
const combined = state.currentToolCallJson + state.buffer;
|
|
1364
|
+
const boundary = findToolCallBoundaryOutsideRjsonSyntax(
|
|
1365
|
+
combined,
|
|
1366
|
+
0,
|
|
1367
|
+
toolCallStart,
|
|
1368
|
+
toolCallEnd
|
|
1369
|
+
);
|
|
1370
|
+
if (boundary == null) {
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
const relativeEndIndex = boundary.endIdx - currentLength;
|
|
1374
|
+
if (relativeEndIndex < 0) {
|
|
1375
|
+
return false;
|
|
1376
|
+
}
|
|
1377
|
+
if (boundary.kind === "nested") {
|
|
1378
|
+
recoverNestedStreamingToolCall({
|
|
1379
|
+
context,
|
|
1380
|
+
jsonSoFar: combined.slice(0, boundary.endIdx),
|
|
1381
|
+
nestedStartIndex: boundary.nestedStartIndex,
|
|
1382
|
+
startIndex: relativeEndIndex,
|
|
1383
|
+
tag: toolCallEnd
|
|
1384
|
+
});
|
|
1385
|
+
return true;
|
|
1386
|
+
}
|
|
1387
|
+
publishText(
|
|
1388
|
+
state.buffer.slice(0, relativeEndIndex),
|
|
1389
|
+
state,
|
|
1390
|
+
controller,
|
|
1391
|
+
tools
|
|
997
1392
|
);
|
|
1393
|
+
state.buffer = state.buffer.slice(relativeEndIndex + toolCallEnd.length);
|
|
1394
|
+
processTagMatch(context);
|
|
1395
|
+
return true;
|
|
1396
|
+
}
|
|
1397
|
+
function processBufferTags(context) {
|
|
1398
|
+
const { state, controller, toolCallStart, tools } = context;
|
|
1399
|
+
while (state.isInsideToolCall) {
|
|
1400
|
+
if (!processInsideToolCallBoundary(context)) {
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
let startIndex = getPotentialStartIndex(state.buffer, toolCallStart);
|
|
998
1405
|
while (startIndex != null) {
|
|
999
|
-
|
|
1000
|
-
if (startIndex + tag.length > state.buffer.length) {
|
|
1406
|
+
if (startIndex + toolCallStart.length > state.buffer.length) {
|
|
1001
1407
|
break;
|
|
1002
1408
|
}
|
|
1003
1409
|
publishText(state.buffer.slice(0, startIndex), state, controller, tools);
|
|
1004
|
-
state.buffer = state.buffer.slice(startIndex +
|
|
1410
|
+
state.buffer = state.buffer.slice(startIndex + toolCallStart.length);
|
|
1005
1411
|
processTagMatch(context);
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1412
|
+
while (state.isInsideToolCall) {
|
|
1413
|
+
if (!processInsideToolCallBoundary(context)) {
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
startIndex = getPotentialStartIndex(state.buffer, toolCallStart);
|
|
1010
1418
|
}
|
|
1011
1419
|
}
|
|
1012
1420
|
function handlePartialTag(state, controller, toolCallStart, toolCallEnd, tools) {
|
|
@@ -1044,6 +1452,7 @@ var hermesProtocol = ({
|
|
|
1044
1452
|
toolCallStart = "<tool_call>",
|
|
1045
1453
|
toolCallEnd = "</tool_call>"
|
|
1046
1454
|
} = {}) => ({
|
|
1455
|
+
...validateNonEmptyDelimiters(toolCallStart, toolCallEnd),
|
|
1047
1456
|
formatTools({
|
|
1048
1457
|
tools,
|
|
1049
1458
|
toolSystemPromptTemplate
|
|
@@ -1068,24 +1477,42 @@ var hermesProtocol = ({
|
|
|
1068
1477
|
text,
|
|
1069
1478
|
options
|
|
1070
1479
|
}) {
|
|
1071
|
-
const startEsc = escapeRegExp(toolCallStart);
|
|
1072
|
-
const endEsc = escapeRegExp(toolCallEnd);
|
|
1073
|
-
const toolCallRegex = new RegExp(
|
|
1074
|
-
`${startEsc}([\0-\uFFFF]*?)${endEsc}`,
|
|
1075
|
-
"gs"
|
|
1076
|
-
);
|
|
1077
1480
|
const processedElements = [];
|
|
1078
1481
|
let currentIndex = 0;
|
|
1079
|
-
let
|
|
1080
|
-
while (
|
|
1081
|
-
|
|
1082
|
-
match,
|
|
1482
|
+
let searchFrom = 0;
|
|
1483
|
+
while (searchFrom < text.length) {
|
|
1484
|
+
const span = findNextToolCallSpan(
|
|
1083
1485
|
text,
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1486
|
+
searchFrom,
|
|
1487
|
+
toolCallStart,
|
|
1488
|
+
toolCallEnd
|
|
1489
|
+
);
|
|
1490
|
+
if (span === null) {
|
|
1491
|
+
break;
|
|
1492
|
+
}
|
|
1493
|
+
if (!span.found) {
|
|
1494
|
+
const skipTo = span.startIdx + toolCallStart.length;
|
|
1495
|
+
if (skipTo > currentIndex) {
|
|
1496
|
+
addTextSegment(text.slice(currentIndex, skipTo), processedElements);
|
|
1497
|
+
currentIndex = skipTo;
|
|
1498
|
+
}
|
|
1499
|
+
searchFrom = skipTo;
|
|
1500
|
+
continue;
|
|
1501
|
+
}
|
|
1502
|
+
const toolCallJson = text.slice(span.jsonStart, span.endIdx);
|
|
1503
|
+
const fullMatch = text.slice(
|
|
1504
|
+
span.startIdx,
|
|
1505
|
+
span.endIdx + toolCallEnd.length
|
|
1506
|
+
);
|
|
1507
|
+
if (span.startIdx > currentIndex) {
|
|
1508
|
+
addTextSegment(
|
|
1509
|
+
text.slice(currentIndex, span.startIdx),
|
|
1510
|
+
processedElements
|
|
1511
|
+
);
|
|
1512
|
+
}
|
|
1513
|
+
processToolCallJson(toolCallJson, fullMatch, processedElements, options);
|
|
1514
|
+
currentIndex = span.endIdx + toolCallEnd.length;
|
|
1515
|
+
searchFrom = currentIndex;
|
|
1089
1516
|
}
|
|
1090
1517
|
if (currentIndex < text.length) {
|
|
1091
1518
|
const remainingText = text.slice(currentIndex);
|
|
@@ -1138,14 +1565,26 @@ var hermesProtocol = ({
|
|
|
1138
1565
|
});
|
|
1139
1566
|
},
|
|
1140
1567
|
extractToolCallSegments({ text }) {
|
|
1141
|
-
const startEsc = escapeRegExp(toolCallStart);
|
|
1142
|
-
const endEsc = escapeRegExp(toolCallEnd);
|
|
1143
|
-
const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
|
|
1144
1568
|
const segments = [];
|
|
1145
|
-
let
|
|
1146
|
-
while (
|
|
1147
|
-
|
|
1148
|
-
|
|
1569
|
+
let searchFrom = 0;
|
|
1570
|
+
while (searchFrom < text.length) {
|
|
1571
|
+
const span = findNextToolCallSpan(
|
|
1572
|
+
text,
|
|
1573
|
+
searchFrom,
|
|
1574
|
+
toolCallStart,
|
|
1575
|
+
toolCallEnd
|
|
1576
|
+
);
|
|
1577
|
+
if (span === null) {
|
|
1578
|
+
break;
|
|
1579
|
+
}
|
|
1580
|
+
if (!span.found) {
|
|
1581
|
+
searchFrom = span.startIdx + toolCallStart.length;
|
|
1582
|
+
continue;
|
|
1583
|
+
}
|
|
1584
|
+
segments.push(
|
|
1585
|
+
text.slice(span.startIdx, span.endIdx + toolCallEnd.length)
|
|
1586
|
+
);
|
|
1587
|
+
searchFrom = span.endIdx + toolCallEnd.length;
|
|
1149
1588
|
}
|
|
1150
1589
|
return segments;
|
|
1151
1590
|
}
|
|
@@ -1434,7 +1873,13 @@ function processToolCall(params) {
|
|
|
1434
1873
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
1435
1874
|
options,
|
|
1436
1875
|
`Could not process XML tool call: ${toolCall.toolName}`,
|
|
1437
|
-
{
|
|
1876
|
+
{
|
|
1877
|
+
toolCall: originalCallText,
|
|
1878
|
+
error,
|
|
1879
|
+
toolName: toolCall.toolName,
|
|
1880
|
+
toolCallId: generateToolCallId(),
|
|
1881
|
+
dropReason: "malformed-tool-call-body"
|
|
1882
|
+
}
|
|
1438
1883
|
);
|
|
1439
1884
|
processedElements.push({ type: "text", text: originalCallText });
|
|
1440
1885
|
}
|
|
@@ -1876,7 +2321,10 @@ function handleStreamingToolCallEnd(params) {
|
|
|
1876
2321
|
});
|
|
1877
2322
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, "Could not process streaming XML tool call", {
|
|
1878
2323
|
toolCall: original,
|
|
1879
|
-
error
|
|
2324
|
+
error,
|
|
2325
|
+
toolName: currentToolCall.name,
|
|
2326
|
+
toolCallId: currentToolCall.toolCallId,
|
|
2327
|
+
dropReason: "malformed-tool-call-body"
|
|
1880
2328
|
});
|
|
1881
2329
|
}
|
|
1882
2330
|
}
|
|
@@ -2438,7 +2886,13 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2438
2886
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
2439
2887
|
options,
|
|
2440
2888
|
"Could not complete streaming XML tool call at finish.",
|
|
2441
|
-
{
|
|
2889
|
+
{
|
|
2890
|
+
toolCall: unfinishedContent,
|
|
2891
|
+
toolCallId: currentToolCall.toolCallId,
|
|
2892
|
+
toolName: currentToolCall.name,
|
|
2893
|
+
dropReason: "unfinished-tool-call",
|
|
2894
|
+
error
|
|
2895
|
+
}
|
|
2442
2896
|
);
|
|
2443
2897
|
}
|
|
2444
2898
|
buffer = "";
|
|
@@ -2664,7 +3118,8 @@ var QWEN3CODER_TOOL_PARSER_CALL_TAG_NAMES = /* @__PURE__ */ new Set([
|
|
|
2664
3118
|
"invoke",
|
|
2665
3119
|
"tool_call"
|
|
2666
3120
|
]);
|
|
2667
|
-
var CALL_SHORTHAND_VALUE_RE = /^<\s*(call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s
|
|
3121
|
+
var CALL_SHORTHAND_VALUE_RE = /^<\s*(call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>/<]+))/i;
|
|
3122
|
+
var NESTED_CALL_SHORTHAND_VALUE_RE = /<\s*(?:call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>/<]+))/i;
|
|
2668
3123
|
var QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_START_RE = /<\s*(?!\/)\s*(call|function|tool|invoke)\b/i;
|
|
2669
3124
|
var QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE = /<\s*(?!\/)\s*(call|function|tool|invoke)\b[^>]*>/i;
|
|
2670
3125
|
var QWEN3CODER_TOOL_PARSER_STREAM_TOOL_CALL_CLOSE_TAG_RE = /<\s*\/\s*tool_call\s*>/i;
|
|
@@ -3063,6 +3518,12 @@ function getShorthandValue(openTag) {
|
|
|
3063
3518
|
}
|
|
3064
3519
|
return unescapeXml(value);
|
|
3065
3520
|
}
|
|
3521
|
+
function extractShorthandToolNameFromRaw(rawText) {
|
|
3522
|
+
var _a, _b;
|
|
3523
|
+
const match = NESTED_CALL_SHORTHAND_VALUE_RE.exec(rawText);
|
|
3524
|
+
const value = (_b = (_a = match == null ? void 0 : match[1]) != null ? _a : match == null ? void 0 : match[2]) != null ? _b : match == null ? void 0 : match[3];
|
|
3525
|
+
return value ? unescapeXml(value) : null;
|
|
3526
|
+
}
|
|
3066
3527
|
function extractFirstTagText(xml, tagName) {
|
|
3067
3528
|
var _a;
|
|
3068
3529
|
const lower = xml.toLowerCase();
|
|
@@ -3384,6 +3845,20 @@ function parseQwen3CoderToolParserClosedMatches(inner, outerNameAttr) {
|
|
|
3384
3845
|
}
|
|
3385
3846
|
return closedCalls.concat(trailingCalls);
|
|
3386
3847
|
}
|
|
3848
|
+
var QWEN3CODER_TOOL_NAME_SALVAGE_REGEX = /<(?:function|call|tool|invoke)(?:\s*=\s*"([^"]+)"|\s*=\s*'([^']+)'|\s*=\s*([^\s>/]+)|\s+name\s*=\s*"([^"]+)"|\s+name\s*=\s*'([^']+)')|<(?:name|tool_name)\b[^>]*>([\s\S]*?)<\s*\/\s*(?:name|tool_name)\s*>/i;
|
|
3849
|
+
function extractQwen3CoderToolNameFromMarkup(markup) {
|
|
3850
|
+
var _a, _b, _c, _d, _e;
|
|
3851
|
+
const match = markup.match(QWEN3CODER_TOOL_NAME_SALVAGE_REGEX);
|
|
3852
|
+
if (!match) {
|
|
3853
|
+
return void 0;
|
|
3854
|
+
}
|
|
3855
|
+
const name = (_e = (_d = (_c = (_b = (_a = match[1]) != null ? _a : match[2]) != null ? _b : match[3]) != null ? _c : match[4]) != null ? _d : match[5]) != null ? _e : match[6];
|
|
3856
|
+
if (!name) {
|
|
3857
|
+
return void 0;
|
|
3858
|
+
}
|
|
3859
|
+
const trimmed = name.trim();
|
|
3860
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
3861
|
+
}
|
|
3387
3862
|
function parseQwen3CoderToolParserToolCallSegment(segment) {
|
|
3388
3863
|
var _a;
|
|
3389
3864
|
const extracted = extractToolCallInnerXml(segment);
|
|
@@ -3508,7 +3983,12 @@ var qwen3CoderProtocol = () => ({
|
|
|
3508
3983
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
3509
3984
|
options,
|
|
3510
3985
|
"Could not process Qwen3CoderToolParser XML tool call; keeping original text.",
|
|
3511
|
-
{
|
|
3986
|
+
{
|
|
3987
|
+
toolCall: fallbackText,
|
|
3988
|
+
toolName: extractQwen3CoderToolNameFromMarkup(segment),
|
|
3989
|
+
toolCallId: generateToolCallId(),
|
|
3990
|
+
dropReason: "malformed-tool-call-body"
|
|
3991
|
+
}
|
|
3512
3992
|
);
|
|
3513
3993
|
processedElements.push({ type: "text", text: fallbackText });
|
|
3514
3994
|
return false;
|
|
@@ -3521,7 +4001,12 @@ var qwen3CoderProtocol = () => ({
|
|
|
3521
4001
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
3522
4002
|
options,
|
|
3523
4003
|
"Could not process Qwen3CoderToolParser <function> call; keeping original text.",
|
|
3524
|
-
{
|
|
4004
|
+
{
|
|
4005
|
+
toolCall: raw,
|
|
4006
|
+
toolName: extractQwen3CoderToolNameFromMarkup(raw),
|
|
4007
|
+
toolCallId: generateToolCallId(),
|
|
4008
|
+
dropReason: "malformed-tool-call-body"
|
|
4009
|
+
}
|
|
3525
4010
|
);
|
|
3526
4011
|
processedElements.push({ type: "text", text: raw });
|
|
3527
4012
|
};
|
|
@@ -3771,7 +4256,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3771
4256
|
});
|
|
3772
4257
|
};
|
|
3773
4258
|
const finalizeCall = (controller, callState, fallbackToolName, rawToolCallText = null) => {
|
|
3774
|
-
var _a, _b;
|
|
4259
|
+
var _a, _b, _c, _d;
|
|
3775
4260
|
const resolvedToolName = (_a = callState.toolName) != null ? _a : fallbackToolName;
|
|
3776
4261
|
if (!resolvedToolName || resolvedToolName.trim().length === 0) {
|
|
3777
4262
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
@@ -3785,12 +4270,14 @@ var qwen3CoderProtocol = () => ({
|
|
|
3785
4270
|
flushText(controller, rawText);
|
|
3786
4271
|
}
|
|
3787
4272
|
});
|
|
3788
|
-
(
|
|
4273
|
+
(_d = options == null ? void 0 : options.onError) == null ? void 0 : _d.call(
|
|
3789
4274
|
options,
|
|
3790
4275
|
shouldEmitRaw && rawToolCallText ? "Could not resolve Qwen3CoderToolParser tool name for tool call; emitting original text." : "Could not resolve Qwen3CoderToolParser tool name for tool call",
|
|
3791
4276
|
{
|
|
3792
4277
|
toolCallId: callState.toolCallId,
|
|
3793
|
-
toolCall: rawToolCallText
|
|
4278
|
+
toolCall: rawToolCallText,
|
|
4279
|
+
toolName: (_c = (_b = callState.toolName) != null ? _b : fallbackToolName) != null ? _c : void 0,
|
|
4280
|
+
dropReason: "unresolved-tool-name"
|
|
3794
4281
|
}
|
|
3795
4282
|
);
|
|
3796
4283
|
return false;
|
|
@@ -4246,25 +4733,36 @@ var qwen3CoderProtocol = () => ({
|
|
|
4246
4733
|
}
|
|
4247
4734
|
}
|
|
4248
4735
|
};
|
|
4249
|
-
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall) => {
|
|
4250
|
-
var _a;
|
|
4736
|
+
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall, metadata = {}) => {
|
|
4737
|
+
var _a, _b;
|
|
4251
4738
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
4252
|
-
(_a =
|
|
4739
|
+
const toolName = (_a = metadata.toolName) != null ? _a : extractShorthandToolNameFromRaw(rawToolCall);
|
|
4740
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
4253
4741
|
options,
|
|
4254
4742
|
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser XML tool call at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser XML tool call at finish.",
|
|
4255
|
-
{
|
|
4743
|
+
{
|
|
4744
|
+
toolCall: rawToolCall,
|
|
4745
|
+
...metadata.toolCallId ? { toolCallId: metadata.toolCallId } : {},
|
|
4746
|
+
...toolName ? { toolName } : {},
|
|
4747
|
+
dropReason: "unfinished-tool-call"
|
|
4748
|
+
}
|
|
4256
4749
|
);
|
|
4257
4750
|
if (shouldEmitRaw) {
|
|
4258
4751
|
flushText(controller, rawToolCall);
|
|
4259
4752
|
}
|
|
4260
4753
|
};
|
|
4261
|
-
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText) => {
|
|
4754
|
+
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText, callState) => {
|
|
4262
4755
|
var _a;
|
|
4263
4756
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
4264
4757
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4265
4758
|
options,
|
|
4266
4759
|
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser call block at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser call block at finish.",
|
|
4267
|
-
{
|
|
4760
|
+
{
|
|
4761
|
+
toolCall: rawCallText,
|
|
4762
|
+
toolCallId: callState.toolCallId,
|
|
4763
|
+
...callState.toolName ? { toolName: callState.toolName } : {},
|
|
4764
|
+
dropReason: "unfinished-tool-call"
|
|
4765
|
+
}
|
|
4268
4766
|
);
|
|
4269
4767
|
if (shouldEmitRaw) {
|
|
4270
4768
|
flushText(controller, rawCallText);
|
|
@@ -4315,7 +4813,10 @@ var qwen3CoderProtocol = () => ({
|
|
|
4315
4813
|
flushText(controller, result.trailingText);
|
|
4316
4814
|
}
|
|
4317
4815
|
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
4318
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
4816
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
4817
|
+
toolCallId: toolCall.activeCall.toolCallId,
|
|
4818
|
+
...toolCall.activeCall.toolName ? { toolName: toolCall.activeCall.toolName } : {}
|
|
4819
|
+
});
|
|
4319
4820
|
}
|
|
4320
4821
|
} else if (toolCall.mode === "multi") {
|
|
4321
4822
|
if (toolCall.activeCall) {
|
|
@@ -4332,14 +4833,21 @@ var qwen3CoderProtocol = () => ({
|
|
|
4332
4833
|
flushText(controller, result.trailingText);
|
|
4333
4834
|
}
|
|
4334
4835
|
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
4335
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
4836
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
4837
|
+
toolCallId: toolCall.activeCall.toolCallId,
|
|
4838
|
+
...toolCall.activeCall.toolName ? { toolName: toolCall.activeCall.toolName } : {}
|
|
4839
|
+
});
|
|
4336
4840
|
}
|
|
4337
4841
|
toolCall.activeCall = null;
|
|
4338
4842
|
} else if (toolCall.emittedToolCallCount === 0) {
|
|
4339
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
4843
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
4844
|
+
toolName: toolCall.outerNameAttr
|
|
4845
|
+
});
|
|
4340
4846
|
}
|
|
4341
4847
|
} else {
|
|
4342
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
4848
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
4849
|
+
toolName: toolCall.outerNameAttr
|
|
4850
|
+
});
|
|
4343
4851
|
}
|
|
4344
4852
|
toolCall = null;
|
|
4345
4853
|
}
|
|
@@ -4357,7 +4865,8 @@ var qwen3CoderProtocol = () => ({
|
|
|
4357
4865
|
if (!result.ok && openTag) {
|
|
4358
4866
|
reportUnfinishedImplicitCallAtFinish(
|
|
4359
4867
|
controller,
|
|
4360
|
-
callState.raw || openTag + callState.buffer
|
|
4868
|
+
callState.raw || openTag + callState.buffer,
|
|
4869
|
+
callState
|
|
4361
4870
|
);
|
|
4362
4871
|
}
|
|
4363
4872
|
} else {
|
|
@@ -4736,26 +5245,28 @@ function findToolCalls2(text, toolNames) {
|
|
|
4736
5245
|
);
|
|
4737
5246
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
4738
5247
|
}
|
|
4739
|
-
function
|
|
4740
|
-
|
|
5248
|
+
function yamlFailureCause(failure) {
|
|
5249
|
+
if (failure.kind === "yaml-parse-error") {
|
|
5250
|
+
return { kind: "yaml-parse-error", errors: failure.errors };
|
|
5251
|
+
}
|
|
5252
|
+
return { kind: "yaml-non-mapping" };
|
|
5253
|
+
}
|
|
5254
|
+
function parseYamlContent(yamlContent) {
|
|
4741
5255
|
const { normalized, nonEmptyLines } = normalizeYamlContent(yamlContent);
|
|
4742
5256
|
if (nonEmptyLines.length === 0) {
|
|
4743
|
-
return {};
|
|
5257
|
+
return { ok: true, value: {} };
|
|
4744
5258
|
}
|
|
4745
5259
|
const parsed = parseYamlDocumentAsMapping(normalized);
|
|
4746
5260
|
if (parsed.errors.length > 0) {
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
5261
|
+
return {
|
|
5262
|
+
ok: false,
|
|
5263
|
+
failure: { kind: "yaml-parse-error", errors: parsed.errors }
|
|
5264
|
+
};
|
|
4751
5265
|
}
|
|
4752
5266
|
if (parsed.value === null) {
|
|
4753
|
-
|
|
4754
|
-
got: "non-mapping"
|
|
4755
|
-
});
|
|
4756
|
-
return null;
|
|
5267
|
+
return { ok: false, failure: { kind: "yaml-non-mapping" } };
|
|
4757
5268
|
}
|
|
4758
|
-
return parsed.value;
|
|
5269
|
+
return { ok: true, value: parsed.value };
|
|
4759
5270
|
}
|
|
4760
5271
|
function parseYamlContentForStreamProgress(yamlContent) {
|
|
4761
5272
|
const { normalized, nonEmptyLines } = normalizeYamlContent(yamlContent);
|
|
@@ -4787,11 +5298,16 @@ function processToolCallMatch(text, tc, currentIndex, processedElements, options
|
|
|
4787
5298
|
return currentIndex;
|
|
4788
5299
|
}
|
|
4789
5300
|
addTextSegment(text.slice(currentIndex, tc.startIndex), processedElements);
|
|
4790
|
-
const
|
|
4791
|
-
if (
|
|
5301
|
+
const result = parseYamlContent(tc.content);
|
|
5302
|
+
if (!result.ok) {
|
|
4792
5303
|
const originalText = text.slice(tc.startIndex, tc.endIndex);
|
|
5304
|
+
const cause = yamlFailureCause(result.failure);
|
|
4793
5305
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse YAML tool call", {
|
|
4794
|
-
toolCall: originalText
|
|
5306
|
+
toolCall: originalText,
|
|
5307
|
+
toolName: tc.toolName,
|
|
5308
|
+
toolCallId: generateToolCallId(),
|
|
5309
|
+
dropReason: "malformed-tool-call-body",
|
|
5310
|
+
cause
|
|
4795
5311
|
});
|
|
4796
5312
|
processedElements.push({ type: "text", text: originalText });
|
|
4797
5313
|
} else {
|
|
@@ -4799,7 +5315,7 @@ function processToolCallMatch(text, tc, currentIndex, processedElements, options
|
|
|
4799
5315
|
type: "tool-call",
|
|
4800
5316
|
toolCallId: generateToolCallId(),
|
|
4801
5317
|
toolName: tc.toolName,
|
|
4802
|
-
input: JSON.stringify(
|
|
5318
|
+
input: JSON.stringify(result.value)
|
|
4803
5319
|
});
|
|
4804
5320
|
}
|
|
4805
5321
|
return tc.endIndex;
|
|
@@ -4922,9 +5438,9 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4922
5438
|
};
|
|
4923
5439
|
const processToolCallEnd = (controller, toolContent, toolName, toolCallId) => {
|
|
4924
5440
|
var _a;
|
|
4925
|
-
const
|
|
5441
|
+
const result = parseYamlContent(toolContent);
|
|
4926
5442
|
flushText(controller);
|
|
4927
|
-
if (
|
|
5443
|
+
if (!result.ok) {
|
|
4928
5444
|
const original = `<${toolName}>${toolContent}</${toolName}>`;
|
|
4929
5445
|
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
4930
5446
|
emitFailedToolInputLifecycle({
|
|
@@ -4937,12 +5453,16 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4937
5453
|
}
|
|
4938
5454
|
});
|
|
4939
5455
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse streaming YAML tool call", {
|
|
4940
|
-
toolCall: original
|
|
5456
|
+
toolCall: original,
|
|
5457
|
+
toolName,
|
|
5458
|
+
toolCallId,
|
|
5459
|
+
dropReason: "malformed-tool-call-body",
|
|
5460
|
+
cause: yamlFailureCause(result.failure)
|
|
4941
5461
|
});
|
|
4942
5462
|
} else {
|
|
4943
5463
|
const finalInput = stringifyToolInputWithSchema({
|
|
4944
5464
|
toolName,
|
|
4945
|
-
args:
|
|
5465
|
+
args: result.value,
|
|
4946
5466
|
tools
|
|
4947
5467
|
});
|
|
4948
5468
|
if (currentToolCall && currentToolCall.toolCallId === toolCallId) {
|
|
@@ -4972,9 +5492,9 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4972
5492
|
emitToolInputProgress2(controller, buffer);
|
|
4973
5493
|
const { name: toolName, toolCallId } = currentToolCall;
|
|
4974
5494
|
const reconciledBuffer = stripTrailingPartialCloseTag(buffer, toolName);
|
|
4975
|
-
const
|
|
5495
|
+
const result = parseYamlContent(reconciledBuffer);
|
|
4976
5496
|
flushText(controller);
|
|
4977
|
-
if (
|
|
5497
|
+
if (!result.ok) {
|
|
4978
5498
|
const unfinishedContent = `<${toolName}>${buffer}`;
|
|
4979
5499
|
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
4980
5500
|
emitFailedToolInputLifecycle({
|
|
@@ -4989,12 +5509,18 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4989
5509
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4990
5510
|
options,
|
|
4991
5511
|
"Could not complete streaming YAML tool call at finish.",
|
|
4992
|
-
{
|
|
5512
|
+
{
|
|
5513
|
+
toolCall: unfinishedContent,
|
|
5514
|
+
toolCallId,
|
|
5515
|
+
toolName,
|
|
5516
|
+
dropReason: "unfinished-tool-call",
|
|
5517
|
+
cause: yamlFailureCause(result.failure)
|
|
5518
|
+
}
|
|
4993
5519
|
);
|
|
4994
5520
|
} else {
|
|
4995
5521
|
const finalInput = stringifyToolInputWithSchema({
|
|
4996
5522
|
toolName,
|
|
4997
|
-
args:
|
|
5523
|
+
args: result.value,
|
|
4998
5524
|
tools
|
|
4999
5525
|
});
|
|
5000
5526
|
emitFinalizedToolInputLifecycle({
|
|
@@ -7327,4 +7853,4 @@ export {
|
|
|
7327
7853
|
morphXmlToolMiddleware,
|
|
7328
7854
|
yamlXmlToolMiddleware
|
|
7329
7855
|
};
|
|
7330
|
-
//# sourceMappingURL=chunk-
|
|
7856
|
+
//# sourceMappingURL=chunk-GAJX7HXU.js.map
|