@ai-sdk-tool/parser 4.1.20 → 4.1.22
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-TLZV6QE3.js → chunk-2I56ZDEY.js} +3 -3
- package/dist/{chunk-TLZV6QE3.js.map → chunk-2I56ZDEY.js.map} +1 -1
- package/dist/{chunk-AELRIRO2.js → chunk-DKZ4GAQM.js} +918 -396
- package/dist/chunk-DKZ4GAQM.js.map +1 -0
- package/dist/community.cjs +917 -395
- package/dist/community.cjs.map +1 -1
- package/dist/community.js +2 -2
- package/dist/index.cjs +922 -400
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/rxml.cjs +1 -1
- package/dist/rxml.cjs.map +1 -1
- package/dist/rxml.js +1 -1
- package/package.json +17 -17
- package/dist/chunk-AELRIRO2.js.map +0 -1
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
parse as parse2,
|
|
6
6
|
stringify,
|
|
7
7
|
unescapeXml
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-2I56ZDEY.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;
|
|
@@ -604,10 +898,10 @@ function findTopLevelPropertyValueStart(text, property) {
|
|
|
604
898
|
function extractTopLevelStringProperty(text, property) {
|
|
605
899
|
const valueStart = findTopLevelPropertyValueStart(text, property);
|
|
606
900
|
if (valueStart == null || valueStart >= text.length) {
|
|
607
|
-
return
|
|
901
|
+
return;
|
|
608
902
|
}
|
|
609
903
|
if (text.charAt(valueStart) !== '"') {
|
|
610
|
-
return
|
|
904
|
+
return;
|
|
611
905
|
}
|
|
612
906
|
let valueEnd = valueStart + 1;
|
|
613
907
|
let escaped = false;
|
|
@@ -622,7 +916,7 @@ function extractTopLevelStringProperty(text, property) {
|
|
|
622
916
|
}
|
|
623
917
|
valueEnd += 1;
|
|
624
918
|
}
|
|
625
|
-
return
|
|
919
|
+
return;
|
|
626
920
|
}
|
|
627
921
|
function extractJsonValueSlice(text, valueStart) {
|
|
628
922
|
if (valueStart >= text.length) {
|
|
@@ -786,10 +1080,12 @@ function emitToolCallFromParsed(state, controller, parsedToolCall, tools) {
|
|
|
786
1080
|
}
|
|
787
1081
|
function canonicalizeArgumentsProgressInput(progress, toolName, tools) {
|
|
788
1082
|
if (progress.argumentsText === void 0 || !progress.argumentsComplete) {
|
|
789
|
-
return
|
|
1083
|
+
return;
|
|
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,
|
|
@@ -797,7 +1093,7 @@ function canonicalizeArgumentsProgressInput(progress, toolName, tools) {
|
|
|
797
1093
|
fallback: canonicalizeToolInput
|
|
798
1094
|
});
|
|
799
1095
|
} catch (e) {
|
|
800
|
-
return
|
|
1096
|
+
return;
|
|
801
1097
|
}
|
|
802
1098
|
}
|
|
803
1099
|
function emitToolInputProgress(state, controller, tools) {
|
|
@@ -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();
|
|
@@ -3345,7 +3806,7 @@ function parseQwen3CoderToolParserClosedMatches(inner, outerNameAttr) {
|
|
|
3345
3806
|
var _a, _b;
|
|
3346
3807
|
const callBlockMatches = Array.from(inner.matchAll(CALL_BLOCK_RE));
|
|
3347
3808
|
if (callBlockMatches.length === 0) {
|
|
3348
|
-
return
|
|
3809
|
+
return;
|
|
3349
3810
|
}
|
|
3350
3811
|
const closedBlocks = [];
|
|
3351
3812
|
let lastClosedEnd = 0;
|
|
@@ -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;
|
|
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;
|
|
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
|
};
|
|
@@ -3667,9 +4152,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3667
4152
|
tryEmitToolCallSegment(synthetic, trailing);
|
|
3668
4153
|
return true;
|
|
3669
4154
|
};
|
|
3670
|
-
const tryParseCallBlocksWithoutWrapper = () =>
|
|
3671
|
-
return tryParseCallBlocksWithoutWrapperText(text);
|
|
3672
|
-
};
|
|
4155
|
+
const tryParseCallBlocksWithoutWrapper = () => tryParseCallBlocksWithoutWrapperText(text);
|
|
3673
4156
|
const tryParseSingleFunctionCall = () => {
|
|
3674
4157
|
const lowerText = text.toLowerCase();
|
|
3675
4158
|
const startIndex = lowerText.indexOf("<function");
|
|
@@ -3771,7 +4254,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3771
4254
|
});
|
|
3772
4255
|
};
|
|
3773
4256
|
const finalizeCall = (controller, callState, fallbackToolName, rawToolCallText = null) => {
|
|
3774
|
-
var _a, _b;
|
|
4257
|
+
var _a, _b, _c, _d;
|
|
3775
4258
|
const resolvedToolName = (_a = callState.toolName) != null ? _a : fallbackToolName;
|
|
3776
4259
|
if (!resolvedToolName || resolvedToolName.trim().length === 0) {
|
|
3777
4260
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
@@ -3785,12 +4268,14 @@ var qwen3CoderProtocol = () => ({
|
|
|
3785
4268
|
flushText(controller, rawText);
|
|
3786
4269
|
}
|
|
3787
4270
|
});
|
|
3788
|
-
(
|
|
4271
|
+
(_d = options == null ? void 0 : options.onError) == null ? void 0 : _d.call(
|
|
3789
4272
|
options,
|
|
3790
4273
|
shouldEmitRaw && rawToolCallText ? "Could not resolve Qwen3CoderToolParser tool name for tool call; emitting original text." : "Could not resolve Qwen3CoderToolParser tool name for tool call",
|
|
3791
4274
|
{
|
|
3792
4275
|
toolCallId: callState.toolCallId,
|
|
3793
|
-
toolCall: rawToolCallText
|
|
4276
|
+
toolCall: rawToolCallText,
|
|
4277
|
+
toolName: (_c = (_b = callState.toolName) != null ? _b : fallbackToolName) != null ? _c : void 0,
|
|
4278
|
+
dropReason: "unresolved-tool-name"
|
|
3794
4279
|
}
|
|
3795
4280
|
);
|
|
3796
4281
|
return false;
|
|
@@ -4246,25 +4731,36 @@ var qwen3CoderProtocol = () => ({
|
|
|
4246
4731
|
}
|
|
4247
4732
|
}
|
|
4248
4733
|
};
|
|
4249
|
-
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall) => {
|
|
4250
|
-
var _a;
|
|
4734
|
+
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall, metadata = {}) => {
|
|
4735
|
+
var _a, _b;
|
|
4251
4736
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
4252
|
-
(_a =
|
|
4737
|
+
const toolName = (_a = metadata.toolName) != null ? _a : extractShorthandToolNameFromRaw(rawToolCall);
|
|
4738
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
4253
4739
|
options,
|
|
4254
4740
|
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
|
-
{
|
|
4741
|
+
{
|
|
4742
|
+
toolCall: rawToolCall,
|
|
4743
|
+
...metadata.toolCallId ? { toolCallId: metadata.toolCallId } : {},
|
|
4744
|
+
...toolName ? { toolName } : {},
|
|
4745
|
+
dropReason: "unfinished-tool-call"
|
|
4746
|
+
}
|
|
4256
4747
|
);
|
|
4257
4748
|
if (shouldEmitRaw) {
|
|
4258
4749
|
flushText(controller, rawToolCall);
|
|
4259
4750
|
}
|
|
4260
4751
|
};
|
|
4261
|
-
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText) => {
|
|
4752
|
+
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText, callState) => {
|
|
4262
4753
|
var _a;
|
|
4263
4754
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
4264
4755
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4265
4756
|
options,
|
|
4266
4757
|
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser call block at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser call block at finish.",
|
|
4267
|
-
{
|
|
4758
|
+
{
|
|
4759
|
+
toolCall: rawCallText,
|
|
4760
|
+
toolCallId: callState.toolCallId,
|
|
4761
|
+
...callState.toolName ? { toolName: callState.toolName } : {},
|
|
4762
|
+
dropReason: "unfinished-tool-call"
|
|
4763
|
+
}
|
|
4268
4764
|
);
|
|
4269
4765
|
if (shouldEmitRaw) {
|
|
4270
4766
|
flushText(controller, rawCallText);
|
|
@@ -4315,7 +4811,10 @@ var qwen3CoderProtocol = () => ({
|
|
|
4315
4811
|
flushText(controller, result.trailingText);
|
|
4316
4812
|
}
|
|
4317
4813
|
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
4318
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
4814
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
4815
|
+
toolCallId: toolCall.activeCall.toolCallId,
|
|
4816
|
+
...toolCall.activeCall.toolName ? { toolName: toolCall.activeCall.toolName } : {}
|
|
4817
|
+
});
|
|
4319
4818
|
}
|
|
4320
4819
|
} else if (toolCall.mode === "multi") {
|
|
4321
4820
|
if (toolCall.activeCall) {
|
|
@@ -4332,14 +4831,21 @@ var qwen3CoderProtocol = () => ({
|
|
|
4332
4831
|
flushText(controller, result.trailingText);
|
|
4333
4832
|
}
|
|
4334
4833
|
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
4335
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
4834
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
4835
|
+
toolCallId: toolCall.activeCall.toolCallId,
|
|
4836
|
+
...toolCall.activeCall.toolName ? { toolName: toolCall.activeCall.toolName } : {}
|
|
4837
|
+
});
|
|
4336
4838
|
}
|
|
4337
4839
|
toolCall.activeCall = null;
|
|
4338
4840
|
} else if (toolCall.emittedToolCallCount === 0) {
|
|
4339
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
4841
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
4842
|
+
toolName: toolCall.outerNameAttr
|
|
4843
|
+
});
|
|
4340
4844
|
}
|
|
4341
4845
|
} else {
|
|
4342
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
4846
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
4847
|
+
toolName: toolCall.outerNameAttr
|
|
4848
|
+
});
|
|
4343
4849
|
}
|
|
4344
4850
|
toolCall = null;
|
|
4345
4851
|
}
|
|
@@ -4357,7 +4863,8 @@ var qwen3CoderProtocol = () => ({
|
|
|
4357
4863
|
if (!result.ok && openTag) {
|
|
4358
4864
|
reportUnfinishedImplicitCallAtFinish(
|
|
4359
4865
|
controller,
|
|
4360
|
-
callState.raw || openTag + callState.buffer
|
|
4866
|
+
callState.raw || openTag + callState.buffer,
|
|
4867
|
+
callState
|
|
4361
4868
|
);
|
|
4362
4869
|
}
|
|
4363
4870
|
} else {
|
|
@@ -4736,26 +5243,28 @@ function findToolCalls2(text, toolNames) {
|
|
|
4736
5243
|
);
|
|
4737
5244
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
4738
5245
|
}
|
|
4739
|
-
function
|
|
4740
|
-
|
|
5246
|
+
function yamlFailureCause(failure) {
|
|
5247
|
+
if (failure.kind === "yaml-parse-error") {
|
|
5248
|
+
return { kind: "yaml-parse-error", errors: failure.errors };
|
|
5249
|
+
}
|
|
5250
|
+
return { kind: "yaml-non-mapping" };
|
|
5251
|
+
}
|
|
5252
|
+
function parseYamlContent(yamlContent) {
|
|
4741
5253
|
const { normalized, nonEmptyLines } = normalizeYamlContent(yamlContent);
|
|
4742
5254
|
if (nonEmptyLines.length === 0) {
|
|
4743
|
-
return {};
|
|
5255
|
+
return { ok: true, value: {} };
|
|
4744
5256
|
}
|
|
4745
5257
|
const parsed = parseYamlDocumentAsMapping(normalized);
|
|
4746
5258
|
if (parsed.errors.length > 0) {
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
5259
|
+
return {
|
|
5260
|
+
ok: false,
|
|
5261
|
+
failure: { kind: "yaml-parse-error", errors: parsed.errors }
|
|
5262
|
+
};
|
|
4751
5263
|
}
|
|
4752
5264
|
if (parsed.value === null) {
|
|
4753
|
-
|
|
4754
|
-
got: "non-mapping"
|
|
4755
|
-
});
|
|
4756
|
-
return null;
|
|
5265
|
+
return { ok: false, failure: { kind: "yaml-non-mapping" } };
|
|
4757
5266
|
}
|
|
4758
|
-
return parsed.value;
|
|
5267
|
+
return { ok: true, value: parsed.value };
|
|
4759
5268
|
}
|
|
4760
5269
|
function parseYamlContentForStreamProgress(yamlContent) {
|
|
4761
5270
|
const { normalized, nonEmptyLines } = normalizeYamlContent(yamlContent);
|
|
@@ -4787,20 +5296,25 @@ function processToolCallMatch(text, tc, currentIndex, processedElements, options
|
|
|
4787
5296
|
return currentIndex;
|
|
4788
5297
|
}
|
|
4789
5298
|
addTextSegment(text.slice(currentIndex, tc.startIndex), processedElements);
|
|
4790
|
-
const
|
|
4791
|
-
if (
|
|
4792
|
-
const originalText = text.slice(tc.startIndex, tc.endIndex);
|
|
4793
|
-
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse YAML tool call", {
|
|
4794
|
-
toolCall: originalText
|
|
4795
|
-
});
|
|
4796
|
-
processedElements.push({ type: "text", text: originalText });
|
|
4797
|
-
} else {
|
|
5299
|
+
const result = parseYamlContent(tc.content);
|
|
5300
|
+
if (result.ok) {
|
|
4798
5301
|
processedElements.push({
|
|
4799
5302
|
type: "tool-call",
|
|
4800
5303
|
toolCallId: generateToolCallId(),
|
|
4801
5304
|
toolName: tc.toolName,
|
|
4802
|
-
input: JSON.stringify(
|
|
5305
|
+
input: JSON.stringify(result.value)
|
|
5306
|
+
});
|
|
5307
|
+
} else {
|
|
5308
|
+
const originalText = text.slice(tc.startIndex, tc.endIndex);
|
|
5309
|
+
const cause = yamlFailureCause(result.failure);
|
|
5310
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse YAML tool call", {
|
|
5311
|
+
toolCall: originalText,
|
|
5312
|
+
toolName: tc.toolName,
|
|
5313
|
+
toolCallId: generateToolCallId(),
|
|
5314
|
+
dropReason: "malformed-tool-call-body",
|
|
5315
|
+
cause
|
|
4803
5316
|
});
|
|
5317
|
+
processedElements.push({ type: "text", text: originalText });
|
|
4804
5318
|
}
|
|
4805
5319
|
return tc.endIndex;
|
|
4806
5320
|
}
|
|
@@ -4827,327 +5341,335 @@ function stripTrailingPartialCloseTag(content, toolName) {
|
|
|
4827
5341
|
)}${preservedLeadingWhitespace}`;
|
|
4828
5342
|
return contentWithoutPartial.trimEnd();
|
|
4829
5343
|
}
|
|
4830
|
-
var yamlXmlProtocol = (_protocolOptions) => {
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
args = { value: toolCall.input };
|
|
4842
|
-
}
|
|
5344
|
+
var yamlXmlProtocol = (_protocolOptions) => ({
|
|
5345
|
+
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
5346
|
+
return formatToolsWithPromptTemplate({ tools, toolSystemPromptTemplate });
|
|
5347
|
+
},
|
|
5348
|
+
formatToolCall(toolCall) {
|
|
5349
|
+
let args = {};
|
|
5350
|
+
if (toolCall.input != null) {
|
|
5351
|
+
try {
|
|
5352
|
+
args = JSON.parse(toolCall.input);
|
|
5353
|
+
} catch (e) {
|
|
5354
|
+
args = { value: toolCall.input };
|
|
4843
5355
|
}
|
|
4844
|
-
|
|
4845
|
-
|
|
5356
|
+
}
|
|
5357
|
+
const yamlContent = YAML.stringify(args);
|
|
5358
|
+
return `<${toolCall.toolName}>
|
|
4846
5359
|
${yamlContent}</${toolCall.toolName}>`;
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
}
|
|
5360
|
+
},
|
|
5361
|
+
parseGeneratedText({ text, tools, options }) {
|
|
5362
|
+
const toolNames = extractToolNames(tools);
|
|
5363
|
+
if (toolNames.length === 0) {
|
|
5364
|
+
return [{ type: "text", text }];
|
|
5365
|
+
}
|
|
5366
|
+
const processedElements = [];
|
|
5367
|
+
let currentIndex = 0;
|
|
5368
|
+
let parseText = text;
|
|
5369
|
+
let toolCalls = findToolCalls2(parseText, toolNames);
|
|
5370
|
+
if (toolCalls.length === 0) {
|
|
5371
|
+
const repaired = tryRepairXmlSelfClosingRootWithBody(
|
|
5372
|
+
parseText,
|
|
5373
|
+
toolNames
|
|
5374
|
+
);
|
|
5375
|
+
if (repaired) {
|
|
5376
|
+
const repairedCalls = findToolCalls2(repaired, toolNames);
|
|
5377
|
+
if (repairedCalls.length > 0) {
|
|
5378
|
+
parseText = repaired;
|
|
5379
|
+
toolCalls = repairedCalls;
|
|
4868
5380
|
}
|
|
4869
5381
|
}
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
5382
|
+
}
|
|
5383
|
+
for (const tc of toolCalls) {
|
|
5384
|
+
currentIndex = processToolCallMatch(
|
|
5385
|
+
parseText,
|
|
5386
|
+
tc,
|
|
5387
|
+
currentIndex,
|
|
5388
|
+
processedElements,
|
|
5389
|
+
options
|
|
5390
|
+
);
|
|
5391
|
+
}
|
|
5392
|
+
if (currentIndex < parseText.length) {
|
|
5393
|
+
addTextSegment(parseText.slice(currentIndex), processedElements);
|
|
5394
|
+
}
|
|
5395
|
+
return processedElements;
|
|
5396
|
+
},
|
|
5397
|
+
createStreamParser({ tools, options }) {
|
|
5398
|
+
const toolNames = extractToolNames(tools);
|
|
5399
|
+
let buffer = "";
|
|
5400
|
+
let currentToolCall = null;
|
|
5401
|
+
let currentTextId = null;
|
|
5402
|
+
let hasEmittedTextStart = false;
|
|
5403
|
+
const flushText = createFlushTextHandler(
|
|
5404
|
+
() => currentTextId,
|
|
5405
|
+
(newId) => {
|
|
5406
|
+
currentTextId = newId;
|
|
5407
|
+
},
|
|
5408
|
+
() => hasEmittedTextStart,
|
|
5409
|
+
(value) => {
|
|
5410
|
+
hasEmittedTextStart = value;
|
|
4878
5411
|
}
|
|
4879
|
-
|
|
4880
|
-
|
|
5412
|
+
);
|
|
5413
|
+
const emitToolInputProgress2 = (controller, toolContent) => {
|
|
5414
|
+
if (!currentToolCall) {
|
|
5415
|
+
return;
|
|
4881
5416
|
}
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
);
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
toolName: currentToolCall.name,
|
|
4910
|
-
args: parsedArgs,
|
|
5417
|
+
const parsedArgs = parseYamlContentForStreamProgress(toolContent);
|
|
5418
|
+
if (parsedArgs === null) {
|
|
5419
|
+
return;
|
|
5420
|
+
}
|
|
5421
|
+
const fullInput = stringifyToolInputWithSchema({
|
|
5422
|
+
toolName: currentToolCall.name,
|
|
5423
|
+
args: parsedArgs,
|
|
5424
|
+
tools
|
|
5425
|
+
});
|
|
5426
|
+
if (fullInput === "{}" && toolContent.trim().length === 0) {
|
|
5427
|
+
return;
|
|
5428
|
+
}
|
|
5429
|
+
emitToolInputProgressDelta({
|
|
5430
|
+
controller,
|
|
5431
|
+
id: currentToolCall.toolCallId,
|
|
5432
|
+
state: currentToolCall,
|
|
5433
|
+
fullInput
|
|
5434
|
+
});
|
|
5435
|
+
};
|
|
5436
|
+
const processToolCallEnd = (controller, toolContent, toolName, toolCallId) => {
|
|
5437
|
+
var _a;
|
|
5438
|
+
const result = parseYamlContent(toolContent);
|
|
5439
|
+
flushText(controller);
|
|
5440
|
+
if (result.ok) {
|
|
5441
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
5442
|
+
toolName,
|
|
5443
|
+
args: result.value,
|
|
4911
5444
|
tools
|
|
4912
5445
|
});
|
|
4913
|
-
if (
|
|
4914
|
-
|
|
4915
|
-
}
|
|
4916
|
-
emitToolInputProgressDelta({
|
|
4917
|
-
controller,
|
|
4918
|
-
id: currentToolCall.toolCallId,
|
|
4919
|
-
state: currentToolCall,
|
|
4920
|
-
fullInput
|
|
4921
|
-
});
|
|
4922
|
-
};
|
|
4923
|
-
const processToolCallEnd = (controller, toolContent, toolName, toolCallId) => {
|
|
4924
|
-
var _a;
|
|
4925
|
-
const parsedArgs = parseYamlContent(toolContent, options);
|
|
4926
|
-
flushText(controller);
|
|
4927
|
-
if (parsedArgs === null) {
|
|
4928
|
-
const original = `<${toolName}>${toolContent}</${toolName}>`;
|
|
4929
|
-
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
4930
|
-
emitFailedToolInputLifecycle({
|
|
5446
|
+
if (currentToolCall && currentToolCall.toolCallId === toolCallId) {
|
|
5447
|
+
emitFinalizedToolInputLifecycle({
|
|
4931
5448
|
controller,
|
|
4932
5449
|
id: toolCallId,
|
|
4933
|
-
|
|
4934
|
-
rawToolCallText: original,
|
|
4935
|
-
emitRawText: (rawText) => {
|
|
4936
|
-
flushText(controller, rawText);
|
|
4937
|
-
}
|
|
4938
|
-
});
|
|
4939
|
-
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse streaming YAML tool call", {
|
|
4940
|
-
toolCall: original
|
|
4941
|
-
});
|
|
4942
|
-
} else {
|
|
4943
|
-
const finalInput = stringifyToolInputWithSchema({
|
|
5450
|
+
state: currentToolCall,
|
|
4944
5451
|
toolName,
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
});
|
|
4948
|
-
if (currentToolCall && currentToolCall.toolCallId === toolCallId) {
|
|
4949
|
-
emitFinalizedToolInputLifecycle({
|
|
4950
|
-
controller,
|
|
4951
|
-
id: toolCallId,
|
|
4952
|
-
state: currentToolCall,
|
|
4953
|
-
toolName,
|
|
4954
|
-
finalInput,
|
|
4955
|
-
onMismatch: options == null ? void 0 : options.onError
|
|
4956
|
-
});
|
|
4957
|
-
} else {
|
|
4958
|
-
enqueueToolInputEndAndCall({
|
|
4959
|
-
controller,
|
|
4960
|
-
id: toolCallId,
|
|
4961
|
-
toolName,
|
|
4962
|
-
input: finalInput
|
|
4963
|
-
});
|
|
4964
|
-
}
|
|
4965
|
-
}
|
|
4966
|
-
};
|
|
4967
|
-
const finalizeUnclosedToolCall = (controller) => {
|
|
4968
|
-
var _a;
|
|
4969
|
-
if (!currentToolCall) {
|
|
4970
|
-
return;
|
|
4971
|
-
}
|
|
4972
|
-
emitToolInputProgress2(controller, buffer);
|
|
4973
|
-
const { name: toolName, toolCallId } = currentToolCall;
|
|
4974
|
-
const reconciledBuffer = stripTrailingPartialCloseTag(buffer, toolName);
|
|
4975
|
-
const parsedArgs = parseYamlContent(reconciledBuffer, options);
|
|
4976
|
-
flushText(controller);
|
|
4977
|
-
if (parsedArgs === null) {
|
|
4978
|
-
const unfinishedContent = `<${toolName}>${buffer}`;
|
|
4979
|
-
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
4980
|
-
emitFailedToolInputLifecycle({
|
|
4981
|
-
controller,
|
|
4982
|
-
id: toolCallId,
|
|
4983
|
-
emitRawToolCallTextOnError: emitRawFallback,
|
|
4984
|
-
rawToolCallText: unfinishedContent,
|
|
4985
|
-
emitRawText: (rawText) => {
|
|
4986
|
-
flushText(controller, rawText);
|
|
4987
|
-
}
|
|
5452
|
+
finalInput,
|
|
5453
|
+
onMismatch: options == null ? void 0 : options.onError
|
|
4988
5454
|
});
|
|
4989
|
-
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4990
|
-
options,
|
|
4991
|
-
"Could not complete streaming YAML tool call at finish.",
|
|
4992
|
-
{ toolCall: unfinishedContent }
|
|
4993
|
-
);
|
|
4994
5455
|
} else {
|
|
4995
|
-
|
|
4996
|
-
toolName,
|
|
4997
|
-
args: parsedArgs,
|
|
4998
|
-
tools
|
|
4999
|
-
});
|
|
5000
|
-
emitFinalizedToolInputLifecycle({
|
|
5456
|
+
enqueueToolInputEndAndCall({
|
|
5001
5457
|
controller,
|
|
5002
5458
|
id: toolCallId,
|
|
5003
|
-
state: currentToolCall,
|
|
5004
5459
|
toolName,
|
|
5005
|
-
finalInput
|
|
5006
|
-
onMismatch: options == null ? void 0 : options.onError
|
|
5460
|
+
input: finalInput
|
|
5007
5461
|
});
|
|
5008
5462
|
}
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
var _a;
|
|
5014
|
-
const endIdx = buffer.indexOf(endTag);
|
|
5015
|
-
if (endIdx === -1) {
|
|
5016
|
-
emitToolInputProgress2(controller, buffer);
|
|
5017
|
-
return false;
|
|
5018
|
-
}
|
|
5019
|
-
const content = buffer.slice(0, endIdx);
|
|
5020
|
-
emitToolInputProgress2(controller, content);
|
|
5021
|
-
buffer = buffer.slice(endIdx + endTag.length);
|
|
5022
|
-
processToolCallEnd(
|
|
5463
|
+
} else {
|
|
5464
|
+
const original = `<${toolName}>${toolContent}</${toolName}>`;
|
|
5465
|
+
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
5466
|
+
emitFailedToolInputLifecycle({
|
|
5023
5467
|
controller,
|
|
5024
|
-
|
|
5468
|
+
id: toolCallId,
|
|
5469
|
+
emitRawToolCallTextOnError: emitRawFallback,
|
|
5470
|
+
rawToolCallText: original,
|
|
5471
|
+
emitRawText: (rawText) => {
|
|
5472
|
+
flushText(controller, rawText);
|
|
5473
|
+
}
|
|
5474
|
+
});
|
|
5475
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse streaming YAML tool call", {
|
|
5476
|
+
toolCall: original,
|
|
5025
5477
|
toolName,
|
|
5026
|
-
|
|
5478
|
+
toolCallId,
|
|
5479
|
+
dropReason: "malformed-tool-call-body",
|
|
5480
|
+
cause: yamlFailureCause(result.failure)
|
|
5481
|
+
});
|
|
5482
|
+
}
|
|
5483
|
+
};
|
|
5484
|
+
const finalizeUnclosedToolCall = (controller) => {
|
|
5485
|
+
var _a;
|
|
5486
|
+
if (!currentToolCall) {
|
|
5487
|
+
return;
|
|
5488
|
+
}
|
|
5489
|
+
emitToolInputProgress2(controller, buffer);
|
|
5490
|
+
const { name: toolName, toolCallId } = currentToolCall;
|
|
5491
|
+
const reconciledBuffer = stripTrailingPartialCloseTag(buffer, toolName);
|
|
5492
|
+
const result = parseYamlContent(reconciledBuffer);
|
|
5493
|
+
flushText(controller);
|
|
5494
|
+
if (result.ok) {
|
|
5495
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
5496
|
+
toolName,
|
|
5497
|
+
args: result.value,
|
|
5498
|
+
tools
|
|
5499
|
+
});
|
|
5500
|
+
emitFinalizedToolInputLifecycle({
|
|
5501
|
+
controller,
|
|
5502
|
+
id: toolCallId,
|
|
5503
|
+
state: currentToolCall,
|
|
5504
|
+
toolName,
|
|
5505
|
+
finalInput,
|
|
5506
|
+
onMismatch: options == null ? void 0 : options.onError
|
|
5507
|
+
});
|
|
5508
|
+
} else {
|
|
5509
|
+
const unfinishedContent = `<${toolName}>${buffer}`;
|
|
5510
|
+
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
5511
|
+
emitFailedToolInputLifecycle({
|
|
5512
|
+
controller,
|
|
5513
|
+
id: toolCallId,
|
|
5514
|
+
emitRawToolCallTextOnError: emitRawFallback,
|
|
5515
|
+
rawToolCallText: unfinishedContent,
|
|
5516
|
+
emitRawText: (rawText) => {
|
|
5517
|
+
flushText(controller, rawText);
|
|
5518
|
+
}
|
|
5519
|
+
});
|
|
5520
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
5521
|
+
options,
|
|
5522
|
+
"Could not complete streaming YAML tool call at finish.",
|
|
5523
|
+
{
|
|
5524
|
+
toolCall: unfinishedContent,
|
|
5525
|
+
toolCallId,
|
|
5526
|
+
toolName,
|
|
5527
|
+
dropReason: "unfinished-tool-call",
|
|
5528
|
+
cause: yamlFailureCause(result.failure)
|
|
5529
|
+
}
|
|
5027
5530
|
);
|
|
5531
|
+
}
|
|
5532
|
+
buffer = "";
|
|
5533
|
+
currentToolCall = null;
|
|
5534
|
+
};
|
|
5535
|
+
const handlePendingToolCall = (controller, endTag, toolName) => {
|
|
5536
|
+
var _a;
|
|
5537
|
+
const endIdx = buffer.indexOf(endTag);
|
|
5538
|
+
if (endIdx === -1) {
|
|
5539
|
+
emitToolInputProgress2(controller, buffer);
|
|
5540
|
+
return false;
|
|
5541
|
+
}
|
|
5542
|
+
const content = buffer.slice(0, endIdx);
|
|
5543
|
+
emitToolInputProgress2(controller, content);
|
|
5544
|
+
buffer = buffer.slice(endIdx + endTag.length);
|
|
5545
|
+
processToolCallEnd(
|
|
5546
|
+
controller,
|
|
5547
|
+
content,
|
|
5548
|
+
toolName,
|
|
5549
|
+
(_a = currentToolCall == null ? void 0 : currentToolCall.toolCallId) != null ? _a : generateToolCallId()
|
|
5550
|
+
);
|
|
5551
|
+
currentToolCall = null;
|
|
5552
|
+
return true;
|
|
5553
|
+
};
|
|
5554
|
+
const flushSafeText = (controller) => {
|
|
5555
|
+
const maxTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n} />`.length)) : 0;
|
|
5556
|
+
const tail = Math.max(0, maxTagLen - 1);
|
|
5557
|
+
const safeLen = Math.max(0, buffer.length - tail);
|
|
5558
|
+
if (safeLen > 0) {
|
|
5559
|
+
flushText(controller, buffer.slice(0, safeLen));
|
|
5560
|
+
buffer = buffer.slice(safeLen);
|
|
5561
|
+
}
|
|
5562
|
+
};
|
|
5563
|
+
const handleNewToolTag = (controller, tagIndex, tagName, selfClosing, tagLength) => {
|
|
5564
|
+
if (tagIndex > 0) {
|
|
5565
|
+
flushText(controller, buffer.slice(0, tagIndex));
|
|
5566
|
+
}
|
|
5567
|
+
flushText(controller);
|
|
5568
|
+
if (selfClosing) {
|
|
5569
|
+
buffer = buffer.slice(tagIndex + tagLength);
|
|
5570
|
+
const toolCallId = generateToolCallId();
|
|
5571
|
+
currentToolCall = {
|
|
5572
|
+
name: tagName,
|
|
5573
|
+
toolCallId,
|
|
5574
|
+
emittedInput: ""
|
|
5575
|
+
};
|
|
5576
|
+
controller.enqueue({
|
|
5577
|
+
type: "tool-input-start",
|
|
5578
|
+
id: toolCallId,
|
|
5579
|
+
toolName: tagName
|
|
5580
|
+
});
|
|
5581
|
+
processToolCallEnd(controller, "", tagName, toolCallId);
|
|
5028
5582
|
currentToolCall = null;
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
const
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
};
|
|
5053
|
-
controller.enqueue({
|
|
5054
|
-
type: "tool-input-start",
|
|
5055
|
-
id: toolCallId,
|
|
5056
|
-
toolName: tagName
|
|
5057
|
-
});
|
|
5058
|
-
processToolCallEnd(controller, "", tagName, toolCallId);
|
|
5059
|
-
currentToolCall = null;
|
|
5583
|
+
} else {
|
|
5584
|
+
const startTag = `<${tagName}>`;
|
|
5585
|
+
buffer = buffer.slice(tagIndex + startTag.length);
|
|
5586
|
+
currentToolCall = {
|
|
5587
|
+
name: tagName,
|
|
5588
|
+
toolCallId: generateToolCallId(),
|
|
5589
|
+
emittedInput: ""
|
|
5590
|
+
};
|
|
5591
|
+
controller.enqueue({
|
|
5592
|
+
type: "tool-input-start",
|
|
5593
|
+
id: currentToolCall.toolCallId,
|
|
5594
|
+
toolName: tagName
|
|
5595
|
+
});
|
|
5596
|
+
}
|
|
5597
|
+
};
|
|
5598
|
+
const processBuffer = (controller) => {
|
|
5599
|
+
while (true) {
|
|
5600
|
+
if (currentToolCall) {
|
|
5601
|
+
const toolName = currentToolCall.name;
|
|
5602
|
+
const endTag = `</${toolName}>`;
|
|
5603
|
+
if (!handlePendingToolCall(controller, endTag, toolName)) {
|
|
5604
|
+
break;
|
|
5605
|
+
}
|
|
5060
5606
|
} else {
|
|
5061
|
-
const
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
controller.enqueue({
|
|
5069
|
-
type: "tool-input-start",
|
|
5070
|
-
id: currentToolCall.toolCallId,
|
|
5071
|
-
toolName: tagName
|
|
5072
|
-
});
|
|
5073
|
-
}
|
|
5074
|
-
};
|
|
5075
|
-
const processBuffer = (controller) => {
|
|
5076
|
-
while (true) {
|
|
5077
|
-
if (currentToolCall) {
|
|
5078
|
-
const toolName = currentToolCall.name;
|
|
5079
|
-
const endTag = `</${toolName}>`;
|
|
5080
|
-
if (!handlePendingToolCall(controller, endTag, toolName)) {
|
|
5081
|
-
break;
|
|
5082
|
-
}
|
|
5083
|
-
} else {
|
|
5084
|
-
const { index, name, selfClosing, tagLength } = findEarliestToolTag(
|
|
5085
|
-
buffer,
|
|
5086
|
-
toolNames
|
|
5087
|
-
);
|
|
5088
|
-
if (index === -1) {
|
|
5089
|
-
flushSafeText(controller);
|
|
5090
|
-
break;
|
|
5091
|
-
}
|
|
5092
|
-
handleNewToolTag(controller, index, name, selfClosing, tagLength);
|
|
5607
|
+
const { index, name, selfClosing, tagLength } = findEarliestToolTag(
|
|
5608
|
+
buffer,
|
|
5609
|
+
toolNames
|
|
5610
|
+
);
|
|
5611
|
+
if (index === -1) {
|
|
5612
|
+
flushSafeText(controller);
|
|
5613
|
+
break;
|
|
5093
5614
|
}
|
|
5615
|
+
handleNewToolTag(controller, index, name, selfClosing, tagLength);
|
|
5094
5616
|
}
|
|
5095
|
-
}
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
finalizeUnclosedToolCall(controller);
|
|
5102
|
-
} else if (buffer) {
|
|
5103
|
-
flushText(controller, buffer);
|
|
5104
|
-
buffer = "";
|
|
5105
|
-
}
|
|
5106
|
-
flushText(controller);
|
|
5107
|
-
controller.enqueue(chunk);
|
|
5108
|
-
return;
|
|
5109
|
-
}
|
|
5110
|
-
if (chunk.type !== "text-delta") {
|
|
5111
|
-
if (!currentToolCall && buffer) {
|
|
5112
|
-
flushText(controller, buffer);
|
|
5113
|
-
buffer = "";
|
|
5114
|
-
}
|
|
5115
|
-
controller.enqueue(chunk);
|
|
5116
|
-
return;
|
|
5117
|
-
}
|
|
5118
|
-
const textContent = (_a = chunk.delta) != null ? _a : "";
|
|
5119
|
-
buffer += textContent;
|
|
5120
|
-
processBuffer(controller);
|
|
5121
|
-
},
|
|
5122
|
-
flush(controller) {
|
|
5617
|
+
}
|
|
5618
|
+
};
|
|
5619
|
+
return new TransformStream({
|
|
5620
|
+
transform(chunk, controller) {
|
|
5621
|
+
var _a;
|
|
5622
|
+
if (chunk.type === "finish") {
|
|
5123
5623
|
if (currentToolCall) {
|
|
5124
5624
|
finalizeUnclosedToolCall(controller);
|
|
5125
5625
|
} else if (buffer) {
|
|
5126
5626
|
flushText(controller, buffer);
|
|
5127
5627
|
buffer = "";
|
|
5128
5628
|
}
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5629
|
+
flushText(controller);
|
|
5630
|
+
controller.enqueue(chunk);
|
|
5631
|
+
return;
|
|
5632
|
+
}
|
|
5633
|
+
if (chunk.type !== "text-delta") {
|
|
5634
|
+
if (!currentToolCall && buffer) {
|
|
5635
|
+
flushText(controller, buffer);
|
|
5636
|
+
buffer = "";
|
|
5136
5637
|
}
|
|
5638
|
+
controller.enqueue(chunk);
|
|
5639
|
+
return;
|
|
5640
|
+
}
|
|
5641
|
+
const textContent = (_a = chunk.delta) != null ? _a : "";
|
|
5642
|
+
buffer += textContent;
|
|
5643
|
+
processBuffer(controller);
|
|
5644
|
+
},
|
|
5645
|
+
flush(controller) {
|
|
5646
|
+
if (currentToolCall) {
|
|
5647
|
+
finalizeUnclosedToolCall(controller);
|
|
5648
|
+
} else if (buffer) {
|
|
5649
|
+
flushText(controller, buffer);
|
|
5650
|
+
buffer = "";
|
|
5651
|
+
}
|
|
5652
|
+
if (currentTextId && hasEmittedTextStart) {
|
|
5653
|
+
controller.enqueue({
|
|
5654
|
+
type: "text-end",
|
|
5655
|
+
id: currentTextId
|
|
5656
|
+
});
|
|
5657
|
+
hasEmittedTextStart = false;
|
|
5658
|
+
currentTextId = null;
|
|
5137
5659
|
}
|
|
5138
|
-
});
|
|
5139
|
-
},
|
|
5140
|
-
extractToolCallSegments({ text, tools }) {
|
|
5141
|
-
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
5142
|
-
if (toolNames.length === 0) {
|
|
5143
|
-
return [];
|
|
5144
5660
|
}
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5661
|
+
});
|
|
5662
|
+
},
|
|
5663
|
+
extractToolCallSegments({ text, tools }) {
|
|
5664
|
+
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
5665
|
+
if (toolNames.length === 0) {
|
|
5666
|
+
return [];
|
|
5148
5667
|
}
|
|
5149
|
-
|
|
5150
|
-
}
|
|
5668
|
+
return findToolCalls2(text, toolNames).map(
|
|
5669
|
+
(tc) => `<${tc.toolName}>${tc.content}</${tc.toolName}>`
|
|
5670
|
+
);
|
|
5671
|
+
}
|
|
5672
|
+
});
|
|
5151
5673
|
|
|
5152
5674
|
// src/core/utils/dynamic-tool-schema.ts
|
|
5153
5675
|
function createDynamicIfThenElseSchema(tools) {
|
|
@@ -5343,7 +5865,7 @@ function parseJsonCandidate(candidateText) {
|
|
|
5343
5865
|
try {
|
|
5344
5866
|
return parse(candidateText);
|
|
5345
5867
|
} catch (e) {
|
|
5346
|
-
return
|
|
5868
|
+
return;
|
|
5347
5869
|
}
|
|
5348
5870
|
}
|
|
5349
5871
|
function extractCodeBlockCandidates(text) {
|
|
@@ -7327,4 +7849,4 @@ export {
|
|
|
7327
7849
|
morphXmlToolMiddleware,
|
|
7328
7850
|
yamlXmlToolMiddleware
|
|
7329
7851
|
};
|
|
7330
|
-
//# sourceMappingURL=chunk-
|
|
7852
|
+
//# sourceMappingURL=chunk-DKZ4GAQM.js.map
|