@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
package/dist/community.cjs
CHANGED
|
@@ -4645,13 +4645,312 @@ function shouldEmitRawToolCallTextOnError(options) {
|
|
|
4645
4645
|
}
|
|
4646
4646
|
|
|
4647
4647
|
// src/core/protocols/hermes-protocol.ts
|
|
4648
|
+
var RJSON_IDENTIFIER_CHAR_REGEX = /[$a-zA-Z0-9_\-+.*?!|&%^/#\\]/;
|
|
4649
|
+
var RJSON_NUMBER_TOKEN_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
4650
|
+
function validateNonEmptyDelimiters(toolCallStart, toolCallEnd) {
|
|
4651
|
+
if (toolCallStart.length === 0) {
|
|
4652
|
+
throw new TypeError("hermesProtocol toolCallStart must not be empty");
|
|
4653
|
+
}
|
|
4654
|
+
if (toolCallEnd.length === 0) {
|
|
4655
|
+
throw new TypeError("hermesProtocol toolCallEnd must not be empty");
|
|
4656
|
+
}
|
|
4657
|
+
return {};
|
|
4658
|
+
}
|
|
4659
|
+
function isRjsonIdentifierChar(ch) {
|
|
4660
|
+
return ch != null && RJSON_IDENTIFIER_CHAR_REGEX.test(ch);
|
|
4661
|
+
}
|
|
4662
|
+
function isRjsonPropertyLikeDelimiter(startTag) {
|
|
4663
|
+
const key = startTag.endsWith(":") ? startTag.slice(0, -1) : "";
|
|
4664
|
+
return key.length > 0 && [...key].every((ch) => isRjsonIdentifierChar(ch));
|
|
4665
|
+
}
|
|
4666
|
+
function previousRjsonToken(json, index, minIndex = 0) {
|
|
4667
|
+
let start = index - 1;
|
|
4668
|
+
while (start >= minIndex && isRjsonIdentifierChar(json[start])) {
|
|
4669
|
+
start -= 1;
|
|
4670
|
+
}
|
|
4671
|
+
return json.slice(start + 1, index);
|
|
4672
|
+
}
|
|
4673
|
+
function previousTokenAllowsComment(json, index, minIndex = 0) {
|
|
4674
|
+
const previous = previousRjsonToken(json, index, minIndex);
|
|
4675
|
+
if (previous.length === 0) {
|
|
4676
|
+
return true;
|
|
4677
|
+
}
|
|
4678
|
+
return RJSON_NUMBER_TOKEN_REGEX.test(previous) || previous === "true" || previous === "false" || previous === "null";
|
|
4679
|
+
}
|
|
4680
|
+
function startsRjsonComment(json, index, minIndex = 0) {
|
|
4681
|
+
if (!(json[index] === "/" && json[index + 1] === "/" || json[index] === "/" && json[index + 1] === "*")) {
|
|
4682
|
+
return false;
|
|
4683
|
+
}
|
|
4684
|
+
if (index > minIndex && isRjsonIdentifierChar(json[index - 1])) {
|
|
4685
|
+
return previousTokenAllowsComment(json, index, minIndex);
|
|
4686
|
+
}
|
|
4687
|
+
return true;
|
|
4688
|
+
}
|
|
4689
|
+
function hasNestedStartBoundary(segment, startIndex) {
|
|
4690
|
+
const previous = segment[startIndex - 1];
|
|
4691
|
+
return previous == null || WHITESPACE_JSON_REGEX.test(previous) || previous === "}";
|
|
4692
|
+
}
|
|
4693
|
+
function isLikelyNestedToolCallStart(segment, startIndex, startTag) {
|
|
4694
|
+
if (isRjsonPropertyLikeDelimiter(startTag)) {
|
|
4695
|
+
return false;
|
|
4696
|
+
}
|
|
4697
|
+
const jsonStart = skipJsonWhitespace(segment, startIndex + startTag.length);
|
|
4698
|
+
return segment[jsonStart] === "{" && hasNestedStartBoundary(segment, startIndex);
|
|
4699
|
+
}
|
|
4700
|
+
function findToolCallBoundaryOutsideRjsonSyntax(text, scanFrom, startTag, endTag) {
|
|
4701
|
+
let quote = null;
|
|
4702
|
+
let esc = false;
|
|
4703
|
+
let inLineComment = false;
|
|
4704
|
+
let inBlockComment = false;
|
|
4705
|
+
let lineCommentSawEndTag = false;
|
|
4706
|
+
let blockCommentSawEndTag = false;
|
|
4707
|
+
let nestedStartIndex = null;
|
|
4708
|
+
for (let index = scanFrom; index < text.length; index += 1) {
|
|
4709
|
+
const ch = text[index];
|
|
4710
|
+
if (esc) {
|
|
4711
|
+
esc = false;
|
|
4712
|
+
continue;
|
|
4713
|
+
}
|
|
4714
|
+
if (quote !== null) {
|
|
4715
|
+
if (ch === "\\") {
|
|
4716
|
+
esc = true;
|
|
4717
|
+
continue;
|
|
4718
|
+
}
|
|
4719
|
+
if (ch === quote) {
|
|
4720
|
+
quote = null;
|
|
4721
|
+
}
|
|
4722
|
+
continue;
|
|
4723
|
+
}
|
|
4724
|
+
if (inLineComment) {
|
|
4725
|
+
if (ch === "\n" || ch === "\r") {
|
|
4726
|
+
inLineComment = false;
|
|
4727
|
+
lineCommentSawEndTag = false;
|
|
4728
|
+
continue;
|
|
4729
|
+
}
|
|
4730
|
+
if (text.startsWith(endTag, index)) {
|
|
4731
|
+
lineCommentSawEndTag = true;
|
|
4732
|
+
index += endTag.length - 1;
|
|
4733
|
+
continue;
|
|
4734
|
+
}
|
|
4735
|
+
if (lineCommentSawEndTag && text.startsWith(startTag, index) && text[skipJsonWhitespace(text, index + startTag.length)] === "{") {
|
|
4736
|
+
nestedStartIndex = index;
|
|
4737
|
+
inLineComment = false;
|
|
4738
|
+
lineCommentSawEndTag = false;
|
|
4739
|
+
index += startTag.length - 1;
|
|
4740
|
+
continue;
|
|
4741
|
+
}
|
|
4742
|
+
continue;
|
|
4743
|
+
}
|
|
4744
|
+
if (inBlockComment) {
|
|
4745
|
+
if (ch === "*" && text[index + 1] === "/") {
|
|
4746
|
+
inBlockComment = false;
|
|
4747
|
+
blockCommentSawEndTag = false;
|
|
4748
|
+
index += 1;
|
|
4749
|
+
continue;
|
|
4750
|
+
}
|
|
4751
|
+
if (text.startsWith(endTag, index)) {
|
|
4752
|
+
blockCommentSawEndTag = true;
|
|
4753
|
+
index += endTag.length - 1;
|
|
4754
|
+
continue;
|
|
4755
|
+
}
|
|
4756
|
+
if (blockCommentSawEndTag && text.startsWith(startTag, index) && text[skipJsonWhitespace(text, index + startTag.length)] === "{") {
|
|
4757
|
+
nestedStartIndex = index;
|
|
4758
|
+
inBlockComment = false;
|
|
4759
|
+
blockCommentSawEndTag = false;
|
|
4760
|
+
index += startTag.length - 1;
|
|
4761
|
+
continue;
|
|
4762
|
+
}
|
|
4763
|
+
continue;
|
|
4764
|
+
}
|
|
4765
|
+
if (startsRjsonComment(text, index, scanFrom)) {
|
|
4766
|
+
if (text[index + 1] === "/") {
|
|
4767
|
+
inLineComment = true;
|
|
4768
|
+
lineCommentSawEndTag = false;
|
|
4769
|
+
index += 1;
|
|
4770
|
+
continue;
|
|
4771
|
+
}
|
|
4772
|
+
if (text[index + 1] === "*") {
|
|
4773
|
+
inBlockComment = true;
|
|
4774
|
+
blockCommentSawEndTag = false;
|
|
4775
|
+
index += 1;
|
|
4776
|
+
continue;
|
|
4777
|
+
}
|
|
4778
|
+
}
|
|
4779
|
+
if (text.startsWith(endTag, index)) {
|
|
4780
|
+
return nestedStartIndex == null ? { kind: "end", endIdx: index } : { kind: "nested", endIdx: index, nestedStartIndex };
|
|
4781
|
+
}
|
|
4782
|
+
if (nestedStartIndex == null && text.startsWith(startTag, index) && isLikelyNestedToolCallStart(text, index, startTag)) {
|
|
4783
|
+
nestedStartIndex = index;
|
|
4784
|
+
index += startTag.length - 1;
|
|
4785
|
+
continue;
|
|
4786
|
+
}
|
|
4787
|
+
if (ch === '"' || ch === "'") {
|
|
4788
|
+
quote = ch;
|
|
4789
|
+
}
|
|
4790
|
+
}
|
|
4791
|
+
return null;
|
|
4792
|
+
}
|
|
4793
|
+
function findNextToolCallSpan(text, searchFrom, startTag, endTag) {
|
|
4794
|
+
const startIdx = text.indexOf(startTag, searchFrom);
|
|
4795
|
+
if (startIdx === -1) {
|
|
4796
|
+
return null;
|
|
4797
|
+
}
|
|
4798
|
+
const jsonStart = startIdx + startTag.length;
|
|
4799
|
+
const boundary = findToolCallBoundaryOutsideRjsonSyntax(
|
|
4800
|
+
text,
|
|
4801
|
+
jsonStart,
|
|
4802
|
+
startTag,
|
|
4803
|
+
endTag
|
|
4804
|
+
);
|
|
4805
|
+
if (boundary == null) {
|
|
4806
|
+
return { startIdx, found: false };
|
|
4807
|
+
}
|
|
4808
|
+
if (boundary.kind === "nested") {
|
|
4809
|
+
return { startIdx, found: false };
|
|
4810
|
+
}
|
|
4811
|
+
return { startIdx, found: true, jsonStart, endIdx: boundary.endIdx };
|
|
4812
|
+
}
|
|
4648
4813
|
function canonicalizeToolInput(argumentsValue) {
|
|
4649
4814
|
return JSON.stringify(argumentsValue != null ? argumentsValue : {});
|
|
4650
4815
|
}
|
|
4816
|
+
var CHAR_CODE_BACKSLASH = 92;
|
|
4817
|
+
var CHAR_CODE_QUOTE = 34;
|
|
4818
|
+
var CHAR_CODE_LF = 10;
|
|
4819
|
+
var CHAR_CODE_CR = 13;
|
|
4820
|
+
var CHAR_CODE_TAB = 9;
|
|
4821
|
+
var CHAR_CODE_SLASH = 47;
|
|
4822
|
+
var CHAR_CODE_STAR = 42;
|
|
4823
|
+
var CHAR_CODE_CONTROL_UPPER = 31;
|
|
4824
|
+
var CHAR_CODE_SINGLE_QUOTE = 39;
|
|
4825
|
+
function hasControlCharInString(json) {
|
|
4826
|
+
let quote = null;
|
|
4827
|
+
let esc = false;
|
|
4828
|
+
for (let i = 0; i < json.length; i += 1) {
|
|
4829
|
+
const code = json.charCodeAt(i);
|
|
4830
|
+
if (esc) {
|
|
4831
|
+
esc = false;
|
|
4832
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
4833
|
+
return true;
|
|
4834
|
+
}
|
|
4835
|
+
continue;
|
|
4836
|
+
}
|
|
4837
|
+
if (quote !== null && code === CHAR_CODE_BACKSLASH) {
|
|
4838
|
+
esc = true;
|
|
4839
|
+
continue;
|
|
4840
|
+
}
|
|
4841
|
+
if (quote !== null) {
|
|
4842
|
+
if (code === quote) {
|
|
4843
|
+
quote = null;
|
|
4844
|
+
continue;
|
|
4845
|
+
}
|
|
4846
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
4847
|
+
return true;
|
|
4848
|
+
}
|
|
4849
|
+
continue;
|
|
4850
|
+
}
|
|
4851
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_SLASH) {
|
|
4852
|
+
i += 2;
|
|
4853
|
+
while (i < json.length && json.charCodeAt(i) !== CHAR_CODE_LF && json.charCodeAt(i) !== CHAR_CODE_CR) {
|
|
4854
|
+
i += 1;
|
|
4855
|
+
}
|
|
4856
|
+
continue;
|
|
4857
|
+
}
|
|
4858
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_STAR) {
|
|
4859
|
+
i += 2;
|
|
4860
|
+
while (i + 1 < json.length && !(json.charCodeAt(i) === CHAR_CODE_STAR && json.charCodeAt(i + 1) === CHAR_CODE_SLASH)) {
|
|
4861
|
+
i += 1;
|
|
4862
|
+
}
|
|
4863
|
+
i += 1;
|
|
4864
|
+
continue;
|
|
4865
|
+
}
|
|
4866
|
+
if (code === CHAR_CODE_QUOTE || code === CHAR_CODE_SINGLE_QUOTE) {
|
|
4867
|
+
quote = code;
|
|
4868
|
+
}
|
|
4869
|
+
}
|
|
4870
|
+
return false;
|
|
4871
|
+
}
|
|
4872
|
+
function normalizeJsonStringCtrl(json) {
|
|
4873
|
+
if (!hasControlCharInString(json)) {
|
|
4874
|
+
return json;
|
|
4875
|
+
}
|
|
4876
|
+
const parts = [];
|
|
4877
|
+
let chunkStart = 0;
|
|
4878
|
+
let quote = null;
|
|
4879
|
+
let esc = false;
|
|
4880
|
+
const flushUpTo = (end) => {
|
|
4881
|
+
if (chunkStart < end) {
|
|
4882
|
+
parts.push(json.slice(chunkStart, end));
|
|
4883
|
+
}
|
|
4884
|
+
};
|
|
4885
|
+
const escapeForCode = (code) => {
|
|
4886
|
+
switch (code) {
|
|
4887
|
+
case CHAR_CODE_LF:
|
|
4888
|
+
return "\\n";
|
|
4889
|
+
case CHAR_CODE_CR:
|
|
4890
|
+
return "\\r";
|
|
4891
|
+
case CHAR_CODE_TAB:
|
|
4892
|
+
return "\\t";
|
|
4893
|
+
default:
|
|
4894
|
+
return `\\u${code.toString(16).padStart(4, "0")}`;
|
|
4895
|
+
}
|
|
4896
|
+
};
|
|
4897
|
+
for (let i = 0; i < json.length; i += 1) {
|
|
4898
|
+
const code = json.charCodeAt(i);
|
|
4899
|
+
if (esc) {
|
|
4900
|
+
esc = false;
|
|
4901
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
4902
|
+
flushUpTo(i - 1);
|
|
4903
|
+
parts.push(escapeForCode(code));
|
|
4904
|
+
chunkStart = i + 1;
|
|
4905
|
+
}
|
|
4906
|
+
continue;
|
|
4907
|
+
}
|
|
4908
|
+
if (quote !== null && code === CHAR_CODE_BACKSLASH) {
|
|
4909
|
+
esc = true;
|
|
4910
|
+
continue;
|
|
4911
|
+
}
|
|
4912
|
+
if (quote !== null) {
|
|
4913
|
+
if (code === quote) {
|
|
4914
|
+
quote = null;
|
|
4915
|
+
continue;
|
|
4916
|
+
}
|
|
4917
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
4918
|
+
flushUpTo(i);
|
|
4919
|
+
parts.push(escapeForCode(code));
|
|
4920
|
+
chunkStart = i + 1;
|
|
4921
|
+
}
|
|
4922
|
+
continue;
|
|
4923
|
+
}
|
|
4924
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_SLASH) {
|
|
4925
|
+
i += 2;
|
|
4926
|
+
while (i < json.length && json.charCodeAt(i) !== CHAR_CODE_LF && json.charCodeAt(i) !== CHAR_CODE_CR) {
|
|
4927
|
+
i += 1;
|
|
4928
|
+
}
|
|
4929
|
+
continue;
|
|
4930
|
+
}
|
|
4931
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_STAR) {
|
|
4932
|
+
i += 2;
|
|
4933
|
+
while (i + 1 < json.length && !(json.charCodeAt(i) === CHAR_CODE_STAR && json.charCodeAt(i + 1) === CHAR_CODE_SLASH)) {
|
|
4934
|
+
i += 1;
|
|
4935
|
+
}
|
|
4936
|
+
i += 1;
|
|
4937
|
+
continue;
|
|
4938
|
+
}
|
|
4939
|
+
if (code === CHAR_CODE_QUOTE || code === CHAR_CODE_SINGLE_QUOTE) {
|
|
4940
|
+
quote = code;
|
|
4941
|
+
}
|
|
4942
|
+
}
|
|
4943
|
+
if (chunkStart < json.length) {
|
|
4944
|
+
parts.push(json.slice(chunkStart));
|
|
4945
|
+
}
|
|
4946
|
+
return parts.join("");
|
|
4947
|
+
}
|
|
4651
4948
|
function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
|
|
4652
4949
|
var _a;
|
|
4653
4950
|
try {
|
|
4654
|
-
const parsedToolCall = parse3(
|
|
4951
|
+
const parsedToolCall = parse3(
|
|
4952
|
+
normalizeJsonStringCtrl(toolCallJson)
|
|
4953
|
+
);
|
|
4655
4954
|
processedElements.push({
|
|
4656
4955
|
type: "tool-call",
|
|
4657
4956
|
toolCallId: generateToolCallId(),
|
|
@@ -4659,6 +4958,8 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
4659
4958
|
input: canonicalizeToolInput(parsedToolCall.arguments)
|
|
4660
4959
|
});
|
|
4661
4960
|
} catch (error) {
|
|
4961
|
+
const salvagedToolName = extractStreamingToolCallProgress(toolCallJson).toolName;
|
|
4962
|
+
const salvagedToolCallId = generateToolCallId();
|
|
4662
4963
|
logParseFailure({
|
|
4663
4964
|
phase: "generated-text",
|
|
4664
4965
|
reason: "Failed to parse tool call JSON segment",
|
|
@@ -4668,24 +4969,17 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
4668
4969
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4669
4970
|
options,
|
|
4670
4971
|
"Could not process JSON tool call, keeping original text.",
|
|
4671
|
-
{
|
|
4972
|
+
{
|
|
4973
|
+
toolCall: fullMatch,
|
|
4974
|
+
error,
|
|
4975
|
+
toolName: salvagedToolName,
|
|
4976
|
+
toolCallId: salvagedToolCallId,
|
|
4977
|
+
dropReason: "malformed-tool-call-body"
|
|
4978
|
+
}
|
|
4672
4979
|
);
|
|
4673
4980
|
processedElements.push({ type: "text", text: fullMatch });
|
|
4674
4981
|
}
|
|
4675
4982
|
}
|
|
4676
|
-
function processMatchedToolCall(context) {
|
|
4677
|
-
const { match, text, currentIndex, processedElements, options } = context;
|
|
4678
|
-
const startIndex = match.index;
|
|
4679
|
-
const toolCallJson = match[1];
|
|
4680
|
-
if (startIndex > currentIndex) {
|
|
4681
|
-
const textSegment = text.slice(currentIndex, startIndex);
|
|
4682
|
-
addTextSegment(textSegment, processedElements);
|
|
4683
|
-
}
|
|
4684
|
-
if (toolCallJson) {
|
|
4685
|
-
processToolCallJson(toolCallJson, match[0], processedElements, options);
|
|
4686
|
-
}
|
|
4687
|
-
return startIndex + match[0].length;
|
|
4688
|
-
}
|
|
4689
4983
|
var WHITESPACE_JSON_REGEX = /\s/;
|
|
4690
4984
|
function skipJsonWhitespace(text, fromIndex) {
|
|
4691
4985
|
let index = fromIndex;
|
|
@@ -4952,7 +5246,9 @@ function canonicalizeArgumentsProgressInput(progress, toolName, tools) {
|
|
|
4952
5246
|
return void 0;
|
|
4953
5247
|
}
|
|
4954
5248
|
try {
|
|
4955
|
-
const parsedArguments = parse3(
|
|
5249
|
+
const parsedArguments = parse3(
|
|
5250
|
+
normalizeJsonStringCtrl(progress.argumentsText)
|
|
5251
|
+
);
|
|
4956
5252
|
return stringifyToolInputWithSchema({
|
|
4957
5253
|
toolName,
|
|
4958
5254
|
args: parsedArguments,
|
|
@@ -5012,14 +5308,16 @@ function closeTextBlock(state, controller) {
|
|
|
5012
5308
|
}
|
|
5013
5309
|
}
|
|
5014
5310
|
function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer, tools, options) {
|
|
5015
|
-
var _a;
|
|
5311
|
+
var _a, _b, _c, _d;
|
|
5016
5312
|
if (!state.currentToolCallJson && trailingBuffer.length === 0) {
|
|
5017
5313
|
state.isInsideToolCall = false;
|
|
5018
5314
|
return;
|
|
5019
5315
|
}
|
|
5020
5316
|
if (state.currentToolCallJson) {
|
|
5021
5317
|
try {
|
|
5022
|
-
const parsedToolCall = parse3(
|
|
5318
|
+
const parsedToolCall = parse3(
|
|
5319
|
+
normalizeJsonStringCtrl(state.currentToolCallJson)
|
|
5320
|
+
);
|
|
5023
5321
|
emitToolCallFromParsed(state, controller, parsedToolCall, tools);
|
|
5024
5322
|
state.currentToolCallJson = "";
|
|
5025
5323
|
state.isInsideToolCall = false;
|
|
@@ -5051,11 +5349,19 @@ function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer
|
|
|
5051
5349
|
id: errorId
|
|
5052
5350
|
});
|
|
5053
5351
|
}
|
|
5352
|
+
const streamingToolCallId = (_b = (_a = state.activeToolInput) == null ? void 0 : _a.id) != null ? _b : generateToolCallId();
|
|
5353
|
+
const streamingToolName = (_c = state.activeToolInput) == null ? void 0 : _c.toolName;
|
|
5054
5354
|
closeToolInput(state, controller);
|
|
5055
|
-
|
|
5355
|
+
const toolName = streamingToolName != null ? streamingToolName : state.currentToolCallJson ? extractStreamingToolCallProgress(state.currentToolCallJson).toolName : void 0;
|
|
5356
|
+
(_d = options == null ? void 0 : options.onError) == null ? void 0 : _d.call(
|
|
5056
5357
|
options,
|
|
5057
5358
|
shouldEmitRawFallback ? "Could not complete streaming JSON tool call at finish; emitting original text." : "Could not complete streaming JSON tool call at finish.",
|
|
5058
|
-
{
|
|
5359
|
+
{
|
|
5360
|
+
toolCall: errorContent,
|
|
5361
|
+
toolCallId: streamingToolCallId,
|
|
5362
|
+
toolName,
|
|
5363
|
+
dropReason: "unfinished-tool-call"
|
|
5364
|
+
}
|
|
5059
5365
|
);
|
|
5060
5366
|
state.currentToolCallJson = "";
|
|
5061
5367
|
state.isInsideToolCall = false;
|
|
@@ -5100,14 +5406,18 @@ function publishText(text, state, controller, tools) {
|
|
|
5100
5406
|
}
|
|
5101
5407
|
}
|
|
5102
5408
|
function emitToolCall(context) {
|
|
5103
|
-
var _a;
|
|
5409
|
+
var _a, _b, _c, _d, _e;
|
|
5104
5410
|
const { state, controller, toolCallStart, toolCallEnd, options, tools } = context;
|
|
5105
5411
|
try {
|
|
5106
|
-
const parsedToolCall = parse3(
|
|
5412
|
+
const parsedToolCall = parse3(
|
|
5413
|
+
normalizeJsonStringCtrl(state.currentToolCallJson)
|
|
5414
|
+
);
|
|
5107
5415
|
emitToolCallFromParsed(state, controller, parsedToolCall, tools);
|
|
5108
5416
|
} catch (error) {
|
|
5109
5417
|
const errorContent = `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`;
|
|
5110
5418
|
const shouldEmitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
5419
|
+
const streamingToolCallId = (_b = (_a = state.activeToolInput) == null ? void 0 : _a.id) != null ? _b : generateToolCallId();
|
|
5420
|
+
const streamingToolName = (_d = (_c = state.activeToolInput) == null ? void 0 : _c.toolName) != null ? _d : extractStreamingToolCallProgress(state.currentToolCallJson).toolName;
|
|
5111
5421
|
logParseFailure({
|
|
5112
5422
|
phase: "stream",
|
|
5113
5423
|
reason: "Failed to parse streaming tool call JSON segment",
|
|
@@ -5131,11 +5441,15 @@ function emitToolCall(context) {
|
|
|
5131
5441
|
});
|
|
5132
5442
|
}
|
|
5133
5443
|
closeToolInput(state, controller);
|
|
5134
|
-
(
|
|
5444
|
+
(_e = options == null ? void 0 : options.onError) == null ? void 0 : _e.call(
|
|
5135
5445
|
options,
|
|
5136
5446
|
shouldEmitRawFallback ? "Could not process streaming JSON tool call; emitting original text." : "Could not process streaming JSON tool call.",
|
|
5137
5447
|
{
|
|
5138
|
-
toolCall: errorContent
|
|
5448
|
+
toolCall: errorContent,
|
|
5449
|
+
error,
|
|
5450
|
+
toolCallId: streamingToolCallId,
|
|
5451
|
+
toolName: streamingToolName,
|
|
5452
|
+
dropReason: "malformed-tool-call-body"
|
|
5139
5453
|
}
|
|
5140
5454
|
);
|
|
5141
5455
|
}
|
|
@@ -5152,24 +5466,118 @@ function processTagMatch(context) {
|
|
|
5152
5466
|
state.activeToolInput = null;
|
|
5153
5467
|
}
|
|
5154
5468
|
}
|
|
5155
|
-
function
|
|
5469
|
+
function recoverNestedStreamingToolCall(options) {
|
|
5470
|
+
var _a, _b, _c, _d;
|
|
5471
|
+
const { context, jsonSoFar, nestedStartIndex, startIndex, tag } = options;
|
|
5472
|
+
const {
|
|
5473
|
+
state,
|
|
5474
|
+
controller,
|
|
5475
|
+
toolCallStart,
|
|
5476
|
+
toolCallEnd,
|
|
5477
|
+
options: parserOptions
|
|
5478
|
+
} = context;
|
|
5479
|
+
const droppedToolCall = `${toolCallStart}${jsonSoFar.slice(
|
|
5480
|
+
0,
|
|
5481
|
+
nestedStartIndex
|
|
5482
|
+
)}`;
|
|
5483
|
+
const shouldEmitRawFallback = shouldEmitRawToolCallTextOnError(parserOptions);
|
|
5484
|
+
const streamingToolCallId = (_a = state.activeToolInput) == null ? void 0 : _a.id;
|
|
5485
|
+
const streamingToolName = (_c = (_b = state.activeToolInput) == null ? void 0 : _b.toolName) != null ? _c : extractStreamingToolCallProgress(jsonSoFar.slice(0, nestedStartIndex)).toolName;
|
|
5486
|
+
logParseFailure({
|
|
5487
|
+
phase: "stream",
|
|
5488
|
+
reason: "Abandoning malformed streaming tool call before nested start tag",
|
|
5489
|
+
snippet: droppedToolCall
|
|
5490
|
+
});
|
|
5491
|
+
if (shouldEmitRawFallback) {
|
|
5492
|
+
const errorId = generateId();
|
|
5493
|
+
controller.enqueue({
|
|
5494
|
+
type: "text-start",
|
|
5495
|
+
id: errorId
|
|
5496
|
+
});
|
|
5497
|
+
controller.enqueue({
|
|
5498
|
+
type: "text-delta",
|
|
5499
|
+
id: errorId,
|
|
5500
|
+
delta: droppedToolCall
|
|
5501
|
+
});
|
|
5502
|
+
controller.enqueue({
|
|
5503
|
+
type: "text-end",
|
|
5504
|
+
id: errorId
|
|
5505
|
+
});
|
|
5506
|
+
}
|
|
5507
|
+
closeToolInput(state, controller);
|
|
5508
|
+
(_d = parserOptions == null ? void 0 : parserOptions.onError) == null ? void 0 : _d.call(
|
|
5509
|
+
parserOptions,
|
|
5510
|
+
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.",
|
|
5511
|
+
{
|
|
5512
|
+
toolCall: droppedToolCall,
|
|
5513
|
+
toolCallId: streamingToolCallId,
|
|
5514
|
+
toolName: streamingToolName,
|
|
5515
|
+
dropReason: "malformed-nested-tool-call"
|
|
5516
|
+
}
|
|
5517
|
+
);
|
|
5518
|
+
state.currentToolCallJson = "";
|
|
5519
|
+
state.isInsideToolCall = false;
|
|
5520
|
+
state.buffer = jsonSoFar.slice(nestedStartIndex) + toolCallEnd + state.buffer.slice(startIndex + tag.length);
|
|
5521
|
+
return getPotentialStartIndex(state.buffer, toolCallStart);
|
|
5522
|
+
}
|
|
5523
|
+
function processInsideToolCallBoundary(context) {
|
|
5156
5524
|
const { state, controller, toolCallStart, toolCallEnd, tools } = context;
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5525
|
+
const currentLength = state.currentToolCallJson.length;
|
|
5526
|
+
const combined = state.currentToolCallJson + state.buffer;
|
|
5527
|
+
const boundary = findToolCallBoundaryOutsideRjsonSyntax(
|
|
5528
|
+
combined,
|
|
5529
|
+
0,
|
|
5530
|
+
toolCallStart,
|
|
5531
|
+
toolCallEnd
|
|
5532
|
+
);
|
|
5533
|
+
if (boundary == null) {
|
|
5534
|
+
return false;
|
|
5535
|
+
}
|
|
5536
|
+
const relativeEndIndex = boundary.endIdx - currentLength;
|
|
5537
|
+
if (relativeEndIndex < 0) {
|
|
5538
|
+
return false;
|
|
5539
|
+
}
|
|
5540
|
+
if (boundary.kind === "nested") {
|
|
5541
|
+
recoverNestedStreamingToolCall({
|
|
5542
|
+
context,
|
|
5543
|
+
jsonSoFar: combined.slice(0, boundary.endIdx),
|
|
5544
|
+
nestedStartIndex: boundary.nestedStartIndex,
|
|
5545
|
+
startIndex: relativeEndIndex,
|
|
5546
|
+
tag: toolCallEnd
|
|
5547
|
+
});
|
|
5548
|
+
return true;
|
|
5549
|
+
}
|
|
5550
|
+
publishText(
|
|
5551
|
+
state.buffer.slice(0, relativeEndIndex),
|
|
5552
|
+
state,
|
|
5553
|
+
controller,
|
|
5554
|
+
tools
|
|
5160
5555
|
);
|
|
5556
|
+
state.buffer = state.buffer.slice(relativeEndIndex + toolCallEnd.length);
|
|
5557
|
+
processTagMatch(context);
|
|
5558
|
+
return true;
|
|
5559
|
+
}
|
|
5560
|
+
function processBufferTags(context) {
|
|
5561
|
+
const { state, controller, toolCallStart, tools } = context;
|
|
5562
|
+
while (state.isInsideToolCall) {
|
|
5563
|
+
if (!processInsideToolCallBoundary(context)) {
|
|
5564
|
+
return;
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5567
|
+
let startIndex = getPotentialStartIndex(state.buffer, toolCallStart);
|
|
5161
5568
|
while (startIndex != null) {
|
|
5162
|
-
|
|
5163
|
-
if (startIndex + tag.length > state.buffer.length) {
|
|
5569
|
+
if (startIndex + toolCallStart.length > state.buffer.length) {
|
|
5164
5570
|
break;
|
|
5165
5571
|
}
|
|
5166
5572
|
publishText(state.buffer.slice(0, startIndex), state, controller, tools);
|
|
5167
|
-
state.buffer = state.buffer.slice(startIndex +
|
|
5573
|
+
state.buffer = state.buffer.slice(startIndex + toolCallStart.length);
|
|
5168
5574
|
processTagMatch(context);
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5575
|
+
while (state.isInsideToolCall) {
|
|
5576
|
+
if (!processInsideToolCallBoundary(context)) {
|
|
5577
|
+
return;
|
|
5578
|
+
}
|
|
5579
|
+
}
|
|
5580
|
+
startIndex = getPotentialStartIndex(state.buffer, toolCallStart);
|
|
5173
5581
|
}
|
|
5174
5582
|
}
|
|
5175
5583
|
function handlePartialTag(state, controller, toolCallStart, toolCallEnd, tools) {
|
|
@@ -5207,6 +5615,7 @@ var hermesProtocol = ({
|
|
|
5207
5615
|
toolCallStart = "<tool_call>",
|
|
5208
5616
|
toolCallEnd = "</tool_call>"
|
|
5209
5617
|
} = {}) => ({
|
|
5618
|
+
...validateNonEmptyDelimiters(toolCallStart, toolCallEnd),
|
|
5210
5619
|
formatTools({
|
|
5211
5620
|
tools,
|
|
5212
5621
|
toolSystemPromptTemplate
|
|
@@ -5231,24 +5640,42 @@ var hermesProtocol = ({
|
|
|
5231
5640
|
text,
|
|
5232
5641
|
options
|
|
5233
5642
|
}) {
|
|
5234
|
-
const startEsc = escapeRegExp(toolCallStart);
|
|
5235
|
-
const endEsc = escapeRegExp(toolCallEnd);
|
|
5236
|
-
const toolCallRegex = new RegExp(
|
|
5237
|
-
`${startEsc}([\0-\uFFFF]*?)${endEsc}`,
|
|
5238
|
-
"gs"
|
|
5239
|
-
);
|
|
5240
5643
|
const processedElements = [];
|
|
5241
5644
|
let currentIndex = 0;
|
|
5242
|
-
let
|
|
5243
|
-
while (
|
|
5244
|
-
|
|
5245
|
-
match,
|
|
5645
|
+
let searchFrom = 0;
|
|
5646
|
+
while (searchFrom < text.length) {
|
|
5647
|
+
const span = findNextToolCallSpan(
|
|
5246
5648
|
text,
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5649
|
+
searchFrom,
|
|
5650
|
+
toolCallStart,
|
|
5651
|
+
toolCallEnd
|
|
5652
|
+
);
|
|
5653
|
+
if (span === null) {
|
|
5654
|
+
break;
|
|
5655
|
+
}
|
|
5656
|
+
if (!span.found) {
|
|
5657
|
+
const skipTo = span.startIdx + toolCallStart.length;
|
|
5658
|
+
if (skipTo > currentIndex) {
|
|
5659
|
+
addTextSegment(text.slice(currentIndex, skipTo), processedElements);
|
|
5660
|
+
currentIndex = skipTo;
|
|
5661
|
+
}
|
|
5662
|
+
searchFrom = skipTo;
|
|
5663
|
+
continue;
|
|
5664
|
+
}
|
|
5665
|
+
const toolCallJson = text.slice(span.jsonStart, span.endIdx);
|
|
5666
|
+
const fullMatch = text.slice(
|
|
5667
|
+
span.startIdx,
|
|
5668
|
+
span.endIdx + toolCallEnd.length
|
|
5669
|
+
);
|
|
5670
|
+
if (span.startIdx > currentIndex) {
|
|
5671
|
+
addTextSegment(
|
|
5672
|
+
text.slice(currentIndex, span.startIdx),
|
|
5673
|
+
processedElements
|
|
5674
|
+
);
|
|
5675
|
+
}
|
|
5676
|
+
processToolCallJson(toolCallJson, fullMatch, processedElements, options);
|
|
5677
|
+
currentIndex = span.endIdx + toolCallEnd.length;
|
|
5678
|
+
searchFrom = currentIndex;
|
|
5252
5679
|
}
|
|
5253
5680
|
if (currentIndex < text.length) {
|
|
5254
5681
|
const remainingText = text.slice(currentIndex);
|
|
@@ -5301,14 +5728,26 @@ var hermesProtocol = ({
|
|
|
5301
5728
|
});
|
|
5302
5729
|
},
|
|
5303
5730
|
extractToolCallSegments({ text }) {
|
|
5304
|
-
const startEsc = escapeRegExp(toolCallStart);
|
|
5305
|
-
const endEsc = escapeRegExp(toolCallEnd);
|
|
5306
|
-
const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
|
|
5307
5731
|
const segments = [];
|
|
5308
|
-
let
|
|
5309
|
-
while (
|
|
5310
|
-
|
|
5311
|
-
|
|
5732
|
+
let searchFrom = 0;
|
|
5733
|
+
while (searchFrom < text.length) {
|
|
5734
|
+
const span = findNextToolCallSpan(
|
|
5735
|
+
text,
|
|
5736
|
+
searchFrom,
|
|
5737
|
+
toolCallStart,
|
|
5738
|
+
toolCallEnd
|
|
5739
|
+
);
|
|
5740
|
+
if (span === null) {
|
|
5741
|
+
break;
|
|
5742
|
+
}
|
|
5743
|
+
if (!span.found) {
|
|
5744
|
+
searchFrom = span.startIdx + toolCallStart.length;
|
|
5745
|
+
continue;
|
|
5746
|
+
}
|
|
5747
|
+
segments.push(
|
|
5748
|
+
text.slice(span.startIdx, span.endIdx + toolCallEnd.length)
|
|
5749
|
+
);
|
|
5750
|
+
searchFrom = span.endIdx + toolCallEnd.length;
|
|
5312
5751
|
}
|
|
5313
5752
|
return segments;
|
|
5314
5753
|
}
|
|
@@ -5597,7 +6036,13 @@ function processToolCall(params) {
|
|
|
5597
6036
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
5598
6037
|
options,
|
|
5599
6038
|
`Could not process XML tool call: ${toolCall.toolName}`,
|
|
5600
|
-
{
|
|
6039
|
+
{
|
|
6040
|
+
toolCall: originalCallText,
|
|
6041
|
+
error,
|
|
6042
|
+
toolName: toolCall.toolName,
|
|
6043
|
+
toolCallId: generateToolCallId(),
|
|
6044
|
+
dropReason: "malformed-tool-call-body"
|
|
6045
|
+
}
|
|
5601
6046
|
);
|
|
5602
6047
|
processedElements.push({ type: "text", text: originalCallText });
|
|
5603
6048
|
}
|
|
@@ -6039,7 +6484,10 @@ function handleStreamingToolCallEnd(params) {
|
|
|
6039
6484
|
});
|
|
6040
6485
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, "Could not process streaming XML tool call", {
|
|
6041
6486
|
toolCall: original,
|
|
6042
|
-
error
|
|
6487
|
+
error,
|
|
6488
|
+
toolName: currentToolCall.name,
|
|
6489
|
+
toolCallId: currentToolCall.toolCallId,
|
|
6490
|
+
dropReason: "malformed-tool-call-body"
|
|
6043
6491
|
});
|
|
6044
6492
|
}
|
|
6045
6493
|
}
|
|
@@ -6601,7 +7049,13 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
6601
7049
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
6602
7050
|
options,
|
|
6603
7051
|
"Could not complete streaming XML tool call at finish.",
|
|
6604
|
-
{
|
|
7052
|
+
{
|
|
7053
|
+
toolCall: unfinishedContent,
|
|
7054
|
+
toolCallId: currentToolCall.toolCallId,
|
|
7055
|
+
toolName: currentToolCall.name,
|
|
7056
|
+
dropReason: "unfinished-tool-call",
|
|
7057
|
+
error
|
|
7058
|
+
}
|
|
6605
7059
|
);
|
|
6606
7060
|
}
|
|
6607
7061
|
buffer = "";
|
|
@@ -6827,7 +7281,8 @@ var QWEN3CODER_TOOL_PARSER_CALL_TAG_NAMES = /* @__PURE__ */ new Set([
|
|
|
6827
7281
|
"invoke",
|
|
6828
7282
|
"tool_call"
|
|
6829
7283
|
]);
|
|
6830
|
-
var CALL_SHORTHAND_VALUE_RE = /^<\s*(call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s
|
|
7284
|
+
var CALL_SHORTHAND_VALUE_RE = /^<\s*(call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>/<]+))/i;
|
|
7285
|
+
var NESTED_CALL_SHORTHAND_VALUE_RE = /<\s*(?:call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>/<]+))/i;
|
|
6831
7286
|
var QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_START_RE = /<\s*(?!\/)\s*(call|function|tool|invoke)\b/i;
|
|
6832
7287
|
var QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE = /<\s*(?!\/)\s*(call|function|tool|invoke)\b[^>]*>/i;
|
|
6833
7288
|
var QWEN3CODER_TOOL_PARSER_STREAM_TOOL_CALL_CLOSE_TAG_RE = /<\s*\/\s*tool_call\s*>/i;
|
|
@@ -7226,6 +7681,12 @@ function getShorthandValue(openTag) {
|
|
|
7226
7681
|
}
|
|
7227
7682
|
return unescapeXml(value);
|
|
7228
7683
|
}
|
|
7684
|
+
function extractShorthandToolNameFromRaw(rawText) {
|
|
7685
|
+
var _a, _b;
|
|
7686
|
+
const match = NESTED_CALL_SHORTHAND_VALUE_RE.exec(rawText);
|
|
7687
|
+
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];
|
|
7688
|
+
return value ? unescapeXml(value) : null;
|
|
7689
|
+
}
|
|
7229
7690
|
function extractFirstTagText(xml, tagName) {
|
|
7230
7691
|
var _a;
|
|
7231
7692
|
const lower = xml.toLowerCase();
|
|
@@ -7547,6 +8008,20 @@ function parseQwen3CoderToolParserClosedMatches(inner, outerNameAttr) {
|
|
|
7547
8008
|
}
|
|
7548
8009
|
return closedCalls.concat(trailingCalls);
|
|
7549
8010
|
}
|
|
8011
|
+
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;
|
|
8012
|
+
function extractQwen3CoderToolNameFromMarkup(markup) {
|
|
8013
|
+
var _a, _b, _c, _d, _e;
|
|
8014
|
+
const match = markup.match(QWEN3CODER_TOOL_NAME_SALVAGE_REGEX);
|
|
8015
|
+
if (!match) {
|
|
8016
|
+
return void 0;
|
|
8017
|
+
}
|
|
8018
|
+
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];
|
|
8019
|
+
if (!name) {
|
|
8020
|
+
return void 0;
|
|
8021
|
+
}
|
|
8022
|
+
const trimmed = name.trim();
|
|
8023
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
8024
|
+
}
|
|
7550
8025
|
function parseQwen3CoderToolParserToolCallSegment(segment) {
|
|
7551
8026
|
var _a;
|
|
7552
8027
|
const extracted = extractToolCallInnerXml(segment);
|
|
@@ -7671,7 +8146,12 @@ var qwen3CoderProtocol = () => ({
|
|
|
7671
8146
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
7672
8147
|
options,
|
|
7673
8148
|
"Could not process Qwen3CoderToolParser XML tool call; keeping original text.",
|
|
7674
|
-
{
|
|
8149
|
+
{
|
|
8150
|
+
toolCall: fallbackText,
|
|
8151
|
+
toolName: extractQwen3CoderToolNameFromMarkup(segment),
|
|
8152
|
+
toolCallId: generateToolCallId(),
|
|
8153
|
+
dropReason: "malformed-tool-call-body"
|
|
8154
|
+
}
|
|
7675
8155
|
);
|
|
7676
8156
|
processedElements.push({ type: "text", text: fallbackText });
|
|
7677
8157
|
return false;
|
|
@@ -7684,7 +8164,12 @@ var qwen3CoderProtocol = () => ({
|
|
|
7684
8164
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
7685
8165
|
options,
|
|
7686
8166
|
"Could not process Qwen3CoderToolParser <function> call; keeping original text.",
|
|
7687
|
-
{
|
|
8167
|
+
{
|
|
8168
|
+
toolCall: raw,
|
|
8169
|
+
toolName: extractQwen3CoderToolNameFromMarkup(raw),
|
|
8170
|
+
toolCallId: generateToolCallId(),
|
|
8171
|
+
dropReason: "malformed-tool-call-body"
|
|
8172
|
+
}
|
|
7688
8173
|
);
|
|
7689
8174
|
processedElements.push({ type: "text", text: raw });
|
|
7690
8175
|
};
|
|
@@ -7934,7 +8419,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
7934
8419
|
});
|
|
7935
8420
|
};
|
|
7936
8421
|
const finalizeCall = (controller, callState, fallbackToolName, rawToolCallText = null) => {
|
|
7937
|
-
var _a, _b;
|
|
8422
|
+
var _a, _b, _c, _d;
|
|
7938
8423
|
const resolvedToolName = (_a = callState.toolName) != null ? _a : fallbackToolName;
|
|
7939
8424
|
if (!resolvedToolName || resolvedToolName.trim().length === 0) {
|
|
7940
8425
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
@@ -7948,12 +8433,14 @@ var qwen3CoderProtocol = () => ({
|
|
|
7948
8433
|
flushText(controller, rawText);
|
|
7949
8434
|
}
|
|
7950
8435
|
});
|
|
7951
|
-
(
|
|
8436
|
+
(_d = options == null ? void 0 : options.onError) == null ? void 0 : _d.call(
|
|
7952
8437
|
options,
|
|
7953
8438
|
shouldEmitRaw && rawToolCallText ? "Could not resolve Qwen3CoderToolParser tool name for tool call; emitting original text." : "Could not resolve Qwen3CoderToolParser tool name for tool call",
|
|
7954
8439
|
{
|
|
7955
8440
|
toolCallId: callState.toolCallId,
|
|
7956
|
-
toolCall: rawToolCallText
|
|
8441
|
+
toolCall: rawToolCallText,
|
|
8442
|
+
toolName: (_c = (_b = callState.toolName) != null ? _b : fallbackToolName) != null ? _c : void 0,
|
|
8443
|
+
dropReason: "unresolved-tool-name"
|
|
7957
8444
|
}
|
|
7958
8445
|
);
|
|
7959
8446
|
return false;
|
|
@@ -8409,25 +8896,36 @@ var qwen3CoderProtocol = () => ({
|
|
|
8409
8896
|
}
|
|
8410
8897
|
}
|
|
8411
8898
|
};
|
|
8412
|
-
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall) => {
|
|
8413
|
-
var _a;
|
|
8899
|
+
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall, metadata = {}) => {
|
|
8900
|
+
var _a, _b;
|
|
8414
8901
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
8415
|
-
(_a =
|
|
8902
|
+
const toolName = (_a = metadata.toolName) != null ? _a : extractShorthandToolNameFromRaw(rawToolCall);
|
|
8903
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
8416
8904
|
options,
|
|
8417
8905
|
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser XML tool call at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser XML tool call at finish.",
|
|
8418
|
-
{
|
|
8906
|
+
{
|
|
8907
|
+
toolCall: rawToolCall,
|
|
8908
|
+
...metadata.toolCallId ? { toolCallId: metadata.toolCallId } : {},
|
|
8909
|
+
...toolName ? { toolName } : {},
|
|
8910
|
+
dropReason: "unfinished-tool-call"
|
|
8911
|
+
}
|
|
8419
8912
|
);
|
|
8420
8913
|
if (shouldEmitRaw) {
|
|
8421
8914
|
flushText(controller, rawToolCall);
|
|
8422
8915
|
}
|
|
8423
8916
|
};
|
|
8424
|
-
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText) => {
|
|
8917
|
+
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText, callState) => {
|
|
8425
8918
|
var _a;
|
|
8426
8919
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
8427
8920
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
8428
8921
|
options,
|
|
8429
8922
|
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser call block at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser call block at finish.",
|
|
8430
|
-
{
|
|
8923
|
+
{
|
|
8924
|
+
toolCall: rawCallText,
|
|
8925
|
+
toolCallId: callState.toolCallId,
|
|
8926
|
+
...callState.toolName ? { toolName: callState.toolName } : {},
|
|
8927
|
+
dropReason: "unfinished-tool-call"
|
|
8928
|
+
}
|
|
8431
8929
|
);
|
|
8432
8930
|
if (shouldEmitRaw) {
|
|
8433
8931
|
flushText(controller, rawCallText);
|
|
@@ -8478,7 +8976,10 @@ var qwen3CoderProtocol = () => ({
|
|
|
8478
8976
|
flushText(controller, result.trailingText);
|
|
8479
8977
|
}
|
|
8480
8978
|
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
8481
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
8979
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
8980
|
+
toolCallId: toolCall.activeCall.toolCallId,
|
|
8981
|
+
...toolCall.activeCall.toolName ? { toolName: toolCall.activeCall.toolName } : {}
|
|
8982
|
+
});
|
|
8482
8983
|
}
|
|
8483
8984
|
} else if (toolCall.mode === "multi") {
|
|
8484
8985
|
if (toolCall.activeCall) {
|
|
@@ -8495,14 +8996,21 @@ var qwen3CoderProtocol = () => ({
|
|
|
8495
8996
|
flushText(controller, result.trailingText);
|
|
8496
8997
|
}
|
|
8497
8998
|
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
8498
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
8999
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
9000
|
+
toolCallId: toolCall.activeCall.toolCallId,
|
|
9001
|
+
...toolCall.activeCall.toolName ? { toolName: toolCall.activeCall.toolName } : {}
|
|
9002
|
+
});
|
|
8499
9003
|
}
|
|
8500
9004
|
toolCall.activeCall = null;
|
|
8501
9005
|
} else if (toolCall.emittedToolCallCount === 0) {
|
|
8502
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
9006
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
9007
|
+
toolName: toolCall.outerNameAttr
|
|
9008
|
+
});
|
|
8503
9009
|
}
|
|
8504
9010
|
} else {
|
|
8505
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
9011
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
9012
|
+
toolName: toolCall.outerNameAttr
|
|
9013
|
+
});
|
|
8506
9014
|
}
|
|
8507
9015
|
toolCall = null;
|
|
8508
9016
|
}
|
|
@@ -8520,7 +9028,8 @@ var qwen3CoderProtocol = () => ({
|
|
|
8520
9028
|
if (!result.ok && openTag) {
|
|
8521
9029
|
reportUnfinishedImplicitCallAtFinish(
|
|
8522
9030
|
controller,
|
|
8523
|
-
callState.raw || openTag + callState.buffer
|
|
9031
|
+
callState.raw || openTag + callState.buffer,
|
|
9032
|
+
callState
|
|
8524
9033
|
);
|
|
8525
9034
|
}
|
|
8526
9035
|
} else {
|
|
@@ -8898,26 +9407,28 @@ function findToolCalls2(text, toolNames) {
|
|
|
8898
9407
|
);
|
|
8899
9408
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
8900
9409
|
}
|
|
8901
|
-
function
|
|
8902
|
-
|
|
9410
|
+
function yamlFailureCause(failure) {
|
|
9411
|
+
if (failure.kind === "yaml-parse-error") {
|
|
9412
|
+
return { kind: "yaml-parse-error", errors: failure.errors };
|
|
9413
|
+
}
|
|
9414
|
+
return { kind: "yaml-non-mapping" };
|
|
9415
|
+
}
|
|
9416
|
+
function parseYamlContent(yamlContent) {
|
|
8903
9417
|
const { normalized, nonEmptyLines } = normalizeYamlContent(yamlContent);
|
|
8904
9418
|
if (nonEmptyLines.length === 0) {
|
|
8905
|
-
return {};
|
|
9419
|
+
return { ok: true, value: {} };
|
|
8906
9420
|
}
|
|
8907
9421
|
const parsed = parseYamlDocumentAsMapping(normalized);
|
|
8908
9422
|
if (parsed.errors.length > 0) {
|
|
8909
|
-
|
|
8910
|
-
|
|
8911
|
-
|
|
8912
|
-
|
|
9423
|
+
return {
|
|
9424
|
+
ok: false,
|
|
9425
|
+
failure: { kind: "yaml-parse-error", errors: parsed.errors }
|
|
9426
|
+
};
|
|
8913
9427
|
}
|
|
8914
9428
|
if (parsed.value === null) {
|
|
8915
|
-
|
|
8916
|
-
got: "non-mapping"
|
|
8917
|
-
});
|
|
8918
|
-
return null;
|
|
9429
|
+
return { ok: false, failure: { kind: "yaml-non-mapping" } };
|
|
8919
9430
|
}
|
|
8920
|
-
return parsed.value;
|
|
9431
|
+
return { ok: true, value: parsed.value };
|
|
8921
9432
|
}
|
|
8922
9433
|
function parseYamlContentForStreamProgress(yamlContent) {
|
|
8923
9434
|
const { normalized, nonEmptyLines } = normalizeYamlContent(yamlContent);
|
|
@@ -8949,11 +9460,16 @@ function processToolCallMatch(text, tc, currentIndex, processedElements, options
|
|
|
8949
9460
|
return currentIndex;
|
|
8950
9461
|
}
|
|
8951
9462
|
addTextSegment(text.slice(currentIndex, tc.startIndex), processedElements);
|
|
8952
|
-
const
|
|
8953
|
-
if (
|
|
9463
|
+
const result = parseYamlContent(tc.content);
|
|
9464
|
+
if (!result.ok) {
|
|
8954
9465
|
const originalText = text.slice(tc.startIndex, tc.endIndex);
|
|
9466
|
+
const cause = yamlFailureCause(result.failure);
|
|
8955
9467
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse YAML tool call", {
|
|
8956
|
-
toolCall: originalText
|
|
9468
|
+
toolCall: originalText,
|
|
9469
|
+
toolName: tc.toolName,
|
|
9470
|
+
toolCallId: generateToolCallId(),
|
|
9471
|
+
dropReason: "malformed-tool-call-body",
|
|
9472
|
+
cause
|
|
8957
9473
|
});
|
|
8958
9474
|
processedElements.push({ type: "text", text: originalText });
|
|
8959
9475
|
} else {
|
|
@@ -8961,7 +9477,7 @@ function processToolCallMatch(text, tc, currentIndex, processedElements, options
|
|
|
8961
9477
|
type: "tool-call",
|
|
8962
9478
|
toolCallId: generateToolCallId(),
|
|
8963
9479
|
toolName: tc.toolName,
|
|
8964
|
-
input: JSON.stringify(
|
|
9480
|
+
input: JSON.stringify(result.value)
|
|
8965
9481
|
});
|
|
8966
9482
|
}
|
|
8967
9483
|
return tc.endIndex;
|
|
@@ -9084,9 +9600,9 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
9084
9600
|
};
|
|
9085
9601
|
const processToolCallEnd = (controller, toolContent, toolName, toolCallId) => {
|
|
9086
9602
|
var _a;
|
|
9087
|
-
const
|
|
9603
|
+
const result = parseYamlContent(toolContent);
|
|
9088
9604
|
flushText(controller);
|
|
9089
|
-
if (
|
|
9605
|
+
if (!result.ok) {
|
|
9090
9606
|
const original = `<${toolName}>${toolContent}</${toolName}>`;
|
|
9091
9607
|
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
9092
9608
|
emitFailedToolInputLifecycle({
|
|
@@ -9099,12 +9615,16 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
9099
9615
|
}
|
|
9100
9616
|
});
|
|
9101
9617
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse streaming YAML tool call", {
|
|
9102
|
-
toolCall: original
|
|
9618
|
+
toolCall: original,
|
|
9619
|
+
toolName,
|
|
9620
|
+
toolCallId,
|
|
9621
|
+
dropReason: "malformed-tool-call-body",
|
|
9622
|
+
cause: yamlFailureCause(result.failure)
|
|
9103
9623
|
});
|
|
9104
9624
|
} else {
|
|
9105
9625
|
const finalInput = stringifyToolInputWithSchema({
|
|
9106
9626
|
toolName,
|
|
9107
|
-
args:
|
|
9627
|
+
args: result.value,
|
|
9108
9628
|
tools
|
|
9109
9629
|
});
|
|
9110
9630
|
if (currentToolCall && currentToolCall.toolCallId === toolCallId) {
|
|
@@ -9134,9 +9654,9 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
9134
9654
|
emitToolInputProgress2(controller, buffer);
|
|
9135
9655
|
const { name: toolName, toolCallId } = currentToolCall;
|
|
9136
9656
|
const reconciledBuffer = stripTrailingPartialCloseTag(buffer, toolName);
|
|
9137
|
-
const
|
|
9657
|
+
const result = parseYamlContent(reconciledBuffer);
|
|
9138
9658
|
flushText(controller);
|
|
9139
|
-
if (
|
|
9659
|
+
if (!result.ok) {
|
|
9140
9660
|
const unfinishedContent = `<${toolName}>${buffer}`;
|
|
9141
9661
|
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
9142
9662
|
emitFailedToolInputLifecycle({
|
|
@@ -9151,12 +9671,18 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
9151
9671
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
9152
9672
|
options,
|
|
9153
9673
|
"Could not complete streaming YAML tool call at finish.",
|
|
9154
|
-
{
|
|
9674
|
+
{
|
|
9675
|
+
toolCall: unfinishedContent,
|
|
9676
|
+
toolCallId,
|
|
9677
|
+
toolName,
|
|
9678
|
+
dropReason: "unfinished-tool-call",
|
|
9679
|
+
cause: yamlFailureCause(result.failure)
|
|
9680
|
+
}
|
|
9155
9681
|
);
|
|
9156
9682
|
} else {
|
|
9157
9683
|
const finalInput = stringifyToolInputWithSchema({
|
|
9158
9684
|
toolName,
|
|
9159
|
-
args:
|
|
9685
|
+
args: result.value,
|
|
9160
9686
|
tools
|
|
9161
9687
|
});
|
|
9162
9688
|
emitFinalizedToolInputLifecycle({
|