@ai-sdk-tool/parser 4.1.20 → 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/index.cjs
CHANGED
|
@@ -988,11 +988,6 @@ function createFlushTextHandler(getCurrentTextId, setCurrentTextId, getHasEmitte
|
|
|
988
988
|
};
|
|
989
989
|
}
|
|
990
990
|
|
|
991
|
-
// src/core/utils/regex.ts
|
|
992
|
-
function escapeRegExp(literal) {
|
|
993
|
-
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
994
|
-
}
|
|
995
|
-
|
|
996
991
|
// src/core/utils/streamed-tool-input-delta.ts
|
|
997
992
|
function emitDelta({
|
|
998
993
|
controller,
|
|
@@ -1974,13 +1969,312 @@ function shouldEmitRawToolCallTextOnError(options) {
|
|
|
1974
1969
|
}
|
|
1975
1970
|
|
|
1976
1971
|
// src/core/protocols/hermes-protocol.ts
|
|
1972
|
+
var RJSON_IDENTIFIER_CHAR_REGEX = /[$a-zA-Z0-9_\-+.*?!|&%^/#\\]/;
|
|
1973
|
+
var RJSON_NUMBER_TOKEN_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
1974
|
+
function validateNonEmptyDelimiters(toolCallStart, toolCallEnd) {
|
|
1975
|
+
if (toolCallStart.length === 0) {
|
|
1976
|
+
throw new TypeError("hermesProtocol toolCallStart must not be empty");
|
|
1977
|
+
}
|
|
1978
|
+
if (toolCallEnd.length === 0) {
|
|
1979
|
+
throw new TypeError("hermesProtocol toolCallEnd must not be empty");
|
|
1980
|
+
}
|
|
1981
|
+
return {};
|
|
1982
|
+
}
|
|
1983
|
+
function isRjsonIdentifierChar(ch) {
|
|
1984
|
+
return ch != null && RJSON_IDENTIFIER_CHAR_REGEX.test(ch);
|
|
1985
|
+
}
|
|
1986
|
+
function isRjsonPropertyLikeDelimiter(startTag) {
|
|
1987
|
+
const key = startTag.endsWith(":") ? startTag.slice(0, -1) : "";
|
|
1988
|
+
return key.length > 0 && [...key].every((ch) => isRjsonIdentifierChar(ch));
|
|
1989
|
+
}
|
|
1990
|
+
function previousRjsonToken(json, index, minIndex = 0) {
|
|
1991
|
+
let start = index - 1;
|
|
1992
|
+
while (start >= minIndex && isRjsonIdentifierChar(json[start])) {
|
|
1993
|
+
start -= 1;
|
|
1994
|
+
}
|
|
1995
|
+
return json.slice(start + 1, index);
|
|
1996
|
+
}
|
|
1997
|
+
function previousTokenAllowsComment(json, index, minIndex = 0) {
|
|
1998
|
+
const previous = previousRjsonToken(json, index, minIndex);
|
|
1999
|
+
if (previous.length === 0) {
|
|
2000
|
+
return true;
|
|
2001
|
+
}
|
|
2002
|
+
return RJSON_NUMBER_TOKEN_REGEX.test(previous) || previous === "true" || previous === "false" || previous === "null";
|
|
2003
|
+
}
|
|
2004
|
+
function startsRjsonComment(json, index, minIndex = 0) {
|
|
2005
|
+
if (!(json[index] === "/" && json[index + 1] === "/" || json[index] === "/" && json[index + 1] === "*")) {
|
|
2006
|
+
return false;
|
|
2007
|
+
}
|
|
2008
|
+
if (index > minIndex && isRjsonIdentifierChar(json[index - 1])) {
|
|
2009
|
+
return previousTokenAllowsComment(json, index, minIndex);
|
|
2010
|
+
}
|
|
2011
|
+
return true;
|
|
2012
|
+
}
|
|
2013
|
+
function hasNestedStartBoundary(segment, startIndex) {
|
|
2014
|
+
const previous = segment[startIndex - 1];
|
|
2015
|
+
return previous == null || WHITESPACE_JSON_REGEX.test(previous) || previous === "}";
|
|
2016
|
+
}
|
|
2017
|
+
function isLikelyNestedToolCallStart(segment, startIndex, startTag) {
|
|
2018
|
+
if (isRjsonPropertyLikeDelimiter(startTag)) {
|
|
2019
|
+
return false;
|
|
2020
|
+
}
|
|
2021
|
+
const jsonStart = skipJsonWhitespace(segment, startIndex + startTag.length);
|
|
2022
|
+
return segment[jsonStart] === "{" && hasNestedStartBoundary(segment, startIndex);
|
|
2023
|
+
}
|
|
2024
|
+
function findToolCallBoundaryOutsideRjsonSyntax(text, scanFrom, startTag, endTag) {
|
|
2025
|
+
let quote = null;
|
|
2026
|
+
let esc = false;
|
|
2027
|
+
let inLineComment = false;
|
|
2028
|
+
let inBlockComment = false;
|
|
2029
|
+
let lineCommentSawEndTag = false;
|
|
2030
|
+
let blockCommentSawEndTag = false;
|
|
2031
|
+
let nestedStartIndex = null;
|
|
2032
|
+
for (let index = scanFrom; index < text.length; index += 1) {
|
|
2033
|
+
const ch = text[index];
|
|
2034
|
+
if (esc) {
|
|
2035
|
+
esc = false;
|
|
2036
|
+
continue;
|
|
2037
|
+
}
|
|
2038
|
+
if (quote !== null) {
|
|
2039
|
+
if (ch === "\\") {
|
|
2040
|
+
esc = true;
|
|
2041
|
+
continue;
|
|
2042
|
+
}
|
|
2043
|
+
if (ch === quote) {
|
|
2044
|
+
quote = null;
|
|
2045
|
+
}
|
|
2046
|
+
continue;
|
|
2047
|
+
}
|
|
2048
|
+
if (inLineComment) {
|
|
2049
|
+
if (ch === "\n" || ch === "\r") {
|
|
2050
|
+
inLineComment = false;
|
|
2051
|
+
lineCommentSawEndTag = false;
|
|
2052
|
+
continue;
|
|
2053
|
+
}
|
|
2054
|
+
if (text.startsWith(endTag, index)) {
|
|
2055
|
+
lineCommentSawEndTag = true;
|
|
2056
|
+
index += endTag.length - 1;
|
|
2057
|
+
continue;
|
|
2058
|
+
}
|
|
2059
|
+
if (lineCommentSawEndTag && text.startsWith(startTag, index) && text[skipJsonWhitespace(text, index + startTag.length)] === "{") {
|
|
2060
|
+
nestedStartIndex = index;
|
|
2061
|
+
inLineComment = false;
|
|
2062
|
+
lineCommentSawEndTag = false;
|
|
2063
|
+
index += startTag.length - 1;
|
|
2064
|
+
continue;
|
|
2065
|
+
}
|
|
2066
|
+
continue;
|
|
2067
|
+
}
|
|
2068
|
+
if (inBlockComment) {
|
|
2069
|
+
if (ch === "*" && text[index + 1] === "/") {
|
|
2070
|
+
inBlockComment = false;
|
|
2071
|
+
blockCommentSawEndTag = false;
|
|
2072
|
+
index += 1;
|
|
2073
|
+
continue;
|
|
2074
|
+
}
|
|
2075
|
+
if (text.startsWith(endTag, index)) {
|
|
2076
|
+
blockCommentSawEndTag = true;
|
|
2077
|
+
index += endTag.length - 1;
|
|
2078
|
+
continue;
|
|
2079
|
+
}
|
|
2080
|
+
if (blockCommentSawEndTag && text.startsWith(startTag, index) && text[skipJsonWhitespace(text, index + startTag.length)] === "{") {
|
|
2081
|
+
nestedStartIndex = index;
|
|
2082
|
+
inBlockComment = false;
|
|
2083
|
+
blockCommentSawEndTag = false;
|
|
2084
|
+
index += startTag.length - 1;
|
|
2085
|
+
continue;
|
|
2086
|
+
}
|
|
2087
|
+
continue;
|
|
2088
|
+
}
|
|
2089
|
+
if (startsRjsonComment(text, index, scanFrom)) {
|
|
2090
|
+
if (text[index + 1] === "/") {
|
|
2091
|
+
inLineComment = true;
|
|
2092
|
+
lineCommentSawEndTag = false;
|
|
2093
|
+
index += 1;
|
|
2094
|
+
continue;
|
|
2095
|
+
}
|
|
2096
|
+
if (text[index + 1] === "*") {
|
|
2097
|
+
inBlockComment = true;
|
|
2098
|
+
blockCommentSawEndTag = false;
|
|
2099
|
+
index += 1;
|
|
2100
|
+
continue;
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
if (text.startsWith(endTag, index)) {
|
|
2104
|
+
return nestedStartIndex == null ? { kind: "end", endIdx: index } : { kind: "nested", endIdx: index, nestedStartIndex };
|
|
2105
|
+
}
|
|
2106
|
+
if (nestedStartIndex == null && text.startsWith(startTag, index) && isLikelyNestedToolCallStart(text, index, startTag)) {
|
|
2107
|
+
nestedStartIndex = index;
|
|
2108
|
+
index += startTag.length - 1;
|
|
2109
|
+
continue;
|
|
2110
|
+
}
|
|
2111
|
+
if (ch === '"' || ch === "'") {
|
|
2112
|
+
quote = ch;
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
return null;
|
|
2116
|
+
}
|
|
2117
|
+
function findNextToolCallSpan(text, searchFrom, startTag, endTag) {
|
|
2118
|
+
const startIdx = text.indexOf(startTag, searchFrom);
|
|
2119
|
+
if (startIdx === -1) {
|
|
2120
|
+
return null;
|
|
2121
|
+
}
|
|
2122
|
+
const jsonStart = startIdx + startTag.length;
|
|
2123
|
+
const boundary = findToolCallBoundaryOutsideRjsonSyntax(
|
|
2124
|
+
text,
|
|
2125
|
+
jsonStart,
|
|
2126
|
+
startTag,
|
|
2127
|
+
endTag
|
|
2128
|
+
);
|
|
2129
|
+
if (boundary == null) {
|
|
2130
|
+
return { startIdx, found: false };
|
|
2131
|
+
}
|
|
2132
|
+
if (boundary.kind === "nested") {
|
|
2133
|
+
return { startIdx, found: false };
|
|
2134
|
+
}
|
|
2135
|
+
return { startIdx, found: true, jsonStart, endIdx: boundary.endIdx };
|
|
2136
|
+
}
|
|
1977
2137
|
function canonicalizeToolInput(argumentsValue) {
|
|
1978
2138
|
return JSON.stringify(argumentsValue != null ? argumentsValue : {});
|
|
1979
2139
|
}
|
|
2140
|
+
var CHAR_CODE_BACKSLASH = 92;
|
|
2141
|
+
var CHAR_CODE_QUOTE = 34;
|
|
2142
|
+
var CHAR_CODE_LF = 10;
|
|
2143
|
+
var CHAR_CODE_CR = 13;
|
|
2144
|
+
var CHAR_CODE_TAB = 9;
|
|
2145
|
+
var CHAR_CODE_SLASH = 47;
|
|
2146
|
+
var CHAR_CODE_STAR = 42;
|
|
2147
|
+
var CHAR_CODE_CONTROL_UPPER = 31;
|
|
2148
|
+
var CHAR_CODE_SINGLE_QUOTE = 39;
|
|
2149
|
+
function hasControlCharInString(json) {
|
|
2150
|
+
let quote = null;
|
|
2151
|
+
let esc = false;
|
|
2152
|
+
for (let i = 0; i < json.length; i += 1) {
|
|
2153
|
+
const code = json.charCodeAt(i);
|
|
2154
|
+
if (esc) {
|
|
2155
|
+
esc = false;
|
|
2156
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
2157
|
+
return true;
|
|
2158
|
+
}
|
|
2159
|
+
continue;
|
|
2160
|
+
}
|
|
2161
|
+
if (quote !== null && code === CHAR_CODE_BACKSLASH) {
|
|
2162
|
+
esc = true;
|
|
2163
|
+
continue;
|
|
2164
|
+
}
|
|
2165
|
+
if (quote !== null) {
|
|
2166
|
+
if (code === quote) {
|
|
2167
|
+
quote = null;
|
|
2168
|
+
continue;
|
|
2169
|
+
}
|
|
2170
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
2171
|
+
return true;
|
|
2172
|
+
}
|
|
2173
|
+
continue;
|
|
2174
|
+
}
|
|
2175
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_SLASH) {
|
|
2176
|
+
i += 2;
|
|
2177
|
+
while (i < json.length && json.charCodeAt(i) !== CHAR_CODE_LF && json.charCodeAt(i) !== CHAR_CODE_CR) {
|
|
2178
|
+
i += 1;
|
|
2179
|
+
}
|
|
2180
|
+
continue;
|
|
2181
|
+
}
|
|
2182
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_STAR) {
|
|
2183
|
+
i += 2;
|
|
2184
|
+
while (i + 1 < json.length && !(json.charCodeAt(i) === CHAR_CODE_STAR && json.charCodeAt(i + 1) === CHAR_CODE_SLASH)) {
|
|
2185
|
+
i += 1;
|
|
2186
|
+
}
|
|
2187
|
+
i += 1;
|
|
2188
|
+
continue;
|
|
2189
|
+
}
|
|
2190
|
+
if (code === CHAR_CODE_QUOTE || code === CHAR_CODE_SINGLE_QUOTE) {
|
|
2191
|
+
quote = code;
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
return false;
|
|
2195
|
+
}
|
|
2196
|
+
function normalizeJsonStringCtrl(json) {
|
|
2197
|
+
if (!hasControlCharInString(json)) {
|
|
2198
|
+
return json;
|
|
2199
|
+
}
|
|
2200
|
+
const parts = [];
|
|
2201
|
+
let chunkStart = 0;
|
|
2202
|
+
let quote = null;
|
|
2203
|
+
let esc = false;
|
|
2204
|
+
const flushUpTo = (end) => {
|
|
2205
|
+
if (chunkStart < end) {
|
|
2206
|
+
parts.push(json.slice(chunkStart, end));
|
|
2207
|
+
}
|
|
2208
|
+
};
|
|
2209
|
+
const escapeForCode = (code) => {
|
|
2210
|
+
switch (code) {
|
|
2211
|
+
case CHAR_CODE_LF:
|
|
2212
|
+
return "\\n";
|
|
2213
|
+
case CHAR_CODE_CR:
|
|
2214
|
+
return "\\r";
|
|
2215
|
+
case CHAR_CODE_TAB:
|
|
2216
|
+
return "\\t";
|
|
2217
|
+
default:
|
|
2218
|
+
return `\\u${code.toString(16).padStart(4, "0")}`;
|
|
2219
|
+
}
|
|
2220
|
+
};
|
|
2221
|
+
for (let i = 0; i < json.length; i += 1) {
|
|
2222
|
+
const code = json.charCodeAt(i);
|
|
2223
|
+
if (esc) {
|
|
2224
|
+
esc = false;
|
|
2225
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
2226
|
+
flushUpTo(i - 1);
|
|
2227
|
+
parts.push(escapeForCode(code));
|
|
2228
|
+
chunkStart = i + 1;
|
|
2229
|
+
}
|
|
2230
|
+
continue;
|
|
2231
|
+
}
|
|
2232
|
+
if (quote !== null && code === CHAR_CODE_BACKSLASH) {
|
|
2233
|
+
esc = true;
|
|
2234
|
+
continue;
|
|
2235
|
+
}
|
|
2236
|
+
if (quote !== null) {
|
|
2237
|
+
if (code === quote) {
|
|
2238
|
+
quote = null;
|
|
2239
|
+
continue;
|
|
2240
|
+
}
|
|
2241
|
+
if (code <= CHAR_CODE_CONTROL_UPPER) {
|
|
2242
|
+
flushUpTo(i);
|
|
2243
|
+
parts.push(escapeForCode(code));
|
|
2244
|
+
chunkStart = i + 1;
|
|
2245
|
+
}
|
|
2246
|
+
continue;
|
|
2247
|
+
}
|
|
2248
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_SLASH) {
|
|
2249
|
+
i += 2;
|
|
2250
|
+
while (i < json.length && json.charCodeAt(i) !== CHAR_CODE_LF && json.charCodeAt(i) !== CHAR_CODE_CR) {
|
|
2251
|
+
i += 1;
|
|
2252
|
+
}
|
|
2253
|
+
continue;
|
|
2254
|
+
}
|
|
2255
|
+
if (code === CHAR_CODE_SLASH && json.charCodeAt(i + 1) === CHAR_CODE_STAR) {
|
|
2256
|
+
i += 2;
|
|
2257
|
+
while (i + 1 < json.length && !(json.charCodeAt(i) === CHAR_CODE_STAR && json.charCodeAt(i + 1) === CHAR_CODE_SLASH)) {
|
|
2258
|
+
i += 1;
|
|
2259
|
+
}
|
|
2260
|
+
i += 1;
|
|
2261
|
+
continue;
|
|
2262
|
+
}
|
|
2263
|
+
if (code === CHAR_CODE_QUOTE || code === CHAR_CODE_SINGLE_QUOTE) {
|
|
2264
|
+
quote = code;
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
if (chunkStart < json.length) {
|
|
2268
|
+
parts.push(json.slice(chunkStart));
|
|
2269
|
+
}
|
|
2270
|
+
return parts.join("");
|
|
2271
|
+
}
|
|
1980
2272
|
function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
|
|
1981
2273
|
var _a;
|
|
1982
2274
|
try {
|
|
1983
|
-
const parsedToolCall = parse(
|
|
2275
|
+
const parsedToolCall = parse(
|
|
2276
|
+
normalizeJsonStringCtrl(toolCallJson)
|
|
2277
|
+
);
|
|
1984
2278
|
processedElements.push({
|
|
1985
2279
|
type: "tool-call",
|
|
1986
2280
|
toolCallId: generateToolCallId(),
|
|
@@ -1988,6 +2282,8 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
1988
2282
|
input: canonicalizeToolInput(parsedToolCall.arguments)
|
|
1989
2283
|
});
|
|
1990
2284
|
} catch (error) {
|
|
2285
|
+
const salvagedToolName = extractStreamingToolCallProgress(toolCallJson).toolName;
|
|
2286
|
+
const salvagedToolCallId = generateToolCallId();
|
|
1991
2287
|
logParseFailure({
|
|
1992
2288
|
phase: "generated-text",
|
|
1993
2289
|
reason: "Failed to parse tool call JSON segment",
|
|
@@ -1997,24 +2293,17 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
1997
2293
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
1998
2294
|
options,
|
|
1999
2295
|
"Could not process JSON tool call, keeping original text.",
|
|
2000
|
-
{
|
|
2296
|
+
{
|
|
2297
|
+
toolCall: fullMatch,
|
|
2298
|
+
error,
|
|
2299
|
+
toolName: salvagedToolName,
|
|
2300
|
+
toolCallId: salvagedToolCallId,
|
|
2301
|
+
dropReason: "malformed-tool-call-body"
|
|
2302
|
+
}
|
|
2001
2303
|
);
|
|
2002
2304
|
processedElements.push({ type: "text", text: fullMatch });
|
|
2003
2305
|
}
|
|
2004
2306
|
}
|
|
2005
|
-
function processMatchedToolCall(context) {
|
|
2006
|
-
const { match, text, currentIndex, processedElements, options } = context;
|
|
2007
|
-
const startIndex = match.index;
|
|
2008
|
-
const toolCallJson = match[1];
|
|
2009
|
-
if (startIndex > currentIndex) {
|
|
2010
|
-
const textSegment = text.slice(currentIndex, startIndex);
|
|
2011
|
-
addTextSegment(textSegment, processedElements);
|
|
2012
|
-
}
|
|
2013
|
-
if (toolCallJson) {
|
|
2014
|
-
processToolCallJson(toolCallJson, match[0], processedElements, options);
|
|
2015
|
-
}
|
|
2016
|
-
return startIndex + match[0].length;
|
|
2017
|
-
}
|
|
2018
2307
|
var WHITESPACE_JSON_REGEX = /\s/;
|
|
2019
2308
|
function skipJsonWhitespace(text, fromIndex) {
|
|
2020
2309
|
let index = fromIndex;
|
|
@@ -2281,7 +2570,9 @@ function canonicalizeArgumentsProgressInput(progress, toolName, tools) {
|
|
|
2281
2570
|
return void 0;
|
|
2282
2571
|
}
|
|
2283
2572
|
try {
|
|
2284
|
-
const parsedArguments = parse(
|
|
2573
|
+
const parsedArguments = parse(
|
|
2574
|
+
normalizeJsonStringCtrl(progress.argumentsText)
|
|
2575
|
+
);
|
|
2285
2576
|
return stringifyToolInputWithSchema({
|
|
2286
2577
|
toolName,
|
|
2287
2578
|
args: parsedArguments,
|
|
@@ -2341,14 +2632,16 @@ function closeTextBlock(state, controller) {
|
|
|
2341
2632
|
}
|
|
2342
2633
|
}
|
|
2343
2634
|
function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer, tools, options) {
|
|
2344
|
-
var _a;
|
|
2635
|
+
var _a, _b, _c, _d;
|
|
2345
2636
|
if (!state.currentToolCallJson && trailingBuffer.length === 0) {
|
|
2346
2637
|
state.isInsideToolCall = false;
|
|
2347
2638
|
return;
|
|
2348
2639
|
}
|
|
2349
2640
|
if (state.currentToolCallJson) {
|
|
2350
2641
|
try {
|
|
2351
|
-
const parsedToolCall = parse(
|
|
2642
|
+
const parsedToolCall = parse(
|
|
2643
|
+
normalizeJsonStringCtrl(state.currentToolCallJson)
|
|
2644
|
+
);
|
|
2352
2645
|
emitToolCallFromParsed(state, controller, parsedToolCall, tools);
|
|
2353
2646
|
state.currentToolCallJson = "";
|
|
2354
2647
|
state.isInsideToolCall = false;
|
|
@@ -2380,11 +2673,19 @@ function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer
|
|
|
2380
2673
|
id: errorId
|
|
2381
2674
|
});
|
|
2382
2675
|
}
|
|
2676
|
+
const streamingToolCallId = (_b = (_a = state.activeToolInput) == null ? void 0 : _a.id) != null ? _b : generateToolCallId();
|
|
2677
|
+
const streamingToolName = (_c = state.activeToolInput) == null ? void 0 : _c.toolName;
|
|
2383
2678
|
closeToolInput(state, controller);
|
|
2384
|
-
|
|
2679
|
+
const toolName = streamingToolName != null ? streamingToolName : state.currentToolCallJson ? extractStreamingToolCallProgress(state.currentToolCallJson).toolName : void 0;
|
|
2680
|
+
(_d = options == null ? void 0 : options.onError) == null ? void 0 : _d.call(
|
|
2385
2681
|
options,
|
|
2386
2682
|
shouldEmitRawFallback ? "Could not complete streaming JSON tool call at finish; emitting original text." : "Could not complete streaming JSON tool call at finish.",
|
|
2387
|
-
{
|
|
2683
|
+
{
|
|
2684
|
+
toolCall: errorContent,
|
|
2685
|
+
toolCallId: streamingToolCallId,
|
|
2686
|
+
toolName,
|
|
2687
|
+
dropReason: "unfinished-tool-call"
|
|
2688
|
+
}
|
|
2388
2689
|
);
|
|
2389
2690
|
state.currentToolCallJson = "";
|
|
2390
2691
|
state.isInsideToolCall = false;
|
|
@@ -2429,14 +2730,18 @@ function publishText(text, state, controller, tools) {
|
|
|
2429
2730
|
}
|
|
2430
2731
|
}
|
|
2431
2732
|
function emitToolCall(context) {
|
|
2432
|
-
var _a;
|
|
2733
|
+
var _a, _b, _c, _d, _e;
|
|
2433
2734
|
const { state, controller, toolCallStart, toolCallEnd, options, tools } = context;
|
|
2434
2735
|
try {
|
|
2435
|
-
const parsedToolCall = parse(
|
|
2736
|
+
const parsedToolCall = parse(
|
|
2737
|
+
normalizeJsonStringCtrl(state.currentToolCallJson)
|
|
2738
|
+
);
|
|
2436
2739
|
emitToolCallFromParsed(state, controller, parsedToolCall, tools);
|
|
2437
2740
|
} catch (error) {
|
|
2438
2741
|
const errorContent = `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`;
|
|
2439
2742
|
const shouldEmitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
2743
|
+
const streamingToolCallId = (_b = (_a = state.activeToolInput) == null ? void 0 : _a.id) != null ? _b : generateToolCallId();
|
|
2744
|
+
const streamingToolName = (_d = (_c = state.activeToolInput) == null ? void 0 : _c.toolName) != null ? _d : extractStreamingToolCallProgress(state.currentToolCallJson).toolName;
|
|
2440
2745
|
logParseFailure({
|
|
2441
2746
|
phase: "stream",
|
|
2442
2747
|
reason: "Failed to parse streaming tool call JSON segment",
|
|
@@ -2460,11 +2765,15 @@ function emitToolCall(context) {
|
|
|
2460
2765
|
});
|
|
2461
2766
|
}
|
|
2462
2767
|
closeToolInput(state, controller);
|
|
2463
|
-
(
|
|
2768
|
+
(_e = options == null ? void 0 : options.onError) == null ? void 0 : _e.call(
|
|
2464
2769
|
options,
|
|
2465
2770
|
shouldEmitRawFallback ? "Could not process streaming JSON tool call; emitting original text." : "Could not process streaming JSON tool call.",
|
|
2466
2771
|
{
|
|
2467
|
-
toolCall: errorContent
|
|
2772
|
+
toolCall: errorContent,
|
|
2773
|
+
error,
|
|
2774
|
+
toolCallId: streamingToolCallId,
|
|
2775
|
+
toolName: streamingToolName,
|
|
2776
|
+
dropReason: "malformed-tool-call-body"
|
|
2468
2777
|
}
|
|
2469
2778
|
);
|
|
2470
2779
|
}
|
|
@@ -2481,24 +2790,118 @@ function processTagMatch(context) {
|
|
|
2481
2790
|
state.activeToolInput = null;
|
|
2482
2791
|
}
|
|
2483
2792
|
}
|
|
2484
|
-
function
|
|
2793
|
+
function recoverNestedStreamingToolCall(options) {
|
|
2794
|
+
var _a, _b, _c, _d;
|
|
2795
|
+
const { context, jsonSoFar, nestedStartIndex, startIndex, tag } = options;
|
|
2796
|
+
const {
|
|
2797
|
+
state,
|
|
2798
|
+
controller,
|
|
2799
|
+
toolCallStart,
|
|
2800
|
+
toolCallEnd,
|
|
2801
|
+
options: parserOptions
|
|
2802
|
+
} = context;
|
|
2803
|
+
const droppedToolCall = `${toolCallStart}${jsonSoFar.slice(
|
|
2804
|
+
0,
|
|
2805
|
+
nestedStartIndex
|
|
2806
|
+
)}`;
|
|
2807
|
+
const shouldEmitRawFallback = shouldEmitRawToolCallTextOnError(parserOptions);
|
|
2808
|
+
const streamingToolCallId = (_a = state.activeToolInput) == null ? void 0 : _a.id;
|
|
2809
|
+
const streamingToolName = (_c = (_b = state.activeToolInput) == null ? void 0 : _b.toolName) != null ? _c : extractStreamingToolCallProgress(jsonSoFar.slice(0, nestedStartIndex)).toolName;
|
|
2810
|
+
logParseFailure({
|
|
2811
|
+
phase: "stream",
|
|
2812
|
+
reason: "Abandoning malformed streaming tool call before nested start tag",
|
|
2813
|
+
snippet: droppedToolCall
|
|
2814
|
+
});
|
|
2815
|
+
if (shouldEmitRawFallback) {
|
|
2816
|
+
const errorId = generateId();
|
|
2817
|
+
controller.enqueue({
|
|
2818
|
+
type: "text-start",
|
|
2819
|
+
id: errorId
|
|
2820
|
+
});
|
|
2821
|
+
controller.enqueue({
|
|
2822
|
+
type: "text-delta",
|
|
2823
|
+
id: errorId,
|
|
2824
|
+
delta: droppedToolCall
|
|
2825
|
+
});
|
|
2826
|
+
controller.enqueue({
|
|
2827
|
+
type: "text-end",
|
|
2828
|
+
id: errorId
|
|
2829
|
+
});
|
|
2830
|
+
}
|
|
2831
|
+
closeToolInput(state, controller);
|
|
2832
|
+
(_d = parserOptions == null ? void 0 : parserOptions.onError) == null ? void 0 : _d.call(
|
|
2833
|
+
parserOptions,
|
|
2834
|
+
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.",
|
|
2835
|
+
{
|
|
2836
|
+
toolCall: droppedToolCall,
|
|
2837
|
+
toolCallId: streamingToolCallId,
|
|
2838
|
+
toolName: streamingToolName,
|
|
2839
|
+
dropReason: "malformed-nested-tool-call"
|
|
2840
|
+
}
|
|
2841
|
+
);
|
|
2842
|
+
state.currentToolCallJson = "";
|
|
2843
|
+
state.isInsideToolCall = false;
|
|
2844
|
+
state.buffer = jsonSoFar.slice(nestedStartIndex) + toolCallEnd + state.buffer.slice(startIndex + tag.length);
|
|
2845
|
+
return getPotentialStartIndex(state.buffer, toolCallStart);
|
|
2846
|
+
}
|
|
2847
|
+
function processInsideToolCallBoundary(context) {
|
|
2485
2848
|
const { state, controller, toolCallStart, toolCallEnd, tools } = context;
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2849
|
+
const currentLength = state.currentToolCallJson.length;
|
|
2850
|
+
const combined = state.currentToolCallJson + state.buffer;
|
|
2851
|
+
const boundary = findToolCallBoundaryOutsideRjsonSyntax(
|
|
2852
|
+
combined,
|
|
2853
|
+
0,
|
|
2854
|
+
toolCallStart,
|
|
2855
|
+
toolCallEnd
|
|
2489
2856
|
);
|
|
2857
|
+
if (boundary == null) {
|
|
2858
|
+
return false;
|
|
2859
|
+
}
|
|
2860
|
+
const relativeEndIndex = boundary.endIdx - currentLength;
|
|
2861
|
+
if (relativeEndIndex < 0) {
|
|
2862
|
+
return false;
|
|
2863
|
+
}
|
|
2864
|
+
if (boundary.kind === "nested") {
|
|
2865
|
+
recoverNestedStreamingToolCall({
|
|
2866
|
+
context,
|
|
2867
|
+
jsonSoFar: combined.slice(0, boundary.endIdx),
|
|
2868
|
+
nestedStartIndex: boundary.nestedStartIndex,
|
|
2869
|
+
startIndex: relativeEndIndex,
|
|
2870
|
+
tag: toolCallEnd
|
|
2871
|
+
});
|
|
2872
|
+
return true;
|
|
2873
|
+
}
|
|
2874
|
+
publishText(
|
|
2875
|
+
state.buffer.slice(0, relativeEndIndex),
|
|
2876
|
+
state,
|
|
2877
|
+
controller,
|
|
2878
|
+
tools
|
|
2879
|
+
);
|
|
2880
|
+
state.buffer = state.buffer.slice(relativeEndIndex + toolCallEnd.length);
|
|
2881
|
+
processTagMatch(context);
|
|
2882
|
+
return true;
|
|
2883
|
+
}
|
|
2884
|
+
function processBufferTags(context) {
|
|
2885
|
+
const { state, controller, toolCallStart, tools } = context;
|
|
2886
|
+
while (state.isInsideToolCall) {
|
|
2887
|
+
if (!processInsideToolCallBoundary(context)) {
|
|
2888
|
+
return;
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
let startIndex = getPotentialStartIndex(state.buffer, toolCallStart);
|
|
2490
2892
|
while (startIndex != null) {
|
|
2491
|
-
|
|
2492
|
-
if (startIndex + tag.length > state.buffer.length) {
|
|
2893
|
+
if (startIndex + toolCallStart.length > state.buffer.length) {
|
|
2493
2894
|
break;
|
|
2494
2895
|
}
|
|
2495
2896
|
publishText(state.buffer.slice(0, startIndex), state, controller, tools);
|
|
2496
|
-
state.buffer = state.buffer.slice(startIndex +
|
|
2897
|
+
state.buffer = state.buffer.slice(startIndex + toolCallStart.length);
|
|
2497
2898
|
processTagMatch(context);
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2899
|
+
while (state.isInsideToolCall) {
|
|
2900
|
+
if (!processInsideToolCallBoundary(context)) {
|
|
2901
|
+
return;
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
startIndex = getPotentialStartIndex(state.buffer, toolCallStart);
|
|
2502
2905
|
}
|
|
2503
2906
|
}
|
|
2504
2907
|
function handlePartialTag(state, controller, toolCallStart, toolCallEnd, tools) {
|
|
@@ -2536,6 +2939,7 @@ var hermesProtocol = ({
|
|
|
2536
2939
|
toolCallStart = "<tool_call>",
|
|
2537
2940
|
toolCallEnd = "</tool_call>"
|
|
2538
2941
|
} = {}) => ({
|
|
2942
|
+
...validateNonEmptyDelimiters(toolCallStart, toolCallEnd),
|
|
2539
2943
|
formatTools({
|
|
2540
2944
|
tools,
|
|
2541
2945
|
toolSystemPromptTemplate
|
|
@@ -2560,24 +2964,42 @@ var hermesProtocol = ({
|
|
|
2560
2964
|
text,
|
|
2561
2965
|
options
|
|
2562
2966
|
}) {
|
|
2563
|
-
const startEsc = escapeRegExp(toolCallStart);
|
|
2564
|
-
const endEsc = escapeRegExp(toolCallEnd);
|
|
2565
|
-
const toolCallRegex = new RegExp(
|
|
2566
|
-
`${startEsc}([\0-\uFFFF]*?)${endEsc}`,
|
|
2567
|
-
"gs"
|
|
2568
|
-
);
|
|
2569
2967
|
const processedElements = [];
|
|
2570
2968
|
let currentIndex = 0;
|
|
2571
|
-
let
|
|
2572
|
-
while (
|
|
2573
|
-
|
|
2574
|
-
match,
|
|
2969
|
+
let searchFrom = 0;
|
|
2970
|
+
while (searchFrom < text.length) {
|
|
2971
|
+
const span = findNextToolCallSpan(
|
|
2575
2972
|
text,
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2973
|
+
searchFrom,
|
|
2974
|
+
toolCallStart,
|
|
2975
|
+
toolCallEnd
|
|
2976
|
+
);
|
|
2977
|
+
if (span === null) {
|
|
2978
|
+
break;
|
|
2979
|
+
}
|
|
2980
|
+
if (!span.found) {
|
|
2981
|
+
const skipTo = span.startIdx + toolCallStart.length;
|
|
2982
|
+
if (skipTo > currentIndex) {
|
|
2983
|
+
addTextSegment(text.slice(currentIndex, skipTo), processedElements);
|
|
2984
|
+
currentIndex = skipTo;
|
|
2985
|
+
}
|
|
2986
|
+
searchFrom = skipTo;
|
|
2987
|
+
continue;
|
|
2988
|
+
}
|
|
2989
|
+
const toolCallJson = text.slice(span.jsonStart, span.endIdx);
|
|
2990
|
+
const fullMatch = text.slice(
|
|
2991
|
+
span.startIdx,
|
|
2992
|
+
span.endIdx + toolCallEnd.length
|
|
2993
|
+
);
|
|
2994
|
+
if (span.startIdx > currentIndex) {
|
|
2995
|
+
addTextSegment(
|
|
2996
|
+
text.slice(currentIndex, span.startIdx),
|
|
2997
|
+
processedElements
|
|
2998
|
+
);
|
|
2999
|
+
}
|
|
3000
|
+
processToolCallJson(toolCallJson, fullMatch, processedElements, options);
|
|
3001
|
+
currentIndex = span.endIdx + toolCallEnd.length;
|
|
3002
|
+
searchFrom = currentIndex;
|
|
2581
3003
|
}
|
|
2582
3004
|
if (currentIndex < text.length) {
|
|
2583
3005
|
const remainingText = text.slice(currentIndex);
|
|
@@ -2630,14 +3052,26 @@ var hermesProtocol = ({
|
|
|
2630
3052
|
});
|
|
2631
3053
|
},
|
|
2632
3054
|
extractToolCallSegments({ text }) {
|
|
2633
|
-
const startEsc = escapeRegExp(toolCallStart);
|
|
2634
|
-
const endEsc = escapeRegExp(toolCallEnd);
|
|
2635
|
-
const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
|
|
2636
3055
|
const segments = [];
|
|
2637
|
-
let
|
|
2638
|
-
while (
|
|
2639
|
-
|
|
2640
|
-
|
|
3056
|
+
let searchFrom = 0;
|
|
3057
|
+
while (searchFrom < text.length) {
|
|
3058
|
+
const span = findNextToolCallSpan(
|
|
3059
|
+
text,
|
|
3060
|
+
searchFrom,
|
|
3061
|
+
toolCallStart,
|
|
3062
|
+
toolCallEnd
|
|
3063
|
+
);
|
|
3064
|
+
if (span === null) {
|
|
3065
|
+
break;
|
|
3066
|
+
}
|
|
3067
|
+
if (!span.found) {
|
|
3068
|
+
searchFrom = span.startIdx + toolCallStart.length;
|
|
3069
|
+
continue;
|
|
3070
|
+
}
|
|
3071
|
+
segments.push(
|
|
3072
|
+
text.slice(span.startIdx, span.endIdx + toolCallEnd.length)
|
|
3073
|
+
);
|
|
3074
|
+
searchFrom = span.endIdx + toolCallEnd.length;
|
|
2641
3075
|
}
|
|
2642
3076
|
return segments;
|
|
2643
3077
|
}
|
|
@@ -4485,6 +4919,11 @@ function createIntermediateCall(toolName, rawSegment, schema) {
|
|
|
4485
4919
|
};
|
|
4486
4920
|
}
|
|
4487
4921
|
|
|
4922
|
+
// src/core/utils/regex.ts
|
|
4923
|
+
function escapeRegExp(literal) {
|
|
4924
|
+
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4925
|
+
}
|
|
4926
|
+
|
|
4488
4927
|
// src/rxml/heuristics/xml-defaults.ts
|
|
4489
4928
|
var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
4490
4929
|
var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
@@ -5128,7 +5567,13 @@ function processToolCall(params) {
|
|
|
5128
5567
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
5129
5568
|
options,
|
|
5130
5569
|
`Could not process XML tool call: ${toolCall.toolName}`,
|
|
5131
|
-
{
|
|
5570
|
+
{
|
|
5571
|
+
toolCall: originalCallText,
|
|
5572
|
+
error,
|
|
5573
|
+
toolName: toolCall.toolName,
|
|
5574
|
+
toolCallId: generateToolCallId(),
|
|
5575
|
+
dropReason: "malformed-tool-call-body"
|
|
5576
|
+
}
|
|
5132
5577
|
);
|
|
5133
5578
|
processedElements.push({ type: "text", text: originalCallText });
|
|
5134
5579
|
}
|
|
@@ -5570,7 +6015,10 @@ function handleStreamingToolCallEnd(params) {
|
|
|
5570
6015
|
});
|
|
5571
6016
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, "Could not process streaming XML tool call", {
|
|
5572
6017
|
toolCall: original,
|
|
5573
|
-
error
|
|
6018
|
+
error,
|
|
6019
|
+
toolName: currentToolCall.name,
|
|
6020
|
+
toolCallId: currentToolCall.toolCallId,
|
|
6021
|
+
dropReason: "malformed-tool-call-body"
|
|
5574
6022
|
});
|
|
5575
6023
|
}
|
|
5576
6024
|
}
|
|
@@ -6132,7 +6580,13 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
6132
6580
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
6133
6581
|
options,
|
|
6134
6582
|
"Could not complete streaming XML tool call at finish.",
|
|
6135
|
-
{
|
|
6583
|
+
{
|
|
6584
|
+
toolCall: unfinishedContent,
|
|
6585
|
+
toolCallId: currentToolCall.toolCallId,
|
|
6586
|
+
toolName: currentToolCall.name,
|
|
6587
|
+
dropReason: "unfinished-tool-call",
|
|
6588
|
+
error
|
|
6589
|
+
}
|
|
6136
6590
|
);
|
|
6137
6591
|
}
|
|
6138
6592
|
buffer = "";
|
|
@@ -6358,7 +6812,8 @@ var QWEN3CODER_TOOL_PARSER_CALL_TAG_NAMES = /* @__PURE__ */ new Set([
|
|
|
6358
6812
|
"invoke",
|
|
6359
6813
|
"tool_call"
|
|
6360
6814
|
]);
|
|
6361
|
-
var CALL_SHORTHAND_VALUE_RE = /^<\s*(call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s
|
|
6815
|
+
var CALL_SHORTHAND_VALUE_RE = /^<\s*(call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>/<]+))/i;
|
|
6816
|
+
var NESTED_CALL_SHORTHAND_VALUE_RE = /<\s*(?:call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>/<]+))/i;
|
|
6362
6817
|
var QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_START_RE = /<\s*(?!\/)\s*(call|function|tool|invoke)\b/i;
|
|
6363
6818
|
var QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE = /<\s*(?!\/)\s*(call|function|tool|invoke)\b[^>]*>/i;
|
|
6364
6819
|
var QWEN3CODER_TOOL_PARSER_STREAM_TOOL_CALL_CLOSE_TAG_RE = /<\s*\/\s*tool_call\s*>/i;
|
|
@@ -6757,6 +7212,12 @@ function getShorthandValue(openTag) {
|
|
|
6757
7212
|
}
|
|
6758
7213
|
return unescapeXml(value);
|
|
6759
7214
|
}
|
|
7215
|
+
function extractShorthandToolNameFromRaw(rawText) {
|
|
7216
|
+
var _a, _b;
|
|
7217
|
+
const match = NESTED_CALL_SHORTHAND_VALUE_RE.exec(rawText);
|
|
7218
|
+
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];
|
|
7219
|
+
return value ? unescapeXml(value) : null;
|
|
7220
|
+
}
|
|
6760
7221
|
function extractFirstTagText(xml, tagName) {
|
|
6761
7222
|
var _a;
|
|
6762
7223
|
const lower = xml.toLowerCase();
|
|
@@ -7078,6 +7539,20 @@ function parseQwen3CoderToolParserClosedMatches(inner, outerNameAttr) {
|
|
|
7078
7539
|
}
|
|
7079
7540
|
return closedCalls.concat(trailingCalls);
|
|
7080
7541
|
}
|
|
7542
|
+
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;
|
|
7543
|
+
function extractQwen3CoderToolNameFromMarkup(markup) {
|
|
7544
|
+
var _a, _b, _c, _d, _e;
|
|
7545
|
+
const match = markup.match(QWEN3CODER_TOOL_NAME_SALVAGE_REGEX);
|
|
7546
|
+
if (!match) {
|
|
7547
|
+
return void 0;
|
|
7548
|
+
}
|
|
7549
|
+
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];
|
|
7550
|
+
if (!name) {
|
|
7551
|
+
return void 0;
|
|
7552
|
+
}
|
|
7553
|
+
const trimmed = name.trim();
|
|
7554
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
7555
|
+
}
|
|
7081
7556
|
function parseQwen3CoderToolParserToolCallSegment(segment) {
|
|
7082
7557
|
var _a;
|
|
7083
7558
|
const extracted = extractToolCallInnerXml(segment);
|
|
@@ -7202,7 +7677,12 @@ var qwen3CoderProtocol = () => ({
|
|
|
7202
7677
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
7203
7678
|
options,
|
|
7204
7679
|
"Could not process Qwen3CoderToolParser XML tool call; keeping original text.",
|
|
7205
|
-
{
|
|
7680
|
+
{
|
|
7681
|
+
toolCall: fallbackText,
|
|
7682
|
+
toolName: extractQwen3CoderToolNameFromMarkup(segment),
|
|
7683
|
+
toolCallId: generateToolCallId(),
|
|
7684
|
+
dropReason: "malformed-tool-call-body"
|
|
7685
|
+
}
|
|
7206
7686
|
);
|
|
7207
7687
|
processedElements.push({ type: "text", text: fallbackText });
|
|
7208
7688
|
return false;
|
|
@@ -7215,7 +7695,12 @@ var qwen3CoderProtocol = () => ({
|
|
|
7215
7695
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
7216
7696
|
options,
|
|
7217
7697
|
"Could not process Qwen3CoderToolParser <function> call; keeping original text.",
|
|
7218
|
-
{
|
|
7698
|
+
{
|
|
7699
|
+
toolCall: raw,
|
|
7700
|
+
toolName: extractQwen3CoderToolNameFromMarkup(raw),
|
|
7701
|
+
toolCallId: generateToolCallId(),
|
|
7702
|
+
dropReason: "malformed-tool-call-body"
|
|
7703
|
+
}
|
|
7219
7704
|
);
|
|
7220
7705
|
processedElements.push({ type: "text", text: raw });
|
|
7221
7706
|
};
|
|
@@ -7465,7 +7950,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
7465
7950
|
});
|
|
7466
7951
|
};
|
|
7467
7952
|
const finalizeCall = (controller, callState, fallbackToolName, rawToolCallText = null) => {
|
|
7468
|
-
var _a, _b;
|
|
7953
|
+
var _a, _b, _c, _d;
|
|
7469
7954
|
const resolvedToolName = (_a = callState.toolName) != null ? _a : fallbackToolName;
|
|
7470
7955
|
if (!resolvedToolName || resolvedToolName.trim().length === 0) {
|
|
7471
7956
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
@@ -7479,12 +7964,14 @@ var qwen3CoderProtocol = () => ({
|
|
|
7479
7964
|
flushText(controller, rawText);
|
|
7480
7965
|
}
|
|
7481
7966
|
});
|
|
7482
|
-
(
|
|
7967
|
+
(_d = options == null ? void 0 : options.onError) == null ? void 0 : _d.call(
|
|
7483
7968
|
options,
|
|
7484
7969
|
shouldEmitRaw && rawToolCallText ? "Could not resolve Qwen3CoderToolParser tool name for tool call; emitting original text." : "Could not resolve Qwen3CoderToolParser tool name for tool call",
|
|
7485
7970
|
{
|
|
7486
7971
|
toolCallId: callState.toolCallId,
|
|
7487
|
-
toolCall: rawToolCallText
|
|
7972
|
+
toolCall: rawToolCallText,
|
|
7973
|
+
toolName: (_c = (_b = callState.toolName) != null ? _b : fallbackToolName) != null ? _c : void 0,
|
|
7974
|
+
dropReason: "unresolved-tool-name"
|
|
7488
7975
|
}
|
|
7489
7976
|
);
|
|
7490
7977
|
return false;
|
|
@@ -7940,25 +8427,36 @@ var qwen3CoderProtocol = () => ({
|
|
|
7940
8427
|
}
|
|
7941
8428
|
}
|
|
7942
8429
|
};
|
|
7943
|
-
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall) => {
|
|
7944
|
-
var _a;
|
|
8430
|
+
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall, metadata = {}) => {
|
|
8431
|
+
var _a, _b;
|
|
7945
8432
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
7946
|
-
(_a =
|
|
8433
|
+
const toolName = (_a = metadata.toolName) != null ? _a : extractShorthandToolNameFromRaw(rawToolCall);
|
|
8434
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
7947
8435
|
options,
|
|
7948
8436
|
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser XML tool call at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser XML tool call at finish.",
|
|
7949
|
-
{
|
|
8437
|
+
{
|
|
8438
|
+
toolCall: rawToolCall,
|
|
8439
|
+
...metadata.toolCallId ? { toolCallId: metadata.toolCallId } : {},
|
|
8440
|
+
...toolName ? { toolName } : {},
|
|
8441
|
+
dropReason: "unfinished-tool-call"
|
|
8442
|
+
}
|
|
7950
8443
|
);
|
|
7951
8444
|
if (shouldEmitRaw) {
|
|
7952
8445
|
flushText(controller, rawToolCall);
|
|
7953
8446
|
}
|
|
7954
8447
|
};
|
|
7955
|
-
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText) => {
|
|
8448
|
+
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText, callState) => {
|
|
7956
8449
|
var _a;
|
|
7957
8450
|
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
7958
8451
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
7959
8452
|
options,
|
|
7960
8453
|
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser call block at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser call block at finish.",
|
|
7961
|
-
{
|
|
8454
|
+
{
|
|
8455
|
+
toolCall: rawCallText,
|
|
8456
|
+
toolCallId: callState.toolCallId,
|
|
8457
|
+
...callState.toolName ? { toolName: callState.toolName } : {},
|
|
8458
|
+
dropReason: "unfinished-tool-call"
|
|
8459
|
+
}
|
|
7962
8460
|
);
|
|
7963
8461
|
if (shouldEmitRaw) {
|
|
7964
8462
|
flushText(controller, rawCallText);
|
|
@@ -8009,7 +8507,10 @@ var qwen3CoderProtocol = () => ({
|
|
|
8009
8507
|
flushText(controller, result.trailingText);
|
|
8010
8508
|
}
|
|
8011
8509
|
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
8012
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
8510
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
8511
|
+
toolCallId: toolCall.activeCall.toolCallId,
|
|
8512
|
+
...toolCall.activeCall.toolName ? { toolName: toolCall.activeCall.toolName } : {}
|
|
8513
|
+
});
|
|
8013
8514
|
}
|
|
8014
8515
|
} else if (toolCall.mode === "multi") {
|
|
8015
8516
|
if (toolCall.activeCall) {
|
|
@@ -8026,14 +8527,21 @@ var qwen3CoderProtocol = () => ({
|
|
|
8026
8527
|
flushText(controller, result.trailingText);
|
|
8027
8528
|
}
|
|
8028
8529
|
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
8029
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
8530
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
8531
|
+
toolCallId: toolCall.activeCall.toolCallId,
|
|
8532
|
+
...toolCall.activeCall.toolName ? { toolName: toolCall.activeCall.toolName } : {}
|
|
8533
|
+
});
|
|
8030
8534
|
}
|
|
8031
8535
|
toolCall.activeCall = null;
|
|
8032
8536
|
} else if (toolCall.emittedToolCallCount === 0) {
|
|
8033
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
8537
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
8538
|
+
toolName: toolCall.outerNameAttr
|
|
8539
|
+
});
|
|
8034
8540
|
}
|
|
8035
8541
|
} else {
|
|
8036
|
-
reportUnfinishedToolCallAtFinish(controller, toolCall.raw
|
|
8542
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw, {
|
|
8543
|
+
toolName: toolCall.outerNameAttr
|
|
8544
|
+
});
|
|
8037
8545
|
}
|
|
8038
8546
|
toolCall = null;
|
|
8039
8547
|
}
|
|
@@ -8051,7 +8559,8 @@ var qwen3CoderProtocol = () => ({
|
|
|
8051
8559
|
if (!result.ok && openTag) {
|
|
8052
8560
|
reportUnfinishedImplicitCallAtFinish(
|
|
8053
8561
|
controller,
|
|
8054
|
-
callState.raw || openTag + callState.buffer
|
|
8562
|
+
callState.raw || openTag + callState.buffer,
|
|
8563
|
+
callState
|
|
8055
8564
|
);
|
|
8056
8565
|
}
|
|
8057
8566
|
} else {
|
|
@@ -8430,26 +8939,28 @@ function findToolCalls2(text, toolNames) {
|
|
|
8430
8939
|
);
|
|
8431
8940
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
8432
8941
|
}
|
|
8433
|
-
function
|
|
8434
|
-
|
|
8942
|
+
function yamlFailureCause(failure) {
|
|
8943
|
+
if (failure.kind === "yaml-parse-error") {
|
|
8944
|
+
return { kind: "yaml-parse-error", errors: failure.errors };
|
|
8945
|
+
}
|
|
8946
|
+
return { kind: "yaml-non-mapping" };
|
|
8947
|
+
}
|
|
8948
|
+
function parseYamlContent(yamlContent) {
|
|
8435
8949
|
const { normalized, nonEmptyLines } = normalizeYamlContent(yamlContent);
|
|
8436
8950
|
if (nonEmptyLines.length === 0) {
|
|
8437
|
-
return {};
|
|
8951
|
+
return { ok: true, value: {} };
|
|
8438
8952
|
}
|
|
8439
8953
|
const parsed = parseYamlDocumentAsMapping(normalized);
|
|
8440
8954
|
if (parsed.errors.length > 0) {
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
|
|
8955
|
+
return {
|
|
8956
|
+
ok: false,
|
|
8957
|
+
failure: { kind: "yaml-parse-error", errors: parsed.errors }
|
|
8958
|
+
};
|
|
8445
8959
|
}
|
|
8446
8960
|
if (parsed.value === null) {
|
|
8447
|
-
|
|
8448
|
-
got: "non-mapping"
|
|
8449
|
-
});
|
|
8450
|
-
return null;
|
|
8961
|
+
return { ok: false, failure: { kind: "yaml-non-mapping" } };
|
|
8451
8962
|
}
|
|
8452
|
-
return parsed.value;
|
|
8963
|
+
return { ok: true, value: parsed.value };
|
|
8453
8964
|
}
|
|
8454
8965
|
function parseYamlContentForStreamProgress(yamlContent) {
|
|
8455
8966
|
const { normalized, nonEmptyLines } = normalizeYamlContent(yamlContent);
|
|
@@ -8481,11 +8992,16 @@ function processToolCallMatch(text, tc, currentIndex, processedElements, options
|
|
|
8481
8992
|
return currentIndex;
|
|
8482
8993
|
}
|
|
8483
8994
|
addTextSegment(text.slice(currentIndex, tc.startIndex), processedElements);
|
|
8484
|
-
const
|
|
8485
|
-
if (
|
|
8995
|
+
const result = parseYamlContent(tc.content);
|
|
8996
|
+
if (!result.ok) {
|
|
8486
8997
|
const originalText = text.slice(tc.startIndex, tc.endIndex);
|
|
8998
|
+
const cause = yamlFailureCause(result.failure);
|
|
8487
8999
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse YAML tool call", {
|
|
8488
|
-
toolCall: originalText
|
|
9000
|
+
toolCall: originalText,
|
|
9001
|
+
toolName: tc.toolName,
|
|
9002
|
+
toolCallId: generateToolCallId(),
|
|
9003
|
+
dropReason: "malformed-tool-call-body",
|
|
9004
|
+
cause
|
|
8489
9005
|
});
|
|
8490
9006
|
processedElements.push({ type: "text", text: originalText });
|
|
8491
9007
|
} else {
|
|
@@ -8493,7 +9009,7 @@ function processToolCallMatch(text, tc, currentIndex, processedElements, options
|
|
|
8493
9009
|
type: "tool-call",
|
|
8494
9010
|
toolCallId: generateToolCallId(),
|
|
8495
9011
|
toolName: tc.toolName,
|
|
8496
|
-
input: JSON.stringify(
|
|
9012
|
+
input: JSON.stringify(result.value)
|
|
8497
9013
|
});
|
|
8498
9014
|
}
|
|
8499
9015
|
return tc.endIndex;
|
|
@@ -8616,9 +9132,9 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
8616
9132
|
};
|
|
8617
9133
|
const processToolCallEnd = (controller, toolContent, toolName, toolCallId) => {
|
|
8618
9134
|
var _a;
|
|
8619
|
-
const
|
|
9135
|
+
const result = parseYamlContent(toolContent);
|
|
8620
9136
|
flushText(controller);
|
|
8621
|
-
if (
|
|
9137
|
+
if (!result.ok) {
|
|
8622
9138
|
const original = `<${toolName}>${toolContent}</${toolName}>`;
|
|
8623
9139
|
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
8624
9140
|
emitFailedToolInputLifecycle({
|
|
@@ -8631,12 +9147,16 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
8631
9147
|
}
|
|
8632
9148
|
});
|
|
8633
9149
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse streaming YAML tool call", {
|
|
8634
|
-
toolCall: original
|
|
9150
|
+
toolCall: original,
|
|
9151
|
+
toolName,
|
|
9152
|
+
toolCallId,
|
|
9153
|
+
dropReason: "malformed-tool-call-body",
|
|
9154
|
+
cause: yamlFailureCause(result.failure)
|
|
8635
9155
|
});
|
|
8636
9156
|
} else {
|
|
8637
9157
|
const finalInput = stringifyToolInputWithSchema({
|
|
8638
9158
|
toolName,
|
|
8639
|
-
args:
|
|
9159
|
+
args: result.value,
|
|
8640
9160
|
tools
|
|
8641
9161
|
});
|
|
8642
9162
|
if (currentToolCall && currentToolCall.toolCallId === toolCallId) {
|
|
@@ -8666,9 +9186,9 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
8666
9186
|
emitToolInputProgress2(controller, buffer);
|
|
8667
9187
|
const { name: toolName, toolCallId } = currentToolCall;
|
|
8668
9188
|
const reconciledBuffer = stripTrailingPartialCloseTag(buffer, toolName);
|
|
8669
|
-
const
|
|
9189
|
+
const result = parseYamlContent(reconciledBuffer);
|
|
8670
9190
|
flushText(controller);
|
|
8671
|
-
if (
|
|
9191
|
+
if (!result.ok) {
|
|
8672
9192
|
const unfinishedContent = `<${toolName}>${buffer}`;
|
|
8673
9193
|
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
8674
9194
|
emitFailedToolInputLifecycle({
|
|
@@ -8683,12 +9203,18 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
8683
9203
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
8684
9204
|
options,
|
|
8685
9205
|
"Could not complete streaming YAML tool call at finish.",
|
|
8686
|
-
{
|
|
9206
|
+
{
|
|
9207
|
+
toolCall: unfinishedContent,
|
|
9208
|
+
toolCallId,
|
|
9209
|
+
toolName,
|
|
9210
|
+
dropReason: "unfinished-tool-call",
|
|
9211
|
+
cause: yamlFailureCause(result.failure)
|
|
9212
|
+
}
|
|
8687
9213
|
);
|
|
8688
9214
|
} else {
|
|
8689
9215
|
const finalInput = stringifyToolInputWithSchema({
|
|
8690
9216
|
toolName,
|
|
8691
|
-
args:
|
|
9217
|
+
args: result.value,
|
|
8692
9218
|
tools
|
|
8693
9219
|
});
|
|
8694
9220
|
emitFinalizedToolInputLifecycle({
|