@ai-sdk-tool/parser 4.0.0 → 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-2KK5BDZF.js → chunk-GMTE7BY5.js} +23 -6
- package/dist/chunk-GMTE7BY5.js.map +1 -0
- package/dist/{chunk-CXWS24JX.js → chunk-MHZC45AC.js} +5 -2
- package/dist/{chunk-CXWS24JX.js.map → chunk-MHZC45AC.js.map} +1 -1
- package/dist/{chunk-ERJKQKCR.js → chunk-O6NWVXQD.js} +2578 -379
- 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 +7873 -5545
- 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 +2600 -384
- 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 +22 -5
- 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 +22 -5
- package/dist/schema-coerce.cjs.map +1 -1
- package/dist/schema-coerce.js +1 -1
- package/package.json +6 -6
- package/dist/chunk-2KK5BDZF.js.map +0 -1
- package/dist/chunk-ERJKQKCR.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/;
|
|
@@ -176,9 +179,19 @@ function getPotentialStartIndex(text, searchedText) {
|
|
|
176
179
|
if (directIndex !== -1) {
|
|
177
180
|
return directIndex;
|
|
178
181
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
+
const textLength = text.length;
|
|
183
|
+
const searchedTextLength = searchedText.length;
|
|
184
|
+
const startAt = Math.max(0, textLength - searchedTextLength + 1);
|
|
185
|
+
for (let i = startAt; i < textLength; i++) {
|
|
186
|
+
let match = true;
|
|
187
|
+
const currentSuffixLength = textLength - i;
|
|
188
|
+
for (let j = 0; j < currentSuffixLength; j++) {
|
|
189
|
+
if (text[i + j] !== searchedText[j]) {
|
|
190
|
+
match = false;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (match) {
|
|
182
195
|
return i;
|
|
183
196
|
}
|
|
184
197
|
}
|
|
@@ -247,7 +260,7 @@ function createFlushTextHandler(getCurrentTextId, setCurrentTextId, getHasEmitte
|
|
|
247
260
|
};
|
|
248
261
|
}
|
|
249
262
|
|
|
250
|
-
// src/core/protocols/
|
|
263
|
+
// src/core/protocols/hermes-protocol.ts
|
|
251
264
|
function shouldEmitRawToolCallTextOnError(options) {
|
|
252
265
|
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
253
266
|
}
|
|
@@ -790,7 +803,7 @@ function handlePartialTag(state, controller, toolCallStart, toolCallEnd) {
|
|
|
790
803
|
state.buffer = "";
|
|
791
804
|
}
|
|
792
805
|
}
|
|
793
|
-
var
|
|
806
|
+
var hermesProtocol = ({
|
|
794
807
|
toolCallStart = "<tool_call>",
|
|
795
808
|
toolCallEnd = "</tool_call>"
|
|
796
809
|
} = {}) => ({
|
|
@@ -892,14 +905,6 @@ var jsonProtocol = ({
|
|
|
892
905
|
}
|
|
893
906
|
});
|
|
894
907
|
|
|
895
|
-
// src/core/protocols/protocol-interface.ts
|
|
896
|
-
function isProtocolFactory(protocol) {
|
|
897
|
-
return typeof protocol === "function";
|
|
898
|
-
}
|
|
899
|
-
function isTCMProtocolFactory(protocol) {
|
|
900
|
-
return typeof protocol === "function";
|
|
901
|
-
}
|
|
902
|
-
|
|
903
908
|
// src/core/utils/regex-constants.ts
|
|
904
909
|
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
905
910
|
var WHITESPACE_REGEX = /\s/;
|
|
@@ -1002,7 +1007,7 @@ ${body}
|
|
|
1002
1007
|
</${rootTag}>`;
|
|
1003
1008
|
}
|
|
1004
1009
|
|
|
1005
|
-
// src/core/protocols/xml-protocol.ts
|
|
1010
|
+
// src/core/protocols/morph-xml-protocol.ts
|
|
1006
1011
|
function getToolSchema(tools, toolName) {
|
|
1007
1012
|
var _a;
|
|
1008
1013
|
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
@@ -1978,7 +1983,7 @@ function findToolCallsWithFallbacks(text, toolNames) {
|
|
|
1978
1983
|
}
|
|
1979
1984
|
return { parseText, toolCalls };
|
|
1980
1985
|
}
|
|
1981
|
-
var
|
|
1986
|
+
var morphXmlProtocol = (protocolOptions) => {
|
|
1982
1987
|
var _a;
|
|
1983
1988
|
const parseOptions = {
|
|
1984
1989
|
repair: true,
|
|
@@ -2241,196 +2246,2066 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
2241
2246
|
};
|
|
2242
2247
|
};
|
|
2243
2248
|
|
|
2244
|
-
// src/core/protocols/
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
2249
|
+
// src/core/protocols/protocol-interface.ts
|
|
2250
|
+
function isProtocolFactory(protocol) {
|
|
2251
|
+
return typeof protocol === "function";
|
|
2248
2252
|
}
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
let pattern = selfClosingTagCache2.get(toolName);
|
|
2252
|
-
if (!pattern) {
|
|
2253
|
-
pattern = new RegExp(`<\\s*${escapeRegExp(toolName)}\\s*/>`, "g");
|
|
2254
|
-
selfClosingTagCache2.set(toolName, pattern);
|
|
2255
|
-
}
|
|
2256
|
-
return pattern;
|
|
2253
|
+
function isTCMProtocolFactory(protocol) {
|
|
2254
|
+
return typeof protocol === "function";
|
|
2257
2255
|
}
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
var
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
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;
|
|
2268
2271
|
}
|
|
2269
|
-
const
|
|
2270
|
-
const
|
|
2271
|
-
|
|
2272
|
-
|
|
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;
|
|
2273
2280
|
}
|
|
2274
|
-
|
|
2275
|
-
...
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
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;
|
|
2282
2325
|
}
|
|
2283
|
-
return
|
|
2326
|
+
return i;
|
|
2284
2327
|
}
|
|
2285
|
-
function
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
const
|
|
2289
|
-
const
|
|
2290
|
-
|
|
2291
|
-
|
|
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;
|
|
2292
2336
|
}
|
|
2293
|
-
|
|
2294
|
-
|
|
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;
|
|
2295
2346
|
}
|
|
2296
|
-
|
|
2297
|
-
} catch (error) {
|
|
2298
|
-
return {
|
|
2299
|
-
value: null,
|
|
2300
|
-
errors: [
|
|
2301
|
-
error instanceof Error ? error.message : "Unknown YAML parsing error"
|
|
2302
|
-
]
|
|
2303
|
-
};
|
|
2347
|
+
out = next;
|
|
2304
2348
|
}
|
|
2305
2349
|
}
|
|
2306
|
-
function
|
|
2350
|
+
function isTagBoundaryChar(ch) {
|
|
2351
|
+
return ch === "" || isAsciiWhitespace(ch) || ch === ">" || ch === "/";
|
|
2352
|
+
}
|
|
2353
|
+
function findTagEndIndex(text, startIndex) {
|
|
2307
2354
|
var _a;
|
|
2308
|
-
|
|
2309
|
-
let
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
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;
|
|
2320
2370
|
}
|
|
2321
|
-
index -= 1;
|
|
2322
2371
|
}
|
|
2323
2372
|
return null;
|
|
2324
2373
|
}
|
|
2325
|
-
function
|
|
2326
|
-
|
|
2327
|
-
|
|
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)) {
|
|
2328
2379
|
return null;
|
|
2329
2380
|
}
|
|
2330
|
-
|
|
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;
|
|
2331
2406
|
}
|
|
2332
|
-
function
|
|
2333
|
-
const
|
|
2334
|
-
if (
|
|
2335
|
-
return
|
|
2407
|
+
function parseQwen3CoderToolParserParamName(openTag, tagNameLower) {
|
|
2408
|
+
const shorthand = parseShorthandValue(openTag, tagNameLower);
|
|
2409
|
+
if (shorthand != null) {
|
|
2410
|
+
return unescapeXml(shorthand);
|
|
2336
2411
|
}
|
|
2337
|
-
return
|
|
2412
|
+
return getAttributeValue(openTag, "name");
|
|
2338
2413
|
}
|
|
2339
|
-
function
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
return false;
|
|
2414
|
+
function getCdataSectionNextIndex(textLower, startIndex) {
|
|
2415
|
+
if (!textLower.startsWith("<![cdata[", startIndex)) {
|
|
2416
|
+
return startIndex;
|
|
2343
2417
|
}
|
|
2344
|
-
|
|
2418
|
+
const cdataEnd = textLower.indexOf("]]>", startIndex + "<![cdata[".length);
|
|
2419
|
+
if (cdataEnd === -1) {
|
|
2420
|
+
return null;
|
|
2421
|
+
}
|
|
2422
|
+
return cdataEnd + 3;
|
|
2345
2423
|
}
|
|
2346
|
-
function
|
|
2424
|
+
function parseMatchingTagHeader(textLower, lt, tagNameLower) {
|
|
2347
2425
|
var _a;
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2426
|
+
let i = skipAsciiWhitespace(textLower, lt + 1);
|
|
2427
|
+
const isClosing = textLower[i] === "/";
|
|
2428
|
+
if (isClosing) {
|
|
2429
|
+
i += 1;
|
|
2430
|
+
i = skipAsciiWhitespace(textLower, i);
|
|
2351
2431
|
}
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
return false;
|
|
2432
|
+
if (!textLower.startsWith(tagNameLower, i)) {
|
|
2433
|
+
return null;
|
|
2355
2434
|
}
|
|
2356
|
-
|
|
2357
|
-
|
|
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;
|
|
2358
2440
|
}
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
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;
|
|
2366
2460
|
continue;
|
|
2367
2461
|
}
|
|
2368
|
-
const
|
|
2369
|
-
if (
|
|
2370
|
-
|
|
2462
|
+
const header = parseMatchingTagHeader(textLower, lt, tagNameLower);
|
|
2463
|
+
if (!header) {
|
|
2464
|
+
index = lt + 1;
|
|
2371
2465
|
continue;
|
|
2372
2466
|
}
|
|
2373
|
-
|
|
2374
|
-
|
|
2467
|
+
const gt = textLower.indexOf(">", header.afterName);
|
|
2468
|
+
if (gt === -1) {
|
|
2469
|
+
return null;
|
|
2375
2470
|
}
|
|
2376
|
-
if (
|
|
2377
|
-
|
|
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;
|
|
2378
2478
|
}
|
|
2379
|
-
|
|
2479
|
+
const isSelfClosing = isSelfClosingXmlTag(textLower, lt, gt);
|
|
2480
|
+
if (!isSelfClosing) {
|
|
2481
|
+
depth += 1;
|
|
2482
|
+
}
|
|
2483
|
+
index = gt + 1;
|
|
2380
2484
|
}
|
|
2381
|
-
return false;
|
|
2382
2485
|
}
|
|
2383
|
-
function
|
|
2486
|
+
function findClosingTagStartWithBoundary(lowerText, valueStart, tagNameLower, allowEndOfStringBoundary) {
|
|
2384
2487
|
var _a;
|
|
2385
|
-
|
|
2386
|
-
|
|
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;
|
|
2387
2504
|
}
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
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) {
|
|
2392
2511
|
return null;
|
|
2393
2512
|
}
|
|
2394
|
-
|
|
2395
|
-
|
|
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) {
|
|
2396
2543
|
return null;
|
|
2397
2544
|
}
|
|
2398
|
-
|
|
2399
|
-
|
|
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" };
|
|
2400
2552
|
}
|
|
2401
|
-
if (
|
|
2553
|
+
if (lowerText[i] === "/") {
|
|
2402
2554
|
return null;
|
|
2403
2555
|
}
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
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;
|
|
2409
2563
|
}
|
|
2410
|
-
const
|
|
2411
|
-
if (!
|
|
2412
|
-
return
|
|
2564
|
+
const tagNameLower = lowerText.slice(nameStart, i);
|
|
2565
|
+
if (!QWEN3CODER_TOOL_PARSER_PARAM_TAG_NAMES.has(tagNameLower)) {
|
|
2566
|
+
return null;
|
|
2413
2567
|
}
|
|
2414
|
-
return
|
|
2415
|
-
}
|
|
2416
|
-
function hasUnstableProgressTail(normalized) {
|
|
2417
|
-
return hasIncompleteMappingTail(normalized) || hasIncompleteSequenceTail(normalized) || hasSplitNestedKeyTail(normalized) || hasUnterminatedPlainScalarTail(normalized);
|
|
2568
|
+
return { kind: "match", tagNameLower };
|
|
2418
2569
|
}
|
|
2419
|
-
function
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
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
|
+
};
|
|
2423
2586
|
}
|
|
2424
|
-
|
|
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
|
+
};
|
|
2425
2595
|
}
|
|
2426
|
-
|
|
2427
|
-
|
|
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;
|
|
2428
2613
|
}
|
|
2429
|
-
if (
|
|
2430
|
-
return
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2614
|
+
if (tagNameParse.kind === "partial") {
|
|
2615
|
+
return { kind: "partial", start: startIndex, openEnd: null };
|
|
2616
|
+
}
|
|
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)
|
|
2434
4309
|
])
|
|
2435
4310
|
);
|
|
2436
4311
|
}
|
|
@@ -2442,7 +4317,7 @@ function stabilizeParsedValueForStreamProgress(value, source) {
|
|
|
2442
4317
|
}
|
|
2443
4318
|
return trimTrailingNewlineInUnknown(value);
|
|
2444
4319
|
}
|
|
2445
|
-
function
|
|
4320
|
+
function findClosingTagEnd2(text, contentStart, toolName) {
|
|
2446
4321
|
let pos = contentStart;
|
|
2447
4322
|
let depth = 1;
|
|
2448
4323
|
while (pos < text.length) {
|
|
@@ -2513,9 +4388,9 @@ function findEarliestTagPosition(openIdx, selfIdx) {
|
|
|
2513
4388
|
function collectToolCallsForName(text, toolName) {
|
|
2514
4389
|
const toolCalls = [];
|
|
2515
4390
|
let searchIndex = 0;
|
|
4391
|
+
const startTag = `<${toolName}>`;
|
|
2516
4392
|
const selfTagRegex = getSelfClosingTagPattern2(toolName);
|
|
2517
4393
|
while (searchIndex < text.length) {
|
|
2518
|
-
const startTag = `<${toolName}>`;
|
|
2519
4394
|
const openIdx = text.indexOf(startTag, searchIndex);
|
|
2520
4395
|
selfTagRegex.lastIndex = searchIndex;
|
|
2521
4396
|
const selfMatch = selfTagRegex.exec(text);
|
|
@@ -2540,7 +4415,7 @@ function collectToolCallsForName(text, toolName) {
|
|
|
2540
4415
|
continue;
|
|
2541
4416
|
}
|
|
2542
4417
|
const contentStart = tagStart + startTag.length;
|
|
2543
|
-
const fullTagEnd =
|
|
4418
|
+
const fullTagEnd = findClosingTagEnd2(text, contentStart, toolName);
|
|
2544
4419
|
if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
|
|
2545
4420
|
const endTag = `</${toolName}>`;
|
|
2546
4421
|
const endTagStart = fullTagEnd - endTag.length;
|
|
@@ -2690,7 +4565,7 @@ function stripTrailingPartialCloseTag(content, toolName) {
|
|
|
2690
4565
|
)}${preservedLeadingWhitespace}`;
|
|
2691
4566
|
return contentWithoutPartial.trimEnd();
|
|
2692
4567
|
}
|
|
2693
|
-
var
|
|
4568
|
+
var yamlXmlProtocol = (_protocolOptions) => {
|
|
2694
4569
|
return {
|
|
2695
4570
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
2696
4571
|
return toolSystemPromptTemplate(tools || []);
|
|
@@ -2814,7 +4689,7 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2814
4689
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse streaming YAML tool call", {
|
|
2815
4690
|
toolCall: original
|
|
2816
4691
|
});
|
|
2817
|
-
if (
|
|
4692
|
+
if (shouldEmitRawToolCallTextOnError4(options)) {
|
|
2818
4693
|
flushText(controller, original);
|
|
2819
4694
|
}
|
|
2820
4695
|
}
|
|
@@ -2859,7 +4734,7 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2859
4734
|
"Could not complete streaming YAML tool call at finish.",
|
|
2860
4735
|
{ toolCall: unfinishedContent }
|
|
2861
4736
|
);
|
|
2862
|
-
if (
|
|
4737
|
+
if (shouldEmitRawToolCallTextOnError4(options)) {
|
|
2863
4738
|
flushText(controller, unfinishedContent);
|
|
2864
4739
|
}
|
|
2865
4740
|
}
|
|
@@ -3400,36 +5275,6 @@ function recoverToolCallFromJsonCandidates(text, tools) {
|
|
|
3400
5275
|
return null;
|
|
3401
5276
|
}
|
|
3402
5277
|
|
|
3403
|
-
// src/core/utils/tool-call-coercion.ts
|
|
3404
|
-
function coerceToolCallInput(toolName, input, tools) {
|
|
3405
|
-
var _a;
|
|
3406
|
-
let args = {};
|
|
3407
|
-
if (typeof input === "string") {
|
|
3408
|
-
try {
|
|
3409
|
-
args = JSON.parse(input);
|
|
3410
|
-
} catch (e) {
|
|
3411
|
-
return;
|
|
3412
|
-
}
|
|
3413
|
-
} else if (input && typeof input === "object") {
|
|
3414
|
-
args = input;
|
|
3415
|
-
} else {
|
|
3416
|
-
return;
|
|
3417
|
-
}
|
|
3418
|
-
const schema = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
3419
|
-
const coerced = coerceBySchema(args, schema);
|
|
3420
|
-
return JSON.stringify(coerced != null ? coerced : {});
|
|
3421
|
-
}
|
|
3422
|
-
function coerceToolCallPart(part, tools) {
|
|
3423
|
-
const coercedInput = coerceToolCallInput(part.toolName, part.input, tools);
|
|
3424
|
-
if (coercedInput === void 0) {
|
|
3425
|
-
return part;
|
|
3426
|
-
}
|
|
3427
|
-
return {
|
|
3428
|
-
...part,
|
|
3429
|
-
input: coercedInput
|
|
3430
|
-
};
|
|
3431
|
-
}
|
|
3432
|
-
|
|
3433
5278
|
// src/core/utils/tool-choice.ts
|
|
3434
5279
|
function ensureNonEmptyToolName(name) {
|
|
3435
5280
|
if (typeof name !== "string") {
|
|
@@ -3637,23 +5482,127 @@ async function wrapGenerate({
|
|
|
3637
5482
|
};
|
|
3638
5483
|
}
|
|
3639
5484
|
|
|
3640
|
-
// src/core/prompts/
|
|
3641
|
-
function
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
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
|
+
}
|
|
3653
5604
|
}
|
|
3654
|
-
|
|
3655
|
-
// src/core/prompts/tool-response.ts
|
|
3656
|
-
function unwrapToolResult(result) {
|
|
5605
|
+
function unwrapToolResult(result, mediaStrategy) {
|
|
3657
5606
|
var _a, _b;
|
|
3658
5607
|
switch (result.type) {
|
|
3659
5608
|
case "text":
|
|
@@ -3669,43 +5618,11 @@ function unwrapToolResult(result) {
|
|
|
3669
5618
|
case "error-json":
|
|
3670
5619
|
return `[Error: ${JSON.stringify(result.value)}]`;
|
|
3671
5620
|
case "content": {
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
return (_a2 = contentPart.text) != null ? _a2 : "";
|
|
3678
|
-
case "image-data":
|
|
3679
|
-
return `[Image: ${contentPart.mediaType}]`;
|
|
3680
|
-
case "image-url":
|
|
3681
|
-
return `[Image URL: ${contentPart.url}]`;
|
|
3682
|
-
case "image-file-id": {
|
|
3683
|
-
const fileId = contentPart.fileId;
|
|
3684
|
-
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
3685
|
-
return `[Image ID: ${displayId}]`;
|
|
3686
|
-
}
|
|
3687
|
-
case "file-data": {
|
|
3688
|
-
const filePart = contentPart;
|
|
3689
|
-
if (filePart.filename) {
|
|
3690
|
-
return `[File: ${filePart.filename} (${filePart.mediaType})]`;
|
|
3691
|
-
}
|
|
3692
|
-
return `[File: ${filePart.mediaType}]`;
|
|
3693
|
-
}
|
|
3694
|
-
case "file-url":
|
|
3695
|
-
return `[File URL: ${contentPart.url}]`;
|
|
3696
|
-
case "file-id": {
|
|
3697
|
-
const fileId = contentPart.fileId;
|
|
3698
|
-
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
3699
|
-
return `[File ID: ${displayId}]`;
|
|
3700
|
-
}
|
|
3701
|
-
case "media":
|
|
3702
|
-
return `[Media: ${contentPart.mediaType}]`;
|
|
3703
|
-
case "custom":
|
|
3704
|
-
return "[Custom content]";
|
|
3705
|
-
default:
|
|
3706
|
-
return "[Unknown content]";
|
|
3707
|
-
}
|
|
3708
|
-
}).join("\n");
|
|
5621
|
+
const parts = result.value;
|
|
5622
|
+
if (shouldPassRawContent(parts, mediaStrategy)) {
|
|
5623
|
+
return parts;
|
|
5624
|
+
}
|
|
5625
|
+
return parts.map(formatContentPartPlaceholder).join("\n");
|
|
3709
5626
|
}
|
|
3710
5627
|
default: {
|
|
3711
5628
|
const _exhaustive = result;
|
|
@@ -3713,58 +5630,89 @@ function unwrapToolResult(result) {
|
|
|
3713
5630
|
}
|
|
3714
5631
|
}
|
|
3715
5632
|
}
|
|
3716
|
-
|
|
3717
|
-
|
|
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
|
+
);
|
|
3718
5640
|
return `<tool_response>${JSON.stringify({
|
|
3719
|
-
|
|
3720
|
-
|
|
5641
|
+
name: toolResult.toolName,
|
|
5642
|
+
content: unwrappedResult
|
|
3721
5643
|
})}</tool_response>`;
|
|
3722
5644
|
}
|
|
3723
|
-
function
|
|
3724
|
-
|
|
3725
|
-
const toolNameXml = `<tool_name>${toolResult.toolName}</tool_name>`;
|
|
3726
|
-
const resultLines = formatXmlNode("result", unwrappedResult, 1);
|
|
3727
|
-
return [
|
|
3728
|
-
"<tool_response>",
|
|
3729
|
-
` ${toolNameXml}`,
|
|
3730
|
-
...resultLines,
|
|
3731
|
-
"</tool_response>"
|
|
3732
|
-
].join("\n");
|
|
5645
|
+
function formatToolResponseAsHermes(toolResult) {
|
|
5646
|
+
return formatToolResponseAsHermesWithOptions(toolResult);
|
|
3733
5647
|
}
|
|
3734
|
-
function
|
|
3735
|
-
const
|
|
3736
|
-
if (
|
|
3737
|
-
return
|
|
5648
|
+
function jsonSchemaToPythonType(schema) {
|
|
5649
|
+
const type = schema.type;
|
|
5650
|
+
if (type === "string") {
|
|
5651
|
+
return "str";
|
|
3738
5652
|
}
|
|
3739
|
-
if (
|
|
3740
|
-
return
|
|
5653
|
+
if (type === "number") {
|
|
5654
|
+
return "float";
|
|
3741
5655
|
}
|
|
3742
|
-
if (
|
|
3743
|
-
|
|
3744
|
-
|
|
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)}]`;
|
|
3745
5666
|
}
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
5667
|
+
return "list[Any]";
|
|
5668
|
+
}
|
|
5669
|
+
if (type === "object") {
|
|
5670
|
+
const additionalProperties = schema.additionalProperties;
|
|
5671
|
+
if (additionalProperties) {
|
|
5672
|
+
return `dict[str, ${jsonSchemaToPythonType(additionalProperties)}]`;
|
|
3749
5673
|
}
|
|
3750
|
-
|
|
3751
|
-
return lines2;
|
|
5674
|
+
return "dict";
|
|
3752
5675
|
}
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
return [`${indent}<${tagName}></${tagName}>`];
|
|
5676
|
+
if (Array.isArray(type)) {
|
|
5677
|
+
return `Union[${type.map((t) => jsonSchemaToPythonType({ type: t })).join(",")}]`;
|
|
3756
5678
|
}
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
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
|
+
}
|
|
3760
5697
|
}
|
|
3761
|
-
|
|
3762
|
-
|
|
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>`;
|
|
3763
5711
|
}
|
|
3764
5712
|
|
|
3765
|
-
// src/core/prompts/xml-
|
|
5713
|
+
// src/core/prompts/morph-xml-prompt.ts
|
|
3766
5714
|
import dedent from "dedent";
|
|
3767
|
-
function
|
|
5715
|
+
function morphXmlSystemPromptTemplate(tools) {
|
|
3768
5716
|
const toolsText = renderToolsForXmlPrompt(tools);
|
|
3769
5717
|
const header = dedent`
|
|
3770
5718
|
# Tools
|
|
@@ -3988,9 +5936,241 @@ function stripSchemaKeys(value) {
|
|
|
3988
5936
|
}
|
|
3989
5937
|
return value;
|
|
3990
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
|
+
}
|
|
3991
6171
|
|
|
3992
|
-
// src/core/prompts/yaml-
|
|
3993
|
-
function
|
|
6172
|
+
// src/core/prompts/yaml-xml-prompt.ts
|
|
6173
|
+
function yamlXmlSystemPromptTemplate(tools, includeMultilineExample = true) {
|
|
3994
6174
|
const toolsJson = JSON.stringify(tools);
|
|
3995
6175
|
const multilineExample = includeMultilineExample ? `
|
|
3996
6176
|
|
|
@@ -4029,6 +6209,9 @@ unit: celsius
|
|
|
4029
6209
|
- Do NOT ask clarifying questions. Use reasonable defaults for optional parameters.
|
|
4030
6210
|
- If a task requires multiple function calls, make ALL of them at once.`;
|
|
4031
6211
|
}
|
|
6212
|
+
function formatToolResponseAsYaml(toolResult) {
|
|
6213
|
+
return morphFormatToolResponseAsXml(toolResult);
|
|
6214
|
+
}
|
|
4032
6215
|
|
|
4033
6216
|
// src/stream-handler.ts
|
|
4034
6217
|
async function wrapStream({
|
|
@@ -4193,8 +6376,75 @@ function normalizeUsage(usage) {
|
|
|
4193
6376
|
return ZERO_USAGE;
|
|
4194
6377
|
}
|
|
4195
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
|
+
|
|
4196
6443
|
// src/transform-handler.ts
|
|
4197
6444
|
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
6445
|
+
if (systemPrompt.trim().length === 0) {
|
|
6446
|
+
return processedPrompt;
|
|
6447
|
+
}
|
|
4198
6448
|
const systemIndex = processedPrompt.findIndex((m) => m.role === "system");
|
|
4199
6449
|
if (systemIndex !== -1) {
|
|
4200
6450
|
const existing = processedPrompt[systemIndex].content;
|
|
@@ -4390,94 +6640,30 @@ function transformParams({
|
|
|
4390
6640
|
}
|
|
4391
6641
|
return baseReturnParams;
|
|
4392
6642
|
}
|
|
4393
|
-
function processAssistantContent(content, resolvedProtocol, providerOptions) {
|
|
4394
|
-
var _a;
|
|
4395
|
-
const newContent = [];
|
|
4396
|
-
for (const item of content) {
|
|
4397
|
-
switch (item.type) {
|
|
4398
|
-
case "tool-call":
|
|
4399
|
-
newContent.push({
|
|
4400
|
-
type: "text",
|
|
4401
|
-
text: resolvedProtocol.formatToolCall(item)
|
|
4402
|
-
});
|
|
4403
|
-
break;
|
|
4404
|
-
case "text":
|
|
4405
|
-
case "reasoning":
|
|
4406
|
-
newContent.push(item);
|
|
4407
|
-
break;
|
|
4408
|
-
default: {
|
|
4409
|
-
const options = extractOnErrorOption(providerOptions);
|
|
4410
|
-
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4411
|
-
options,
|
|
4412
|
-
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
4413
|
-
{ content: item }
|
|
4414
|
-
);
|
|
4415
|
-
newContent.push({
|
|
4416
|
-
type: "text",
|
|
4417
|
-
text: JSON.stringify(item)
|
|
4418
|
-
});
|
|
4419
|
-
}
|
|
4420
|
-
}
|
|
4421
|
-
}
|
|
4422
|
-
const onlyText = newContent.every((c) => c.type === "text");
|
|
4423
|
-
return onlyText ? [
|
|
4424
|
-
{
|
|
4425
|
-
type: "text",
|
|
4426
|
-
text: newContent.map((c) => c.text).join("\n")
|
|
4427
|
-
}
|
|
4428
|
-
] : newContent;
|
|
4429
|
-
}
|
|
4430
|
-
function formatApprovalResponse(part) {
|
|
4431
|
-
const status = part.approved ? "Approved" : "Denied";
|
|
4432
|
-
const reason = part.reason ? `: ${part.reason}` : "";
|
|
4433
|
-
return `[Tool Approval ${status}${reason}]`;
|
|
4434
|
-
}
|
|
4435
|
-
function processToolMessage(toolResults, approvalResponses, toolResponsePromptTemplate) {
|
|
4436
|
-
const resultTexts = toolResults.map((toolResult) => {
|
|
4437
|
-
return toolResponsePromptTemplate(toolResult);
|
|
4438
|
-
});
|
|
4439
|
-
const approvalTexts = approvalResponses.map(formatApprovalResponse);
|
|
4440
|
-
const allTexts = [...resultTexts, ...approvalTexts];
|
|
4441
|
-
return {
|
|
4442
|
-
role: "user",
|
|
4443
|
-
content: [
|
|
4444
|
-
{
|
|
4445
|
-
type: "text",
|
|
4446
|
-
text: allTexts.join("\n")
|
|
4447
|
-
}
|
|
4448
|
-
]
|
|
4449
|
-
};
|
|
4450
|
-
}
|
|
4451
6643
|
function processMessage(message, resolvedProtocol, providerOptions, toolResponsePromptTemplate) {
|
|
4452
6644
|
if (message.role === "assistant") {
|
|
4453
|
-
const condensedContent =
|
|
4454
|
-
message.content,
|
|
4455
|
-
resolvedProtocol,
|
|
4456
|
-
|
|
4457
|
-
|
|
6645
|
+
const condensedContent = assistantToolCallsToTextContent({
|
|
6646
|
+
content: message.content,
|
|
6647
|
+
protocol: resolvedProtocol,
|
|
6648
|
+
conversionOptions: {
|
|
6649
|
+
onError: providerOptions == null ? void 0 : providerOptions.onError
|
|
6650
|
+
}
|
|
6651
|
+
});
|
|
4458
6652
|
return {
|
|
4459
6653
|
role: "assistant",
|
|
4460
6654
|
content: condensedContent
|
|
4461
6655
|
};
|
|
4462
6656
|
}
|
|
4463
6657
|
if (message.role === "tool") {
|
|
4464
|
-
const toolContent = message.content;
|
|
4465
|
-
const toolResultParts = toolContent.filter(
|
|
4466
|
-
(part) => part.type === "tool-result"
|
|
4467
|
-
);
|
|
4468
|
-
const approvalResponseParts = toolContent.filter(
|
|
4469
|
-
(part) => part.type === "tool-approval-response"
|
|
4470
|
-
);
|
|
4471
6658
|
if (!toolResponsePromptTemplate) {
|
|
4472
6659
|
throw new Error(
|
|
4473
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.'
|
|
4474
6661
|
);
|
|
4475
6662
|
}
|
|
4476
|
-
return
|
|
4477
|
-
|
|
4478
|
-
approvalResponseParts,
|
|
6663
|
+
return toolRoleContentToUserTextMessage({
|
|
6664
|
+
toolContent: message.content,
|
|
4479
6665
|
toolResponsePromptTemplate
|
|
4480
|
-
);
|
|
6666
|
+
});
|
|
4481
6667
|
}
|
|
4482
6668
|
return message;
|
|
4483
6669
|
}
|
|
@@ -4528,6 +6714,9 @@ function mergeConsecutiveUserMessages(processedPrompt) {
|
|
|
4528
6714
|
const current = processedPrompt[i];
|
|
4529
6715
|
const prev = processedPrompt[i - 1];
|
|
4530
6716
|
if (current.role === "user" && prev.role === "user") {
|
|
6717
|
+
if (!(isAllTextContent(prev.content) && isAllTextContent(current.content))) {
|
|
6718
|
+
continue;
|
|
6719
|
+
}
|
|
4531
6720
|
const prevContent = prev.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
4532
6721
|
const currentContent = current.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
4533
6722
|
processedPrompt[i - 1] = {
|
|
@@ -4587,19 +6776,24 @@ function createToolMiddleware({
|
|
|
4587
6776
|
|
|
4588
6777
|
// src/preconfigured-middleware.ts
|
|
4589
6778
|
var hermesToolMiddleware = createToolMiddleware({
|
|
4590
|
-
protocol:
|
|
6779
|
+
protocol: hermesProtocol(),
|
|
4591
6780
|
toolSystemPromptTemplate: hermesSystemPromptTemplate,
|
|
4592
|
-
toolResponsePromptTemplate:
|
|
6781
|
+
toolResponsePromptTemplate: formatToolResponseAsHermes
|
|
6782
|
+
});
|
|
6783
|
+
var qwen3CoderToolMiddleware = createToolMiddleware({
|
|
6784
|
+
protocol: qwen3CoderProtocol,
|
|
6785
|
+
toolSystemPromptTemplate: qwen3coderSystemPromptTemplate,
|
|
6786
|
+
toolResponsePromptTemplate: formatToolResponseAsQwen3CoderXml
|
|
4593
6787
|
});
|
|
4594
|
-
var
|
|
4595
|
-
protocol:
|
|
4596
|
-
toolSystemPromptTemplate:
|
|
4597
|
-
toolResponsePromptTemplate:
|
|
6788
|
+
var morphXmlToolMiddleware = createToolMiddleware({
|
|
6789
|
+
protocol: morphXmlProtocol({}),
|
|
6790
|
+
toolSystemPromptTemplate: morphXmlSystemPromptTemplate,
|
|
6791
|
+
toolResponsePromptTemplate: morphFormatToolResponseAsXml
|
|
4598
6792
|
});
|
|
4599
|
-
var
|
|
4600
|
-
protocol:
|
|
4601
|
-
toolSystemPromptTemplate:
|
|
4602
|
-
toolResponsePromptTemplate:
|
|
6793
|
+
var yamlXmlToolMiddleware = createToolMiddleware({
|
|
6794
|
+
protocol: yamlXmlProtocol({}),
|
|
6795
|
+
toolSystemPromptTemplate: yamlXmlSystemPromptTemplate,
|
|
6796
|
+
toolResponsePromptTemplate: formatToolResponseAsYaml
|
|
4603
6797
|
});
|
|
4604
6798
|
|
|
4605
6799
|
export {
|
|
@@ -4609,11 +6803,14 @@ export {
|
|
|
4609
6803
|
logParsedChunk,
|
|
4610
6804
|
logParsedSummary,
|
|
4611
6805
|
getPotentialStartIndex,
|
|
4612
|
-
|
|
6806
|
+
hermesProtocol,
|
|
6807
|
+
morphXmlProtocol,
|
|
4613
6808
|
isProtocolFactory,
|
|
4614
6809
|
isTCMProtocolFactory,
|
|
4615
|
-
|
|
4616
|
-
|
|
6810
|
+
qwen3CoderProtocol,
|
|
6811
|
+
uiTarsXmlProtocol,
|
|
6812
|
+
Qwen3CoderToolParser,
|
|
6813
|
+
yamlXmlProtocol,
|
|
4617
6814
|
createDynamicIfThenElseSchema,
|
|
4618
6815
|
extractOnErrorOption,
|
|
4619
6816
|
originalToolsSchema,
|
|
@@ -4624,12 +6821,14 @@ export {
|
|
|
4624
6821
|
isToolResultPart,
|
|
4625
6822
|
hasInputProperty,
|
|
4626
6823
|
wrapGenerate,
|
|
6824
|
+
morphFormatToolResponseAsXml,
|
|
4627
6825
|
wrapStream,
|
|
4628
6826
|
toolChoiceStream,
|
|
4629
6827
|
transformParams,
|
|
4630
6828
|
createToolMiddleware,
|
|
4631
6829
|
hermesToolMiddleware,
|
|
4632
|
-
|
|
4633
|
-
|
|
6830
|
+
qwen3CoderToolMiddleware,
|
|
6831
|
+
morphXmlToolMiddleware,
|
|
6832
|
+
yamlXmlToolMiddleware
|
|
4634
6833
|
};
|
|
4635
|
-
//# sourceMappingURL=chunk-
|
|
6834
|
+
//# sourceMappingURL=chunk-O6NWVXQD.js.map
|