@ai-sdk-tool/parser 4.0.1 → 4.1.1
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-DPGORNPB.js → chunk-722D5BGD.js} +3339 -826
- package/dist/chunk-722D5BGD.js.map +1 -0
- package/dist/{chunk-76E6H46R.js → chunk-D4YULTAO.js} +11 -8
- package/dist/chunk-D4YULTAO.js.map +1 -0
- package/dist/{chunk-DJB4DAZO.js → chunk-GMTE7BY5.js} +1 -1
- package/dist/{chunk-DJB4DAZO.js.map → chunk-GMTE7BY5.js.map} +1 -1
- package/dist/{chunk-IX4FJELL.js → chunk-QBZNMO5C.js} +1 -1
- package/dist/chunk-QBZNMO5C.js.map +1 -0
- package/dist/community.cjs +7868 -5243
- 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 +7199 -4683
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -62
- package/dist/index.d.ts +40 -62
- package/dist/index.js +28 -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 +6 -6
- package/dist/rxml.cjs.map +1 -1
- package/dist/rxml.d.cts +23 -23
- package/dist/rxml.d.ts +23 -23
- package/dist/rxml.js +2 -2
- package/dist/schema-coerce.cjs.map +1 -1
- package/dist/schema-coerce.js +1 -1
- package/package.json +7 -7
- package/dist/chunk-76E6H46R.js.map +0 -1
- package/dist/chunk-DPGORNPB.js.map +0 -1
- package/dist/chunk-IX4FJELL.js.map +0 -1
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
escapeRegExp,
|
|
3
|
+
escapeXmlMinimalAttr,
|
|
4
|
+
escapeXmlMinimalText,
|
|
3
5
|
parse as parse2,
|
|
4
|
-
stringify
|
|
5
|
-
|
|
6
|
+
stringify,
|
|
7
|
+
unescapeXml
|
|
8
|
+
} from "./chunk-D4YULTAO.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/;
|
|
@@ -219,6 +222,12 @@ function generateToolCallId() {
|
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
// src/core/utils/protocol-utils.ts
|
|
225
|
+
function formatToolsWithPromptTemplate(options) {
|
|
226
|
+
return options.toolSystemPromptTemplate(options.tools || []);
|
|
227
|
+
}
|
|
228
|
+
function extractToolNames(tools) {
|
|
229
|
+
return tools.map((tool) => tool.name).filter(Boolean);
|
|
230
|
+
}
|
|
222
231
|
function addTextSegment(text, processedElements) {
|
|
223
232
|
if (text.trim()) {
|
|
224
233
|
processedElements.push({ type: "text", text });
|
|
@@ -257,10 +266,222 @@ function createFlushTextHandler(getCurrentTextId, setCurrentTextId, getHasEmitte
|
|
|
257
266
|
};
|
|
258
267
|
}
|
|
259
268
|
|
|
260
|
-
// src/core/
|
|
269
|
+
// src/core/utils/streamed-tool-input-delta.ts
|
|
270
|
+
function emitDelta({
|
|
271
|
+
controller,
|
|
272
|
+
id,
|
|
273
|
+
state,
|
|
274
|
+
nextInput
|
|
275
|
+
}) {
|
|
276
|
+
if (!nextInput.startsWith(state.emittedInput)) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
const delta = nextInput.slice(state.emittedInput.length);
|
|
280
|
+
if (delta.length === 0) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
controller.enqueue({
|
|
284
|
+
type: "tool-input-delta",
|
|
285
|
+
id,
|
|
286
|
+
delta
|
|
287
|
+
});
|
|
288
|
+
state.emittedInput = nextInput;
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
function toIncompleteJsonPrefix(fullJson) {
|
|
292
|
+
const trimmed = fullJson.trim();
|
|
293
|
+
let prefix = trimmed;
|
|
294
|
+
while (prefix.endsWith("}") || prefix.endsWith("]")) {
|
|
295
|
+
prefix = prefix.slice(0, -1);
|
|
296
|
+
}
|
|
297
|
+
prefix = prefix.trimEnd();
|
|
298
|
+
if (prefix.endsWith('"')) {
|
|
299
|
+
prefix = prefix.slice(0, -1);
|
|
300
|
+
}
|
|
301
|
+
if (prefix.length === 0) {
|
|
302
|
+
if (trimmed.startsWith("[") || trimmed.startsWith("{")) {
|
|
303
|
+
return trimmed.startsWith("{") ? "{" : "[";
|
|
304
|
+
}
|
|
305
|
+
if (trimmed.startsWith("]")) {
|
|
306
|
+
return "[";
|
|
307
|
+
}
|
|
308
|
+
if (trimmed.startsWith("}")) {
|
|
309
|
+
return "{";
|
|
310
|
+
}
|
|
311
|
+
if (trimmed.startsWith('"')) {
|
|
312
|
+
return '"';
|
|
313
|
+
}
|
|
314
|
+
return "{";
|
|
315
|
+
}
|
|
316
|
+
return prefix;
|
|
317
|
+
}
|
|
318
|
+
function emitPrefixDelta(params) {
|
|
319
|
+
return emitDelta({
|
|
320
|
+
...params,
|
|
321
|
+
nextInput: params.candidate
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
var DEFAULT_TOOL_INPUT_DELTA_CHUNK_CHARS = 512;
|
|
325
|
+
function emitChunkedPrefixDelta(params) {
|
|
326
|
+
const { maxChunkChars = DEFAULT_TOOL_INPUT_DELTA_CHUNK_CHARS } = params;
|
|
327
|
+
if (maxChunkChars <= 0) {
|
|
328
|
+
return emitPrefixDelta(params);
|
|
329
|
+
}
|
|
330
|
+
const growth = params.candidate.length - params.state.emittedInput.length;
|
|
331
|
+
if (growth <= 0) {
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
if (growth <= maxChunkChars) {
|
|
335
|
+
return emitPrefixDelta(params);
|
|
336
|
+
}
|
|
337
|
+
let emittedAny = false;
|
|
338
|
+
let cursor = params.state.emittedInput.length + maxChunkChars;
|
|
339
|
+
while (cursor < params.candidate.length) {
|
|
340
|
+
const didEmit = emitPrefixDelta({
|
|
341
|
+
controller: params.controller,
|
|
342
|
+
id: params.id,
|
|
343
|
+
state: params.state,
|
|
344
|
+
candidate: params.candidate.slice(0, cursor)
|
|
345
|
+
});
|
|
346
|
+
if (!didEmit) {
|
|
347
|
+
return emittedAny;
|
|
348
|
+
}
|
|
349
|
+
emittedAny = true;
|
|
350
|
+
cursor += maxChunkChars;
|
|
351
|
+
}
|
|
352
|
+
return emitPrefixDelta({
|
|
353
|
+
controller: params.controller,
|
|
354
|
+
id: params.id,
|
|
355
|
+
state: params.state,
|
|
356
|
+
candidate: params.candidate
|
|
357
|
+
}) || emittedAny;
|
|
358
|
+
}
|
|
359
|
+
function emitFinalRemainder(params) {
|
|
360
|
+
var _a;
|
|
361
|
+
const result = emitDelta({
|
|
362
|
+
...params,
|
|
363
|
+
nextInput: params.finalFullJson
|
|
364
|
+
});
|
|
365
|
+
if (!result && params.state.emittedInput.length > 0) {
|
|
366
|
+
(_a = params.onMismatch) == null ? void 0 : _a.call(
|
|
367
|
+
params,
|
|
368
|
+
"Final JSON does not extend emitted tool-input prefix",
|
|
369
|
+
{
|
|
370
|
+
emittedLength: params.state.emittedInput.length,
|
|
371
|
+
finalLength: params.finalFullJson.length
|
|
372
|
+
}
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// src/core/utils/tool-call-coercion.ts
|
|
379
|
+
function coerceToolCallInput(toolName, input, tools) {
|
|
380
|
+
var _a;
|
|
381
|
+
let args = {};
|
|
382
|
+
if (typeof input === "string") {
|
|
383
|
+
try {
|
|
384
|
+
args = JSON.parse(input);
|
|
385
|
+
} catch (e) {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
} else if (input && typeof input === "object") {
|
|
389
|
+
args = input;
|
|
390
|
+
} else {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const schema = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
394
|
+
const coerced = coerceBySchema(args, schema);
|
|
395
|
+
return JSON.stringify(coerced != null ? coerced : {});
|
|
396
|
+
}
|
|
397
|
+
function coerceToolCallPart(part, tools) {
|
|
398
|
+
const coercedInput = coerceToolCallInput(part.toolName, part.input, tools);
|
|
399
|
+
if (coercedInput === void 0) {
|
|
400
|
+
return part;
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
...part,
|
|
404
|
+
input: coercedInput
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// src/core/utils/tool-input-streaming.ts
|
|
409
|
+
function stringifyToolInputWithSchema(options) {
|
|
410
|
+
var _a;
|
|
411
|
+
const coerced = coerceToolCallInput(
|
|
412
|
+
options.toolName,
|
|
413
|
+
options.args,
|
|
414
|
+
options.tools
|
|
415
|
+
);
|
|
416
|
+
if (coerced !== void 0) {
|
|
417
|
+
return coerced;
|
|
418
|
+
}
|
|
419
|
+
if (options.fallback) {
|
|
420
|
+
return options.fallback(options.args);
|
|
421
|
+
}
|
|
422
|
+
return JSON.stringify((_a = options.args) != null ? _a : {});
|
|
423
|
+
}
|
|
424
|
+
function emitToolInputProgressDelta(options) {
|
|
425
|
+
var _a;
|
|
426
|
+
const mode = (_a = options.mode) != null ? _a : "incomplete-json-prefix";
|
|
427
|
+
const candidate = mode === "full-json" ? options.fullInput : toIncompleteJsonPrefix(options.fullInput);
|
|
428
|
+
return emitChunkedPrefixDelta({
|
|
429
|
+
controller: options.controller,
|
|
430
|
+
id: options.id,
|
|
431
|
+
state: options.state,
|
|
432
|
+
candidate
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
function enqueueToolInputEndAndCall(options) {
|
|
436
|
+
enqueueToolInputEnd({
|
|
437
|
+
controller: options.controller,
|
|
438
|
+
id: options.id
|
|
439
|
+
});
|
|
440
|
+
options.controller.enqueue({
|
|
441
|
+
type: "tool-call",
|
|
442
|
+
toolCallId: options.id,
|
|
443
|
+
toolName: options.toolName,
|
|
444
|
+
input: options.input
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
function enqueueToolInputEnd(options) {
|
|
448
|
+
options.controller.enqueue({
|
|
449
|
+
type: "tool-input-end",
|
|
450
|
+
id: options.id
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
function emitFailedToolInputLifecycle(options) {
|
|
454
|
+
var _a;
|
|
455
|
+
if (options.endInput !== false) {
|
|
456
|
+
enqueueToolInputEnd({
|
|
457
|
+
controller: options.controller,
|
|
458
|
+
id: options.id
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
if (options.emitRawToolCallTextOnError && typeof options.rawToolCallText === "string" && options.rawToolCallText.length > 0) {
|
|
462
|
+
(_a = options.emitRawText) == null ? void 0 : _a.call(options, options.rawToolCallText);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function emitFinalizedToolInputLifecycle(options) {
|
|
466
|
+
emitFinalRemainder({
|
|
467
|
+
controller: options.controller,
|
|
468
|
+
id: options.id,
|
|
469
|
+
state: options.state,
|
|
470
|
+
finalFullJson: options.finalInput,
|
|
471
|
+
onMismatch: options.onMismatch
|
|
472
|
+
});
|
|
473
|
+
enqueueToolInputEndAndCall({
|
|
474
|
+
controller: options.controller,
|
|
475
|
+
id: options.id,
|
|
476
|
+
toolName: options.toolName,
|
|
477
|
+
input: options.finalInput
|
|
478
|
+
});
|
|
479
|
+
}
|
|
261
480
|
function shouldEmitRawToolCallTextOnError(options) {
|
|
262
481
|
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
263
482
|
}
|
|
483
|
+
|
|
484
|
+
// src/core/protocols/hermes-protocol.ts
|
|
264
485
|
function canonicalizeToolInput(argumentsValue) {
|
|
265
486
|
return JSON.stringify(argumentsValue != null ? argumentsValue : {});
|
|
266
487
|
}
|
|
@@ -524,19 +745,13 @@ function emitToolInputDelta(state, controller, fullInput) {
|
|
|
524
745
|
if (!active) {
|
|
525
746
|
return;
|
|
526
747
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
}
|
|
530
|
-
const delta = fullInput.slice(active.emittedInput.length);
|
|
531
|
-
if (delta.length === 0) {
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
controller.enqueue({
|
|
535
|
-
type: "tool-input-delta",
|
|
748
|
+
emitToolInputProgressDelta({
|
|
749
|
+
controller,
|
|
536
750
|
id: active.id,
|
|
537
|
-
|
|
751
|
+
state: active,
|
|
752
|
+
fullInput,
|
|
753
|
+
mode: "full-json"
|
|
538
754
|
});
|
|
539
|
-
active.emittedInput = fullInput;
|
|
540
755
|
}
|
|
541
756
|
function closeToolInput(state, controller) {
|
|
542
757
|
if (!state.activeToolInput) {
|
|
@@ -548,11 +763,16 @@ function closeToolInput(state, controller) {
|
|
|
548
763
|
});
|
|
549
764
|
state.activeToolInput = null;
|
|
550
765
|
}
|
|
551
|
-
function emitToolCallFromParsed(state, controller, parsedToolCall) {
|
|
766
|
+
function emitToolCallFromParsed(state, controller, parsedToolCall, tools) {
|
|
552
767
|
var _a, _b, _c, _d;
|
|
553
768
|
closeTextBlock(state, controller);
|
|
554
769
|
const toolName = typeof parsedToolCall.name === "string" ? parsedToolCall.name : (_b = (_a = state.activeToolInput) == null ? void 0 : _a.toolName) != null ? _b : "unknown";
|
|
555
|
-
const input =
|
|
770
|
+
const input = stringifyToolInputWithSchema({
|
|
771
|
+
toolName,
|
|
772
|
+
args: parsedToolCall.arguments,
|
|
773
|
+
tools,
|
|
774
|
+
fallback: canonicalizeToolInput
|
|
775
|
+
});
|
|
556
776
|
ensureToolInputStart(state, controller, toolName);
|
|
557
777
|
emitToolInputDelta(state, controller, input);
|
|
558
778
|
const toolCallId = (_d = (_c = state.activeToolInput) == null ? void 0 : _c.id) != null ? _d : generateToolCallId();
|
|
@@ -564,18 +784,23 @@ function emitToolCallFromParsed(state, controller, parsedToolCall) {
|
|
|
564
784
|
input
|
|
565
785
|
});
|
|
566
786
|
}
|
|
567
|
-
function canonicalizeArgumentsProgressInput(progress) {
|
|
787
|
+
function canonicalizeArgumentsProgressInput(progress, toolName, tools) {
|
|
568
788
|
if (progress.argumentsText === void 0 || !progress.argumentsComplete) {
|
|
569
789
|
return void 0;
|
|
570
790
|
}
|
|
571
791
|
try {
|
|
572
792
|
const parsedArguments = parse(progress.argumentsText);
|
|
573
|
-
return
|
|
793
|
+
return stringifyToolInputWithSchema({
|
|
794
|
+
toolName,
|
|
795
|
+
args: parsedArguments,
|
|
796
|
+
tools,
|
|
797
|
+
fallback: canonicalizeToolInput
|
|
798
|
+
});
|
|
574
799
|
} catch (e) {
|
|
575
800
|
return void 0;
|
|
576
801
|
}
|
|
577
802
|
}
|
|
578
|
-
function emitToolInputProgress(state, controller) {
|
|
803
|
+
function emitToolInputProgress(state, controller, tools) {
|
|
579
804
|
if (!(state.isInsideToolCall && state.currentToolCallJson)) {
|
|
580
805
|
return;
|
|
581
806
|
}
|
|
@@ -584,7 +809,11 @@ function emitToolInputProgress(state, controller) {
|
|
|
584
809
|
return;
|
|
585
810
|
}
|
|
586
811
|
ensureToolInputStart(state, controller, progress.toolName);
|
|
587
|
-
const canonicalProgressInput = canonicalizeArgumentsProgressInput(
|
|
812
|
+
const canonicalProgressInput = canonicalizeArgumentsProgressInput(
|
|
813
|
+
progress,
|
|
814
|
+
progress.toolName,
|
|
815
|
+
tools
|
|
816
|
+
);
|
|
588
817
|
if (canonicalProgressInput !== void 0) {
|
|
589
818
|
emitToolInputDelta(state, controller, canonicalProgressInput);
|
|
590
819
|
}
|
|
@@ -619,7 +848,7 @@ function closeTextBlock(state, controller) {
|
|
|
619
848
|
state.hasEmittedTextStart = false;
|
|
620
849
|
}
|
|
621
850
|
}
|
|
622
|
-
function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer, options) {
|
|
851
|
+
function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer, tools, options) {
|
|
623
852
|
var _a;
|
|
624
853
|
if (!state.currentToolCallJson && trailingBuffer.length === 0) {
|
|
625
854
|
state.isInsideToolCall = false;
|
|
@@ -628,7 +857,7 @@ function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer
|
|
|
628
857
|
if (state.currentToolCallJson) {
|
|
629
858
|
try {
|
|
630
859
|
const parsedToolCall = parse(state.currentToolCallJson);
|
|
631
|
-
emitToolCallFromParsed(state, controller, parsedToolCall);
|
|
860
|
+
emitToolCallFromParsed(state, controller, parsedToolCall, tools);
|
|
632
861
|
state.currentToolCallJson = "";
|
|
633
862
|
state.isInsideToolCall = false;
|
|
634
863
|
return;
|
|
@@ -668,7 +897,7 @@ function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer
|
|
|
668
897
|
state.currentToolCallJson = "";
|
|
669
898
|
state.isInsideToolCall = false;
|
|
670
899
|
}
|
|
671
|
-
function handleFinishChunk(state, controller, toolCallStart, options, chunk) {
|
|
900
|
+
function handleFinishChunk(state, controller, toolCallStart, tools, options, chunk) {
|
|
672
901
|
if (state.isInsideToolCall) {
|
|
673
902
|
const trailingBuffer = state.buffer;
|
|
674
903
|
state.buffer = "";
|
|
@@ -677,6 +906,7 @@ function handleFinishChunk(state, controller, toolCallStart, options, chunk) {
|
|
|
677
906
|
controller,
|
|
678
907
|
toolCallStart,
|
|
679
908
|
trailingBuffer,
|
|
909
|
+
tools,
|
|
680
910
|
options
|
|
681
911
|
);
|
|
682
912
|
} else if (state.buffer.length > 0) {
|
|
@@ -685,11 +915,11 @@ function handleFinishChunk(state, controller, toolCallStart, options, chunk) {
|
|
|
685
915
|
closeTextBlock(state, controller);
|
|
686
916
|
controller.enqueue(chunk);
|
|
687
917
|
}
|
|
688
|
-
function publishText(text, state, controller) {
|
|
918
|
+
function publishText(text, state, controller, tools) {
|
|
689
919
|
if (state.isInsideToolCall) {
|
|
690
920
|
closeTextBlock(state, controller);
|
|
691
921
|
state.currentToolCallJson += text;
|
|
692
|
-
emitToolInputProgress(state, controller);
|
|
922
|
+
emitToolInputProgress(state, controller, tools);
|
|
693
923
|
} else if (text.length > 0) {
|
|
694
924
|
if (!state.currentTextId) {
|
|
695
925
|
state.currentTextId = generateId();
|
|
@@ -708,10 +938,10 @@ function publishText(text, state, controller) {
|
|
|
708
938
|
}
|
|
709
939
|
function emitToolCall(context) {
|
|
710
940
|
var _a;
|
|
711
|
-
const { state, controller, toolCallStart, toolCallEnd, options } = context;
|
|
941
|
+
const { state, controller, toolCallStart, toolCallEnd, options, tools } = context;
|
|
712
942
|
try {
|
|
713
943
|
const parsedToolCall = parse(state.currentToolCallJson);
|
|
714
|
-
emitToolCallFromParsed(state, controller, parsedToolCall);
|
|
944
|
+
emitToolCallFromParsed(state, controller, parsedToolCall, tools);
|
|
715
945
|
} catch (error) {
|
|
716
946
|
const errorContent = `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`;
|
|
717
947
|
const shouldEmitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
@@ -760,7 +990,7 @@ function processTagMatch(context) {
|
|
|
760
990
|
}
|
|
761
991
|
}
|
|
762
992
|
function processBufferTags(context) {
|
|
763
|
-
const { state, controller, toolCallStart, toolCallEnd } = context;
|
|
993
|
+
const { state, controller, toolCallStart, toolCallEnd, tools } = context;
|
|
764
994
|
let startIndex = getPotentialStartIndex(
|
|
765
995
|
state.buffer,
|
|
766
996
|
state.isInsideToolCall ? toolCallEnd : toolCallStart
|
|
@@ -770,7 +1000,7 @@ function processBufferTags(context) {
|
|
|
770
1000
|
if (startIndex + tag.length > state.buffer.length) {
|
|
771
1001
|
break;
|
|
772
1002
|
}
|
|
773
|
-
publishText(state.buffer.slice(0, startIndex), state, controller);
|
|
1003
|
+
publishText(state.buffer.slice(0, startIndex), state, controller, tools);
|
|
774
1004
|
state.buffer = state.buffer.slice(startIndex + tag.length);
|
|
775
1005
|
processTagMatch(context);
|
|
776
1006
|
startIndex = getPotentialStartIndex(
|
|
@@ -779,28 +1009,38 @@ function processBufferTags(context) {
|
|
|
779
1009
|
);
|
|
780
1010
|
}
|
|
781
1011
|
}
|
|
782
|
-
function handlePartialTag(state, controller, toolCallStart, toolCallEnd) {
|
|
1012
|
+
function handlePartialTag(state, controller, toolCallStart, toolCallEnd, tools) {
|
|
783
1013
|
if (state.isInsideToolCall) {
|
|
784
1014
|
const potentialEndIndex = getPotentialStartIndex(state.buffer, toolCallEnd);
|
|
785
1015
|
if (potentialEndIndex != null && potentialEndIndex + toolCallEnd.length > state.buffer.length) {
|
|
786
|
-
publishText(
|
|
1016
|
+
publishText(
|
|
1017
|
+
state.buffer.slice(0, potentialEndIndex),
|
|
1018
|
+
state,
|
|
1019
|
+
controller,
|
|
1020
|
+
tools
|
|
1021
|
+
);
|
|
787
1022
|
state.buffer = state.buffer.slice(potentialEndIndex);
|
|
788
1023
|
} else {
|
|
789
|
-
publishText(state.buffer, state, controller);
|
|
1024
|
+
publishText(state.buffer, state, controller, tools);
|
|
790
1025
|
state.buffer = "";
|
|
791
1026
|
}
|
|
792
1027
|
return;
|
|
793
1028
|
}
|
|
794
1029
|
const potentialIndex = getPotentialStartIndex(state.buffer, toolCallStart);
|
|
795
1030
|
if (potentialIndex != null && potentialIndex + toolCallStart.length > state.buffer.length) {
|
|
796
|
-
publishText(
|
|
1031
|
+
publishText(
|
|
1032
|
+
state.buffer.slice(0, potentialIndex),
|
|
1033
|
+
state,
|
|
1034
|
+
controller,
|
|
1035
|
+
tools
|
|
1036
|
+
);
|
|
797
1037
|
state.buffer = state.buffer.slice(potentialIndex);
|
|
798
1038
|
} else {
|
|
799
|
-
publishText(state.buffer, state, controller);
|
|
1039
|
+
publishText(state.buffer, state, controller, tools);
|
|
800
1040
|
state.buffer = "";
|
|
801
1041
|
}
|
|
802
1042
|
}
|
|
803
|
-
var
|
|
1043
|
+
var hermesProtocol = ({
|
|
804
1044
|
toolCallStart = "<tool_call>",
|
|
805
1045
|
toolCallEnd = "</tool_call>"
|
|
806
1046
|
} = {}) => ({
|
|
@@ -808,7 +1048,7 @@ var jsonProtocol = ({
|
|
|
808
1048
|
tools,
|
|
809
1049
|
toolSystemPromptTemplate
|
|
810
1050
|
}) {
|
|
811
|
-
return
|
|
1051
|
+
return formatToolsWithPromptTemplate({ tools, toolSystemPromptTemplate });
|
|
812
1052
|
},
|
|
813
1053
|
formatToolCall(toolCall) {
|
|
814
1054
|
let args = {};
|
|
@@ -854,6 +1094,7 @@ var jsonProtocol = ({
|
|
|
854
1094
|
return processedElements;
|
|
855
1095
|
},
|
|
856
1096
|
createStreamParser({
|
|
1097
|
+
tools,
|
|
857
1098
|
options
|
|
858
1099
|
}) {
|
|
859
1100
|
const state = {
|
|
@@ -868,7 +1109,14 @@ var jsonProtocol = ({
|
|
|
868
1109
|
transform(chunk, controller) {
|
|
869
1110
|
var _a;
|
|
870
1111
|
if (chunk.type === "finish") {
|
|
871
|
-
handleFinishChunk(
|
|
1112
|
+
handleFinishChunk(
|
|
1113
|
+
state,
|
|
1114
|
+
controller,
|
|
1115
|
+
toolCallStart,
|
|
1116
|
+
tools,
|
|
1117
|
+
options,
|
|
1118
|
+
chunk
|
|
1119
|
+
);
|
|
872
1120
|
return;
|
|
873
1121
|
}
|
|
874
1122
|
if (chunk.type !== "text-delta") {
|
|
@@ -882,9 +1130,10 @@ var jsonProtocol = ({
|
|
|
882
1130
|
controller,
|
|
883
1131
|
toolCallStart,
|
|
884
1132
|
toolCallEnd,
|
|
885
|
-
options
|
|
1133
|
+
options,
|
|
1134
|
+
tools
|
|
886
1135
|
});
|
|
887
|
-
handlePartialTag(state, controller, toolCallStart, toolCallEnd);
|
|
1136
|
+
handlePartialTag(state, controller, toolCallStart, toolCallEnd, tools);
|
|
888
1137
|
}
|
|
889
1138
|
});
|
|
890
1139
|
},
|
|
@@ -902,92 +1151,10 @@ var jsonProtocol = ({
|
|
|
902
1151
|
}
|
|
903
1152
|
});
|
|
904
1153
|
|
|
905
|
-
// src/core/protocols/protocol-interface.ts
|
|
906
|
-
function isProtocolFactory(protocol) {
|
|
907
|
-
return typeof protocol === "function";
|
|
908
|
-
}
|
|
909
|
-
function isTCMProtocolFactory(protocol) {
|
|
910
|
-
return typeof protocol === "function";
|
|
911
|
-
}
|
|
912
|
-
|
|
913
1154
|
// src/core/utils/regex-constants.ts
|
|
914
1155
|
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
915
1156
|
var WHITESPACE_REGEX = /\s/;
|
|
916
1157
|
|
|
917
|
-
// src/core/utils/streamed-tool-input-delta.ts
|
|
918
|
-
function emitDelta({
|
|
919
|
-
controller,
|
|
920
|
-
id,
|
|
921
|
-
state,
|
|
922
|
-
nextInput
|
|
923
|
-
}) {
|
|
924
|
-
if (!nextInput.startsWith(state.emittedInput)) {
|
|
925
|
-
return false;
|
|
926
|
-
}
|
|
927
|
-
const delta = nextInput.slice(state.emittedInput.length);
|
|
928
|
-
if (delta.length === 0) {
|
|
929
|
-
return false;
|
|
930
|
-
}
|
|
931
|
-
controller.enqueue({
|
|
932
|
-
type: "tool-input-delta",
|
|
933
|
-
id,
|
|
934
|
-
delta
|
|
935
|
-
});
|
|
936
|
-
state.emittedInput = nextInput;
|
|
937
|
-
return true;
|
|
938
|
-
}
|
|
939
|
-
function toIncompleteJsonPrefix(fullJson) {
|
|
940
|
-
const trimmed = fullJson.trim();
|
|
941
|
-
let prefix = trimmed;
|
|
942
|
-
while (prefix.endsWith("}") || prefix.endsWith("]")) {
|
|
943
|
-
prefix = prefix.slice(0, -1);
|
|
944
|
-
}
|
|
945
|
-
prefix = prefix.trimEnd();
|
|
946
|
-
if (prefix.endsWith('"')) {
|
|
947
|
-
prefix = prefix.slice(0, -1);
|
|
948
|
-
}
|
|
949
|
-
if (prefix.length === 0) {
|
|
950
|
-
if (trimmed.startsWith("[") || trimmed.startsWith("{")) {
|
|
951
|
-
return trimmed.startsWith("{") ? "{" : "[";
|
|
952
|
-
}
|
|
953
|
-
if (trimmed.startsWith("]")) {
|
|
954
|
-
return "[";
|
|
955
|
-
}
|
|
956
|
-
if (trimmed.startsWith("}")) {
|
|
957
|
-
return "{";
|
|
958
|
-
}
|
|
959
|
-
if (trimmed.startsWith('"')) {
|
|
960
|
-
return '"';
|
|
961
|
-
}
|
|
962
|
-
return "{";
|
|
963
|
-
}
|
|
964
|
-
return prefix;
|
|
965
|
-
}
|
|
966
|
-
function emitPrefixDelta(params) {
|
|
967
|
-
return emitDelta({
|
|
968
|
-
...params,
|
|
969
|
-
nextInput: params.candidate
|
|
970
|
-
});
|
|
971
|
-
}
|
|
972
|
-
function emitFinalRemainder(params) {
|
|
973
|
-
var _a;
|
|
974
|
-
const result = emitDelta({
|
|
975
|
-
...params,
|
|
976
|
-
nextInput: params.finalFullJson
|
|
977
|
-
});
|
|
978
|
-
if (!result && params.state.emittedInput.length > 0) {
|
|
979
|
-
(_a = params.onMismatch) == null ? void 0 : _a.call(
|
|
980
|
-
params,
|
|
981
|
-
"Final JSON does not extend emitted tool-input prefix",
|
|
982
|
-
{
|
|
983
|
-
emittedLength: params.state.emittedInput.length,
|
|
984
|
-
finalLength: params.finalFullJson.length
|
|
985
|
-
}
|
|
986
|
-
);
|
|
987
|
-
}
|
|
988
|
-
return result;
|
|
989
|
-
}
|
|
990
|
-
|
|
991
1158
|
// src/core/utils/xml-root-repair.ts
|
|
992
1159
|
var XML_SELF_CLOSING_ROOT_WITH_BODY_REGEX = /^<([A-Za-z_][A-Za-z0-9_-]*)\s*\r?\n([\s\S]+?)\r?\n\s*\/>\s*$/;
|
|
993
1160
|
function tryRepairXmlSelfClosingRootWithBody(rawText, toolNames) {
|
|
@@ -1012,18 +1179,244 @@ ${body}
|
|
|
1012
1179
|
</${rootTag}>`;
|
|
1013
1180
|
}
|
|
1014
1181
|
|
|
1015
|
-
// src/core/
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
const
|
|
1182
|
+
// src/core/utils/xml-tool-tag-scanner.ts
|
|
1183
|
+
var selfClosingTagCache = /* @__PURE__ */ new Map();
|
|
1184
|
+
function getSelfClosingTagPattern(toolName) {
|
|
1185
|
+
let pattern = selfClosingTagCache.get(toolName);
|
|
1186
|
+
if (!pattern) {
|
|
1187
|
+
pattern = new RegExp(`<\\s*${escapeRegExp(toolName)}\\s*/>`, "g");
|
|
1188
|
+
selfClosingTagCache.set(toolName, pattern);
|
|
1189
|
+
}
|
|
1190
|
+
return pattern;
|
|
1191
|
+
}
|
|
1192
|
+
function findSelfClosingTag(text, toolName, fromIndex) {
|
|
1193
|
+
const pattern = getSelfClosingTagPattern(toolName);
|
|
1194
|
+
pattern.lastIndex = fromIndex;
|
|
1195
|
+
const match = pattern.exec(text);
|
|
1196
|
+
if (!match || match.index === void 0) {
|
|
1197
|
+
return null;
|
|
1198
|
+
}
|
|
1199
|
+
return { index: match.index, length: match[0].length };
|
|
1200
|
+
}
|
|
1201
|
+
function findNextToolTag(text, searchIndex, toolName) {
|
|
1202
|
+
var _a, _b;
|
|
1203
|
+
const startTag = `<${toolName}>`;
|
|
1204
|
+
const openIdx = text.indexOf(startTag, searchIndex);
|
|
1205
|
+
const selfMatch = findSelfClosingTag(text, toolName, searchIndex);
|
|
1206
|
+
const selfIdx = (_a = selfMatch == null ? void 0 : selfMatch.index) != null ? _a : -1;
|
|
1207
|
+
if (openIdx === -1 && selfIdx === -1) {
|
|
1208
|
+
return null;
|
|
1209
|
+
}
|
|
1210
|
+
const isSelfClosing = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx);
|
|
1211
|
+
return {
|
|
1212
|
+
tagStart: isSelfClosing ? selfIdx : openIdx,
|
|
1213
|
+
isSelfClosing,
|
|
1214
|
+
tagLength: isSelfClosing ? (_b = selfMatch == null ? void 0 : selfMatch.length) != null ? _b : 0 : startTag.length
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
function findEarliestToolTag(buffer, toolNames) {
|
|
1218
|
+
var _a, _b;
|
|
1219
|
+
let bestIndex = -1;
|
|
1220
|
+
let bestName = "";
|
|
1221
|
+
let bestSelfClosing = false;
|
|
1222
|
+
let bestTagLength = 0;
|
|
1223
|
+
for (const name of toolNames) {
|
|
1224
|
+
const openTag = `<${name}>`;
|
|
1225
|
+
const idxOpen = buffer.indexOf(openTag);
|
|
1226
|
+
const selfMatch = findSelfClosingTag(buffer, name, 0);
|
|
1227
|
+
const idxSelf = (_a = selfMatch == null ? void 0 : selfMatch.index) != null ? _a : -1;
|
|
1228
|
+
if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
|
|
1229
|
+
bestIndex = idxOpen;
|
|
1230
|
+
bestName = name;
|
|
1231
|
+
bestSelfClosing = false;
|
|
1232
|
+
bestTagLength = openTag.length;
|
|
1233
|
+
}
|
|
1234
|
+
if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
|
|
1235
|
+
bestIndex = idxSelf;
|
|
1236
|
+
bestName = name;
|
|
1237
|
+
bestSelfClosing = true;
|
|
1238
|
+
bestTagLength = (_b = selfMatch == null ? void 0 : selfMatch.length) != null ? _b : 0;
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
return {
|
|
1242
|
+
index: bestIndex,
|
|
1243
|
+
name: bestName,
|
|
1244
|
+
selfClosing: bestSelfClosing,
|
|
1245
|
+
tagLength: bestTagLength
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// src/core/protocols/morph-xml-stream-state-machine.ts
|
|
1250
|
+
function processToolCallInBuffer(params) {
|
|
1251
|
+
const {
|
|
1252
|
+
buffer,
|
|
1253
|
+
currentToolCall,
|
|
1254
|
+
tools,
|
|
1255
|
+
options,
|
|
1256
|
+
controller,
|
|
1257
|
+
flushText,
|
|
1258
|
+
setBuffer,
|
|
1259
|
+
parseOptions,
|
|
1260
|
+
emitToolInputProgress: emitToolInputProgress2,
|
|
1261
|
+
handleStreamingToolCallEnd: handleStreamingToolCallEnd2
|
|
1262
|
+
} = params;
|
|
1263
|
+
const endTagPattern = new RegExp(
|
|
1264
|
+
`</\\s*${escapeRegExp(currentToolCall.name)}\\s*>`
|
|
1265
|
+
);
|
|
1266
|
+
const endMatch = endTagPattern.exec(buffer);
|
|
1267
|
+
if (!endMatch || endMatch.index === void 0) {
|
|
1268
|
+
emitToolInputProgress2(controller, currentToolCall, buffer);
|
|
1269
|
+
return { buffer, currentToolCall, shouldBreak: true };
|
|
1270
|
+
}
|
|
1271
|
+
const endIdx = endMatch.index;
|
|
1272
|
+
const endPos = endIdx + endMatch[0].length;
|
|
1273
|
+
const content = buffer.substring(0, endIdx);
|
|
1274
|
+
emitToolInputProgress2(controller, currentToolCall, content);
|
|
1275
|
+
const remainder = buffer.substring(endPos);
|
|
1276
|
+
setBuffer(remainder);
|
|
1277
|
+
handleStreamingToolCallEnd2({
|
|
1278
|
+
toolContent: content,
|
|
1279
|
+
currentToolCall,
|
|
1280
|
+
tools,
|
|
1281
|
+
options,
|
|
1282
|
+
ctrl: controller,
|
|
1283
|
+
flushText,
|
|
1284
|
+
parseOptions
|
|
1285
|
+
});
|
|
1286
|
+
return {
|
|
1287
|
+
buffer: remainder,
|
|
1288
|
+
currentToolCall: null,
|
|
1289
|
+
shouldBreak: false
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
function processNoToolCallInBuffer(params) {
|
|
1293
|
+
const {
|
|
1294
|
+
buffer,
|
|
1295
|
+
toolNames,
|
|
1296
|
+
controller,
|
|
1297
|
+
flushText,
|
|
1298
|
+
tools,
|
|
1299
|
+
options,
|
|
1300
|
+
parseOptions,
|
|
1301
|
+
setBuffer,
|
|
1302
|
+
emitToolInputStart,
|
|
1303
|
+
findPotentialToolTagStart: findPotentialToolTagStart2,
|
|
1304
|
+
handleStreamingToolCallEnd: handleStreamingToolCallEnd2
|
|
1305
|
+
} = params;
|
|
1306
|
+
const {
|
|
1307
|
+
index: earliestStartTagIndex,
|
|
1308
|
+
name: earliestToolName,
|
|
1309
|
+
selfClosing,
|
|
1310
|
+
tagLength
|
|
1311
|
+
} = findEarliestToolTag(buffer, toolNames);
|
|
1312
|
+
if (earliestStartTagIndex === -1) {
|
|
1313
|
+
const potentialStart = findPotentialToolTagStart2(buffer, toolNames);
|
|
1314
|
+
const safeLen = Math.max(
|
|
1315
|
+
0,
|
|
1316
|
+
potentialStart === -1 ? buffer.length : potentialStart
|
|
1317
|
+
);
|
|
1318
|
+
const remaining = buffer.slice(safeLen);
|
|
1319
|
+
if (safeLen > 0) {
|
|
1320
|
+
flushText(controller, buffer.slice(0, safeLen));
|
|
1321
|
+
setBuffer(remaining);
|
|
1322
|
+
}
|
|
1323
|
+
return {
|
|
1324
|
+
buffer: remaining,
|
|
1325
|
+
currentToolCall: null,
|
|
1326
|
+
shouldBreak: true,
|
|
1327
|
+
shouldContinue: false
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
flushText(controller, buffer.substring(0, earliestStartTagIndex));
|
|
1331
|
+
if (selfClosing) {
|
|
1332
|
+
const newBuffer2 = buffer.substring(earliestStartTagIndex + tagLength);
|
|
1333
|
+
setBuffer(newBuffer2);
|
|
1334
|
+
const currentToolCall = emitToolInputStart(controller, earliestToolName);
|
|
1335
|
+
handleStreamingToolCallEnd2({
|
|
1336
|
+
toolContent: "",
|
|
1337
|
+
currentToolCall,
|
|
1338
|
+
tools,
|
|
1339
|
+
options,
|
|
1340
|
+
ctrl: controller,
|
|
1341
|
+
flushText,
|
|
1342
|
+
parseOptions
|
|
1343
|
+
});
|
|
1344
|
+
return {
|
|
1345
|
+
buffer: newBuffer2,
|
|
1346
|
+
currentToolCall: null,
|
|
1347
|
+
shouldBreak: false,
|
|
1348
|
+
shouldContinue: false
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
const startTag = `<${earliestToolName}>`;
|
|
1352
|
+
const newBuffer = buffer.substring(earliestStartTagIndex + startTag.length);
|
|
1353
|
+
setBuffer(newBuffer);
|
|
1354
|
+
return {
|
|
1355
|
+
buffer: newBuffer,
|
|
1356
|
+
currentToolCall: emitToolInputStart(controller, earliestToolName),
|
|
1357
|
+
shouldBreak: false,
|
|
1358
|
+
shouldContinue: true
|
|
1359
|
+
};
|
|
1360
|
+
}
|
|
1361
|
+
function createProcessBufferHandler(options) {
|
|
1362
|
+
return (controller) => {
|
|
1363
|
+
while (true) {
|
|
1364
|
+
const currentToolCall = options.getCurrentToolCall();
|
|
1365
|
+
if (currentToolCall) {
|
|
1366
|
+
const result = processToolCallInBuffer({
|
|
1367
|
+
buffer: options.getBuffer(),
|
|
1368
|
+
currentToolCall,
|
|
1369
|
+
tools: options.tools,
|
|
1370
|
+
options: options.parserOptions,
|
|
1371
|
+
controller,
|
|
1372
|
+
flushText: options.flushText,
|
|
1373
|
+
setBuffer: options.setBuffer,
|
|
1374
|
+
parseOptions: options.parseOptions,
|
|
1375
|
+
emitToolInputProgress: options.emitToolInputProgress,
|
|
1376
|
+
handleStreamingToolCallEnd: options.handleStreamingToolCallEnd
|
|
1377
|
+
});
|
|
1378
|
+
options.setBuffer(result.buffer);
|
|
1379
|
+
options.setCurrentToolCall(result.currentToolCall);
|
|
1380
|
+
if (result.shouldBreak) {
|
|
1381
|
+
break;
|
|
1382
|
+
}
|
|
1383
|
+
} else {
|
|
1384
|
+
const result = processNoToolCallInBuffer({
|
|
1385
|
+
buffer: options.getBuffer(),
|
|
1386
|
+
toolNames: options.toolNames,
|
|
1387
|
+
controller,
|
|
1388
|
+
flushText: options.flushText,
|
|
1389
|
+
tools: options.tools,
|
|
1390
|
+
options: options.parserOptions,
|
|
1391
|
+
parseOptions: options.parseOptions,
|
|
1392
|
+
setBuffer: options.setBuffer,
|
|
1393
|
+
emitToolInputStart: options.emitToolInputStart,
|
|
1394
|
+
findPotentialToolTagStart: options.findPotentialToolTagStart,
|
|
1395
|
+
handleStreamingToolCallEnd: options.handleStreamingToolCallEnd
|
|
1396
|
+
});
|
|
1397
|
+
options.setBuffer(result.buffer);
|
|
1398
|
+
options.setCurrentToolCall(result.currentToolCall);
|
|
1399
|
+
if (result.shouldBreak) {
|
|
1400
|
+
break;
|
|
1401
|
+
}
|
|
1402
|
+
if (result.shouldContinue) {
|
|
1403
|
+
continue;
|
|
1404
|
+
}
|
|
1405
|
+
break;
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
// src/core/protocols/morph-xml-protocol.ts
|
|
1412
|
+
function getToolSchema(tools, toolName) {
|
|
1413
|
+
var _a;
|
|
1414
|
+
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
1415
|
+
}
|
|
1416
|
+
function processToolCall(params) {
|
|
1417
|
+
var _a, _b;
|
|
1418
|
+
const { toolCall, tools, options, text, processedElements, parseOptions } = params;
|
|
1419
|
+
const toolSchema = getToolSchema(tools, toolCall.toolName);
|
|
1027
1420
|
const parseConfig = {
|
|
1028
1421
|
...parseOptions != null ? parseOptions : {},
|
|
1029
1422
|
onError: (_a = options == null ? void 0 : options.onError) != null ? _a : parseOptions == null ? void 0 : parseOptions.onError
|
|
@@ -1248,6 +1641,76 @@ function schemaAllowsArrayType(schema) {
|
|
|
1248
1641
|
}
|
|
1249
1642
|
return false;
|
|
1250
1643
|
}
|
|
1644
|
+
function schemaAllowsStringType(schema) {
|
|
1645
|
+
if (!schema || typeof schema !== "object") {
|
|
1646
|
+
return false;
|
|
1647
|
+
}
|
|
1648
|
+
const schemaRecord = schema;
|
|
1649
|
+
const typeValue = schemaRecord.type;
|
|
1650
|
+
if (typeValue === "string") {
|
|
1651
|
+
return true;
|
|
1652
|
+
}
|
|
1653
|
+
if (Array.isArray(typeValue) && typeValue.includes("string")) {
|
|
1654
|
+
return true;
|
|
1655
|
+
}
|
|
1656
|
+
const unions = [schemaRecord.anyOf, schemaRecord.oneOf, schemaRecord.allOf];
|
|
1657
|
+
for (const union of unions) {
|
|
1658
|
+
if (!Array.isArray(union)) {
|
|
1659
|
+
continue;
|
|
1660
|
+
}
|
|
1661
|
+
if (union.some((entry) => schemaAllowsStringType(entry))) {
|
|
1662
|
+
return true;
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
return false;
|
|
1666
|
+
}
|
|
1667
|
+
function getObjectSchemaStringPropertyNames(schema) {
|
|
1668
|
+
const propertyNames = getObjectSchemaPropertyNames(schema);
|
|
1669
|
+
if (!propertyNames) {
|
|
1670
|
+
return null;
|
|
1671
|
+
}
|
|
1672
|
+
const out = /* @__PURE__ */ new Set();
|
|
1673
|
+
for (const name of propertyNames) {
|
|
1674
|
+
const property = getSchemaObjectProperty(schema, name);
|
|
1675
|
+
if (schemaAllowsStringType(property)) {
|
|
1676
|
+
out.add(name);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
return out;
|
|
1680
|
+
}
|
|
1681
|
+
function findTrailingUnclosedStringTag(options) {
|
|
1682
|
+
let bestName = null;
|
|
1683
|
+
let bestOpenIndex = -1;
|
|
1684
|
+
for (const name of options.stringPropertyNames) {
|
|
1685
|
+
const openPattern = new RegExp(
|
|
1686
|
+
`<${escapeRegExp(name)}(?:\\s[^>]*)?>`,
|
|
1687
|
+
"gi"
|
|
1688
|
+
);
|
|
1689
|
+
const closePattern = new RegExp(`</\\s*${escapeRegExp(name)}\\s*>`, "gi");
|
|
1690
|
+
let lastOpen = -1;
|
|
1691
|
+
for (const match of options.toolContent.matchAll(openPattern)) {
|
|
1692
|
+
const index = match.index;
|
|
1693
|
+
if (index !== void 0) {
|
|
1694
|
+
lastOpen = index;
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
if (lastOpen === -1) {
|
|
1698
|
+
continue;
|
|
1699
|
+
}
|
|
1700
|
+
let lastClose = -1;
|
|
1701
|
+
for (const match of options.toolContent.matchAll(closePattern)) {
|
|
1702
|
+
const index = match.index;
|
|
1703
|
+
if (index !== void 0) {
|
|
1704
|
+
lastClose = index;
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
if (lastOpen > lastClose && lastOpen > bestOpenIndex) {
|
|
1708
|
+
bestOpenIndex = lastOpen;
|
|
1709
|
+
bestName = name;
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
return bestName;
|
|
1713
|
+
}
|
|
1251
1714
|
function getSchemaObjectProperty(schema, propertyName) {
|
|
1252
1715
|
if (!schema || typeof schema !== "object") {
|
|
1253
1716
|
return null;
|
|
@@ -1297,8 +1760,10 @@ function isStableXmlProgressCandidate(options) {
|
|
|
1297
1760
|
}
|
|
1298
1761
|
function parseXmlContentForStreamProgress({
|
|
1299
1762
|
toolContent,
|
|
1763
|
+
toolName,
|
|
1300
1764
|
toolSchema,
|
|
1301
|
-
parseOptions
|
|
1765
|
+
parseOptions,
|
|
1766
|
+
tools
|
|
1302
1767
|
}) {
|
|
1303
1768
|
const tryParse = (content) => {
|
|
1304
1769
|
try {
|
|
@@ -1317,7 +1782,29 @@ function parseXmlContentForStreamProgress({
|
|
|
1317
1782
|
parsed: strictFull,
|
|
1318
1783
|
toolSchema
|
|
1319
1784
|
})) {
|
|
1320
|
-
return
|
|
1785
|
+
return stringifyToolInputWithSchema({
|
|
1786
|
+
toolName,
|
|
1787
|
+
args: strictFull,
|
|
1788
|
+
tools
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1791
|
+
const stringPropertyNames = getObjectSchemaStringPropertyNames(toolSchema);
|
|
1792
|
+
if (stringPropertyNames && stringPropertyNames.size > 0) {
|
|
1793
|
+
const trailingStringTag = findTrailingUnclosedStringTag({
|
|
1794
|
+
toolContent,
|
|
1795
|
+
stringPropertyNames
|
|
1796
|
+
});
|
|
1797
|
+
if (trailingStringTag) {
|
|
1798
|
+
const repaired = `${toolContent}</${trailingStringTag}>`;
|
|
1799
|
+
const parsedRepaired = tryParse(repaired);
|
|
1800
|
+
if (parsedRepaired !== null) {
|
|
1801
|
+
return stringifyToolInputWithSchema({
|
|
1802
|
+
toolName,
|
|
1803
|
+
args: parsedRepaired,
|
|
1804
|
+
tools
|
|
1805
|
+
});
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1321
1808
|
}
|
|
1322
1809
|
let searchEnd = toolContent.length;
|
|
1323
1810
|
while (searchEnd > 0) {
|
|
@@ -1336,7 +1823,11 @@ function parseXmlContentForStreamProgress({
|
|
|
1336
1823
|
parsed: parsedCandidate,
|
|
1337
1824
|
toolSchema
|
|
1338
1825
|
})) {
|
|
1339
|
-
return
|
|
1826
|
+
return stringifyToolInputWithSchema({
|
|
1827
|
+
toolName,
|
|
1828
|
+
args: parsedCandidate,
|
|
1829
|
+
tools
|
|
1830
|
+
});
|
|
1340
1831
|
}
|
|
1341
1832
|
searchEnd = gtIndex;
|
|
1342
1833
|
}
|
|
@@ -1361,37 +1852,35 @@ function handleStreamingToolCallEnd(params) {
|
|
|
1361
1852
|
flushText(ctrl);
|
|
1362
1853
|
try {
|
|
1363
1854
|
const parsedResult = parse2(toolContent, toolSchema, parseConfig);
|
|
1364
|
-
const finalInput =
|
|
1365
|
-
|
|
1855
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
1856
|
+
toolName: currentToolCall.name,
|
|
1857
|
+
args: parsedResult,
|
|
1858
|
+
tools
|
|
1859
|
+
});
|
|
1860
|
+
emitFinalizedToolInputLifecycle({
|
|
1366
1861
|
controller: ctrl,
|
|
1367
1862
|
id: currentToolCall.toolCallId,
|
|
1368
1863
|
state: currentToolCall,
|
|
1369
|
-
finalFullJson: finalInput,
|
|
1370
|
-
onMismatch: options == null ? void 0 : options.onError
|
|
1371
|
-
});
|
|
1372
|
-
ctrl.enqueue({
|
|
1373
|
-
type: "tool-input-end",
|
|
1374
|
-
id: currentToolCall.toolCallId
|
|
1375
|
-
});
|
|
1376
|
-
ctrl.enqueue({
|
|
1377
|
-
type: "tool-call",
|
|
1378
|
-
toolCallId: currentToolCall.toolCallId,
|
|
1379
1864
|
toolName: currentToolCall.name,
|
|
1380
|
-
|
|
1865
|
+
finalInput,
|
|
1866
|
+
onMismatch: options == null ? void 0 : options.onError
|
|
1381
1867
|
});
|
|
1382
1868
|
} catch (error) {
|
|
1383
|
-
ctrl.enqueue({
|
|
1384
|
-
type: "tool-input-end",
|
|
1385
|
-
id: currentToolCall.toolCallId
|
|
1386
|
-
});
|
|
1387
1869
|
const original = `<${currentToolCall.name}>${toolContent}</${currentToolCall.name}>`;
|
|
1870
|
+
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
1871
|
+
emitFailedToolInputLifecycle({
|
|
1872
|
+
controller: ctrl,
|
|
1873
|
+
id: currentToolCall.toolCallId,
|
|
1874
|
+
emitRawToolCallTextOnError: emitRawFallback,
|
|
1875
|
+
rawToolCallText: original,
|
|
1876
|
+
emitRawText: (rawText) => {
|
|
1877
|
+
flushText(ctrl, rawText);
|
|
1878
|
+
}
|
|
1879
|
+
});
|
|
1388
1880
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, "Could not process streaming XML tool call", {
|
|
1389
1881
|
toolCall: original,
|
|
1390
1882
|
error
|
|
1391
1883
|
});
|
|
1392
|
-
if (shouldEmitRawToolCallTextOnError2(options)) {
|
|
1393
|
-
flushText(ctrl, original);
|
|
1394
|
-
}
|
|
1395
1884
|
}
|
|
1396
1885
|
}
|
|
1397
1886
|
function findClosingTagEndFlexible(text, contentStart, toolName) {
|
|
@@ -1491,22 +1980,6 @@ function nextTagToken(text, fromPos) {
|
|
|
1491
1980
|
nextPos: open.nextPos
|
|
1492
1981
|
};
|
|
1493
1982
|
}
|
|
1494
|
-
function findNextToolTag(text, searchIndex, toolName) {
|
|
1495
|
-
var _a, _b;
|
|
1496
|
-
const startTag = `<${toolName}>`;
|
|
1497
|
-
const openIdx = text.indexOf(startTag, searchIndex);
|
|
1498
|
-
const selfMatch = findSelfClosingTag(text, toolName, searchIndex);
|
|
1499
|
-
const selfIdx = (_a = selfMatch == null ? void 0 : selfMatch.index) != null ? _a : -1;
|
|
1500
|
-
if (openIdx === -1 && selfIdx === -1) {
|
|
1501
|
-
return null;
|
|
1502
|
-
}
|
|
1503
|
-
const isSelfClosing = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx);
|
|
1504
|
-
return {
|
|
1505
|
-
tagStart: isSelfClosing ? selfIdx : openIdx,
|
|
1506
|
-
isSelfClosing,
|
|
1507
|
-
tagLength: isSelfClosing ? (_b = selfMatch == null ? void 0 : selfMatch.length) != null ? _b : 0 : startTag.length
|
|
1508
|
-
};
|
|
1509
|
-
}
|
|
1510
1983
|
function findLastCloseTagStart(segment, toolName) {
|
|
1511
1984
|
const closeTagPattern = new RegExp(
|
|
1512
1985
|
`</\\s*${escapeRegExp(toolName)}\\s*>`,
|
|
@@ -1534,24 +2007,6 @@ function pushSelfClosingToolCall(toolCalls, toolName, text, tagStart, tagLength)
|
|
|
1534
2007
|
});
|
|
1535
2008
|
return endIndex;
|
|
1536
2009
|
}
|
|
1537
|
-
var selfClosingTagCache = /* @__PURE__ */ new Map();
|
|
1538
|
-
function getSelfClosingTagPattern(toolName) {
|
|
1539
|
-
let pattern = selfClosingTagCache.get(toolName);
|
|
1540
|
-
if (!pattern) {
|
|
1541
|
-
pattern = new RegExp(`<\\s*${escapeRegExp(toolName)}\\s*/>`, "g");
|
|
1542
|
-
selfClosingTagCache.set(toolName, pattern);
|
|
1543
|
-
}
|
|
1544
|
-
return pattern;
|
|
1545
|
-
}
|
|
1546
|
-
function findSelfClosingTag(text, toolName, fromIndex) {
|
|
1547
|
-
const pattern = getSelfClosingTagPattern(toolName);
|
|
1548
|
-
pattern.lastIndex = fromIndex;
|
|
1549
|
-
const match = pattern.exec(text);
|
|
1550
|
-
if (!match || match.index === void 0) {
|
|
1551
|
-
return null;
|
|
1552
|
-
}
|
|
1553
|
-
return { index: match.index, length: match[0].length };
|
|
1554
|
-
}
|
|
1555
2010
|
function appendOpenToolCallIfComplete(toolCalls, text, toolName, tagStart, startTag) {
|
|
1556
2011
|
const contentStart = tagStart + startTag.length;
|
|
1557
2012
|
const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
|
|
@@ -1703,39 +2158,6 @@ function findLinePrefixedToolCall(text, toolNames) {
|
|
|
1703
2158
|
}
|
|
1704
2159
|
return best;
|
|
1705
2160
|
}
|
|
1706
|
-
function findEarliestToolTag(buffer, toolNames) {
|
|
1707
|
-
var _a, _b;
|
|
1708
|
-
let bestIndex = -1;
|
|
1709
|
-
let bestName = "";
|
|
1710
|
-
let bestSelfClosing = false;
|
|
1711
|
-
let bestTagLength = 0;
|
|
1712
|
-
if (toolNames.length > 0) {
|
|
1713
|
-
for (const name of toolNames) {
|
|
1714
|
-
const openTag = `<${name}>`;
|
|
1715
|
-
const idxOpen = buffer.indexOf(openTag);
|
|
1716
|
-
const selfMatch = findSelfClosingTag(buffer, name, 0);
|
|
1717
|
-
const idxSelf = (_a = selfMatch == null ? void 0 : selfMatch.index) != null ? _a : -1;
|
|
1718
|
-
if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
|
|
1719
|
-
bestIndex = idxOpen;
|
|
1720
|
-
bestName = name;
|
|
1721
|
-
bestSelfClosing = false;
|
|
1722
|
-
bestTagLength = openTag.length;
|
|
1723
|
-
}
|
|
1724
|
-
if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
|
|
1725
|
-
bestIndex = idxSelf;
|
|
1726
|
-
bestName = name;
|
|
1727
|
-
bestSelfClosing = true;
|
|
1728
|
-
bestTagLength = (_b = selfMatch == null ? void 0 : selfMatch.length) != null ? _b : 0;
|
|
1729
|
-
}
|
|
1730
|
-
}
|
|
1731
|
-
}
|
|
1732
|
-
return {
|
|
1733
|
-
index: bestIndex,
|
|
1734
|
-
name: bestName,
|
|
1735
|
-
selfClosing: bestSelfClosing,
|
|
1736
|
-
tagLength: bestTagLength
|
|
1737
|
-
};
|
|
1738
|
-
}
|
|
1739
2161
|
function isOpenTagPrefix(suffix, toolName) {
|
|
1740
2162
|
return `${toolName}>`.startsWith(suffix);
|
|
1741
2163
|
}
|
|
@@ -1813,160 +2235,6 @@ function findPotentialToolTagStart(buffer, toolNames) {
|
|
|
1813
2235
|
}
|
|
1814
2236
|
return -1;
|
|
1815
2237
|
}
|
|
1816
|
-
function processToolCallInBuffer(params) {
|
|
1817
|
-
const {
|
|
1818
|
-
buffer,
|
|
1819
|
-
currentToolCall,
|
|
1820
|
-
tools,
|
|
1821
|
-
options,
|
|
1822
|
-
controller,
|
|
1823
|
-
flushText,
|
|
1824
|
-
setBuffer,
|
|
1825
|
-
parseOptions,
|
|
1826
|
-
emitToolInputProgress: emitToolInputProgress2
|
|
1827
|
-
} = params;
|
|
1828
|
-
const endTagPattern = new RegExp(
|
|
1829
|
-
`</\\s*${escapeRegExp(currentToolCall.name)}\\s*>`
|
|
1830
|
-
);
|
|
1831
|
-
const endMatch = endTagPattern.exec(buffer);
|
|
1832
|
-
if (!endMatch || endMatch.index === void 0) {
|
|
1833
|
-
emitToolInputProgress2(controller, currentToolCall, buffer);
|
|
1834
|
-
return { buffer, currentToolCall, shouldBreak: true };
|
|
1835
|
-
}
|
|
1836
|
-
const endIdx = endMatch.index;
|
|
1837
|
-
const endPos = endIdx + endMatch[0].length;
|
|
1838
|
-
const content = buffer.substring(0, endIdx);
|
|
1839
|
-
emitToolInputProgress2(controller, currentToolCall, content);
|
|
1840
|
-
const remainder = buffer.substring(endPos);
|
|
1841
|
-
setBuffer(remainder);
|
|
1842
|
-
handleStreamingToolCallEnd({
|
|
1843
|
-
toolContent: content,
|
|
1844
|
-
currentToolCall,
|
|
1845
|
-
tools,
|
|
1846
|
-
options,
|
|
1847
|
-
ctrl: controller,
|
|
1848
|
-
flushText,
|
|
1849
|
-
parseOptions
|
|
1850
|
-
});
|
|
1851
|
-
return {
|
|
1852
|
-
buffer: remainder,
|
|
1853
|
-
currentToolCall: null,
|
|
1854
|
-
shouldBreak: false
|
|
1855
|
-
};
|
|
1856
|
-
}
|
|
1857
|
-
function processNoToolCallInBuffer(params) {
|
|
1858
|
-
const {
|
|
1859
|
-
buffer,
|
|
1860
|
-
toolNames,
|
|
1861
|
-
controller,
|
|
1862
|
-
flushText,
|
|
1863
|
-
tools,
|
|
1864
|
-
options,
|
|
1865
|
-
parseOptions,
|
|
1866
|
-
setBuffer,
|
|
1867
|
-
emitToolInputStart
|
|
1868
|
-
} = params;
|
|
1869
|
-
const {
|
|
1870
|
-
index: earliestStartTagIndex,
|
|
1871
|
-
name: earliestToolName,
|
|
1872
|
-
selfClosing,
|
|
1873
|
-
tagLength
|
|
1874
|
-
} = findEarliestToolTag(buffer, toolNames);
|
|
1875
|
-
if (earliestStartTagIndex === -1) {
|
|
1876
|
-
const potentialStart = findPotentialToolTagStart(buffer, toolNames);
|
|
1877
|
-
const safeLen = Math.max(
|
|
1878
|
-
0,
|
|
1879
|
-
potentialStart === -1 ? buffer.length : potentialStart
|
|
1880
|
-
);
|
|
1881
|
-
const remaining = buffer.slice(safeLen);
|
|
1882
|
-
if (safeLen > 0) {
|
|
1883
|
-
flushText(controller, buffer.slice(0, safeLen));
|
|
1884
|
-
setBuffer(remaining);
|
|
1885
|
-
}
|
|
1886
|
-
return {
|
|
1887
|
-
buffer: remaining,
|
|
1888
|
-
currentToolCall: null,
|
|
1889
|
-
shouldBreak: true,
|
|
1890
|
-
shouldContinue: false
|
|
1891
|
-
};
|
|
1892
|
-
}
|
|
1893
|
-
flushText(controller, buffer.substring(0, earliestStartTagIndex));
|
|
1894
|
-
if (selfClosing) {
|
|
1895
|
-
const newBuffer2 = buffer.substring(earliestStartTagIndex + tagLength);
|
|
1896
|
-
setBuffer(newBuffer2);
|
|
1897
|
-
const currentToolCall = emitToolInputStart(controller, earliestToolName);
|
|
1898
|
-
handleStreamingToolCallEnd({
|
|
1899
|
-
toolContent: "",
|
|
1900
|
-
currentToolCall,
|
|
1901
|
-
tools,
|
|
1902
|
-
options,
|
|
1903
|
-
ctrl: controller,
|
|
1904
|
-
flushText,
|
|
1905
|
-
parseOptions
|
|
1906
|
-
});
|
|
1907
|
-
return {
|
|
1908
|
-
buffer: newBuffer2,
|
|
1909
|
-
currentToolCall: null,
|
|
1910
|
-
shouldBreak: false,
|
|
1911
|
-
shouldContinue: false
|
|
1912
|
-
};
|
|
1913
|
-
}
|
|
1914
|
-
const startTag = `<${earliestToolName}>`;
|
|
1915
|
-
const newBuffer = buffer.substring(earliestStartTagIndex + startTag.length);
|
|
1916
|
-
setBuffer(newBuffer);
|
|
1917
|
-
return {
|
|
1918
|
-
buffer: newBuffer,
|
|
1919
|
-
currentToolCall: emitToolInputStart(controller, earliestToolName),
|
|
1920
|
-
shouldBreak: false,
|
|
1921
|
-
shouldContinue: true
|
|
1922
|
-
};
|
|
1923
|
-
}
|
|
1924
|
-
function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, setCurrentToolCall, tools, options, toolNames, flushText, parseOptions, emitToolInputProgress2, emitToolInputStart) {
|
|
1925
|
-
return (controller) => {
|
|
1926
|
-
while (true) {
|
|
1927
|
-
const currentToolCall = getCurrentToolCall();
|
|
1928
|
-
if (currentToolCall) {
|
|
1929
|
-
const result = processToolCallInBuffer({
|
|
1930
|
-
buffer: getBuffer(),
|
|
1931
|
-
currentToolCall,
|
|
1932
|
-
tools,
|
|
1933
|
-
options,
|
|
1934
|
-
controller,
|
|
1935
|
-
flushText,
|
|
1936
|
-
setBuffer,
|
|
1937
|
-
parseOptions,
|
|
1938
|
-
emitToolInputProgress: emitToolInputProgress2
|
|
1939
|
-
});
|
|
1940
|
-
setBuffer(result.buffer);
|
|
1941
|
-
setCurrentToolCall(result.currentToolCall);
|
|
1942
|
-
if (result.shouldBreak) {
|
|
1943
|
-
break;
|
|
1944
|
-
}
|
|
1945
|
-
} else {
|
|
1946
|
-
const result = processNoToolCallInBuffer({
|
|
1947
|
-
buffer: getBuffer(),
|
|
1948
|
-
toolNames,
|
|
1949
|
-
controller,
|
|
1950
|
-
flushText,
|
|
1951
|
-
tools,
|
|
1952
|
-
options,
|
|
1953
|
-
parseOptions,
|
|
1954
|
-
setBuffer,
|
|
1955
|
-
emitToolInputStart
|
|
1956
|
-
});
|
|
1957
|
-
setBuffer(result.buffer);
|
|
1958
|
-
setCurrentToolCall(result.currentToolCall);
|
|
1959
|
-
if (result.shouldBreak) {
|
|
1960
|
-
break;
|
|
1961
|
-
}
|
|
1962
|
-
if (result.shouldContinue) {
|
|
1963
|
-
continue;
|
|
1964
|
-
}
|
|
1965
|
-
break;
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
};
|
|
1969
|
-
}
|
|
1970
2238
|
function findToolCallsWithFallbacks(text, toolNames) {
|
|
1971
2239
|
let parseText = text;
|
|
1972
2240
|
let toolCalls = findToolCalls(parseText, toolNames);
|
|
@@ -1988,7 +2256,7 @@ function findToolCallsWithFallbacks(text, toolNames) {
|
|
|
1988
2256
|
}
|
|
1989
2257
|
return { parseText, toolCalls };
|
|
1990
2258
|
}
|
|
1991
|
-
var
|
|
2259
|
+
var morphXmlProtocol = (protocolOptions) => {
|
|
1992
2260
|
var _a;
|
|
1993
2261
|
const parseOptions = {
|
|
1994
2262
|
repair: true,
|
|
@@ -1997,7 +2265,7 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
1997
2265
|
};
|
|
1998
2266
|
return {
|
|
1999
2267
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
2000
|
-
return
|
|
2268
|
+
return formatToolsWithPromptTemplate({ tools, toolSystemPromptTemplate });
|
|
2001
2269
|
},
|
|
2002
2270
|
formatToolCall(toolCall) {
|
|
2003
2271
|
let args = {};
|
|
@@ -2015,7 +2283,7 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
2015
2283
|
});
|
|
2016
2284
|
},
|
|
2017
2285
|
parseGeneratedText({ text, tools, options }) {
|
|
2018
|
-
const toolNames = tools
|
|
2286
|
+
const toolNames = extractToolNames(tools);
|
|
2019
2287
|
if (toolNames.length === 0) {
|
|
2020
2288
|
return [{ type: "text", text }];
|
|
2021
2289
|
}
|
|
@@ -2051,7 +2319,7 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
2051
2319
|
return processedElements;
|
|
2052
2320
|
},
|
|
2053
2321
|
createStreamParser({ tools, options }) {
|
|
2054
|
-
const toolNames = tools
|
|
2322
|
+
const toolNames = extractToolNames(tools);
|
|
2055
2323
|
let buffer = "";
|
|
2056
2324
|
let currentToolCall = null;
|
|
2057
2325
|
let currentTextId = null;
|
|
@@ -2072,6 +2340,7 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
2072
2340
|
name: toolName,
|
|
2073
2341
|
toolCallId: generateToolCallId(),
|
|
2074
2342
|
emittedInput: "",
|
|
2343
|
+
lastProgressContentLength: null,
|
|
2075
2344
|
lastProgressGtIndex: null,
|
|
2076
2345
|
lastProgressFullInput: null
|
|
2077
2346
|
};
|
|
@@ -2084,7 +2353,8 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
2084
2353
|
};
|
|
2085
2354
|
const emitToolInputProgress2 = (controller, toolCall, toolContent) => {
|
|
2086
2355
|
const progressGtIndex = toolContent.lastIndexOf(">");
|
|
2087
|
-
|
|
2356
|
+
const progressContentLength = toolContent.length;
|
|
2357
|
+
if (toolCall.lastProgressGtIndex === progressGtIndex && toolCall.lastProgressContentLength === progressContentLength) {
|
|
2088
2358
|
const cached = toolCall.lastProgressFullInput;
|
|
2089
2359
|
if (cached == null) {
|
|
2090
2360
|
return;
|
|
@@ -2092,22 +2362,24 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
2092
2362
|
if (cached === "{}" && toolContent.trim().length === 0) {
|
|
2093
2363
|
return;
|
|
2094
2364
|
}
|
|
2095
|
-
|
|
2096
|
-
emitPrefixDelta({
|
|
2365
|
+
emitToolInputProgressDelta({
|
|
2097
2366
|
controller,
|
|
2098
2367
|
id: toolCall.toolCallId,
|
|
2099
2368
|
state: toolCall,
|
|
2100
|
-
|
|
2369
|
+
fullInput: cached
|
|
2101
2370
|
});
|
|
2102
2371
|
return;
|
|
2103
2372
|
}
|
|
2104
2373
|
const toolSchema = getToolSchema(tools, toolCall.name);
|
|
2105
2374
|
const fullInput = parseXmlContentForStreamProgress({
|
|
2106
2375
|
toolContent,
|
|
2376
|
+
toolName: toolCall.name,
|
|
2107
2377
|
toolSchema,
|
|
2108
|
-
parseOptions
|
|
2378
|
+
parseOptions,
|
|
2379
|
+
tools
|
|
2109
2380
|
});
|
|
2110
2381
|
toolCall.lastProgressGtIndex = progressGtIndex;
|
|
2382
|
+
toolCall.lastProgressContentLength = progressContentLength;
|
|
2111
2383
|
toolCall.lastProgressFullInput = fullInput;
|
|
2112
2384
|
if (fullInput == null) {
|
|
2113
2385
|
return;
|
|
@@ -2115,12 +2387,11 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
2115
2387
|
if (fullInput === "{}" && toolContent.trim().length === 0) {
|
|
2116
2388
|
return;
|
|
2117
2389
|
}
|
|
2118
|
-
|
|
2119
|
-
emitPrefixDelta({
|
|
2390
|
+
emitToolInputProgressDelta({
|
|
2120
2391
|
controller,
|
|
2121
2392
|
id: toolCall.toolCallId,
|
|
2122
2393
|
state: toolCall,
|
|
2123
|
-
|
|
2394
|
+
fullInput
|
|
2124
2395
|
});
|
|
2125
2396
|
};
|
|
2126
2397
|
const finalizeUnclosedToolCall = (controller) => {
|
|
@@ -2142,59 +2413,59 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
2142
2413
|
);
|
|
2143
2414
|
}
|
|
2144
2415
|
const parsedResult = parse2(buffer, toolSchema, parseConfig);
|
|
2145
|
-
const finalInput =
|
|
2146
|
-
|
|
2416
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
2417
|
+
toolName: currentToolCall.name,
|
|
2418
|
+
args: parsedResult,
|
|
2419
|
+
tools
|
|
2420
|
+
});
|
|
2421
|
+
emitFinalizedToolInputLifecycle({
|
|
2147
2422
|
controller,
|
|
2148
2423
|
id: currentToolCall.toolCallId,
|
|
2149
2424
|
state: currentToolCall,
|
|
2150
|
-
finalFullJson: finalInput,
|
|
2151
|
-
onMismatch: options == null ? void 0 : options.onError
|
|
2152
|
-
});
|
|
2153
|
-
controller.enqueue({
|
|
2154
|
-
type: "tool-input-end",
|
|
2155
|
-
id: currentToolCall.toolCallId
|
|
2156
|
-
});
|
|
2157
|
-
controller.enqueue({
|
|
2158
|
-
type: "tool-call",
|
|
2159
|
-
toolCallId: currentToolCall.toolCallId,
|
|
2160
2425
|
toolName: currentToolCall.name,
|
|
2161
|
-
|
|
2426
|
+
finalInput,
|
|
2427
|
+
onMismatch: options == null ? void 0 : options.onError
|
|
2162
2428
|
});
|
|
2163
2429
|
} catch (error) {
|
|
2164
|
-
controller.enqueue({
|
|
2165
|
-
type: "tool-input-end",
|
|
2166
|
-
id: currentToolCall.toolCallId
|
|
2167
|
-
});
|
|
2168
2430
|
const unfinishedContent = `<${currentToolCall.name}>${buffer}`;
|
|
2431
|
+
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
2432
|
+
emitFailedToolInputLifecycle({
|
|
2433
|
+
controller,
|
|
2434
|
+
id: currentToolCall.toolCallId,
|
|
2435
|
+
emitRawToolCallTextOnError: emitRawFallback,
|
|
2436
|
+
rawToolCallText: unfinishedContent,
|
|
2437
|
+
emitRawText: (rawText) => {
|
|
2438
|
+
flushText(controller, rawText);
|
|
2439
|
+
}
|
|
2440
|
+
});
|
|
2169
2441
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
2170
2442
|
options,
|
|
2171
2443
|
"Could not complete streaming XML tool call at finish.",
|
|
2172
2444
|
{ toolCall: unfinishedContent, error }
|
|
2173
2445
|
);
|
|
2174
|
-
if (shouldEmitRawToolCallTextOnError2(options)) {
|
|
2175
|
-
flushText(controller, unfinishedContent);
|
|
2176
|
-
}
|
|
2177
2446
|
}
|
|
2178
2447
|
buffer = "";
|
|
2179
2448
|
currentToolCall = null;
|
|
2180
2449
|
};
|
|
2181
|
-
const processBuffer = createProcessBufferHandler(
|
|
2182
|
-
() => buffer,
|
|
2183
|
-
(newBuffer) => {
|
|
2450
|
+
const processBuffer = createProcessBufferHandler({
|
|
2451
|
+
getBuffer: () => buffer,
|
|
2452
|
+
setBuffer: (newBuffer) => {
|
|
2184
2453
|
buffer = newBuffer;
|
|
2185
2454
|
},
|
|
2186
|
-
() => currentToolCall,
|
|
2187
|
-
(newToolCall) => {
|
|
2455
|
+
getCurrentToolCall: () => currentToolCall,
|
|
2456
|
+
setCurrentToolCall: (newToolCall) => {
|
|
2188
2457
|
currentToolCall = newToolCall;
|
|
2189
2458
|
},
|
|
2190
2459
|
tools,
|
|
2191
|
-
options,
|
|
2460
|
+
parserOptions: options,
|
|
2192
2461
|
toolNames,
|
|
2193
2462
|
flushText,
|
|
2194
2463
|
parseOptions,
|
|
2195
|
-
emitToolInputProgress2,
|
|
2196
|
-
emitToolInputStart
|
|
2197
|
-
|
|
2464
|
+
emitToolInputProgress: emitToolInputProgress2,
|
|
2465
|
+
emitToolInputStart,
|
|
2466
|
+
findPotentialToolTagStart,
|
|
2467
|
+
handleStreamingToolCallEnd
|
|
2468
|
+
});
|
|
2198
2469
|
return new TransformStream({
|
|
2199
2470
|
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Stateful stream parsing requires branching over chunk lifecycle and parser states.
|
|
2200
2471
|
transform(chunk, controller) {
|
|
@@ -2230,41 +2501,1950 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
2230
2501
|
flushText(controller, buffer);
|
|
2231
2502
|
buffer = "";
|
|
2232
2503
|
}
|
|
2233
|
-
if (currentTextId && hasEmittedTextStart) {
|
|
2234
|
-
controller.enqueue({
|
|
2235
|
-
type: "text-end",
|
|
2236
|
-
id: currentTextId
|
|
2237
|
-
});
|
|
2238
|
-
hasEmittedTextStart = false;
|
|
2239
|
-
currentTextId = null;
|
|
2504
|
+
if (currentTextId && hasEmittedTextStart) {
|
|
2505
|
+
controller.enqueue({
|
|
2506
|
+
type: "text-end",
|
|
2507
|
+
id: currentTextId
|
|
2508
|
+
});
|
|
2509
|
+
hasEmittedTextStart = false;
|
|
2510
|
+
currentTextId = null;
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
});
|
|
2514
|
+
},
|
|
2515
|
+
extractToolCallSegments({ text, tools }) {
|
|
2516
|
+
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
2517
|
+
if (toolNames.length === 0) {
|
|
2518
|
+
return [];
|
|
2519
|
+
}
|
|
2520
|
+
return findToolCalls(text, toolNames).map((tc) => tc.segment);
|
|
2521
|
+
}
|
|
2522
|
+
};
|
|
2523
|
+
};
|
|
2524
|
+
|
|
2525
|
+
// src/core/protocols/protocol-interface.ts
|
|
2526
|
+
function isProtocolFactory(protocol) {
|
|
2527
|
+
return typeof protocol === "function";
|
|
2528
|
+
}
|
|
2529
|
+
var isTCMProtocolFactory = isProtocolFactory;
|
|
2530
|
+
|
|
2531
|
+
// src/core/protocols/qwen3coder-stream-call-content.ts
|
|
2532
|
+
function consumeToolNameTag(options) {
|
|
2533
|
+
var _a, _b, _c, _d;
|
|
2534
|
+
if (options.callState.toolName) {
|
|
2535
|
+
return options.work;
|
|
2536
|
+
}
|
|
2537
|
+
const match = options.nameTagRe.exec(options.work);
|
|
2538
|
+
if (!match) {
|
|
2539
|
+
return options.work;
|
|
2540
|
+
}
|
|
2541
|
+
const value = options.normalizeXmlTextValue((_a = match[2]) != null ? _a : "");
|
|
2542
|
+
if (value.trim().length > 0) {
|
|
2543
|
+
options.callState.toolName = value;
|
|
2544
|
+
}
|
|
2545
|
+
const start = (_b = match.index) != null ? _b : 0;
|
|
2546
|
+
const consumedLength = (_d = (_c = match[0]) == null ? void 0 : _c.length) != null ? _d : 0;
|
|
2547
|
+
const nextWork = options.work.slice(0, start) + options.work.slice(start + consumedLength);
|
|
2548
|
+
options.maybeEmitToolInputStart();
|
|
2549
|
+
return nextWork;
|
|
2550
|
+
}
|
|
2551
|
+
function consumeSingleParamTag(options) {
|
|
2552
|
+
var _a;
|
|
2553
|
+
const parsed = options.parseParamTagAt(
|
|
2554
|
+
options.work,
|
|
2555
|
+
options.lower,
|
|
2556
|
+
options.lt,
|
|
2557
|
+
{
|
|
2558
|
+
allowEndOfString: options.allowEndOfString,
|
|
2559
|
+
callEndTagNameLower: options.callState.endTagName
|
|
2560
|
+
}
|
|
2561
|
+
);
|
|
2562
|
+
if (!parsed) {
|
|
2563
|
+
return {
|
|
2564
|
+
nextIndex: options.lt + 1,
|
|
2565
|
+
nextLastKept: options.lastKept,
|
|
2566
|
+
shouldStop: false
|
|
2567
|
+
};
|
|
2568
|
+
}
|
|
2569
|
+
if (parsed.kind === "partial") {
|
|
2570
|
+
if (parsed.name !== void 0) {
|
|
2571
|
+
options.callState.partialParam = {
|
|
2572
|
+
name: parsed.name,
|
|
2573
|
+
value: (_a = parsed.value) != null ? _a : ""
|
|
2574
|
+
};
|
|
2575
|
+
}
|
|
2576
|
+
return {
|
|
2577
|
+
nextIndex: options.lt + 1,
|
|
2578
|
+
nextLastKept: options.lastKept,
|
|
2579
|
+
shouldStop: true
|
|
2580
|
+
};
|
|
2581
|
+
}
|
|
2582
|
+
options.callState.partialParam = null;
|
|
2583
|
+
options.mergeParamValue(options.callState.args, parsed.name, parsed.value);
|
|
2584
|
+
return {
|
|
2585
|
+
keepSlice: options.work.slice(options.lastKept, parsed.start),
|
|
2586
|
+
nextIndex: parsed.end,
|
|
2587
|
+
nextLastKept: parsed.end,
|
|
2588
|
+
shouldStop: false
|
|
2589
|
+
};
|
|
2590
|
+
}
|
|
2591
|
+
function consumeParamTags(options) {
|
|
2592
|
+
const lower = options.work.toLowerCase();
|
|
2593
|
+
let index = 0;
|
|
2594
|
+
let lastKept = 0;
|
|
2595
|
+
let pieces = null;
|
|
2596
|
+
while (true) {
|
|
2597
|
+
const lt = lower.indexOf("<", index);
|
|
2598
|
+
if (lt === -1) {
|
|
2599
|
+
break;
|
|
2600
|
+
}
|
|
2601
|
+
const step = consumeSingleParamTag({
|
|
2602
|
+
allowEndOfString: options.allowEndOfString,
|
|
2603
|
+
callState: options.callState,
|
|
2604
|
+
lower,
|
|
2605
|
+
lt,
|
|
2606
|
+
work: options.work,
|
|
2607
|
+
lastKept,
|
|
2608
|
+
parseParamTagAt: options.parseParamTagAt,
|
|
2609
|
+
mergeParamValue: options.mergeParamValue
|
|
2610
|
+
});
|
|
2611
|
+
if (step.keepSlice !== void 0) {
|
|
2612
|
+
pieces != null ? pieces : pieces = [];
|
|
2613
|
+
pieces.push(step.keepSlice);
|
|
2614
|
+
}
|
|
2615
|
+
index = step.nextIndex;
|
|
2616
|
+
lastKept = step.nextLastKept;
|
|
2617
|
+
if (step.shouldStop) {
|
|
2618
|
+
break;
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2621
|
+
options.maybeEmitToolInputStart();
|
|
2622
|
+
if (!pieces) {
|
|
2623
|
+
return options.work;
|
|
2624
|
+
}
|
|
2625
|
+
pieces.push(options.work.slice(lastKept));
|
|
2626
|
+
return pieces.join("");
|
|
2627
|
+
}
|
|
2628
|
+
function parseCallContent(options) {
|
|
2629
|
+
let work = options.content;
|
|
2630
|
+
work = consumeToolNameTag({
|
|
2631
|
+
callState: options.callState,
|
|
2632
|
+
work,
|
|
2633
|
+
nameTagRe: options.nameTagRe,
|
|
2634
|
+
normalizeXmlTextValue: options.normalizeXmlTextValue,
|
|
2635
|
+
maybeEmitToolInputStart: options.maybeEmitToolInputStart
|
|
2636
|
+
});
|
|
2637
|
+
work = consumeParamTags({
|
|
2638
|
+
callState: options.callState,
|
|
2639
|
+
work,
|
|
2640
|
+
allowEndOfString: options.allowEndOfString,
|
|
2641
|
+
parseParamTagAt: options.parseParamTagAt,
|
|
2642
|
+
mergeParamValue: options.mergeParamValue,
|
|
2643
|
+
maybeEmitToolInputStart: options.maybeEmitToolInputStart
|
|
2644
|
+
});
|
|
2645
|
+
options.maybeEmitToolInputStart();
|
|
2646
|
+
options.maybeEmitToolInputProgress();
|
|
2647
|
+
return work;
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
// src/core/protocols/qwen3coder-protocol.ts
|
|
2651
|
+
var TOOL_CALL_OPEN_RE = /<tool_call\b[^>]*>/i;
|
|
2652
|
+
var TOOL_CALL_CLOSE_RE = /<\/tool_call\s*>/i;
|
|
2653
|
+
var TOOL_CALL_CLOSE_TRAILING_RE = /<\/tool_call\s*>\s*$/i;
|
|
2654
|
+
var TOOL_CALL_BLOCK_RE = /<tool_call\b[^>]*>[\s\S]*?<\/tool_call\s*>/gi;
|
|
2655
|
+
var LEADING_CALL_CLOSE_TAG_RE = /^\s*<\s*\/\s*(?:tool_call|function|call|tool|invoke)\s*>/i;
|
|
2656
|
+
var CALL_BLOCK_RE = /<(call|function|tool|invoke)\b[^>]*>[\s\S]*?<\/\1\s*>/gi;
|
|
2657
|
+
var QWEN3CODER_TOOL_PARSER_PARAM_TAG_NAMES = /* @__PURE__ */ new Set([
|
|
2658
|
+
"parameter",
|
|
2659
|
+
"param",
|
|
2660
|
+
"argument",
|
|
2661
|
+
"arg"
|
|
2662
|
+
]);
|
|
2663
|
+
var QWEN3CODER_TOOL_PARSER_CALL_TAG_NAMES = /* @__PURE__ */ new Set([
|
|
2664
|
+
"function",
|
|
2665
|
+
"call",
|
|
2666
|
+
"tool",
|
|
2667
|
+
"invoke",
|
|
2668
|
+
"tool_call"
|
|
2669
|
+
]);
|
|
2670
|
+
var CALL_SHORTHAND_VALUE_RE = /^<\s*(call|function|tool|invoke)\b\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>/]+))/i;
|
|
2671
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_START_RE = /<\s*(?!\/)\s*(call|function|tool|invoke)\b/i;
|
|
2672
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE = /<\s*(?!\/)\s*(call|function|tool|invoke)\b[^>]*>/i;
|
|
2673
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_TOOL_CALL_CLOSE_TAG_RE = /<\s*\/\s*tool_call\s*>/i;
|
|
2674
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_NAME_OR_PARAM_SIGNAL_RE = /<\s*(?!\/)\s*(name|tool_name|parameter|param|argument|arg)\b/i;
|
|
2675
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_NAME_TAG_RE = /<\s*(name|tool_name)\b[^>]*>([\s\S]*?)<\s*\/\s*\1\s*>/i;
|
|
2676
|
+
var QWEN3CODER_TOOL_PARSER_STREAM_SELF_CLOSING_TAG_RE = /\/\s*>$/;
|
|
2677
|
+
function isAsciiWhitespace(ch) {
|
|
2678
|
+
return ch === " " || ch === "\n" || ch === "\r" || ch === " " || ch === "\f";
|
|
2679
|
+
}
|
|
2680
|
+
function skipAsciiWhitespace(text, index) {
|
|
2681
|
+
var _a;
|
|
2682
|
+
let i = index;
|
|
2683
|
+
while (i < text.length && isAsciiWhitespace((_a = text[i]) != null ? _a : "")) {
|
|
2684
|
+
i += 1;
|
|
2685
|
+
}
|
|
2686
|
+
return i;
|
|
2687
|
+
}
|
|
2688
|
+
function stripLeadingToolCallCloseTags(text) {
|
|
2689
|
+
let out = text;
|
|
2690
|
+
while (true) {
|
|
2691
|
+
const start = skipAsciiWhitespace(out, 0);
|
|
2692
|
+
const trimmed = out.slice(start);
|
|
2693
|
+
const match = TOOL_CALL_CLOSE_RE.exec(trimmed);
|
|
2694
|
+
if (!match || match.index !== 0 || !match[0]) {
|
|
2695
|
+
return out;
|
|
2696
|
+
}
|
|
2697
|
+
out = out.slice(start + match[0].length);
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
function stripTrailingToolCallCloseTags(text) {
|
|
2701
|
+
let out = text;
|
|
2702
|
+
while (true) {
|
|
2703
|
+
const next = out.replace(TOOL_CALL_CLOSE_TRAILING_RE, "");
|
|
2704
|
+
if (next === out) {
|
|
2705
|
+
return out;
|
|
2706
|
+
}
|
|
2707
|
+
out = next;
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
function isTagBoundaryChar(ch) {
|
|
2711
|
+
return ch === "" || isAsciiWhitespace(ch) || ch === ">" || ch === "/";
|
|
2712
|
+
}
|
|
2713
|
+
function findTagEndIndex(text, startIndex) {
|
|
2714
|
+
var _a;
|
|
2715
|
+
let quote = null;
|
|
2716
|
+
for (let i = startIndex; i < text.length; i += 1) {
|
|
2717
|
+
const ch = (_a = text[i]) != null ? _a : "";
|
|
2718
|
+
if (quote) {
|
|
2719
|
+
if (ch === quote) {
|
|
2720
|
+
quote = null;
|
|
2721
|
+
}
|
|
2722
|
+
continue;
|
|
2723
|
+
}
|
|
2724
|
+
if (ch === '"' || ch === "'") {
|
|
2725
|
+
quote = ch;
|
|
2726
|
+
continue;
|
|
2727
|
+
}
|
|
2728
|
+
if (ch === ">") {
|
|
2729
|
+
return i;
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
return null;
|
|
2733
|
+
}
|
|
2734
|
+
function parseShorthandValue(openTag, tagNameLower) {
|
|
2735
|
+
var _a, _b;
|
|
2736
|
+
let i = 1;
|
|
2737
|
+
i = skipAsciiWhitespace(openTag, i);
|
|
2738
|
+
if (!openTag.toLowerCase().startsWith(tagNameLower, i)) {
|
|
2739
|
+
return null;
|
|
2740
|
+
}
|
|
2741
|
+
i += tagNameLower.length;
|
|
2742
|
+
i = skipAsciiWhitespace(openTag, i);
|
|
2743
|
+
if (openTag[i] !== "=") {
|
|
2744
|
+
return null;
|
|
2745
|
+
}
|
|
2746
|
+
i += 1;
|
|
2747
|
+
i = skipAsciiWhitespace(openTag, i);
|
|
2748
|
+
const quote = (_a = openTag[i]) != null ? _a : "";
|
|
2749
|
+
if (quote === '"' || quote === "'") {
|
|
2750
|
+
const end = openTag.indexOf(quote, i + 1);
|
|
2751
|
+
if (end === -1) {
|
|
2752
|
+
return null;
|
|
2753
|
+
}
|
|
2754
|
+
return openTag.slice(i + 1, end);
|
|
2755
|
+
}
|
|
2756
|
+
const start = i;
|
|
2757
|
+
while (i < openTag.length) {
|
|
2758
|
+
const ch = (_b = openTag[i]) != null ? _b : "";
|
|
2759
|
+
if (isAsciiWhitespace(ch) || ch === ">" || ch === "/") {
|
|
2760
|
+
break;
|
|
2761
|
+
}
|
|
2762
|
+
i += 1;
|
|
2763
|
+
}
|
|
2764
|
+
const value = openTag.slice(start, i);
|
|
2765
|
+
return value.length > 0 ? value : null;
|
|
2766
|
+
}
|
|
2767
|
+
function parseQwen3CoderToolParserParamName(openTag, tagNameLower) {
|
|
2768
|
+
const shorthand = parseShorthandValue(openTag, tagNameLower);
|
|
2769
|
+
if (shorthand != null) {
|
|
2770
|
+
return unescapeXml(shorthand);
|
|
2771
|
+
}
|
|
2772
|
+
return getAttributeValue(openTag, "name");
|
|
2773
|
+
}
|
|
2774
|
+
function getCdataSectionNextIndex(textLower, startIndex) {
|
|
2775
|
+
if (!textLower.startsWith("<![cdata[", startIndex)) {
|
|
2776
|
+
return startIndex;
|
|
2777
|
+
}
|
|
2778
|
+
const cdataEnd = textLower.indexOf("]]>", startIndex + "<![cdata[".length);
|
|
2779
|
+
if (cdataEnd === -1) {
|
|
2780
|
+
return null;
|
|
2781
|
+
}
|
|
2782
|
+
return cdataEnd + 3;
|
|
2783
|
+
}
|
|
2784
|
+
function parseMatchingTagHeader(textLower, lt, tagNameLower) {
|
|
2785
|
+
var _a;
|
|
2786
|
+
let i = skipAsciiWhitespace(textLower, lt + 1);
|
|
2787
|
+
const isClosing = textLower[i] === "/";
|
|
2788
|
+
if (isClosing) {
|
|
2789
|
+
i += 1;
|
|
2790
|
+
i = skipAsciiWhitespace(textLower, i);
|
|
2791
|
+
}
|
|
2792
|
+
if (!textLower.startsWith(tagNameLower, i)) {
|
|
2793
|
+
return null;
|
|
2794
|
+
}
|
|
2795
|
+
const afterName = i + tagNameLower.length;
|
|
2796
|
+
const boundary = (_a = textLower[afterName]) != null ? _a : "";
|
|
2797
|
+
const validBoundary = isClosing ? isTagBoundaryChar(boundary) : isTagBoundaryChar(boundary) || boundary === "=";
|
|
2798
|
+
if (boundary && !validBoundary) {
|
|
2799
|
+
return null;
|
|
2800
|
+
}
|
|
2801
|
+
return { isClosing, afterName };
|
|
2802
|
+
}
|
|
2803
|
+
function isSelfClosingXmlTag(textLower, lt, gt) {
|
|
2804
|
+
return textLower.slice(lt, gt + 1).trimEnd().endsWith("/>");
|
|
2805
|
+
}
|
|
2806
|
+
function findClosingTagEnd(textLower, startIndex, tagNameLower) {
|
|
2807
|
+
let depth = 1;
|
|
2808
|
+
let index = startIndex;
|
|
2809
|
+
while (true) {
|
|
2810
|
+
const lt = textLower.indexOf("<", index);
|
|
2811
|
+
if (lt === -1) {
|
|
2812
|
+
return null;
|
|
2813
|
+
}
|
|
2814
|
+
const cdataNextIndex = getCdataSectionNextIndex(textLower, lt);
|
|
2815
|
+
if (cdataNextIndex == null) {
|
|
2816
|
+
return null;
|
|
2817
|
+
}
|
|
2818
|
+
if (cdataNextIndex !== lt) {
|
|
2819
|
+
index = cdataNextIndex;
|
|
2820
|
+
continue;
|
|
2821
|
+
}
|
|
2822
|
+
const header = parseMatchingTagHeader(textLower, lt, tagNameLower);
|
|
2823
|
+
if (!header) {
|
|
2824
|
+
index = lt + 1;
|
|
2825
|
+
continue;
|
|
2826
|
+
}
|
|
2827
|
+
const gt = textLower.indexOf(">", header.afterName);
|
|
2828
|
+
if (gt === -1) {
|
|
2829
|
+
return null;
|
|
2830
|
+
}
|
|
2831
|
+
if (header.isClosing) {
|
|
2832
|
+
depth -= 1;
|
|
2833
|
+
if (depth === 0) {
|
|
2834
|
+
return { start: lt, end: gt + 1 };
|
|
2835
|
+
}
|
|
2836
|
+
index = gt + 1;
|
|
2837
|
+
continue;
|
|
2838
|
+
}
|
|
2839
|
+
const isSelfClosing = isSelfClosingXmlTag(textLower, lt, gt);
|
|
2840
|
+
if (!isSelfClosing) {
|
|
2841
|
+
depth += 1;
|
|
2842
|
+
}
|
|
2843
|
+
index = gt + 1;
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
function findClosingTagStartWithBoundary(lowerText, valueStart, tagNameLower, allowEndOfStringBoundary) {
|
|
2847
|
+
var _a;
|
|
2848
|
+
const needle = `</${tagNameLower}`;
|
|
2849
|
+
let searchIndex = valueStart;
|
|
2850
|
+
while (searchIndex < lowerText.length) {
|
|
2851
|
+
const found = lowerText.indexOf(needle, searchIndex);
|
|
2852
|
+
if (found === -1) {
|
|
2853
|
+
return -1;
|
|
2854
|
+
}
|
|
2855
|
+
const nextChar = (_a = lowerText[found + needle.length]) != null ? _a : "";
|
|
2856
|
+
if (nextChar === "" && !allowEndOfStringBoundary) {
|
|
2857
|
+
searchIndex = found + needle.length;
|
|
2858
|
+
continue;
|
|
2859
|
+
}
|
|
2860
|
+
if (isTagBoundaryChar(nextChar)) {
|
|
2861
|
+
return found;
|
|
2862
|
+
}
|
|
2863
|
+
searchIndex = found + needle.length;
|
|
2864
|
+
}
|
|
2865
|
+
return -1;
|
|
2866
|
+
}
|
|
2867
|
+
function toSupportedCallEndTagName(tagNameLower) {
|
|
2868
|
+
var _a;
|
|
2869
|
+
const normalized = (_a = tagNameLower == null ? void 0 : tagNameLower.trim().toLowerCase()) != null ? _a : "";
|
|
2870
|
+
if (!normalized) {
|
|
2871
|
+
return null;
|
|
2872
|
+
}
|
|
2873
|
+
return QWEN3CODER_TOOL_PARSER_CALL_TAG_NAMES.has(normalized) ? normalized : null;
|
|
2874
|
+
}
|
|
2875
|
+
function findUnclosedParamBoundaryIndex(lowerText, valueStart, callEndTagNameLower, allowEndOfString) {
|
|
2876
|
+
const normalizedCallEndTag = toSupportedCallEndTagName(callEndTagNameLower);
|
|
2877
|
+
const callCloseIndex = normalizedCallEndTag ? findClosingTagStartWithBoundary(
|
|
2878
|
+
lowerText,
|
|
2879
|
+
valueStart,
|
|
2880
|
+
normalizedCallEndTag,
|
|
2881
|
+
allowEndOfString
|
|
2882
|
+
) : findClosingTagStartWithBoundary(
|
|
2883
|
+
lowerText,
|
|
2884
|
+
valueStart,
|
|
2885
|
+
"function",
|
|
2886
|
+
allowEndOfString
|
|
2887
|
+
);
|
|
2888
|
+
const indices = [
|
|
2889
|
+
lowerText.indexOf("<parameter", valueStart),
|
|
2890
|
+
lowerText.indexOf("<param", valueStart),
|
|
2891
|
+
lowerText.indexOf("<argument", valueStart),
|
|
2892
|
+
lowerText.indexOf("<arg", valueStart),
|
|
2893
|
+
callCloseIndex,
|
|
2894
|
+
findClosingTagStartWithBoundary(
|
|
2895
|
+
lowerText,
|
|
2896
|
+
valueStart,
|
|
2897
|
+
"tool_call",
|
|
2898
|
+
allowEndOfString
|
|
2899
|
+
),
|
|
2900
|
+
lowerText.indexOf("<function", valueStart)
|
|
2901
|
+
].filter((index) => index !== -1);
|
|
2902
|
+
if (indices.length === 0) {
|
|
2903
|
+
return null;
|
|
2904
|
+
}
|
|
2905
|
+
return Math.min(...indices);
|
|
2906
|
+
}
|
|
2907
|
+
function parseQwen3CoderToolParserParamTagNameLower(lowerText, startIndex) {
|
|
2908
|
+
var _a;
|
|
2909
|
+
let i = skipAsciiWhitespace(lowerText, startIndex + 1);
|
|
2910
|
+
if (i >= lowerText.length) {
|
|
2911
|
+
return { kind: "partial" };
|
|
2912
|
+
}
|
|
2913
|
+
if (lowerText[i] === "/") {
|
|
2914
|
+
return null;
|
|
2915
|
+
}
|
|
2916
|
+
const nameStart = i;
|
|
2917
|
+
while (i < lowerText.length) {
|
|
2918
|
+
const ch = (_a = lowerText[i]) != null ? _a : "";
|
|
2919
|
+
if (isAsciiWhitespace(ch) || ch === ">" || ch === "/" || ch === "=") {
|
|
2920
|
+
break;
|
|
2921
|
+
}
|
|
2922
|
+
i += 1;
|
|
2923
|
+
}
|
|
2924
|
+
const tagNameLower = lowerText.slice(nameStart, i);
|
|
2925
|
+
if (!QWEN3CODER_TOOL_PARSER_PARAM_TAG_NAMES.has(tagNameLower)) {
|
|
2926
|
+
return null;
|
|
2927
|
+
}
|
|
2928
|
+
return { kind: "match", tagNameLower };
|
|
2929
|
+
}
|
|
2930
|
+
function parseQwen3CoderToolParserUnclosedParamValue(options) {
|
|
2931
|
+
var _a;
|
|
2932
|
+
const valueStart = options.openEnd + 1;
|
|
2933
|
+
const boundaryIndex = findUnclosedParamBoundaryIndex(
|
|
2934
|
+
options.lowerText,
|
|
2935
|
+
valueStart,
|
|
2936
|
+
(_a = options.callEndTagNameLower) != null ? _a : null,
|
|
2937
|
+
options.allowEndOfString
|
|
2938
|
+
);
|
|
2939
|
+
if (boundaryIndex == null) {
|
|
2940
|
+
if (!options.allowEndOfString) {
|
|
2941
|
+
const rawProgressValue = options.text.slice(valueStart);
|
|
2942
|
+
return {
|
|
2943
|
+
kind: "partial",
|
|
2944
|
+
start: options.startIndex,
|
|
2945
|
+
openEnd: options.openEnd,
|
|
2946
|
+
name: options.paramName,
|
|
2947
|
+
value: rawProgressValue ? normalizeXmlTextValue(rawProgressValue) : ""
|
|
2948
|
+
};
|
|
2949
|
+
}
|
|
2950
|
+
const rawValue2 = options.text.slice(valueStart);
|
|
2951
|
+
return {
|
|
2952
|
+
kind: "match",
|
|
2953
|
+
start: options.startIndex,
|
|
2954
|
+
end: options.text.length,
|
|
2955
|
+
name: options.paramName,
|
|
2956
|
+
value: rawValue2 ? normalizeXmlTextValue(rawValue2) : ""
|
|
2957
|
+
};
|
|
2958
|
+
}
|
|
2959
|
+
const rawValue = options.text.slice(valueStart, boundaryIndex);
|
|
2960
|
+
return {
|
|
2961
|
+
kind: "match",
|
|
2962
|
+
start: options.startIndex,
|
|
2963
|
+
end: boundaryIndex,
|
|
2964
|
+
name: options.paramName,
|
|
2965
|
+
value: rawValue ? normalizeXmlTextValue(rawValue) : ""
|
|
2966
|
+
};
|
|
2967
|
+
}
|
|
2968
|
+
function parseQwen3CoderToolParserParamTagAt(text, lowerText, startIndex, options) {
|
|
2969
|
+
var _a;
|
|
2970
|
+
const tagNameParse = parseQwen3CoderToolParserParamTagNameLower(
|
|
2971
|
+
lowerText,
|
|
2972
|
+
startIndex
|
|
2973
|
+
);
|
|
2974
|
+
if (!tagNameParse) {
|
|
2975
|
+
return null;
|
|
2976
|
+
}
|
|
2977
|
+
if (tagNameParse.kind === "partial") {
|
|
2978
|
+
return { kind: "partial", start: startIndex, openEnd: null };
|
|
2979
|
+
}
|
|
2980
|
+
const tagNameLower = tagNameParse.tagNameLower;
|
|
2981
|
+
const openEnd = findTagEndIndex(text, startIndex);
|
|
2982
|
+
if (openEnd == null) {
|
|
2983
|
+
return { kind: "partial", start: startIndex, openEnd: null };
|
|
2984
|
+
}
|
|
2985
|
+
const openTag = text.slice(startIndex, openEnd + 1);
|
|
2986
|
+
const paramNameRaw = parseQwen3CoderToolParserParamName(
|
|
2987
|
+
openTag,
|
|
2988
|
+
tagNameLower
|
|
2989
|
+
);
|
|
2990
|
+
const paramName = (_a = paramNameRaw == null ? void 0 : paramNameRaw.trim()) != null ? _a : "";
|
|
2991
|
+
if (paramName.length === 0) {
|
|
2992
|
+
return null;
|
|
2993
|
+
}
|
|
2994
|
+
const selfClosing = openTag.trimEnd().endsWith("/>");
|
|
2995
|
+
if (selfClosing) {
|
|
2996
|
+
return {
|
|
2997
|
+
kind: "match",
|
|
2998
|
+
start: startIndex,
|
|
2999
|
+
end: openEnd + 1,
|
|
3000
|
+
name: paramName,
|
|
3001
|
+
value: ""
|
|
3002
|
+
};
|
|
3003
|
+
}
|
|
3004
|
+
const valueStart = openEnd + 1;
|
|
3005
|
+
const close = findClosingTagEnd(lowerText, valueStart, tagNameLower);
|
|
3006
|
+
if (!close) {
|
|
3007
|
+
return parseQwen3CoderToolParserUnclosedParamValue({
|
|
3008
|
+
text,
|
|
3009
|
+
lowerText,
|
|
3010
|
+
startIndex,
|
|
3011
|
+
openEnd,
|
|
3012
|
+
paramName,
|
|
3013
|
+
allowEndOfString: (options == null ? void 0 : options.allowEndOfString) === true,
|
|
3014
|
+
callEndTagNameLower: options == null ? void 0 : options.callEndTagNameLower
|
|
3015
|
+
});
|
|
3016
|
+
}
|
|
3017
|
+
const rawValue = text.slice(openEnd + 1, close.start);
|
|
3018
|
+
return {
|
|
3019
|
+
kind: "match",
|
|
3020
|
+
start: startIndex,
|
|
3021
|
+
end: close.end,
|
|
3022
|
+
name: paramName,
|
|
3023
|
+
value: rawValue ? normalizeXmlTextValue(rawValue) : ""
|
|
3024
|
+
};
|
|
3025
|
+
}
|
|
3026
|
+
function normalizeXmlTextValue(raw) {
|
|
3027
|
+
let out = raw.trim();
|
|
3028
|
+
if (out.startsWith("<![CDATA[") && out.endsWith("]]>")) {
|
|
3029
|
+
out = out.slice("<![CDATA[".length, -"]]>".length).trim();
|
|
3030
|
+
}
|
|
3031
|
+
return unescapeXml(out);
|
|
3032
|
+
}
|
|
3033
|
+
function getOpeningTag(xml) {
|
|
3034
|
+
const gt = xml.indexOf(">");
|
|
3035
|
+
if (gt === -1) {
|
|
3036
|
+
return null;
|
|
3037
|
+
}
|
|
3038
|
+
return xml.slice(0, gt + 1);
|
|
3039
|
+
}
|
|
3040
|
+
var attrValueRegExpCache = /* @__PURE__ */ new Map();
|
|
3041
|
+
function getAttributeValue(openTag, attrName) {
|
|
3042
|
+
var _a;
|
|
3043
|
+
let re = attrValueRegExpCache.get(attrName);
|
|
3044
|
+
if (!re) {
|
|
3045
|
+
re = new RegExp(
|
|
3046
|
+
`\\b${escapeRegExp(attrName)}\\s*=\\s*(["'])([\\s\\S]*?)\\1`,
|
|
3047
|
+
"i"
|
|
3048
|
+
);
|
|
3049
|
+
attrValueRegExpCache.set(attrName, re);
|
|
3050
|
+
}
|
|
3051
|
+
const match = re.exec(openTag);
|
|
3052
|
+
if (!match) {
|
|
3053
|
+
return null;
|
|
3054
|
+
}
|
|
3055
|
+
return unescapeXml((_a = match[2]) != null ? _a : "");
|
|
3056
|
+
}
|
|
3057
|
+
function getShorthandValue(openTag) {
|
|
3058
|
+
var _a, _b;
|
|
3059
|
+
const match = CALL_SHORTHAND_VALUE_RE.exec(openTag);
|
|
3060
|
+
if (!match) {
|
|
3061
|
+
return null;
|
|
3062
|
+
}
|
|
3063
|
+
const value = (_b = (_a = match[2]) != null ? _a : match[3]) != null ? _b : match[4];
|
|
3064
|
+
if (!value) {
|
|
3065
|
+
return null;
|
|
3066
|
+
}
|
|
3067
|
+
return unescapeXml(value);
|
|
3068
|
+
}
|
|
3069
|
+
function extractFirstTagText(xml, tagName) {
|
|
3070
|
+
var _a;
|
|
3071
|
+
const lower = xml.toLowerCase();
|
|
3072
|
+
const tagLower = tagName.toLowerCase();
|
|
3073
|
+
let index = 0;
|
|
3074
|
+
while (true) {
|
|
3075
|
+
const lt = lower.indexOf("<", index);
|
|
3076
|
+
if (lt === -1) {
|
|
3077
|
+
return null;
|
|
3078
|
+
}
|
|
3079
|
+
const i = skipAsciiWhitespace(lower, lt + 1);
|
|
3080
|
+
if (i >= lower.length || lower[i] === "/") {
|
|
3081
|
+
index = lt + 1;
|
|
3082
|
+
continue;
|
|
3083
|
+
}
|
|
3084
|
+
if (!lower.startsWith(tagLower, i)) {
|
|
3085
|
+
index = lt + 1;
|
|
3086
|
+
continue;
|
|
3087
|
+
}
|
|
3088
|
+
const afterName = i + tagLower.length;
|
|
3089
|
+
const boundary = (_a = lower[afterName]) != null ? _a : "";
|
|
3090
|
+
if (boundary && !isTagBoundaryChar(boundary)) {
|
|
3091
|
+
index = lt + 1;
|
|
3092
|
+
continue;
|
|
3093
|
+
}
|
|
3094
|
+
const openEnd = findTagEndIndex(xml, lt);
|
|
3095
|
+
if (openEnd == null) {
|
|
3096
|
+
return null;
|
|
3097
|
+
}
|
|
3098
|
+
const contentStart = openEnd + 1;
|
|
3099
|
+
const close = findClosingTagEnd(lower, contentStart, tagLower);
|
|
3100
|
+
if (!close) {
|
|
3101
|
+
return null;
|
|
3102
|
+
}
|
|
3103
|
+
return normalizeXmlTextValue(xml.slice(contentStart, close.start));
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3106
|
+
function extractToolCallInnerXml(segment) {
|
|
3107
|
+
const openMatch = TOOL_CALL_OPEN_RE.exec(segment);
|
|
3108
|
+
const closeMatch = TOOL_CALL_CLOSE_RE.exec(segment);
|
|
3109
|
+
if (!(openMatch && closeMatch)) {
|
|
3110
|
+
return null;
|
|
3111
|
+
}
|
|
3112
|
+
const openIndex = openMatch.index;
|
|
3113
|
+
const openTag = openMatch[0];
|
|
3114
|
+
const openEnd = openIndex + openTag.length;
|
|
3115
|
+
const closeIndex = segment.toLowerCase().lastIndexOf("</tool_call");
|
|
3116
|
+
if (closeIndex === -1) {
|
|
3117
|
+
return null;
|
|
3118
|
+
}
|
|
3119
|
+
const closeGt = segment.indexOf(">", closeIndex);
|
|
3120
|
+
if (closeGt === -1) {
|
|
3121
|
+
return null;
|
|
3122
|
+
}
|
|
3123
|
+
return {
|
|
3124
|
+
outerOpenTag: openTag,
|
|
3125
|
+
inner: segment.slice(openEnd, closeIndex)
|
|
3126
|
+
};
|
|
3127
|
+
}
|
|
3128
|
+
function mergeParamValue(args, key, value) {
|
|
3129
|
+
const existing = args[key];
|
|
3130
|
+
if (existing === void 0) {
|
|
3131
|
+
args[key] = value;
|
|
3132
|
+
return;
|
|
3133
|
+
}
|
|
3134
|
+
if (Array.isArray(existing)) {
|
|
3135
|
+
existing.push(value);
|
|
3136
|
+
return;
|
|
3137
|
+
}
|
|
3138
|
+
args[key] = [existing, value];
|
|
3139
|
+
}
|
|
3140
|
+
function mergeArgsWithPartialParam(args, partialParam) {
|
|
3141
|
+
if (!partialParam) {
|
|
3142
|
+
return args;
|
|
3143
|
+
}
|
|
3144
|
+
const existing = args[partialParam.name];
|
|
3145
|
+
if (existing === void 0) {
|
|
3146
|
+
return {
|
|
3147
|
+
...args,
|
|
3148
|
+
[partialParam.name]: partialParam.value
|
|
3149
|
+
};
|
|
3150
|
+
}
|
|
3151
|
+
if (Array.isArray(existing)) {
|
|
3152
|
+
return {
|
|
3153
|
+
...args,
|
|
3154
|
+
[partialParam.name]: [...existing, partialParam.value]
|
|
3155
|
+
};
|
|
3156
|
+
}
|
|
3157
|
+
return {
|
|
3158
|
+
...args,
|
|
3159
|
+
[partialParam.name]: [existing, partialParam.value]
|
|
3160
|
+
};
|
|
3161
|
+
}
|
|
3162
|
+
function extractParameters(xml, options) {
|
|
3163
|
+
var _a;
|
|
3164
|
+
const args = {};
|
|
3165
|
+
const lower = xml.toLowerCase();
|
|
3166
|
+
let index = 0;
|
|
3167
|
+
while (true) {
|
|
3168
|
+
const lt = lower.indexOf("<", index);
|
|
3169
|
+
if (lt === -1) {
|
|
3170
|
+
break;
|
|
3171
|
+
}
|
|
3172
|
+
const parsed = parseQwen3CoderToolParserParamTagAt(xml, lower, lt, {
|
|
3173
|
+
allowEndOfString: true,
|
|
3174
|
+
callEndTagNameLower: options == null ? void 0 : options.callEndTagNameLower
|
|
3175
|
+
});
|
|
3176
|
+
if (!parsed) {
|
|
3177
|
+
index = lt + 1;
|
|
3178
|
+
continue;
|
|
3179
|
+
}
|
|
3180
|
+
if (parsed.kind === "match") {
|
|
3181
|
+
mergeParamValue(args, parsed.name, parsed.value);
|
|
3182
|
+
index = parsed.end;
|
|
3183
|
+
continue;
|
|
3184
|
+
}
|
|
3185
|
+
index = ((_a = parsed.openEnd) != null ? _a : lt) + 1;
|
|
3186
|
+
}
|
|
3187
|
+
return args;
|
|
3188
|
+
}
|
|
3189
|
+
function parseSingleFunctionCallXml(xml, fallbackToolName) {
|
|
3190
|
+
var _a, _b, _c;
|
|
3191
|
+
const openingTag = getOpeningTag(xml);
|
|
3192
|
+
const toolNameAttr = openingTag ? getAttributeValue(openingTag, "name") : null;
|
|
3193
|
+
const shorthandName = openingTag ? getShorthandValue(openingTag) : null;
|
|
3194
|
+
const toolName = (_c = (_b = (_a = toolNameAttr != null ? toolNameAttr : shorthandName) != null ? _a : extractFirstTagText(xml, "name")) != null ? _b : extractFirstTagText(xml, "tool_name")) != null ? _c : fallbackToolName;
|
|
3195
|
+
const callEndTagNameLower = toSupportedCallEndTagName(
|
|
3196
|
+
openingTag ? getOpenTagNameLower(openingTag) : null
|
|
3197
|
+
);
|
|
3198
|
+
if (!toolName || toolName.trim().length === 0) {
|
|
3199
|
+
return null;
|
|
3200
|
+
}
|
|
3201
|
+
return {
|
|
3202
|
+
toolName,
|
|
3203
|
+
args: extractParameters(xml, { callEndTagNameLower })
|
|
3204
|
+
};
|
|
3205
|
+
}
|
|
3206
|
+
function findImplicitCallOpenIndices(lowerText) {
|
|
3207
|
+
var _a;
|
|
3208
|
+
const indices = [];
|
|
3209
|
+
let index = 0;
|
|
3210
|
+
while (true) {
|
|
3211
|
+
const lt = lowerText.indexOf("<", index);
|
|
3212
|
+
if (lt === -1) {
|
|
3213
|
+
break;
|
|
3214
|
+
}
|
|
3215
|
+
const i = skipAsciiWhitespace(lowerText, lt + 1);
|
|
3216
|
+
if (i >= lowerText.length) {
|
|
3217
|
+
break;
|
|
3218
|
+
}
|
|
3219
|
+
if (lowerText[i] === "/") {
|
|
3220
|
+
index = lt + 1;
|
|
3221
|
+
continue;
|
|
3222
|
+
}
|
|
3223
|
+
const tagNames = ["call", "function", "tool", "invoke"];
|
|
3224
|
+
for (const tagName of tagNames) {
|
|
3225
|
+
if (!lowerText.startsWith(tagName, i)) {
|
|
3226
|
+
continue;
|
|
3227
|
+
}
|
|
3228
|
+
const after = i + tagName.length;
|
|
3229
|
+
const boundary = (_a = lowerText[after]) != null ? _a : "";
|
|
3230
|
+
if (boundary && !isTagBoundaryChar(boundary) && boundary !== "=") {
|
|
3231
|
+
continue;
|
|
3232
|
+
}
|
|
3233
|
+
indices.push(lt);
|
|
3234
|
+
break;
|
|
3235
|
+
}
|
|
3236
|
+
index = lt + 1;
|
|
3237
|
+
}
|
|
3238
|
+
return indices;
|
|
3239
|
+
}
|
|
3240
|
+
function splitImplicitCallBlocks(xml) {
|
|
3241
|
+
var _a, _b;
|
|
3242
|
+
const lower = xml.toLowerCase();
|
|
3243
|
+
const starts = findImplicitCallOpenIndices(lower);
|
|
3244
|
+
if (starts.length === 0) {
|
|
3245
|
+
return [];
|
|
3246
|
+
}
|
|
3247
|
+
const blocks = [];
|
|
3248
|
+
for (let i = 0; i < starts.length; i += 1) {
|
|
3249
|
+
const start = (_a = starts[i]) != null ? _a : 0;
|
|
3250
|
+
const end = (_b = starts[i + 1]) != null ? _b : xml.length;
|
|
3251
|
+
blocks.push(xml.slice(start, end));
|
|
3252
|
+
}
|
|
3253
|
+
return blocks;
|
|
3254
|
+
}
|
|
3255
|
+
function stripLeadingCallCloseTags(text) {
|
|
3256
|
+
let out = text;
|
|
3257
|
+
while (true) {
|
|
3258
|
+
const match = LEADING_CALL_CLOSE_TAG_RE.exec(out);
|
|
3259
|
+
if (!match) {
|
|
3260
|
+
return out;
|
|
3261
|
+
}
|
|
3262
|
+
out = out.slice(match[0].length);
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
function getOpenTagNameLower(openTag) {
|
|
3266
|
+
var _a;
|
|
3267
|
+
const lowerOpenTag = openTag.toLowerCase();
|
|
3268
|
+
const lt = lowerOpenTag.indexOf("<");
|
|
3269
|
+
if (lt === -1) {
|
|
3270
|
+
return null;
|
|
3271
|
+
}
|
|
3272
|
+
let i = skipAsciiWhitespace(lowerOpenTag, lt + 1);
|
|
3273
|
+
if (i >= lowerOpenTag.length || lowerOpenTag[i] === "/") {
|
|
3274
|
+
return null;
|
|
3275
|
+
}
|
|
3276
|
+
const start = i;
|
|
3277
|
+
while (i < lowerOpenTag.length) {
|
|
3278
|
+
const ch = (_a = lowerOpenTag[i]) != null ? _a : "";
|
|
3279
|
+
if (isAsciiWhitespace(ch) || ch === ">" || ch === "/" || ch === "=") {
|
|
3280
|
+
break;
|
|
3281
|
+
}
|
|
3282
|
+
i += 1;
|
|
3283
|
+
}
|
|
3284
|
+
const tagName = lowerOpenTag.slice(start, i);
|
|
3285
|
+
return tagName.length > 0 ? tagName : null;
|
|
3286
|
+
}
|
|
3287
|
+
function splitImplicitCallAndTail(callBlock) {
|
|
3288
|
+
var _a;
|
|
3289
|
+
const openingTag = getOpeningTag(callBlock);
|
|
3290
|
+
const openingTagName = toSupportedCallEndTagName(
|
|
3291
|
+
openingTag ? getOpenTagNameLower(openingTag) : null
|
|
3292
|
+
);
|
|
3293
|
+
const lowerCallBlock = callBlock.toLowerCase();
|
|
3294
|
+
let consumed = 0;
|
|
3295
|
+
if (openingTag) {
|
|
3296
|
+
consumed = openingTag.length;
|
|
3297
|
+
if (openingTagName) {
|
|
3298
|
+
const close = findClosingTagEnd(lowerCallBlock, consumed, openingTagName);
|
|
3299
|
+
if (close) {
|
|
3300
|
+
consumed = Math.max(consumed, close.end);
|
|
3301
|
+
}
|
|
3302
|
+
}
|
|
3303
|
+
}
|
|
3304
|
+
let index = 0;
|
|
3305
|
+
while (true) {
|
|
3306
|
+
const lt = lowerCallBlock.indexOf("<", index);
|
|
3307
|
+
if (lt === -1) {
|
|
3308
|
+
break;
|
|
3309
|
+
}
|
|
3310
|
+
const parsed = parseQwen3CoderToolParserParamTagAt(
|
|
3311
|
+
callBlock,
|
|
3312
|
+
lowerCallBlock,
|
|
3313
|
+
lt,
|
|
3314
|
+
{
|
|
3315
|
+
allowEndOfString: true,
|
|
3316
|
+
callEndTagNameLower: openingTagName
|
|
3317
|
+
}
|
|
3318
|
+
);
|
|
3319
|
+
if (!parsed) {
|
|
3320
|
+
index = lt + 1;
|
|
3321
|
+
continue;
|
|
3322
|
+
}
|
|
3323
|
+
if (parsed.kind === "partial") {
|
|
3324
|
+
index = ((_a = parsed.openEnd) != null ? _a : lt) + 1;
|
|
3325
|
+
continue;
|
|
3326
|
+
}
|
|
3327
|
+
consumed = Math.max(consumed, parsed.end);
|
|
3328
|
+
index = parsed.end;
|
|
3329
|
+
}
|
|
3330
|
+
const clamped = Math.max(0, Math.min(consumed, callBlock.length));
|
|
3331
|
+
return {
|
|
3332
|
+
callContent: callBlock.slice(0, clamped),
|
|
3333
|
+
trailingText: callBlock.slice(clamped)
|
|
3334
|
+
};
|
|
3335
|
+
}
|
|
3336
|
+
function parseQwen3CoderToolParserCallBlocks(blocks, outerNameAttr) {
|
|
3337
|
+
const calls = [];
|
|
3338
|
+
for (const block of blocks) {
|
|
3339
|
+
const parsed = parseSingleFunctionCallXml(block, outerNameAttr);
|
|
3340
|
+
if (!parsed) {
|
|
3341
|
+
return null;
|
|
3342
|
+
}
|
|
3343
|
+
calls.push(parsed);
|
|
3344
|
+
}
|
|
3345
|
+
return calls;
|
|
3346
|
+
}
|
|
3347
|
+
function parseQwen3CoderToolParserClosedMatches(inner, outerNameAttr) {
|
|
3348
|
+
var _a, _b;
|
|
3349
|
+
const callBlockMatches = Array.from(inner.matchAll(CALL_BLOCK_RE));
|
|
3350
|
+
if (callBlockMatches.length === 0) {
|
|
3351
|
+
return void 0;
|
|
3352
|
+
}
|
|
3353
|
+
const closedBlocks = [];
|
|
3354
|
+
let lastClosedEnd = 0;
|
|
3355
|
+
for (const match of callBlockMatches) {
|
|
3356
|
+
const callBlock = (_a = match[0]) != null ? _a : "";
|
|
3357
|
+
const startIndex = (_b = match.index) != null ? _b : -1;
|
|
3358
|
+
if (!callBlock || startIndex < 0) {
|
|
3359
|
+
continue;
|
|
3360
|
+
}
|
|
3361
|
+
closedBlocks.push(callBlock);
|
|
3362
|
+
lastClosedEnd = startIndex + callBlock.length;
|
|
3363
|
+
}
|
|
3364
|
+
const closedCalls = parseQwen3CoderToolParserCallBlocks(
|
|
3365
|
+
closedBlocks,
|
|
3366
|
+
outerNameAttr
|
|
3367
|
+
);
|
|
3368
|
+
if (!closedCalls) {
|
|
3369
|
+
return null;
|
|
3370
|
+
}
|
|
3371
|
+
const trailingInner = inner.slice(lastClosedEnd);
|
|
3372
|
+
if (trailingInner.trim().length === 0) {
|
|
3373
|
+
return closedCalls;
|
|
3374
|
+
}
|
|
3375
|
+
const trailingBlocks = splitImplicitCallBlocks(trailingInner).filter(
|
|
3376
|
+
(b) => b.trim().length > 0
|
|
3377
|
+
);
|
|
3378
|
+
if (trailingBlocks.length === 0) {
|
|
3379
|
+
return closedCalls;
|
|
3380
|
+
}
|
|
3381
|
+
const trailingCalls = parseQwen3CoderToolParserCallBlocks(
|
|
3382
|
+
trailingBlocks,
|
|
3383
|
+
outerNameAttr
|
|
3384
|
+
);
|
|
3385
|
+
if (!trailingCalls) {
|
|
3386
|
+
return closedCalls;
|
|
3387
|
+
}
|
|
3388
|
+
return closedCalls.concat(trailingCalls);
|
|
3389
|
+
}
|
|
3390
|
+
function parseQwen3CoderToolParserToolCallSegment(segment) {
|
|
3391
|
+
var _a;
|
|
3392
|
+
const extracted = extractToolCallInnerXml(segment);
|
|
3393
|
+
if (!extracted) {
|
|
3394
|
+
return null;
|
|
3395
|
+
}
|
|
3396
|
+
const { inner, outerOpenTag } = extracted;
|
|
3397
|
+
const outerNameAttr = getAttributeValue(outerOpenTag, "name");
|
|
3398
|
+
const closedCalls = parseQwen3CoderToolParserClosedMatches(
|
|
3399
|
+
inner,
|
|
3400
|
+
outerNameAttr
|
|
3401
|
+
);
|
|
3402
|
+
if (closedCalls) {
|
|
3403
|
+
return closedCalls;
|
|
3404
|
+
}
|
|
3405
|
+
if (closedCalls === null) {
|
|
3406
|
+
return null;
|
|
3407
|
+
}
|
|
3408
|
+
const implicitBlocks = splitImplicitCallBlocks(inner).filter(
|
|
3409
|
+
(b) => b.trim().length > 0
|
|
3410
|
+
);
|
|
3411
|
+
if (implicitBlocks.length > 0) {
|
|
3412
|
+
return parseQwen3CoderToolParserCallBlocks(implicitBlocks, outerNameAttr);
|
|
3413
|
+
}
|
|
3414
|
+
const single = (_a = parseSingleFunctionCallXml(inner, outerNameAttr)) != null ? _a : parseSingleFunctionCallXml(segment, outerNameAttr);
|
|
3415
|
+
if (!single) {
|
|
3416
|
+
return null;
|
|
3417
|
+
}
|
|
3418
|
+
return [single];
|
|
3419
|
+
}
|
|
3420
|
+
function parseToolCallInput(input) {
|
|
3421
|
+
if (input == null) {
|
|
3422
|
+
return {};
|
|
3423
|
+
}
|
|
3424
|
+
try {
|
|
3425
|
+
return JSON.parse(input);
|
|
3426
|
+
} catch (e) {
|
|
3427
|
+
return input;
|
|
3428
|
+
}
|
|
3429
|
+
}
|
|
3430
|
+
function toQwen3CoderToolParserParamText(value) {
|
|
3431
|
+
if (typeof value === "string") {
|
|
3432
|
+
return value;
|
|
3433
|
+
}
|
|
3434
|
+
if (value === null) {
|
|
3435
|
+
return "None";
|
|
3436
|
+
}
|
|
3437
|
+
if (typeof value === "boolean") {
|
|
3438
|
+
return value ? "True" : "False";
|
|
3439
|
+
}
|
|
3440
|
+
if (value === void 0) {
|
|
3441
|
+
return "";
|
|
3442
|
+
}
|
|
3443
|
+
if (typeof value === "object") {
|
|
3444
|
+
return JSON.stringify(value);
|
|
3445
|
+
}
|
|
3446
|
+
return String(value);
|
|
3447
|
+
}
|
|
3448
|
+
function appendQwen3CoderToolParserParameter(lines, key, value) {
|
|
3449
|
+
const nameAttr = escapeXmlMinimalAttr(key, '"');
|
|
3450
|
+
const text = escapeXmlMinimalText(toQwen3CoderToolParserParamText(value));
|
|
3451
|
+
lines.push(` <parameter="${nameAttr}">${text}</parameter>`);
|
|
3452
|
+
}
|
|
3453
|
+
function appendQwen3CoderToolParserArgs(lines, args) {
|
|
3454
|
+
if (args && typeof args === "object" && !Array.isArray(args)) {
|
|
3455
|
+
for (const [key, value] of Object.entries(args)) {
|
|
3456
|
+
if (Array.isArray(value)) {
|
|
3457
|
+
for (const item of value) {
|
|
3458
|
+
appendQwen3CoderToolParserParameter(lines, key, item);
|
|
3459
|
+
}
|
|
3460
|
+
} else {
|
|
3461
|
+
appendQwen3CoderToolParserParameter(lines, key, value);
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
return;
|
|
3465
|
+
}
|
|
3466
|
+
if (args !== void 0 && args !== null && args !== "") {
|
|
3467
|
+
appendQwen3CoderToolParserParameter(lines, "input", args);
|
|
3468
|
+
}
|
|
3469
|
+
}
|
|
3470
|
+
var qwen3CoderProtocol = () => ({
|
|
3471
|
+
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
3472
|
+
return formatToolsWithPromptTemplate({ tools, toolSystemPromptTemplate });
|
|
3473
|
+
},
|
|
3474
|
+
formatToolCall(toolCall) {
|
|
3475
|
+
const args = parseToolCallInput(toolCall.input);
|
|
3476
|
+
const lines = ["<tool_call>"];
|
|
3477
|
+
lines.push(
|
|
3478
|
+
` <function="${escapeXmlMinimalAttr(toolCall.toolName, '"')}">`
|
|
3479
|
+
);
|
|
3480
|
+
appendQwen3CoderToolParserArgs(lines, args);
|
|
3481
|
+
lines.push(" </function>");
|
|
3482
|
+
lines.push("</tool_call>");
|
|
3483
|
+
return lines.join("\n");
|
|
3484
|
+
},
|
|
3485
|
+
parseGeneratedText({ text, tools, options }) {
|
|
3486
|
+
const processedElements = [];
|
|
3487
|
+
const emitToolCalls = (calls) => {
|
|
3488
|
+
for (const call of calls) {
|
|
3489
|
+
processedElements.push({
|
|
3490
|
+
type: "tool-call",
|
|
3491
|
+
toolCallId: generateToolCallId(),
|
|
3492
|
+
toolName: call.toolName,
|
|
3493
|
+
input: stringifyToolInputWithSchema({
|
|
3494
|
+
tools,
|
|
3495
|
+
toolName: call.toolName,
|
|
3496
|
+
args: call.args
|
|
3497
|
+
})
|
|
3498
|
+
});
|
|
3499
|
+
}
|
|
3500
|
+
};
|
|
3501
|
+
const pushText = (value) => {
|
|
3502
|
+
if (value.length === 0) {
|
|
3503
|
+
return;
|
|
3504
|
+
}
|
|
3505
|
+
processedElements.push({ type: "text", text: value });
|
|
3506
|
+
};
|
|
3507
|
+
const tryEmitToolCallSegment = (segment, fallbackText = segment) => {
|
|
3508
|
+
var _a;
|
|
3509
|
+
const parsedCalls = parseQwen3CoderToolParserToolCallSegment(segment);
|
|
3510
|
+
if (!parsedCalls) {
|
|
3511
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
3512
|
+
options,
|
|
3513
|
+
"Could not process Qwen3CoderToolParser XML tool call; keeping original text.",
|
|
3514
|
+
{ toolCall: fallbackText }
|
|
3515
|
+
);
|
|
3516
|
+
processedElements.push({ type: "text", text: fallbackText });
|
|
3517
|
+
return false;
|
|
3518
|
+
}
|
|
3519
|
+
emitToolCalls(parsedCalls);
|
|
3520
|
+
return true;
|
|
3521
|
+
};
|
|
3522
|
+
const emitWrapperlessCallParseFailureAsText = (raw) => {
|
|
3523
|
+
var _a;
|
|
3524
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
3525
|
+
options,
|
|
3526
|
+
"Could not process Qwen3CoderToolParser <function> call; keeping original text.",
|
|
3527
|
+
{ toolCall: raw }
|
|
3528
|
+
);
|
|
3529
|
+
processedElements.push({ type: "text", text: raw });
|
|
3530
|
+
};
|
|
3531
|
+
const tryParseCallBlocksWithoutWrapperByImplicitStarts = (sourceText, starts) => {
|
|
3532
|
+
var _a, _b;
|
|
3533
|
+
let index = 0;
|
|
3534
|
+
for (let i = 0; i < starts.length; i += 1) {
|
|
3535
|
+
const startIndex = (_a = starts[i]) != null ? _a : -1;
|
|
3536
|
+
if (startIndex < 0) {
|
|
3537
|
+
continue;
|
|
3538
|
+
}
|
|
3539
|
+
const endIndex = (_b = starts[i + 1]) != null ? _b : sourceText.length;
|
|
3540
|
+
pushText(
|
|
3541
|
+
stripTrailingToolCallCloseTags(
|
|
3542
|
+
stripLeadingToolCallCloseTags(sourceText.slice(index, startIndex))
|
|
3543
|
+
)
|
|
3544
|
+
);
|
|
3545
|
+
const full = sourceText.slice(startIndex, endIndex);
|
|
3546
|
+
const { callContent, trailingText } = splitImplicitCallAndTail(full);
|
|
3547
|
+
const parsed = parseSingleFunctionCallXml(callContent, null);
|
|
3548
|
+
if (parsed) {
|
|
3549
|
+
emitToolCalls([parsed]);
|
|
3550
|
+
pushText(
|
|
3551
|
+
stripTrailingToolCallCloseTags(
|
|
3552
|
+
stripLeadingToolCallCloseTags(trailingText)
|
|
3553
|
+
)
|
|
3554
|
+
);
|
|
3555
|
+
} else {
|
|
3556
|
+
emitWrapperlessCallParseFailureAsText(full);
|
|
3557
|
+
}
|
|
3558
|
+
index = endIndex;
|
|
3559
|
+
}
|
|
3560
|
+
pushText(
|
|
3561
|
+
stripTrailingToolCallCloseTags(
|
|
3562
|
+
stripLeadingToolCallCloseTags(sourceText.slice(index))
|
|
3563
|
+
)
|
|
3564
|
+
);
|
|
3565
|
+
return true;
|
|
3566
|
+
};
|
|
3567
|
+
const tryParseCallBlocksWithoutWrapperByMatches = (sourceText, matches) => {
|
|
3568
|
+
var _a;
|
|
3569
|
+
let index = 0;
|
|
3570
|
+
for (const match of matches) {
|
|
3571
|
+
const full = match[0];
|
|
3572
|
+
const startIndex = (_a = match.index) != null ? _a : -1;
|
|
3573
|
+
if (!full || startIndex < 0) {
|
|
3574
|
+
continue;
|
|
3575
|
+
}
|
|
3576
|
+
pushText(
|
|
3577
|
+
stripTrailingToolCallCloseTags(
|
|
3578
|
+
stripLeadingToolCallCloseTags(sourceText.slice(index, startIndex))
|
|
3579
|
+
)
|
|
3580
|
+
);
|
|
3581
|
+
const parsed = parseSingleFunctionCallXml(full, null);
|
|
3582
|
+
if (parsed) {
|
|
3583
|
+
emitToolCalls([parsed]);
|
|
3584
|
+
} else {
|
|
3585
|
+
emitWrapperlessCallParseFailureAsText(full);
|
|
3586
|
+
}
|
|
3587
|
+
index = startIndex + full.length;
|
|
3588
|
+
}
|
|
3589
|
+
const trailing = sourceText.slice(index);
|
|
3590
|
+
const trailingStarts = findImplicitCallOpenIndices(
|
|
3591
|
+
trailing.toLowerCase()
|
|
3592
|
+
);
|
|
3593
|
+
if (trailingStarts.length > 0) {
|
|
3594
|
+
return tryParseCallBlocksWithoutWrapperByImplicitStarts(
|
|
3595
|
+
trailing,
|
|
3596
|
+
trailingStarts
|
|
3597
|
+
);
|
|
3598
|
+
}
|
|
3599
|
+
pushText(
|
|
3600
|
+
stripTrailingToolCallCloseTags(stripLeadingToolCallCloseTags(trailing))
|
|
3601
|
+
);
|
|
3602
|
+
return true;
|
|
3603
|
+
};
|
|
3604
|
+
const tryParseCallBlocksWithoutWrapperText = (sourceText) => {
|
|
3605
|
+
const matches = Array.from(sourceText.matchAll(CALL_BLOCK_RE));
|
|
3606
|
+
if (matches.length > 0) {
|
|
3607
|
+
return tryParseCallBlocksWithoutWrapperByMatches(sourceText, matches);
|
|
3608
|
+
}
|
|
3609
|
+
const starts = findImplicitCallOpenIndices(sourceText.toLowerCase());
|
|
3610
|
+
if (starts.length === 0) {
|
|
3611
|
+
return false;
|
|
3612
|
+
}
|
|
3613
|
+
return tryParseCallBlocksWithoutWrapperByImplicitStarts(
|
|
3614
|
+
sourceText,
|
|
3615
|
+
starts
|
|
3616
|
+
);
|
|
3617
|
+
};
|
|
3618
|
+
const pushTextOrParseWrapperlessCalls = (segment) => {
|
|
3619
|
+
if (segment.length === 0) {
|
|
3620
|
+
return;
|
|
3621
|
+
}
|
|
3622
|
+
if (!tryParseCallBlocksWithoutWrapperText(segment)) {
|
|
3623
|
+
pushText(segment);
|
|
3624
|
+
}
|
|
3625
|
+
};
|
|
3626
|
+
const handleCompleteToolCallRemainder = (remainder) => {
|
|
3627
|
+
if (!remainder) {
|
|
3628
|
+
return;
|
|
3629
|
+
}
|
|
3630
|
+
const lowerRemainder = remainder.toLowerCase();
|
|
3631
|
+
const trailingIndex = lowerRemainder.indexOf("<tool_call");
|
|
3632
|
+
if (trailingIndex === -1) {
|
|
3633
|
+
pushTextOrParseWrapperlessCalls(remainder);
|
|
3634
|
+
return;
|
|
3635
|
+
}
|
|
3636
|
+
pushTextOrParseWrapperlessCalls(remainder.slice(0, trailingIndex));
|
|
3637
|
+
const trailing = remainder.slice(trailingIndex);
|
|
3638
|
+
const synthetic = TOOL_CALL_CLOSE_RE.test(trailing) ? trailing : `${trailing}</tool_call>`;
|
|
3639
|
+
tryEmitToolCallSegment(synthetic, trailing);
|
|
3640
|
+
};
|
|
3641
|
+
const tryParseCompleteToolCallBlocks = () => {
|
|
3642
|
+
var _a;
|
|
3643
|
+
const matches = Array.from(text.matchAll(TOOL_CALL_BLOCK_RE));
|
|
3644
|
+
if (matches.length === 0) {
|
|
3645
|
+
return false;
|
|
3646
|
+
}
|
|
3647
|
+
let index = 0;
|
|
3648
|
+
for (const match of matches) {
|
|
3649
|
+
const full = match[0];
|
|
3650
|
+
const startIndex = (_a = match.index) != null ? _a : -1;
|
|
3651
|
+
if (!full || startIndex < 0) {
|
|
3652
|
+
continue;
|
|
3653
|
+
}
|
|
3654
|
+
pushTextOrParseWrapperlessCalls(text.slice(index, startIndex));
|
|
3655
|
+
tryEmitToolCallSegment(full);
|
|
3656
|
+
index = startIndex + full.length;
|
|
3657
|
+
}
|
|
3658
|
+
handleCompleteToolCallRemainder(text.slice(index));
|
|
3659
|
+
return true;
|
|
3660
|
+
};
|
|
3661
|
+
const tryParseIncompleteToolCall = () => {
|
|
3662
|
+
const lowerText = text.toLowerCase();
|
|
3663
|
+
const startIndex = lowerText.indexOf("<tool_call");
|
|
3664
|
+
if (startIndex === -1) {
|
|
3665
|
+
return false;
|
|
3666
|
+
}
|
|
3667
|
+
pushTextOrParseWrapperlessCalls(text.slice(0, startIndex));
|
|
3668
|
+
const trailing = text.slice(startIndex);
|
|
3669
|
+
const synthetic = TOOL_CALL_CLOSE_RE.test(trailing) ? trailing : `${trailing}</tool_call>`;
|
|
3670
|
+
tryEmitToolCallSegment(synthetic, trailing);
|
|
3671
|
+
return true;
|
|
3672
|
+
};
|
|
3673
|
+
const tryParseCallBlocksWithoutWrapper = () => {
|
|
3674
|
+
return tryParseCallBlocksWithoutWrapperText(text);
|
|
3675
|
+
};
|
|
3676
|
+
const tryParseSingleFunctionCall = () => {
|
|
3677
|
+
const lowerText = text.toLowerCase();
|
|
3678
|
+
const startIndex = lowerText.indexOf("<function");
|
|
3679
|
+
if (startIndex === -1) {
|
|
3680
|
+
return false;
|
|
3681
|
+
}
|
|
3682
|
+
pushText(stripTrailingToolCallCloseTags(text.slice(0, startIndex)));
|
|
3683
|
+
const trailing = stripLeadingToolCallCloseTags(text.slice(startIndex));
|
|
3684
|
+
const parsed = parseSingleFunctionCallXml(trailing, null);
|
|
3685
|
+
if (!parsed) {
|
|
3686
|
+
processedElements.push({ type: "text", text: trailing });
|
|
3687
|
+
return true;
|
|
3688
|
+
}
|
|
3689
|
+
emitToolCalls([parsed]);
|
|
3690
|
+
return true;
|
|
3691
|
+
};
|
|
3692
|
+
if (tryParseCompleteToolCallBlocks()) {
|
|
3693
|
+
return processedElements;
|
|
3694
|
+
}
|
|
3695
|
+
if (tryParseIncompleteToolCall()) {
|
|
3696
|
+
return processedElements;
|
|
3697
|
+
}
|
|
3698
|
+
if (tryParseCallBlocksWithoutWrapper()) {
|
|
3699
|
+
return processedElements;
|
|
3700
|
+
}
|
|
3701
|
+
if (tryParseSingleFunctionCall()) {
|
|
3702
|
+
return processedElements;
|
|
3703
|
+
}
|
|
3704
|
+
return [{ type: "text", text }];
|
|
3705
|
+
},
|
|
3706
|
+
extractToolCallSegments({ text }) {
|
|
3707
|
+
return Array.from(text.matchAll(TOOL_CALL_BLOCK_RE)).map((m) => m[0]).filter((s) => Boolean(s));
|
|
3708
|
+
},
|
|
3709
|
+
createStreamParser({ tools, options }) {
|
|
3710
|
+
const toolCallStartPrefixLower = "<tool_call";
|
|
3711
|
+
const implicitCallPrefixesLower = [
|
|
3712
|
+
"<function",
|
|
3713
|
+
"<call",
|
|
3714
|
+
"<tool",
|
|
3715
|
+
"<invoke"
|
|
3716
|
+
];
|
|
3717
|
+
let buffer = "";
|
|
3718
|
+
let toolCall = null;
|
|
3719
|
+
let implicitCall = null;
|
|
3720
|
+
let implicitCallOpenTag = null;
|
|
3721
|
+
let currentTextId = null;
|
|
3722
|
+
let hasEmittedTextStart = false;
|
|
3723
|
+
const flushText = createFlushTextHandler(
|
|
3724
|
+
() => currentTextId,
|
|
3725
|
+
(id) => {
|
|
3726
|
+
currentTextId = id;
|
|
3727
|
+
},
|
|
3728
|
+
() => hasEmittedTextStart,
|
|
3729
|
+
(value) => {
|
|
3730
|
+
hasEmittedTextStart = value;
|
|
3731
|
+
}
|
|
3732
|
+
);
|
|
3733
|
+
const maybeEmitToolInputStart = (controller, callState) => {
|
|
3734
|
+
if (callState.hasEmittedStart) {
|
|
3735
|
+
return;
|
|
3736
|
+
}
|
|
3737
|
+
const toolName = callState.toolName;
|
|
3738
|
+
if (!toolName || toolName.trim().length === 0) {
|
|
3739
|
+
return;
|
|
3740
|
+
}
|
|
3741
|
+
flushText(controller);
|
|
3742
|
+
controller.enqueue({
|
|
3743
|
+
type: "tool-input-start",
|
|
3744
|
+
id: callState.toolCallId,
|
|
3745
|
+
toolName
|
|
3746
|
+
});
|
|
3747
|
+
callState.hasEmittedStart = true;
|
|
3748
|
+
};
|
|
3749
|
+
const maybeEmitToolInputProgress = (controller, callState) => {
|
|
3750
|
+
if (!callState.hasEmittedStart) {
|
|
3751
|
+
return;
|
|
3752
|
+
}
|
|
3753
|
+
const toolName = callState.toolName;
|
|
3754
|
+
if (!toolName) {
|
|
3755
|
+
return;
|
|
3756
|
+
}
|
|
3757
|
+
const argsForProgress = mergeArgsWithPartialParam(
|
|
3758
|
+
callState.args,
|
|
3759
|
+
callState.partialParam
|
|
3760
|
+
);
|
|
3761
|
+
const fullInput = stringifyToolInputWithSchema({
|
|
3762
|
+
tools,
|
|
3763
|
+
toolName,
|
|
3764
|
+
args: argsForProgress
|
|
3765
|
+
});
|
|
3766
|
+
if (fullInput === "{}") {
|
|
3767
|
+
return;
|
|
3768
|
+
}
|
|
3769
|
+
emitToolInputProgressDelta({
|
|
3770
|
+
controller,
|
|
3771
|
+
id: callState.toolCallId,
|
|
3772
|
+
state: callState,
|
|
3773
|
+
fullInput
|
|
3774
|
+
});
|
|
3775
|
+
};
|
|
3776
|
+
const finalizeCall = (controller, callState, fallbackToolName, rawToolCallText = null) => {
|
|
3777
|
+
var _a, _b;
|
|
3778
|
+
const resolvedToolName = (_a = callState.toolName) != null ? _a : fallbackToolName;
|
|
3779
|
+
if (!resolvedToolName || resolvedToolName.trim().length === 0) {
|
|
3780
|
+
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
3781
|
+
emitFailedToolInputLifecycle({
|
|
3782
|
+
controller,
|
|
3783
|
+
id: callState.toolCallId,
|
|
3784
|
+
endInput: callState.hasEmittedStart,
|
|
3785
|
+
emitRawToolCallTextOnError: shouldEmitRaw,
|
|
3786
|
+
rawToolCallText,
|
|
3787
|
+
emitRawText: (rawText) => {
|
|
3788
|
+
flushText(controller, rawText);
|
|
3789
|
+
}
|
|
3790
|
+
});
|
|
3791
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
3792
|
+
options,
|
|
3793
|
+
shouldEmitRaw && rawToolCallText ? "Could not resolve Qwen3CoderToolParser tool name for tool call; emitting original text." : "Could not resolve Qwen3CoderToolParser tool name for tool call",
|
|
3794
|
+
{
|
|
3795
|
+
toolCallId: callState.toolCallId,
|
|
3796
|
+
toolCall: rawToolCallText
|
|
3797
|
+
}
|
|
3798
|
+
);
|
|
3799
|
+
return false;
|
|
3800
|
+
}
|
|
3801
|
+
callState.toolName = resolvedToolName;
|
|
3802
|
+
maybeEmitToolInputStart(controller, callState);
|
|
3803
|
+
maybeEmitToolInputProgress(controller, callState);
|
|
3804
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
3805
|
+
tools,
|
|
3806
|
+
toolName: resolvedToolName,
|
|
3807
|
+
args: callState.args
|
|
3808
|
+
});
|
|
3809
|
+
emitFinalizedToolInputLifecycle({
|
|
3810
|
+
controller,
|
|
3811
|
+
id: callState.toolCallId,
|
|
3812
|
+
state: callState,
|
|
3813
|
+
toolName: resolvedToolName,
|
|
3814
|
+
finalInput,
|
|
3815
|
+
onMismatch: options == null ? void 0 : options.onError
|
|
3816
|
+
});
|
|
3817
|
+
return true;
|
|
3818
|
+
};
|
|
3819
|
+
const parseStreamingCallContent = (controller, callState, content, allowEndOfString) => parseCallContent({
|
|
3820
|
+
callState,
|
|
3821
|
+
content,
|
|
3822
|
+
allowEndOfString,
|
|
3823
|
+
nameTagRe: QWEN3CODER_TOOL_PARSER_STREAM_NAME_TAG_RE,
|
|
3824
|
+
normalizeXmlTextValue,
|
|
3825
|
+
parseParamTagAt: parseQwen3CoderToolParserParamTagAt,
|
|
3826
|
+
mergeParamValue,
|
|
3827
|
+
maybeEmitToolInputStart: () => {
|
|
3828
|
+
maybeEmitToolInputStart(controller, callState);
|
|
3829
|
+
},
|
|
3830
|
+
maybeEmitToolInputProgress: () => {
|
|
3831
|
+
maybeEmitToolInputProgress(controller, callState);
|
|
3832
|
+
}
|
|
3833
|
+
});
|
|
3834
|
+
const closeTagCache = /* @__PURE__ */ new Map();
|
|
3835
|
+
const getCloseTagPattern = (endTagName) => {
|
|
3836
|
+
const cached = closeTagCache.get(endTagName);
|
|
3837
|
+
if (cached) {
|
|
3838
|
+
return cached;
|
|
3839
|
+
}
|
|
3840
|
+
const created = new RegExp(
|
|
3841
|
+
`<\\s*\\/\\s*${escapeRegExp(endTagName)}\\s*>`,
|
|
3842
|
+
"i"
|
|
3843
|
+
);
|
|
3844
|
+
closeTagCache.set(endTagName, created);
|
|
3845
|
+
return created;
|
|
3846
|
+
};
|
|
3847
|
+
const getNextCallStartInBuffer = (callState) => {
|
|
3848
|
+
var _a;
|
|
3849
|
+
if (callState.endTagName === "tool_call") {
|
|
3850
|
+
return -1;
|
|
3851
|
+
}
|
|
3852
|
+
const match = QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE.exec(
|
|
3853
|
+
callState.buffer
|
|
3854
|
+
);
|
|
3855
|
+
return (_a = match == null ? void 0 : match.index) != null ? _a : -1;
|
|
3856
|
+
};
|
|
3857
|
+
const finalizeStreamingCall = (controller, callState, fallbackToolName, remainder) => {
|
|
3858
|
+
const rawToolCallText = remainder.length > 0 && callState.raw.endsWith(remainder) ? callState.raw.slice(0, -remainder.length) : callState.raw;
|
|
3859
|
+
const ok = finalizeCall(
|
|
3860
|
+
controller,
|
|
3861
|
+
callState,
|
|
3862
|
+
fallbackToolName,
|
|
3863
|
+
rawToolCallText
|
|
3864
|
+
);
|
|
3865
|
+
if (ok && toolCall) {
|
|
3866
|
+
toolCall.emittedToolCallCount += 1;
|
|
3867
|
+
}
|
|
3868
|
+
};
|
|
3869
|
+
const consumeCallAtNextBoundary = (controller, callState, fallbackToolName, nextCallStart) => {
|
|
3870
|
+
const beforeNextCall = callState.buffer.slice(0, nextCallStart);
|
|
3871
|
+
const afterNextCall = callState.buffer.slice(nextCallStart);
|
|
3872
|
+
callState.buffer = parseStreamingCallContent(
|
|
3873
|
+
controller,
|
|
3874
|
+
callState,
|
|
3875
|
+
beforeNextCall,
|
|
3876
|
+
true
|
|
3877
|
+
);
|
|
3878
|
+
finalizeStreamingCall(
|
|
3879
|
+
controller,
|
|
3880
|
+
callState,
|
|
3881
|
+
fallbackToolName,
|
|
3882
|
+
afterNextCall
|
|
3883
|
+
);
|
|
3884
|
+
return { done: true, remainder: afterNextCall };
|
|
3885
|
+
};
|
|
3886
|
+
const consumeCall = (controller, callState, incoming, fallbackToolName) => {
|
|
3887
|
+
var _a, _b, _c;
|
|
3888
|
+
callState.buffer += incoming;
|
|
3889
|
+
callState.raw += incoming;
|
|
3890
|
+
const closeMatch = getCloseTagPattern(callState.endTagName).exec(
|
|
3891
|
+
callState.buffer
|
|
3892
|
+
);
|
|
3893
|
+
const closeStart = (_a = closeMatch == null ? void 0 : closeMatch.index) != null ? _a : -1;
|
|
3894
|
+
const nextCallStart = getNextCallStartInBuffer(callState);
|
|
3895
|
+
const shouldCloseAtNextBoundary = nextCallStart !== -1 && (closeStart === -1 || nextCallStart < closeStart);
|
|
3896
|
+
if (shouldCloseAtNextBoundary) {
|
|
3897
|
+
return consumeCallAtNextBoundary(
|
|
3898
|
+
controller,
|
|
3899
|
+
callState,
|
|
3900
|
+
fallbackToolName,
|
|
3901
|
+
nextCallStart
|
|
3902
|
+
);
|
|
3903
|
+
}
|
|
3904
|
+
if (!closeMatch) {
|
|
3905
|
+
callState.buffer = parseStreamingCallContent(
|
|
3906
|
+
controller,
|
|
3907
|
+
callState,
|
|
3908
|
+
callState.buffer,
|
|
3909
|
+
false
|
|
3910
|
+
);
|
|
3911
|
+
return { done: false, remainder: "" };
|
|
3912
|
+
}
|
|
3913
|
+
const closeEnd = closeStart + ((_c = (_b = closeMatch[0]) == null ? void 0 : _b.length) != null ? _c : 0);
|
|
3914
|
+
const beforeClose = callState.buffer.slice(0, closeStart);
|
|
3915
|
+
const afterClose = callState.buffer.slice(closeEnd);
|
|
3916
|
+
parseStreamingCallContent(controller, callState, beforeClose, true);
|
|
3917
|
+
callState.buffer = "";
|
|
3918
|
+
finalizeStreamingCall(
|
|
3919
|
+
controller,
|
|
3920
|
+
callState,
|
|
3921
|
+
fallbackToolName,
|
|
3922
|
+
afterClose
|
|
3923
|
+
);
|
|
3924
|
+
return { done: true, remainder: afterClose };
|
|
3925
|
+
};
|
|
3926
|
+
const finalizeCallAtFinish = (controller, callState, fallbackToolName) => {
|
|
3927
|
+
callState.buffer = parseStreamingCallContent(
|
|
3928
|
+
controller,
|
|
3929
|
+
callState,
|
|
3930
|
+
callState.buffer,
|
|
3931
|
+
true
|
|
3932
|
+
);
|
|
3933
|
+
const trailingText = stripLeadingCallCloseTags(callState.buffer);
|
|
3934
|
+
callState.buffer = "";
|
|
3935
|
+
const ok = finalizeCall(controller, callState, fallbackToolName, null);
|
|
3936
|
+
return {
|
|
3937
|
+
ok,
|
|
3938
|
+
trailingText
|
|
3939
|
+
};
|
|
3940
|
+
};
|
|
3941
|
+
const flushSafeTextPrefix = (controller) => {
|
|
3942
|
+
const lower = buffer.toLowerCase();
|
|
3943
|
+
const potentialIndices = [
|
|
3944
|
+
getPotentialStartIndex(lower, toolCallStartPrefixLower),
|
|
3945
|
+
...implicitCallPrefixesLower.map(
|
|
3946
|
+
(prefix) => getPotentialStartIndex(lower, prefix)
|
|
3947
|
+
)
|
|
3948
|
+
].filter((value) => value != null);
|
|
3949
|
+
const potentialIndex = potentialIndices.length > 0 ? Math.min(...potentialIndices) : null;
|
|
3950
|
+
if (potentialIndex == null) {
|
|
3951
|
+
if (buffer.length > 0) {
|
|
3952
|
+
flushText(controller, buffer);
|
|
3953
|
+
buffer = "";
|
|
3954
|
+
}
|
|
3955
|
+
return;
|
|
3956
|
+
}
|
|
3957
|
+
if (potentialIndex > 0) {
|
|
3958
|
+
flushText(controller, buffer.slice(0, potentialIndex));
|
|
3959
|
+
buffer = buffer.slice(potentialIndex);
|
|
3960
|
+
}
|
|
3961
|
+
};
|
|
3962
|
+
const stripLeadingToolCallCloseTagsFromBuffer = () => {
|
|
3963
|
+
if (!buffer) {
|
|
3964
|
+
return;
|
|
3965
|
+
}
|
|
3966
|
+
const stripped = stripLeadingToolCallCloseTags(buffer);
|
|
3967
|
+
if (stripped !== buffer) {
|
|
3968
|
+
buffer = stripped;
|
|
3969
|
+
}
|
|
3970
|
+
};
|
|
3971
|
+
const startToolCallIfPresent = (_controller) => {
|
|
3972
|
+
if (toolCall) {
|
|
3973
|
+
return;
|
|
3974
|
+
}
|
|
3975
|
+
if (implicitCall) {
|
|
3976
|
+
return;
|
|
3977
|
+
}
|
|
3978
|
+
const lower = buffer.toLowerCase();
|
|
3979
|
+
const startIndex = getPotentialStartIndex(
|
|
3980
|
+
lower,
|
|
3981
|
+
toolCallStartPrefixLower
|
|
3982
|
+
);
|
|
3983
|
+
if (startIndex == null || startIndex !== 0) {
|
|
3984
|
+
return;
|
|
3985
|
+
}
|
|
3986
|
+
const gtIndex = buffer.indexOf(">");
|
|
3987
|
+
if (gtIndex === -1) {
|
|
3988
|
+
return;
|
|
3989
|
+
}
|
|
3990
|
+
const openTag = buffer.slice(0, gtIndex + 1);
|
|
3991
|
+
if (!TOOL_CALL_OPEN_RE.test(openTag)) {
|
|
3992
|
+
return;
|
|
3993
|
+
}
|
|
3994
|
+
toolCall = {
|
|
3995
|
+
outerOpenTag: openTag,
|
|
3996
|
+
outerNameAttr: getAttributeValue(openTag, "name"),
|
|
3997
|
+
raw: openTag,
|
|
3998
|
+
mode: "unknown",
|
|
3999
|
+
innerBuffer: "",
|
|
4000
|
+
activeCall: null,
|
|
4001
|
+
emittedToolCallCount: 0
|
|
4002
|
+
};
|
|
4003
|
+
const remainder = buffer.slice(gtIndex + 1);
|
|
4004
|
+
buffer = "";
|
|
4005
|
+
if (remainder.length > 0) {
|
|
4006
|
+
toolCall.raw += remainder;
|
|
4007
|
+
toolCall.innerBuffer += remainder;
|
|
4008
|
+
}
|
|
4009
|
+
};
|
|
4010
|
+
const startImplicitCallIfPresent = (controller) => {
|
|
4011
|
+
var _a, _b, _c, _d;
|
|
4012
|
+
if (toolCall || implicitCall) {
|
|
4013
|
+
return;
|
|
4014
|
+
}
|
|
4015
|
+
const match = QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE.exec(buffer);
|
|
4016
|
+
const startIndex = (_a = match == null ? void 0 : match.index) != null ? _a : -1;
|
|
4017
|
+
const openTag = (_b = match == null ? void 0 : match[0]) != null ? _b : "";
|
|
4018
|
+
const callTagName = ((_c = match == null ? void 0 : match[1]) != null ? _c : "").toLowerCase();
|
|
4019
|
+
if (!match || startIndex !== 0 || !openTag || !callTagName) {
|
|
4020
|
+
return;
|
|
4021
|
+
}
|
|
4022
|
+
const inlineToolName = (_d = getAttributeValue(openTag, "name")) != null ? _d : getShorthandValue(openTag);
|
|
4023
|
+
if (!inlineToolName || inlineToolName.trim().length === 0) {
|
|
4024
|
+
return;
|
|
4025
|
+
}
|
|
4026
|
+
const selfClosing = QWEN3CODER_TOOL_PARSER_STREAM_SELF_CLOSING_TAG_RE.test(openTag);
|
|
4027
|
+
buffer = buffer.slice(openTag.length);
|
|
4028
|
+
const newCall = {
|
|
4029
|
+
endTagName: callTagName,
|
|
4030
|
+
toolCallId: generateToolCallId(),
|
|
4031
|
+
toolName: inlineToolName,
|
|
4032
|
+
hasEmittedStart: false,
|
|
4033
|
+
partialParam: null,
|
|
4034
|
+
emittedInput: "",
|
|
4035
|
+
raw: openTag,
|
|
4036
|
+
args: {},
|
|
4037
|
+
buffer: ""
|
|
4038
|
+
};
|
|
4039
|
+
maybeEmitToolInputStart(controller, newCall);
|
|
4040
|
+
if (selfClosing) {
|
|
4041
|
+
finalizeCall(controller, newCall, inlineToolName, newCall.raw);
|
|
4042
|
+
return;
|
|
4043
|
+
}
|
|
4044
|
+
implicitCall = newCall;
|
|
4045
|
+
implicitCallOpenTag = openTag;
|
|
4046
|
+
};
|
|
4047
|
+
const processImplicitCall = (controller) => {
|
|
4048
|
+
while (implicitCall) {
|
|
4049
|
+
const callState = implicitCall;
|
|
4050
|
+
const { done, remainder } = consumeCall(
|
|
4051
|
+
controller,
|
|
4052
|
+
callState,
|
|
4053
|
+
buffer,
|
|
4054
|
+
null
|
|
4055
|
+
);
|
|
4056
|
+
buffer = "";
|
|
4057
|
+
if (!done) {
|
|
4058
|
+
return;
|
|
4059
|
+
}
|
|
4060
|
+
implicitCall = null;
|
|
4061
|
+
implicitCallOpenTag = null;
|
|
4062
|
+
if (remainder.length > 0) {
|
|
4063
|
+
buffer = remainder;
|
|
4064
|
+
}
|
|
4065
|
+
stripLeadingToolCallCloseTagsFromBuffer();
|
|
4066
|
+
flushSafeTextPrefix(controller);
|
|
4067
|
+
startToolCallIfPresent(controller);
|
|
4068
|
+
if (toolCall) {
|
|
4069
|
+
processToolCall2(controller);
|
|
4070
|
+
return;
|
|
4071
|
+
}
|
|
4072
|
+
startImplicitCallIfPresent(controller);
|
|
4073
|
+
}
|
|
4074
|
+
};
|
|
4075
|
+
const drainStarts = (controller) => {
|
|
4076
|
+
while (true) {
|
|
4077
|
+
if (toolCall || implicitCall) {
|
|
4078
|
+
return;
|
|
4079
|
+
}
|
|
4080
|
+
const before = buffer;
|
|
4081
|
+
startToolCallIfPresent(controller);
|
|
4082
|
+
if (toolCall) {
|
|
4083
|
+
processToolCall2(controller);
|
|
4084
|
+
return;
|
|
4085
|
+
}
|
|
4086
|
+
startImplicitCallIfPresent(controller);
|
|
4087
|
+
if (implicitCall) {
|
|
4088
|
+
processImplicitCall(controller);
|
|
4089
|
+
return;
|
|
4090
|
+
}
|
|
4091
|
+
if (buffer === before) {
|
|
4092
|
+
return;
|
|
4093
|
+
}
|
|
4094
|
+
stripLeadingToolCallCloseTagsFromBuffer();
|
|
4095
|
+
flushSafeTextPrefix(controller);
|
|
4096
|
+
}
|
|
4097
|
+
};
|
|
4098
|
+
const processToolCall2 = (controller) => {
|
|
4099
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
4100
|
+
while (toolCall) {
|
|
4101
|
+
if (toolCall.mode === "unknown") {
|
|
4102
|
+
const callMatch = QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_START_RE.exec(
|
|
4103
|
+
toolCall.innerBuffer
|
|
4104
|
+
);
|
|
4105
|
+
const signalMatch = QWEN3CODER_TOOL_PARSER_STREAM_NAME_OR_PARAM_SIGNAL_RE.exec(
|
|
4106
|
+
toolCall.innerBuffer
|
|
4107
|
+
);
|
|
4108
|
+
if (callMatch && (!signalMatch || ((_a = callMatch.index) != null ? _a : 0) < ((_b = signalMatch.index) != null ? _b : 0))) {
|
|
4109
|
+
toolCall.mode = "multi";
|
|
4110
|
+
} else if (signalMatch) {
|
|
4111
|
+
toolCall.mode = "single";
|
|
4112
|
+
const activeCall = {
|
|
4113
|
+
endTagName: "tool_call",
|
|
4114
|
+
toolCallId: generateToolCallId(),
|
|
4115
|
+
toolName: toolCall.outerNameAttr,
|
|
4116
|
+
hasEmittedStart: false,
|
|
4117
|
+
partialParam: null,
|
|
4118
|
+
emittedInput: "",
|
|
4119
|
+
raw: toolCall.outerOpenTag,
|
|
4120
|
+
args: {},
|
|
4121
|
+
buffer: ""
|
|
4122
|
+
};
|
|
4123
|
+
toolCall.activeCall = activeCall;
|
|
4124
|
+
if (toolCall.outerNameAttr) {
|
|
4125
|
+
maybeEmitToolInputStart(controller, activeCall);
|
|
4126
|
+
}
|
|
4127
|
+
} else {
|
|
4128
|
+
return;
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
if (toolCall.mode === "single") {
|
|
4132
|
+
const callState = toolCall.activeCall;
|
|
4133
|
+
if (!callState) {
|
|
4134
|
+
return;
|
|
4135
|
+
}
|
|
4136
|
+
const { done, remainder } = consumeCall(
|
|
4137
|
+
controller,
|
|
4138
|
+
callState,
|
|
4139
|
+
toolCall.innerBuffer,
|
|
4140
|
+
toolCall.outerNameAttr
|
|
4141
|
+
);
|
|
4142
|
+
toolCall.innerBuffer = "";
|
|
4143
|
+
if (!done) {
|
|
4144
|
+
return;
|
|
4145
|
+
}
|
|
4146
|
+
toolCall = null;
|
|
4147
|
+
if (remainder.length > 0) {
|
|
4148
|
+
buffer = remainder + buffer;
|
|
4149
|
+
}
|
|
4150
|
+
flushSafeTextPrefix(controller);
|
|
4151
|
+
startToolCallIfPresent(controller);
|
|
4152
|
+
continue;
|
|
4153
|
+
}
|
|
4154
|
+
if (toolCall.mode === "multi") {
|
|
4155
|
+
if (toolCall.activeCall) {
|
|
4156
|
+
const callState = toolCall.activeCall;
|
|
4157
|
+
const { done, remainder } = consumeCall(
|
|
4158
|
+
controller,
|
|
4159
|
+
callState,
|
|
4160
|
+
toolCall.innerBuffer,
|
|
4161
|
+
toolCall.outerNameAttr
|
|
4162
|
+
);
|
|
4163
|
+
toolCall.innerBuffer = "";
|
|
4164
|
+
if (!done) {
|
|
4165
|
+
return;
|
|
4166
|
+
}
|
|
4167
|
+
toolCall.activeCall = null;
|
|
4168
|
+
toolCall.innerBuffer = remainder;
|
|
4169
|
+
continue;
|
|
4170
|
+
}
|
|
4171
|
+
const closeMatch = QWEN3CODER_TOOL_PARSER_STREAM_TOOL_CALL_CLOSE_TAG_RE.exec(
|
|
4172
|
+
toolCall.innerBuffer
|
|
4173
|
+
);
|
|
4174
|
+
const callOpenMatch = QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_TAG_RE.exec(
|
|
4175
|
+
toolCall.innerBuffer
|
|
4176
|
+
);
|
|
4177
|
+
if (!(closeMatch || callOpenMatch)) {
|
|
4178
|
+
return;
|
|
4179
|
+
}
|
|
4180
|
+
const closeIndex = (_c = closeMatch == null ? void 0 : closeMatch.index) != null ? _c : -1;
|
|
4181
|
+
const callIndex = (_d = callOpenMatch == null ? void 0 : callOpenMatch.index) != null ? _d : -1;
|
|
4182
|
+
const hasClose = closeIndex !== -1;
|
|
4183
|
+
const hasCall = callIndex !== -1;
|
|
4184
|
+
const chooseClose = hasClose && (!hasCall || closeIndex < callIndex);
|
|
4185
|
+
const nextIndex = chooseClose ? closeIndex : callIndex;
|
|
4186
|
+
if (nextIndex > 0) {
|
|
4187
|
+
toolCall.innerBuffer = toolCall.innerBuffer.slice(nextIndex);
|
|
4188
|
+
}
|
|
4189
|
+
if (chooseClose) {
|
|
4190
|
+
const matchLen = (_f = (_e = closeMatch == null ? void 0 : closeMatch[0]) == null ? void 0 : _e.length) != null ? _f : 0;
|
|
4191
|
+
const remainder = toolCall.innerBuffer.slice(matchLen);
|
|
4192
|
+
toolCall = null;
|
|
4193
|
+
if (remainder.length > 0) {
|
|
4194
|
+
buffer = remainder + buffer;
|
|
4195
|
+
}
|
|
4196
|
+
flushSafeTextPrefix(controller);
|
|
4197
|
+
startToolCallIfPresent(controller);
|
|
4198
|
+
continue;
|
|
4199
|
+
}
|
|
4200
|
+
if (!callOpenMatch) {
|
|
4201
|
+
return;
|
|
4202
|
+
}
|
|
4203
|
+
const openTag = (_g = callOpenMatch[0]) != null ? _g : "";
|
|
4204
|
+
const callTagName = ((_h = callOpenMatch[1]) != null ? _h : "").toLowerCase();
|
|
4205
|
+
const rest = toolCall.innerBuffer.slice(openTag.length);
|
|
4206
|
+
const selfClosing = QWEN3CODER_TOOL_PARSER_STREAM_SELF_CLOSING_TAG_RE.test(openTag);
|
|
4207
|
+
if (selfClosing) {
|
|
4208
|
+
const toolNameAttr2 = (_j = (_i = getAttributeValue(openTag, "name")) != null ? _i : getShorthandValue(openTag)) != null ? _j : toolCall.outerNameAttr;
|
|
4209
|
+
const immediateCall = {
|
|
4210
|
+
endTagName: callTagName,
|
|
4211
|
+
toolCallId: generateToolCallId(),
|
|
4212
|
+
toolName: toolNameAttr2,
|
|
4213
|
+
hasEmittedStart: false,
|
|
4214
|
+
partialParam: null,
|
|
4215
|
+
emittedInput: "",
|
|
4216
|
+
raw: openTag,
|
|
4217
|
+
args: {},
|
|
4218
|
+
buffer: ""
|
|
4219
|
+
};
|
|
4220
|
+
const ok = finalizeCall(
|
|
4221
|
+
controller,
|
|
4222
|
+
immediateCall,
|
|
4223
|
+
toolNameAttr2,
|
|
4224
|
+
immediateCall.raw
|
|
4225
|
+
);
|
|
4226
|
+
if (ok) {
|
|
4227
|
+
toolCall.emittedToolCallCount += 1;
|
|
4228
|
+
}
|
|
4229
|
+
toolCall.innerBuffer = rest;
|
|
4230
|
+
continue;
|
|
4231
|
+
}
|
|
4232
|
+
const toolNameAttr = (_k = getAttributeValue(openTag, "name")) != null ? _k : getShorthandValue(openTag);
|
|
4233
|
+
const newCall = {
|
|
4234
|
+
endTagName: callTagName,
|
|
4235
|
+
toolCallId: generateToolCallId(),
|
|
4236
|
+
toolName: toolNameAttr,
|
|
4237
|
+
hasEmittedStart: false,
|
|
4238
|
+
partialParam: null,
|
|
4239
|
+
emittedInput: "",
|
|
4240
|
+
raw: openTag,
|
|
4241
|
+
args: {},
|
|
4242
|
+
buffer: ""
|
|
4243
|
+
};
|
|
4244
|
+
if (toolNameAttr) {
|
|
4245
|
+
maybeEmitToolInputStart(controller, newCall);
|
|
4246
|
+
}
|
|
4247
|
+
toolCall.activeCall = newCall;
|
|
4248
|
+
toolCall.innerBuffer = rest;
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
4251
|
+
};
|
|
4252
|
+
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall) => {
|
|
4253
|
+
var _a;
|
|
4254
|
+
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
4255
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4256
|
+
options,
|
|
4257
|
+
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser XML tool call at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser XML tool call at finish.",
|
|
4258
|
+
{ toolCall: rawToolCall }
|
|
4259
|
+
);
|
|
4260
|
+
if (shouldEmitRaw) {
|
|
4261
|
+
flushText(controller, rawToolCall);
|
|
4262
|
+
}
|
|
4263
|
+
};
|
|
4264
|
+
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText) => {
|
|
4265
|
+
var _a;
|
|
4266
|
+
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
4267
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4268
|
+
options,
|
|
4269
|
+
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser call block at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser call block at finish.",
|
|
4270
|
+
{ toolCall: rawCallText }
|
|
4271
|
+
);
|
|
4272
|
+
if (shouldEmitRaw) {
|
|
4273
|
+
flushText(controller, rawCallText);
|
|
4274
|
+
}
|
|
4275
|
+
};
|
|
4276
|
+
const handleFinish = (controller) => {
|
|
4277
|
+
var _a, _b;
|
|
4278
|
+
if (toolCall) {
|
|
4279
|
+
processToolCall2(controller);
|
|
4280
|
+
if (toolCall) {
|
|
4281
|
+
if (toolCall.mode === "unknown") {
|
|
4282
|
+
const callMatch = QWEN3CODER_TOOL_PARSER_STREAM_CALL_OPEN_START_RE.exec(
|
|
4283
|
+
toolCall.innerBuffer
|
|
4284
|
+
);
|
|
4285
|
+
const signalMatch = QWEN3CODER_TOOL_PARSER_STREAM_NAME_OR_PARAM_SIGNAL_RE.exec(
|
|
4286
|
+
toolCall.innerBuffer
|
|
4287
|
+
);
|
|
4288
|
+
if (callMatch && (!signalMatch || ((_a = callMatch.index) != null ? _a : 0) < ((_b = signalMatch.index) != null ? _b : 0))) {
|
|
4289
|
+
toolCall.mode = "multi";
|
|
4290
|
+
} else if (signalMatch) {
|
|
4291
|
+
toolCall.mode = "single";
|
|
4292
|
+
toolCall.activeCall = {
|
|
4293
|
+
endTagName: "tool_call",
|
|
4294
|
+
toolCallId: generateToolCallId(),
|
|
4295
|
+
toolName: toolCall.outerNameAttr,
|
|
4296
|
+
hasEmittedStart: false,
|
|
4297
|
+
partialParam: null,
|
|
4298
|
+
emittedInput: "",
|
|
4299
|
+
raw: toolCall.outerOpenTag,
|
|
4300
|
+
args: {},
|
|
4301
|
+
buffer: ""
|
|
4302
|
+
};
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4305
|
+
if (toolCall.mode === "single" && toolCall.activeCall) {
|
|
4306
|
+
toolCall.activeCall.buffer += toolCall.innerBuffer;
|
|
4307
|
+
toolCall.innerBuffer = "";
|
|
4308
|
+
const result = finalizeCallAtFinish(
|
|
4309
|
+
controller,
|
|
4310
|
+
toolCall.activeCall,
|
|
4311
|
+
toolCall.outerNameAttr
|
|
4312
|
+
);
|
|
4313
|
+
if (result.ok) {
|
|
4314
|
+
toolCall.emittedToolCallCount += 1;
|
|
4315
|
+
}
|
|
4316
|
+
const shouldFlushTrailingText = result.ok || !shouldEmitRawToolCallTextOnError(options);
|
|
4317
|
+
if (shouldFlushTrailingText && result.trailingText.length > 0) {
|
|
4318
|
+
flushText(controller, result.trailingText);
|
|
4319
|
+
}
|
|
4320
|
+
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
4321
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw);
|
|
4322
|
+
}
|
|
4323
|
+
} else if (toolCall.mode === "multi") {
|
|
4324
|
+
if (toolCall.activeCall) {
|
|
4325
|
+
const result = finalizeCallAtFinish(
|
|
4326
|
+
controller,
|
|
4327
|
+
toolCall.activeCall,
|
|
4328
|
+
toolCall.outerNameAttr
|
|
4329
|
+
);
|
|
4330
|
+
if (result.ok) {
|
|
4331
|
+
toolCall.emittedToolCallCount += 1;
|
|
4332
|
+
}
|
|
4333
|
+
const shouldFlushTrailingText = result.ok || !shouldEmitRawToolCallTextOnError(options);
|
|
4334
|
+
if (shouldFlushTrailingText && result.trailingText.length > 0) {
|
|
4335
|
+
flushText(controller, result.trailingText);
|
|
4336
|
+
}
|
|
4337
|
+
if (!result.ok && toolCall.emittedToolCallCount === 0) {
|
|
4338
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw);
|
|
4339
|
+
}
|
|
4340
|
+
toolCall.activeCall = null;
|
|
4341
|
+
} else if (toolCall.emittedToolCallCount === 0) {
|
|
4342
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw);
|
|
4343
|
+
}
|
|
4344
|
+
} else {
|
|
4345
|
+
reportUnfinishedToolCallAtFinish(controller, toolCall.raw);
|
|
2240
4346
|
}
|
|
4347
|
+
toolCall = null;
|
|
2241
4348
|
}
|
|
2242
|
-
});
|
|
2243
|
-
},
|
|
2244
|
-
extractToolCallSegments({ text, tools }) {
|
|
2245
|
-
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
2246
|
-
if (toolNames.length === 0) {
|
|
2247
|
-
return [];
|
|
2248
4349
|
}
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
4350
|
+
if (implicitCall) {
|
|
4351
|
+
const callState = implicitCall;
|
|
4352
|
+
const openTag = implicitCallOpenTag;
|
|
4353
|
+
implicitCall = null;
|
|
4354
|
+
implicitCallOpenTag = null;
|
|
4355
|
+
const result = finalizeCallAtFinish(controller, callState, null);
|
|
4356
|
+
const shouldFlushTrailingText = result.ok || !shouldEmitRawToolCallTextOnError(options);
|
|
4357
|
+
if (shouldFlushTrailingText && result.trailingText.length > 0) {
|
|
4358
|
+
flushText(controller, result.trailingText);
|
|
4359
|
+
}
|
|
4360
|
+
if (!result.ok && openTag) {
|
|
4361
|
+
reportUnfinishedImplicitCallAtFinish(
|
|
4362
|
+
controller,
|
|
4363
|
+
callState.raw || openTag + callState.buffer
|
|
4364
|
+
);
|
|
4365
|
+
}
|
|
4366
|
+
} else {
|
|
4367
|
+
stripLeadingToolCallCloseTagsFromBuffer();
|
|
4368
|
+
flushSafeTextPrefix(controller);
|
|
4369
|
+
drainStarts(controller);
|
|
4370
|
+
}
|
|
4371
|
+
if (buffer.length > 0) {
|
|
4372
|
+
flushText(controller, buffer);
|
|
4373
|
+
buffer = "";
|
|
4374
|
+
}
|
|
4375
|
+
flushText(controller);
|
|
4376
|
+
};
|
|
4377
|
+
const handlePassthroughChunk = (controller, chunk) => {
|
|
4378
|
+
if (!toolCall && buffer) {
|
|
4379
|
+
flushText(controller, buffer);
|
|
4380
|
+
buffer = "";
|
|
4381
|
+
}
|
|
4382
|
+
controller.enqueue(chunk);
|
|
4383
|
+
};
|
|
4384
|
+
const handleTextDeltaChunk = (controller, delta) => {
|
|
4385
|
+
if (toolCall) {
|
|
4386
|
+
toolCall.raw += delta;
|
|
4387
|
+
toolCall.innerBuffer += delta;
|
|
4388
|
+
processToolCall2(controller);
|
|
4389
|
+
return;
|
|
4390
|
+
}
|
|
4391
|
+
if (implicitCall) {
|
|
4392
|
+
const callState = implicitCall;
|
|
4393
|
+
const { done, remainder } = consumeCall(
|
|
4394
|
+
controller,
|
|
4395
|
+
callState,
|
|
4396
|
+
delta,
|
|
4397
|
+
null
|
|
4398
|
+
);
|
|
4399
|
+
if (!done) {
|
|
4400
|
+
return;
|
|
4401
|
+
}
|
|
4402
|
+
implicitCall = null;
|
|
4403
|
+
implicitCallOpenTag = null;
|
|
4404
|
+
if (remainder.length > 0) {
|
|
4405
|
+
buffer = remainder + buffer;
|
|
4406
|
+
}
|
|
4407
|
+
stripLeadingToolCallCloseTagsFromBuffer();
|
|
4408
|
+
flushSafeTextPrefix(controller);
|
|
4409
|
+
drainStarts(controller);
|
|
4410
|
+
return;
|
|
4411
|
+
}
|
|
4412
|
+
buffer += delta;
|
|
4413
|
+
stripLeadingToolCallCloseTagsFromBuffer();
|
|
4414
|
+
flushSafeTextPrefix(controller);
|
|
4415
|
+
drainStarts(controller);
|
|
4416
|
+
};
|
|
4417
|
+
const handleTransformChunk = (controller, chunk) => {
|
|
4418
|
+
if (chunk.type === "finish") {
|
|
4419
|
+
handleFinish(controller);
|
|
4420
|
+
controller.enqueue(chunk);
|
|
4421
|
+
return;
|
|
4422
|
+
}
|
|
4423
|
+
if (chunk.type !== "text-delta") {
|
|
4424
|
+
handlePassthroughChunk(controller, chunk);
|
|
4425
|
+
return;
|
|
4426
|
+
}
|
|
4427
|
+
const delta = chunk.delta;
|
|
4428
|
+
if (!delta) {
|
|
4429
|
+
return;
|
|
4430
|
+
}
|
|
4431
|
+
handleTextDeltaChunk(controller, delta);
|
|
4432
|
+
};
|
|
4433
|
+
return new TransformStream({
|
|
4434
|
+
transform(chunk, controller) {
|
|
4435
|
+
handleTransformChunk(controller, chunk);
|
|
4436
|
+
},
|
|
4437
|
+
flush(controller) {
|
|
4438
|
+
handleFinish(controller);
|
|
4439
|
+
}
|
|
4440
|
+
});
|
|
4441
|
+
}
|
|
4442
|
+
});
|
|
4443
|
+
var uiTarsXmlProtocol = qwen3CoderProtocol;
|
|
4444
|
+
var Qwen3CoderToolParser = qwen3CoderProtocol;
|
|
2253
4445
|
|
|
2254
|
-
// src/core/protocols/yaml-protocol.ts
|
|
4446
|
+
// src/core/protocols/yaml-xml-protocol.ts
|
|
2255
4447
|
import YAML from "yaml";
|
|
2256
|
-
function shouldEmitRawToolCallTextOnError3(options) {
|
|
2257
|
-
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
2258
|
-
}
|
|
2259
|
-
var selfClosingTagCache2 = /* @__PURE__ */ new Map();
|
|
2260
|
-
function getSelfClosingTagPattern2(toolName) {
|
|
2261
|
-
let pattern = selfClosingTagCache2.get(toolName);
|
|
2262
|
-
if (!pattern) {
|
|
2263
|
-
pattern = new RegExp(`<\\s*${escapeRegExp(toolName)}\\s*/>`, "g");
|
|
2264
|
-
selfClosingTagCache2.set(toolName, pattern);
|
|
2265
|
-
}
|
|
2266
|
-
return pattern;
|
|
2267
|
-
}
|
|
2268
4448
|
var LEADING_WHITESPACE_RE = /^(\s*)/;
|
|
2269
4449
|
var INCOMPLETE_MAPPING_TAIL_RE = /^[^:[\]{}-][^:]*:\s*$/;
|
|
2270
4450
|
var INCOMPLETE_SEQUENCE_TAIL_RE = /^-\s*$/;
|
|
@@ -2452,7 +4632,7 @@ function stabilizeParsedValueForStreamProgress(value, source) {
|
|
|
2452
4632
|
}
|
|
2453
4633
|
return trimTrailingNewlineInUnknown(value);
|
|
2454
4634
|
}
|
|
2455
|
-
function
|
|
4635
|
+
function findClosingTagEnd2(text, contentStart, toolName) {
|
|
2456
4636
|
let pos = contentStart;
|
|
2457
4637
|
let depth = 1;
|
|
2458
4638
|
while (pos < text.length) {
|
|
@@ -2512,34 +4692,19 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
2512
4692
|
}
|
|
2513
4693
|
return -1;
|
|
2514
4694
|
}
|
|
2515
|
-
function findEarliestTagPosition(openIdx, selfIdx) {
|
|
2516
|
-
const hasSelf = selfIdx !== -1;
|
|
2517
|
-
const hasOpen = openIdx !== -1;
|
|
2518
|
-
if (hasSelf && (!hasOpen || selfIdx < openIdx)) {
|
|
2519
|
-
return { tagStart: selfIdx, isSelfClosing: true };
|
|
2520
|
-
}
|
|
2521
|
-
return { tagStart: openIdx, isSelfClosing: false };
|
|
2522
|
-
}
|
|
2523
4695
|
function collectToolCallsForName(text, toolName) {
|
|
2524
4696
|
const toolCalls = [];
|
|
2525
4697
|
let searchIndex = 0;
|
|
2526
4698
|
const startTag = `<${toolName}>`;
|
|
2527
|
-
const selfTagRegex = getSelfClosingTagPattern2(toolName);
|
|
2528
4699
|
while (searchIndex < text.length) {
|
|
2529
|
-
const
|
|
2530
|
-
|
|
2531
|
-
const selfMatch = selfTagRegex.exec(text);
|
|
2532
|
-
const selfIdx = selfMatch ? selfMatch.index : -1;
|
|
2533
|
-
const selfTagLength = selfMatch ? selfMatch[0].length : 0;
|
|
2534
|
-
if (openIdx === -1 && selfIdx === -1) {
|
|
4700
|
+
const match = findNextToolTag(text, searchIndex, toolName);
|
|
4701
|
+
if (match === null) {
|
|
2535
4702
|
break;
|
|
2536
4703
|
}
|
|
2537
|
-
const
|
|
2538
|
-
|
|
2539
|
-
selfIdx
|
|
2540
|
-
);
|
|
4704
|
+
const tagStart = match.tagStart;
|
|
4705
|
+
const isSelfClosing = match.isSelfClosing;
|
|
2541
4706
|
if (isSelfClosing) {
|
|
2542
|
-
const endIndex = tagStart +
|
|
4707
|
+
const endIndex = tagStart + match.tagLength;
|
|
2543
4708
|
toolCalls.push({
|
|
2544
4709
|
toolName,
|
|
2545
4710
|
startIndex: tagStart,
|
|
@@ -2550,7 +4715,7 @@ function collectToolCallsForName(text, toolName) {
|
|
|
2550
4715
|
continue;
|
|
2551
4716
|
}
|
|
2552
4717
|
const contentStart = tagStart + startTag.length;
|
|
2553
|
-
const fullTagEnd =
|
|
4718
|
+
const fullTagEnd = findClosingTagEnd2(text, contentStart, toolName);
|
|
2554
4719
|
if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
|
|
2555
4720
|
const endTag = `</${toolName}>`;
|
|
2556
4721
|
const endTagStart = fullTagEnd - endTag.length;
|
|
@@ -2645,38 +4810,6 @@ function processToolCallMatch(text, tc, currentIndex, processedElements, options
|
|
|
2645
4810
|
}
|
|
2646
4811
|
return tc.endIndex;
|
|
2647
4812
|
}
|
|
2648
|
-
function findEarliestToolTag2(buffer, toolNames) {
|
|
2649
|
-
let bestIndex = -1;
|
|
2650
|
-
let bestName = "";
|
|
2651
|
-
let bestSelfClosing = false;
|
|
2652
|
-
let bestTagLength = 0;
|
|
2653
|
-
for (const name of toolNames) {
|
|
2654
|
-
const openTag = `<${name}>`;
|
|
2655
|
-
const selfTagRegex = getSelfClosingTagPattern2(name);
|
|
2656
|
-
const idxOpen = buffer.indexOf(openTag);
|
|
2657
|
-
selfTagRegex.lastIndex = 0;
|
|
2658
|
-
const selfMatch = selfTagRegex.exec(buffer);
|
|
2659
|
-
const idxSelf = selfMatch ? selfMatch.index : -1;
|
|
2660
|
-
if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
|
|
2661
|
-
bestIndex = idxOpen;
|
|
2662
|
-
bestName = name;
|
|
2663
|
-
bestSelfClosing = false;
|
|
2664
|
-
bestTagLength = openTag.length;
|
|
2665
|
-
}
|
|
2666
|
-
if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
|
|
2667
|
-
bestIndex = idxSelf;
|
|
2668
|
-
bestName = name;
|
|
2669
|
-
bestSelfClosing = true;
|
|
2670
|
-
bestTagLength = selfMatch ? selfMatch[0].length : 0;
|
|
2671
|
-
}
|
|
2672
|
-
}
|
|
2673
|
-
return {
|
|
2674
|
-
index: bestIndex,
|
|
2675
|
-
name: bestName,
|
|
2676
|
-
selfClosing: bestSelfClosing,
|
|
2677
|
-
tagLength: bestTagLength
|
|
2678
|
-
};
|
|
2679
|
-
}
|
|
2680
4813
|
function stripTrailingPartialCloseTag(content, toolName) {
|
|
2681
4814
|
const closeTag = `</${toolName}>`;
|
|
2682
4815
|
const lastLineBreakIndex = Math.max(
|
|
@@ -2700,10 +4833,10 @@ function stripTrailingPartialCloseTag(content, toolName) {
|
|
|
2700
4833
|
)}${preservedLeadingWhitespace}`;
|
|
2701
4834
|
return contentWithoutPartial.trimEnd();
|
|
2702
4835
|
}
|
|
2703
|
-
var
|
|
4836
|
+
var yamlXmlProtocol = (_protocolOptions) => {
|
|
2704
4837
|
return {
|
|
2705
4838
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
2706
|
-
return
|
|
4839
|
+
return formatToolsWithPromptTemplate({ tools, toolSystemPromptTemplate });
|
|
2707
4840
|
},
|
|
2708
4841
|
formatToolCall(toolCall) {
|
|
2709
4842
|
let args = {};
|
|
@@ -2719,7 +4852,7 @@ var yamlProtocol = (_protocolOptions) => {
|
|
|
2719
4852
|
${yamlContent}</${toolCall.toolName}>`;
|
|
2720
4853
|
},
|
|
2721
4854
|
parseGeneratedText({ text, tools, options }) {
|
|
2722
|
-
const toolNames = tools
|
|
4855
|
+
const toolNames = extractToolNames(tools);
|
|
2723
4856
|
if (toolNames.length === 0) {
|
|
2724
4857
|
return [{ type: "text", text }];
|
|
2725
4858
|
}
|
|
@@ -2755,7 +4888,7 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2755
4888
|
return processedElements;
|
|
2756
4889
|
},
|
|
2757
4890
|
createStreamParser({ tools, options }) {
|
|
2758
|
-
const toolNames = tools
|
|
4891
|
+
const toolNames = extractToolNames(tools);
|
|
2759
4892
|
let buffer = "";
|
|
2760
4893
|
let currentToolCall = null;
|
|
2761
4894
|
let currentTextId = null;
|
|
@@ -2778,16 +4911,19 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2778
4911
|
if (parsedArgs === null) {
|
|
2779
4912
|
return;
|
|
2780
4913
|
}
|
|
2781
|
-
const fullInput =
|
|
4914
|
+
const fullInput = stringifyToolInputWithSchema({
|
|
4915
|
+
toolName: currentToolCall.name,
|
|
4916
|
+
args: parsedArgs,
|
|
4917
|
+
tools
|
|
4918
|
+
});
|
|
2782
4919
|
if (fullInput === "{}" && toolContent.trim().length === 0) {
|
|
2783
4920
|
return;
|
|
2784
4921
|
}
|
|
2785
|
-
|
|
2786
|
-
emitPrefixDelta({
|
|
4922
|
+
emitToolInputProgressDelta({
|
|
2787
4923
|
controller,
|
|
2788
4924
|
id: currentToolCall.toolCallId,
|
|
2789
4925
|
state: currentToolCall,
|
|
2790
|
-
|
|
4926
|
+
fullInput
|
|
2791
4927
|
});
|
|
2792
4928
|
};
|
|
2793
4929
|
const processToolCallEnd = (controller, toolContent, toolName, toolCallId) => {
|
|
@@ -2795,38 +4931,43 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2795
4931
|
const parsedArgs = parseYamlContent(toolContent, options);
|
|
2796
4932
|
flushText(controller);
|
|
2797
4933
|
if (parsedArgs !== null) {
|
|
2798
|
-
const finalInput =
|
|
4934
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
4935
|
+
toolName,
|
|
4936
|
+
args: parsedArgs,
|
|
4937
|
+
tools
|
|
4938
|
+
});
|
|
2799
4939
|
if (currentToolCall && currentToolCall.toolCallId === toolCallId) {
|
|
2800
|
-
|
|
4940
|
+
emitFinalizedToolInputLifecycle({
|
|
2801
4941
|
controller,
|
|
2802
4942
|
id: toolCallId,
|
|
2803
4943
|
state: currentToolCall,
|
|
2804
|
-
|
|
4944
|
+
toolName,
|
|
4945
|
+
finalInput,
|
|
2805
4946
|
onMismatch: options == null ? void 0 : options.onError
|
|
2806
4947
|
});
|
|
4948
|
+
} else {
|
|
4949
|
+
enqueueToolInputEndAndCall({
|
|
4950
|
+
controller,
|
|
4951
|
+
id: toolCallId,
|
|
4952
|
+
toolName,
|
|
4953
|
+
input: finalInput
|
|
4954
|
+
});
|
|
2807
4955
|
}
|
|
2808
|
-
controller.enqueue({
|
|
2809
|
-
type: "tool-input-end",
|
|
2810
|
-
id: toolCallId
|
|
2811
|
-
});
|
|
2812
|
-
controller.enqueue({
|
|
2813
|
-
type: "tool-call",
|
|
2814
|
-
toolCallId,
|
|
2815
|
-
toolName,
|
|
2816
|
-
input: finalInput
|
|
2817
|
-
});
|
|
2818
4956
|
} else {
|
|
2819
|
-
controller.enqueue({
|
|
2820
|
-
type: "tool-input-end",
|
|
2821
|
-
id: toolCallId
|
|
2822
|
-
});
|
|
2823
4957
|
const original = `<${toolName}>${toolContent}</${toolName}>`;
|
|
4958
|
+
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
4959
|
+
emitFailedToolInputLifecycle({
|
|
4960
|
+
controller,
|
|
4961
|
+
id: toolCallId,
|
|
4962
|
+
emitRawToolCallTextOnError: emitRawFallback,
|
|
4963
|
+
rawToolCallText: original,
|
|
4964
|
+
emitRawText: (rawText) => {
|
|
4965
|
+
flushText(controller, rawText);
|
|
4966
|
+
}
|
|
4967
|
+
});
|
|
2824
4968
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse streaming YAML tool call", {
|
|
2825
4969
|
toolCall: original
|
|
2826
4970
|
});
|
|
2827
|
-
if (shouldEmitRawToolCallTextOnError3(options)) {
|
|
2828
|
-
flushText(controller, original);
|
|
2829
|
-
}
|
|
2830
4971
|
}
|
|
2831
4972
|
};
|
|
2832
4973
|
const finalizeUnclosedToolCall = (controller) => {
|
|
@@ -2840,38 +4981,36 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2840
4981
|
const parsedArgs = parseYamlContent(reconciledBuffer, options);
|
|
2841
4982
|
flushText(controller);
|
|
2842
4983
|
if (parsedArgs !== null) {
|
|
2843
|
-
const finalInput =
|
|
2844
|
-
|
|
4984
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
4985
|
+
toolName,
|
|
4986
|
+
args: parsedArgs,
|
|
4987
|
+
tools
|
|
4988
|
+
});
|
|
4989
|
+
emitFinalizedToolInputLifecycle({
|
|
2845
4990
|
controller,
|
|
2846
4991
|
id: toolCallId,
|
|
2847
4992
|
state: currentToolCall,
|
|
2848
|
-
finalFullJson: finalInput,
|
|
2849
|
-
onMismatch: options == null ? void 0 : options.onError
|
|
2850
|
-
});
|
|
2851
|
-
controller.enqueue({
|
|
2852
|
-
type: "tool-input-end",
|
|
2853
|
-
id: toolCallId
|
|
2854
|
-
});
|
|
2855
|
-
controller.enqueue({
|
|
2856
|
-
type: "tool-call",
|
|
2857
|
-
toolCallId,
|
|
2858
4993
|
toolName,
|
|
2859
|
-
|
|
4994
|
+
finalInput,
|
|
4995
|
+
onMismatch: options == null ? void 0 : options.onError
|
|
2860
4996
|
});
|
|
2861
4997
|
} else {
|
|
2862
|
-
controller.enqueue({
|
|
2863
|
-
type: "tool-input-end",
|
|
2864
|
-
id: toolCallId
|
|
2865
|
-
});
|
|
2866
4998
|
const unfinishedContent = `<${toolName}>${buffer}`;
|
|
4999
|
+
const emitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
5000
|
+
emitFailedToolInputLifecycle({
|
|
5001
|
+
controller,
|
|
5002
|
+
id: toolCallId,
|
|
5003
|
+
emitRawToolCallTextOnError: emitRawFallback,
|
|
5004
|
+
rawToolCallText: unfinishedContent,
|
|
5005
|
+
emitRawText: (rawText) => {
|
|
5006
|
+
flushText(controller, rawText);
|
|
5007
|
+
}
|
|
5008
|
+
});
|
|
2867
5009
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
2868
5010
|
options,
|
|
2869
5011
|
"Could not complete streaming YAML tool call at finish.",
|
|
2870
5012
|
{ toolCall: unfinishedContent }
|
|
2871
5013
|
);
|
|
2872
|
-
if (shouldEmitRawToolCallTextOnError3(options)) {
|
|
2873
|
-
flushText(controller, unfinishedContent);
|
|
2874
|
-
}
|
|
2875
5014
|
}
|
|
2876
5015
|
buffer = "";
|
|
2877
5016
|
currentToolCall = null;
|
|
@@ -2948,7 +5087,7 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
2948
5087
|
break;
|
|
2949
5088
|
}
|
|
2950
5089
|
} else {
|
|
2951
|
-
const { index, name, selfClosing, tagLength } =
|
|
5090
|
+
const { index, name, selfClosing, tagLength } = findEarliestToolTag(
|
|
2952
5091
|
buffer,
|
|
2953
5092
|
toolNames
|
|
2954
5093
|
);
|
|
@@ -3145,9 +5284,38 @@ function decodeOriginalTools(originalTools, options) {
|
|
|
3145
5284
|
}
|
|
3146
5285
|
return decodedTools;
|
|
3147
5286
|
}
|
|
5287
|
+
function decodeOriginalToolsFromProviderOptions(providerOptions, options) {
|
|
5288
|
+
var _a;
|
|
5289
|
+
return decodeOriginalTools(
|
|
5290
|
+
(_a = providerOptions == null ? void 0 : providerOptions.toolCallMiddleware) == null ? void 0 : _a.originalTools,
|
|
5291
|
+
options
|
|
5292
|
+
);
|
|
5293
|
+
}
|
|
3148
5294
|
function extractToolNamesFromOriginalTools(originalTools) {
|
|
3149
5295
|
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
3150
5296
|
}
|
|
5297
|
+
function isRecord(value) {
|
|
5298
|
+
return typeof value === "object" && value !== null;
|
|
5299
|
+
}
|
|
5300
|
+
function getToolCallMiddlewareOptions(providerOptions) {
|
|
5301
|
+
if (!isRecord(providerOptions)) {
|
|
5302
|
+
return {};
|
|
5303
|
+
}
|
|
5304
|
+
const toolCallMiddleware = providerOptions.toolCallMiddleware;
|
|
5305
|
+
if (!isRecord(toolCallMiddleware)) {
|
|
5306
|
+
return {};
|
|
5307
|
+
}
|
|
5308
|
+
return toolCallMiddleware;
|
|
5309
|
+
}
|
|
5310
|
+
function mergeToolCallMiddlewareOptions(providerOptions, overrides) {
|
|
5311
|
+
return {
|
|
5312
|
+
...isRecord(providerOptions) ? providerOptions : {},
|
|
5313
|
+
toolCallMiddleware: {
|
|
5314
|
+
...getToolCallMiddlewareOptions(providerOptions),
|
|
5315
|
+
...overrides
|
|
5316
|
+
}
|
|
5317
|
+
};
|
|
5318
|
+
}
|
|
3151
5319
|
function isToolChoiceActive(params) {
|
|
3152
5320
|
var _a, _b, _c;
|
|
3153
5321
|
const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
|
|
@@ -3167,7 +5335,7 @@ function hasInputProperty(obj) {
|
|
|
3167
5335
|
}
|
|
3168
5336
|
|
|
3169
5337
|
// src/core/utils/generated-text-json-recovery.ts
|
|
3170
|
-
function
|
|
5338
|
+
function isRecord2(value) {
|
|
3171
5339
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3172
5340
|
}
|
|
3173
5341
|
function safeStringify2(value) {
|
|
@@ -3323,7 +5491,7 @@ function toRecoveredParts(text, candidate, toolCallPart) {
|
|
|
3323
5491
|
return out;
|
|
3324
5492
|
}
|
|
3325
5493
|
function parseAsToolPayload(payload, tools) {
|
|
3326
|
-
if (!
|
|
5494
|
+
if (!isRecord2(payload)) {
|
|
3327
5495
|
return null;
|
|
3328
5496
|
}
|
|
3329
5497
|
const toolName = typeof payload.name === "string" && payload.name.trim().length > 0 ? payload.name.trim() : null;
|
|
@@ -3334,7 +5502,7 @@ function parseAsToolPayload(payload, tools) {
|
|
|
3334
5502
|
return null;
|
|
3335
5503
|
}
|
|
3336
5504
|
const rawArgs = Object.hasOwn(payload, "arguments") ? payload.arguments : {};
|
|
3337
|
-
if (!
|
|
5505
|
+
if (!isRecord2(rawArgs)) {
|
|
3338
5506
|
return null;
|
|
3339
5507
|
}
|
|
3340
5508
|
return {
|
|
@@ -3344,14 +5512,14 @@ function parseAsToolPayload(payload, tools) {
|
|
|
3344
5512
|
}
|
|
3345
5513
|
function isLikelyArgumentsShapeForTool(args, tool) {
|
|
3346
5514
|
const unwrapped = unwrapJsonSchema(tool.inputSchema);
|
|
3347
|
-
if (!
|
|
5515
|
+
if (!isRecord2(unwrapped)) {
|
|
3348
5516
|
return false;
|
|
3349
5517
|
}
|
|
3350
5518
|
if (getSchemaType(unwrapped) !== "object") {
|
|
3351
5519
|
return false;
|
|
3352
5520
|
}
|
|
3353
5521
|
const properties = unwrapped.properties;
|
|
3354
|
-
if (!
|
|
5522
|
+
if (!isRecord2(properties)) {
|
|
3355
5523
|
return false;
|
|
3356
5524
|
}
|
|
3357
5525
|
const keys = Object.keys(args);
|
|
@@ -3371,11 +5539,11 @@ function parseAsArgumentsOnly(payload, tools) {
|
|
|
3371
5539
|
if (tools.length !== 1) {
|
|
3372
5540
|
return null;
|
|
3373
5541
|
}
|
|
3374
|
-
if (!
|
|
5542
|
+
if (!isRecord2(payload)) {
|
|
3375
5543
|
return null;
|
|
3376
5544
|
}
|
|
3377
5545
|
const hasNameEnvelope = Object.hasOwn(payload, "name") && typeof payload.name === "string" && payload.name.length > 0;
|
|
3378
|
-
const hasArgumentsEnvelope = Object.hasOwn(payload, "arguments") && (typeof payload.arguments === "string" ||
|
|
5546
|
+
const hasArgumentsEnvelope = Object.hasOwn(payload, "arguments") && (typeof payload.arguments === "string" || isRecord2(payload.arguments));
|
|
3379
5547
|
if (hasNameEnvelope || hasArgumentsEnvelope) {
|
|
3380
5548
|
return null;
|
|
3381
5549
|
}
|
|
@@ -3410,36 +5578,6 @@ function recoverToolCallFromJsonCandidates(text, tools) {
|
|
|
3410
5578
|
return null;
|
|
3411
5579
|
}
|
|
3412
5580
|
|
|
3413
|
-
// src/core/utils/tool-call-coercion.ts
|
|
3414
|
-
function coerceToolCallInput(toolName, input, tools) {
|
|
3415
|
-
var _a;
|
|
3416
|
-
let args = {};
|
|
3417
|
-
if (typeof input === "string") {
|
|
3418
|
-
try {
|
|
3419
|
-
args = JSON.parse(input);
|
|
3420
|
-
} catch (e) {
|
|
3421
|
-
return;
|
|
3422
|
-
}
|
|
3423
|
-
} else if (input && typeof input === "object") {
|
|
3424
|
-
args = input;
|
|
3425
|
-
} else {
|
|
3426
|
-
return;
|
|
3427
|
-
}
|
|
3428
|
-
const schema = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
3429
|
-
const coerced = coerceBySchema(args, schema);
|
|
3430
|
-
return JSON.stringify(coerced != null ? coerced : {});
|
|
3431
|
-
}
|
|
3432
|
-
function coerceToolCallPart(part, tools) {
|
|
3433
|
-
const coercedInput = coerceToolCallInput(part.toolName, part.input, tools);
|
|
3434
|
-
if (coercedInput === void 0) {
|
|
3435
|
-
return part;
|
|
3436
|
-
}
|
|
3437
|
-
return {
|
|
3438
|
-
...part,
|
|
3439
|
-
input: coercedInput
|
|
3440
|
-
};
|
|
3441
|
-
}
|
|
3442
|
-
|
|
3443
5581
|
// src/core/utils/tool-choice.ts
|
|
3444
5582
|
function ensureNonEmptyToolName(name) {
|
|
3445
5583
|
if (typeof name !== "string") {
|
|
@@ -3494,6 +5632,30 @@ function parseToolChoicePayload({
|
|
|
3494
5632
|
input: coercedInput != null ? coercedInput : safeStringify3(rawArgs)
|
|
3495
5633
|
};
|
|
3496
5634
|
}
|
|
5635
|
+
function resolveToolChoiceSelection({
|
|
5636
|
+
text,
|
|
5637
|
+
tools,
|
|
5638
|
+
onError,
|
|
5639
|
+
errorMessage
|
|
5640
|
+
}) {
|
|
5641
|
+
if (typeof text !== "string") {
|
|
5642
|
+
return {
|
|
5643
|
+
toolName: "unknown",
|
|
5644
|
+
input: "{}",
|
|
5645
|
+
originText: ""
|
|
5646
|
+
};
|
|
5647
|
+
}
|
|
5648
|
+
const parsed = parseToolChoicePayload({
|
|
5649
|
+
text,
|
|
5650
|
+
tools,
|
|
5651
|
+
onError,
|
|
5652
|
+
errorMessage
|
|
5653
|
+
});
|
|
5654
|
+
return {
|
|
5655
|
+
...parsed,
|
|
5656
|
+
originText: text
|
|
5657
|
+
};
|
|
5658
|
+
}
|
|
3497
5659
|
|
|
3498
5660
|
// src/generate-handler.ts
|
|
3499
5661
|
function logDebugSummary(debugSummary, toolCall, originText) {
|
|
@@ -3513,29 +5675,23 @@ async function handleToolChoice(doGenerate, params, tools) {
|
|
|
3513
5675
|
var _a, _b, _c, _d;
|
|
3514
5676
|
const result = await doGenerate();
|
|
3515
5677
|
const first = (_a = result.content) == null ? void 0 : _a[0];
|
|
5678
|
+
const firstText = (first == null ? void 0 : first.type) === "text" ? first.text : void 0;
|
|
3516
5679
|
const onError = (_b = extractOnErrorOption(params.providerOptions)) == null ? void 0 : _b.onError;
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
if (first && first.type === "text") {
|
|
3520
|
-
if (getDebugLevel() === "parse") {
|
|
3521
|
-
logRawChunk(first.text);
|
|
3522
|
-
}
|
|
3523
|
-
const parsed = parseToolChoicePayload({
|
|
3524
|
-
text: first.text,
|
|
3525
|
-
tools,
|
|
3526
|
-
onError,
|
|
3527
|
-
errorMessage: "Failed to parse toolChoice JSON from generated model output"
|
|
3528
|
-
});
|
|
3529
|
-
toolName = parsed.toolName;
|
|
3530
|
-
input = parsed.input;
|
|
5680
|
+
if (typeof firstText === "string" && getDebugLevel() === "parse") {
|
|
5681
|
+
logRawChunk(firstText);
|
|
3531
5682
|
}
|
|
5683
|
+
const { toolName, input, originText } = resolveToolChoiceSelection({
|
|
5684
|
+
text: firstText,
|
|
5685
|
+
tools,
|
|
5686
|
+
onError,
|
|
5687
|
+
errorMessage: "Failed to parse toolChoice JSON from generated model output"
|
|
5688
|
+
});
|
|
3532
5689
|
const toolCall = {
|
|
3533
5690
|
type: "tool-call",
|
|
3534
5691
|
toolCallId: generateToolCallId(),
|
|
3535
5692
|
toolName,
|
|
3536
5693
|
input
|
|
3537
5694
|
};
|
|
3538
|
-
const originText = first && first.type === "text" ? first.text : "";
|
|
3539
5695
|
const debugSummary = (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.debugSummary;
|
|
3540
5696
|
logDebugSummary(debugSummary, toolCall, originText);
|
|
3541
5697
|
return {
|
|
@@ -3556,7 +5712,7 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
3556
5712
|
tools,
|
|
3557
5713
|
options: {
|
|
3558
5714
|
...extractOnErrorOption(providerOptions),
|
|
3559
|
-
...providerOptions
|
|
5715
|
+
...getToolCallMiddlewareOptions(providerOptions)
|
|
3560
5716
|
}
|
|
3561
5717
|
});
|
|
3562
5718
|
const hasToolCall = parsedByProtocol.some(
|
|
@@ -3614,10 +5770,9 @@ async function wrapGenerate({
|
|
|
3614
5770
|
doGenerate,
|
|
3615
5771
|
params
|
|
3616
5772
|
}) {
|
|
3617
|
-
var _a, _b;
|
|
3618
5773
|
const onError = extractOnErrorOption(params.providerOptions);
|
|
3619
|
-
const tools =
|
|
3620
|
-
|
|
5774
|
+
const tools = decodeOriginalToolsFromProviderOptions(
|
|
5775
|
+
params.providerOptions,
|
|
3621
5776
|
onError
|
|
3622
5777
|
);
|
|
3623
5778
|
if (isToolChoiceActive(params)) {
|
|
@@ -3647,23 +5802,147 @@ async function wrapGenerate({
|
|
|
3647
5802
|
};
|
|
3648
5803
|
}
|
|
3649
5804
|
|
|
3650
|
-
// src/core/prompts/
|
|
3651
|
-
function
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
5805
|
+
// src/core/prompts/shared/text-part.ts
|
|
5806
|
+
function toTextPart(text, providerOptions) {
|
|
5807
|
+
if (providerOptions === void 0) {
|
|
5808
|
+
return {
|
|
5809
|
+
type: "text",
|
|
5810
|
+
text
|
|
5811
|
+
};
|
|
5812
|
+
}
|
|
5813
|
+
return {
|
|
5814
|
+
type: "text",
|
|
5815
|
+
text,
|
|
5816
|
+
providerOptions
|
|
5817
|
+
};
|
|
3663
5818
|
}
|
|
3664
5819
|
|
|
3665
|
-
// src/core/prompts/tool-
|
|
3666
|
-
function
|
|
5820
|
+
// src/core/prompts/shared/tool-result-normalizer.ts
|
|
5821
|
+
function isMapping(value) {
|
|
5822
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5823
|
+
}
|
|
5824
|
+
function getMediaKindFromMediaType(mediaType) {
|
|
5825
|
+
if (mediaType.startsWith("image/")) {
|
|
5826
|
+
return "image";
|
|
5827
|
+
}
|
|
5828
|
+
if (mediaType.startsWith("audio/")) {
|
|
5829
|
+
return "audio";
|
|
5830
|
+
}
|
|
5831
|
+
if (mediaType.startsWith("video/")) {
|
|
5832
|
+
return "video";
|
|
5833
|
+
}
|
|
5834
|
+
return "file";
|
|
5835
|
+
}
|
|
5836
|
+
function getContentPartMediaKind(part) {
|
|
5837
|
+
const contentPart = isMapping(part) ? part : void 0;
|
|
5838
|
+
const type = contentPart == null ? void 0 : contentPart.type;
|
|
5839
|
+
switch (type) {
|
|
5840
|
+
case "image-data":
|
|
5841
|
+
case "image-url":
|
|
5842
|
+
case "image-file-id":
|
|
5843
|
+
return "image";
|
|
5844
|
+
case "file-data":
|
|
5845
|
+
case "file-url":
|
|
5846
|
+
case "file-id": {
|
|
5847
|
+
const mediaType = contentPart == null ? void 0 : contentPart.mediaType;
|
|
5848
|
+
if (typeof mediaType === "string") {
|
|
5849
|
+
return getMediaKindFromMediaType(mediaType);
|
|
5850
|
+
}
|
|
5851
|
+
return "file";
|
|
5852
|
+
}
|
|
5853
|
+
case "media": {
|
|
5854
|
+
const mediaType = contentPart == null ? void 0 : contentPart.mediaType;
|
|
5855
|
+
if (typeof mediaType === "string") {
|
|
5856
|
+
return getMediaKindFromMediaType(mediaType);
|
|
5857
|
+
}
|
|
5858
|
+
return "file";
|
|
5859
|
+
}
|
|
5860
|
+
default:
|
|
5861
|
+
return null;
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
function shouldPassRawByStrategy(mediaKind, strategy) {
|
|
5865
|
+
var _a;
|
|
5866
|
+
const mode = getMediaMode(strategy);
|
|
5867
|
+
if (mode === "raw") {
|
|
5868
|
+
return true;
|
|
5869
|
+
}
|
|
5870
|
+
if (mode === "placeholder") {
|
|
5871
|
+
return false;
|
|
5872
|
+
}
|
|
5873
|
+
if (mode === "model") {
|
|
5874
|
+
return false;
|
|
5875
|
+
}
|
|
5876
|
+
return ((_a = strategy == null ? void 0 : strategy.capabilities) == null ? void 0 : _a[mediaKind]) === true;
|
|
5877
|
+
}
|
|
5878
|
+
function getMediaMode(strategy) {
|
|
5879
|
+
var _a;
|
|
5880
|
+
return (_a = strategy == null ? void 0 : strategy.mode) != null ? _a : "placeholder";
|
|
5881
|
+
}
|
|
5882
|
+
function shouldPassRawContent(contentParts, strategy) {
|
|
5883
|
+
const mode = getMediaMode(strategy);
|
|
5884
|
+
if (mode === "raw") {
|
|
5885
|
+
return true;
|
|
5886
|
+
}
|
|
5887
|
+
if (mode === "placeholder") {
|
|
5888
|
+
return false;
|
|
5889
|
+
}
|
|
5890
|
+
if (mode === "model") {
|
|
5891
|
+
return false;
|
|
5892
|
+
}
|
|
5893
|
+
let hasSupportedMediaContent = false;
|
|
5894
|
+
for (const part of contentParts) {
|
|
5895
|
+
const mediaKind = getContentPartMediaKind(part);
|
|
5896
|
+
if (!mediaKind) {
|
|
5897
|
+
continue;
|
|
5898
|
+
}
|
|
5899
|
+
hasSupportedMediaContent = true;
|
|
5900
|
+
if (!shouldPassRawByStrategy(mediaKind, strategy)) {
|
|
5901
|
+
return false;
|
|
5902
|
+
}
|
|
5903
|
+
}
|
|
5904
|
+
return hasSupportedMediaContent;
|
|
5905
|
+
}
|
|
5906
|
+
function formatIdPlaceholder(label, fileId) {
|
|
5907
|
+
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
5908
|
+
return `[${label}: ${displayId}]`;
|
|
5909
|
+
}
|
|
5910
|
+
function formatContentPartPlaceholder(part) {
|
|
5911
|
+
var _a;
|
|
5912
|
+
const contentPart = part;
|
|
5913
|
+
switch (contentPart.type) {
|
|
5914
|
+
case "text":
|
|
5915
|
+
return (_a = contentPart.text) != null ? _a : "";
|
|
5916
|
+
case "image-data":
|
|
5917
|
+
return `[Image: ${contentPart.mediaType}]`;
|
|
5918
|
+
case "image-url":
|
|
5919
|
+
return `[Image URL: ${contentPart.url}]`;
|
|
5920
|
+
case "image-file-id": {
|
|
5921
|
+
const fileId = contentPart.fileId;
|
|
5922
|
+
return formatIdPlaceholder("Image ID", fileId);
|
|
5923
|
+
}
|
|
5924
|
+
case "file-data": {
|
|
5925
|
+
const filePart = contentPart;
|
|
5926
|
+
if (filePart.filename) {
|
|
5927
|
+
return `[File: ${filePart.filename} (${filePart.mediaType})]`;
|
|
5928
|
+
}
|
|
5929
|
+
return `[File: ${filePart.mediaType}]`;
|
|
5930
|
+
}
|
|
5931
|
+
case "file-url":
|
|
5932
|
+
return `[File URL: ${contentPart.url}]`;
|
|
5933
|
+
case "file-id": {
|
|
5934
|
+
const fileId = contentPart.fileId;
|
|
5935
|
+
return formatIdPlaceholder("File ID", fileId);
|
|
5936
|
+
}
|
|
5937
|
+
case "media":
|
|
5938
|
+
return `[Media: ${contentPart.mediaType}]`;
|
|
5939
|
+
case "custom":
|
|
5940
|
+
return "[Custom content]";
|
|
5941
|
+
default:
|
|
5942
|
+
return "[Unknown content]";
|
|
5943
|
+
}
|
|
5944
|
+
}
|
|
5945
|
+
function unwrapToolResult(result, mediaStrategy) {
|
|
3667
5946
|
var _a, _b;
|
|
3668
5947
|
switch (result.type) {
|
|
3669
5948
|
case "text":
|
|
@@ -3679,43 +5958,11 @@ function unwrapToolResult(result) {
|
|
|
3679
5958
|
case "error-json":
|
|
3680
5959
|
return `[Error: ${JSON.stringify(result.value)}]`;
|
|
3681
5960
|
case "content": {
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
return (_a2 = contentPart.text) != null ? _a2 : "";
|
|
3688
|
-
case "image-data":
|
|
3689
|
-
return `[Image: ${contentPart.mediaType}]`;
|
|
3690
|
-
case "image-url":
|
|
3691
|
-
return `[Image URL: ${contentPart.url}]`;
|
|
3692
|
-
case "image-file-id": {
|
|
3693
|
-
const fileId = contentPart.fileId;
|
|
3694
|
-
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
3695
|
-
return `[Image ID: ${displayId}]`;
|
|
3696
|
-
}
|
|
3697
|
-
case "file-data": {
|
|
3698
|
-
const filePart = contentPart;
|
|
3699
|
-
if (filePart.filename) {
|
|
3700
|
-
return `[File: ${filePart.filename} (${filePart.mediaType})]`;
|
|
3701
|
-
}
|
|
3702
|
-
return `[File: ${filePart.mediaType}]`;
|
|
3703
|
-
}
|
|
3704
|
-
case "file-url":
|
|
3705
|
-
return `[File URL: ${contentPart.url}]`;
|
|
3706
|
-
case "file-id": {
|
|
3707
|
-
const fileId = contentPart.fileId;
|
|
3708
|
-
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
3709
|
-
return `[File ID: ${displayId}]`;
|
|
3710
|
-
}
|
|
3711
|
-
case "media":
|
|
3712
|
-
return `[Media: ${contentPart.mediaType}]`;
|
|
3713
|
-
case "custom":
|
|
3714
|
-
return "[Custom content]";
|
|
3715
|
-
default:
|
|
3716
|
-
return "[Unknown content]";
|
|
3717
|
-
}
|
|
3718
|
-
}).join("\n");
|
|
5961
|
+
const parts = result.value;
|
|
5962
|
+
if (shouldPassRawContent(parts, mediaStrategy)) {
|
|
5963
|
+
return parts;
|
|
5964
|
+
}
|
|
5965
|
+
return parts.map(formatContentPartPlaceholder).join("\n");
|
|
3719
5966
|
}
|
|
3720
5967
|
default: {
|
|
3721
5968
|
const _exhaustive = result;
|
|
@@ -3723,58 +5970,89 @@ function unwrapToolResult(result) {
|
|
|
3723
5970
|
}
|
|
3724
5971
|
}
|
|
3725
5972
|
}
|
|
3726
|
-
|
|
3727
|
-
|
|
5973
|
+
|
|
5974
|
+
// src/core/prompts/hermes-prompt.ts
|
|
5975
|
+
function formatToolResponseAsHermesWithOptions(toolResult, options) {
|
|
5976
|
+
const unwrappedResult = unwrapToolResult(
|
|
5977
|
+
toolResult.output,
|
|
5978
|
+
options == null ? void 0 : options.mediaStrategy
|
|
5979
|
+
);
|
|
3728
5980
|
return `<tool_response>${JSON.stringify({
|
|
3729
|
-
|
|
3730
|
-
|
|
5981
|
+
name: toolResult.toolName,
|
|
5982
|
+
content: unwrappedResult
|
|
3731
5983
|
})}</tool_response>`;
|
|
3732
5984
|
}
|
|
3733
|
-
function
|
|
3734
|
-
|
|
3735
|
-
const toolNameXml = `<tool_name>${toolResult.toolName}</tool_name>`;
|
|
3736
|
-
const resultLines = formatXmlNode("result", unwrappedResult, 1);
|
|
3737
|
-
return [
|
|
3738
|
-
"<tool_response>",
|
|
3739
|
-
` ${toolNameXml}`,
|
|
3740
|
-
...resultLines,
|
|
3741
|
-
"</tool_response>"
|
|
3742
|
-
].join("\n");
|
|
5985
|
+
function formatToolResponseAsHermes(toolResult) {
|
|
5986
|
+
return formatToolResponseAsHermesWithOptions(toolResult);
|
|
3743
5987
|
}
|
|
3744
|
-
function
|
|
3745
|
-
const
|
|
3746
|
-
if (
|
|
3747
|
-
return
|
|
5988
|
+
function jsonSchemaToPythonType(schema) {
|
|
5989
|
+
const type = schema.type;
|
|
5990
|
+
if (type === "string") {
|
|
5991
|
+
return "str";
|
|
3748
5992
|
}
|
|
3749
|
-
if (
|
|
3750
|
-
return
|
|
5993
|
+
if (type === "number") {
|
|
5994
|
+
return "float";
|
|
3751
5995
|
}
|
|
3752
|
-
if (
|
|
3753
|
-
|
|
3754
|
-
|
|
5996
|
+
if (type === "integer") {
|
|
5997
|
+
return "int";
|
|
5998
|
+
}
|
|
5999
|
+
if (type === "boolean") {
|
|
6000
|
+
return "bool";
|
|
6001
|
+
}
|
|
6002
|
+
if (type === "array") {
|
|
6003
|
+
const items = schema.items;
|
|
6004
|
+
if (items) {
|
|
6005
|
+
return `list[${jsonSchemaToPythonType(items)}]`;
|
|
3755
6006
|
}
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
6007
|
+
return "list[Any]";
|
|
6008
|
+
}
|
|
6009
|
+
if (type === "object") {
|
|
6010
|
+
const additionalProperties = schema.additionalProperties;
|
|
6011
|
+
if (additionalProperties) {
|
|
6012
|
+
return `dict[str, ${jsonSchemaToPythonType(additionalProperties)}]`;
|
|
3759
6013
|
}
|
|
3760
|
-
|
|
3761
|
-
return lines2;
|
|
6014
|
+
return "dict";
|
|
3762
6015
|
}
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
return [`${indent}<${tagName}></${tagName}>`];
|
|
6016
|
+
if (Array.isArray(type)) {
|
|
6017
|
+
return `Union[${type.map((t) => jsonSchemaToPythonType({ type: t })).join(",")}]`;
|
|
3766
6018
|
}
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
6019
|
+
return "Any";
|
|
6020
|
+
}
|
|
6021
|
+
function renderToolDefinition(tool) {
|
|
6022
|
+
var _a, _b;
|
|
6023
|
+
const schema = tool.inputSchema;
|
|
6024
|
+
const properties = schema.properties;
|
|
6025
|
+
const paramSignature = properties ? Object.entries(properties).map(([name, field]) => `${name}: ${jsonSchemaToPythonType(field)}`).join(", ") : "";
|
|
6026
|
+
const desc = (_a = tool.description) != null ? _a : "";
|
|
6027
|
+
let description = `${tool.name}(${paramSignature}) - ${desc}
|
|
6028
|
+
|
|
6029
|
+
`;
|
|
6030
|
+
if (properties && Object.keys(properties).length > 0) {
|
|
6031
|
+
description += " Args:\n";
|
|
6032
|
+
for (const [paramName, paramFields] of Object.entries(properties)) {
|
|
6033
|
+
const paramDesc = (_b = paramFields.description) != null ? _b : "";
|
|
6034
|
+
description += ` ${paramName}(${jsonSchemaToPythonType(paramFields)}): ${paramDesc.trim()}
|
|
6035
|
+
`;
|
|
6036
|
+
}
|
|
3770
6037
|
}
|
|
3771
|
-
|
|
3772
|
-
|
|
6038
|
+
const parametersJson = JSON.stringify(schema);
|
|
6039
|
+
const descJson = JSON.stringify(description);
|
|
6040
|
+
const nameJson = JSON.stringify(tool.name);
|
|
6041
|
+
return `{"type": "function", "function": {"name": ${nameJson}, "description": ${descJson}, "parameters": ${parametersJson}}}`;
|
|
6042
|
+
}
|
|
6043
|
+
function hermesSystemPromptTemplate(tools) {
|
|
6044
|
+
const toolsRendered = tools.map(renderToolDefinition).join("\n");
|
|
6045
|
+
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>
|
|
6046
|
+
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"}
|
|
6047
|
+
For each function call return a json object with function name and arguments within <tool_call></tool_call> XML tags as follows:
|
|
6048
|
+
<tool_call>
|
|
6049
|
+
{"name": "<function-name>", "arguments": <args-dict>}
|
|
6050
|
+
</tool_call>`;
|
|
3773
6051
|
}
|
|
3774
6052
|
|
|
3775
|
-
// src/core/prompts/xml-
|
|
6053
|
+
// src/core/prompts/morph-xml-prompt.ts
|
|
3776
6054
|
import dedent from "dedent";
|
|
3777
|
-
function
|
|
6055
|
+
function morphXmlSystemPromptTemplate(tools) {
|
|
3778
6056
|
const toolsText = renderToolsForXmlPrompt(tools);
|
|
3779
6057
|
const header = dedent`
|
|
3780
6058
|
# Tools
|
|
@@ -3998,9 +6276,202 @@ function stripSchemaKeys(value) {
|
|
|
3998
6276
|
}
|
|
3999
6277
|
return value;
|
|
4000
6278
|
}
|
|
6279
|
+
function formatXmlNode(tagName, value, depth) {
|
|
6280
|
+
const indent = " ".repeat(depth);
|
|
6281
|
+
if (value === null || value === void 0) {
|
|
6282
|
+
return [`${indent}<${tagName}></${tagName}>`];
|
|
6283
|
+
}
|
|
6284
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
6285
|
+
return [`${indent}<${tagName}>${String(value)}</${tagName}>`];
|
|
6286
|
+
}
|
|
6287
|
+
if (Array.isArray(value)) {
|
|
6288
|
+
if (value.length === 0) {
|
|
6289
|
+
return [`${indent}<${tagName}></${tagName}>`];
|
|
6290
|
+
}
|
|
6291
|
+
const lines2 = [`${indent}<${tagName}>`];
|
|
6292
|
+
for (const item of value) {
|
|
6293
|
+
lines2.push(...formatXmlNode("item", item, depth + 1));
|
|
6294
|
+
}
|
|
6295
|
+
lines2.push(`${indent}</${tagName}>`);
|
|
6296
|
+
return lines2;
|
|
6297
|
+
}
|
|
6298
|
+
const entries = Object.entries(value);
|
|
6299
|
+
if (entries.length === 0) {
|
|
6300
|
+
return [`${indent}<${tagName}></${tagName}>`];
|
|
6301
|
+
}
|
|
6302
|
+
const lines = [`${indent}<${tagName}>`];
|
|
6303
|
+
for (const [key, entryValue] of entries) {
|
|
6304
|
+
lines.push(...formatXmlNode(key, entryValue, depth + 1));
|
|
6305
|
+
}
|
|
6306
|
+
lines.push(`${indent}</${tagName}>`);
|
|
6307
|
+
return lines;
|
|
6308
|
+
}
|
|
6309
|
+
function morphFormatToolResponseAsXmlWithOptions(toolResult, options) {
|
|
6310
|
+
const unwrappedResult = unwrapToolResult(
|
|
6311
|
+
toolResult.output,
|
|
6312
|
+
options == null ? void 0 : options.mediaStrategy
|
|
6313
|
+
);
|
|
6314
|
+
const toolNameXml = `<tool_name>${toolResult.toolName}</tool_name>`;
|
|
6315
|
+
const resultLines = formatXmlNode("result", unwrappedResult, 1);
|
|
6316
|
+
return [
|
|
6317
|
+
"<tool_response>",
|
|
6318
|
+
` ${toolNameXml}`,
|
|
6319
|
+
...resultLines,
|
|
6320
|
+
"</tool_response>"
|
|
6321
|
+
].join("\n");
|
|
6322
|
+
}
|
|
6323
|
+
function morphFormatToolResponseAsXml(toolResult) {
|
|
6324
|
+
return morphFormatToolResponseAsXmlWithOptions(toolResult);
|
|
6325
|
+
}
|
|
6326
|
+
|
|
6327
|
+
// src/core/prompts/qwen3coder-prompt.ts
|
|
6328
|
+
var QWEN3CODER_TOOL_HEADER = "# Tools\n\nYou have access to the following functions:\n\n";
|
|
6329
|
+
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>";
|
|
6330
|
+
var XML_PROMPT_TAG_NAME_RE = /^[A-Za-z_][A-Za-z0-9_.-]*$/;
|
|
6331
|
+
function isMapping2(value) {
|
|
6332
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6333
|
+
}
|
|
6334
|
+
function isSequence(value) {
|
|
6335
|
+
return Array.isArray(value);
|
|
6336
|
+
}
|
|
6337
|
+
function toJinjaString(value) {
|
|
6338
|
+
if (value === void 0) {
|
|
6339
|
+
return "";
|
|
6340
|
+
}
|
|
6341
|
+
if (value === null) {
|
|
6342
|
+
return "None";
|
|
6343
|
+
}
|
|
6344
|
+
if (typeof value === "boolean") {
|
|
6345
|
+
return value ? "True" : "False";
|
|
6346
|
+
}
|
|
6347
|
+
return String(value);
|
|
6348
|
+
}
|
|
6349
|
+
function toJinjaTrimmedString(value) {
|
|
6350
|
+
return toJinjaString(value).trim();
|
|
6351
|
+
}
|
|
6352
|
+
function toEscapedXmlText(value) {
|
|
6353
|
+
return escapeXmlMinimalText(toJinjaString(value));
|
|
6354
|
+
}
|
|
6355
|
+
function toEscapedTrimmedXmlText(value) {
|
|
6356
|
+
return escapeXmlMinimalText(toJinjaTrimmedString(value));
|
|
6357
|
+
}
|
|
6358
|
+
function renderXmlPromptField(key, escapedValue) {
|
|
6359
|
+
if (XML_PROMPT_TAG_NAME_RE.test(key)) {
|
|
6360
|
+
return `
|
|
6361
|
+
<${key}>${escapedValue}</${key}>`;
|
|
6362
|
+
}
|
|
6363
|
+
return `
|
|
6364
|
+
<property name="${escapeXmlMinimalAttr(
|
|
6365
|
+
key,
|
|
6366
|
+
'"'
|
|
6367
|
+
)}">${escapedValue}</property>`;
|
|
6368
|
+
}
|
|
6369
|
+
function renderExtraKeys(jsonDict, handledKeys) {
|
|
6370
|
+
if (!isMapping2(jsonDict)) {
|
|
6371
|
+
return "";
|
|
6372
|
+
}
|
|
6373
|
+
const handled = new Set(handledKeys);
|
|
6374
|
+
let out = "";
|
|
6375
|
+
for (const [jsonKey, jsonValue] of Object.entries(jsonDict)) {
|
|
6376
|
+
if (handled.has(jsonKey)) {
|
|
6377
|
+
continue;
|
|
6378
|
+
}
|
|
6379
|
+
const renderedValue = isMapping2(jsonValue) || isSequence(jsonValue) ? JSON.stringify(jsonValue) : toJinjaString(jsonValue);
|
|
6380
|
+
out += renderXmlPromptField(jsonKey, escapeXmlMinimalText(renderedValue));
|
|
6381
|
+
}
|
|
6382
|
+
return out;
|
|
6383
|
+
}
|
|
6384
|
+
function normalizeInputSchema(inputSchema) {
|
|
6385
|
+
if (typeof inputSchema !== "string") {
|
|
6386
|
+
return inputSchema;
|
|
6387
|
+
}
|
|
6388
|
+
try {
|
|
6389
|
+
return JSON.parse(inputSchema);
|
|
6390
|
+
} catch (e) {
|
|
6391
|
+
return inputSchema;
|
|
6392
|
+
}
|
|
6393
|
+
}
|
|
6394
|
+
function normalizeTool(rawTool) {
|
|
6395
|
+
return {
|
|
6396
|
+
name: rawTool.name,
|
|
6397
|
+
description: rawTool.description,
|
|
6398
|
+
parameters: normalizeInputSchema(rawTool.inputSchema)
|
|
6399
|
+
};
|
|
6400
|
+
}
|
|
6401
|
+
function renderParameter(paramName, paramFieldsRaw) {
|
|
6402
|
+
const paramFields = isMapping2(paramFieldsRaw) ? paramFieldsRaw : void 0;
|
|
6403
|
+
let out = "\n<parameter>";
|
|
6404
|
+
out += `
|
|
6405
|
+
<name>${toEscapedXmlText(paramName)}</name>`;
|
|
6406
|
+
if ((paramFields == null ? void 0 : paramFields.type) !== void 0) {
|
|
6407
|
+
out += `
|
|
6408
|
+
<type>${toEscapedXmlText(paramFields.type)}</type>`;
|
|
6409
|
+
}
|
|
6410
|
+
if ((paramFields == null ? void 0 : paramFields.description) !== void 0) {
|
|
6411
|
+
out += `
|
|
6412
|
+
<description>${toEscapedTrimmedXmlText(paramFields.description)}</description>`;
|
|
6413
|
+
}
|
|
6414
|
+
out += renderExtraKeys(paramFieldsRaw, ["name", "type", "description"]);
|
|
6415
|
+
out += "\n</parameter>";
|
|
6416
|
+
return out;
|
|
6417
|
+
}
|
|
6418
|
+
function renderTool(tool) {
|
|
6419
|
+
let out = `
|
|
6420
|
+
<function>
|
|
6421
|
+
<name>${toEscapedXmlText(tool.name)}</name>`;
|
|
6422
|
+
if (tool.description !== void 0) {
|
|
6423
|
+
out += `
|
|
6424
|
+
<description>${toEscapedTrimmedXmlText(tool.description)}</description>`;
|
|
6425
|
+
}
|
|
6426
|
+
out += "\n<parameters>";
|
|
6427
|
+
const parameters = tool.parameters;
|
|
6428
|
+
if (isMapping2(parameters) && isMapping2(parameters.properties)) {
|
|
6429
|
+
for (const [paramName, paramFieldsRaw] of Object.entries(
|
|
6430
|
+
parameters.properties
|
|
6431
|
+
)) {
|
|
6432
|
+
out += renderParameter(paramName, paramFieldsRaw);
|
|
6433
|
+
}
|
|
6434
|
+
}
|
|
6435
|
+
out += renderExtraKeys(parameters, ["type", "properties"]);
|
|
6436
|
+
out += "\n</parameters>";
|
|
6437
|
+
out += renderExtraKeys(tool, ["type", "name", "description", "parameters"]);
|
|
6438
|
+
out += "\n</function>";
|
|
6439
|
+
return out;
|
|
6440
|
+
}
|
|
6441
|
+
function qwen3coderSystemPromptTemplate(tools) {
|
|
6442
|
+
if (!tools.length) {
|
|
6443
|
+
return "";
|
|
6444
|
+
}
|
|
6445
|
+
let out = `${QWEN3CODER_TOOL_HEADER}<tools>`;
|
|
6446
|
+
for (const tool of tools) {
|
|
6447
|
+
out += renderTool(normalizeTool(tool));
|
|
6448
|
+
}
|
|
6449
|
+
out += "\n</tools>";
|
|
6450
|
+
out += QWEN3CODER_TOOL_CALL_INSTRUCTIONS;
|
|
6451
|
+
return out;
|
|
6452
|
+
}
|
|
6453
|
+
function stringifyToolResponseContent(value) {
|
|
6454
|
+
if (typeof value === "string") {
|
|
6455
|
+
return value;
|
|
6456
|
+
}
|
|
6457
|
+
return JSON.stringify(value);
|
|
6458
|
+
}
|
|
6459
|
+
function formatToolResponseAsQwen3CoderXmlWithOptions(toolResult, options) {
|
|
6460
|
+
const unwrappedResult = unwrapToolResult(
|
|
6461
|
+
toolResult.output,
|
|
6462
|
+
options == null ? void 0 : options.mediaStrategy
|
|
6463
|
+
);
|
|
6464
|
+
const content = stringifyToolResponseContent(unwrappedResult);
|
|
6465
|
+
return `<tool_response>
|
|
6466
|
+
${content}
|
|
6467
|
+
</tool_response>`;
|
|
6468
|
+
}
|
|
6469
|
+
function formatToolResponseAsQwen3CoderXml(toolResult) {
|
|
6470
|
+
return formatToolResponseAsQwen3CoderXmlWithOptions(toolResult);
|
|
6471
|
+
}
|
|
4001
6472
|
|
|
4002
|
-
// src/core/prompts/yaml-
|
|
4003
|
-
function
|
|
6473
|
+
// src/core/prompts/yaml-xml-prompt.ts
|
|
6474
|
+
function yamlXmlSystemPromptTemplate(tools, includeMultilineExample = true) {
|
|
4004
6475
|
const toolsJson = JSON.stringify(tools);
|
|
4005
6476
|
const multilineExample = includeMultilineExample ? `
|
|
4006
6477
|
|
|
@@ -4039,6 +6510,9 @@ unit: celsius
|
|
|
4039
6510
|
- Do NOT ask clarifying questions. Use reasonable defaults for optional parameters.
|
|
4040
6511
|
- If a task requires multiple function calls, make ALL of them at once.`;
|
|
4041
6512
|
}
|
|
6513
|
+
function formatToolResponseAsYaml(toolResult) {
|
|
6514
|
+
return morphFormatToolResponseAsXml(toolResult);
|
|
6515
|
+
}
|
|
4042
6516
|
|
|
4043
6517
|
// src/stream-handler.ts
|
|
4044
6518
|
async function wrapStream({
|
|
@@ -4047,10 +6521,9 @@ async function wrapStream({
|
|
|
4047
6521
|
doGenerate,
|
|
4048
6522
|
params
|
|
4049
6523
|
}) {
|
|
4050
|
-
var _a, _b, _c;
|
|
4051
6524
|
const onErrorOptions = extractOnErrorOption(params.providerOptions);
|
|
4052
|
-
const tools =
|
|
4053
|
-
|
|
6525
|
+
const tools = decodeOriginalToolsFromProviderOptions(
|
|
6526
|
+
params.providerOptions,
|
|
4054
6527
|
onErrorOptions
|
|
4055
6528
|
);
|
|
4056
6529
|
if (isToolChoiceActive(params)) {
|
|
@@ -4064,7 +6537,7 @@ async function wrapStream({
|
|
|
4064
6537
|
const debugLevel = getDebugLevel();
|
|
4065
6538
|
const options = {
|
|
4066
6539
|
...onErrorOptions,
|
|
4067
|
-
...(
|
|
6540
|
+
...getToolCallMiddlewareOptions(params.providerOptions)
|
|
4068
6541
|
};
|
|
4069
6542
|
const coreStream = stream.pipeThrough(
|
|
4070
6543
|
new TransformStream(
|
|
@@ -4114,18 +6587,14 @@ async function toolChoiceStream({
|
|
|
4114
6587
|
var _a;
|
|
4115
6588
|
const normalizedTools = Array.isArray(tools) ? tools : [];
|
|
4116
6589
|
const result = await doGenerate();
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
});
|
|
4126
|
-
toolName = parsed.toolName;
|
|
4127
|
-
input = parsed.input;
|
|
4128
|
-
}
|
|
6590
|
+
const first = (_a = result == null ? void 0 : result.content) == null ? void 0 : _a[0];
|
|
6591
|
+
const firstText = (first == null ? void 0 : first.type) === "text" ? first.text : void 0;
|
|
6592
|
+
const { toolName, input } = resolveToolChoiceSelection({
|
|
6593
|
+
text: firstText,
|
|
6594
|
+
tools: normalizedTools,
|
|
6595
|
+
onError: options == null ? void 0 : options.onError,
|
|
6596
|
+
errorMessage: "Failed to parse toolChoice JSON from streamed model output"
|
|
6597
|
+
});
|
|
4129
6598
|
const stream = new ReadableStream({
|
|
4130
6599
|
start(controller) {
|
|
4131
6600
|
controller.enqueue({
|
|
@@ -4203,8 +6672,108 @@ function normalizeUsage(usage) {
|
|
|
4203
6672
|
return ZERO_USAGE;
|
|
4204
6673
|
}
|
|
4205
6674
|
|
|
6675
|
+
// src/core/prompts/shared/assistant-tool-calls-to-text.ts
|
|
6676
|
+
function assistantToolCallsToTextContent(options) {
|
|
6677
|
+
var _a, _b;
|
|
6678
|
+
const newContent = [];
|
|
6679
|
+
for (const item of options.content) {
|
|
6680
|
+
switch (item.type) {
|
|
6681
|
+
case "tool-call":
|
|
6682
|
+
newContent.push({
|
|
6683
|
+
type: "text",
|
|
6684
|
+
text: options.protocol.formatToolCall(item)
|
|
6685
|
+
});
|
|
6686
|
+
break;
|
|
6687
|
+
case "text":
|
|
6688
|
+
case "reasoning":
|
|
6689
|
+
newContent.push(item);
|
|
6690
|
+
break;
|
|
6691
|
+
default:
|
|
6692
|
+
(_b = (_a = options.conversionOptions) == null ? void 0 : _a.onError) == null ? void 0 : _b.call(
|
|
6693
|
+
_a,
|
|
6694
|
+
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
6695
|
+
{ content: item }
|
|
6696
|
+
);
|
|
6697
|
+
newContent.push({
|
|
6698
|
+
type: "text",
|
|
6699
|
+
text: JSON.stringify(item)
|
|
6700
|
+
});
|
|
6701
|
+
}
|
|
6702
|
+
}
|
|
6703
|
+
if (!newContent.every((entry) => entry.type === "text")) {
|
|
6704
|
+
return newContent;
|
|
6705
|
+
}
|
|
6706
|
+
return [
|
|
6707
|
+
{
|
|
6708
|
+
type: "text",
|
|
6709
|
+
text: newContent.map((entry) => entry.text).join("\n")
|
|
6710
|
+
}
|
|
6711
|
+
];
|
|
6712
|
+
}
|
|
6713
|
+
|
|
6714
|
+
// src/core/prompts/shared/tool-role-to-user-message.ts
|
|
6715
|
+
function formatApprovalResponse(part) {
|
|
6716
|
+
const status = part.approved ? "Approved" : "Denied";
|
|
6717
|
+
const reason = part.reason ? `: ${part.reason}` : "";
|
|
6718
|
+
return `[Tool Approval ${status}${reason}]`;
|
|
6719
|
+
}
|
|
6720
|
+
function normalizeTemplateResult(result) {
|
|
6721
|
+
if (typeof result === "string") {
|
|
6722
|
+
return [toTextPart(result)];
|
|
6723
|
+
}
|
|
6724
|
+
return result;
|
|
6725
|
+
}
|
|
6726
|
+
function appendSection(target, section) {
|
|
6727
|
+
if (section.length === 0) {
|
|
6728
|
+
return;
|
|
6729
|
+
}
|
|
6730
|
+
if (target.length > 0) {
|
|
6731
|
+
target.push(toTextPart("\n"));
|
|
6732
|
+
}
|
|
6733
|
+
target.push(...section);
|
|
6734
|
+
}
|
|
6735
|
+
function mergeAdjacentTextParts(parts) {
|
|
6736
|
+
const merged = [];
|
|
6737
|
+
for (const part of parts) {
|
|
6738
|
+
const last = merged.at(-1);
|
|
6739
|
+
const canMergeTextParts = part.type === "text" && (last == null ? void 0 : last.type) === "text" && part.providerOptions === void 0 && last.providerOptions === void 0;
|
|
6740
|
+
if (canMergeTextParts) {
|
|
6741
|
+
last.text += part.text;
|
|
6742
|
+
continue;
|
|
6743
|
+
}
|
|
6744
|
+
merged.push(part);
|
|
6745
|
+
}
|
|
6746
|
+
return merged;
|
|
6747
|
+
}
|
|
6748
|
+
function toolRoleContentToUserTextMessage(options) {
|
|
6749
|
+
const toolResultParts = options.toolContent.filter(
|
|
6750
|
+
(part) => part.type === "tool-result"
|
|
6751
|
+
);
|
|
6752
|
+
const approvalResponseParts = options.toolContent.filter(
|
|
6753
|
+
(part) => part.type === "tool-approval-response"
|
|
6754
|
+
);
|
|
6755
|
+
const sections = [];
|
|
6756
|
+
for (const toolResult of toolResultParts) {
|
|
6757
|
+
const result = options.toolResponsePromptTemplate(toolResult);
|
|
6758
|
+
appendSection(sections, normalizeTemplateResult(result));
|
|
6759
|
+
}
|
|
6760
|
+
for (const approvalResponse of approvalResponseParts) {
|
|
6761
|
+
appendSection(sections, [
|
|
6762
|
+
toTextPart(formatApprovalResponse(approvalResponse))
|
|
6763
|
+
]);
|
|
6764
|
+
}
|
|
6765
|
+
const normalizedSections = sections.length > 0 ? sections : [toTextPart("")];
|
|
6766
|
+
return {
|
|
6767
|
+
role: "user",
|
|
6768
|
+
content: mergeAdjacentTextParts(normalizedSections)
|
|
6769
|
+
};
|
|
6770
|
+
}
|
|
6771
|
+
|
|
4206
6772
|
// src/transform-handler.ts
|
|
4207
6773
|
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
6774
|
+
if (systemPrompt.trim().length === 0) {
|
|
6775
|
+
return processedPrompt;
|
|
6776
|
+
}
|
|
4208
6777
|
const systemIndex = processedPrompt.findIndex((m) => m.role === "system");
|
|
4209
6778
|
if (systemIndex !== -1) {
|
|
4210
6779
|
const existing = processedPrompt[systemIndex].content;
|
|
@@ -4254,13 +6823,9 @@ function buildBaseReturnParams(params, finalPrompt, functionTools) {
|
|
|
4254
6823
|
prompt: finalPrompt,
|
|
4255
6824
|
tools: [],
|
|
4256
6825
|
toolChoice: void 0,
|
|
4257
|
-
providerOptions: {
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
|
|
4261
|
-
originalTools: originalToolsSchema.encode(functionTools)
|
|
4262
|
-
}
|
|
4263
|
-
}
|
|
6826
|
+
providerOptions: mergeToolCallMiddlewareOptions(params.providerOptions, {
|
|
6827
|
+
originalTools: originalToolsSchema.encode(functionTools)
|
|
6828
|
+
})
|
|
4264
6829
|
};
|
|
4265
6830
|
}
|
|
4266
6831
|
function findProviderDefinedTool(tools, selectedToolName) {
|
|
@@ -4312,13 +6877,10 @@ function handleToolChoiceTool(params, baseReturnParams) {
|
|
|
4312
6877
|
name: selectedTool.name,
|
|
4313
6878
|
description: typeof selectedTool.description === "string" ? selectedTool.description : void 0
|
|
4314
6879
|
},
|
|
4315
|
-
providerOptions:
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
...params.toolChoice ? { toolChoice: params.toolChoice } : {}
|
|
4320
|
-
}
|
|
4321
|
-
}
|
|
6880
|
+
providerOptions: mergeToolCallMiddlewareOptions(
|
|
6881
|
+
baseReturnParams.providerOptions,
|
|
6882
|
+
params.toolChoice ? { toolChoice: params.toolChoice } : {}
|
|
6883
|
+
)
|
|
4322
6884
|
};
|
|
4323
6885
|
}
|
|
4324
6886
|
function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
@@ -4338,13 +6900,12 @@ function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
|
4338
6900
|
type: "json",
|
|
4339
6901
|
schema: createDynamicIfThenElseSchema(functionTools)
|
|
4340
6902
|
},
|
|
4341
|
-
providerOptions:
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
|
|
6903
|
+
providerOptions: mergeToolCallMiddlewareOptions(
|
|
6904
|
+
baseReturnParams.providerOptions,
|
|
6905
|
+
{
|
|
4345
6906
|
toolChoice: { type: "required" }
|
|
4346
6907
|
}
|
|
4347
|
-
|
|
6908
|
+
)
|
|
4348
6909
|
};
|
|
4349
6910
|
}
|
|
4350
6911
|
function transformParams({
|
|
@@ -4400,94 +6961,30 @@ function transformParams({
|
|
|
4400
6961
|
}
|
|
4401
6962
|
return baseReturnParams;
|
|
4402
6963
|
}
|
|
4403
|
-
function processAssistantContent(content, resolvedProtocol, providerOptions) {
|
|
4404
|
-
var _a;
|
|
4405
|
-
const newContent = [];
|
|
4406
|
-
for (const item of content) {
|
|
4407
|
-
switch (item.type) {
|
|
4408
|
-
case "tool-call":
|
|
4409
|
-
newContent.push({
|
|
4410
|
-
type: "text",
|
|
4411
|
-
text: resolvedProtocol.formatToolCall(item)
|
|
4412
|
-
});
|
|
4413
|
-
break;
|
|
4414
|
-
case "text":
|
|
4415
|
-
case "reasoning":
|
|
4416
|
-
newContent.push(item);
|
|
4417
|
-
break;
|
|
4418
|
-
default: {
|
|
4419
|
-
const options = extractOnErrorOption(providerOptions);
|
|
4420
|
-
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4421
|
-
options,
|
|
4422
|
-
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
4423
|
-
{ content: item }
|
|
4424
|
-
);
|
|
4425
|
-
newContent.push({
|
|
4426
|
-
type: "text",
|
|
4427
|
-
text: JSON.stringify(item)
|
|
4428
|
-
});
|
|
4429
|
-
}
|
|
4430
|
-
}
|
|
4431
|
-
}
|
|
4432
|
-
const onlyText = newContent.every((c) => c.type === "text");
|
|
4433
|
-
return onlyText ? [
|
|
4434
|
-
{
|
|
4435
|
-
type: "text",
|
|
4436
|
-
text: newContent.map((c) => c.text).join("\n")
|
|
4437
|
-
}
|
|
4438
|
-
] : newContent;
|
|
4439
|
-
}
|
|
4440
|
-
function formatApprovalResponse(part) {
|
|
4441
|
-
const status = part.approved ? "Approved" : "Denied";
|
|
4442
|
-
const reason = part.reason ? `: ${part.reason}` : "";
|
|
4443
|
-
return `[Tool Approval ${status}${reason}]`;
|
|
4444
|
-
}
|
|
4445
|
-
function processToolMessage(toolResults, approvalResponses, toolResponsePromptTemplate) {
|
|
4446
|
-
const resultTexts = toolResults.map((toolResult) => {
|
|
4447
|
-
return toolResponsePromptTemplate(toolResult);
|
|
4448
|
-
});
|
|
4449
|
-
const approvalTexts = approvalResponses.map(formatApprovalResponse);
|
|
4450
|
-
const allTexts = [...resultTexts, ...approvalTexts];
|
|
4451
|
-
return {
|
|
4452
|
-
role: "user",
|
|
4453
|
-
content: [
|
|
4454
|
-
{
|
|
4455
|
-
type: "text",
|
|
4456
|
-
text: allTexts.join("\n")
|
|
4457
|
-
}
|
|
4458
|
-
]
|
|
4459
|
-
};
|
|
4460
|
-
}
|
|
4461
6964
|
function processMessage(message, resolvedProtocol, providerOptions, toolResponsePromptTemplate) {
|
|
4462
6965
|
if (message.role === "assistant") {
|
|
4463
|
-
const condensedContent =
|
|
4464
|
-
message.content,
|
|
4465
|
-
resolvedProtocol,
|
|
4466
|
-
|
|
4467
|
-
|
|
6966
|
+
const condensedContent = assistantToolCallsToTextContent({
|
|
6967
|
+
content: message.content,
|
|
6968
|
+
protocol: resolvedProtocol,
|
|
6969
|
+
conversionOptions: {
|
|
6970
|
+
onError: providerOptions == null ? void 0 : providerOptions.onError
|
|
6971
|
+
}
|
|
6972
|
+
});
|
|
4468
6973
|
return {
|
|
4469
6974
|
role: "assistant",
|
|
4470
6975
|
content: condensedContent
|
|
4471
6976
|
};
|
|
4472
6977
|
}
|
|
4473
6978
|
if (message.role === "tool") {
|
|
4474
|
-
const toolContent = message.content;
|
|
4475
|
-
const toolResultParts = toolContent.filter(
|
|
4476
|
-
(part) => part.type === "tool-result"
|
|
4477
|
-
);
|
|
4478
|
-
const approvalResponseParts = toolContent.filter(
|
|
4479
|
-
(part) => part.type === "tool-approval-response"
|
|
4480
|
-
);
|
|
4481
6979
|
if (!toolResponsePromptTemplate) {
|
|
4482
6980
|
throw new Error(
|
|
4483
6981
|
'toolResponsePromptTemplate is required when processing messages with role "tool". This parameter is optional for other roles but is required here so tool-result content can be converted into a prompt. Ensure your middleware or transform configuration passes a toolResponsePromptTemplate when tool message processing is enabled.'
|
|
4484
6982
|
);
|
|
4485
6983
|
}
|
|
4486
|
-
return
|
|
4487
|
-
|
|
4488
|
-
approvalResponseParts,
|
|
6984
|
+
return toolRoleContentToUserTextMessage({
|
|
6985
|
+
toolContent: message.content,
|
|
4489
6986
|
toolResponsePromptTemplate
|
|
4490
|
-
);
|
|
6987
|
+
});
|
|
4491
6988
|
}
|
|
4492
6989
|
return message;
|
|
4493
6990
|
}
|
|
@@ -4538,6 +7035,9 @@ function mergeConsecutiveUserMessages(processedPrompt) {
|
|
|
4538
7035
|
const current = processedPrompt[i];
|
|
4539
7036
|
const prev = processedPrompt[i - 1];
|
|
4540
7037
|
if (current.role === "user" && prev.role === "user") {
|
|
7038
|
+
if (!(isAllTextContent(prev.content) && isAllTextContent(current.content))) {
|
|
7039
|
+
continue;
|
|
7040
|
+
}
|
|
4541
7041
|
const prevContent = prev.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
4542
7042
|
const currentContent = current.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
4543
7043
|
processedPrompt[i - 1] = {
|
|
@@ -4597,19 +7097,24 @@ function createToolMiddleware({
|
|
|
4597
7097
|
|
|
4598
7098
|
// src/preconfigured-middleware.ts
|
|
4599
7099
|
var hermesToolMiddleware = createToolMiddleware({
|
|
4600
|
-
protocol:
|
|
7100
|
+
protocol: hermesProtocol(),
|
|
4601
7101
|
toolSystemPromptTemplate: hermesSystemPromptTemplate,
|
|
4602
|
-
toolResponsePromptTemplate:
|
|
7102
|
+
toolResponsePromptTemplate: formatToolResponseAsHermes
|
|
7103
|
+
});
|
|
7104
|
+
var qwen3CoderToolMiddleware = createToolMiddleware({
|
|
7105
|
+
protocol: qwen3CoderProtocol,
|
|
7106
|
+
toolSystemPromptTemplate: qwen3coderSystemPromptTemplate,
|
|
7107
|
+
toolResponsePromptTemplate: formatToolResponseAsQwen3CoderXml
|
|
4603
7108
|
});
|
|
4604
|
-
var
|
|
4605
|
-
protocol:
|
|
4606
|
-
toolSystemPromptTemplate:
|
|
4607
|
-
toolResponsePromptTemplate:
|
|
7109
|
+
var morphXmlToolMiddleware = createToolMiddleware({
|
|
7110
|
+
protocol: morphXmlProtocol({}),
|
|
7111
|
+
toolSystemPromptTemplate: morphXmlSystemPromptTemplate,
|
|
7112
|
+
toolResponsePromptTemplate: morphFormatToolResponseAsXml
|
|
4608
7113
|
});
|
|
4609
|
-
var
|
|
4610
|
-
protocol:
|
|
4611
|
-
toolSystemPromptTemplate:
|
|
4612
|
-
toolResponsePromptTemplate:
|
|
7114
|
+
var yamlXmlToolMiddleware = createToolMiddleware({
|
|
7115
|
+
protocol: yamlXmlProtocol({}),
|
|
7116
|
+
toolSystemPromptTemplate: yamlXmlSystemPromptTemplate,
|
|
7117
|
+
toolResponsePromptTemplate: formatToolResponseAsYaml
|
|
4613
7118
|
});
|
|
4614
7119
|
|
|
4615
7120
|
export {
|
|
@@ -4619,27 +7124,35 @@ export {
|
|
|
4619
7124
|
logParsedChunk,
|
|
4620
7125
|
logParsedSummary,
|
|
4621
7126
|
getPotentialStartIndex,
|
|
4622
|
-
|
|
7127
|
+
hermesProtocol,
|
|
7128
|
+
morphXmlProtocol,
|
|
4623
7129
|
isProtocolFactory,
|
|
4624
7130
|
isTCMProtocolFactory,
|
|
4625
|
-
|
|
4626
|
-
|
|
7131
|
+
qwen3CoderProtocol,
|
|
7132
|
+
uiTarsXmlProtocol,
|
|
7133
|
+
Qwen3CoderToolParser,
|
|
7134
|
+
yamlXmlProtocol,
|
|
4627
7135
|
createDynamicIfThenElseSchema,
|
|
4628
7136
|
extractOnErrorOption,
|
|
4629
7137
|
originalToolsSchema,
|
|
4630
7138
|
encodeOriginalTools,
|
|
4631
7139
|
decodeOriginalTools,
|
|
7140
|
+
decodeOriginalToolsFromProviderOptions,
|
|
4632
7141
|
extractToolNamesFromOriginalTools,
|
|
7142
|
+
getToolCallMiddlewareOptions,
|
|
7143
|
+
mergeToolCallMiddlewareOptions,
|
|
4633
7144
|
isToolChoiceActive,
|
|
4634
7145
|
isToolResultPart,
|
|
4635
7146
|
hasInputProperty,
|
|
4636
7147
|
wrapGenerate,
|
|
7148
|
+
morphFormatToolResponseAsXml,
|
|
4637
7149
|
wrapStream,
|
|
4638
7150
|
toolChoiceStream,
|
|
4639
7151
|
transformParams,
|
|
4640
7152
|
createToolMiddleware,
|
|
4641
7153
|
hermesToolMiddleware,
|
|
4642
|
-
|
|
4643
|
-
|
|
7154
|
+
qwen3CoderToolMiddleware,
|
|
7155
|
+
morphXmlToolMiddleware,
|
|
7156
|
+
yamlXmlToolMiddleware
|
|
4644
7157
|
};
|
|
4645
|
-
//# sourceMappingURL=chunk-
|
|
7158
|
+
//# sourceMappingURL=chunk-722D5BGD.js.map
|