@ai-sdk-tool/parser 4.0.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -20
- package/dist/{chunk-DJB4DAZO.js → chunk-GMTE7BY5.js} +1 -1
- package/dist/{chunk-DJB4DAZO.js.map → chunk-GMTE7BY5.js.map} +1 -1
- package/dist/{chunk-76E6H46R.js → chunk-MHZC45AC.js} +5 -2
- package/dist/{chunk-76E6H46R.js.map → chunk-MHZC45AC.js.map} +1 -1
- package/dist/{chunk-DPGORNPB.js → chunk-O6NWVXQD.js} +2567 -378
- package/dist/chunk-O6NWVXQD.js.map +1 -0
- package/dist/{chunk-IX4FJELL.js → chunk-QBZNMO5C.js} +1 -1
- package/dist/chunk-QBZNMO5C.js.map +1 -0
- package/dist/community.cjs +7877 -5576
- package/dist/community.cjs.map +1 -1
- package/dist/community.d.cts +7 -1
- package/dist/community.d.ts +7 -1
- package/dist/community.js +128 -8
- package/dist/community.js.map +1 -1
- package/dist/index.cjs +2572 -383
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -24
- package/dist/index.d.ts +33 -24
- package/dist/index.js +22 -14
- package/dist/rjson.cjs.map +1 -1
- package/dist/rjson.d.cts +15 -15
- package/dist/rjson.d.ts +15 -15
- package/dist/rjson.js +1 -1
- package/dist/rxml.cjs.map +1 -1
- package/dist/rxml.d.cts +23 -23
- package/dist/rxml.d.ts +23 -23
- package/dist/rxml.js +2 -2
- package/dist/schema-coerce.cjs.map +1 -1
- package/dist/schema-coerce.js +1 -1
- package/package.json +6 -6
- package/dist/chunk-DPGORNPB.js.map +0 -1
- package/dist/chunk-IX4FJELL.js.map +0 -1
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
escapeRegExp,
|
|
3
|
+
escapeXmlMinimalAttr,
|
|
4
|
+
escapeXmlMinimalText,
|
|
3
5
|
parse as parse2,
|
|
4
|
-
stringify
|
|
5
|
-
|
|
6
|
+
stringify,
|
|
7
|
+
unescapeXml
|
|
8
|
+
} from "./chunk-MHZC45AC.js";
|
|
6
9
|
import {
|
|
7
10
|
parse
|
|
8
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-QBZNMO5C.js";
|
|
9
12
|
import {
|
|
10
13
|
coerceBySchema,
|
|
11
14
|
getSchemaType,
|
|
12
15
|
unwrapJsonSchema
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GMTE7BY5.js";
|
|
14
17
|
|
|
15
18
|
// src/core/utils/debug.ts
|
|
16
19
|
var LINE_SPLIT_REGEX = /\r?\n/;
|
|
@@ -257,7 +260,7 @@ function createFlushTextHandler(getCurrentTextId, setCurrentTextId, getHasEmitte
|
|
|
257
260
|
};
|
|
258
261
|
}
|
|
259
262
|
|
|
260
|
-
// src/core/protocols/
|
|
263
|
+
// src/core/protocols/hermes-protocol.ts
|
|
261
264
|
function shouldEmitRawToolCallTextOnError(options) {
|
|
262
265
|
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
263
266
|
}
|
|
@@ -800,7 +803,7 @@ function handlePartialTag(state, controller, toolCallStart, toolCallEnd) {
|
|
|
800
803
|
state.buffer = "";
|
|
801
804
|
}
|
|
802
805
|
}
|
|
803
|
-
var
|
|
806
|
+
var hermesProtocol = ({
|
|
804
807
|
toolCallStart = "<tool_call>",
|
|
805
808
|
toolCallEnd = "</tool_call>"
|
|
806
809
|
} = {}) => ({
|
|
@@ -902,14 +905,6 @@ var jsonProtocol = ({
|
|
|
902
905
|
}
|
|
903
906
|
});
|
|
904
907
|
|
|
905
|
-
// src/core/protocols/protocol-interface.ts
|
|
906
|
-
function isProtocolFactory(protocol) {
|
|
907
|
-
return typeof protocol === "function";
|
|
908
|
-
}
|
|
909
|
-
function isTCMProtocolFactory(protocol) {
|
|
910
|
-
return typeof protocol === "function";
|
|
911
|
-
}
|
|
912
|
-
|
|
913
908
|
// src/core/utils/regex-constants.ts
|
|
914
909
|
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
915
910
|
var WHITESPACE_REGEX = /\s/;
|
|
@@ -1012,7 +1007,7 @@ ${body}
|
|
|
1012
1007
|
</${rootTag}>`;
|
|
1013
1008
|
}
|
|
1014
1009
|
|
|
1015
|
-
// src/core/protocols/xml-protocol.ts
|
|
1010
|
+
// src/core/protocols/morph-xml-protocol.ts
|
|
1016
1011
|
function getToolSchema(tools, toolName) {
|
|
1017
1012
|
var _a;
|
|
1018
1013
|
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
@@ -1988,7 +1983,7 @@ function findToolCallsWithFallbacks(text, toolNames) {
|
|
|
1988
1983
|
}
|
|
1989
1984
|
return { parseText, toolCalls };
|
|
1990
1985
|
}
|
|
1991
|
-
var
|
|
1986
|
+
var morphXmlProtocol = (protocolOptions) => {
|
|
1992
1987
|
var _a;
|
|
1993
1988
|
const parseOptions = {
|
|
1994
1989
|
repair: true,
|
|
@@ -2251,200 +2246,2070 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
2251
2246
|
};
|
|
2252
2247
|
};
|
|
2253
2248
|
|
|
2254
|
-
// src/core/protocols/
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
2249
|
+
// src/core/protocols/protocol-interface.ts
|
|
2250
|
+
function isProtocolFactory(protocol) {
|
|
2251
|
+
return typeof protocol === "function";
|
|
2258
2252
|
}
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
let pattern = selfClosingTagCache2.get(toolName);
|
|
2262
|
-
if (!pattern) {
|
|
2263
|
-
pattern = new RegExp(`<\\s*${escapeRegExp(toolName)}\\s*/>`, "g");
|
|
2264
|
-
selfClosingTagCache2.set(toolName, pattern);
|
|
2265
|
-
}
|
|
2266
|
-
return pattern;
|
|
2253
|
+
function isTCMProtocolFactory(protocol) {
|
|
2254
|
+
return typeof protocol === "function";
|
|
2267
2255
|
}
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
var
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2256
|
+
|
|
2257
|
+
// src/core/utils/tool-call-coercion.ts
|
|
2258
|
+
function coerceToolCallInput(toolName, input, tools) {
|
|
2259
|
+
var _a;
|
|
2260
|
+
let args = {};
|
|
2261
|
+
if (typeof input === "string") {
|
|
2262
|
+
try {
|
|
2263
|
+
args = JSON.parse(input);
|
|
2264
|
+
} catch (e) {
|
|
2265
|
+
return;
|
|
2266
|
+
}
|
|
2267
|
+
} else if (input && typeof input === "object") {
|
|
2268
|
+
args = input;
|
|
2269
|
+
} else {
|
|
2270
|
+
return;
|
|
2278
2271
|
}
|
|
2279
|
-
const
|
|
2280
|
-
const
|
|
2281
|
-
|
|
2282
|
-
|
|
2272
|
+
const schema = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
2273
|
+
const coerced = coerceBySchema(args, schema);
|
|
2274
|
+
return JSON.stringify(coerced != null ? coerced : {});
|
|
2275
|
+
}
|
|
2276
|
+
function coerceToolCallPart(part, tools) {
|
|
2277
|
+
const coercedInput = coerceToolCallInput(part.toolName, part.input, tools);
|
|
2278
|
+
if (coercedInput === void 0) {
|
|
2279
|
+
return part;
|
|
2283
2280
|
}
|
|
2284
|
-
|
|
2285
|
-
...
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2281
|
+
return {
|
|
2282
|
+
...part,
|
|
2283
|
+
input: coercedInput
|
|
2284
|
+
};
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
// src/core/protocols/qwen3coder-protocol.ts
|
|
2288
|
+
function shouldEmitRawToolCallTextOnError3(options) {
|
|
2289
|
+
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
2290
|
+
}
|
|
2291
|
+
var TOOL_CALL_OPEN_RE = /<tool_call\b[^>]*>/i;
|
|
2292
|
+
var TOOL_CALL_CLOSE_RE = /<\/tool_call\s*>/i;
|
|
2293
|
+
var TOOL_CALL_CLOSE_TRAILING_RE = /<\/tool_call\s*>\s*$/i;
|
|
2294
|
+
var TOOL_CALL_BLOCK_RE = /<tool_call\b[^>]*>[\s\S]*?<\/tool_call\s*>/gi;
|
|
2295
|
+
var LEADING_CALL_CLOSE_TAG_RE = /^\s*<\s*\/\s*(?:tool_call|function|call|tool|invoke)\s*>/i;
|
|
2296
|
+
var CALL_BLOCK_RE = /<(call|function|tool|invoke)\b[^>]*>[\s\S]*?<\/\1\s*>/gi;
|
|
2297
|
+
var QWEN3CODER_TOOL_PARSER_PARAM_TAG_NAMES = /* @__PURE__ */ new Set([
|
|
2298
|
+
"parameter",
|
|
2299
|
+
"param",
|
|
2300
|
+
"argument",
|
|
2301
|
+
"arg"
|
|
2302
|
+
]);
|
|
2303
|
+
var QWEN3CODER_TOOL_PARSER_CALL_TAG_NAMES = /* @__PURE__ */ new Set([
|
|
2304
|
+
"function",
|
|
2305
|
+
"call",
|
|
2306
|
+
"tool",
|
|
2307
|
+
"invoke",
|
|
2308
|
+
"tool_call"
|
|
2309
|
+
]);
|
|
2310
|
+
var CALL_SHORTHAND_VALUE_RE = /^<\s*(call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>/]+))/i;
|
|
2311
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_START_RE = /<\s*(?!\/)\s*(call|function|tool|invoke)\b/i;
|
|
2312
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE = /<\s*(?!\/)\s*(call|function|tool|invoke)\b[^>]*>/i;
|
|
2313
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_TOOL_CALL_CLOSE_TAG_RE = /<\s*\/\s*tool_call\s*>/i;
|
|
2314
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_NAME_OR_PARAM_SIGNAL_RE = /<\s*(?!\/)\s*(name|tool_name|parameter|param|argument|arg)\b/i;
|
|
2315
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_NAME_TAG_RE = /<\s*(name|tool_name)\b[^>]*>([\s\S]*?)<\s*\/\s*\1\s*>/i;
|
|
2316
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_SELF_CLOSING_TAG_RE = /\/\s*>$/;
|
|
2317
|
+
function isAsciiWhitespace(ch) {
|
|
2318
|
+
return ch === " " || ch === "\n" || ch === "\r" || ch === " " || ch === "\f";
|
|
2319
|
+
}
|
|
2320
|
+
function skipAsciiWhitespace(text, index) {
|
|
2321
|
+
var _a;
|
|
2322
|
+
let i = index;
|
|
2323
|
+
while (i < text.length && isAsciiWhitespace((_a = text[i]) != null ? _a : "")) {
|
|
2324
|
+
i += 1;
|
|
2292
2325
|
}
|
|
2293
|
-
return
|
|
2326
|
+
return i;
|
|
2294
2327
|
}
|
|
2295
|
-
function
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
const
|
|
2299
|
-
const
|
|
2300
|
-
|
|
2301
|
-
|
|
2328
|
+
function stripLeadingToolCallCloseTags(text) {
|
|
2329
|
+
let out = text;
|
|
2330
|
+
while (true) {
|
|
2331
|
+
const start = skipAsciiWhitespace(out, 0);
|
|
2332
|
+
const trimmed = out.slice(start);
|
|
2333
|
+
const match = TOOL_CALL_CLOSE_RE.exec(trimmed);
|
|
2334
|
+
if (!match || match.index !== 0 || !match[0]) {
|
|
2335
|
+
return out;
|
|
2302
2336
|
}
|
|
2303
|
-
|
|
2304
|
-
|
|
2337
|
+
out = out.slice(start + match[0].length);
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
function stripTrailingToolCallCloseTags(text) {
|
|
2341
|
+
let out = text;
|
|
2342
|
+
while (true) {
|
|
2343
|
+
const next = out.replace(TOOL_CALL_CLOSE_TRAILING_RE, "");
|
|
2344
|
+
if (next === out) {
|
|
2345
|
+
return out;
|
|
2305
2346
|
}
|
|
2306
|
-
|
|
2307
|
-
} catch (error) {
|
|
2308
|
-
return {
|
|
2309
|
-
value: null,
|
|
2310
|
-
errors: [
|
|
2311
|
-
error instanceof Error ? error.message : "Unknown YAML parsing error"
|
|
2312
|
-
]
|
|
2313
|
-
};
|
|
2347
|
+
out = next;
|
|
2314
2348
|
}
|
|
2315
2349
|
}
|
|
2316
|
-
function
|
|
2350
|
+
function isTagBoundaryChar(ch) {
|
|
2351
|
+
return ch === "" || isAsciiWhitespace(ch) || ch === ">" || ch === "/";
|
|
2352
|
+
}
|
|
2353
|
+
function findTagEndIndex(text, startIndex) {
|
|
2317
2354
|
var _a;
|
|
2318
|
-
|
|
2319
|
-
let
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2355
|
+
let quote = null;
|
|
2356
|
+
for (let i = startIndex; i < text.length; i += 1) {
|
|
2357
|
+
const ch = (_a = text[i]) != null ? _a : "";
|
|
2358
|
+
if (quote) {
|
|
2359
|
+
if (ch === quote) {
|
|
2360
|
+
quote = null;
|
|
2361
|
+
}
|
|
2362
|
+
continue;
|
|
2363
|
+
}
|
|
2364
|
+
if (ch === '"' || ch === "'") {
|
|
2365
|
+
quote = ch;
|
|
2366
|
+
continue;
|
|
2367
|
+
}
|
|
2368
|
+
if (ch === ">") {
|
|
2369
|
+
return i;
|
|
2330
2370
|
}
|
|
2331
|
-
index -= 1;
|
|
2332
2371
|
}
|
|
2333
2372
|
return null;
|
|
2334
2373
|
}
|
|
2335
|
-
function
|
|
2336
|
-
|
|
2337
|
-
|
|
2374
|
+
function parseShorthandValue(openTag, tagNameLower) {
|
|
2375
|
+
var _a, _b;
|
|
2376
|
+
let i = 1;
|
|
2377
|
+
i = skipAsciiWhitespace(openTag, i);
|
|
2378
|
+
if (!openTag.toLowerCase().startsWith(tagNameLower, i)) {
|
|
2338
2379
|
return null;
|
|
2339
2380
|
}
|
|
2340
|
-
|
|
2381
|
+
i += tagNameLower.length;
|
|
2382
|
+
i = skipAsciiWhitespace(openTag, i);
|
|
2383
|
+
if (openTag[i] !== "=") {
|
|
2384
|
+
return null;
|
|
2385
|
+
}
|
|
2386
|
+
i += 1;
|
|
2387
|
+
i = skipAsciiWhitespace(openTag, i);
|
|
2388
|
+
const quote = (_a = openTag[i]) != null ? _a : "";
|
|
2389
|
+
if (quote === '"' || quote === "'") {
|
|
2390
|
+
const end = openTag.indexOf(quote, i + 1);
|
|
2391
|
+
if (end === -1) {
|
|
2392
|
+
return null;
|
|
2393
|
+
}
|
|
2394
|
+
return openTag.slice(i + 1, end);
|
|
2395
|
+
}
|
|
2396
|
+
const start = i;
|
|
2397
|
+
while (i < openTag.length) {
|
|
2398
|
+
const ch = (_b = openTag[i]) != null ? _b : "";
|
|
2399
|
+
if (isAsciiWhitespace(ch) || ch === ">" || ch === "/") {
|
|
2400
|
+
break;
|
|
2401
|
+
}
|
|
2402
|
+
i += 1;
|
|
2403
|
+
}
|
|
2404
|
+
const value = openTag.slice(start, i);
|
|
2405
|
+
return value.length > 0 ? value : null;
|
|
2341
2406
|
}
|
|
2342
|
-
function
|
|
2343
|
-
const
|
|
2344
|
-
if (
|
|
2345
|
-
return
|
|
2407
|
+
function parseQwen3CoderToolParserParamName(openTag, tagNameLower) {
|
|
2408
|
+
const shorthand = parseShorthandValue(openTag, tagNameLower);
|
|
2409
|
+
if (shorthand != null) {
|
|
2410
|
+
return unescapeXml(shorthand);
|
|
2346
2411
|
}
|
|
2347
|
-
return
|
|
2412
|
+
return getAttributeValue(openTag, "name");
|
|
2348
2413
|
}
|
|
2349
|
-
function
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
return false;
|
|
2414
|
+
function getCdataSectionNextIndex(textLower, startIndex) {
|
|
2415
|
+
if (!textLower.startsWith("<![cdata[", startIndex)) {
|
|
2416
|
+
return startIndex;
|
|
2353
2417
|
}
|
|
2354
|
-
|
|
2418
|
+
const cdataEnd = textLower.indexOf("]]>", startIndex + "<![cdata[".length);
|
|
2419
|
+
if (cdataEnd === -1) {
|
|
2420
|
+
return null;
|
|
2421
|
+
}
|
|
2422
|
+
return cdataEnd + 3;
|
|
2355
2423
|
}
|
|
2356
|
-
function
|
|
2424
|
+
function parseMatchingTagHeader(textLower, lt, tagNameLower) {
|
|
2357
2425
|
var _a;
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2426
|
+
let i = skipAsciiWhitespace(textLower, lt + 1);
|
|
2427
|
+
const isClosing = textLower[i] === "/";
|
|
2428
|
+
if (isClosing) {
|
|
2429
|
+
i += 1;
|
|
2430
|
+
i = skipAsciiWhitespace(textLower, i);
|
|
2361
2431
|
}
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
return false;
|
|
2432
|
+
if (!textLower.startsWith(tagNameLower, i)) {
|
|
2433
|
+
return null;
|
|
2365
2434
|
}
|
|
2366
|
-
|
|
2367
|
-
|
|
2435
|
+
const afterName = i + tagNameLower.length;
|
|
2436
|
+
const boundary = (_a = textLower[afterName]) != null ? _a : "";
|
|
2437
|
+
const validBoundary = isClosing ? isTagBoundaryChar(boundary) : isTagBoundaryChar(boundary) || boundary === "=";
|
|
2438
|
+
if (boundary && !validBoundary) {
|
|
2439
|
+
return null;
|
|
2368
2440
|
}
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2441
|
+
return { isClosing, afterName };
|
|
2442
|
+
}
|
|
2443
|
+
function isSelfClosingXmlTag(textLower, lt, gt) {
|
|
2444
|
+
return textLower.slice(lt, gt + 1).trimEnd().endsWith("/>");
|
|
2445
|
+
}
|
|
2446
|
+
function findClosingTagEnd(textLower, startIndex, tagNameLower) {
|
|
2447
|
+
let depth = 1;
|
|
2448
|
+
let index = startIndex;
|
|
2449
|
+
while (true) {
|
|
2450
|
+
const lt = textLower.indexOf("<", index);
|
|
2451
|
+
if (lt === -1) {
|
|
2452
|
+
return null;
|
|
2453
|
+
}
|
|
2454
|
+
const cdataNextIndex = getCdataSectionNextIndex(textLower, lt);
|
|
2455
|
+
if (cdataNextIndex == null) {
|
|
2456
|
+
return null;
|
|
2457
|
+
}
|
|
2458
|
+
if (cdataNextIndex !== lt) {
|
|
2459
|
+
index = cdataNextIndex;
|
|
2376
2460
|
continue;
|
|
2377
2461
|
}
|
|
2378
|
-
const
|
|
2379
|
-
if (
|
|
2380
|
-
|
|
2462
|
+
const header = parseMatchingTagHeader(textLower, lt, tagNameLower);
|
|
2463
|
+
if (!header) {
|
|
2464
|
+
index = lt + 1;
|
|
2381
2465
|
continue;
|
|
2382
2466
|
}
|
|
2383
|
-
|
|
2384
|
-
|
|
2467
|
+
const gt = textLower.indexOf(">", header.afterName);
|
|
2468
|
+
if (gt === -1) {
|
|
2469
|
+
return null;
|
|
2385
2470
|
}
|
|
2386
|
-
if (
|
|
2387
|
-
|
|
2471
|
+
if (header.isClosing) {
|
|
2472
|
+
depth -= 1;
|
|
2473
|
+
if (depth === 0) {
|
|
2474
|
+
return { start: lt, end: gt + 1 };
|
|
2475
|
+
}
|
|
2476
|
+
index = gt + 1;
|
|
2477
|
+
continue;
|
|
2388
2478
|
}
|
|
2389
|
-
|
|
2479
|
+
const isSelfClosing = isSelfClosingXmlTag(textLower, lt, gt);
|
|
2480
|
+
if (!isSelfClosing) {
|
|
2481
|
+
depth += 1;
|
|
2482
|
+
}
|
|
2483
|
+
index = gt + 1;
|
|
2390
2484
|
}
|
|
2391
|
-
return false;
|
|
2392
2485
|
}
|
|
2393
|
-
function
|
|
2486
|
+
function findClosingTagStartWithBoundary(lowerText, valueStart, tagNameLower, allowEndOfStringBoundary) {
|
|
2394
2487
|
var _a;
|
|
2395
|
-
|
|
2396
|
-
|
|
2488
|
+
const needle = `</${tagNameLower}`;
|
|
2489
|
+
let searchIndex = valueStart;
|
|
2490
|
+
while (searchIndex < lowerText.length) {
|
|
2491
|
+
const found = lowerText.indexOf(needle, searchIndex);
|
|
2492
|
+
if (found === -1) {
|
|
2493
|
+
return -1;
|
|
2494
|
+
}
|
|
2495
|
+
const nextChar = (_a = lowerText[found + needle.length]) != null ? _a : "";
|
|
2496
|
+
if (nextChar === "" && !allowEndOfStringBoundary) {
|
|
2497
|
+
searchIndex = found + needle.length;
|
|
2498
|
+
continue;
|
|
2499
|
+
}
|
|
2500
|
+
if (isTagBoundaryChar(nextChar)) {
|
|
2501
|
+
return found;
|
|
2502
|
+
}
|
|
2503
|
+
searchIndex = found + needle.length;
|
|
2397
2504
|
}
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2505
|
+
return -1;
|
|
2506
|
+
}
|
|
2507
|
+
function toSupportedCallEndTagName(tagNameLower) {
|
|
2508
|
+
var _a;
|
|
2509
|
+
const normalized = (_a = tagNameLower == null ? void 0 : tagNameLower.trim().toLowerCase()) != null ? _a : "";
|
|
2510
|
+
if (!normalized) {
|
|
2402
2511
|
return null;
|
|
2403
2512
|
}
|
|
2404
|
-
|
|
2405
|
-
|
|
2513
|
+
return QWEN3CODER_TOOL_PARSER_CALL_TAG_NAMES.has(normalized) ? normalized : null;
|
|
2514
|
+
}
|
|
2515
|
+
function findUnclosedParamBoundaryIndex(lowerText, valueStart, callEndTagNameLower, allowEndOfString) {
|
|
2516
|
+
const normalizedCallEndTag = toSupportedCallEndTagName(callEndTagNameLower);
|
|
2517
|
+
const callCloseIndex = normalizedCallEndTag ? findClosingTagStartWithBoundary(
|
|
2518
|
+
lowerText,
|
|
2519
|
+
valueStart,
|
|
2520
|
+
normalizedCallEndTag,
|
|
2521
|
+
allowEndOfString
|
|
2522
|
+
) : findClosingTagStartWithBoundary(
|
|
2523
|
+
lowerText,
|
|
2524
|
+
valueStart,
|
|
2525
|
+
"function",
|
|
2526
|
+
allowEndOfString
|
|
2527
|
+
);
|
|
2528
|
+
const indices = [
|
|
2529
|
+
lowerText.indexOf("<parameter", valueStart),
|
|
2530
|
+
lowerText.indexOf("<param", valueStart),
|
|
2531
|
+
lowerText.indexOf("<argument", valueStart),
|
|
2532
|
+
lowerText.indexOf("<arg", valueStart),
|
|
2533
|
+
callCloseIndex,
|
|
2534
|
+
findClosingTagStartWithBoundary(
|
|
2535
|
+
lowerText,
|
|
2536
|
+
valueStart,
|
|
2537
|
+
"tool_call",
|
|
2538
|
+
allowEndOfString
|
|
2539
|
+
),
|
|
2540
|
+
lowerText.indexOf("<function", valueStart)
|
|
2541
|
+
].filter((index) => index !== -1);
|
|
2542
|
+
if (indices.length === 0) {
|
|
2406
2543
|
return null;
|
|
2407
2544
|
}
|
|
2408
|
-
|
|
2409
|
-
|
|
2545
|
+
return Math.min(...indices);
|
|
2546
|
+
}
|
|
2547
|
+
function parseQwen3CoderToolParserParamTagNameLower(lowerText, startIndex) {
|
|
2548
|
+
var _a;
|
|
2549
|
+
let i = skipAsciiWhitespace(lowerText, startIndex + 1);
|
|
2550
|
+
if (i >= lowerText.length) {
|
|
2551
|
+
return { kind: "partial" };
|
|
2410
2552
|
}
|
|
2411
|
-
if (
|
|
2553
|
+
if (lowerText[i] === "/") {
|
|
2412
2554
|
return null;
|
|
2413
2555
|
}
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2556
|
+
const nameStart = i;
|
|
2557
|
+
while (i < lowerText.length) {
|
|
2558
|
+
const ch = (_a = lowerText[i]) != null ? _a : "";
|
|
2559
|
+
if (isAsciiWhitespace(ch) || ch === ">" || ch === "/" || ch === "=") {
|
|
2560
|
+
break;
|
|
2561
|
+
}
|
|
2562
|
+
i += 1;
|
|
2419
2563
|
}
|
|
2420
|
-
const
|
|
2421
|
-
if (!
|
|
2422
|
-
return
|
|
2564
|
+
const tagNameLower = lowerText.slice(nameStart, i);
|
|
2565
|
+
if (!QWEN3CODER_TOOL_PARSER_PARAM_TAG_NAMES.has(tagNameLower)) {
|
|
2566
|
+
return null;
|
|
2423
2567
|
}
|
|
2424
|
-
return
|
|
2425
|
-
}
|
|
2426
|
-
function hasUnstableProgressTail(normalized) {
|
|
2427
|
-
return hasIncompleteMappingTail(normalized) || hasIncompleteSequenceTail(normalized) || hasSplitNestedKeyTail(normalized) || hasUnterminatedPlainScalarTail(normalized);
|
|
2568
|
+
return { kind: "match", tagNameLower };
|
|
2428
2569
|
}
|
|
2429
|
-
function
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2570
|
+
function parseQwen3CoderToolParserUnclosedParamValue(options) {
|
|
2571
|
+
var _a;
|
|
2572
|
+
const valueStart = options.openEnd + 1;
|
|
2573
|
+
const boundaryIndex = findUnclosedParamBoundaryIndex(
|
|
2574
|
+
options.lowerText,
|
|
2575
|
+
valueStart,
|
|
2576
|
+
(_a = options.callEndTagNameLower) != null ? _a : null,
|
|
2577
|
+
options.allowEndOfString
|
|
2578
|
+
);
|
|
2579
|
+
if (boundaryIndex == null) {
|
|
2580
|
+
if (!options.allowEndOfString) {
|
|
2581
|
+
return {
|
|
2582
|
+
kind: "partial",
|
|
2583
|
+
start: options.startIndex,
|
|
2584
|
+
openEnd: options.openEnd
|
|
2585
|
+
};
|
|
2433
2586
|
}
|
|
2434
|
-
|
|
2587
|
+
const rawValue2 = options.text.slice(valueStart);
|
|
2588
|
+
return {
|
|
2589
|
+
kind: "match",
|
|
2590
|
+
start: options.startIndex,
|
|
2591
|
+
end: options.text.length,
|
|
2592
|
+
name: options.paramName,
|
|
2593
|
+
value: rawValue2 ? normalizeXmlTextValue(rawValue2) : ""
|
|
2594
|
+
};
|
|
2435
2595
|
}
|
|
2436
|
-
|
|
2437
|
-
|
|
2596
|
+
const rawValue = options.text.slice(valueStart, boundaryIndex);
|
|
2597
|
+
return {
|
|
2598
|
+
kind: "match",
|
|
2599
|
+
start: options.startIndex,
|
|
2600
|
+
end: boundaryIndex,
|
|
2601
|
+
name: options.paramName,
|
|
2602
|
+
value: rawValue ? normalizeXmlTextValue(rawValue) : ""
|
|
2603
|
+
};
|
|
2604
|
+
}
|
|
2605
|
+
function parseQwen3CoderToolParserParamTagAt(text, lowerText, startIndex, options) {
|
|
2606
|
+
var _a;
|
|
2607
|
+
const tagNameParse = parseQwen3CoderToolParserParamTagNameLower(
|
|
2608
|
+
lowerText,
|
|
2609
|
+
startIndex
|
|
2610
|
+
);
|
|
2611
|
+
if (!tagNameParse) {
|
|
2612
|
+
return null;
|
|
2438
2613
|
}
|
|
2439
|
-
if (
|
|
2440
|
-
return
|
|
2441
|
-
Object.entries(value).map(([key, item]) => [
|
|
2442
|
-
key,
|
|
2443
|
-
trimTrailingNewlineInUnknown(item)
|
|
2444
|
-
])
|
|
2445
|
-
);
|
|
2614
|
+
if (tagNameParse.kind === "partial") {
|
|
2615
|
+
return { kind: "partial", start: startIndex, openEnd: null };
|
|
2446
2616
|
}
|
|
2447
|
-
|
|
2617
|
+
const tagNameLower = tagNameParse.tagNameLower;
|
|
2618
|
+
const openEnd = findTagEndIndex(text, startIndex);
|
|
2619
|
+
if (openEnd == null) {
|
|
2620
|
+
return { kind: "partial", start: startIndex, openEnd: null };
|
|
2621
|
+
}
|
|
2622
|
+
const openTag = text.slice(startIndex, openEnd + 1);
|
|
2623
|
+
const paramNameRaw = parseQwen3CoderToolParserParamName(
|
|
2624
|
+
openTag,
|
|
2625
|
+
tagNameLower
|
|
2626
|
+
);
|
|
2627
|
+
const paramName = (_a = paramNameRaw == null ? void 0 : paramNameRaw.trim()) != null ? _a : "";
|
|
2628
|
+
if (paramName.length === 0) {
|
|
2629
|
+
return null;
|
|
2630
|
+
}
|
|
2631
|
+
const selfClosing = openTag.trimEnd().endsWith("/>");
|
|
2632
|
+
if (selfClosing) {
|
|
2633
|
+
return {
|
|
2634
|
+
kind: "match",
|
|
2635
|
+
start: startIndex,
|
|
2636
|
+
end: openEnd + 1,
|
|
2637
|
+
name: paramName,
|
|
2638
|
+
value: ""
|
|
2639
|
+
};
|
|
2640
|
+
}
|
|
2641
|
+
const valueStart = openEnd + 1;
|
|
2642
|
+
const close = findClosingTagEnd(lowerText, valueStart, tagNameLower);
|
|
2643
|
+
if (!close) {
|
|
2644
|
+
return parseQwen3CoderToolParserUnclosedParamValue({
|
|
2645
|
+
text,
|
|
2646
|
+
lowerText,
|
|
2647
|
+
startIndex,
|
|
2648
|
+
openEnd,
|
|
2649
|
+
paramName,
|
|
2650
|
+
allowEndOfString: (options == null ? void 0 : options.allowEndOfString) === true,
|
|
2651
|
+
callEndTagNameLower: options == null ? void 0 : options.callEndTagNameLower
|
|
2652
|
+
});
|
|
2653
|
+
}
|
|
2654
|
+
const rawValue = text.slice(openEnd + 1, close.start);
|
|
2655
|
+
return {
|
|
2656
|
+
kind: "match",
|
|
2657
|
+
start: startIndex,
|
|
2658
|
+
end: close.end,
|
|
2659
|
+
name: paramName,
|
|
2660
|
+
value: rawValue ? normalizeXmlTextValue(rawValue) : ""
|
|
2661
|
+
};
|
|
2662
|
+
}
|
|
2663
|
+
function normalizeXmlTextValue(raw) {
|
|
2664
|
+
let out = raw.trim();
|
|
2665
|
+
if (out.startsWith("<![CDATA[") && out.endsWith("]]>")) {
|
|
2666
|
+
out = out.slice("<![CDATA[".length, -"]]>".length).trim();
|
|
2667
|
+
}
|
|
2668
|
+
return unescapeXml(out);
|
|
2669
|
+
}
|
|
2670
|
+
function getOpeningTag(xml) {
|
|
2671
|
+
const gt = xml.indexOf(">");
|
|
2672
|
+
if (gt === -1) {
|
|
2673
|
+
return null;
|
|
2674
|
+
}
|
|
2675
|
+
return xml.slice(0, gt + 1);
|
|
2676
|
+
}
|
|
2677
|
+
var attrValueRegExpCache = /* @__PURE__ */ new Map();
|
|
2678
|
+
function getAttributeValue(openTag, attrName) {
|
|
2679
|
+
var _a;
|
|
2680
|
+
let re = attrValueRegExpCache.get(attrName);
|
|
2681
|
+
if (!re) {
|
|
2682
|
+
re = new RegExp(
|
|
2683
|
+
`\\b${escapeRegExp(attrName)}\\s*=\\s*(["'])([\\s\\S]*?)\\1`,
|
|
2684
|
+
"i"
|
|
2685
|
+
);
|
|
2686
|
+
attrValueRegExpCache.set(attrName, re);
|
|
2687
|
+
}
|
|
2688
|
+
const match = re.exec(openTag);
|
|
2689
|
+
if (!match) {
|
|
2690
|
+
return null;
|
|
2691
|
+
}
|
|
2692
|
+
return unescapeXml((_a = match[2]) != null ? _a : "");
|
|
2693
|
+
}
|
|
2694
|
+
function getShorthandValue(openTag) {
|
|
2695
|
+
var _a, _b;
|
|
2696
|
+
const match = CALL_SHORTHAND_VALUE_RE.exec(openTag);
|
|
2697
|
+
if (!match) {
|
|
2698
|
+
return null;
|
|
2699
|
+
}
|
|
2700
|
+
const value = (_b = (_a = match[2]) != null ? _a : match[3]) != null ? _b : match[4];
|
|
2701
|
+
if (!value) {
|
|
2702
|
+
return null;
|
|
2703
|
+
}
|
|
2704
|
+
return unescapeXml(value);
|
|
2705
|
+
}
|
|
2706
|
+
function extractFirstTagText(xml, tagName) {
|
|
2707
|
+
var _a;
|
|
2708
|
+
const lower = xml.toLowerCase();
|
|
2709
|
+
const tagLower = tagName.toLowerCase();
|
|
2710
|
+
let index = 0;
|
|
2711
|
+
while (true) {
|
|
2712
|
+
const lt = lower.indexOf("<", index);
|
|
2713
|
+
if (lt === -1) {
|
|
2714
|
+
return null;
|
|
2715
|
+
}
|
|
2716
|
+
const i = skipAsciiWhitespace(lower, lt + 1);
|
|
2717
|
+
if (i >= lower.length || lower[i] === "/") {
|
|
2718
|
+
index = lt + 1;
|
|
2719
|
+
continue;
|
|
2720
|
+
}
|
|
2721
|
+
if (!lower.startsWith(tagLower, i)) {
|
|
2722
|
+
index = lt + 1;
|
|
2723
|
+
continue;
|
|
2724
|
+
}
|
|
2725
|
+
const afterName = i + tagLower.length;
|
|
2726
|
+
const boundary = (_a = lower[afterName]) != null ? _a : "";
|
|
2727
|
+
if (boundary && !isTagBoundaryChar(boundary)) {
|
|
2728
|
+
index = lt + 1;
|
|
2729
|
+
continue;
|
|
2730
|
+
}
|
|
2731
|
+
const openEnd = findTagEndIndex(xml, lt);
|
|
2732
|
+
if (openEnd == null) {
|
|
2733
|
+
return null;
|
|
2734
|
+
}
|
|
2735
|
+
const contentStart = openEnd + 1;
|
|
2736
|
+
const close = findClosingTagEnd(lower, contentStart, tagLower);
|
|
2737
|
+
if (!close) {
|
|
2738
|
+
return null;
|
|
2739
|
+
}
|
|
2740
|
+
return normalizeXmlTextValue(xml.slice(contentStart, close.start));
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
function extractToolCallInnerXml(segment) {
|
|
2744
|
+
const openMatch = TOOL_CALL_OPEN_RE.exec(segment);
|
|
2745
|
+
const closeMatch = TOOL_CALL_CLOSE_RE.exec(segment);
|
|
2746
|
+
if (!(openMatch && closeMatch)) {
|
|
2747
|
+
return null;
|
|
2748
|
+
}
|
|
2749
|
+
const openIndex = openMatch.index;
|
|
2750
|
+
const openTag = openMatch[0];
|
|
2751
|
+
const openEnd = openIndex + openTag.length;
|
|
2752
|
+
const closeIndex = segment.toLowerCase().lastIndexOf("</tool_call");
|
|
2753
|
+
if (closeIndex === -1) {
|
|
2754
|
+
return null;
|
|
2755
|
+
}
|
|
2756
|
+
const closeGt = segment.indexOf(">", closeIndex);
|
|
2757
|
+
if (closeGt === -1) {
|
|
2758
|
+
return null;
|
|
2759
|
+
}
|
|
2760
|
+
return {
|
|
2761
|
+
outerOpenTag: openTag,
|
|
2762
|
+
inner: segment.slice(openEnd, closeIndex)
|
|
2763
|
+
};
|
|
2764
|
+
}
|
|
2765
|
+
function mergeParamValue(args, key, value) {
|
|
2766
|
+
const existing = args[key];
|
|
2767
|
+
if (existing === void 0) {
|
|
2768
|
+
args[key] = value;
|
|
2769
|
+
return;
|
|
2770
|
+
}
|
|
2771
|
+
if (Array.isArray(existing)) {
|
|
2772
|
+
existing.push(value);
|
|
2773
|
+
return;
|
|
2774
|
+
}
|
|
2775
|
+
args[key] = [existing, value];
|
|
2776
|
+
}
|
|
2777
|
+
function extractParameters(xml, options) {
|
|
2778
|
+
var _a;
|
|
2779
|
+
const args = {};
|
|
2780
|
+
const lower = xml.toLowerCase();
|
|
2781
|
+
let index = 0;
|
|
2782
|
+
while (true) {
|
|
2783
|
+
const lt = lower.indexOf("<", index);
|
|
2784
|
+
if (lt === -1) {
|
|
2785
|
+
break;
|
|
2786
|
+
}
|
|
2787
|
+
const parsed = parseQwen3CoderToolParserParamTagAt(xml, lower, lt, {
|
|
2788
|
+
allowEndOfString: true,
|
|
2789
|
+
callEndTagNameLower: options == null ? void 0 : options.callEndTagNameLower
|
|
2790
|
+
});
|
|
2791
|
+
if (!parsed) {
|
|
2792
|
+
index = lt + 1;
|
|
2793
|
+
continue;
|
|
2794
|
+
}
|
|
2795
|
+
if (parsed.kind === "match") {
|
|
2796
|
+
mergeParamValue(args, parsed.name, parsed.value);
|
|
2797
|
+
index = parsed.end;
|
|
2798
|
+
continue;
|
|
2799
|
+
}
|
|
2800
|
+
index = ((_a = parsed.openEnd) != null ? _a : lt) + 1;
|
|
2801
|
+
}
|
|
2802
|
+
return args;
|
|
2803
|
+
}
|
|
2804
|
+
function parseSingleFunctionCallXml(xml, fallbackToolName) {
|
|
2805
|
+
var _a, _b, _c;
|
|
2806
|
+
const openingTag = getOpeningTag(xml);
|
|
2807
|
+
const toolNameAttr = openingTag ? getAttributeValue(openingTag, "name") : null;
|
|
2808
|
+
const shorthandName = openingTag ? getShorthandValue(openingTag) : null;
|
|
2809
|
+
const toolName = (_c = (_b = (_a = toolNameAttr != null ? toolNameAttr : shorthandName) != null ? _a : extractFirstTagText(xml, "name")) != null ? _b : extractFirstTagText(xml, "tool_name")) != null ? _c : fallbackToolName;
|
|
2810
|
+
const callEndTagNameLower = toSupportedCallEndTagName(
|
|
2811
|
+
openingTag ? getOpenTagNameLower(openingTag) : null
|
|
2812
|
+
);
|
|
2813
|
+
if (!toolName || toolName.trim().length === 0) {
|
|
2814
|
+
return null;
|
|
2815
|
+
}
|
|
2816
|
+
return {
|
|
2817
|
+
toolName,
|
|
2818
|
+
args: extractParameters(xml, { callEndTagNameLower })
|
|
2819
|
+
};
|
|
2820
|
+
}
|
|
2821
|
+
function findImplicitCallOpenIndices(lowerText) {
|
|
2822
|
+
var _a;
|
|
2823
|
+
const indices = [];
|
|
2824
|
+
let index = 0;
|
|
2825
|
+
while (true) {
|
|
2826
|
+
const lt = lowerText.indexOf("<", index);
|
|
2827
|
+
if (lt === -1) {
|
|
2828
|
+
break;
|
|
2829
|
+
}
|
|
2830
|
+
const i = skipAsciiWhitespace(lowerText, lt + 1);
|
|
2831
|
+
if (i >= lowerText.length) {
|
|
2832
|
+
break;
|
|
2833
|
+
}
|
|
2834
|
+
if (lowerText[i] === "/") {
|
|
2835
|
+
index = lt + 1;
|
|
2836
|
+
continue;
|
|
2837
|
+
}
|
|
2838
|
+
const tagNames = ["call", "function", "tool", "invoke"];
|
|
2839
|
+
for (const tagName of tagNames) {
|
|
2840
|
+
if (!lowerText.startsWith(tagName, i)) {
|
|
2841
|
+
continue;
|
|
2842
|
+
}
|
|
2843
|
+
const after = i + tagName.length;
|
|
2844
|
+
const boundary = (_a = lowerText[after]) != null ? _a : "";
|
|
2845
|
+
if (boundary && !isTagBoundaryChar(boundary) && boundary !== "=") {
|
|
2846
|
+
continue;
|
|
2847
|
+
}
|
|
2848
|
+
indices.push(lt);
|
|
2849
|
+
break;
|
|
2850
|
+
}
|
|
2851
|
+
index = lt + 1;
|
|
2852
|
+
}
|
|
2853
|
+
return indices;
|
|
2854
|
+
}
|
|
2855
|
+
function splitImplicitCallBlocks(xml) {
|
|
2856
|
+
var _a, _b;
|
|
2857
|
+
const lower = xml.toLowerCase();
|
|
2858
|
+
const starts = findImplicitCallOpenIndices(lower);
|
|
2859
|
+
if (starts.length === 0) {
|
|
2860
|
+
return [];
|
|
2861
|
+
}
|
|
2862
|
+
const blocks = [];
|
|
2863
|
+
for (let i = 0; i < starts.length; i += 1) {
|
|
2864
|
+
const start = (_a = starts[i]) != null ? _a : 0;
|
|
2865
|
+
const end = (_b = starts[i + 1]) != null ? _b : xml.length;
|
|
2866
|
+
blocks.push(xml.slice(start, end));
|
|
2867
|
+
}
|
|
2868
|
+
return blocks;
|
|
2869
|
+
}
|
|
2870
|
+
function stripLeadingCallCloseTags(text) {
|
|
2871
|
+
let out = text;
|
|
2872
|
+
while (true) {
|
|
2873
|
+
const match = LEADING_CALL_CLOSE_TAG_RE.exec(out);
|
|
2874
|
+
if (!match) {
|
|
2875
|
+
return out;
|
|
2876
|
+
}
|
|
2877
|
+
out = out.slice(match[0].length);
|
|
2878
|
+
}
|
|
2879
|
+
}
|
|
2880
|
+
function getOpenTagNameLower(openTag) {
|
|
2881
|
+
var _a;
|
|
2882
|
+
const lowerOpenTag = openTag.toLowerCase();
|
|
2883
|
+
const lt = lowerOpenTag.indexOf("<");
|
|
2884
|
+
if (lt === -1) {
|
|
2885
|
+
return null;
|
|
2886
|
+
}
|
|
2887
|
+
let i = skipAsciiWhitespace(lowerOpenTag, lt + 1);
|
|
2888
|
+
if (i >= lowerOpenTag.length || lowerOpenTag[i] === "/") {
|
|
2889
|
+
return null;
|
|
2890
|
+
}
|
|
2891
|
+
const start = i;
|
|
2892
|
+
while (i < lowerOpenTag.length) {
|
|
2893
|
+
const ch = (_a = lowerOpenTag[i]) != null ? _a : "";
|
|
2894
|
+
if (isAsciiWhitespace(ch) || ch === ">" || ch === "/" || ch === "=") {
|
|
2895
|
+
break;
|
|
2896
|
+
}
|
|
2897
|
+
i += 1;
|
|
2898
|
+
}
|
|
2899
|
+
const tagName = lowerOpenTag.slice(start, i);
|
|
2900
|
+
return tagName.length > 0 ? tagName : null;
|
|
2901
|
+
}
|
|
2902
|
+
function splitImplicitCallAndTail(callBlock) {
|
|
2903
|
+
var _a;
|
|
2904
|
+
const openingTag = getOpeningTag(callBlock);
|
|
2905
|
+
const openingTagName = toSupportedCallEndTagName(
|
|
2906
|
+
openingTag ? getOpenTagNameLower(openingTag) : null
|
|
2907
|
+
);
|
|
2908
|
+
const lowerCallBlock = callBlock.toLowerCase();
|
|
2909
|
+
let consumed = 0;
|
|
2910
|
+
if (openingTag) {
|
|
2911
|
+
consumed = openingTag.length;
|
|
2912
|
+
if (openingTagName) {
|
|
2913
|
+
const close = findClosingTagEnd(lowerCallBlock, consumed, openingTagName);
|
|
2914
|
+
if (close) {
|
|
2915
|
+
consumed = Math.max(consumed, close.end);
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
let index = 0;
|
|
2920
|
+
while (true) {
|
|
2921
|
+
const lt = lowerCallBlock.indexOf("<", index);
|
|
2922
|
+
if (lt === -1) {
|
|
2923
|
+
break;
|
|
2924
|
+
}
|
|
2925
|
+
const parsed = parseQwen3CoderToolParserParamTagAt(
|
|
2926
|
+
callBlock,
|
|
2927
|
+
lowerCallBlock,
|
|
2928
|
+
lt,
|
|
2929
|
+
{
|
|
2930
|
+
allowEndOfString: true,
|
|
2931
|
+
callEndTagNameLower: openingTagName
|
|
2932
|
+
}
|
|
2933
|
+
);
|
|
2934
|
+
if (!parsed) {
|
|
2935
|
+
index = lt + 1;
|
|
2936
|
+
continue;
|
|
2937
|
+
}
|
|
2938
|
+
if (parsed.kind === "partial") {
|
|
2939
|
+
index = ((_a = parsed.openEnd) != null ? _a : lt) + 1;
|
|
2940
|
+
continue;
|
|
2941
|
+
}
|
|
2942
|
+
consumed = Math.max(consumed, parsed.end);
|
|
2943
|
+
index = parsed.end;
|
|
2944
|
+
}
|
|
2945
|
+
const clamped = Math.max(0, Math.min(consumed, callBlock.length));
|
|
2946
|
+
return {
|
|
2947
|
+
callContent: callBlock.slice(0, clamped),
|
|
2948
|
+
trailingText: callBlock.slice(clamped)
|
|
2949
|
+
};
|
|
2950
|
+
}
|
|
2951
|
+
function parseQwen3CoderToolParserCallBlocks(blocks, outerNameAttr) {
|
|
2952
|
+
const calls = [];
|
|
2953
|
+
for (const block of blocks) {
|
|
2954
|
+
const parsed = parseSingleFunctionCallXml(block, outerNameAttr);
|
|
2955
|
+
if (!parsed) {
|
|
2956
|
+
return null;
|
|
2957
|
+
}
|
|
2958
|
+
calls.push(parsed);
|
|
2959
|
+
}
|
|
2960
|
+
return calls;
|
|
2961
|
+
}
|
|
2962
|
+
function parseQwen3CoderToolParserClosedMatches(inner, outerNameAttr) {
|
|
2963
|
+
var _a, _b;
|
|
2964
|
+
const callBlockMatches = Array.from(inner.matchAll(CALL_BLOCK_RE));
|
|
2965
|
+
if (callBlockMatches.length === 0) {
|
|
2966
|
+
return void 0;
|
|
2967
|
+
}
|
|
2968
|
+
const closedBlocks = [];
|
|
2969
|
+
let lastClosedEnd = 0;
|
|
2970
|
+
for (const match of callBlockMatches) {
|
|
2971
|
+
const callBlock = (_a = match[0]) != null ? _a : "";
|
|
2972
|
+
const startIndex = (_b = match.index) != null ? _b : -1;
|
|
2973
|
+
if (!callBlock || startIndex < 0) {
|
|
2974
|
+
continue;
|
|
2975
|
+
}
|
|
2976
|
+
closedBlocks.push(callBlock);
|
|
2977
|
+
lastClosedEnd = startIndex + callBlock.length;
|
|
2978
|
+
}
|
|
2979
|
+
const closedCalls = parseQwen3CoderToolParserCallBlocks(
|
|
2980
|
+
closedBlocks,
|
|
2981
|
+
outerNameAttr
|
|
2982
|
+
);
|
|
2983
|
+
if (!closedCalls) {
|
|
2984
|
+
return null;
|
|
2985
|
+
}
|
|
2986
|
+
const trailingInner = inner.slice(lastClosedEnd);
|
|
2987
|
+
if (trailingInner.trim().length === 0) {
|
|
2988
|
+
return closedCalls;
|
|
2989
|
+
}
|
|
2990
|
+
const trailingBlocks = splitImplicitCallBlocks(trailingInner).filter(
|
|
2991
|
+
(b) => b.trim().length > 0
|
|
2992
|
+
);
|
|
2993
|
+
if (trailingBlocks.length === 0) {
|
|
2994
|
+
return closedCalls;
|
|
2995
|
+
}
|
|
2996
|
+
const trailingCalls = parseQwen3CoderToolParserCallBlocks(
|
|
2997
|
+
trailingBlocks,
|
|
2998
|
+
outerNameAttr
|
|
2999
|
+
);
|
|
3000
|
+
if (!trailingCalls) {
|
|
3001
|
+
return closedCalls;
|
|
3002
|
+
}
|
|
3003
|
+
return closedCalls.concat(trailingCalls);
|
|
3004
|
+
}
|
|
3005
|
+
function parseQwen3CoderToolParserToolCallSegment(segment) {
|
|
3006
|
+
var _a;
|
|
3007
|
+
const extracted = extractToolCallInnerXml(segment);
|
|
3008
|
+
if (!extracted) {
|
|
3009
|
+
return null;
|
|
3010
|
+
}
|
|
3011
|
+
const { inner, outerOpenTag } = extracted;
|
|
3012
|
+
const outerNameAttr = getAttributeValue(outerOpenTag, "name");
|
|
3013
|
+
const closedCalls = parseQwen3CoderToolParserClosedMatches(
|
|
3014
|
+
inner,
|
|
3015
|
+
outerNameAttr
|
|
3016
|
+
);
|
|
3017
|
+
if (closedCalls) {
|
|
3018
|
+
return closedCalls;
|
|
3019
|
+
}
|
|
3020
|
+
if (closedCalls === null) {
|
|
3021
|
+
return null;
|
|
3022
|
+
}
|
|
3023
|
+
const implicitBlocks = splitImplicitCallBlocks(inner).filter(
|
|
3024
|
+
(b) => b.trim().length > 0
|
|
3025
|
+
);
|
|
3026
|
+
if (implicitBlocks.length > 0) {
|
|
3027
|
+
return parseQwen3CoderToolParserCallBlocks(implicitBlocks, outerNameAttr);
|
|
3028
|
+
}
|
|
3029
|
+
const single = (_a = parseSingleFunctionCallXml(inner, outerNameAttr)) != null ? _a : parseSingleFunctionCallXml(segment, outerNameAttr);
|
|
3030
|
+
if (!single) {
|
|
3031
|
+
return null;
|
|
3032
|
+
}
|
|
3033
|
+
return [single];
|
|
3034
|
+
}
|
|
3035
|
+
function parseToolCallInput(input) {
|
|
3036
|
+
if (input == null) {
|
|
3037
|
+
return {};
|
|
3038
|
+
}
|
|
3039
|
+
try {
|
|
3040
|
+
return JSON.parse(input);
|
|
3041
|
+
} catch (e) {
|
|
3042
|
+
return input;
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
3045
|
+
function stringifyToolInputWithSchema(options) {
|
|
3046
|
+
const coerced = coerceToolCallInput(
|
|
3047
|
+
options.toolName,
|
|
3048
|
+
options.args,
|
|
3049
|
+
options.tools
|
|
3050
|
+
);
|
|
3051
|
+
return coerced != null ? coerced : JSON.stringify(options.args);
|
|
3052
|
+
}
|
|
3053
|
+
function toQwen3CoderToolParserParamText(value) {
|
|
3054
|
+
if (typeof value === "string") {
|
|
3055
|
+
return value;
|
|
3056
|
+
}
|
|
3057
|
+
if (value === null) {
|
|
3058
|
+
return "None";
|
|
3059
|
+
}
|
|
3060
|
+
if (typeof value === "boolean") {
|
|
3061
|
+
return value ? "True" : "False";
|
|
3062
|
+
}
|
|
3063
|
+
if (value === void 0) {
|
|
3064
|
+
return "";
|
|
3065
|
+
}
|
|
3066
|
+
if (typeof value === "object") {
|
|
3067
|
+
return JSON.stringify(value);
|
|
3068
|
+
}
|
|
3069
|
+
return String(value);
|
|
3070
|
+
}
|
|
3071
|
+
function appendQwen3CoderToolParserParameter(lines, key, value) {
|
|
3072
|
+
const nameAttr = escapeXmlMinimalAttr(key, '"');
|
|
3073
|
+
const text = escapeXmlMinimalText(toQwen3CoderToolParserParamText(value));
|
|
3074
|
+
lines.push(` <parameter="${nameAttr}">${text}</parameter>`);
|
|
3075
|
+
}
|
|
3076
|
+
function appendQwen3CoderToolParserArgs(lines, args) {
|
|
3077
|
+
if (args && typeof args === "object" && !Array.isArray(args)) {
|
|
3078
|
+
for (const [key, value] of Object.entries(args)) {
|
|
3079
|
+
if (Array.isArray(value)) {
|
|
3080
|
+
for (const item of value) {
|
|
3081
|
+
appendQwen3CoderToolParserParameter(lines, key, item);
|
|
3082
|
+
}
|
|
3083
|
+
} else {
|
|
3084
|
+
appendQwen3CoderToolParserParameter(lines, key, value);
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
return;
|
|
3088
|
+
}
|
|
3089
|
+
if (args !== void 0 && args !== null && args !== "") {
|
|
3090
|
+
appendQwen3CoderToolParserParameter(lines, "input", args);
|
|
3091
|
+
}
|
|
3092
|
+
}
|
|
3093
|
+
var qwen3CoderProtocol = () => ({
|
|
3094
|
+
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
3095
|
+
return toolSystemPromptTemplate(tools || []);
|
|
3096
|
+
},
|
|
3097
|
+
formatToolCall(toolCall) {
|
|
3098
|
+
const args = parseToolCallInput(toolCall.input);
|
|
3099
|
+
const lines = ["<tool_call>"];
|
|
3100
|
+
lines.push(
|
|
3101
|
+
` <function="${escapeXmlMinimalAttr(toolCall.toolName, '"')}">`
|
|
3102
|
+
);
|
|
3103
|
+
appendQwen3CoderToolParserArgs(lines, args);
|
|
3104
|
+
lines.push(" </function>");
|
|
3105
|
+
lines.push("</tool_call>");
|
|
3106
|
+
return lines.join("\n");
|
|
3107
|
+
},
|
|
3108
|
+
parseGeneratedText({ text, tools, options }) {
|
|
3109
|
+
const processedElements = [];
|
|
3110
|
+
const emitToolCalls = (calls) => {
|
|
3111
|
+
for (const call of calls) {
|
|
3112
|
+
processedElements.push({
|
|
3113
|
+
type: "tool-call",
|
|
3114
|
+
toolCallId: generateToolCallId(),
|
|
3115
|
+
toolName: call.toolName,
|
|
3116
|
+
input: stringifyToolInputWithSchema({
|
|
3117
|
+
tools,
|
|
3118
|
+
toolName: call.toolName,
|
|
3119
|
+
args: call.args
|
|
3120
|
+
})
|
|
3121
|
+
});
|
|
3122
|
+
}
|
|
3123
|
+
};
|
|
3124
|
+
const pushText = (value) => {
|
|
3125
|
+
if (value.length === 0) {
|
|
3126
|
+
return;
|
|
3127
|
+
}
|
|
3128
|
+
processedElements.push({ type: "text", text: value });
|
|
3129
|
+
};
|
|
3130
|
+
const tryEmitToolCallSegment = (segment, fallbackText = segment) => {
|
|
3131
|
+
var _a;
|
|
3132
|
+
const parsedCalls = parseQwen3CoderToolParserToolCallSegment(segment);
|
|
3133
|
+
if (!parsedCalls) {
|
|
3134
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
3135
|
+
options,
|
|
3136
|
+
"Could not process Qwen3CoderToolParser XML tool call; keeping original text.",
|
|
3137
|
+
{ toolCall: fallbackText }
|
|
3138
|
+
);
|
|
3139
|
+
processedElements.push({ type: "text", text: fallbackText });
|
|
3140
|
+
return false;
|
|
3141
|
+
}
|
|
3142
|
+
emitToolCalls(parsedCalls);
|
|
3143
|
+
return true;
|
|
3144
|
+
};
|
|
3145
|
+
const emitWrapperlessCallParseFailureAsText = (raw) => {
|
|
3146
|
+
var _a;
|
|
3147
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
3148
|
+
options,
|
|
3149
|
+
"Could not process Qwen3CoderToolParser <function> call; keeping original text.",
|
|
3150
|
+
{ toolCall: raw }
|
|
3151
|
+
);
|
|
3152
|
+
processedElements.push({ type: "text", text: raw });
|
|
3153
|
+
};
|
|
3154
|
+
const tryParseCallBlocksWithoutWrapperByImplicitStarts = (sourceText, starts) => {
|
|
3155
|
+
var _a, _b;
|
|
3156
|
+
let index = 0;
|
|
3157
|
+
for (let i = 0; i < starts.length; i += 1) {
|
|
3158
|
+
const startIndex = (_a = starts[i]) != null ? _a : -1;
|
|
3159
|
+
if (startIndex < 0) {
|
|
3160
|
+
continue;
|
|
3161
|
+
}
|
|
3162
|
+
const endIndex = (_b = starts[i + 1]) != null ? _b : sourceText.length;
|
|
3163
|
+
pushText(
|
|
3164
|
+
stripTrailingToolCallCloseTags(
|
|
3165
|
+
stripLeadingToolCallCloseTags(sourceText.slice(index, startIndex))
|
|
3166
|
+
)
|
|
3167
|
+
);
|
|
3168
|
+
const full = sourceText.slice(startIndex, endIndex);
|
|
3169
|
+
const { callContent, trailingText } = splitImplicitCallAndTail(full);
|
|
3170
|
+
const parsed = parseSingleFunctionCallXml(callContent, null);
|
|
3171
|
+
if (parsed) {
|
|
3172
|
+
emitToolCalls([parsed]);
|
|
3173
|
+
pushText(
|
|
3174
|
+
stripTrailingToolCallCloseTags(
|
|
3175
|
+
stripLeadingToolCallCloseTags(trailingText)
|
|
3176
|
+
)
|
|
3177
|
+
);
|
|
3178
|
+
} else {
|
|
3179
|
+
emitWrapperlessCallParseFailureAsText(full);
|
|
3180
|
+
}
|
|
3181
|
+
index = endIndex;
|
|
3182
|
+
}
|
|
3183
|
+
pushText(
|
|
3184
|
+
stripTrailingToolCallCloseTags(
|
|
3185
|
+
stripLeadingToolCallCloseTags(sourceText.slice(index))
|
|
3186
|
+
)
|
|
3187
|
+
);
|
|
3188
|
+
return true;
|
|
3189
|
+
};
|
|
3190
|
+
const tryParseCallBlocksWithoutWrapperByMatches = (sourceText, matches) => {
|
|
3191
|
+
var _a;
|
|
3192
|
+
let index = 0;
|
|
3193
|
+
for (const match of matches) {
|
|
3194
|
+
const full = match[0];
|
|
3195
|
+
const startIndex = (_a = match.index) != null ? _a : -1;
|
|
3196
|
+
if (!full || startIndex < 0) {
|
|
3197
|
+
continue;
|
|
3198
|
+
}
|
|
3199
|
+
pushText(
|
|
3200
|
+
stripTrailingToolCallCloseTags(
|
|
3201
|
+
stripLeadingToolCallCloseTags(sourceText.slice(index, startIndex))
|
|
3202
|
+
)
|
|
3203
|
+
);
|
|
3204
|
+
const parsed = parseSingleFunctionCallXml(full, null);
|
|
3205
|
+
if (parsed) {
|
|
3206
|
+
emitToolCalls([parsed]);
|
|
3207
|
+
} else {
|
|
3208
|
+
emitWrapperlessCallParseFailureAsText(full);
|
|
3209
|
+
}
|
|
3210
|
+
index = startIndex + full.length;
|
|
3211
|
+
}
|
|
3212
|
+
const trailing = sourceText.slice(index);
|
|
3213
|
+
const trailingStarts = findImplicitCallOpenIndices(
|
|
3214
|
+
trailing.toLowerCase()
|
|
3215
|
+
);
|
|
3216
|
+
if (trailingStarts.length > 0) {
|
|
3217
|
+
return tryParseCallBlocksWithoutWrapperByImplicitStarts(
|
|
3218
|
+
trailing,
|
|
3219
|
+
trailingStarts
|
|
3220
|
+
);
|
|
3221
|
+
}
|
|
3222
|
+
pushText(
|
|
3223
|
+
stripTrailingToolCallCloseTags(stripLeadingToolCallCloseTags(trailing))
|
|
3224
|
+
);
|
|
3225
|
+
return true;
|
|
3226
|
+
};
|
|
3227
|
+
const tryParseCallBlocksWithoutWrapperText = (sourceText) => {
|
|
3228
|
+
const matches = Array.from(sourceText.matchAll(CALL_BLOCK_RE));
|
|
3229
|
+
if (matches.length > 0) {
|
|
3230
|
+
return tryParseCallBlocksWithoutWrapperByMatches(sourceText, matches);
|
|
3231
|
+
}
|
|
3232
|
+
const starts = findImplicitCallOpenIndices(sourceText.toLowerCase());
|
|
3233
|
+
if (starts.length === 0) {
|
|
3234
|
+
return false;
|
|
3235
|
+
}
|
|
3236
|
+
return tryParseCallBlocksWithoutWrapperByImplicitStarts(
|
|
3237
|
+
sourceText,
|
|
3238
|
+
starts
|
|
3239
|
+
);
|
|
3240
|
+
};
|
|
3241
|
+
const pushTextOrParseWrapperlessCalls = (segment) => {
|
|
3242
|
+
if (segment.length === 0) {
|
|
3243
|
+
return;
|
|
3244
|
+
}
|
|
3245
|
+
if (!tryParseCallBlocksWithoutWrapperText(segment)) {
|
|
3246
|
+
pushText(segment);
|
|
3247
|
+
}
|
|
3248
|
+
};
|
|
3249
|
+
const handleCompleteToolCallRemainder = (remainder) => {
|
|
3250
|
+
if (!remainder) {
|
|
3251
|
+
return;
|
|
3252
|
+
}
|
|
3253
|
+
const lowerRemainder = remainder.toLowerCase();
|
|
3254
|
+
const trailingIndex = lowerRemainder.indexOf("<tool_call");
|
|
3255
|
+
if (trailingIndex === -1) {
|
|
3256
|
+
pushTextOrParseWrapperlessCalls(remainder);
|
|
3257
|
+
return;
|
|
3258
|
+
}
|
|
3259
|
+
pushTextOrParseWrapperlessCalls(remainder.slice(0, trailingIndex));
|
|
3260
|
+
const trailing = remainder.slice(trailingIndex);
|
|
3261
|
+
const synthetic = TOOL_CALL_CLOSE_RE.test(trailing) ? trailing : `${trailing}</tool_call>`;
|
|
3262
|
+
tryEmitToolCallSegment(synthetic, trailing);
|
|
3263
|
+
};
|
|
3264
|
+
const tryParseCompleteToolCallBlocks = () => {
|
|
3265
|
+
var _a;
|
|
3266
|
+
const matches = Array.from(text.matchAll(TOOL_CALL_BLOCK_RE));
|
|
3267
|
+
if (matches.length === 0) {
|
|
3268
|
+
return false;
|
|
3269
|
+
}
|
|
3270
|
+
let index = 0;
|
|
3271
|
+
for (const match of matches) {
|
|
3272
|
+
const full = match[0];
|
|
3273
|
+
const startIndex = (_a = match.index) != null ? _a : -1;
|
|
3274
|
+
if (!full || startIndex < 0) {
|
|
3275
|
+
continue;
|
|
3276
|
+
}
|
|
3277
|
+
pushTextOrParseWrapperlessCalls(text.slice(index, startIndex));
|
|
3278
|
+
tryEmitToolCallSegment(full);
|
|
3279
|
+
index = startIndex + full.length;
|
|
3280
|
+
}
|
|
3281
|
+
handleCompleteToolCallRemainder(text.slice(index));
|
|
3282
|
+
return true;
|
|
3283
|
+
};
|
|
3284
|
+
const tryParseIncompleteToolCall = () => {
|
|
3285
|
+
const lowerText = text.toLowerCase();
|
|
3286
|
+
const startIndex = lowerText.indexOf("<tool_call");
|
|
3287
|
+
if (startIndex === -1) {
|
|
3288
|
+
return false;
|
|
3289
|
+
}
|
|
3290
|
+
pushTextOrParseWrapperlessCalls(text.slice(0, startIndex));
|
|
3291
|
+
const trailing = text.slice(startIndex);
|
|
3292
|
+
const synthetic = TOOL_CALL_CLOSE_RE.test(trailing) ? trailing : `${trailing}</tool_call>`;
|
|
3293
|
+
tryEmitToolCallSegment(synthetic, trailing);
|
|
3294
|
+
return true;
|
|
3295
|
+
};
|
|
3296
|
+
const tryParseCallBlocksWithoutWrapper = () => {
|
|
3297
|
+
return tryParseCallBlocksWithoutWrapperText(text);
|
|
3298
|
+
};
|
|
3299
|
+
const tryParseSingleFunctionCall = () => {
|
|
3300
|
+
const lowerText = text.toLowerCase();
|
|
3301
|
+
const startIndex = lowerText.indexOf("<function");
|
|
3302
|
+
if (startIndex === -1) {
|
|
3303
|
+
return false;
|
|
3304
|
+
}
|
|
3305
|
+
pushText(stripTrailingToolCallCloseTags(text.slice(0, startIndex)));
|
|
3306
|
+
const trailing = stripLeadingToolCallCloseTags(text.slice(startIndex));
|
|
3307
|
+
const parsed = parseSingleFunctionCallXml(trailing, null);
|
|
3308
|
+
if (!parsed) {
|
|
3309
|
+
processedElements.push({ type: "text", text: trailing });
|
|
3310
|
+
return true;
|
|
3311
|
+
}
|
|
3312
|
+
emitToolCalls([parsed]);
|
|
3313
|
+
return true;
|
|
3314
|
+
};
|
|
3315
|
+
if (tryParseCompleteToolCallBlocks()) {
|
|
3316
|
+
return processedElements;
|
|
3317
|
+
}
|
|
3318
|
+
if (tryParseIncompleteToolCall()) {
|
|
3319
|
+
return processedElements;
|
|
3320
|
+
}
|
|
3321
|
+
if (tryParseCallBlocksWithoutWrapper()) {
|
|
3322
|
+
return processedElements;
|
|
3323
|
+
}
|
|
3324
|
+
if (tryParseSingleFunctionCall()) {
|
|
3325
|
+
return processedElements;
|
|
3326
|
+
}
|
|
3327
|
+
return [{ type: "text", text }];
|
|
3328
|
+
},
|
|
3329
|
+
extractToolCallSegments({ text }) {
|
|
3330
|
+
return Array.from(text.matchAll(TOOL_CALL_BLOCK_RE)).map((m) => m[0]).filter((s) => Boolean(s));
|
|
3331
|
+
},
|
|
3332
|
+
createStreamParser({ tools, options }) {
|
|
3333
|
+
const toolCallStartPrefixLower = "<tool_call";
|
|
3334
|
+
const implicitCallPrefixesLower = [
|
|
3335
|
+
"<function",
|
|
3336
|
+
"<call",
|
|
3337
|
+
"<tool",
|
|
3338
|
+
"<invoke"
|
|
3339
|
+
];
|
|
3340
|
+
let buffer = "";
|
|
3341
|
+
let toolCall = null;
|
|
3342
|
+
let implicitCall = null;
|
|
3343
|
+
let implicitCallOpenTag = null;
|
|
3344
|
+
let currentTextId = null;
|
|
3345
|
+
let hasEmittedTextStart = false;
|
|
3346
|
+
const flushText = createFlushTextHandler(
|
|
3347
|
+
() => currentTextId,
|
|
3348
|
+
(id) => {
|
|
3349
|
+
currentTextId = id;
|
|
3350
|
+
},
|
|
3351
|
+
() => hasEmittedTextStart,
|
|
3352
|
+
(value) => {
|
|
3353
|
+
hasEmittedTextStart = value;
|
|
3354
|
+
}
|
|
3355
|
+
);
|
|
3356
|
+
const removeSlice = (text, start, end) => text.slice(0, start) + text.slice(end);
|
|
3357
|
+
const maybeEmitToolInputStart = (controller, callState) => {
|
|
3358
|
+
if (callState.hasEmittedStart) {
|
|
3359
|
+
return;
|
|
3360
|
+
}
|
|
3361
|
+
const toolName = callState.toolName;
|
|
3362
|
+
if (!toolName || toolName.trim().length === 0) {
|
|
3363
|
+
return;
|
|
3364
|
+
}
|
|
3365
|
+
flushText(controller);
|
|
3366
|
+
controller.enqueue({
|
|
3367
|
+
type: "tool-input-start",
|
|
3368
|
+
id: callState.toolCallId,
|
|
3369
|
+
toolName
|
|
3370
|
+
});
|
|
3371
|
+
callState.hasEmittedStart = true;
|
|
3372
|
+
};
|
|
3373
|
+
const maybeEmitToolInputProgress = (controller, callState) => {
|
|
3374
|
+
if (!callState.hasEmittedStart) {
|
|
3375
|
+
return;
|
|
3376
|
+
}
|
|
3377
|
+
const toolName = callState.toolName;
|
|
3378
|
+
if (!toolName) {
|
|
3379
|
+
return;
|
|
3380
|
+
}
|
|
3381
|
+
const fullInput = stringifyToolInputWithSchema({
|
|
3382
|
+
tools,
|
|
3383
|
+
toolName,
|
|
3384
|
+
args: callState.args
|
|
3385
|
+
});
|
|
3386
|
+
if (fullInput === "{}") {
|
|
3387
|
+
return;
|
|
3388
|
+
}
|
|
3389
|
+
const prefixCandidate = toIncompleteJsonPrefix(fullInput);
|
|
3390
|
+
emitPrefixDelta({
|
|
3391
|
+
controller,
|
|
3392
|
+
id: callState.toolCallId,
|
|
3393
|
+
state: callState,
|
|
3394
|
+
candidate: prefixCandidate
|
|
3395
|
+
});
|
|
3396
|
+
};
|
|
3397
|
+
const finalizeCall = (controller, callState, fallbackToolName, rawToolCallText = null) => {
|
|
3398
|
+
var _a, _b;
|
|
3399
|
+
const resolvedToolName = (_a = callState.toolName) != null ? _a : fallbackToolName;
|
|
3400
|
+
if (!resolvedToolName || resolvedToolName.trim().length === 0) {
|
|
3401
|
+
const shouldEmitRaw = shouldEmitRawToolCallTextOnError3(options);
|
|
3402
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
3403
|
+
options,
|
|
3404
|
+
shouldEmitRaw && rawToolCallText ? "Could not resolve Qwen3CoderToolParser tool name for tool call; emitting original text." : "Could not resolve Qwen3CoderToolParser tool name for tool call",
|
|
3405
|
+
{
|
|
3406
|
+
toolCallId: callState.toolCallId,
|
|
3407
|
+
toolCall: rawToolCallText
|
|
3408
|
+
}
|
|
3409
|
+
);
|
|
3410
|
+
if (callState.hasEmittedStart) {
|
|
3411
|
+
controller.enqueue({
|
|
3412
|
+
type: "tool-input-end",
|
|
3413
|
+
id: callState.toolCallId
|
|
3414
|
+
});
|
|
3415
|
+
}
|
|
3416
|
+
if (shouldEmitRaw && rawToolCallText) {
|
|
3417
|
+
flushText(controller, rawToolCallText);
|
|
3418
|
+
}
|
|
3419
|
+
return false;
|
|
3420
|
+
}
|
|
3421
|
+
callState.toolName = resolvedToolName;
|
|
3422
|
+
maybeEmitToolInputStart(controller, callState);
|
|
3423
|
+
maybeEmitToolInputProgress(controller, callState);
|
|
3424
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
3425
|
+
tools,
|
|
3426
|
+
toolName: resolvedToolName,
|
|
3427
|
+
args: callState.args
|
|
3428
|
+
});
|
|
3429
|
+
emitFinalRemainder({
|
|
3430
|
+
controller,
|
|
3431
|
+
id: callState.toolCallId,
|
|
3432
|
+
state: callState,
|
|
3433
|
+
finalFullJson: finalInput,
|
|
3434
|
+
onMismatch: options == null ? void 0 : options.onError
|
|
3435
|
+
});
|
|
3436
|
+
controller.enqueue({
|
|
3437
|
+
type: "tool-input-end",
|
|
3438
|
+
id: callState.toolCallId
|
|
3439
|
+
});
|
|
3440
|
+
controller.enqueue({
|
|
3441
|
+
type: "tool-call",
|
|
3442
|
+
toolCallId: callState.toolCallId,
|
|
3443
|
+
toolName: resolvedToolName,
|
|
3444
|
+
input: finalInput
|
|
3445
|
+
});
|
|
3446
|
+
return true;
|
|
3447
|
+
};
|
|
3448
|
+
const consumeToolNameTag = (controller, callState, work) => {
|
|
3449
|
+
var _a, _b, _c, _d;
|
|
3450
|
+
if (callState.toolName) {
|
|
3451
|
+
return work;
|
|
3452
|
+
}
|
|
3453
|
+
const match = QWEN3CODER_TOOL_PARSER_STREAM_NAME_TAG_RE.exec(work);
|
|
3454
|
+
if (!match) {
|
|
3455
|
+
return work;
|
|
3456
|
+
}
|
|
3457
|
+
const value = normalizeXmlTextValue((_a = match[2]) != null ? _a : "");
|
|
3458
|
+
if (value.trim().length > 0) {
|
|
3459
|
+
callState.toolName = value;
|
|
3460
|
+
}
|
|
3461
|
+
const start = (_b = match.index) != null ? _b : 0;
|
|
3462
|
+
const nextWork = removeSlice(
|
|
3463
|
+
work,
|
|
3464
|
+
start,
|
|
3465
|
+
start + ((_d = (_c = match[0]) == null ? void 0 : _c.length) != null ? _d : 0)
|
|
3466
|
+
);
|
|
3467
|
+
maybeEmitToolInputStart(controller, callState);
|
|
3468
|
+
return nextWork;
|
|
3469
|
+
};
|
|
3470
|
+
const consumeParamTags = (controller, callState, work, allowEndOfString) => {
|
|
3471
|
+
const lower = work.toLowerCase();
|
|
3472
|
+
let index = 0;
|
|
3473
|
+
let lastKept = 0;
|
|
3474
|
+
let pieces = null;
|
|
3475
|
+
while (true) {
|
|
3476
|
+
const lt = lower.indexOf("<", index);
|
|
3477
|
+
if (lt === -1) {
|
|
3478
|
+
break;
|
|
3479
|
+
}
|
|
3480
|
+
const parsed = parseQwen3CoderToolParserParamTagAt(work, lower, lt, {
|
|
3481
|
+
allowEndOfString,
|
|
3482
|
+
callEndTagNameLower: callState.endTagName
|
|
3483
|
+
});
|
|
3484
|
+
if (!parsed) {
|
|
3485
|
+
index = lt + 1;
|
|
3486
|
+
continue;
|
|
3487
|
+
}
|
|
3488
|
+
if (parsed.kind === "partial") {
|
|
3489
|
+
break;
|
|
3490
|
+
}
|
|
3491
|
+
mergeParamValue(callState.args, parsed.name, parsed.value);
|
|
3492
|
+
pieces != null ? pieces : pieces = [];
|
|
3493
|
+
pieces.push(work.slice(lastKept, parsed.start));
|
|
3494
|
+
lastKept = parsed.end;
|
|
3495
|
+
index = parsed.end;
|
|
3496
|
+
}
|
|
3497
|
+
maybeEmitToolInputStart(controller, callState);
|
|
3498
|
+
if (!pieces) {
|
|
3499
|
+
return work;
|
|
3500
|
+
}
|
|
3501
|
+
pieces.push(work.slice(lastKept));
|
|
3502
|
+
return pieces.join("");
|
|
3503
|
+
};
|
|
3504
|
+
const parseCallContent = (controller, callState, content, allowEndOfString) => {
|
|
3505
|
+
let work = content;
|
|
3506
|
+
work = consumeToolNameTag(controller, callState, work);
|
|
3507
|
+
work = consumeParamTags(controller, callState, work, allowEndOfString);
|
|
3508
|
+
maybeEmitToolInputStart(controller, callState);
|
|
3509
|
+
maybeEmitToolInputProgress(controller, callState);
|
|
3510
|
+
return work;
|
|
3511
|
+
};
|
|
3512
|
+
const closeTagCache = /* @__PURE__ */ new Map();
|
|
3513
|
+
const getCloseTagPattern = (endTagName) => {
|
|
3514
|
+
const cached = closeTagCache.get(endTagName);
|
|
3515
|
+
if (cached) {
|
|
3516
|
+
return cached;
|
|
3517
|
+
}
|
|
3518
|
+
const created = new RegExp(
|
|
3519
|
+
`<\\s*\\/\\s*${escapeRegExp(endTagName)}\\s*>`,
|
|
3520
|
+
"i"
|
|
3521
|
+
);
|
|
3522
|
+
closeTagCache.set(endTagName, created);
|
|
3523
|
+
return created;
|
|
3524
|
+
};
|
|
3525
|
+
const getNextCallStartInBuffer = (callState) => {
|
|
3526
|
+
var _a;
|
|
3527
|
+
if (callState.endTagName === "tool_call") {
|
|
3528
|
+
return -1;
|
|
3529
|
+
}
|
|
3530
|
+
const match = QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE.exec(
|
|
3531
|
+
callState.buffer
|
|
3532
|
+
);
|
|
3533
|
+
return (_a = match == null ? void 0 : match.index) != null ? _a : -1;
|
|
3534
|
+
};
|
|
3535
|
+
const finalizeStreamingCall = (controller, callState, fallbackToolName, remainder) => {
|
|
3536
|
+
const rawToolCallText = remainder.length > 0 && callState.raw.endsWith(remainder) ? callState.raw.slice(0, -remainder.length) : callState.raw;
|
|
3537
|
+
const ok = finalizeCall(
|
|
3538
|
+
controller,
|
|
3539
|
+
callState,
|
|
3540
|
+
fallbackToolName,
|
|
3541
|
+
rawToolCallText
|
|
3542
|
+
);
|
|
3543
|
+
if (ok && toolCall) {
|
|
3544
|
+
toolCall.emittedToolCallCount += 1;
|
|
3545
|
+
}
|
|
3546
|
+
};
|
|
3547
|
+
const consumeCallAtNextBoundary = (controller, callState, fallbackToolName, nextCallStart) => {
|
|
3548
|
+
const beforeNextCall = callState.buffer.slice(0, nextCallStart);
|
|
3549
|
+
const afterNextCall = callState.buffer.slice(nextCallStart);
|
|
3550
|
+
callState.buffer = parseCallContent(
|
|
3551
|
+
controller,
|
|
3552
|
+
callState,
|
|
3553
|
+
beforeNextCall,
|
|
3554
|
+
true
|
|
3555
|
+
);
|
|
3556
|
+
finalizeStreamingCall(
|
|
3557
|
+
controller,
|
|
3558
|
+
callState,
|
|
3559
|
+
fallbackToolName,
|
|
3560
|
+
afterNextCall
|
|
3561
|
+
);
|
|
3562
|
+
return { done: true, remainder: afterNextCall };
|
|
3563
|
+
};
|
|
3564
|
+
const consumeCall = (controller, callState, incoming, fallbackToolName) => {
|
|
3565
|
+
var _a, _b, _c;
|
|
3566
|
+
callState.buffer += incoming;
|
|
3567
|
+
callState.raw += incoming;
|
|
3568
|
+
const closeMatch = getCloseTagPattern(callState.endTagName).exec(
|
|
3569
|
+
callState.buffer
|
|
3570
|
+
);
|
|
3571
|
+
const closeStart = (_a = closeMatch == null ? void 0 : closeMatch.index) != null ? _a : -1;
|
|
3572
|
+
const nextCallStart = getNextCallStartInBuffer(callState);
|
|
3573
|
+
const shouldCloseAtNextBoundary = nextCallStart !== -1 && (closeStart === -1 || nextCallStart < closeStart);
|
|
3574
|
+
if (shouldCloseAtNextBoundary) {
|
|
3575
|
+
return consumeCallAtNextBoundary(
|
|
3576
|
+
controller,
|
|
3577
|
+
callState,
|
|
3578
|
+
fallbackToolName,
|
|
3579
|
+
nextCallStart
|
|
3580
|
+
);
|
|
3581
|
+
}
|
|
3582
|
+
if (!closeMatch) {
|
|
3583
|
+
callState.buffer = parseCallContent(
|
|
3584
|
+
controller,
|
|
3585
|
+
callState,
|
|
3586
|
+
callState.buffer,
|
|
3587
|
+
false
|
|
3588
|
+
);
|
|
3589
|
+
return { done: false, remainder: "" };
|
|
3590
|
+
}
|
|
3591
|
+
const closeEnd = closeStart + ((_c = (_b = closeMatch[0]) == null ? void 0 : _b.length) != null ? _c : 0);
|
|
3592
|
+
const beforeClose = callState.buffer.slice(0, closeStart);
|
|
3593
|
+
const afterClose = callState.buffer.slice(closeEnd);
|
|
3594
|
+
parseCallContent(controller, callState, beforeClose, true);
|
|
3595
|
+
callState.buffer = "";
|
|
3596
|
+
finalizeStreamingCall(
|
|
3597
|
+
controller,
|
|
3598
|
+
callState,
|
|
3599
|
+
fallbackToolName,
|
|
3600
|
+
afterClose
|
|
3601
|
+
);
|
|
3602
|
+
return { done: true, remainder: afterClose };
|
|
3603
|
+
};
|
|
3604
|
+
const finalizeCallAtFinish = (controller, callState, fallbackToolName) => {
|
|
3605
|
+
callState.buffer = parseCallContent(
|
|
3606
|
+
controller,
|
|
3607
|
+
callState,
|
|
3608
|
+
callState.buffer,
|
|
3609
|
+
true
|
|
3610
|
+
);
|
|
3611
|
+
const trailingText = stripLeadingCallCloseTags(callState.buffer);
|
|
3612
|
+
callState.buffer = "";
|
|
3613
|
+
const ok = finalizeCall(controller, callState, fallbackToolName, null);
|
|
3614
|
+
return {
|
|
3615
|
+
ok,
|
|
3616
|
+
trailingText
|
|
3617
|
+
};
|
|
3618
|
+
};
|
|
3619
|
+
const flushSafeTextPrefix = (controller) => {
|
|
3620
|
+
const lower = buffer.toLowerCase();
|
|
3621
|
+
const potentialIndices = [
|
|
3622
|
+
getPotentialStartIndex(lower, toolCallStartPrefixLower),
|
|
3623
|
+
...implicitCallPrefixesLower.map(
|
|
3624
|
+
(prefix) => getPotentialStartIndex(lower, prefix)
|
|
3625
|
+
)
|
|
3626
|
+
].filter((value) => value != null);
|
|
3627
|
+
const potentialIndex = potentialIndices.length > 0 ? Math.min(...potentialIndices) : null;
|
|
3628
|
+
if (potentialIndex == null) {
|
|
3629
|
+
if (buffer.length > 0) {
|
|
3630
|
+
flushText(controller, buffer);
|
|
3631
|
+
buffer = "";
|
|
3632
|
+
}
|
|
3633
|
+
return;
|
|
3634
|
+
}
|
|
3635
|
+
if (potentialIndex > 0) {
|
|
3636
|
+
flushText(controller, buffer.slice(0, potentialIndex));
|
|
3637
|
+
buffer = buffer.slice(potentialIndex);
|
|
3638
|
+
}
|
|
3639
|
+
};
|
|
3640
|
+
const stripLeadingToolCallCloseTagsFromBuffer = () => {
|
|
3641
|
+
if (!buffer) {
|
|
3642
|
+
return;
|
|
3643
|
+
}
|
|
3644
|
+
const stripped = stripLeadingToolCallCloseTags(buffer);
|
|
3645
|
+
if (stripped !== buffer) {
|
|
3646
|
+
buffer = stripped;
|
|
3647
|
+
}
|
|
3648
|
+
};
|
|
3649
|
+
const startToolCallIfPresent = (_controller) => {
|
|
3650
|
+
if (toolCall) {
|
|
3651
|
+
return;
|
|
3652
|
+
}
|
|
3653
|
+
if (implicitCall) {
|
|
3654
|
+
return;
|
|
3655
|
+
}
|
|
3656
|
+
const lower = buffer.toLowerCase();
|
|
3657
|
+
const startIndex = getPotentialStartIndex(
|
|
3658
|
+
lower,
|
|
3659
|
+
toolCallStartPrefixLower
|
|
3660
|
+
);
|
|
3661
|
+
if (startIndex == null || startIndex !== 0) {
|
|
3662
|
+
return;
|
|
3663
|
+
}
|
|
3664
|
+
const gtIndex = buffer.indexOf(">");
|
|
3665
|
+
if (gtIndex === -1) {
|
|
3666
|
+
return;
|
|
3667
|
+
}
|
|
3668
|
+
const openTag = buffer.slice(0, gtIndex + 1);
|
|
3669
|
+
if (!TOOL_CALL_OPEN_RE.test(openTag)) {
|
|
3670
|
+
return;
|
|
3671
|
+
}
|
|
3672
|
+
toolCall = {
|
|
3673
|
+
outerOpenTag: openTag,
|
|
3674
|
+
outerNameAttr: getAttributeValue(openTag, "name"),
|
|
3675
|
+
raw: openTag,
|
|
3676
|
+
mode: "unknown",
|
|
3677
|
+
innerBuffer: "",
|
|
3678
|
+
activeCall: null,
|
|
3679
|
+
emittedToolCallCount: 0
|
|
3680
|
+
};
|
|
3681
|
+
const remainder = buffer.slice(gtIndex + 1);
|
|
3682
|
+
buffer = "";
|
|
3683
|
+
if (remainder.length > 0) {
|
|
3684
|
+
toolCall.raw += remainder;
|
|
3685
|
+
toolCall.innerBuffer += remainder;
|
|
3686
|
+
}
|
|
3687
|
+
};
|
|
3688
|
+
const startImplicitCallIfPresent = (controller) => {
|
|
3689
|
+
var _a, _b, _c, _d;
|
|
3690
|
+
if (toolCall || implicitCall) {
|
|
3691
|
+
return;
|
|
3692
|
+
}
|
|
3693
|
+
const match = QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE.exec(buffer);
|
|
3694
|
+
const startIndex = (_a = match == null ? void 0 : match.index) != null ? _a : -1;
|
|
3695
|
+
const openTag = (_b = match == null ? void 0 : match[0]) != null ? _b : "";
|
|
3696
|
+
const callTagName = ((_c = match == null ? void 0 : match[1]) != null ? _c : "").toLowerCase();
|
|
3697
|
+
if (!match || startIndex !== 0 || !openTag || !callTagName) {
|
|
3698
|
+
return;
|
|
3699
|
+
}
|
|
3700
|
+
const inlineToolName = (_d = getAttributeValue(openTag, "name")) != null ? _d : getShorthandValue(openTag);
|
|
3701
|
+
if (!inlineToolName || inlineToolName.trim().length === 0) {
|
|
3702
|
+
return;
|
|
3703
|
+
}
|
|
3704
|
+
const selfClosing = QWEN3CODER_TOOL_PARSER_STREAM_SELF_CLOSING_TAG_RE.test(openTag);
|
|
3705
|
+
buffer = buffer.slice(openTag.length);
|
|
3706
|
+
const newCall = {
|
|
3707
|
+
endTagName: callTagName,
|
|
3708
|
+
toolCallId: generateToolCallId(),
|
|
3709
|
+
toolName: inlineToolName,
|
|
3710
|
+
hasEmittedStart: false,
|
|
3711
|
+
emittedInput: "",
|
|
3712
|
+
raw: openTag,
|
|
3713
|
+
args: {},
|
|
3714
|
+
buffer: ""
|
|
3715
|
+
};
|
|
3716
|
+
maybeEmitToolInputStart(controller, newCall);
|
|
3717
|
+
if (selfClosing) {
|
|
3718
|
+
finalizeCall(controller, newCall, inlineToolName, newCall.raw);
|
|
3719
|
+
return;
|
|
3720
|
+
}
|
|
3721
|
+
implicitCall = newCall;
|
|
3722
|
+
implicitCallOpenTag = openTag;
|
|
3723
|
+
};
|
|
3724
|
+
const processImplicitCall = (controller) => {
|
|
3725
|
+
while (implicitCall) {
|
|
3726
|
+
const callState = implicitCall;
|
|
3727
|
+
const { done, remainder } = consumeCall(
|
|
3728
|
+
controller,
|
|
3729
|
+
callState,
|
|
3730
|
+
buffer,
|
|
3731
|
+
null
|
|
3732
|
+
);
|
|
3733
|
+
buffer = "";
|
|
3734
|
+
if (!done) {
|
|
3735
|
+
return;
|
|
3736
|
+
}
|
|
3737
|
+
implicitCall = null;
|
|
3738
|
+
implicitCallOpenTag = null;
|
|
3739
|
+
if (remainder.length > 0) {
|
|
3740
|
+
buffer = remainder;
|
|
3741
|
+
}
|
|
3742
|
+
stripLeadingToolCallCloseTagsFromBuffer();
|
|
3743
|
+
flushSafeTextPrefix(controller);
|
|
3744
|
+
startToolCallIfPresent(controller);
|
|
3745
|
+
if (toolCall) {
|
|
3746
|
+
processToolCall2(controller);
|
|
3747
|
+
return;
|
|
3748
|
+
}
|
|
3749
|
+
startImplicitCallIfPresent(controller);
|
|
3750
|
+
}
|
|
3751
|
+
};
|
|
3752
|
+
const drainStarts = (controller) => {
|
|
3753
|
+
while (true) {
|
|
3754
|
+
if (toolCall || implicitCall) {
|
|
3755
|
+
return;
|
|
3756
|
+
}
|
|
3757
|
+
const before = buffer;
|
|
3758
|
+
startToolCallIfPresent(controller);
|
|
3759
|
+
if (toolCall) {
|
|
3760
|
+
processToolCall2(controller);
|
|
3761
|
+
return;
|
|
3762
|
+
}
|
|
3763
|
+
startImplicitCallIfPresent(controller);
|
|
3764
|
+
if (implicitCall) {
|
|
3765
|
+
processImplicitCall(controller);
|
|
3766
|
+
return;
|
|
3767
|
+
}
|
|
3768
|
+
if (buffer === before) {
|
|
3769
|
+
return;
|
|
3770
|
+
}
|
|
3771
|
+
stripLeadingToolCallCloseTagsFromBuffer();
|
|
3772
|
+
flushSafeTextPrefix(controller);
|
|
3773
|
+
}
|
|
3774
|
+
};
|
|
3775
|
+
const processToolCall2 = (controller) => {
|
|
3776
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
3777
|
+
while (toolCall) {
|
|
3778
|
+
if (toolCall.mode === "unknown") {
|
|
3779
|
+
const callMatch = QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_START_RE.exec(
|
|
3780
|
+
toolCall.innerBuffer
|
|
3781
|
+
);
|
|
3782
|
+
const signalMatch = QWEN3CODER_TOOL_PARSER_STREAM_NAME_OR_PARAM_SIGNAL_RE.exec(
|
|
3783
|
+
toolCall.innerBuffer
|
|
3784
|
+
);
|
|
3785
|
+
if (callMatch && (!signalMatch || ((_a = callMatch.index) != null ? _a : 0) < ((_b = signalMatch.index) != null ? _b : 0))) {
|
|
3786
|
+
toolCall.mode = "multi";
|
|
3787
|
+
} else if (signalMatch) {
|
|
3788
|
+
toolCall.mode = "single";
|
|
3789
|
+
const activeCall = {
|
|
3790
|
+
endTagName: "tool_call",
|
|
3791
|
+
toolCallId: generateToolCallId(),
|
|
3792
|
+
toolName: toolCall.outerNameAttr,
|
|
3793
|
+
hasEmittedStart: false,
|
|
3794
|
+
emittedInput: "",
|
|
3795
|
+
raw: toolCall.outerOpenTag,
|
|
3796
|
+
args: {},
|
|
3797
|
+
buffer: ""
|
|
3798
|
+
};
|
|
3799
|
+
toolCall.activeCall = activeCall;
|
|
3800
|
+
if (toolCall.outerNameAttr) {
|
|
3801
|
+
maybeEmitToolInputStart(controller, activeCall);
|
|
3802
|
+
}
|
|
3803
|
+
} else {
|
|
3804
|
+
return;
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3807
|
+
if (toolCall.mode === "single") {
|
|
3808
|
+
const callState = toolCall.activeCall;
|
|
3809
|
+
if (!callState) {
|
|
3810
|
+
return;
|
|
3811
|
+
}
|
|
3812
|
+
const { done, remainder } = consumeCall(
|
|
3813
|
+
controller,
|
|
3814
|
+
callState,
|
|
3815
|
+
toolCall.innerBuffer,
|
|
3816
|
+
toolCall.outerNameAttr
|
|
3817
|
+
);
|
|
3818
|
+
toolCall.innerBuffer = "";
|
|
3819
|
+
if (!done) {
|
|
3820
|
+
return;
|
|
3821
|
+
}
|
|
3822
|
+
toolCall = null;
|
|
3823
|
+
if (remainder.length > 0) {
|
|
3824
|
+
buffer = remainder + buffer;
|
|
3825
|
+
}
|
|
3826
|
+
flushSafeTextPrefix(controller);
|
|
3827
|
+
startToolCallIfPresent(controller);
|
|
3828
|
+
continue;
|
|
3829
|
+
}
|
|
3830
|
+
if (toolCall.mode === "multi") {
|
|
3831
|
+
if (toolCall.activeCall) {
|
|
3832
|
+
const callState = toolCall.activeCall;
|
|
3833
|
+
const { done, remainder } = consumeCall(
|
|
3834
|
+
controller,
|
|
3835
|
+
callState,
|
|
3836
|
+
toolCall.innerBuffer,
|
|
3837
|
+
toolCall.outerNameAttr
|
|
3838
|
+
);
|
|
3839
|
+
toolCall.innerBuffer = "";
|
|
3840
|
+
if (!done) {
|
|
3841
|
+
return;
|
|
3842
|
+
}
|
|
3843
|
+
toolCall.activeCall = null;
|
|
3844
|
+
toolCall.innerBuffer = remainder;
|
|
3845
|
+
continue;
|
|
3846
|
+
}
|
|
3847
|
+
const closeMatch = QWEN3CODER_TOOL_PARSER_STREAM_TOOL_CALL_CLOSE_TAG_RE.exec(
|
|
3848
|
+
toolCall.innerBuffer
|
|
3849
|
+
);
|
|
3850
|
+
const callOpenMatch = QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE.exec(
|
|
3851
|
+
toolCall.innerBuffer
|
|
3852
|
+
);
|
|
3853
|
+
if (!(closeMatch || callOpenMatch)) {
|
|
3854
|
+
return;
|
|
3855
|
+
}
|
|
3856
|
+
const closeIndex = (_c = closeMatch == null ? void 0 : closeMatch.index) != null ? _c : -1;
|
|
3857
|
+
const callIndex = (_d = callOpenMatch == null ? void 0 : callOpenMatch.index) != null ? _d : -1;
|
|
3858
|
+
const hasClose = closeIndex !== -1;
|
|
3859
|
+
const hasCall = callIndex !== -1;
|
|
3860
|
+
const chooseClose = hasClose && (!hasCall || closeIndex < callIndex);
|
|
3861
|
+
const nextIndex = chooseClose ? closeIndex : callIndex;
|
|
3862
|
+
if (nextIndex > 0) {
|
|
3863
|
+
toolCall.innerBuffer = toolCall.innerBuffer.slice(nextIndex);
|
|
3864
|
+
}
|
|
3865
|
+
if (chooseClose) {
|
|
3866
|
+
const matchLen = (_f = (_e = closeMatch == null ? void 0 : closeMatch[0]) == null ? void 0 : _e.length) != null ? _f : 0;
|
|
3867
|
+
const remainder = toolCall.innerBuffer.slice(matchLen);
|
|
3868
|
+
toolCall = null;
|
|
3869
|
+
if (remainder.length > 0) {
|
|
3870
|
+
buffer = remainder + buffer;
|
|
3871
|
+
}
|
|
3872
|
+
flushSafeTextPrefix(controller);
|
|
3873
|
+
startToolCallIfPresent(controller);
|
|
3874
|
+
continue;
|
|
3875
|
+
}
|
|
3876
|
+
if (!callOpenMatch) {
|
|
3877
|
+
return;
|
|
3878
|
+
}
|
|
3879
|
+
const openTag = (_g = callOpenMatch[0]) != null ? _g : "";
|
|
3880
|
+
const callTagName = ((_h = callOpenMatch[1]) != null ? _h : "").toLowerCase();
|
|
3881
|
+
const rest = toolCall.innerBuffer.slice(openTag.length);
|
|
3882
|
+
const selfClosing = QWEN3CODER_TOOL_PARSER_STREAM_SELF_CLOSING_TAG_RE.test(openTag);
|
|
3883
|
+
if (selfClosing) {
|
|
3884
|
+
const toolNameAttr2 = (_j = (_i = getAttributeValue(openTag, "name")) != null ? _i : getShorthandValue(openTag)) != null ? _j : toolCall.outerNameAttr;
|
|
3885
|
+
const immediateCall = {
|
|
3886
|
+
endTagName: callTagName,
|
|
3887
|
+
toolCallId: generateToolCallId(),
|
|
3888
|
+
toolName: toolNameAttr2,
|
|
3889
|
+
hasEmittedStart: false,
|
|
3890
|
+
emittedInput: "",
|
|
3891
|
+
raw: openTag,
|
|
3892
|
+
args: {},
|
|
3893
|
+
buffer: ""
|
|
3894
|
+
};
|
|
3895
|
+
const ok = finalizeCall(
|
|
3896
|
+
controller,
|
|
3897
|
+
immediateCall,
|
|
3898
|
+
toolNameAttr2,
|
|
3899
|
+
immediateCall.raw
|
|
3900
|
+
);
|
|
3901
|
+
if (ok) {
|
|
3902
|
+
toolCall.emittedToolCallCount += 1;
|
|
3903
|
+
}
|
|
3904
|
+
toolCall.innerBuffer = rest;
|
|
3905
|
+
continue;
|
|
3906
|
+
}
|
|
3907
|
+
const toolNameAttr = (_k = getAttributeValue(openTag, "name")) != null ? _k : getShorthandValue(openTag);
|
|
3908
|
+
const newCall = {
|
|
3909
|
+
endTagName: callTagName,
|
|
3910
|
+
toolCallId: generateToolCallId(),
|
|
3911
|
+
toolName: toolNameAttr,
|
|
3912
|
+
hasEmittedStart: false,
|
|
3913
|
+
emittedInput: "",
|
|
3914
|
+
raw: openTag,
|
|
3915
|
+
args: {},
|
|
3916
|
+
buffer: ""
|
|
3917
|
+
};
|
|
3918
|
+
if (toolNameAttr) {
|
|
3919
|
+
maybeEmitToolInputStart(controller, newCall);
|
|
3920
|
+
}
|
|
3921
|
+
toolCall.activeCall = newCall;
|
|
3922
|
+
toolCall.innerBuffer = rest;
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3925
|
+
};
|
|
3926
|
+
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall) => {
|
|
3927
|
+
var _a;
|
|
3928
|
+
const shouldEmitRaw = shouldEmitRawToolCallTextOnError3(options);
|
|
3929
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
3930
|
+
options,
|
|
3931
|
+
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser XML tool call at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser XML tool call at finish.",
|
|
3932
|
+
{ toolCall: rawToolCall }
|
|
3933
|
+
);
|
|
3934
|
+
if (shouldEmitRaw) {
|
|
3935
|
+
flushText(controller, rawToolCall);
|
|
3936
|
+
}
|
|
3937
|
+
};
|
|
3938
|
+
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText) => {
|
|
3939
|
+
var _a;
|
|
3940
|
+
const shouldEmitRaw = shouldEmitRawToolCallTextOnError3(options);
|
|
3941
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
3942
|
+
options,
|
|
3943
|
+
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser call block at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser call block at finish.",
|
|
3944
|
+
{ toolCall: rawCallText }
|
|
3945
|
+
);
|
|
3946
|
+
if (shouldEmitRaw) {
|
|
3947
|
+
flushText(controller, rawCallText);
|
|
3948
|
+
}
|
|
3949
|
+
};
|
|
3950
|
+
const handleFinish = (controller) => {
|
|
3951
|
+
var _a, _b;
|
|
3952
|
+
if (toolCall) {
|
|
3953
|
+
processToolCall2(controller);
|
|
3954
|
+
if (toolCall) {
|
|
3955
|
+
if (toolCall.mode === "unknown") {
|
|
3956
|
+
const callMatch = QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_START_RE.exec(
|
|
3957
|
+
toolCall.innerBuffer
|
|
3958
|
+
);
|
|
3959
|
+
const signalMatch = QWEN3CODER_TOOL_PARSER_STREAM_NAME_OR_PARAM_SIGNAL_RE.exec(
|
|
3960
|
+
toolCall.innerBuffer
|
|
3961
|
+
);
|
|
3962
|
+
if (callMatch && (!signalMatch || ((_a = callMatch.index) != null ? _a : 0) < ((_b = signalMatch.index) != null ? _b : 0))) {
|
|
3963
|
+
toolCall.mode = "multi";
|
|
3964
|
+
} else if (signalMatch) {
|
|
3965
|
+
toolCall.mode = "single";
|
|
3966
|
+
toolCall.activeCall = {
|
|
3967
|
+
endTagName: "tool_call",
|
|
3968
|
+
toolCallId: generateToolCallId(),
|
|
3969
|
+
toolName: toolCall.outerNameAttr,
|
|
3970
|
+
hasEmittedStart: false,
|
|
3971
|
+
emittedInput: "",
|
|
3972
|
+
raw: toolCall.outerOpenTag,
|
|
3973
|
+
args: {},
|
|
3974
|
+
buffer: ""
|
|
3975
|
+
};
|
|
3976
|
+
}
|
|
3977
|
+
}
|
|
3978
|
+
if (toolCall.mode === "single" && toolCall.activeCall) {
|
|
3979
|
+
toolCall.activeCall.buffer += toolCall.innerBuffer;
|
|
3980
|
+
toolCall.innerBuffer = "";
|
|
3981
|
+
const result = finalizeCallAtFinish(
|
|
3982
|
+
controller,
|
|
3983
|
+
toolCall.activeCall,
|
|
3984
|
+
toolCall.outerNameAttr
|
|
3985
|
+
);
|
|
3986
|
+
if (result.ok) {
|
|
3987
|
+
toolCall.emittedToolCallCount += 1;
|
|
3988
|
+
}
|
|
3989
|
+
const shouldFlushTrailingText = result.ok || !shouldEmitRawToolCallTextOnError3(options);
|
|
3990
|
+
if (shouldFlushTrailingText && result.trailingText.length > 0) {
|
|
3991
|
+
flushText(controller, result.trailingText);
|
|
3992
|
+
}
|
|
3993
|
+
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
3994
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw);
|
|
3995
|
+
}
|
|
3996
|
+
} else if (toolCall.mode === "multi") {
|
|
3997
|
+
if (toolCall.activeCall) {
|
|
3998
|
+
const result = finalizeCallAtFinish(
|
|
3999
|
+
controller,
|
|
4000
|
+
toolCall.activeCall,
|
|
4001
|
+
toolCall.outerNameAttr
|
|
4002
|
+
);
|
|
4003
|
+
if (result.ok) {
|
|
4004
|
+
toolCall.emittedToolCallCount += 1;
|
|
4005
|
+
}
|
|
4006
|
+
const shouldFlushTrailingText = result.ok || !shouldEmitRawToolCallTextOnError3(options);
|
|
4007
|
+
if (shouldFlushTrailingText && result.trailingText.length > 0) {
|
|
4008
|
+
flushText(controller, result.trailingText);
|
|
4009
|
+
}
|
|
4010
|
+
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
4011
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw);
|
|
4012
|
+
}
|
|
4013
|
+
toolCall.activeCall = null;
|
|
4014
|
+
} else if (toolCall.emittedToolCallCount === 0) {
|
|
4015
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw);
|
|
4016
|
+
}
|
|
4017
|
+
} else {
|
|
4018
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw);
|
|
4019
|
+
}
|
|
4020
|
+
toolCall = null;
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
if (implicitCall) {
|
|
4024
|
+
const callState = implicitCall;
|
|
4025
|
+
const openTag = implicitCallOpenTag;
|
|
4026
|
+
implicitCall = null;
|
|
4027
|
+
implicitCallOpenTag = null;
|
|
4028
|
+
const result = finalizeCallAtFinish(controller, callState, null);
|
|
4029
|
+
const shouldFlushTrailingText = result.ok || !shouldEmitRawToolCallTextOnError3(options);
|
|
4030
|
+
if (shouldFlushTrailingText && result.trailingText.length > 0) {
|
|
4031
|
+
flushText(controller, result.trailingText);
|
|
4032
|
+
}
|
|
4033
|
+
if (!result.ok && openTag) {
|
|
4034
|
+
reportUnfinishedImplicitCallAtFinish(
|
|
4035
|
+
controller,
|
|
4036
|
+
callState.raw || openTag + callState.buffer
|
|
4037
|
+
);
|
|
4038
|
+
}
|
|
4039
|
+
} else {
|
|
4040
|
+
stripLeadingToolCallCloseTagsFromBuffer();
|
|
4041
|
+
flushSafeTextPrefix(controller);
|
|
4042
|
+
drainStarts(controller);
|
|
4043
|
+
}
|
|
4044
|
+
if (buffer.length > 0) {
|
|
4045
|
+
flushText(controller, buffer);
|
|
4046
|
+
buffer = "";
|
|
4047
|
+
}
|
|
4048
|
+
flushText(controller);
|
|
4049
|
+
};
|
|
4050
|
+
const handlePassthroughChunk = (controller, chunk) => {
|
|
4051
|
+
if (!toolCall && buffer) {
|
|
4052
|
+
flushText(controller, buffer);
|
|
4053
|
+
buffer = "";
|
|
4054
|
+
}
|
|
4055
|
+
controller.enqueue(chunk);
|
|
4056
|
+
};
|
|
4057
|
+
const handleTextDeltaChunk = (controller, delta) => {
|
|
4058
|
+
if (toolCall) {
|
|
4059
|
+
toolCall.raw += delta;
|
|
4060
|
+
toolCall.innerBuffer += delta;
|
|
4061
|
+
processToolCall2(controller);
|
|
4062
|
+
return;
|
|
4063
|
+
}
|
|
4064
|
+
if (implicitCall) {
|
|
4065
|
+
const callState = implicitCall;
|
|
4066
|
+
const { done, remainder } = consumeCall(
|
|
4067
|
+
controller,
|
|
4068
|
+
callState,
|
|
4069
|
+
delta,
|
|
4070
|
+
null
|
|
4071
|
+
);
|
|
4072
|
+
if (!done) {
|
|
4073
|
+
return;
|
|
4074
|
+
}
|
|
4075
|
+
implicitCall = null;
|
|
4076
|
+
implicitCallOpenTag = null;
|
|
4077
|
+
if (remainder.length > 0) {
|
|
4078
|
+
buffer = remainder + buffer;
|
|
4079
|
+
}
|
|
4080
|
+
stripLeadingToolCallCloseTagsFromBuffer();
|
|
4081
|
+
flushSafeTextPrefix(controller);
|
|
4082
|
+
drainStarts(controller);
|
|
4083
|
+
return;
|
|
4084
|
+
}
|
|
4085
|
+
buffer += delta;
|
|
4086
|
+
stripLeadingToolCallCloseTagsFromBuffer();
|
|
4087
|
+
flushSafeTextPrefix(controller);
|
|
4088
|
+
drainStarts(controller);
|
|
4089
|
+
};
|
|
4090
|
+
const handleTransformChunk = (controller, chunk) => {
|
|
4091
|
+
if (chunk.type === "finish") {
|
|
4092
|
+
handleFinish(controller);
|
|
4093
|
+
controller.enqueue(chunk);
|
|
4094
|
+
return;
|
|
4095
|
+
}
|
|
4096
|
+
if (chunk.type !== "text-delta") {
|
|
4097
|
+
handlePassthroughChunk(controller, chunk);
|
|
4098
|
+
return;
|
|
4099
|
+
}
|
|
4100
|
+
const delta = chunk.delta;
|
|
4101
|
+
if (!delta) {
|
|
4102
|
+
return;
|
|
4103
|
+
}
|
|
4104
|
+
handleTextDeltaChunk(controller, delta);
|
|
4105
|
+
};
|
|
4106
|
+
return new TransformStream({
|
|
4107
|
+
transform(chunk, controller) {
|
|
4108
|
+
handleTransformChunk(controller, chunk);
|
|
4109
|
+
},
|
|
4110
|
+
flush(controller) {
|
|
4111
|
+
handleFinish(controller);
|
|
4112
|
+
}
|
|
4113
|
+
});
|
|
4114
|
+
}
|
|
4115
|
+
});
|
|
4116
|
+
var uiTarsXmlProtocol = qwen3CoderProtocol;
|
|
4117
|
+
var Qwen3CoderToolParser = qwen3CoderProtocol;
|
|
4118
|
+
|
|
4119
|
+
// src/core/protocols/yaml-xml-protocol.ts
|
|
4120
|
+
import YAML from "yaml";
|
|
4121
|
+
function shouldEmitRawToolCallTextOnError4(options) {
|
|
4122
|
+
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
4123
|
+
}
|
|
4124
|
+
var selfClosingTagCache2 = /* @__PURE__ */ new Map();
|
|
4125
|
+
function getSelfClosingTagPattern2(toolName) {
|
|
4126
|
+
let pattern = selfClosingTagCache2.get(toolName);
|
|
4127
|
+
if (!pattern) {
|
|
4128
|
+
pattern = new RegExp(`<\\s*${escapeRegExp(toolName)}\\s*/>`, "g");
|
|
4129
|
+
selfClosingTagCache2.set(toolName, pattern);
|
|
4130
|
+
}
|
|
4131
|
+
return pattern;
|
|
4132
|
+
}
|
|
4133
|
+
var LEADING_WHITESPACE_RE = /^(\s*)/;
|
|
4134
|
+
var INCOMPLETE_MAPPING_TAIL_RE = /^[^:[\]{}-][^:]*:\s*$/;
|
|
4135
|
+
var INCOMPLETE_SEQUENCE_TAIL_RE = /^-\s*$/;
|
|
4136
|
+
var BLOCK_SCALAR_KEY_RE = /:\s*[|>][-+0-9]*\s*$/;
|
|
4137
|
+
var PLAIN_MAPPING_VALUE_RE = /^[^:[\]{}-][^:]*:\s*(.+)$/;
|
|
4138
|
+
var PLAIN_SEQUENCE_VALUE_RE = /^-\s+(.+)$/;
|
|
4139
|
+
function normalizeYamlContent(yamlContent) {
|
|
4140
|
+
let normalized = yamlContent;
|
|
4141
|
+
if (normalized.startsWith("\n")) {
|
|
4142
|
+
normalized = normalized.slice(1);
|
|
4143
|
+
}
|
|
4144
|
+
const lines = normalized.split("\n");
|
|
4145
|
+
const nonEmptyLines = lines.filter((line) => line.trim().length > 0);
|
|
4146
|
+
if (nonEmptyLines.length === 0) {
|
|
4147
|
+
return { normalized: "", nonEmptyLines };
|
|
4148
|
+
}
|
|
4149
|
+
const minIndent = Math.min(
|
|
4150
|
+
...nonEmptyLines.map((line) => {
|
|
4151
|
+
const match = line.match(LEADING_WHITESPACE_RE);
|
|
4152
|
+
return match ? match[1].length : 0;
|
|
4153
|
+
})
|
|
4154
|
+
);
|
|
4155
|
+
if (minIndent > 0) {
|
|
4156
|
+
normalized = lines.map((line) => line.slice(minIndent)).join("\n");
|
|
4157
|
+
}
|
|
4158
|
+
return { normalized, nonEmptyLines };
|
|
4159
|
+
}
|
|
4160
|
+
function parseYamlDocumentAsMapping(normalized) {
|
|
4161
|
+
try {
|
|
4162
|
+
const doc = YAML.parseDocument(normalized);
|
|
4163
|
+
const errors = doc.errors.map((e) => e.message);
|
|
4164
|
+
const result = doc.toJSON();
|
|
4165
|
+
if (result === null) {
|
|
4166
|
+
return { value: {}, errors };
|
|
4167
|
+
}
|
|
4168
|
+
if (typeof result !== "object" || Array.isArray(result)) {
|
|
4169
|
+
return { value: null, errors };
|
|
4170
|
+
}
|
|
4171
|
+
return { value: result, errors };
|
|
4172
|
+
} catch (error) {
|
|
4173
|
+
return {
|
|
4174
|
+
value: null,
|
|
4175
|
+
errors: [
|
|
4176
|
+
error instanceof Error ? error.message : "Unknown YAML parsing error"
|
|
4177
|
+
]
|
|
4178
|
+
};
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
function getLastMeaningfulLineInfo(input) {
|
|
4182
|
+
var _a;
|
|
4183
|
+
const lines = input.split("\n");
|
|
4184
|
+
let index = lines.length - 1;
|
|
4185
|
+
while (index >= 0) {
|
|
4186
|
+
const raw = (_a = lines[index]) != null ? _a : "";
|
|
4187
|
+
const trimmed = raw.trim();
|
|
4188
|
+
if (trimmed.length > 0 && !trimmed.startsWith("#")) {
|
|
4189
|
+
return {
|
|
4190
|
+
index,
|
|
4191
|
+
raw,
|
|
4192
|
+
trimmed,
|
|
4193
|
+
indent: raw.length - raw.trimStart().length
|
|
4194
|
+
};
|
|
4195
|
+
}
|
|
4196
|
+
index -= 1;
|
|
4197
|
+
}
|
|
4198
|
+
return null;
|
|
4199
|
+
}
|
|
4200
|
+
function dropLastMeaningfulLine(input) {
|
|
4201
|
+
const lineInfo = getLastMeaningfulLineInfo(input);
|
|
4202
|
+
if (!lineInfo) {
|
|
4203
|
+
return null;
|
|
4204
|
+
}
|
|
4205
|
+
return input.split("\n").slice(0, lineInfo.index).join("\n").trimEnd();
|
|
4206
|
+
}
|
|
4207
|
+
function hasIncompleteMappingTail(normalized) {
|
|
4208
|
+
const lineInfo = getLastMeaningfulLineInfo(normalized);
|
|
4209
|
+
if (!lineInfo) {
|
|
4210
|
+
return false;
|
|
4211
|
+
}
|
|
4212
|
+
return INCOMPLETE_MAPPING_TAIL_RE.test(lineInfo.trimmed);
|
|
4213
|
+
}
|
|
4214
|
+
function hasIncompleteSequenceTail(normalized) {
|
|
4215
|
+
const lineInfo = getLastMeaningfulLineInfo(normalized);
|
|
4216
|
+
if (!lineInfo) {
|
|
4217
|
+
return false;
|
|
4218
|
+
}
|
|
4219
|
+
return INCOMPLETE_SEQUENCE_TAIL_RE.test(lineInfo.trimmed);
|
|
4220
|
+
}
|
|
4221
|
+
function hasSplitNestedKeyTail(normalized) {
|
|
4222
|
+
var _a;
|
|
4223
|
+
const lineInfo = getLastMeaningfulLineInfo(normalized);
|
|
4224
|
+
if (!lineInfo) {
|
|
4225
|
+
return false;
|
|
4226
|
+
}
|
|
4227
|
+
const { trimmed, indent, index } = lineInfo;
|
|
4228
|
+
if (indent === 0) {
|
|
4229
|
+
return false;
|
|
4230
|
+
}
|
|
4231
|
+
if (trimmed.startsWith("#") || trimmed.startsWith("-") || trimmed.includes(":")) {
|
|
4232
|
+
return false;
|
|
4233
|
+
}
|
|
4234
|
+
const lines = normalized.split("\n");
|
|
4235
|
+
let parentIndex = index - 1;
|
|
4236
|
+
while (parentIndex >= 0) {
|
|
4237
|
+
const parentRaw = (_a = lines[parentIndex]) != null ? _a : "";
|
|
4238
|
+
const parentTrimmed = parentRaw.trim();
|
|
4239
|
+
if (parentTrimmed.length === 0 || parentTrimmed.startsWith("#")) {
|
|
4240
|
+
parentIndex -= 1;
|
|
4241
|
+
continue;
|
|
4242
|
+
}
|
|
4243
|
+
const parentIndent = parentRaw.length - parentRaw.trimStart().length;
|
|
4244
|
+
if (parentIndent >= indent) {
|
|
4245
|
+
parentIndex -= 1;
|
|
4246
|
+
continue;
|
|
4247
|
+
}
|
|
4248
|
+
if (!parentTrimmed.endsWith(":")) {
|
|
4249
|
+
return false;
|
|
4250
|
+
}
|
|
4251
|
+
if (BLOCK_SCALAR_KEY_RE.test(parentTrimmed)) {
|
|
4252
|
+
return false;
|
|
4253
|
+
}
|
|
4254
|
+
return true;
|
|
4255
|
+
}
|
|
4256
|
+
return false;
|
|
4257
|
+
}
|
|
4258
|
+
function extractTrailingPlainScalarValue(line) {
|
|
4259
|
+
var _a;
|
|
4260
|
+
if (BLOCK_SCALAR_KEY_RE.test(line)) {
|
|
4261
|
+
return null;
|
|
4262
|
+
}
|
|
4263
|
+
const mappingMatch = line.match(PLAIN_MAPPING_VALUE_RE);
|
|
4264
|
+
const sequenceMatch = line.match(PLAIN_SEQUENCE_VALUE_RE);
|
|
4265
|
+
const value = (_a = mappingMatch == null ? void 0 : mappingMatch[1]) != null ? _a : sequenceMatch == null ? void 0 : sequenceMatch[1];
|
|
4266
|
+
if (!value) {
|
|
4267
|
+
return null;
|
|
4268
|
+
}
|
|
4269
|
+
const trimmedValue = value.trim();
|
|
4270
|
+
if (trimmedValue.length === 0) {
|
|
4271
|
+
return null;
|
|
4272
|
+
}
|
|
4273
|
+
if (trimmedValue.startsWith('"') || trimmedValue.startsWith("'")) {
|
|
4274
|
+
return null;
|
|
4275
|
+
}
|
|
4276
|
+
if (trimmedValue.startsWith("{") || trimmedValue.startsWith("[") || trimmedValue.startsWith("|") || trimmedValue.startsWith(">")) {
|
|
4277
|
+
return null;
|
|
4278
|
+
}
|
|
4279
|
+
return trimmedValue;
|
|
4280
|
+
}
|
|
4281
|
+
function hasUnterminatedPlainScalarTail(normalized) {
|
|
4282
|
+
if (normalized.endsWith("\n")) {
|
|
4283
|
+
return false;
|
|
4284
|
+
}
|
|
4285
|
+
const lineInfo = getLastMeaningfulLineInfo(normalized);
|
|
4286
|
+
if (!lineInfo) {
|
|
4287
|
+
return false;
|
|
4288
|
+
}
|
|
4289
|
+
return extractTrailingPlainScalarValue(lineInfo.trimmed) != null;
|
|
4290
|
+
}
|
|
4291
|
+
function hasUnstableProgressTail(normalized) {
|
|
4292
|
+
return hasIncompleteMappingTail(normalized) || hasIncompleteSequenceTail(normalized) || hasSplitNestedKeyTail(normalized) || hasUnterminatedPlainScalarTail(normalized);
|
|
4293
|
+
}
|
|
4294
|
+
function trimTrailingNewlineInUnknown(value) {
|
|
4295
|
+
if (typeof value === "string") {
|
|
4296
|
+
if (value.endsWith("\n")) {
|
|
4297
|
+
return value.slice(0, -1);
|
|
4298
|
+
}
|
|
4299
|
+
return value;
|
|
4300
|
+
}
|
|
4301
|
+
if (Array.isArray(value)) {
|
|
4302
|
+
return value.map((item) => trimTrailingNewlineInUnknown(item));
|
|
4303
|
+
}
|
|
4304
|
+
if (value && typeof value === "object") {
|
|
4305
|
+
return Object.fromEntries(
|
|
4306
|
+
Object.entries(value).map(([key, item]) => [
|
|
4307
|
+
key,
|
|
4308
|
+
trimTrailingNewlineInUnknown(item)
|
|
4309
|
+
])
|
|
4310
|
+
);
|
|
4311
|
+
}
|
|
4312
|
+
return value;
|
|
2448
4313
|
}
|
|
2449
4314
|
function stabilizeParsedValueForStreamProgress(value, source) {
|
|
2450
4315
|
if (source.endsWith("\n")) {
|
|
@@ -2452,7 +4317,7 @@ function stabilizeParsedValueForStreamProgress(value, source) {
|
|
|
2452
4317
|
}
|
|
2453
4318
|
return trimTrailingNewlineInUnknown(value);
|
|
2454
4319
|
}
|
|
2455
|
-
function
|
|
4320
|
+
function findClosingTagEnd2(text, contentStart, toolName) {
|
|
2456
4321
|
let pos = contentStart;
|
|
2457
4322
|
let depth = 1;
|
|
2458
4323
|
while (pos < text.length) {
|
|
@@ -2550,7 +4415,7 @@ function collectToolCallsForName(text, toolName) {
|
|
|
2550
4415
|
continue;
|
|
2551
4416
|
}
|
|
2552
4417
|
const contentStart = tagStart + startTag.length;
|
|
2553
|
-
const fullTagEnd =
|
|
4418
|
+
const fullTagEnd = findClosingTagEnd2(text, contentStart, toolName);
|
|
2554
4419
|
if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
|
|
2555
4420
|
const endTag = `</${toolName}>`;
|
|
2556
4421
|
const endTagStart = fullTagEnd - endTag.length;
|
|
@@ -2700,7 +4565,7 @@ function stripTrailingPartialCloseTag(content, toolName) {
|
|
|
2700
4565
|
)}${preservedLeadingWhitespace}`;
|
|
2701
4566
|
return contentWithoutPartial.trimEnd();
|
|
2702
4567
|
}
|
|
2703
|
-
var
|
|
4568
|
+
var yamlXmlProtocol = (_protocolOptions) => {
|
|
2704
4569
|
return {
|
|
2705
4570
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
2706
4571
|
return toolSystemPromptTemplate(tools || []);
|
|
@@ -2824,7 +4689,7 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2824
4689
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse streaming YAML tool call", {
|
|
2825
4690
|
toolCall: original
|
|
2826
4691
|
});
|
|
2827
|
-
if (
|
|
4692
|
+
if (shouldEmitRawToolCallTextOnError4(options)) {
|
|
2828
4693
|
flushText(controller, original);
|
|
2829
4694
|
}
|
|
2830
4695
|
}
|
|
@@ -2869,7 +4734,7 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2869
4734
|
"Could not complete streaming YAML tool call at finish.",
|
|
2870
4735
|
{ toolCall: unfinishedContent }
|
|
2871
4736
|
);
|
|
2872
|
-
if (
|
|
4737
|
+
if (shouldEmitRawToolCallTextOnError4(options)) {
|
|
2873
4738
|
flushText(controller, unfinishedContent);
|
|
2874
4739
|
}
|
|
2875
4740
|
}
|
|
@@ -3410,36 +5275,6 @@ function recoverToolCallFromJsonCandidates(text, tools) {
|
|
|
3410
5275
|
return null;
|
|
3411
5276
|
}
|
|
3412
5277
|
|
|
3413
|
-
// src/core/utils/tool-call-coercion.ts
|
|
3414
|
-
function coerceToolCallInput(toolName, input, tools) {
|
|
3415
|
-
var _a;
|
|
3416
|
-
let args = {};
|
|
3417
|
-
if (typeof input === "string") {
|
|
3418
|
-
try {
|
|
3419
|
-
args = JSON.parse(input);
|
|
3420
|
-
} catch (e) {
|
|
3421
|
-
return;
|
|
3422
|
-
}
|
|
3423
|
-
} else if (input && typeof input === "object") {
|
|
3424
|
-
args = input;
|
|
3425
|
-
} else {
|
|
3426
|
-
return;
|
|
3427
|
-
}
|
|
3428
|
-
const schema = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
3429
|
-
const coerced = coerceBySchema(args, schema);
|
|
3430
|
-
return JSON.stringify(coerced != null ? coerced : {});
|
|
3431
|
-
}
|
|
3432
|
-
function coerceToolCallPart(part, tools) {
|
|
3433
|
-
const coercedInput = coerceToolCallInput(part.toolName, part.input, tools);
|
|
3434
|
-
if (coercedInput === void 0) {
|
|
3435
|
-
return part;
|
|
3436
|
-
}
|
|
3437
|
-
return {
|
|
3438
|
-
...part,
|
|
3439
|
-
input: coercedInput
|
|
3440
|
-
};
|
|
3441
|
-
}
|
|
3442
|
-
|
|
3443
5278
|
// src/core/utils/tool-choice.ts
|
|
3444
5279
|
function ensureNonEmptyToolName(name) {
|
|
3445
5280
|
if (typeof name !== "string") {
|
|
@@ -3647,23 +5482,127 @@ async function wrapGenerate({
|
|
|
3647
5482
|
};
|
|
3648
5483
|
}
|
|
3649
5484
|
|
|
3650
|
-
// src/core/prompts/
|
|
3651
|
-
function
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
5485
|
+
// src/core/prompts/shared/tool-result-normalizer.ts
|
|
5486
|
+
function isMapping(value) {
|
|
5487
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5488
|
+
}
|
|
5489
|
+
function getMediaKindFromMediaType(mediaType) {
|
|
5490
|
+
if (mediaType.startsWith("image/")) {
|
|
5491
|
+
return "image";
|
|
5492
|
+
}
|
|
5493
|
+
if (mediaType.startsWith("audio/")) {
|
|
5494
|
+
return "audio";
|
|
5495
|
+
}
|
|
5496
|
+
if (mediaType.startsWith("video/")) {
|
|
5497
|
+
return "video";
|
|
5498
|
+
}
|
|
5499
|
+
return "file";
|
|
5500
|
+
}
|
|
5501
|
+
function getContentPartMediaKind(part) {
|
|
5502
|
+
const contentPart = isMapping(part) ? part : void 0;
|
|
5503
|
+
const type = contentPart == null ? void 0 : contentPart.type;
|
|
5504
|
+
switch (type) {
|
|
5505
|
+
case "image-data":
|
|
5506
|
+
case "image-url":
|
|
5507
|
+
case "image-file-id":
|
|
5508
|
+
return "image";
|
|
5509
|
+
case "file-data":
|
|
5510
|
+
case "file-url":
|
|
5511
|
+
case "file-id": {
|
|
5512
|
+
const mediaType = contentPart == null ? void 0 : contentPart.mediaType;
|
|
5513
|
+
if (typeof mediaType === "string") {
|
|
5514
|
+
return getMediaKindFromMediaType(mediaType);
|
|
5515
|
+
}
|
|
5516
|
+
return "file";
|
|
5517
|
+
}
|
|
5518
|
+
case "media": {
|
|
5519
|
+
const mediaType = contentPart == null ? void 0 : contentPart.mediaType;
|
|
5520
|
+
if (typeof mediaType === "string") {
|
|
5521
|
+
return getMediaKindFromMediaType(mediaType);
|
|
5522
|
+
}
|
|
5523
|
+
return "file";
|
|
5524
|
+
}
|
|
5525
|
+
default:
|
|
5526
|
+
return null;
|
|
5527
|
+
}
|
|
5528
|
+
}
|
|
5529
|
+
function shouldPassRawByStrategy(mediaKind, strategy) {
|
|
5530
|
+
var _a, _b;
|
|
5531
|
+
const mode = (_a = strategy == null ? void 0 : strategy.mode) != null ? _a : "placeholder";
|
|
5532
|
+
if (mode === "raw") {
|
|
5533
|
+
return true;
|
|
5534
|
+
}
|
|
5535
|
+
if (mode === "placeholder") {
|
|
5536
|
+
return false;
|
|
5537
|
+
}
|
|
5538
|
+
if (mode === "model") {
|
|
5539
|
+
return false;
|
|
5540
|
+
}
|
|
5541
|
+
return ((_b = strategy == null ? void 0 : strategy.capabilities) == null ? void 0 : _b[mediaKind]) === true;
|
|
5542
|
+
}
|
|
5543
|
+
function shouldPassRawContent(contentParts, strategy) {
|
|
5544
|
+
var _a;
|
|
5545
|
+
const mode = (_a = strategy == null ? void 0 : strategy.mode) != null ? _a : "placeholder";
|
|
5546
|
+
if (mode === "raw") {
|
|
5547
|
+
return true;
|
|
5548
|
+
}
|
|
5549
|
+
if (mode === "placeholder") {
|
|
5550
|
+
return false;
|
|
5551
|
+
}
|
|
5552
|
+
if (mode === "model") {
|
|
5553
|
+
return false;
|
|
5554
|
+
}
|
|
5555
|
+
let hasSupportedMediaContent = false;
|
|
5556
|
+
for (const part of contentParts) {
|
|
5557
|
+
const mediaKind = getContentPartMediaKind(part);
|
|
5558
|
+
if (!mediaKind) {
|
|
5559
|
+
continue;
|
|
5560
|
+
}
|
|
5561
|
+
hasSupportedMediaContent = true;
|
|
5562
|
+
if (!shouldPassRawByStrategy(mediaKind, strategy)) {
|
|
5563
|
+
return false;
|
|
5564
|
+
}
|
|
5565
|
+
}
|
|
5566
|
+
return hasSupportedMediaContent;
|
|
5567
|
+
}
|
|
5568
|
+
function formatContentPartPlaceholder(part) {
|
|
5569
|
+
var _a;
|
|
5570
|
+
const contentPart = part;
|
|
5571
|
+
switch (contentPart.type) {
|
|
5572
|
+
case "text":
|
|
5573
|
+
return (_a = contentPart.text) != null ? _a : "";
|
|
5574
|
+
case "image-data":
|
|
5575
|
+
return `[Image: ${contentPart.mediaType}]`;
|
|
5576
|
+
case "image-url":
|
|
5577
|
+
return `[Image URL: ${contentPart.url}]`;
|
|
5578
|
+
case "image-file-id": {
|
|
5579
|
+
const fileId = contentPart.fileId;
|
|
5580
|
+
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
5581
|
+
return `[Image ID: ${displayId}]`;
|
|
5582
|
+
}
|
|
5583
|
+
case "file-data": {
|
|
5584
|
+
const filePart = contentPart;
|
|
5585
|
+
if (filePart.filename) {
|
|
5586
|
+
return `[File: ${filePart.filename} (${filePart.mediaType})]`;
|
|
5587
|
+
}
|
|
5588
|
+
return `[File: ${filePart.mediaType}]`;
|
|
5589
|
+
}
|
|
5590
|
+
case "file-url":
|
|
5591
|
+
return `[File URL: ${contentPart.url}]`;
|
|
5592
|
+
case "file-id": {
|
|
5593
|
+
const fileId = contentPart.fileId;
|
|
5594
|
+
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
5595
|
+
return `[File ID: ${displayId}]`;
|
|
5596
|
+
}
|
|
5597
|
+
case "media":
|
|
5598
|
+
return `[Media: ${contentPart.mediaType}]`;
|
|
5599
|
+
case "custom":
|
|
5600
|
+
return "[Custom content]";
|
|
5601
|
+
default:
|
|
5602
|
+
return "[Unknown content]";
|
|
5603
|
+
}
|
|
3663
5604
|
}
|
|
3664
|
-
|
|
3665
|
-
// src/core/prompts/tool-response.ts
|
|
3666
|
-
function unwrapToolResult(result) {
|
|
5605
|
+
function unwrapToolResult(result, mediaStrategy) {
|
|
3667
5606
|
var _a, _b;
|
|
3668
5607
|
switch (result.type) {
|
|
3669
5608
|
case "text":
|
|
@@ -3679,43 +5618,11 @@ function unwrapToolResult(result) {
|
|
|
3679
5618
|
case "error-json":
|
|
3680
5619
|
return `[Error: ${JSON.stringify(result.value)}]`;
|
|
3681
5620
|
case "content": {
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
return (_a2 = contentPart.text) != null ? _a2 : "";
|
|
3688
|
-
case "image-data":
|
|
3689
|
-
return `[Image: ${contentPart.mediaType}]`;
|
|
3690
|
-
case "image-url":
|
|
3691
|
-
return `[Image URL: ${contentPart.url}]`;
|
|
3692
|
-
case "image-file-id": {
|
|
3693
|
-
const fileId = contentPart.fileId;
|
|
3694
|
-
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
3695
|
-
return `[Image ID: ${displayId}]`;
|
|
3696
|
-
}
|
|
3697
|
-
case "file-data": {
|
|
3698
|
-
const filePart = contentPart;
|
|
3699
|
-
if (filePart.filename) {
|
|
3700
|
-
return `[File: ${filePart.filename} (${filePart.mediaType})]`;
|
|
3701
|
-
}
|
|
3702
|
-
return `[File: ${filePart.mediaType}]`;
|
|
3703
|
-
}
|
|
3704
|
-
case "file-url":
|
|
3705
|
-
return `[File URL: ${contentPart.url}]`;
|
|
3706
|
-
case "file-id": {
|
|
3707
|
-
const fileId = contentPart.fileId;
|
|
3708
|
-
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
3709
|
-
return `[File ID: ${displayId}]`;
|
|
3710
|
-
}
|
|
3711
|
-
case "media":
|
|
3712
|
-
return `[Media: ${contentPart.mediaType}]`;
|
|
3713
|
-
case "custom":
|
|
3714
|
-
return "[Custom content]";
|
|
3715
|
-
default:
|
|
3716
|
-
return "[Unknown content]";
|
|
3717
|
-
}
|
|
3718
|
-
}).join("\n");
|
|
5621
|
+
const parts = result.value;
|
|
5622
|
+
if (shouldPassRawContent(parts, mediaStrategy)) {
|
|
5623
|
+
return parts;
|
|
5624
|
+
}
|
|
5625
|
+
return parts.map(formatContentPartPlaceholder).join("\n");
|
|
3719
5626
|
}
|
|
3720
5627
|
default: {
|
|
3721
5628
|
const _exhaustive = result;
|
|
@@ -3723,58 +5630,89 @@ function unwrapToolResult(result) {
|
|
|
3723
5630
|
}
|
|
3724
5631
|
}
|
|
3725
5632
|
}
|
|
3726
|
-
|
|
3727
|
-
|
|
5633
|
+
|
|
5634
|
+
// src/core/prompts/hermes-prompt.ts
|
|
5635
|
+
function formatToolResponseAsHermesWithOptions(toolResult, options) {
|
|
5636
|
+
const unwrappedResult = unwrapToolResult(
|
|
5637
|
+
toolResult.output,
|
|
5638
|
+
options == null ? void 0 : options.mediaStrategy
|
|
5639
|
+
);
|
|
3728
5640
|
return `<tool_response>${JSON.stringify({
|
|
3729
|
-
|
|
3730
|
-
|
|
5641
|
+
name: toolResult.toolName,
|
|
5642
|
+
content: unwrappedResult
|
|
3731
5643
|
})}</tool_response>`;
|
|
3732
5644
|
}
|
|
3733
|
-
function
|
|
3734
|
-
|
|
3735
|
-
const toolNameXml = `<tool_name>${toolResult.toolName}</tool_name>`;
|
|
3736
|
-
const resultLines = formatXmlNode("result", unwrappedResult, 1);
|
|
3737
|
-
return [
|
|
3738
|
-
"<tool_response>",
|
|
3739
|
-
` ${toolNameXml}`,
|
|
3740
|
-
...resultLines,
|
|
3741
|
-
"</tool_response>"
|
|
3742
|
-
].join("\n");
|
|
5645
|
+
function formatToolResponseAsHermes(toolResult) {
|
|
5646
|
+
return formatToolResponseAsHermesWithOptions(toolResult);
|
|
3743
5647
|
}
|
|
3744
|
-
function
|
|
3745
|
-
const
|
|
3746
|
-
if (
|
|
3747
|
-
return
|
|
5648
|
+
function jsonSchemaToPythonType(schema) {
|
|
5649
|
+
const type = schema.type;
|
|
5650
|
+
if (type === "string") {
|
|
5651
|
+
return "str";
|
|
3748
5652
|
}
|
|
3749
|
-
if (
|
|
3750
|
-
return
|
|
5653
|
+
if (type === "number") {
|
|
5654
|
+
return "float";
|
|
3751
5655
|
}
|
|
3752
|
-
if (
|
|
3753
|
-
|
|
3754
|
-
|
|
5656
|
+
if (type === "integer") {
|
|
5657
|
+
return "int";
|
|
5658
|
+
}
|
|
5659
|
+
if (type === "boolean") {
|
|
5660
|
+
return "bool";
|
|
5661
|
+
}
|
|
5662
|
+
if (type === "array") {
|
|
5663
|
+
const items = schema.items;
|
|
5664
|
+
if (items) {
|
|
5665
|
+
return `list[${jsonSchemaToPythonType(items)}]`;
|
|
3755
5666
|
}
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
5667
|
+
return "list[Any]";
|
|
5668
|
+
}
|
|
5669
|
+
if (type === "object") {
|
|
5670
|
+
const additionalProperties = schema.additionalProperties;
|
|
5671
|
+
if (additionalProperties) {
|
|
5672
|
+
return `dict[str, ${jsonSchemaToPythonType(additionalProperties)}]`;
|
|
3759
5673
|
}
|
|
3760
|
-
|
|
3761
|
-
return lines2;
|
|
5674
|
+
return "dict";
|
|
3762
5675
|
}
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
return [`${indent}<${tagName}></${tagName}>`];
|
|
5676
|
+
if (Array.isArray(type)) {
|
|
5677
|
+
return `Union[${type.map((t) => jsonSchemaToPythonType({ type: t })).join(",")}]`;
|
|
3766
5678
|
}
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
5679
|
+
return "Any";
|
|
5680
|
+
}
|
|
5681
|
+
function renderToolDefinition(tool) {
|
|
5682
|
+
var _a, _b;
|
|
5683
|
+
const schema = tool.inputSchema;
|
|
5684
|
+
const properties = schema.properties;
|
|
5685
|
+
const paramSignature = properties ? Object.entries(properties).map(([name, field]) => `${name}: ${jsonSchemaToPythonType(field)}`).join(", ") : "";
|
|
5686
|
+
const desc = (_a = tool.description) != null ? _a : "";
|
|
5687
|
+
let description = `${tool.name}(${paramSignature}) - ${desc}
|
|
5688
|
+
|
|
5689
|
+
`;
|
|
5690
|
+
if (properties && Object.keys(properties).length > 0) {
|
|
5691
|
+
description += " Args:\n";
|
|
5692
|
+
for (const [paramName, paramFields] of Object.entries(properties)) {
|
|
5693
|
+
const paramDesc = (_b = paramFields.description) != null ? _b : "";
|
|
5694
|
+
description += ` ${paramName}(${jsonSchemaToPythonType(paramFields)}): ${paramDesc.trim()}
|
|
5695
|
+
`;
|
|
5696
|
+
}
|
|
3770
5697
|
}
|
|
3771
|
-
|
|
3772
|
-
|
|
5698
|
+
const parametersJson = JSON.stringify(schema);
|
|
5699
|
+
const descJson = JSON.stringify(description);
|
|
5700
|
+
const nameJson = JSON.stringify(tool.name);
|
|
5701
|
+
return `{"type": "function", "function": {"name": ${nameJson}, "description": ${descJson}, "parameters": ${parametersJson}}}`;
|
|
5702
|
+
}
|
|
5703
|
+
function hermesSystemPromptTemplate(tools) {
|
|
5704
|
+
const toolsRendered = tools.map(renderToolDefinition).join("\n");
|
|
5705
|
+
return `You are a function calling AI model. You are provided with function signatures within <tools></tools> XML tags. You may call one or more functions to assist with the user query. Don't make assumptions about what values to plug into functions. Here are the available tools: <tools> ${toolsRendered} </tools>
|
|
5706
|
+
Use the following pydantic model json schema for each tool call you will make: {"properties": {"name": {"title": "Name", "type": "string"}, "arguments": {"title": "Arguments", "type": "object"}}, "required": ["name", "arguments"], "title": "FunctionCall", "type": "object"}
|
|
5707
|
+
For each function call return a json object with function name and arguments within <tool_call></tool_call> XML tags as follows:
|
|
5708
|
+
<tool_call>
|
|
5709
|
+
{"name": "<function-name>", "arguments": <args-dict>}
|
|
5710
|
+
</tool_call>`;
|
|
3773
5711
|
}
|
|
3774
5712
|
|
|
3775
|
-
// src/core/prompts/xml-
|
|
5713
|
+
// src/core/prompts/morph-xml-prompt.ts
|
|
3776
5714
|
import dedent from "dedent";
|
|
3777
|
-
function
|
|
5715
|
+
function morphXmlSystemPromptTemplate(tools) {
|
|
3778
5716
|
const toolsText = renderToolsForXmlPrompt(tools);
|
|
3779
5717
|
const header = dedent`
|
|
3780
5718
|
# Tools
|
|
@@ -3998,9 +5936,241 @@ function stripSchemaKeys(value) {
|
|
|
3998
5936
|
}
|
|
3999
5937
|
return value;
|
|
4000
5938
|
}
|
|
5939
|
+
function formatXmlNode(tagName, value, depth) {
|
|
5940
|
+
const indent = " ".repeat(depth);
|
|
5941
|
+
if (value === null || value === void 0) {
|
|
5942
|
+
return [`${indent}<${tagName}></${tagName}>`];
|
|
5943
|
+
}
|
|
5944
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
5945
|
+
return [`${indent}<${tagName}>${String(value)}</${tagName}>`];
|
|
5946
|
+
}
|
|
5947
|
+
if (Array.isArray(value)) {
|
|
5948
|
+
if (value.length === 0) {
|
|
5949
|
+
return [`${indent}<${tagName}></${tagName}>`];
|
|
5950
|
+
}
|
|
5951
|
+
const lines2 = [`${indent}<${tagName}>`];
|
|
5952
|
+
for (const item of value) {
|
|
5953
|
+
lines2.push(...formatXmlNode("item", item, depth + 1));
|
|
5954
|
+
}
|
|
5955
|
+
lines2.push(`${indent}</${tagName}>`);
|
|
5956
|
+
return lines2;
|
|
5957
|
+
}
|
|
5958
|
+
const entries = Object.entries(value);
|
|
5959
|
+
if (entries.length === 0) {
|
|
5960
|
+
return [`${indent}<${tagName}></${tagName}>`];
|
|
5961
|
+
}
|
|
5962
|
+
const lines = [`${indent}<${tagName}>`];
|
|
5963
|
+
for (const [key, entryValue] of entries) {
|
|
5964
|
+
lines.push(...formatXmlNode(key, entryValue, depth + 1));
|
|
5965
|
+
}
|
|
5966
|
+
lines.push(`${indent}</${tagName}>`);
|
|
5967
|
+
return lines;
|
|
5968
|
+
}
|
|
5969
|
+
function morphFormatToolResponseAsXmlWithOptions(toolResult, options) {
|
|
5970
|
+
const unwrappedResult = unwrapToolResult(
|
|
5971
|
+
toolResult.output,
|
|
5972
|
+
options == null ? void 0 : options.mediaStrategy
|
|
5973
|
+
);
|
|
5974
|
+
const toolNameXml = `<tool_name>${toolResult.toolName}</tool_name>`;
|
|
5975
|
+
const resultLines = formatXmlNode("result", unwrappedResult, 1);
|
|
5976
|
+
return [
|
|
5977
|
+
"<tool_response>",
|
|
5978
|
+
` ${toolNameXml}`,
|
|
5979
|
+
...resultLines,
|
|
5980
|
+
"</tool_response>"
|
|
5981
|
+
].join("\n");
|
|
5982
|
+
}
|
|
5983
|
+
function morphFormatToolResponseAsXml(toolResult) {
|
|
5984
|
+
return morphFormatToolResponseAsXmlWithOptions(toolResult);
|
|
5985
|
+
}
|
|
5986
|
+
|
|
5987
|
+
// src/core/prompts/shared/assistant-tool-calls-to-text.ts
|
|
5988
|
+
function assistantToolCallsToTextContent(options) {
|
|
5989
|
+
var _a, _b;
|
|
5990
|
+
const newContent = [];
|
|
5991
|
+
for (const item of options.content) {
|
|
5992
|
+
switch (item.type) {
|
|
5993
|
+
case "tool-call":
|
|
5994
|
+
newContent.push({
|
|
5995
|
+
type: "text",
|
|
5996
|
+
text: options.protocol.formatToolCall(item)
|
|
5997
|
+
});
|
|
5998
|
+
break;
|
|
5999
|
+
case "text":
|
|
6000
|
+
case "reasoning":
|
|
6001
|
+
newContent.push(item);
|
|
6002
|
+
break;
|
|
6003
|
+
default:
|
|
6004
|
+
(_b = (_a = options.conversionOptions) == null ? void 0 : _a.onError) == null ? void 0 : _b.call(
|
|
6005
|
+
_a,
|
|
6006
|
+
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
6007
|
+
{ content: item }
|
|
6008
|
+
);
|
|
6009
|
+
newContent.push({
|
|
6010
|
+
type: "text",
|
|
6011
|
+
text: JSON.stringify(item)
|
|
6012
|
+
});
|
|
6013
|
+
}
|
|
6014
|
+
}
|
|
6015
|
+
if (!newContent.every((entry) => entry.type === "text")) {
|
|
6016
|
+
return newContent;
|
|
6017
|
+
}
|
|
6018
|
+
return [
|
|
6019
|
+
{
|
|
6020
|
+
type: "text",
|
|
6021
|
+
text: newContent.map((entry) => entry.text).join("\n")
|
|
6022
|
+
}
|
|
6023
|
+
];
|
|
6024
|
+
}
|
|
6025
|
+
|
|
6026
|
+
// src/core/prompts/qwen3coder-prompt.ts
|
|
6027
|
+
var QWEN3CODER_TOOL_HEADER = "# Tools\n\nYou have access to the following functions:\n\n";
|
|
6028
|
+
var QWEN3CODER_TOOL_CALL_INSTRUCTIONS = "\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>";
|
|
6029
|
+
var XML_PROMPT_TAG_NAME_RE = /^[A-Za-z_][A-Za-z0-9_.-]*$/;
|
|
6030
|
+
function isMapping2(value) {
|
|
6031
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6032
|
+
}
|
|
6033
|
+
function isSequence(value) {
|
|
6034
|
+
return Array.isArray(value);
|
|
6035
|
+
}
|
|
6036
|
+
function toJinjaString(value) {
|
|
6037
|
+
if (value === void 0) {
|
|
6038
|
+
return "";
|
|
6039
|
+
}
|
|
6040
|
+
if (value === null) {
|
|
6041
|
+
return "None";
|
|
6042
|
+
}
|
|
6043
|
+
if (typeof value === "boolean") {
|
|
6044
|
+
return value ? "True" : "False";
|
|
6045
|
+
}
|
|
6046
|
+
return String(value);
|
|
6047
|
+
}
|
|
6048
|
+
function toJinjaTrimmedString(value) {
|
|
6049
|
+
return toJinjaString(value).trim();
|
|
6050
|
+
}
|
|
6051
|
+
function toEscapedXmlText(value) {
|
|
6052
|
+
return escapeXmlMinimalText(toJinjaString(value));
|
|
6053
|
+
}
|
|
6054
|
+
function toEscapedTrimmedXmlText(value) {
|
|
6055
|
+
return escapeXmlMinimalText(toJinjaTrimmedString(value));
|
|
6056
|
+
}
|
|
6057
|
+
function renderXmlPromptField(key, escapedValue) {
|
|
6058
|
+
if (XML_PROMPT_TAG_NAME_RE.test(key)) {
|
|
6059
|
+
return `
|
|
6060
|
+
<${key}>${escapedValue}</${key}>`;
|
|
6061
|
+
}
|
|
6062
|
+
return `
|
|
6063
|
+
<property name="${escapeXmlMinimalAttr(
|
|
6064
|
+
key,
|
|
6065
|
+
'"'
|
|
6066
|
+
)}">${escapedValue}</property>`;
|
|
6067
|
+
}
|
|
6068
|
+
function renderExtraKeys(jsonDict, handledKeys) {
|
|
6069
|
+
if (!isMapping2(jsonDict)) {
|
|
6070
|
+
return "";
|
|
6071
|
+
}
|
|
6072
|
+
const handled = new Set(handledKeys);
|
|
6073
|
+
let out = "";
|
|
6074
|
+
for (const [jsonKey, jsonValue] of Object.entries(jsonDict)) {
|
|
6075
|
+
if (handled.has(jsonKey)) {
|
|
6076
|
+
continue;
|
|
6077
|
+
}
|
|
6078
|
+
const renderedValue = isMapping2(jsonValue) || isSequence(jsonValue) ? JSON.stringify(jsonValue) : toJinjaString(jsonValue);
|
|
6079
|
+
out += renderXmlPromptField(jsonKey, escapeXmlMinimalText(renderedValue));
|
|
6080
|
+
}
|
|
6081
|
+
return out;
|
|
6082
|
+
}
|
|
6083
|
+
function normalizeInputSchema(inputSchema) {
|
|
6084
|
+
if (typeof inputSchema !== "string") {
|
|
6085
|
+
return inputSchema;
|
|
6086
|
+
}
|
|
6087
|
+
try {
|
|
6088
|
+
return JSON.parse(inputSchema);
|
|
6089
|
+
} catch (e) {
|
|
6090
|
+
return inputSchema;
|
|
6091
|
+
}
|
|
6092
|
+
}
|
|
6093
|
+
function normalizeTool(rawTool) {
|
|
6094
|
+
return {
|
|
6095
|
+
name: rawTool.name,
|
|
6096
|
+
description: rawTool.description,
|
|
6097
|
+
parameters: normalizeInputSchema(rawTool.inputSchema)
|
|
6098
|
+
};
|
|
6099
|
+
}
|
|
6100
|
+
function renderParameter(paramName, paramFieldsRaw) {
|
|
6101
|
+
const paramFields = isMapping2(paramFieldsRaw) ? paramFieldsRaw : void 0;
|
|
6102
|
+
let out = "\n<parameter>";
|
|
6103
|
+
out += `
|
|
6104
|
+
<name>${toEscapedXmlText(paramName)}</name>`;
|
|
6105
|
+
if ((paramFields == null ? void 0 : paramFields.type) !== void 0) {
|
|
6106
|
+
out += `
|
|
6107
|
+
<type>${toEscapedXmlText(paramFields.type)}</type>`;
|
|
6108
|
+
}
|
|
6109
|
+
if ((paramFields == null ? void 0 : paramFields.description) !== void 0) {
|
|
6110
|
+
out += `
|
|
6111
|
+
<description>${toEscapedTrimmedXmlText(paramFields.description)}</description>`;
|
|
6112
|
+
}
|
|
6113
|
+
out += renderExtraKeys(paramFieldsRaw, ["name", "type", "description"]);
|
|
6114
|
+
out += "\n</parameter>";
|
|
6115
|
+
return out;
|
|
6116
|
+
}
|
|
6117
|
+
function renderTool(tool) {
|
|
6118
|
+
let out = `
|
|
6119
|
+
<function>
|
|
6120
|
+
<name>${toEscapedXmlText(tool.name)}</name>`;
|
|
6121
|
+
if (tool.description !== void 0) {
|
|
6122
|
+
out += `
|
|
6123
|
+
<description>${toEscapedTrimmedXmlText(tool.description)}</description>`;
|
|
6124
|
+
}
|
|
6125
|
+
out += "\n<parameters>";
|
|
6126
|
+
const parameters = tool.parameters;
|
|
6127
|
+
if (isMapping2(parameters) && isMapping2(parameters.properties)) {
|
|
6128
|
+
for (const [paramName, paramFieldsRaw] of Object.entries(
|
|
6129
|
+
parameters.properties
|
|
6130
|
+
)) {
|
|
6131
|
+
out += renderParameter(paramName, paramFieldsRaw);
|
|
6132
|
+
}
|
|
6133
|
+
}
|
|
6134
|
+
out += renderExtraKeys(parameters, ["type", "properties"]);
|
|
6135
|
+
out += "\n</parameters>";
|
|
6136
|
+
out += renderExtraKeys(tool, ["type", "name", "description", "parameters"]);
|
|
6137
|
+
out += "\n</function>";
|
|
6138
|
+
return out;
|
|
6139
|
+
}
|
|
6140
|
+
function qwen3coderSystemPromptTemplate(tools) {
|
|
6141
|
+
if (!tools.length) {
|
|
6142
|
+
return "";
|
|
6143
|
+
}
|
|
6144
|
+
let out = `${QWEN3CODER_TOOL_HEADER}<tools>`;
|
|
6145
|
+
for (const tool of tools) {
|
|
6146
|
+
out += renderTool(normalizeTool(tool));
|
|
6147
|
+
}
|
|
6148
|
+
out += "\n</tools>";
|
|
6149
|
+
out += QWEN3CODER_TOOL_CALL_INSTRUCTIONS;
|
|
6150
|
+
return out;
|
|
6151
|
+
}
|
|
6152
|
+
function stringifyToolResponseContent(value) {
|
|
6153
|
+
if (typeof value === "string") {
|
|
6154
|
+
return value;
|
|
6155
|
+
}
|
|
6156
|
+
return JSON.stringify(value);
|
|
6157
|
+
}
|
|
6158
|
+
function formatToolResponseAsQwen3CoderXmlWithOptions(toolResult, options) {
|
|
6159
|
+
const unwrappedResult = unwrapToolResult(
|
|
6160
|
+
toolResult.output,
|
|
6161
|
+
options == null ? void 0 : options.mediaStrategy
|
|
6162
|
+
);
|
|
6163
|
+
const content = stringifyToolResponseContent(unwrappedResult);
|
|
6164
|
+
return `<tool_response>
|
|
6165
|
+
${content}
|
|
6166
|
+
</tool_response>`;
|
|
6167
|
+
}
|
|
6168
|
+
function formatToolResponseAsQwen3CoderXml(toolResult) {
|
|
6169
|
+
return formatToolResponseAsQwen3CoderXmlWithOptions(toolResult);
|
|
6170
|
+
}
|
|
4001
6171
|
|
|
4002
|
-
// src/core/prompts/yaml-
|
|
4003
|
-
function
|
|
6172
|
+
// src/core/prompts/yaml-xml-prompt.ts
|
|
6173
|
+
function yamlXmlSystemPromptTemplate(tools, includeMultilineExample = true) {
|
|
4004
6174
|
const toolsJson = JSON.stringify(tools);
|
|
4005
6175
|
const multilineExample = includeMultilineExample ? `
|
|
4006
6176
|
|
|
@@ -4039,6 +6209,9 @@ unit: celsius
|
|
|
4039
6209
|
- Do NOT ask clarifying questions. Use reasonable defaults for optional parameters.
|
|
4040
6210
|
- If a task requires multiple function calls, make ALL of them at once.`;
|
|
4041
6211
|
}
|
|
6212
|
+
function formatToolResponseAsYaml(toolResult) {
|
|
6213
|
+
return morphFormatToolResponseAsXml(toolResult);
|
|
6214
|
+
}
|
|
4042
6215
|
|
|
4043
6216
|
// src/stream-handler.ts
|
|
4044
6217
|
async function wrapStream({
|
|
@@ -4203,8 +6376,75 @@ function normalizeUsage(usage) {
|
|
|
4203
6376
|
return ZERO_USAGE;
|
|
4204
6377
|
}
|
|
4205
6378
|
|
|
6379
|
+
// src/core/prompts/shared/tool-role-to-user-message.ts
|
|
6380
|
+
function formatApprovalResponse(part) {
|
|
6381
|
+
const status = part.approved ? "Approved" : "Denied";
|
|
6382
|
+
const reason = part.reason ? `: ${part.reason}` : "";
|
|
6383
|
+
return `[Tool Approval ${status}${reason}]`;
|
|
6384
|
+
}
|
|
6385
|
+
function toTextPart(text) {
|
|
6386
|
+
return {
|
|
6387
|
+
type: "text",
|
|
6388
|
+
text
|
|
6389
|
+
};
|
|
6390
|
+
}
|
|
6391
|
+
function normalizeTemplateResult(result) {
|
|
6392
|
+
if (typeof result === "string") {
|
|
6393
|
+
return [toTextPart(result)];
|
|
6394
|
+
}
|
|
6395
|
+
return result;
|
|
6396
|
+
}
|
|
6397
|
+
function appendSection(target, section) {
|
|
6398
|
+
if (section.length === 0) {
|
|
6399
|
+
return;
|
|
6400
|
+
}
|
|
6401
|
+
if (target.length > 0) {
|
|
6402
|
+
target.push(toTextPart("\n"));
|
|
6403
|
+
}
|
|
6404
|
+
target.push(...section);
|
|
6405
|
+
}
|
|
6406
|
+
function mergeAdjacentTextParts(parts) {
|
|
6407
|
+
const merged = [];
|
|
6408
|
+
for (const part of parts) {
|
|
6409
|
+
const last = merged.at(-1);
|
|
6410
|
+
const canMergeTextParts = part.type === "text" && (last == null ? void 0 : last.type) === "text" && part.providerOptions === void 0 && last.providerOptions === void 0;
|
|
6411
|
+
if (canMergeTextParts) {
|
|
6412
|
+
last.text += part.text;
|
|
6413
|
+
continue;
|
|
6414
|
+
}
|
|
6415
|
+
merged.push(part);
|
|
6416
|
+
}
|
|
6417
|
+
return merged;
|
|
6418
|
+
}
|
|
6419
|
+
function toolRoleContentToUserTextMessage(options) {
|
|
6420
|
+
const toolResultParts = options.toolContent.filter(
|
|
6421
|
+
(part) => part.type === "tool-result"
|
|
6422
|
+
);
|
|
6423
|
+
const approvalResponseParts = options.toolContent.filter(
|
|
6424
|
+
(part) => part.type === "tool-approval-response"
|
|
6425
|
+
);
|
|
6426
|
+
const sections = [];
|
|
6427
|
+
for (const toolResult of toolResultParts) {
|
|
6428
|
+
const result = options.toolResponsePromptTemplate(toolResult);
|
|
6429
|
+
appendSection(sections, normalizeTemplateResult(result));
|
|
6430
|
+
}
|
|
6431
|
+
for (const approvalResponse of approvalResponseParts) {
|
|
6432
|
+
appendSection(sections, [
|
|
6433
|
+
toTextPart(formatApprovalResponse(approvalResponse))
|
|
6434
|
+
]);
|
|
6435
|
+
}
|
|
6436
|
+
const normalizedSections = sections.length > 0 ? sections : [toTextPart("")];
|
|
6437
|
+
return {
|
|
6438
|
+
role: "user",
|
|
6439
|
+
content: mergeAdjacentTextParts(normalizedSections)
|
|
6440
|
+
};
|
|
6441
|
+
}
|
|
6442
|
+
|
|
4206
6443
|
// src/transform-handler.ts
|
|
4207
6444
|
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
6445
|
+
if (systemPrompt.trim().length === 0) {
|
|
6446
|
+
return processedPrompt;
|
|
6447
|
+
}
|
|
4208
6448
|
const systemIndex = processedPrompt.findIndex((m) => m.role === "system");
|
|
4209
6449
|
if (systemIndex !== -1) {
|
|
4210
6450
|
const existing = processedPrompt[systemIndex].content;
|
|
@@ -4400,94 +6640,30 @@ function transformParams({
|
|
|
4400
6640
|
}
|
|
4401
6641
|
return baseReturnParams;
|
|
4402
6642
|
}
|
|
4403
|
-
function processAssistantContent(content, resolvedProtocol, providerOptions) {
|
|
4404
|
-
var _a;
|
|
4405
|
-
const newContent = [];
|
|
4406
|
-
for (const item of content) {
|
|
4407
|
-
switch (item.type) {
|
|
4408
|
-
case "tool-call":
|
|
4409
|
-
newContent.push({
|
|
4410
|
-
type: "text",
|
|
4411
|
-
text: resolvedProtocol.formatToolCall(item)
|
|
4412
|
-
});
|
|
4413
|
-
break;
|
|
4414
|
-
case "text":
|
|
4415
|
-
case "reasoning":
|
|
4416
|
-
newContent.push(item);
|
|
4417
|
-
break;
|
|
4418
|
-
default: {
|
|
4419
|
-
const options = extractOnErrorOption(providerOptions);
|
|
4420
|
-
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4421
|
-
options,
|
|
4422
|
-
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
4423
|
-
{ content: item }
|
|
4424
|
-
);
|
|
4425
|
-
newContent.push({
|
|
4426
|
-
type: "text",
|
|
4427
|
-
text: JSON.stringify(item)
|
|
4428
|
-
});
|
|
4429
|
-
}
|
|
4430
|
-
}
|
|
4431
|
-
}
|
|
4432
|
-
const onlyText = newContent.every((c) => c.type === "text");
|
|
4433
|
-
return onlyText ? [
|
|
4434
|
-
{
|
|
4435
|
-
type: "text",
|
|
4436
|
-
text: newContent.map((c) => c.text).join("\n")
|
|
4437
|
-
}
|
|
4438
|
-
] : newContent;
|
|
4439
|
-
}
|
|
4440
|
-
function formatApprovalResponse(part) {
|
|
4441
|
-
const status = part.approved ? "Approved" : "Denied";
|
|
4442
|
-
const reason = part.reason ? `: ${part.reason}` : "";
|
|
4443
|
-
return `[Tool Approval ${status}${reason}]`;
|
|
4444
|
-
}
|
|
4445
|
-
function processToolMessage(toolResults, approvalResponses, toolResponsePromptTemplate) {
|
|
4446
|
-
const resultTexts = toolResults.map((toolResult) => {
|
|
4447
|
-
return toolResponsePromptTemplate(toolResult);
|
|
4448
|
-
});
|
|
4449
|
-
const approvalTexts = approvalResponses.map(formatApprovalResponse);
|
|
4450
|
-
const allTexts = [...resultTexts, ...approvalTexts];
|
|
4451
|
-
return {
|
|
4452
|
-
role: "user",
|
|
4453
|
-
content: [
|
|
4454
|
-
{
|
|
4455
|
-
type: "text",
|
|
4456
|
-
text: allTexts.join("\n")
|
|
4457
|
-
}
|
|
4458
|
-
]
|
|
4459
|
-
};
|
|
4460
|
-
}
|
|
4461
6643
|
function processMessage(message, resolvedProtocol, providerOptions, toolResponsePromptTemplate) {
|
|
4462
6644
|
if (message.role === "assistant") {
|
|
4463
|
-
const condensedContent =
|
|
4464
|
-
message.content,
|
|
4465
|
-
resolvedProtocol,
|
|
4466
|
-
|
|
4467
|
-
|
|
6645
|
+
const condensedContent = assistantToolCallsToTextContent({
|
|
6646
|
+
content: message.content,
|
|
6647
|
+
protocol: resolvedProtocol,
|
|
6648
|
+
conversionOptions: {
|
|
6649
|
+
onError: providerOptions == null ? void 0 : providerOptions.onError
|
|
6650
|
+
}
|
|
6651
|
+
});
|
|
4468
6652
|
return {
|
|
4469
6653
|
role: "assistant",
|
|
4470
6654
|
content: condensedContent
|
|
4471
6655
|
};
|
|
4472
6656
|
}
|
|
4473
6657
|
if (message.role === "tool") {
|
|
4474
|
-
const toolContent = message.content;
|
|
4475
|
-
const toolResultParts = toolContent.filter(
|
|
4476
|
-
(part) => part.type === "tool-result"
|
|
4477
|
-
);
|
|
4478
|
-
const approvalResponseParts = toolContent.filter(
|
|
4479
|
-
(part) => part.type === "tool-approval-response"
|
|
4480
|
-
);
|
|
4481
6658
|
if (!toolResponsePromptTemplate) {
|
|
4482
6659
|
throw new Error(
|
|
4483
6660
|
'toolResponsePromptTemplate is required when processing messages with role "tool". This parameter is optional for other roles but is required here so tool-result content can be converted into a prompt. Ensure your middleware or transform configuration passes a toolResponsePromptTemplate when tool message processing is enabled.'
|
|
4484
6661
|
);
|
|
4485
6662
|
}
|
|
4486
|
-
return
|
|
4487
|
-
|
|
4488
|
-
approvalResponseParts,
|
|
6663
|
+
return toolRoleContentToUserTextMessage({
|
|
6664
|
+
toolContent: message.content,
|
|
4489
6665
|
toolResponsePromptTemplate
|
|
4490
|
-
);
|
|
6666
|
+
});
|
|
4491
6667
|
}
|
|
4492
6668
|
return message;
|
|
4493
6669
|
}
|
|
@@ -4538,6 +6714,9 @@ function mergeConsecutiveUserMessages(processedPrompt) {
|
|
|
4538
6714
|
const current = processedPrompt[i];
|
|
4539
6715
|
const prev = processedPrompt[i - 1];
|
|
4540
6716
|
if (current.role === "user" && prev.role === "user") {
|
|
6717
|
+
if (!(isAllTextContent(prev.content) && isAllTextContent(current.content))) {
|
|
6718
|
+
continue;
|
|
6719
|
+
}
|
|
4541
6720
|
const prevContent = prev.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
4542
6721
|
const currentContent = current.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
4543
6722
|
processedPrompt[i - 1] = {
|
|
@@ -4597,19 +6776,24 @@ function createToolMiddleware({
|
|
|
4597
6776
|
|
|
4598
6777
|
// src/preconfigured-middleware.ts
|
|
4599
6778
|
var hermesToolMiddleware = createToolMiddleware({
|
|
4600
|
-
protocol:
|
|
6779
|
+
protocol: hermesProtocol(),
|
|
4601
6780
|
toolSystemPromptTemplate: hermesSystemPromptTemplate,
|
|
4602
|
-
toolResponsePromptTemplate:
|
|
6781
|
+
toolResponsePromptTemplate: formatToolResponseAsHermes
|
|
6782
|
+
});
|
|
6783
|
+
var qwen3CoderToolMiddleware = createToolMiddleware({
|
|
6784
|
+
protocol: qwen3CoderProtocol,
|
|
6785
|
+
toolSystemPromptTemplate: qwen3coderSystemPromptTemplate,
|
|
6786
|
+
toolResponsePromptTemplate: formatToolResponseAsQwen3CoderXml
|
|
4603
6787
|
});
|
|
4604
|
-
var
|
|
4605
|
-
protocol:
|
|
4606
|
-
toolSystemPromptTemplate:
|
|
4607
|
-
toolResponsePromptTemplate:
|
|
6788
|
+
var morphXmlToolMiddleware = createToolMiddleware({
|
|
6789
|
+
protocol: morphXmlProtocol({}),
|
|
6790
|
+
toolSystemPromptTemplate: morphXmlSystemPromptTemplate,
|
|
6791
|
+
toolResponsePromptTemplate: morphFormatToolResponseAsXml
|
|
4608
6792
|
});
|
|
4609
|
-
var
|
|
4610
|
-
protocol:
|
|
4611
|
-
toolSystemPromptTemplate:
|
|
4612
|
-
toolResponsePromptTemplate:
|
|
6793
|
+
var yamlXmlToolMiddleware = createToolMiddleware({
|
|
6794
|
+
protocol: yamlXmlProtocol({}),
|
|
6795
|
+
toolSystemPromptTemplate: yamlXmlSystemPromptTemplate,
|
|
6796
|
+
toolResponsePromptTemplate: formatToolResponseAsYaml
|
|
4613
6797
|
});
|
|
4614
6798
|
|
|
4615
6799
|
export {
|
|
@@ -4619,11 +6803,14 @@ export {
|
|
|
4619
6803
|
logParsedChunk,
|
|
4620
6804
|
logParsedSummary,
|
|
4621
6805
|
getPotentialStartIndex,
|
|
4622
|
-
|
|
6806
|
+
hermesProtocol,
|
|
6807
|
+
morphXmlProtocol,
|
|
4623
6808
|
isProtocolFactory,
|
|
4624
6809
|
isTCMProtocolFactory,
|
|
4625
|
-
|
|
4626
|
-
|
|
6810
|
+
qwen3CoderProtocol,
|
|
6811
|
+
uiTarsXmlProtocol,
|
|
6812
|
+
Qwen3CoderToolParser,
|
|
6813
|
+
yamlXmlProtocol,
|
|
4627
6814
|
createDynamicIfThenElseSchema,
|
|
4628
6815
|
extractOnErrorOption,
|
|
4629
6816
|
originalToolsSchema,
|
|
@@ -4634,12 +6821,14 @@ export {
|
|
|
4634
6821
|
isToolResultPart,
|
|
4635
6822
|
hasInputProperty,
|
|
4636
6823
|
wrapGenerate,
|
|
6824
|
+
morphFormatToolResponseAsXml,
|
|
4637
6825
|
wrapStream,
|
|
4638
6826
|
toolChoiceStream,
|
|
4639
6827
|
transformParams,
|
|
4640
6828
|
createToolMiddleware,
|
|
4641
6829
|
hermesToolMiddleware,
|
|
4642
|
-
|
|
4643
|
-
|
|
6830
|
+
qwen3CoderToolMiddleware,
|
|
6831
|
+
morphXmlToolMiddleware,
|
|
6832
|
+
yamlXmlToolMiddleware
|
|
4644
6833
|
};
|
|
4645
|
-
//# sourceMappingURL=chunk-
|
|
6834
|
+
//# sourceMappingURL=chunk-O6NWVXQD.js.map
|