@ai-sdk-tool/parser 4.1.0 → 4.1.2
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 +3 -3
- package/dist/{chunk-MHZC45AC.js → chunk-D4YULTAO.js} +7 -7
- package/dist/chunk-D4YULTAO.js.map +1 -0
- package/dist/{chunk-O6NWVXQD.js → chunk-X3NZ2YHV.js} +1226 -840
- package/dist/chunk-X3NZ2YHV.js.map +1 -0
- package/dist/community.cjs +5414 -5028
- package/dist/community.cjs.map +1 -1
- package/dist/community.js +2 -2
- package/dist/index.cjs +2754 -2365
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -40
- package/dist/index.d.ts +9 -40
- package/dist/index.js +8 -2
- package/dist/rxml.cjs +6 -6
- package/dist/rxml.cjs.map +1 -1
- package/dist/rxml.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-MHZC45AC.js.map +0 -1
- package/dist/chunk-O6NWVXQD.js.map +0 -1
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
parse as parse2,
|
|
6
6
|
stringify,
|
|
7
7
|
unescapeXml
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-D4YULTAO.js";
|
|
9
9
|
import {
|
|
10
10
|
parse
|
|
11
11
|
} from "./chunk-QBZNMO5C.js";
|
|
@@ -222,6 +222,12 @@ function generateToolCallId() {
|
|
|
222
222
|
}
|
|
223
223
|
|
|
224
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
|
+
}
|
|
225
231
|
function addTextSegment(text, processedElements) {
|
|
226
232
|
if (text.trim()) {
|
|
227
233
|
processedElements.push({ type: "text", text });
|
|
@@ -260,10 +266,222 @@ function createFlushTextHandler(getCurrentTextId, setCurrentTextId, getHasEmitte
|
|
|
260
266
|
};
|
|
261
267
|
}
|
|
262
268
|
|
|
263
|
-
// 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
|
+
}
|
|
264
480
|
function shouldEmitRawToolCallTextOnError(options) {
|
|
265
481
|
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
266
482
|
}
|
|
483
|
+
|
|
484
|
+
// src/core/protocols/hermes-protocol.ts
|
|
267
485
|
function canonicalizeToolInput(argumentsValue) {
|
|
268
486
|
return JSON.stringify(argumentsValue != null ? argumentsValue : {});
|
|
269
487
|
}
|
|
@@ -527,19 +745,13 @@ function emitToolInputDelta(state, controller, fullInput) {
|
|
|
527
745
|
if (!active) {
|
|
528
746
|
return;
|
|
529
747
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
}
|
|
533
|
-
const delta = fullInput.slice(active.emittedInput.length);
|
|
534
|
-
if (delta.length === 0) {
|
|
535
|
-
return;
|
|
536
|
-
}
|
|
537
|
-
controller.enqueue({
|
|
538
|
-
type: "tool-input-delta",
|
|
748
|
+
emitToolInputProgressDelta({
|
|
749
|
+
controller,
|
|
539
750
|
id: active.id,
|
|
540
|
-
|
|
751
|
+
state: active,
|
|
752
|
+
fullInput,
|
|
753
|
+
mode: "full-json"
|
|
541
754
|
});
|
|
542
|
-
active.emittedInput = fullInput;
|
|
543
755
|
}
|
|
544
756
|
function closeToolInput(state, controller) {
|
|
545
757
|
if (!state.activeToolInput) {
|
|
@@ -551,11 +763,16 @@ function closeToolInput(state, controller) {
|
|
|
551
763
|
});
|
|
552
764
|
state.activeToolInput = null;
|
|
553
765
|
}
|
|
554
|
-
function emitToolCallFromParsed(state, controller, parsedToolCall) {
|
|
766
|
+
function emitToolCallFromParsed(state, controller, parsedToolCall, tools) {
|
|
555
767
|
var _a, _b, _c, _d;
|
|
556
768
|
closeTextBlock(state, controller);
|
|
557
769
|
const toolName = typeof parsedToolCall.name === "string" ? parsedToolCall.name : (_b = (_a = state.activeToolInput) == null ? void 0 : _a.toolName) != null ? _b : "unknown";
|
|
558
|
-
const input =
|
|
770
|
+
const input = stringifyToolInputWithSchema({
|
|
771
|
+
toolName,
|
|
772
|
+
args: parsedToolCall.arguments,
|
|
773
|
+
tools,
|
|
774
|
+
fallback: canonicalizeToolInput
|
|
775
|
+
});
|
|
559
776
|
ensureToolInputStart(state, controller, toolName);
|
|
560
777
|
emitToolInputDelta(state, controller, input);
|
|
561
778
|
const toolCallId = (_d = (_c = state.activeToolInput) == null ? void 0 : _c.id) != null ? _d : generateToolCallId();
|
|
@@ -567,18 +784,23 @@ function emitToolCallFromParsed(state, controller, parsedToolCall) {
|
|
|
567
784
|
input
|
|
568
785
|
});
|
|
569
786
|
}
|
|
570
|
-
function canonicalizeArgumentsProgressInput(progress) {
|
|
787
|
+
function canonicalizeArgumentsProgressInput(progress, toolName, tools) {
|
|
571
788
|
if (progress.argumentsText === void 0 || !progress.argumentsComplete) {
|
|
572
789
|
return void 0;
|
|
573
790
|
}
|
|
574
791
|
try {
|
|
575
792
|
const parsedArguments = parse(progress.argumentsText);
|
|
576
|
-
return
|
|
793
|
+
return stringifyToolInputWithSchema({
|
|
794
|
+
toolName,
|
|
795
|
+
args: parsedArguments,
|
|
796
|
+
tools,
|
|
797
|
+
fallback: canonicalizeToolInput
|
|
798
|
+
});
|
|
577
799
|
} catch (e) {
|
|
578
800
|
return void 0;
|
|
579
801
|
}
|
|
580
802
|
}
|
|
581
|
-
function emitToolInputProgress(state, controller) {
|
|
803
|
+
function emitToolInputProgress(state, controller, tools) {
|
|
582
804
|
if (!(state.isInsideToolCall && state.currentToolCallJson)) {
|
|
583
805
|
return;
|
|
584
806
|
}
|
|
@@ -587,7 +809,11 @@ function emitToolInputProgress(state, controller) {
|
|
|
587
809
|
return;
|
|
588
810
|
}
|
|
589
811
|
ensureToolInputStart(state, controller, progress.toolName);
|
|
590
|
-
const canonicalProgressInput = canonicalizeArgumentsProgressInput(
|
|
812
|
+
const canonicalProgressInput = canonicalizeArgumentsProgressInput(
|
|
813
|
+
progress,
|
|
814
|
+
progress.toolName,
|
|
815
|
+
tools
|
|
816
|
+
);
|
|
591
817
|
if (canonicalProgressInput !== void 0) {
|
|
592
818
|
emitToolInputDelta(state, controller, canonicalProgressInput);
|
|
593
819
|
}
|
|
@@ -622,7 +848,7 @@ function closeTextBlock(state, controller) {
|
|
|
622
848
|
state.hasEmittedTextStart = false;
|
|
623
849
|
}
|
|
624
850
|
}
|
|
625
|
-
function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer, options) {
|
|
851
|
+
function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer, tools, options) {
|
|
626
852
|
var _a;
|
|
627
853
|
if (!state.currentToolCallJson && trailingBuffer.length === 0) {
|
|
628
854
|
state.isInsideToolCall = false;
|
|
@@ -631,7 +857,7 @@ function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer
|
|
|
631
857
|
if (state.currentToolCallJson) {
|
|
632
858
|
try {
|
|
633
859
|
const parsedToolCall = parse(state.currentToolCallJson);
|
|
634
|
-
emitToolCallFromParsed(state, controller, parsedToolCall);
|
|
860
|
+
emitToolCallFromParsed(state, controller, parsedToolCall, tools);
|
|
635
861
|
state.currentToolCallJson = "";
|
|
636
862
|
state.isInsideToolCall = false;
|
|
637
863
|
return;
|
|
@@ -671,7 +897,7 @@ function emitIncompleteToolCall(state, controller, toolCallStart, trailingBuffer
|
|
|
671
897
|
state.currentToolCallJson = "";
|
|
672
898
|
state.isInsideToolCall = false;
|
|
673
899
|
}
|
|
674
|
-
function handleFinishChunk(state, controller, toolCallStart, options, chunk) {
|
|
900
|
+
function handleFinishChunk(state, controller, toolCallStart, tools, options, chunk) {
|
|
675
901
|
if (state.isInsideToolCall) {
|
|
676
902
|
const trailingBuffer = state.buffer;
|
|
677
903
|
state.buffer = "";
|
|
@@ -680,6 +906,7 @@ function handleFinishChunk(state, controller, toolCallStart, options, chunk) {
|
|
|
680
906
|
controller,
|
|
681
907
|
toolCallStart,
|
|
682
908
|
trailingBuffer,
|
|
909
|
+
tools,
|
|
683
910
|
options
|
|
684
911
|
);
|
|
685
912
|
} else if (state.buffer.length > 0) {
|
|
@@ -688,11 +915,11 @@ function handleFinishChunk(state, controller, toolCallStart, options, chunk) {
|
|
|
688
915
|
closeTextBlock(state, controller);
|
|
689
916
|
controller.enqueue(chunk);
|
|
690
917
|
}
|
|
691
|
-
function publishText(text, state, controller) {
|
|
918
|
+
function publishText(text, state, controller, tools) {
|
|
692
919
|
if (state.isInsideToolCall) {
|
|
693
920
|
closeTextBlock(state, controller);
|
|
694
921
|
state.currentToolCallJson += text;
|
|
695
|
-
emitToolInputProgress(state, controller);
|
|
922
|
+
emitToolInputProgress(state, controller, tools);
|
|
696
923
|
} else if (text.length > 0) {
|
|
697
924
|
if (!state.currentTextId) {
|
|
698
925
|
state.currentTextId = generateId();
|
|
@@ -711,10 +938,10 @@ function publishText(text, state, controller) {
|
|
|
711
938
|
}
|
|
712
939
|
function emitToolCall(context) {
|
|
713
940
|
var _a;
|
|
714
|
-
const { state, controller, toolCallStart, toolCallEnd, options } = context;
|
|
941
|
+
const { state, controller, toolCallStart, toolCallEnd, options, tools } = context;
|
|
715
942
|
try {
|
|
716
943
|
const parsedToolCall = parse(state.currentToolCallJson);
|
|
717
|
-
emitToolCallFromParsed(state, controller, parsedToolCall);
|
|
944
|
+
emitToolCallFromParsed(state, controller, parsedToolCall, tools);
|
|
718
945
|
} catch (error) {
|
|
719
946
|
const errorContent = `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`;
|
|
720
947
|
const shouldEmitRawFallback = shouldEmitRawToolCallTextOnError(options);
|
|
@@ -763,7 +990,7 @@ function processTagMatch(context) {
|
|
|
763
990
|
}
|
|
764
991
|
}
|
|
765
992
|
function processBufferTags(context) {
|
|
766
|
-
const { state, controller, toolCallStart, toolCallEnd } = context;
|
|
993
|
+
const { state, controller, toolCallStart, toolCallEnd, tools } = context;
|
|
767
994
|
let startIndex = getPotentialStartIndex(
|
|
768
995
|
state.buffer,
|
|
769
996
|
state.isInsideToolCall ? toolCallEnd : toolCallStart
|
|
@@ -773,7 +1000,7 @@ function processBufferTags(context) {
|
|
|
773
1000
|
if (startIndex + tag.length > state.buffer.length) {
|
|
774
1001
|
break;
|
|
775
1002
|
}
|
|
776
|
-
publishText(state.buffer.slice(0, startIndex), state, controller);
|
|
1003
|
+
publishText(state.buffer.slice(0, startIndex), state, controller, tools);
|
|
777
1004
|
state.buffer = state.buffer.slice(startIndex + tag.length);
|
|
778
1005
|
processTagMatch(context);
|
|
779
1006
|
startIndex = getPotentialStartIndex(
|
|
@@ -782,24 +1009,34 @@ function processBufferTags(context) {
|
|
|
782
1009
|
);
|
|
783
1010
|
}
|
|
784
1011
|
}
|
|
785
|
-
function handlePartialTag(state, controller, toolCallStart, toolCallEnd) {
|
|
1012
|
+
function handlePartialTag(state, controller, toolCallStart, toolCallEnd, tools) {
|
|
786
1013
|
if (state.isInsideToolCall) {
|
|
787
1014
|
const potentialEndIndex = getPotentialStartIndex(state.buffer, toolCallEnd);
|
|
788
1015
|
if (potentialEndIndex != null && potentialEndIndex + toolCallEnd.length > state.buffer.length) {
|
|
789
|
-
publishText(
|
|
1016
|
+
publishText(
|
|
1017
|
+
state.buffer.slice(0, potentialEndIndex),
|
|
1018
|
+
state,
|
|
1019
|
+
controller,
|
|
1020
|
+
tools
|
|
1021
|
+
);
|
|
790
1022
|
state.buffer = state.buffer.slice(potentialEndIndex);
|
|
791
1023
|
} else {
|
|
792
|
-
publishText(state.buffer, state, controller);
|
|
1024
|
+
publishText(state.buffer, state, controller, tools);
|
|
793
1025
|
state.buffer = "";
|
|
794
1026
|
}
|
|
795
1027
|
return;
|
|
796
1028
|
}
|
|
797
1029
|
const potentialIndex = getPotentialStartIndex(state.buffer, toolCallStart);
|
|
798
1030
|
if (potentialIndex != null && potentialIndex + toolCallStart.length > state.buffer.length) {
|
|
799
|
-
publishText(
|
|
1031
|
+
publishText(
|
|
1032
|
+
state.buffer.slice(0, potentialIndex),
|
|
1033
|
+
state,
|
|
1034
|
+
controller,
|
|
1035
|
+
tools
|
|
1036
|
+
);
|
|
800
1037
|
state.buffer = state.buffer.slice(potentialIndex);
|
|
801
1038
|
} else {
|
|
802
|
-
publishText(state.buffer, state, controller);
|
|
1039
|
+
publishText(state.buffer, state, controller, tools);
|
|
803
1040
|
state.buffer = "";
|
|
804
1041
|
}
|
|
805
1042
|
}
|
|
@@ -811,7 +1048,7 @@ var hermesProtocol = ({
|
|
|
811
1048
|
tools,
|
|
812
1049
|
toolSystemPromptTemplate
|
|
813
1050
|
}) {
|
|
814
|
-
return
|
|
1051
|
+
return formatToolsWithPromptTemplate({ tools, toolSystemPromptTemplate });
|
|
815
1052
|
},
|
|
816
1053
|
formatToolCall(toolCall) {
|
|
817
1054
|
let args = {};
|
|
@@ -857,6 +1094,7 @@ var hermesProtocol = ({
|
|
|
857
1094
|
return processedElements;
|
|
858
1095
|
},
|
|
859
1096
|
createStreamParser({
|
|
1097
|
+
tools,
|
|
860
1098
|
options
|
|
861
1099
|
}) {
|
|
862
1100
|
const state = {
|
|
@@ -871,7 +1109,14 @@ var hermesProtocol = ({
|
|
|
871
1109
|
transform(chunk, controller) {
|
|
872
1110
|
var _a;
|
|
873
1111
|
if (chunk.type === "finish") {
|
|
874
|
-
handleFinishChunk(
|
|
1112
|
+
handleFinishChunk(
|
|
1113
|
+
state,
|
|
1114
|
+
controller,
|
|
1115
|
+
toolCallStart,
|
|
1116
|
+
tools,
|
|
1117
|
+
options,
|
|
1118
|
+
chunk
|
|
1119
|
+
);
|
|
875
1120
|
return;
|
|
876
1121
|
}
|
|
877
1122
|
if (chunk.type !== "text-delta") {
|
|
@@ -885,9 +1130,10 @@ var hermesProtocol = ({
|
|
|
885
1130
|
controller,
|
|
886
1131
|
toolCallStart,
|
|
887
1132
|
toolCallEnd,
|
|
888
|
-
options
|
|
1133
|
+
options,
|
|
1134
|
+
tools
|
|
889
1135
|
});
|
|
890
|
-
handlePartialTag(state, controller, toolCallStart, toolCallEnd);
|
|
1136
|
+
handlePartialTag(state, controller, toolCallStart, toolCallEnd, tools);
|
|
891
1137
|
}
|
|
892
1138
|
});
|
|
893
1139
|
},
|
|
@@ -909,80 +1155,6 @@ var hermesProtocol = ({
|
|
|
909
1155
|
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
910
1156
|
var WHITESPACE_REGEX = /\s/;
|
|
911
1157
|
|
|
912
|
-
// src/core/utils/streamed-tool-input-delta.ts
|
|
913
|
-
function emitDelta({
|
|
914
|
-
controller,
|
|
915
|
-
id,
|
|
916
|
-
state,
|
|
917
|
-
nextInput
|
|
918
|
-
}) {
|
|
919
|
-
if (!nextInput.startsWith(state.emittedInput)) {
|
|
920
|
-
return false;
|
|
921
|
-
}
|
|
922
|
-
const delta = nextInput.slice(state.emittedInput.length);
|
|
923
|
-
if (delta.length === 0) {
|
|
924
|
-
return false;
|
|
925
|
-
}
|
|
926
|
-
controller.enqueue({
|
|
927
|
-
type: "tool-input-delta",
|
|
928
|
-
id,
|
|
929
|
-
delta
|
|
930
|
-
});
|
|
931
|
-
state.emittedInput = nextInput;
|
|
932
|
-
return true;
|
|
933
|
-
}
|
|
934
|
-
function toIncompleteJsonPrefix(fullJson) {
|
|
935
|
-
const trimmed = fullJson.trim();
|
|
936
|
-
let prefix = trimmed;
|
|
937
|
-
while (prefix.endsWith("}") || prefix.endsWith("]")) {
|
|
938
|
-
prefix = prefix.slice(0, -1);
|
|
939
|
-
}
|
|
940
|
-
prefix = prefix.trimEnd();
|
|
941
|
-
if (prefix.endsWith('"')) {
|
|
942
|
-
prefix = prefix.slice(0, -1);
|
|
943
|
-
}
|
|
944
|
-
if (prefix.length === 0) {
|
|
945
|
-
if (trimmed.startsWith("[") || trimmed.startsWith("{")) {
|
|
946
|
-
return trimmed.startsWith("{") ? "{" : "[";
|
|
947
|
-
}
|
|
948
|
-
if (trimmed.startsWith("]")) {
|
|
949
|
-
return "[";
|
|
950
|
-
}
|
|
951
|
-
if (trimmed.startsWith("}")) {
|
|
952
|
-
return "{";
|
|
953
|
-
}
|
|
954
|
-
if (trimmed.startsWith('"')) {
|
|
955
|
-
return '"';
|
|
956
|
-
}
|
|
957
|
-
return "{";
|
|
958
|
-
}
|
|
959
|
-
return prefix;
|
|
960
|
-
}
|
|
961
|
-
function emitPrefixDelta(params) {
|
|
962
|
-
return emitDelta({
|
|
963
|
-
...params,
|
|
964
|
-
nextInput: params.candidate
|
|
965
|
-
});
|
|
966
|
-
}
|
|
967
|
-
function emitFinalRemainder(params) {
|
|
968
|
-
var _a;
|
|
969
|
-
const result = emitDelta({
|
|
970
|
-
...params,
|
|
971
|
-
nextInput: params.finalFullJson
|
|
972
|
-
});
|
|
973
|
-
if (!result && params.state.emittedInput.length > 0) {
|
|
974
|
-
(_a = params.onMismatch) == null ? void 0 : _a.call(
|
|
975
|
-
params,
|
|
976
|
-
"Final JSON does not extend emitted tool-input prefix",
|
|
977
|
-
{
|
|
978
|
-
emittedLength: params.state.emittedInput.length,
|
|
979
|
-
finalLength: params.finalFullJson.length
|
|
980
|
-
}
|
|
981
|
-
);
|
|
982
|
-
}
|
|
983
|
-
return result;
|
|
984
|
-
}
|
|
985
|
-
|
|
986
1158
|
// src/core/utils/xml-root-repair.ts
|
|
987
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*$/;
|
|
988
1160
|
function tryRepairXmlSelfClosingRootWithBody(rawText, toolNames) {
|
|
@@ -1007,15 +1179,241 @@ ${body}
|
|
|
1007
1179
|
</${rootTag}>`;
|
|
1008
1180
|
}
|
|
1009
1181
|
|
|
1010
|
-
// src/core/
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
}
|
|
1018
|
-
|
|
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) {
|
|
1019
1417
|
var _a, _b;
|
|
1020
1418
|
const { toolCall, tools, options, text, processedElements, parseOptions } = params;
|
|
1021
1419
|
const toolSchema = getToolSchema(tools, toolCall.toolName);
|
|
@@ -1243,6 +1641,76 @@ function schemaAllowsArrayType(schema) {
|
|
|
1243
1641
|
}
|
|
1244
1642
|
return false;
|
|
1245
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
|
+
}
|
|
1246
1714
|
function getSchemaObjectProperty(schema, propertyName) {
|
|
1247
1715
|
if (!schema || typeof schema !== "object") {
|
|
1248
1716
|
return null;
|
|
@@ -1292,8 +1760,10 @@ function isStableXmlProgressCandidate(options) {
|
|
|
1292
1760
|
}
|
|
1293
1761
|
function parseXmlContentForStreamProgress({
|
|
1294
1762
|
toolContent,
|
|
1763
|
+
toolName,
|
|
1295
1764
|
toolSchema,
|
|
1296
|
-
parseOptions
|
|
1765
|
+
parseOptions,
|
|
1766
|
+
tools
|
|
1297
1767
|
}) {
|
|
1298
1768
|
const tryParse = (content) => {
|
|
1299
1769
|
try {
|
|
@@ -1312,7 +1782,29 @@ function parseXmlContentForStreamProgress({
|
|
|
1312
1782
|
parsed: strictFull,
|
|
1313
1783
|
toolSchema
|
|
1314
1784
|
})) {
|
|
1315
|
-
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
|
+
}
|
|
1316
1808
|
}
|
|
1317
1809
|
let searchEnd = toolContent.length;
|
|
1318
1810
|
while (searchEnd > 0) {
|
|
@@ -1331,7 +1823,11 @@ function parseXmlContentForStreamProgress({
|
|
|
1331
1823
|
parsed: parsedCandidate,
|
|
1332
1824
|
toolSchema
|
|
1333
1825
|
})) {
|
|
1334
|
-
return
|
|
1826
|
+
return stringifyToolInputWithSchema({
|
|
1827
|
+
toolName,
|
|
1828
|
+
args: parsedCandidate,
|
|
1829
|
+
tools
|
|
1830
|
+
});
|
|
1335
1831
|
}
|
|
1336
1832
|
searchEnd = gtIndex;
|
|
1337
1833
|
}
|
|
@@ -1356,37 +1852,35 @@ function handleStreamingToolCallEnd(params) {
|
|
|
1356
1852
|
flushText(ctrl);
|
|
1357
1853
|
try {
|
|
1358
1854
|
const parsedResult = parse2(toolContent, toolSchema, parseConfig);
|
|
1359
|
-
const finalInput =
|
|
1360
|
-
|
|
1855
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
1856
|
+
toolName: currentToolCall.name,
|
|
1857
|
+
args: parsedResult,
|
|
1858
|
+
tools
|
|
1859
|
+
});
|
|
1860
|
+
emitFinalizedToolInputLifecycle({
|
|
1361
1861
|
controller: ctrl,
|
|
1362
1862
|
id: currentToolCall.toolCallId,
|
|
1363
1863
|
state: currentToolCall,
|
|
1364
|
-
finalFullJson: finalInput,
|
|
1365
|
-
onMismatch: options == null ? void 0 : options.onError
|
|
1366
|
-
});
|
|
1367
|
-
ctrl.enqueue({
|
|
1368
|
-
type: "tool-input-end",
|
|
1369
|
-
id: currentToolCall.toolCallId
|
|
1370
|
-
});
|
|
1371
|
-
ctrl.enqueue({
|
|
1372
|
-
type: "tool-call",
|
|
1373
|
-
toolCallId: currentToolCall.toolCallId,
|
|
1374
1864
|
toolName: currentToolCall.name,
|
|
1375
|
-
|
|
1865
|
+
finalInput,
|
|
1866
|
+
onMismatch: options == null ? void 0 : options.onError
|
|
1376
1867
|
});
|
|
1377
1868
|
} catch (error) {
|
|
1378
|
-
ctrl.enqueue({
|
|
1379
|
-
type: "tool-input-end",
|
|
1380
|
-
id: currentToolCall.toolCallId
|
|
1381
|
-
});
|
|
1382
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
|
+
});
|
|
1383
1880
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, "Could not process streaming XML tool call", {
|
|
1384
1881
|
toolCall: original,
|
|
1385
1882
|
error
|
|
1386
1883
|
});
|
|
1387
|
-
if (shouldEmitRawToolCallTextOnError2(options)) {
|
|
1388
|
-
flushText(ctrl, original);
|
|
1389
|
-
}
|
|
1390
1884
|
}
|
|
1391
1885
|
}
|
|
1392
1886
|
function findClosingTagEndFlexible(text, contentStart, toolName) {
|
|
@@ -1486,22 +1980,6 @@ function nextTagToken(text, fromPos) {
|
|
|
1486
1980
|
nextPos: open.nextPos
|
|
1487
1981
|
};
|
|
1488
1982
|
}
|
|
1489
|
-
function findNextToolTag(text, searchIndex, toolName) {
|
|
1490
|
-
var _a, _b;
|
|
1491
|
-
const startTag = `<${toolName}>`;
|
|
1492
|
-
const openIdx = text.indexOf(startTag, searchIndex);
|
|
1493
|
-
const selfMatch = findSelfClosingTag(text, toolName, searchIndex);
|
|
1494
|
-
const selfIdx = (_a = selfMatch == null ? void 0 : selfMatch.index) != null ? _a : -1;
|
|
1495
|
-
if (openIdx === -1 && selfIdx === -1) {
|
|
1496
|
-
return null;
|
|
1497
|
-
}
|
|
1498
|
-
const isSelfClosing = selfIdx !== -1 && (openIdx === -1 || selfIdx < openIdx);
|
|
1499
|
-
return {
|
|
1500
|
-
tagStart: isSelfClosing ? selfIdx : openIdx,
|
|
1501
|
-
isSelfClosing,
|
|
1502
|
-
tagLength: isSelfClosing ? (_b = selfMatch == null ? void 0 : selfMatch.length) != null ? _b : 0 : startTag.length
|
|
1503
|
-
};
|
|
1504
|
-
}
|
|
1505
1983
|
function findLastCloseTagStart(segment, toolName) {
|
|
1506
1984
|
const closeTagPattern = new RegExp(
|
|
1507
1985
|
`</\\s*${escapeRegExp(toolName)}\\s*>`,
|
|
@@ -1529,24 +2007,6 @@ function pushSelfClosingToolCall(toolCalls, toolName, text, tagStart, tagLength)
|
|
|
1529
2007
|
});
|
|
1530
2008
|
return endIndex;
|
|
1531
2009
|
}
|
|
1532
|
-
var selfClosingTagCache = /* @__PURE__ */ new Map();
|
|
1533
|
-
function getSelfClosingTagPattern(toolName) {
|
|
1534
|
-
let pattern = selfClosingTagCache.get(toolName);
|
|
1535
|
-
if (!pattern) {
|
|
1536
|
-
pattern = new RegExp(`<\\s*${escapeRegExp(toolName)}\\s*/>`, "g");
|
|
1537
|
-
selfClosingTagCache.set(toolName, pattern);
|
|
1538
|
-
}
|
|
1539
|
-
return pattern;
|
|
1540
|
-
}
|
|
1541
|
-
function findSelfClosingTag(text, toolName, fromIndex) {
|
|
1542
|
-
const pattern = getSelfClosingTagPattern(toolName);
|
|
1543
|
-
pattern.lastIndex = fromIndex;
|
|
1544
|
-
const match = pattern.exec(text);
|
|
1545
|
-
if (!match || match.index === void 0) {
|
|
1546
|
-
return null;
|
|
1547
|
-
}
|
|
1548
|
-
return { index: match.index, length: match[0].length };
|
|
1549
|
-
}
|
|
1550
2010
|
function appendOpenToolCallIfComplete(toolCalls, text, toolName, tagStart, startTag) {
|
|
1551
2011
|
const contentStart = tagStart + startTag.length;
|
|
1552
2012
|
const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
|
|
@@ -1698,39 +2158,6 @@ function findLinePrefixedToolCall(text, toolNames) {
|
|
|
1698
2158
|
}
|
|
1699
2159
|
return best;
|
|
1700
2160
|
}
|
|
1701
|
-
function findEarliestToolTag(buffer, toolNames) {
|
|
1702
|
-
var _a, _b;
|
|
1703
|
-
let bestIndex = -1;
|
|
1704
|
-
let bestName = "";
|
|
1705
|
-
let bestSelfClosing = false;
|
|
1706
|
-
let bestTagLength = 0;
|
|
1707
|
-
if (toolNames.length > 0) {
|
|
1708
|
-
for (const name of toolNames) {
|
|
1709
|
-
const openTag = `<${name}>`;
|
|
1710
|
-
const idxOpen = buffer.indexOf(openTag);
|
|
1711
|
-
const selfMatch = findSelfClosingTag(buffer, name, 0);
|
|
1712
|
-
const idxSelf = (_a = selfMatch == null ? void 0 : selfMatch.index) != null ? _a : -1;
|
|
1713
|
-
if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
|
|
1714
|
-
bestIndex = idxOpen;
|
|
1715
|
-
bestName = name;
|
|
1716
|
-
bestSelfClosing = false;
|
|
1717
|
-
bestTagLength = openTag.length;
|
|
1718
|
-
}
|
|
1719
|
-
if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
|
|
1720
|
-
bestIndex = idxSelf;
|
|
1721
|
-
bestName = name;
|
|
1722
|
-
bestSelfClosing = true;
|
|
1723
|
-
bestTagLength = (_b = selfMatch == null ? void 0 : selfMatch.length) != null ? _b : 0;
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
|
-
return {
|
|
1728
|
-
index: bestIndex,
|
|
1729
|
-
name: bestName,
|
|
1730
|
-
selfClosing: bestSelfClosing,
|
|
1731
|
-
tagLength: bestTagLength
|
|
1732
|
-
};
|
|
1733
|
-
}
|
|
1734
2161
|
function isOpenTagPrefix(suffix, toolName) {
|
|
1735
2162
|
return `${toolName}>`.startsWith(suffix);
|
|
1736
2163
|
}
|
|
@@ -1748,219 +2175,65 @@ function consumeToolNamePrefix(text, index, toolName) {
|
|
|
1748
2175
|
if (text.charAt(i) !== toolName.charAt(nameIndex)) {
|
|
1749
2176
|
return { index: i, done: false, valid: false };
|
|
1750
2177
|
}
|
|
1751
|
-
i += 1;
|
|
1752
|
-
nameIndex += 1;
|
|
1753
|
-
}
|
|
1754
|
-
return { index: i, done: nameIndex === toolName.length, valid: true };
|
|
1755
|
-
}
|
|
1756
|
-
function isSelfClosingSuffixRemainder(text, index) {
|
|
1757
|
-
if (text.charAt(index) !== "/") {
|
|
1758
|
-
return false;
|
|
1759
|
-
}
|
|
1760
|
-
if (index + 1 >= text.length) {
|
|
1761
|
-
return true;
|
|
1762
|
-
}
|
|
1763
|
-
return index + 1 === text.length - 1 && text.charAt(index + 1) === ">";
|
|
1764
|
-
}
|
|
1765
|
-
function isSelfClosingTagPrefix(suffix, toolName) {
|
|
1766
|
-
let i = consumeWhitespace(suffix, 0);
|
|
1767
|
-
if (i >= suffix.length) {
|
|
1768
|
-
return true;
|
|
1769
|
-
}
|
|
1770
|
-
const nameRemainder = suffix.slice(i);
|
|
1771
|
-
if (toolName.startsWith(nameRemainder)) {
|
|
1772
|
-
return true;
|
|
1773
|
-
}
|
|
1774
|
-
const nameResult = consumeToolNamePrefix(suffix, i, toolName);
|
|
1775
|
-
if (!nameResult.valid) {
|
|
1776
|
-
return false;
|
|
1777
|
-
}
|
|
1778
|
-
i = nameResult.index;
|
|
1779
|
-
if (i >= suffix.length) {
|
|
1780
|
-
return true;
|
|
1781
|
-
}
|
|
1782
|
-
if (!nameResult.done) {
|
|
1783
|
-
return false;
|
|
1784
|
-
}
|
|
1785
|
-
i = consumeWhitespace(suffix, i);
|
|
1786
|
-
if (i >= suffix.length) {
|
|
1787
|
-
return true;
|
|
1788
|
-
}
|
|
1789
|
-
return isSelfClosingSuffixRemainder(suffix, i);
|
|
1790
|
-
}
|
|
1791
|
-
function findPotentialToolTagStart(buffer, toolNames) {
|
|
1792
|
-
if (toolNames.length === 0 || buffer.length === 0) {
|
|
1793
|
-
return -1;
|
|
1794
|
-
}
|
|
1795
|
-
const lastGt = buffer.lastIndexOf(">");
|
|
1796
|
-
const offset = lastGt === -1 ? 0 : lastGt + 1;
|
|
1797
|
-
const trailing = buffer.slice(offset);
|
|
1798
|
-
for (let i = trailing.length - 1; i >= 0; i -= 1) {
|
|
1799
|
-
if (trailing.charAt(i) !== "<") {
|
|
1800
|
-
continue;
|
|
1801
|
-
}
|
|
1802
|
-
const suffix = trailing.slice(i + 1);
|
|
1803
|
-
for (const name of toolNames) {
|
|
1804
|
-
if (isOpenTagPrefix(suffix, name) || isSelfClosingTagPrefix(suffix, name)) {
|
|
1805
|
-
return offset + i;
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
}
|
|
1809
|
-
return -1;
|
|
1810
|
-
}
|
|
1811
|
-
function processToolCallInBuffer(params) {
|
|
1812
|
-
const {
|
|
1813
|
-
buffer,
|
|
1814
|
-
currentToolCall,
|
|
1815
|
-
tools,
|
|
1816
|
-
options,
|
|
1817
|
-
controller,
|
|
1818
|
-
flushText,
|
|
1819
|
-
setBuffer,
|
|
1820
|
-
parseOptions,
|
|
1821
|
-
emitToolInputProgress: emitToolInputProgress2
|
|
1822
|
-
} = params;
|
|
1823
|
-
const endTagPattern = new RegExp(
|
|
1824
|
-
`</\\s*${escapeRegExp(currentToolCall.name)}\\s*>`
|
|
1825
|
-
);
|
|
1826
|
-
const endMatch = endTagPattern.exec(buffer);
|
|
1827
|
-
if (!endMatch || endMatch.index === void 0) {
|
|
1828
|
-
emitToolInputProgress2(controller, currentToolCall, buffer);
|
|
1829
|
-
return { buffer, currentToolCall, shouldBreak: true };
|
|
1830
|
-
}
|
|
1831
|
-
const endIdx = endMatch.index;
|
|
1832
|
-
const endPos = endIdx + endMatch[0].length;
|
|
1833
|
-
const content = buffer.substring(0, endIdx);
|
|
1834
|
-
emitToolInputProgress2(controller, currentToolCall, content);
|
|
1835
|
-
const remainder = buffer.substring(endPos);
|
|
1836
|
-
setBuffer(remainder);
|
|
1837
|
-
handleStreamingToolCallEnd({
|
|
1838
|
-
toolContent: content,
|
|
1839
|
-
currentToolCall,
|
|
1840
|
-
tools,
|
|
1841
|
-
options,
|
|
1842
|
-
ctrl: controller,
|
|
1843
|
-
flushText,
|
|
1844
|
-
parseOptions
|
|
1845
|
-
});
|
|
1846
|
-
return {
|
|
1847
|
-
buffer: remainder,
|
|
1848
|
-
currentToolCall: null,
|
|
1849
|
-
shouldBreak: false
|
|
1850
|
-
};
|
|
1851
|
-
}
|
|
1852
|
-
function processNoToolCallInBuffer(params) {
|
|
1853
|
-
const {
|
|
1854
|
-
buffer,
|
|
1855
|
-
toolNames,
|
|
1856
|
-
controller,
|
|
1857
|
-
flushText,
|
|
1858
|
-
tools,
|
|
1859
|
-
options,
|
|
1860
|
-
parseOptions,
|
|
1861
|
-
setBuffer,
|
|
1862
|
-
emitToolInputStart
|
|
1863
|
-
} = params;
|
|
1864
|
-
const {
|
|
1865
|
-
index: earliestStartTagIndex,
|
|
1866
|
-
name: earliestToolName,
|
|
1867
|
-
selfClosing,
|
|
1868
|
-
tagLength
|
|
1869
|
-
} = findEarliestToolTag(buffer, toolNames);
|
|
1870
|
-
if (earliestStartTagIndex === -1) {
|
|
1871
|
-
const potentialStart = findPotentialToolTagStart(buffer, toolNames);
|
|
1872
|
-
const safeLen = Math.max(
|
|
1873
|
-
0,
|
|
1874
|
-
potentialStart === -1 ? buffer.length : potentialStart
|
|
1875
|
-
);
|
|
1876
|
-
const remaining = buffer.slice(safeLen);
|
|
1877
|
-
if (safeLen > 0) {
|
|
1878
|
-
flushText(controller, buffer.slice(0, safeLen));
|
|
1879
|
-
setBuffer(remaining);
|
|
1880
|
-
}
|
|
1881
|
-
return {
|
|
1882
|
-
buffer: remaining,
|
|
1883
|
-
currentToolCall: null,
|
|
1884
|
-
shouldBreak: true,
|
|
1885
|
-
shouldContinue: false
|
|
1886
|
-
};
|
|
2178
|
+
i += 1;
|
|
2179
|
+
nameIndex += 1;
|
|
1887
2180
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
handleStreamingToolCallEnd({
|
|
1894
|
-
toolContent: "",
|
|
1895
|
-
currentToolCall,
|
|
1896
|
-
tools,
|
|
1897
|
-
options,
|
|
1898
|
-
ctrl: controller,
|
|
1899
|
-
flushText,
|
|
1900
|
-
parseOptions
|
|
1901
|
-
});
|
|
1902
|
-
return {
|
|
1903
|
-
buffer: newBuffer2,
|
|
1904
|
-
currentToolCall: null,
|
|
1905
|
-
shouldBreak: false,
|
|
1906
|
-
shouldContinue: false
|
|
1907
|
-
};
|
|
2181
|
+
return { index: i, done: nameIndex === toolName.length, valid: true };
|
|
2182
|
+
}
|
|
2183
|
+
function isSelfClosingSuffixRemainder(text, index) {
|
|
2184
|
+
if (text.charAt(index) !== "/") {
|
|
2185
|
+
return false;
|
|
1908
2186
|
}
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
return
|
|
1913
|
-
buffer: newBuffer,
|
|
1914
|
-
currentToolCall: emitToolInputStart(controller, earliestToolName),
|
|
1915
|
-
shouldBreak: false,
|
|
1916
|
-
shouldContinue: true
|
|
1917
|
-
};
|
|
2187
|
+
if (index + 1 >= text.length) {
|
|
2188
|
+
return true;
|
|
2189
|
+
}
|
|
2190
|
+
return index + 1 === text.length - 1 && text.charAt(index + 1) === ">";
|
|
1918
2191
|
}
|
|
1919
|
-
function
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
break;
|
|
2192
|
+
function isSelfClosingTagPrefix(suffix, toolName) {
|
|
2193
|
+
let i = consumeWhitespace(suffix, 0);
|
|
2194
|
+
if (i >= suffix.length) {
|
|
2195
|
+
return true;
|
|
2196
|
+
}
|
|
2197
|
+
const nameRemainder = suffix.slice(i);
|
|
2198
|
+
if (toolName.startsWith(nameRemainder)) {
|
|
2199
|
+
return true;
|
|
2200
|
+
}
|
|
2201
|
+
const nameResult = consumeToolNamePrefix(suffix, i, toolName);
|
|
2202
|
+
if (!nameResult.valid) {
|
|
2203
|
+
return false;
|
|
2204
|
+
}
|
|
2205
|
+
i = nameResult.index;
|
|
2206
|
+
if (i >= suffix.length) {
|
|
2207
|
+
return true;
|
|
2208
|
+
}
|
|
2209
|
+
if (!nameResult.done) {
|
|
2210
|
+
return false;
|
|
2211
|
+
}
|
|
2212
|
+
i = consumeWhitespace(suffix, i);
|
|
2213
|
+
if (i >= suffix.length) {
|
|
2214
|
+
return true;
|
|
2215
|
+
}
|
|
2216
|
+
return isSelfClosingSuffixRemainder(suffix, i);
|
|
2217
|
+
}
|
|
2218
|
+
function findPotentialToolTagStart(buffer, toolNames) {
|
|
2219
|
+
if (toolNames.length === 0 || buffer.length === 0) {
|
|
2220
|
+
return -1;
|
|
2221
|
+
}
|
|
2222
|
+
const lastGt = buffer.lastIndexOf(">");
|
|
2223
|
+
const offset = lastGt === -1 ? 0 : lastGt + 1;
|
|
2224
|
+
const trailing = buffer.slice(offset);
|
|
2225
|
+
for (let i = trailing.length - 1; i >= 0; i -= 1) {
|
|
2226
|
+
if (trailing.charAt(i) !== "<") {
|
|
2227
|
+
continue;
|
|
2228
|
+
}
|
|
2229
|
+
const suffix = trailing.slice(i + 1);
|
|
2230
|
+
for (const name of toolNames) {
|
|
2231
|
+
if (isOpenTagPrefix(suffix, name) || isSelfClosingTagPrefix(suffix, name)) {
|
|
2232
|
+
return offset + i;
|
|
1961
2233
|
}
|
|
1962
2234
|
}
|
|
1963
|
-
}
|
|
2235
|
+
}
|
|
2236
|
+
return -1;
|
|
1964
2237
|
}
|
|
1965
2238
|
function findToolCallsWithFallbacks(text, toolNames) {
|
|
1966
2239
|
let parseText = text;
|
|
@@ -1992,7 +2265,7 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
1992
2265
|
};
|
|
1993
2266
|
return {
|
|
1994
2267
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1995
|
-
return
|
|
2268
|
+
return formatToolsWithPromptTemplate({ tools, toolSystemPromptTemplate });
|
|
1996
2269
|
},
|
|
1997
2270
|
formatToolCall(toolCall) {
|
|
1998
2271
|
let args = {};
|
|
@@ -2010,7 +2283,7 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2010
2283
|
});
|
|
2011
2284
|
},
|
|
2012
2285
|
parseGeneratedText({ text, tools, options }) {
|
|
2013
|
-
const toolNames = tools
|
|
2286
|
+
const toolNames = extractToolNames(tools);
|
|
2014
2287
|
if (toolNames.length === 0) {
|
|
2015
2288
|
return [{ type: "text", text }];
|
|
2016
2289
|
}
|
|
@@ -2046,7 +2319,7 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2046
2319
|
return processedElements;
|
|
2047
2320
|
},
|
|
2048
2321
|
createStreamParser({ tools, options }) {
|
|
2049
|
-
const toolNames = tools
|
|
2322
|
+
const toolNames = extractToolNames(tools);
|
|
2050
2323
|
let buffer = "";
|
|
2051
2324
|
let currentToolCall = null;
|
|
2052
2325
|
let currentTextId = null;
|
|
@@ -2067,6 +2340,7 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2067
2340
|
name: toolName,
|
|
2068
2341
|
toolCallId: generateToolCallId(),
|
|
2069
2342
|
emittedInput: "",
|
|
2343
|
+
lastProgressContentLength: null,
|
|
2070
2344
|
lastProgressGtIndex: null,
|
|
2071
2345
|
lastProgressFullInput: null
|
|
2072
2346
|
};
|
|
@@ -2079,7 +2353,8 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2079
2353
|
};
|
|
2080
2354
|
const emitToolInputProgress2 = (controller, toolCall, toolContent) => {
|
|
2081
2355
|
const progressGtIndex = toolContent.lastIndexOf(">");
|
|
2082
|
-
|
|
2356
|
+
const progressContentLength = toolContent.length;
|
|
2357
|
+
if (toolCall.lastProgressGtIndex === progressGtIndex && toolCall.lastProgressContentLength === progressContentLength) {
|
|
2083
2358
|
const cached = toolCall.lastProgressFullInput;
|
|
2084
2359
|
if (cached == null) {
|
|
2085
2360
|
return;
|
|
@@ -2087,22 +2362,24 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2087
2362
|
if (cached === "{}" && toolContent.trim().length === 0) {
|
|
2088
2363
|
return;
|
|
2089
2364
|
}
|
|
2090
|
-
|
|
2091
|
-
emitPrefixDelta({
|
|
2365
|
+
emitToolInputProgressDelta({
|
|
2092
2366
|
controller,
|
|
2093
2367
|
id: toolCall.toolCallId,
|
|
2094
2368
|
state: toolCall,
|
|
2095
|
-
|
|
2369
|
+
fullInput: cached
|
|
2096
2370
|
});
|
|
2097
2371
|
return;
|
|
2098
2372
|
}
|
|
2099
2373
|
const toolSchema = getToolSchema(tools, toolCall.name);
|
|
2100
2374
|
const fullInput = parseXmlContentForStreamProgress({
|
|
2101
2375
|
toolContent,
|
|
2376
|
+
toolName: toolCall.name,
|
|
2102
2377
|
toolSchema,
|
|
2103
|
-
parseOptions
|
|
2378
|
+
parseOptions,
|
|
2379
|
+
tools
|
|
2104
2380
|
});
|
|
2105
2381
|
toolCall.lastProgressGtIndex = progressGtIndex;
|
|
2382
|
+
toolCall.lastProgressContentLength = progressContentLength;
|
|
2106
2383
|
toolCall.lastProgressFullInput = fullInput;
|
|
2107
2384
|
if (fullInput == null) {
|
|
2108
2385
|
return;
|
|
@@ -2110,12 +2387,11 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2110
2387
|
if (fullInput === "{}" && toolContent.trim().length === 0) {
|
|
2111
2388
|
return;
|
|
2112
2389
|
}
|
|
2113
|
-
|
|
2114
|
-
emitPrefixDelta({
|
|
2390
|
+
emitToolInputProgressDelta({
|
|
2115
2391
|
controller,
|
|
2116
2392
|
id: toolCall.toolCallId,
|
|
2117
2393
|
state: toolCall,
|
|
2118
|
-
|
|
2394
|
+
fullInput
|
|
2119
2395
|
});
|
|
2120
2396
|
};
|
|
2121
2397
|
const finalizeUnclosedToolCall = (controller) => {
|
|
@@ -2137,59 +2413,59 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2137
2413
|
);
|
|
2138
2414
|
}
|
|
2139
2415
|
const parsedResult = parse2(buffer, toolSchema, parseConfig);
|
|
2140
|
-
const finalInput =
|
|
2141
|
-
|
|
2416
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
2417
|
+
toolName: currentToolCall.name,
|
|
2418
|
+
args: parsedResult,
|
|
2419
|
+
tools
|
|
2420
|
+
});
|
|
2421
|
+
emitFinalizedToolInputLifecycle({
|
|
2142
2422
|
controller,
|
|
2143
2423
|
id: currentToolCall.toolCallId,
|
|
2144
2424
|
state: currentToolCall,
|
|
2145
|
-
finalFullJson: finalInput,
|
|
2146
|
-
onMismatch: options == null ? void 0 : options.onError
|
|
2147
|
-
});
|
|
2148
|
-
controller.enqueue({
|
|
2149
|
-
type: "tool-input-end",
|
|
2150
|
-
id: currentToolCall.toolCallId
|
|
2151
|
-
});
|
|
2152
|
-
controller.enqueue({
|
|
2153
|
-
type: "tool-call",
|
|
2154
|
-
toolCallId: currentToolCall.toolCallId,
|
|
2155
2425
|
toolName: currentToolCall.name,
|
|
2156
|
-
|
|
2426
|
+
finalInput,
|
|
2427
|
+
onMismatch: options == null ? void 0 : options.onError
|
|
2157
2428
|
});
|
|
2158
2429
|
} catch (error) {
|
|
2159
|
-
controller.enqueue({
|
|
2160
|
-
type: "tool-input-end",
|
|
2161
|
-
id: currentToolCall.toolCallId
|
|
2162
|
-
});
|
|
2163
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
|
+
});
|
|
2164
2441
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
2165
2442
|
options,
|
|
2166
2443
|
"Could not complete streaming XML tool call at finish.",
|
|
2167
2444
|
{ toolCall: unfinishedContent, error }
|
|
2168
2445
|
);
|
|
2169
|
-
if (shouldEmitRawToolCallTextOnError2(options)) {
|
|
2170
|
-
flushText(controller, unfinishedContent);
|
|
2171
|
-
}
|
|
2172
2446
|
}
|
|
2173
2447
|
buffer = "";
|
|
2174
2448
|
currentToolCall = null;
|
|
2175
2449
|
};
|
|
2176
|
-
const processBuffer = createProcessBufferHandler(
|
|
2177
|
-
() => buffer,
|
|
2178
|
-
(newBuffer) => {
|
|
2450
|
+
const processBuffer = createProcessBufferHandler({
|
|
2451
|
+
getBuffer: () => buffer,
|
|
2452
|
+
setBuffer: (newBuffer) => {
|
|
2179
2453
|
buffer = newBuffer;
|
|
2180
2454
|
},
|
|
2181
|
-
() => currentToolCall,
|
|
2182
|
-
(newToolCall) => {
|
|
2455
|
+
getCurrentToolCall: () => currentToolCall,
|
|
2456
|
+
setCurrentToolCall: (newToolCall) => {
|
|
2183
2457
|
currentToolCall = newToolCall;
|
|
2184
2458
|
},
|
|
2185
2459
|
tools,
|
|
2186
|
-
options,
|
|
2460
|
+
parserOptions: options,
|
|
2187
2461
|
toolNames,
|
|
2188
2462
|
flushText,
|
|
2189
2463
|
parseOptions,
|
|
2190
|
-
emitToolInputProgress2,
|
|
2191
|
-
emitToolInputStart
|
|
2192
|
-
|
|
2464
|
+
emitToolInputProgress: emitToolInputProgress2,
|
|
2465
|
+
emitToolInputStart,
|
|
2466
|
+
findPotentialToolTagStart,
|
|
2467
|
+
handleStreamingToolCallEnd
|
|
2468
|
+
});
|
|
2193
2469
|
return new TransformStream({
|
|
2194
2470
|
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Stateful stream parsing requires branching over chunk lifecycle and parser states.
|
|
2195
2471
|
transform(chunk, controller) {
|
|
@@ -2250,44 +2526,128 @@ var morphXmlProtocol = (protocolOptions) => {
|
|
|
2250
2526
|
function isProtocolFactory(protocol) {
|
|
2251
2527
|
return typeof protocol === "function";
|
|
2252
2528
|
}
|
|
2253
|
-
|
|
2254
|
-
return typeof protocol === "function";
|
|
2255
|
-
}
|
|
2529
|
+
var isTCMProtocolFactory = isProtocolFactory;
|
|
2256
2530
|
|
|
2257
|
-
// src/core/
|
|
2258
|
-
function
|
|
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) {
|
|
2259
2552
|
var _a;
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2553
|
+
const parsed = options.parseParamTagAt(
|
|
2554
|
+
options.work,
|
|
2555
|
+
options.lower,
|
|
2556
|
+
options.lt,
|
|
2557
|
+
{
|
|
2558
|
+
allowEndOfString: options.allowEndOfString,
|
|
2559
|
+
callEndTagNameLower: options.callState.endTagName
|
|
2266
2560
|
}
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2561
|
+
);
|
|
2562
|
+
if (!parsed) {
|
|
2563
|
+
return {
|
|
2564
|
+
nextIndex: options.lt + 1,
|
|
2565
|
+
nextLastKept: options.lastKept,
|
|
2566
|
+
shouldStop: false
|
|
2567
|
+
};
|
|
2271
2568
|
}
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
return
|
|
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
|
+
};
|
|
2280
2581
|
}
|
|
2582
|
+
options.callState.partialParam = null;
|
|
2583
|
+
options.mergeParamValue(options.callState.args, parsed.name, parsed.value);
|
|
2281
2584
|
return {
|
|
2282
|
-
|
|
2283
|
-
|
|
2585
|
+
keepSlice: options.work.slice(options.lastKept, parsed.start),
|
|
2586
|
+
nextIndex: parsed.end,
|
|
2587
|
+
nextLastKept: parsed.end,
|
|
2588
|
+
shouldStop: false
|
|
2284
2589
|
};
|
|
2285
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
|
+
}
|
|
2286
2649
|
|
|
2287
2650
|
// src/core/protocols/qwen3coder-protocol.ts
|
|
2288
|
-
function shouldEmitRawToolCallTextOnError3(options) {
|
|
2289
|
-
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
2290
|
-
}
|
|
2291
2651
|
var TOOL_CALL_OPEN_RE = /<tool_call\b[^>]*>/i;
|
|
2292
2652
|
var TOOL_CALL_CLOSE_RE = /<\/tool_call\s*>/i;
|
|
2293
2653
|
var TOOL_CALL_CLOSE_TRAILING_RE = /<\/tool_call\s*>\s*$/i;
|
|
@@ -2578,10 +2938,13 @@ function parseQwen3CoderToolParserUnclosedParamValue(options) {
|
|
|
2578
2938
|
);
|
|
2579
2939
|
if (boundaryIndex == null) {
|
|
2580
2940
|
if (!options.allowEndOfString) {
|
|
2941
|
+
const rawProgressValue = options.text.slice(valueStart);
|
|
2581
2942
|
return {
|
|
2582
2943
|
kind: "partial",
|
|
2583
2944
|
start: options.startIndex,
|
|
2584
|
-
openEnd: options.openEnd
|
|
2945
|
+
openEnd: options.openEnd,
|
|
2946
|
+
name: options.paramName,
|
|
2947
|
+
value: rawProgressValue ? normalizeXmlTextValue(rawProgressValue) : ""
|
|
2585
2948
|
};
|
|
2586
2949
|
}
|
|
2587
2950
|
const rawValue2 = options.text.slice(valueStart);
|
|
@@ -2774,6 +3137,28 @@ function mergeParamValue(args, key, value) {
|
|
|
2774
3137
|
}
|
|
2775
3138
|
args[key] = [existing, value];
|
|
2776
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
|
+
}
|
|
2777
3162
|
function extractParameters(xml, options) {
|
|
2778
3163
|
var _a;
|
|
2779
3164
|
const args = {};
|
|
@@ -3042,14 +3427,6 @@ function parseToolCallInput(input) {
|
|
|
3042
3427
|
return input;
|
|
3043
3428
|
}
|
|
3044
3429
|
}
|
|
3045
|
-
function stringifyToolInputWithSchema(options) {
|
|
3046
|
-
const coerced = coerceToolCallInput(
|
|
3047
|
-
options.toolName,
|
|
3048
|
-
options.args,
|
|
3049
|
-
options.tools
|
|
3050
|
-
);
|
|
3051
|
-
return coerced != null ? coerced : JSON.stringify(options.args);
|
|
3052
|
-
}
|
|
3053
3430
|
function toQwen3CoderToolParserParamText(value) {
|
|
3054
3431
|
if (typeof value === "string") {
|
|
3055
3432
|
return value;
|
|
@@ -3092,7 +3469,7 @@ function appendQwen3CoderToolParserArgs(lines, args) {
|
|
|
3092
3469
|
}
|
|
3093
3470
|
var qwen3CoderProtocol = () => ({
|
|
3094
3471
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
3095
|
-
return
|
|
3472
|
+
return formatToolsWithPromptTemplate({ tools, toolSystemPromptTemplate });
|
|
3096
3473
|
},
|
|
3097
3474
|
formatToolCall(toolCall) {
|
|
3098
3475
|
const args = parseToolCallInput(toolCall.input);
|
|
@@ -3353,7 +3730,6 @@ var qwen3CoderProtocol = () => ({
|
|
|
3353
3730
|
hasEmittedTextStart = value;
|
|
3354
3731
|
}
|
|
3355
3732
|
);
|
|
3356
|
-
const removeSlice = (text, start, end) => text.slice(0, start) + text.slice(end);
|
|
3357
3733
|
const maybeEmitToolInputStart = (controller, callState) => {
|
|
3358
3734
|
if (callState.hasEmittedStart) {
|
|
3359
3735
|
return;
|
|
@@ -3378,27 +3754,40 @@ var qwen3CoderProtocol = () => ({
|
|
|
3378
3754
|
if (!toolName) {
|
|
3379
3755
|
return;
|
|
3380
3756
|
}
|
|
3757
|
+
const argsForProgress = mergeArgsWithPartialParam(
|
|
3758
|
+
callState.args,
|
|
3759
|
+
callState.partialParam
|
|
3760
|
+
);
|
|
3381
3761
|
const fullInput = stringifyToolInputWithSchema({
|
|
3382
3762
|
tools,
|
|
3383
3763
|
toolName,
|
|
3384
|
-
args:
|
|
3764
|
+
args: argsForProgress
|
|
3385
3765
|
});
|
|
3386
3766
|
if (fullInput === "{}") {
|
|
3387
3767
|
return;
|
|
3388
3768
|
}
|
|
3389
|
-
|
|
3390
|
-
emitPrefixDelta({
|
|
3769
|
+
emitToolInputProgressDelta({
|
|
3391
3770
|
controller,
|
|
3392
3771
|
id: callState.toolCallId,
|
|
3393
3772
|
state: callState,
|
|
3394
|
-
|
|
3773
|
+
fullInput
|
|
3395
3774
|
});
|
|
3396
3775
|
};
|
|
3397
3776
|
const finalizeCall = (controller, callState, fallbackToolName, rawToolCallText = null) => {
|
|
3398
3777
|
var _a, _b;
|
|
3399
3778
|
const resolvedToolName = (_a = callState.toolName) != null ? _a : fallbackToolName;
|
|
3400
3779
|
if (!resolvedToolName || resolvedToolName.trim().length === 0) {
|
|
3401
|
-
const shouldEmitRaw =
|
|
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
|
+
});
|
|
3402
3791
|
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
3403
3792
|
options,
|
|
3404
3793
|
shouldEmitRaw && rawToolCallText ? "Could not resolve Qwen3CoderToolParser tool name for tool call; emitting original text." : "Could not resolve Qwen3CoderToolParser tool name for tool call",
|
|
@@ -3406,109 +3795,42 @@ var qwen3CoderProtocol = () => ({
|
|
|
3406
3795
|
toolCallId: callState.toolCallId,
|
|
3407
3796
|
toolCall: rawToolCallText
|
|
3408
3797
|
}
|
|
3409
|
-
);
|
|
3410
|
-
|
|
3411
|
-
controller.enqueue({
|
|
3412
|
-
type: "tool-input-end",
|
|
3413
|
-
id: callState.toolCallId
|
|
3414
|
-
});
|
|
3415
|
-
}
|
|
3416
|
-
if (shouldEmitRaw && rawToolCallText) {
|
|
3417
|
-
flushText(controller, rawToolCallText);
|
|
3418
|
-
}
|
|
3419
|
-
return false;
|
|
3420
|
-
}
|
|
3421
|
-
callState.toolName = resolvedToolName;
|
|
3422
|
-
maybeEmitToolInputStart(controller, callState);
|
|
3423
|
-
maybeEmitToolInputProgress(controller, callState);
|
|
3424
|
-
const finalInput = stringifyToolInputWithSchema({
|
|
3425
|
-
tools,
|
|
3426
|
-
toolName: resolvedToolName,
|
|
3427
|
-
args: callState.args
|
|
3428
|
-
});
|
|
3429
|
-
emitFinalRemainder({
|
|
3430
|
-
controller,
|
|
3431
|
-
id: callState.toolCallId,
|
|
3432
|
-
state: callState,
|
|
3433
|
-
finalFullJson: finalInput,
|
|
3434
|
-
onMismatch: options == null ? void 0 : options.onError
|
|
3435
|
-
});
|
|
3436
|
-
controller.enqueue({
|
|
3437
|
-
type: "tool-input-end",
|
|
3438
|
-
id: callState.toolCallId
|
|
3439
|
-
});
|
|
3440
|
-
controller.enqueue({
|
|
3441
|
-
type: "tool-call",
|
|
3442
|
-
toolCallId: callState.toolCallId,
|
|
3443
|
-
toolName: resolvedToolName,
|
|
3444
|
-
input: finalInput
|
|
3445
|
-
});
|
|
3446
|
-
return true;
|
|
3447
|
-
};
|
|
3448
|
-
const consumeToolNameTag = (controller, callState, work) => {
|
|
3449
|
-
var _a, _b, _c, _d;
|
|
3450
|
-
if (callState.toolName) {
|
|
3451
|
-
return work;
|
|
3452
|
-
}
|
|
3453
|
-
const match = QWEN3CODER_TOOL_PARSER_STREAM_NAME_TAG_RE.exec(work);
|
|
3454
|
-
if (!match) {
|
|
3455
|
-
return work;
|
|
3456
|
-
}
|
|
3457
|
-
const value = normalizeXmlTextValue((_a = match[2]) != null ? _a : "");
|
|
3458
|
-
if (value.trim().length > 0) {
|
|
3459
|
-
callState.toolName = value;
|
|
3460
|
-
}
|
|
3461
|
-
const start = (_b = match.index) != null ? _b : 0;
|
|
3462
|
-
const nextWork = removeSlice(
|
|
3463
|
-
work,
|
|
3464
|
-
start,
|
|
3465
|
-
start + ((_d = (_c = match[0]) == null ? void 0 : _c.length) != null ? _d : 0)
|
|
3466
|
-
);
|
|
3467
|
-
maybeEmitToolInputStart(controller, callState);
|
|
3468
|
-
return nextWork;
|
|
3469
|
-
};
|
|
3470
|
-
const consumeParamTags = (controller, callState, work, allowEndOfString) => {
|
|
3471
|
-
const lower = work.toLowerCase();
|
|
3472
|
-
let index = 0;
|
|
3473
|
-
let lastKept = 0;
|
|
3474
|
-
let pieces = null;
|
|
3475
|
-
while (true) {
|
|
3476
|
-
const lt = lower.indexOf("<", index);
|
|
3477
|
-
if (lt === -1) {
|
|
3478
|
-
break;
|
|
3479
|
-
}
|
|
3480
|
-
const parsed = parseQwen3CoderToolParserParamTagAt(work, lower, lt, {
|
|
3481
|
-
allowEndOfString,
|
|
3482
|
-
callEndTagNameLower: callState.endTagName
|
|
3483
|
-
});
|
|
3484
|
-
if (!parsed) {
|
|
3485
|
-
index = lt + 1;
|
|
3486
|
-
continue;
|
|
3487
|
-
}
|
|
3488
|
-
if (parsed.kind === "partial") {
|
|
3489
|
-
break;
|
|
3490
|
-
}
|
|
3491
|
-
mergeParamValue(callState.args, parsed.name, parsed.value);
|
|
3492
|
-
pieces != null ? pieces : pieces = [];
|
|
3493
|
-
pieces.push(work.slice(lastKept, parsed.start));
|
|
3494
|
-
lastKept = parsed.end;
|
|
3495
|
-
index = parsed.end;
|
|
3496
|
-
}
|
|
3497
|
-
maybeEmitToolInputStart(controller, callState);
|
|
3498
|
-
if (!pieces) {
|
|
3499
|
-
return work;
|
|
3798
|
+
);
|
|
3799
|
+
return false;
|
|
3500
3800
|
}
|
|
3501
|
-
|
|
3502
|
-
return pieces.join("");
|
|
3503
|
-
};
|
|
3504
|
-
const parseCallContent = (controller, callState, content, allowEndOfString) => {
|
|
3505
|
-
let work = content;
|
|
3506
|
-
work = consumeToolNameTag(controller, callState, work);
|
|
3507
|
-
work = consumeParamTags(controller, callState, work, allowEndOfString);
|
|
3801
|
+
callState.toolName = resolvedToolName;
|
|
3508
3802
|
maybeEmitToolInputStart(controller, callState);
|
|
3509
3803
|
maybeEmitToolInputProgress(controller, callState);
|
|
3510
|
-
|
|
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;
|
|
3511
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
|
+
});
|
|
3512
3834
|
const closeTagCache = /* @__PURE__ */ new Map();
|
|
3513
3835
|
const getCloseTagPattern = (endTagName) => {
|
|
3514
3836
|
const cached = closeTagCache.get(endTagName);
|
|
@@ -3547,7 +3869,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3547
3869
|
const consumeCallAtNextBoundary = (controller, callState, fallbackToolName, nextCallStart) => {
|
|
3548
3870
|
const beforeNextCall = callState.buffer.slice(0, nextCallStart);
|
|
3549
3871
|
const afterNextCall = callState.buffer.slice(nextCallStart);
|
|
3550
|
-
callState.buffer =
|
|
3872
|
+
callState.buffer = parseStreamingCallContent(
|
|
3551
3873
|
controller,
|
|
3552
3874
|
callState,
|
|
3553
3875
|
beforeNextCall,
|
|
@@ -3580,7 +3902,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3580
3902
|
);
|
|
3581
3903
|
}
|
|
3582
3904
|
if (!closeMatch) {
|
|
3583
|
-
callState.buffer =
|
|
3905
|
+
callState.buffer = parseStreamingCallContent(
|
|
3584
3906
|
controller,
|
|
3585
3907
|
callState,
|
|
3586
3908
|
callState.buffer,
|
|
@@ -3591,7 +3913,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3591
3913
|
const closeEnd = closeStart + ((_c = (_b = closeMatch[0]) == null ? void 0 : _b.length) != null ? _c : 0);
|
|
3592
3914
|
const beforeClose = callState.buffer.slice(0, closeStart);
|
|
3593
3915
|
const afterClose = callState.buffer.slice(closeEnd);
|
|
3594
|
-
|
|
3916
|
+
parseStreamingCallContent(controller, callState, beforeClose, true);
|
|
3595
3917
|
callState.buffer = "";
|
|
3596
3918
|
finalizeStreamingCall(
|
|
3597
3919
|
controller,
|
|
@@ -3602,7 +3924,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3602
3924
|
return { done: true, remainder: afterClose };
|
|
3603
3925
|
};
|
|
3604
3926
|
const finalizeCallAtFinish = (controller, callState, fallbackToolName) => {
|
|
3605
|
-
callState.buffer =
|
|
3927
|
+
callState.buffer = parseStreamingCallContent(
|
|
3606
3928
|
controller,
|
|
3607
3929
|
callState,
|
|
3608
3930
|
callState.buffer,
|
|
@@ -3708,6 +4030,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3708
4030
|
toolCallId: generateToolCallId(),
|
|
3709
4031
|
toolName: inlineToolName,
|
|
3710
4032
|
hasEmittedStart: false,
|
|
4033
|
+
partialParam: null,
|
|
3711
4034
|
emittedInput: "",
|
|
3712
4035
|
raw: openTag,
|
|
3713
4036
|
args: {},
|
|
@@ -3791,6 +4114,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3791
4114
|
toolCallId: generateToolCallId(),
|
|
3792
4115
|
toolName: toolCall.outerNameAttr,
|
|
3793
4116
|
hasEmittedStart: false,
|
|
4117
|
+
partialParam: null,
|
|
3794
4118
|
emittedInput: "",
|
|
3795
4119
|
raw: toolCall.outerOpenTag,
|
|
3796
4120
|
args: {},
|
|
@@ -3887,6 +4211,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3887
4211
|
toolCallId: generateToolCallId(),
|
|
3888
4212
|
toolName: toolNameAttr2,
|
|
3889
4213
|
hasEmittedStart: false,
|
|
4214
|
+
partialParam: null,
|
|
3890
4215
|
emittedInput: "",
|
|
3891
4216
|
raw: openTag,
|
|
3892
4217
|
args: {},
|
|
@@ -3910,6 +4235,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3910
4235
|
toolCallId: generateToolCallId(),
|
|
3911
4236
|
toolName: toolNameAttr,
|
|
3912
4237
|
hasEmittedStart: false,
|
|
4238
|
+
partialParam: null,
|
|
3913
4239
|
emittedInput: "",
|
|
3914
4240
|
raw: openTag,
|
|
3915
4241
|
args: {},
|
|
@@ -3925,7 +4251,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3925
4251
|
};
|
|
3926
4252
|
const reportUnfinishedToolCallAtFinish = (controller, rawToolCall) => {
|
|
3927
4253
|
var _a;
|
|
3928
|
-
const shouldEmitRaw =
|
|
4254
|
+
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
3929
4255
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
3930
4256
|
options,
|
|
3931
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.",
|
|
@@ -3937,7 +4263,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3937
4263
|
};
|
|
3938
4264
|
const reportUnfinishedImplicitCallAtFinish = (controller, rawCallText) => {
|
|
3939
4265
|
var _a;
|
|
3940
|
-
const shouldEmitRaw =
|
|
4266
|
+
const shouldEmitRaw = shouldEmitRawToolCallTextOnError(options);
|
|
3941
4267
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
3942
4268
|
options,
|
|
3943
4269
|
shouldEmitRaw ? "Could not complete streaming Qwen3CoderToolParser call block at finish; emitting original text." : "Could not complete streaming Qwen3CoderToolParser call block at finish.",
|
|
@@ -3968,6 +4294,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3968
4294
|
toolCallId: generateToolCallId(),
|
|
3969
4295
|
toolName: toolCall.outerNameAttr,
|
|
3970
4296
|
hasEmittedStart: false,
|
|
4297
|
+
partialParam: null,
|
|
3971
4298
|
emittedInput: "",
|
|
3972
4299
|
raw: toolCall.outerOpenTag,
|
|
3973
4300
|
args: {},
|
|
@@ -3986,7 +4313,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
3986
4313
|
if (result.ok) {
|
|
3987
4314
|
toolCall.emittedToolCallCount += 1;
|
|
3988
4315
|
}
|
|
3989
|
-
const shouldFlushTrailingText = result.ok || !
|
|
4316
|
+
const shouldFlushTrailingText = result.ok || !shouldEmitRawToolCallTextOnError(options);
|
|
3990
4317
|
if (shouldFlushTrailingText && result.trailingText.length > 0) {
|
|
3991
4318
|
flushText(controller, result.trailingText);
|
|
3992
4319
|
}
|
|
@@ -4003,7 +4330,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
4003
4330
|
if (result.ok) {
|
|
4004
4331
|
toolCall.emittedToolCallCount += 1;
|
|
4005
4332
|
}
|
|
4006
|
-
const shouldFlushTrailingText = result.ok || !
|
|
4333
|
+
const shouldFlushTrailingText = result.ok || !shouldEmitRawToolCallTextOnError(options);
|
|
4007
4334
|
if (shouldFlushTrailingText && result.trailingText.length > 0) {
|
|
4008
4335
|
flushText(controller, result.trailingText);
|
|
4009
4336
|
}
|
|
@@ -4026,7 +4353,7 @@ var qwen3CoderProtocol = () => ({
|
|
|
4026
4353
|
implicitCall = null;
|
|
4027
4354
|
implicitCallOpenTag = null;
|
|
4028
4355
|
const result = finalizeCallAtFinish(controller, callState, null);
|
|
4029
|
-
const shouldFlushTrailingText = result.ok || !
|
|
4356
|
+
const shouldFlushTrailingText = result.ok || !shouldEmitRawToolCallTextOnError(options);
|
|
4030
4357
|
if (shouldFlushTrailingText && result.trailingText.length > 0) {
|
|
4031
4358
|
flushText(controller, result.trailingText);
|
|
4032
4359
|
}
|
|
@@ -4118,18 +4445,6 @@ var Qwen3CoderToolParser = qwen3CoderProtocol;
|
|
|
4118
4445
|
|
|
4119
4446
|
// src/core/protocols/yaml-xml-protocol.ts
|
|
4120
4447
|
import YAML from "yaml";
|
|
4121
|
-
function shouldEmitRawToolCallTextOnError4(options) {
|
|
4122
|
-
return (options == null ? void 0 : options.emitRawToolCallTextOnError) === true;
|
|
4123
|
-
}
|
|
4124
|
-
var selfClosingTagCache2 = /* @__PURE__ */ new Map();
|
|
4125
|
-
function getSelfClosingTagPattern2(toolName) {
|
|
4126
|
-
let pattern = selfClosingTagCache2.get(toolName);
|
|
4127
|
-
if (!pattern) {
|
|
4128
|
-
pattern = new RegExp(`<\\s*${escapeRegExp(toolName)}\\s*/>`, "g");
|
|
4129
|
-
selfClosingTagCache2.set(toolName, pattern);
|
|
4130
|
-
}
|
|
4131
|
-
return pattern;
|
|
4132
|
-
}
|
|
4133
4448
|
var LEADING_WHITESPACE_RE = /^(\s*)/;
|
|
4134
4449
|
var INCOMPLETE_MAPPING_TAIL_RE = /^[^:[\]{}-][^:]*:\s*$/;
|
|
4135
4450
|
var INCOMPLETE_SEQUENCE_TAIL_RE = /^-\s*$/;
|
|
@@ -4377,34 +4692,19 @@ function findClosingTagEnd2(text, contentStart, toolName) {
|
|
|
4377
4692
|
}
|
|
4378
4693
|
return -1;
|
|
4379
4694
|
}
|
|
4380
|
-
function findEarliestTagPosition(openIdx, selfIdx) {
|
|
4381
|
-
const hasSelf = selfIdx !== -1;
|
|
4382
|
-
const hasOpen = openIdx !== -1;
|
|
4383
|
-
if (hasSelf && (!hasOpen || selfIdx < openIdx)) {
|
|
4384
|
-
return { tagStart: selfIdx, isSelfClosing: true };
|
|
4385
|
-
}
|
|
4386
|
-
return { tagStart: openIdx, isSelfClosing: false };
|
|
4387
|
-
}
|
|
4388
4695
|
function collectToolCallsForName(text, toolName) {
|
|
4389
4696
|
const toolCalls = [];
|
|
4390
4697
|
let searchIndex = 0;
|
|
4391
4698
|
const startTag = `<${toolName}>`;
|
|
4392
|
-
const selfTagRegex = getSelfClosingTagPattern2(toolName);
|
|
4393
4699
|
while (searchIndex < text.length) {
|
|
4394
|
-
const
|
|
4395
|
-
|
|
4396
|
-
const selfMatch = selfTagRegex.exec(text);
|
|
4397
|
-
const selfIdx = selfMatch ? selfMatch.index : -1;
|
|
4398
|
-
const selfTagLength = selfMatch ? selfMatch[0].length : 0;
|
|
4399
|
-
if (openIdx === -1 && selfIdx === -1) {
|
|
4700
|
+
const match = findNextToolTag(text, searchIndex, toolName);
|
|
4701
|
+
if (match === null) {
|
|
4400
4702
|
break;
|
|
4401
4703
|
}
|
|
4402
|
-
const
|
|
4403
|
-
|
|
4404
|
-
selfIdx
|
|
4405
|
-
);
|
|
4704
|
+
const tagStart = match.tagStart;
|
|
4705
|
+
const isSelfClosing = match.isSelfClosing;
|
|
4406
4706
|
if (isSelfClosing) {
|
|
4407
|
-
const endIndex = tagStart +
|
|
4707
|
+
const endIndex = tagStart + match.tagLength;
|
|
4408
4708
|
toolCalls.push({
|
|
4409
4709
|
toolName,
|
|
4410
4710
|
startIndex: tagStart,
|
|
@@ -4510,38 +4810,6 @@ function processToolCallMatch(text, tc, currentIndex, processedElements, options
|
|
|
4510
4810
|
}
|
|
4511
4811
|
return tc.endIndex;
|
|
4512
4812
|
}
|
|
4513
|
-
function findEarliestToolTag2(buffer, toolNames) {
|
|
4514
|
-
let bestIndex = -1;
|
|
4515
|
-
let bestName = "";
|
|
4516
|
-
let bestSelfClosing = false;
|
|
4517
|
-
let bestTagLength = 0;
|
|
4518
|
-
for (const name of toolNames) {
|
|
4519
|
-
const openTag = `<${name}>`;
|
|
4520
|
-
const selfTagRegex = getSelfClosingTagPattern2(name);
|
|
4521
|
-
const idxOpen = buffer.indexOf(openTag);
|
|
4522
|
-
selfTagRegex.lastIndex = 0;
|
|
4523
|
-
const selfMatch = selfTagRegex.exec(buffer);
|
|
4524
|
-
const idxSelf = selfMatch ? selfMatch.index : -1;
|
|
4525
|
-
if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
|
|
4526
|
-
bestIndex = idxOpen;
|
|
4527
|
-
bestName = name;
|
|
4528
|
-
bestSelfClosing = false;
|
|
4529
|
-
bestTagLength = openTag.length;
|
|
4530
|
-
}
|
|
4531
|
-
if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
|
|
4532
|
-
bestIndex = idxSelf;
|
|
4533
|
-
bestName = name;
|
|
4534
|
-
bestSelfClosing = true;
|
|
4535
|
-
bestTagLength = selfMatch ? selfMatch[0].length : 0;
|
|
4536
|
-
}
|
|
4537
|
-
}
|
|
4538
|
-
return {
|
|
4539
|
-
index: bestIndex,
|
|
4540
|
-
name: bestName,
|
|
4541
|
-
selfClosing: bestSelfClosing,
|
|
4542
|
-
tagLength: bestTagLength
|
|
4543
|
-
};
|
|
4544
|
-
}
|
|
4545
4813
|
function stripTrailingPartialCloseTag(content, toolName) {
|
|
4546
4814
|
const closeTag = `</${toolName}>`;
|
|
4547
4815
|
const lastLineBreakIndex = Math.max(
|
|
@@ -4568,7 +4836,7 @@ function stripTrailingPartialCloseTag(content, toolName) {
|
|
|
4568
4836
|
var yamlXmlProtocol = (_protocolOptions) => {
|
|
4569
4837
|
return {
|
|
4570
4838
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
4571
|
-
return
|
|
4839
|
+
return formatToolsWithPromptTemplate({ tools, toolSystemPromptTemplate });
|
|
4572
4840
|
},
|
|
4573
4841
|
formatToolCall(toolCall) {
|
|
4574
4842
|
let args = {};
|
|
@@ -4584,7 +4852,7 @@ var yamlXmlProtocol = (_protocolOptions) => {
|
|
|
4584
4852
|
${yamlContent}</${toolCall.toolName}>`;
|
|
4585
4853
|
},
|
|
4586
4854
|
parseGeneratedText({ text, tools, options }) {
|
|
4587
|
-
const toolNames = tools
|
|
4855
|
+
const toolNames = extractToolNames(tools);
|
|
4588
4856
|
if (toolNames.length === 0) {
|
|
4589
4857
|
return [{ type: "text", text }];
|
|
4590
4858
|
}
|
|
@@ -4620,7 +4888,7 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4620
4888
|
return processedElements;
|
|
4621
4889
|
},
|
|
4622
4890
|
createStreamParser({ tools, options }) {
|
|
4623
|
-
const toolNames = tools
|
|
4891
|
+
const toolNames = extractToolNames(tools);
|
|
4624
4892
|
let buffer = "";
|
|
4625
4893
|
let currentToolCall = null;
|
|
4626
4894
|
let currentTextId = null;
|
|
@@ -4643,16 +4911,19 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4643
4911
|
if (parsedArgs === null) {
|
|
4644
4912
|
return;
|
|
4645
4913
|
}
|
|
4646
|
-
const fullInput =
|
|
4914
|
+
const fullInput = stringifyToolInputWithSchema({
|
|
4915
|
+
toolName: currentToolCall.name,
|
|
4916
|
+
args: parsedArgs,
|
|
4917
|
+
tools
|
|
4918
|
+
});
|
|
4647
4919
|
if (fullInput === "{}" && toolContent.trim().length === 0) {
|
|
4648
4920
|
return;
|
|
4649
4921
|
}
|
|
4650
|
-
|
|
4651
|
-
emitPrefixDelta({
|
|
4922
|
+
emitToolInputProgressDelta({
|
|
4652
4923
|
controller,
|
|
4653
4924
|
id: currentToolCall.toolCallId,
|
|
4654
4925
|
state: currentToolCall,
|
|
4655
|
-
|
|
4926
|
+
fullInput
|
|
4656
4927
|
});
|
|
4657
4928
|
};
|
|
4658
4929
|
const processToolCallEnd = (controller, toolContent, toolName, toolCallId) => {
|
|
@@ -4660,38 +4931,43 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4660
4931
|
const parsedArgs = parseYamlContent(toolContent, options);
|
|
4661
4932
|
flushText(controller);
|
|
4662
4933
|
if (parsedArgs !== null) {
|
|
4663
|
-
const finalInput =
|
|
4934
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
4935
|
+
toolName,
|
|
4936
|
+
args: parsedArgs,
|
|
4937
|
+
tools
|
|
4938
|
+
});
|
|
4664
4939
|
if (currentToolCall && currentToolCall.toolCallId === toolCallId) {
|
|
4665
|
-
|
|
4940
|
+
emitFinalizedToolInputLifecycle({
|
|
4666
4941
|
controller,
|
|
4667
4942
|
id: toolCallId,
|
|
4668
4943
|
state: currentToolCall,
|
|
4669
|
-
|
|
4944
|
+
toolName,
|
|
4945
|
+
finalInput,
|
|
4670
4946
|
onMismatch: options == null ? void 0 : options.onError
|
|
4671
4947
|
});
|
|
4948
|
+
} else {
|
|
4949
|
+
enqueueToolInputEndAndCall({
|
|
4950
|
+
controller,
|
|
4951
|
+
id: toolCallId,
|
|
4952
|
+
toolName,
|
|
4953
|
+
input: finalInput
|
|
4954
|
+
});
|
|
4672
4955
|
}
|
|
4673
|
-
controller.enqueue({
|
|
4674
|
-
type: "tool-input-end",
|
|
4675
|
-
id: toolCallId
|
|
4676
|
-
});
|
|
4677
|
-
controller.enqueue({
|
|
4678
|
-
type: "tool-call",
|
|
4679
|
-
toolCallId,
|
|
4680
|
-
toolName,
|
|
4681
|
-
input: finalInput
|
|
4682
|
-
});
|
|
4683
4956
|
} else {
|
|
4684
|
-
controller.enqueue({
|
|
4685
|
-
type: "tool-input-end",
|
|
4686
|
-
id: toolCallId
|
|
4687
|
-
});
|
|
4688
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
|
+
});
|
|
4689
4968
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Could not parse streaming YAML tool call", {
|
|
4690
4969
|
toolCall: original
|
|
4691
4970
|
});
|
|
4692
|
-
if (shouldEmitRawToolCallTextOnError4(options)) {
|
|
4693
|
-
flushText(controller, original);
|
|
4694
|
-
}
|
|
4695
4971
|
}
|
|
4696
4972
|
};
|
|
4697
4973
|
const finalizeUnclosedToolCall = (controller) => {
|
|
@@ -4705,38 +4981,36 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4705
4981
|
const parsedArgs = parseYamlContent(reconciledBuffer, options);
|
|
4706
4982
|
flushText(controller);
|
|
4707
4983
|
if (parsedArgs !== null) {
|
|
4708
|
-
const finalInput =
|
|
4709
|
-
|
|
4984
|
+
const finalInput = stringifyToolInputWithSchema({
|
|
4985
|
+
toolName,
|
|
4986
|
+
args: parsedArgs,
|
|
4987
|
+
tools
|
|
4988
|
+
});
|
|
4989
|
+
emitFinalizedToolInputLifecycle({
|
|
4710
4990
|
controller,
|
|
4711
4991
|
id: toolCallId,
|
|
4712
4992
|
state: currentToolCall,
|
|
4713
|
-
finalFullJson: finalInput,
|
|
4714
|
-
onMismatch: options == null ? void 0 : options.onError
|
|
4715
|
-
});
|
|
4716
|
-
controller.enqueue({
|
|
4717
|
-
type: "tool-input-end",
|
|
4718
|
-
id: toolCallId
|
|
4719
|
-
});
|
|
4720
|
-
controller.enqueue({
|
|
4721
|
-
type: "tool-call",
|
|
4722
|
-
toolCallId,
|
|
4723
4993
|
toolName,
|
|
4724
|
-
|
|
4994
|
+
finalInput,
|
|
4995
|
+
onMismatch: options == null ? void 0 : options.onError
|
|
4725
4996
|
});
|
|
4726
4997
|
} else {
|
|
4727
|
-
controller.enqueue({
|
|
4728
|
-
type: "tool-input-end",
|
|
4729
|
-
id: toolCallId
|
|
4730
|
-
});
|
|
4731
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
|
+
});
|
|
4732
5009
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
4733
5010
|
options,
|
|
4734
5011
|
"Could not complete streaming YAML tool call at finish.",
|
|
4735
5012
|
{ toolCall: unfinishedContent }
|
|
4736
5013
|
);
|
|
4737
|
-
if (shouldEmitRawToolCallTextOnError4(options)) {
|
|
4738
|
-
flushText(controller, unfinishedContent);
|
|
4739
|
-
}
|
|
4740
5014
|
}
|
|
4741
5015
|
buffer = "";
|
|
4742
5016
|
currentToolCall = null;
|
|
@@ -4813,7 +5087,7 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4813
5087
|
break;
|
|
4814
5088
|
}
|
|
4815
5089
|
} else {
|
|
4816
|
-
const { index, name, selfClosing, tagLength } =
|
|
5090
|
+
const { index, name, selfClosing, tagLength } = findEarliestToolTag(
|
|
4817
5091
|
buffer,
|
|
4818
5092
|
toolNames
|
|
4819
5093
|
);
|
|
@@ -5010,9 +5284,38 @@ function decodeOriginalTools(originalTools, options) {
|
|
|
5010
5284
|
}
|
|
5011
5285
|
return decodedTools;
|
|
5012
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
|
+
}
|
|
5013
5294
|
function extractToolNamesFromOriginalTools(originalTools) {
|
|
5014
5295
|
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
5015
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
|
+
}
|
|
5016
5319
|
function isToolChoiceActive(params) {
|
|
5017
5320
|
var _a, _b, _c;
|
|
5018
5321
|
const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
|
|
@@ -5032,7 +5335,7 @@ function hasInputProperty(obj) {
|
|
|
5032
5335
|
}
|
|
5033
5336
|
|
|
5034
5337
|
// src/core/utils/generated-text-json-recovery.ts
|
|
5035
|
-
function
|
|
5338
|
+
function isRecord2(value) {
|
|
5036
5339
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5037
5340
|
}
|
|
5038
5341
|
function safeStringify2(value) {
|
|
@@ -5188,7 +5491,7 @@ function toRecoveredParts(text, candidate, toolCallPart) {
|
|
|
5188
5491
|
return out;
|
|
5189
5492
|
}
|
|
5190
5493
|
function parseAsToolPayload(payload, tools) {
|
|
5191
|
-
if (!
|
|
5494
|
+
if (!isRecord2(payload)) {
|
|
5192
5495
|
return null;
|
|
5193
5496
|
}
|
|
5194
5497
|
const toolName = typeof payload.name === "string" && payload.name.trim().length > 0 ? payload.name.trim() : null;
|
|
@@ -5199,7 +5502,7 @@ function parseAsToolPayload(payload, tools) {
|
|
|
5199
5502
|
return null;
|
|
5200
5503
|
}
|
|
5201
5504
|
const rawArgs = Object.hasOwn(payload, "arguments") ? payload.arguments : {};
|
|
5202
|
-
if (!
|
|
5505
|
+
if (!isRecord2(rawArgs)) {
|
|
5203
5506
|
return null;
|
|
5204
5507
|
}
|
|
5205
5508
|
return {
|
|
@@ -5209,14 +5512,14 @@ function parseAsToolPayload(payload, tools) {
|
|
|
5209
5512
|
}
|
|
5210
5513
|
function isLikelyArgumentsShapeForTool(args, tool) {
|
|
5211
5514
|
const unwrapped = unwrapJsonSchema(tool.inputSchema);
|
|
5212
|
-
if (!
|
|
5515
|
+
if (!isRecord2(unwrapped)) {
|
|
5213
5516
|
return false;
|
|
5214
5517
|
}
|
|
5215
5518
|
if (getSchemaType(unwrapped) !== "object") {
|
|
5216
5519
|
return false;
|
|
5217
5520
|
}
|
|
5218
5521
|
const properties = unwrapped.properties;
|
|
5219
|
-
if (!
|
|
5522
|
+
if (!isRecord2(properties)) {
|
|
5220
5523
|
return false;
|
|
5221
5524
|
}
|
|
5222
5525
|
const keys = Object.keys(args);
|
|
@@ -5236,11 +5539,11 @@ function parseAsArgumentsOnly(payload, tools) {
|
|
|
5236
5539
|
if (tools.length !== 1) {
|
|
5237
5540
|
return null;
|
|
5238
5541
|
}
|
|
5239
|
-
if (!
|
|
5542
|
+
if (!isRecord2(payload)) {
|
|
5240
5543
|
return null;
|
|
5241
5544
|
}
|
|
5242
5545
|
const hasNameEnvelope = Object.hasOwn(payload, "name") && typeof payload.name === "string" && payload.name.length > 0;
|
|
5243
|
-
const hasArgumentsEnvelope = Object.hasOwn(payload, "arguments") && (typeof payload.arguments === "string" ||
|
|
5546
|
+
const hasArgumentsEnvelope = Object.hasOwn(payload, "arguments") && (typeof payload.arguments === "string" || isRecord2(payload.arguments));
|
|
5244
5547
|
if (hasNameEnvelope || hasArgumentsEnvelope) {
|
|
5245
5548
|
return null;
|
|
5246
5549
|
}
|
|
@@ -5329,6 +5632,30 @@ function parseToolChoicePayload({
|
|
|
5329
5632
|
input: coercedInput != null ? coercedInput : safeStringify3(rawArgs)
|
|
5330
5633
|
};
|
|
5331
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
|
+
}
|
|
5332
5659
|
|
|
5333
5660
|
// src/generate-handler.ts
|
|
5334
5661
|
function logDebugSummary(debugSummary, toolCall, originText) {
|
|
@@ -5348,29 +5675,23 @@ async function handleToolChoice(doGenerate, params, tools) {
|
|
|
5348
5675
|
var _a, _b, _c, _d;
|
|
5349
5676
|
const result = await doGenerate();
|
|
5350
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;
|
|
5351
5679
|
const onError = (_b = extractOnErrorOption(params.providerOptions)) == null ? void 0 : _b.onError;
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
if (first && first.type === "text") {
|
|
5355
|
-
if (getDebugLevel() === "parse") {
|
|
5356
|
-
logRawChunk(first.text);
|
|
5357
|
-
}
|
|
5358
|
-
const parsed = parseToolChoicePayload({
|
|
5359
|
-
text: first.text,
|
|
5360
|
-
tools,
|
|
5361
|
-
onError,
|
|
5362
|
-
errorMessage: "Failed to parse toolChoice JSON from generated model output"
|
|
5363
|
-
});
|
|
5364
|
-
toolName = parsed.toolName;
|
|
5365
|
-
input = parsed.input;
|
|
5680
|
+
if (typeof firstText === "string" && getDebugLevel() === "parse") {
|
|
5681
|
+
logRawChunk(firstText);
|
|
5366
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
|
+
});
|
|
5367
5689
|
const toolCall = {
|
|
5368
5690
|
type: "tool-call",
|
|
5369
5691
|
toolCallId: generateToolCallId(),
|
|
5370
5692
|
toolName,
|
|
5371
5693
|
input
|
|
5372
5694
|
};
|
|
5373
|
-
const originText = first && first.type === "text" ? first.text : "";
|
|
5374
5695
|
const debugSummary = (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.debugSummary;
|
|
5375
5696
|
logDebugSummary(debugSummary, toolCall, originText);
|
|
5376
5697
|
return {
|
|
@@ -5391,7 +5712,7 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
5391
5712
|
tools,
|
|
5392
5713
|
options: {
|
|
5393
5714
|
...extractOnErrorOption(providerOptions),
|
|
5394
|
-
...providerOptions
|
|
5715
|
+
...getToolCallMiddlewareOptions(providerOptions)
|
|
5395
5716
|
}
|
|
5396
5717
|
});
|
|
5397
5718
|
const hasToolCall = parsedByProtocol.some(
|
|
@@ -5449,10 +5770,9 @@ async function wrapGenerate({
|
|
|
5449
5770
|
doGenerate,
|
|
5450
5771
|
params
|
|
5451
5772
|
}) {
|
|
5452
|
-
var _a, _b;
|
|
5453
5773
|
const onError = extractOnErrorOption(params.providerOptions);
|
|
5454
|
-
const tools =
|
|
5455
|
-
|
|
5774
|
+
const tools = decodeOriginalToolsFromProviderOptions(
|
|
5775
|
+
params.providerOptions,
|
|
5456
5776
|
onError
|
|
5457
5777
|
);
|
|
5458
5778
|
if (isToolChoiceActive(params)) {
|
|
@@ -5482,6 +5802,21 @@ async function wrapGenerate({
|
|
|
5482
5802
|
};
|
|
5483
5803
|
}
|
|
5484
5804
|
|
|
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
|
+
};
|
|
5818
|
+
}
|
|
5819
|
+
|
|
5485
5820
|
// src/core/prompts/shared/tool-result-normalizer.ts
|
|
5486
5821
|
function isMapping(value) {
|
|
5487
5822
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -5527,8 +5862,8 @@ function getContentPartMediaKind(part) {
|
|
|
5527
5862
|
}
|
|
5528
5863
|
}
|
|
5529
5864
|
function shouldPassRawByStrategy(mediaKind, strategy) {
|
|
5530
|
-
var _a
|
|
5531
|
-
const mode = (
|
|
5865
|
+
var _a;
|
|
5866
|
+
const mode = getMediaMode(strategy);
|
|
5532
5867
|
if (mode === "raw") {
|
|
5533
5868
|
return true;
|
|
5534
5869
|
}
|
|
@@ -5538,11 +5873,14 @@ function shouldPassRawByStrategy(mediaKind, strategy) {
|
|
|
5538
5873
|
if (mode === "model") {
|
|
5539
5874
|
return false;
|
|
5540
5875
|
}
|
|
5541
|
-
return ((
|
|
5876
|
+
return ((_a = strategy == null ? void 0 : strategy.capabilities) == null ? void 0 : _a[mediaKind]) === true;
|
|
5542
5877
|
}
|
|
5543
|
-
function
|
|
5878
|
+
function getMediaMode(strategy) {
|
|
5544
5879
|
var _a;
|
|
5545
|
-
|
|
5880
|
+
return (_a = strategy == null ? void 0 : strategy.mode) != null ? _a : "placeholder";
|
|
5881
|
+
}
|
|
5882
|
+
function shouldPassRawContent(contentParts, strategy) {
|
|
5883
|
+
const mode = getMediaMode(strategy);
|
|
5546
5884
|
if (mode === "raw") {
|
|
5547
5885
|
return true;
|
|
5548
5886
|
}
|
|
@@ -5565,6 +5903,10 @@ function shouldPassRawContent(contentParts, strategy) {
|
|
|
5565
5903
|
}
|
|
5566
5904
|
return hasSupportedMediaContent;
|
|
5567
5905
|
}
|
|
5906
|
+
function formatIdPlaceholder(label, fileId) {
|
|
5907
|
+
const displayId = typeof fileId === "string" ? fileId : JSON.stringify(fileId);
|
|
5908
|
+
return `[${label}: ${displayId}]`;
|
|
5909
|
+
}
|
|
5568
5910
|
function formatContentPartPlaceholder(part) {
|
|
5569
5911
|
var _a;
|
|
5570
5912
|
const contentPart = part;
|
|
@@ -5577,8 +5919,7 @@ function formatContentPartPlaceholder(part) {
|
|
|
5577
5919
|
return `[Image URL: ${contentPart.url}]`;
|
|
5578
5920
|
case "image-file-id": {
|
|
5579
5921
|
const fileId = contentPart.fileId;
|
|
5580
|
-
|
|
5581
|
-
return `[Image ID: ${displayId}]`;
|
|
5922
|
+
return formatIdPlaceholder("Image ID", fileId);
|
|
5582
5923
|
}
|
|
5583
5924
|
case "file-data": {
|
|
5584
5925
|
const filePart = contentPart;
|
|
@@ -5591,8 +5932,7 @@ function formatContentPartPlaceholder(part) {
|
|
|
5591
5932
|
return `[File URL: ${contentPart.url}]`;
|
|
5592
5933
|
case "file-id": {
|
|
5593
5934
|
const fileId = contentPart.fileId;
|
|
5594
|
-
|
|
5595
|
-
return `[File ID: ${displayId}]`;
|
|
5935
|
+
return formatIdPlaceholder("File ID", fileId);
|
|
5596
5936
|
}
|
|
5597
5937
|
case "media":
|
|
5598
5938
|
return `[Media: ${contentPart.mediaType}]`;
|
|
@@ -5714,6 +6054,7 @@ For each function call return a json object with function name and arguments wit
|
|
|
5714
6054
|
import dedent from "dedent";
|
|
5715
6055
|
function morphXmlSystemPromptTemplate(tools) {
|
|
5716
6056
|
const toolsText = renderToolsForXmlPrompt(tools);
|
|
6057
|
+
const inputExamplesText = renderInputExamplesForXmlPrompt(tools);
|
|
5717
6058
|
const header = dedent`
|
|
5718
6059
|
# Tools
|
|
5719
6060
|
You may call one or more functions to assist with the user query.
|
|
@@ -5728,7 +6069,7 @@ function morphXmlSystemPromptTemplate(tools) {
|
|
|
5728
6069
|
<rules>
|
|
5729
6070
|
- Use exactly one XML element whose tag name is the function name.
|
|
5730
6071
|
- Put each parameter as a child element.
|
|
5731
|
-
- Values must follow the schema exactly (numbers, arrays, objects, enums
|
|
6072
|
+
- Values must follow the schema exactly (numbers, arrays, objects, enums -> copy as-is).
|
|
5732
6073
|
- Do not add or remove functions or parameters.
|
|
5733
6074
|
- Each required parameter must appear once.
|
|
5734
6075
|
- Output nothing before or after the function call.
|
|
@@ -5744,7 +6085,7 @@ function morphXmlSystemPromptTemplate(tools) {
|
|
|
5744
6085
|
multiple lines</example_parameter_2>
|
|
5745
6086
|
</example_function_name>
|
|
5746
6087
|
`;
|
|
5747
|
-
return [header, definitions, rules, examples].join("\n\n");
|
|
6088
|
+
return [header, definitions, rules, examples, inputExamplesText].filter((section) => section.trim().length > 0).join("\n\n");
|
|
5748
6089
|
}
|
|
5749
6090
|
var INDENT = " ";
|
|
5750
6091
|
function renderToolsForXmlPrompt(tools) {
|
|
@@ -5764,6 +6105,67 @@ function renderToolForXmlPrompt(tool) {
|
|
|
5764
6105
|
lines.push(`schema: ${stringifySchema(normalizedSchema)}`);
|
|
5765
6106
|
return lines.join("\n");
|
|
5766
6107
|
}
|
|
6108
|
+
function getToolInputExamples(tool) {
|
|
6109
|
+
const inputExamples = tool.inputExamples;
|
|
6110
|
+
if (!Array.isArray(inputExamples)) {
|
|
6111
|
+
return [];
|
|
6112
|
+
}
|
|
6113
|
+
return inputExamples.filter(
|
|
6114
|
+
(example) => typeof example === "object" && example !== null && "input" in example && example.input !== void 0
|
|
6115
|
+
);
|
|
6116
|
+
}
|
|
6117
|
+
function safeStringifyInputExample(input, sourceError) {
|
|
6118
|
+
try {
|
|
6119
|
+
const serialized = JSON.stringify(input);
|
|
6120
|
+
return serialized != null ? serialized : "null";
|
|
6121
|
+
} catch (stringifyError) {
|
|
6122
|
+
let reason = "";
|
|
6123
|
+
if (sourceError instanceof Error) {
|
|
6124
|
+
reason = sourceError.message;
|
|
6125
|
+
} else if (stringifyError instanceof Error) {
|
|
6126
|
+
reason = stringifyError.message;
|
|
6127
|
+
}
|
|
6128
|
+
return reason.length > 0 ? `[unserializable input: ${reason}]` : "[unserializable input]";
|
|
6129
|
+
}
|
|
6130
|
+
}
|
|
6131
|
+
function renderMorphXmlInputExample(toolName, input) {
|
|
6132
|
+
try {
|
|
6133
|
+
return stringify(toolName, input, {
|
|
6134
|
+
suppressEmptyNode: false,
|
|
6135
|
+
format: true,
|
|
6136
|
+
minimalEscaping: true
|
|
6137
|
+
});
|
|
6138
|
+
} catch (error) {
|
|
6139
|
+
const fallbackContent = safeStringifyInputExample(input, error);
|
|
6140
|
+
const escapedFallback = escapeXmlMinimalText(fallbackContent);
|
|
6141
|
+
return `<${toolName}>${escapedFallback}</${toolName}>`;
|
|
6142
|
+
}
|
|
6143
|
+
}
|
|
6144
|
+
function renderInputExamplesForXmlPrompt(tools) {
|
|
6145
|
+
const renderedTools = tools.map((tool) => {
|
|
6146
|
+
const inputExamples = getToolInputExamples(tool);
|
|
6147
|
+
if (inputExamples.length === 0) {
|
|
6148
|
+
return "";
|
|
6149
|
+
}
|
|
6150
|
+
const renderedExamples = inputExamples.map((example, index) => {
|
|
6151
|
+
const xml = renderMorphXmlInputExample(tool.name, example.input);
|
|
6152
|
+
return `Example ${index + 1}:
|
|
6153
|
+
${xml}`;
|
|
6154
|
+
}).join("\n\n");
|
|
6155
|
+
return `Tool: ${tool.name}
|
|
6156
|
+
${renderedExamples}`;
|
|
6157
|
+
}).filter((text) => text.length > 0).join("\n\n");
|
|
6158
|
+
if (renderedTools.length === 0) {
|
|
6159
|
+
return "";
|
|
6160
|
+
}
|
|
6161
|
+
return [
|
|
6162
|
+
"# Input Examples",
|
|
6163
|
+
"Treat these as canonical tool-call patterns.",
|
|
6164
|
+
"Reuse the closest structure and nesting, change only values, and do not invent parameters.",
|
|
6165
|
+
"Do not copy example values unless they match the user's request.",
|
|
6166
|
+
renderedTools
|
|
6167
|
+
].join("\n\n");
|
|
6168
|
+
}
|
|
5767
6169
|
function normalizeSchema(schema) {
|
|
5768
6170
|
if (typeof schema === "string") {
|
|
5769
6171
|
try {
|
|
@@ -5984,45 +6386,6 @@ function morphFormatToolResponseAsXml(toolResult) {
|
|
|
5984
6386
|
return morphFormatToolResponseAsXmlWithOptions(toolResult);
|
|
5985
6387
|
}
|
|
5986
6388
|
|
|
5987
|
-
// src/core/prompts/shared/assistant-tool-calls-to-text.ts
|
|
5988
|
-
function assistantToolCallsToTextContent(options) {
|
|
5989
|
-
var _a, _b;
|
|
5990
|
-
const newContent = [];
|
|
5991
|
-
for (const item of options.content) {
|
|
5992
|
-
switch (item.type) {
|
|
5993
|
-
case "tool-call":
|
|
5994
|
-
newContent.push({
|
|
5995
|
-
type: "text",
|
|
5996
|
-
text: options.protocol.formatToolCall(item)
|
|
5997
|
-
});
|
|
5998
|
-
break;
|
|
5999
|
-
case "text":
|
|
6000
|
-
case "reasoning":
|
|
6001
|
-
newContent.push(item);
|
|
6002
|
-
break;
|
|
6003
|
-
default:
|
|
6004
|
-
(_b = (_a = options.conversionOptions) == null ? void 0 : _a.onError) == null ? void 0 : _b.call(
|
|
6005
|
-
_a,
|
|
6006
|
-
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
6007
|
-
{ content: item }
|
|
6008
|
-
);
|
|
6009
|
-
newContent.push({
|
|
6010
|
-
type: "text",
|
|
6011
|
-
text: JSON.stringify(item)
|
|
6012
|
-
});
|
|
6013
|
-
}
|
|
6014
|
-
}
|
|
6015
|
-
if (!newContent.every((entry) => entry.type === "text")) {
|
|
6016
|
-
return newContent;
|
|
6017
|
-
}
|
|
6018
|
-
return [
|
|
6019
|
-
{
|
|
6020
|
-
type: "text",
|
|
6021
|
-
text: newContent.map((entry) => entry.text).join("\n")
|
|
6022
|
-
}
|
|
6023
|
-
];
|
|
6024
|
-
}
|
|
6025
|
-
|
|
6026
6389
|
// src/core/prompts/qwen3coder-prompt.ts
|
|
6027
6390
|
var QWEN3CODER_TOOL_HEADER = "# Tools\n\nYou have access to the following functions:\n\n";
|
|
6028
6391
|
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>";
|
|
@@ -6220,10 +6583,9 @@ async function wrapStream({
|
|
|
6220
6583
|
doGenerate,
|
|
6221
6584
|
params
|
|
6222
6585
|
}) {
|
|
6223
|
-
var _a, _b, _c;
|
|
6224
6586
|
const onErrorOptions = extractOnErrorOption(params.providerOptions);
|
|
6225
|
-
const tools =
|
|
6226
|
-
|
|
6587
|
+
const tools = decodeOriginalToolsFromProviderOptions(
|
|
6588
|
+
params.providerOptions,
|
|
6227
6589
|
onErrorOptions
|
|
6228
6590
|
);
|
|
6229
6591
|
if (isToolChoiceActive(params)) {
|
|
@@ -6237,7 +6599,7 @@ async function wrapStream({
|
|
|
6237
6599
|
const debugLevel = getDebugLevel();
|
|
6238
6600
|
const options = {
|
|
6239
6601
|
...onErrorOptions,
|
|
6240
|
-
...(
|
|
6602
|
+
...getToolCallMiddlewareOptions(params.providerOptions)
|
|
6241
6603
|
};
|
|
6242
6604
|
const coreStream = stream.pipeThrough(
|
|
6243
6605
|
new TransformStream(
|
|
@@ -6287,18 +6649,14 @@ async function toolChoiceStream({
|
|
|
6287
6649
|
var _a;
|
|
6288
6650
|
const normalizedTools = Array.isArray(tools) ? tools : [];
|
|
6289
6651
|
const result = await doGenerate();
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
});
|
|
6299
|
-
toolName = parsed.toolName;
|
|
6300
|
-
input = parsed.input;
|
|
6301
|
-
}
|
|
6652
|
+
const first = (_a = result == null ? void 0 : result.content) == null ? void 0 : _a[0];
|
|
6653
|
+
const firstText = (first == null ? void 0 : first.type) === "text" ? first.text : void 0;
|
|
6654
|
+
const { toolName, input } = resolveToolChoiceSelection({
|
|
6655
|
+
text: firstText,
|
|
6656
|
+
tools: normalizedTools,
|
|
6657
|
+
onError: options == null ? void 0 : options.onError,
|
|
6658
|
+
errorMessage: "Failed to parse toolChoice JSON from streamed model output"
|
|
6659
|
+
});
|
|
6302
6660
|
const stream = new ReadableStream({
|
|
6303
6661
|
start(controller) {
|
|
6304
6662
|
controller.enqueue({
|
|
@@ -6376,18 +6734,51 @@ function normalizeUsage(usage) {
|
|
|
6376
6734
|
return ZERO_USAGE;
|
|
6377
6735
|
}
|
|
6378
6736
|
|
|
6737
|
+
// src/core/prompts/shared/assistant-tool-calls-to-text.ts
|
|
6738
|
+
function assistantToolCallsToTextContent(options) {
|
|
6739
|
+
var _a, _b;
|
|
6740
|
+
const newContent = [];
|
|
6741
|
+
for (const item of options.content) {
|
|
6742
|
+
switch (item.type) {
|
|
6743
|
+
case "tool-call":
|
|
6744
|
+
newContent.push({
|
|
6745
|
+
type: "text",
|
|
6746
|
+
text: options.protocol.formatToolCall(item)
|
|
6747
|
+
});
|
|
6748
|
+
break;
|
|
6749
|
+
case "text":
|
|
6750
|
+
case "reasoning":
|
|
6751
|
+
newContent.push(item);
|
|
6752
|
+
break;
|
|
6753
|
+
default:
|
|
6754
|
+
(_b = (_a = options.conversionOptions) == null ? void 0 : _a.onError) == null ? void 0 : _b.call(
|
|
6755
|
+
_a,
|
|
6756
|
+
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
6757
|
+
{ content: item }
|
|
6758
|
+
);
|
|
6759
|
+
newContent.push({
|
|
6760
|
+
type: "text",
|
|
6761
|
+
text: JSON.stringify(item)
|
|
6762
|
+
});
|
|
6763
|
+
}
|
|
6764
|
+
}
|
|
6765
|
+
if (!newContent.every((entry) => entry.type === "text")) {
|
|
6766
|
+
return newContent;
|
|
6767
|
+
}
|
|
6768
|
+
return [
|
|
6769
|
+
{
|
|
6770
|
+
type: "text",
|
|
6771
|
+
text: newContent.map((entry) => entry.text).join("\n")
|
|
6772
|
+
}
|
|
6773
|
+
];
|
|
6774
|
+
}
|
|
6775
|
+
|
|
6379
6776
|
// src/core/prompts/shared/tool-role-to-user-message.ts
|
|
6380
6777
|
function formatApprovalResponse(part) {
|
|
6381
6778
|
const status = part.approved ? "Approved" : "Denied";
|
|
6382
6779
|
const reason = part.reason ? `: ${part.reason}` : "";
|
|
6383
6780
|
return `[Tool Approval ${status}${reason}]`;
|
|
6384
6781
|
}
|
|
6385
|
-
function toTextPart(text) {
|
|
6386
|
-
return {
|
|
6387
|
-
type: "text",
|
|
6388
|
-
text
|
|
6389
|
-
};
|
|
6390
|
-
}
|
|
6391
6782
|
function normalizeTemplateResult(result) {
|
|
6392
6783
|
if (typeof result === "string") {
|
|
6393
6784
|
return [toTextPart(result)];
|
|
@@ -6494,13 +6885,9 @@ function buildBaseReturnParams(params, finalPrompt, functionTools) {
|
|
|
6494
6885
|
prompt: finalPrompt,
|
|
6495
6886
|
tools: [],
|
|
6496
6887
|
toolChoice: void 0,
|
|
6497
|
-
providerOptions: {
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
|
|
6501
|
-
originalTools: originalToolsSchema.encode(functionTools)
|
|
6502
|
-
}
|
|
6503
|
-
}
|
|
6888
|
+
providerOptions: mergeToolCallMiddlewareOptions(params.providerOptions, {
|
|
6889
|
+
originalTools: originalToolsSchema.encode(functionTools)
|
|
6890
|
+
})
|
|
6504
6891
|
};
|
|
6505
6892
|
}
|
|
6506
6893
|
function findProviderDefinedTool(tools, selectedToolName) {
|
|
@@ -6552,13 +6939,10 @@ function handleToolChoiceTool(params, baseReturnParams) {
|
|
|
6552
6939
|
name: selectedTool.name,
|
|
6553
6940
|
description: typeof selectedTool.description === "string" ? selectedTool.description : void 0
|
|
6554
6941
|
},
|
|
6555
|
-
providerOptions:
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
...params.toolChoice ? { toolChoice: params.toolChoice } : {}
|
|
6560
|
-
}
|
|
6561
|
-
}
|
|
6942
|
+
providerOptions: mergeToolCallMiddlewareOptions(
|
|
6943
|
+
baseReturnParams.providerOptions,
|
|
6944
|
+
params.toolChoice ? { toolChoice: params.toolChoice } : {}
|
|
6945
|
+
)
|
|
6562
6946
|
};
|
|
6563
6947
|
}
|
|
6564
6948
|
function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
@@ -6578,13 +6962,12 @@ function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
|
6578
6962
|
type: "json",
|
|
6579
6963
|
schema: createDynamicIfThenElseSchema(functionTools)
|
|
6580
6964
|
},
|
|
6581
|
-
providerOptions:
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
|
|
6965
|
+
providerOptions: mergeToolCallMiddlewareOptions(
|
|
6966
|
+
baseReturnParams.providerOptions,
|
|
6967
|
+
{
|
|
6585
6968
|
toolChoice: { type: "required" }
|
|
6586
6969
|
}
|
|
6587
|
-
|
|
6970
|
+
)
|
|
6588
6971
|
};
|
|
6589
6972
|
}
|
|
6590
6973
|
function transformParams({
|
|
@@ -6816,7 +7199,10 @@ export {
|
|
|
6816
7199
|
originalToolsSchema,
|
|
6817
7200
|
encodeOriginalTools,
|
|
6818
7201
|
decodeOriginalTools,
|
|
7202
|
+
decodeOriginalToolsFromProviderOptions,
|
|
6819
7203
|
extractToolNamesFromOriginalTools,
|
|
7204
|
+
getToolCallMiddlewareOptions,
|
|
7205
|
+
mergeToolCallMiddlewareOptions,
|
|
6820
7206
|
isToolChoiceActive,
|
|
6821
7207
|
isToolResultPart,
|
|
6822
7208
|
hasInputProperty,
|
|
@@ -6831,4 +7217,4 @@ export {
|
|
|
6831
7217
|
morphXmlToolMiddleware,
|
|
6832
7218
|
yamlXmlToolMiddleware
|
|
6833
7219
|
};
|
|
6834
|
-
//# sourceMappingURL=chunk-
|
|
7220
|
+
//# sourceMappingURL=chunk-X3NZ2YHV.js.map
|