@browser-ai/core 2.1.2 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +291 -274
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +291 -274
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -454,7 +454,267 @@ var ToolCallFenceDetector = class {
|
|
|
454
454
|
}
|
|
455
455
|
};
|
|
456
456
|
|
|
457
|
-
// src/
|
|
457
|
+
// ../shared/src/streaming/tool-call-stream-utils.ts
|
|
458
|
+
function extractToolName(content) {
|
|
459
|
+
const jsonMatch = content.match(/\{\s*"name"\s*:\s*"([^"]+)"/);
|
|
460
|
+
if (jsonMatch) {
|
|
461
|
+
return jsonMatch[1];
|
|
462
|
+
}
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
var ARGUMENTS_FIELD_REGEX = /"arguments"\s*:\s*/g;
|
|
466
|
+
var ARGUMENTS_SEARCH_OVERLAP = 32;
|
|
467
|
+
function createArgumentsStreamState() {
|
|
468
|
+
return {
|
|
469
|
+
searchFrom: 0,
|
|
470
|
+
valueStartIndex: null,
|
|
471
|
+
parseIndex: 0,
|
|
472
|
+
started: false,
|
|
473
|
+
depth: 0,
|
|
474
|
+
inString: false,
|
|
475
|
+
escaped: false,
|
|
476
|
+
complete: false
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
function extractArgumentsDelta(content, state) {
|
|
480
|
+
if (state.complete) {
|
|
481
|
+
return "";
|
|
482
|
+
}
|
|
483
|
+
if (state.valueStartIndex === null) {
|
|
484
|
+
ARGUMENTS_FIELD_REGEX.lastIndex = state.searchFrom;
|
|
485
|
+
const match = ARGUMENTS_FIELD_REGEX.exec(content);
|
|
486
|
+
ARGUMENTS_FIELD_REGEX.lastIndex = 0;
|
|
487
|
+
if (!match || match.index === void 0) {
|
|
488
|
+
state.searchFrom = Math.max(0, content.length - ARGUMENTS_SEARCH_OVERLAP);
|
|
489
|
+
return "";
|
|
490
|
+
}
|
|
491
|
+
state.valueStartIndex = match.index + match[0].length;
|
|
492
|
+
state.parseIndex = state.valueStartIndex;
|
|
493
|
+
state.searchFrom = state.valueStartIndex;
|
|
494
|
+
}
|
|
495
|
+
if (state.parseIndex >= content.length) {
|
|
496
|
+
return "";
|
|
497
|
+
}
|
|
498
|
+
let delta = "";
|
|
499
|
+
for (let i = state.parseIndex; i < content.length; i++) {
|
|
500
|
+
const char = content[i];
|
|
501
|
+
delta += char;
|
|
502
|
+
if (!state.started) {
|
|
503
|
+
if (!/\s/.test(char)) {
|
|
504
|
+
state.started = true;
|
|
505
|
+
if (char === "{" || char === "[") {
|
|
506
|
+
state.depth = 1;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
continue;
|
|
510
|
+
}
|
|
511
|
+
if (state.escaped) {
|
|
512
|
+
state.escaped = false;
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
if (char === "\\") {
|
|
516
|
+
state.escaped = true;
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
if (char === '"') {
|
|
520
|
+
state.inString = !state.inString;
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
if (!state.inString) {
|
|
524
|
+
if (char === "{" || char === "[") {
|
|
525
|
+
state.depth += 1;
|
|
526
|
+
} else if (char === "}" || char === "]") {
|
|
527
|
+
if (state.depth > 0) {
|
|
528
|
+
state.depth -= 1;
|
|
529
|
+
if (state.depth === 0) {
|
|
530
|
+
state.parseIndex = i + 1;
|
|
531
|
+
state.complete = true;
|
|
532
|
+
return delta;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
state.parseIndex = content.length;
|
|
539
|
+
return delta;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// ../shared/src/streaming/stream-processor.ts
|
|
543
|
+
function generateToolCallId2() {
|
|
544
|
+
return `call_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
545
|
+
}
|
|
546
|
+
async function processToolCallStream(chunks, emitTextDelta, controller, options) {
|
|
547
|
+
const fenceDetector = new ToolCallFenceDetector();
|
|
548
|
+
let currentToolCallId = null;
|
|
549
|
+
let toolInputStartEmitted = false;
|
|
550
|
+
let accumulatedFenceContent = "";
|
|
551
|
+
let argumentsStreamState = createArgumentsStreamState();
|
|
552
|
+
let insideFence = false;
|
|
553
|
+
let toolCallDetected = false;
|
|
554
|
+
let toolCalls = [];
|
|
555
|
+
let trailingText = "";
|
|
556
|
+
const resetFenceState = () => {
|
|
557
|
+
currentToolCallId = null;
|
|
558
|
+
toolInputStartEmitted = false;
|
|
559
|
+
accumulatedFenceContent = "";
|
|
560
|
+
argumentsStreamState = createArgumentsStreamState();
|
|
561
|
+
insideFence = false;
|
|
562
|
+
};
|
|
563
|
+
for await (const chunk of chunks) {
|
|
564
|
+
if (toolCallDetected) {
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
fenceDetector.addChunk(chunk);
|
|
568
|
+
while (fenceDetector.hasContent()) {
|
|
569
|
+
const wasInsideFence = insideFence;
|
|
570
|
+
const result = fenceDetector.detectStreamingFence();
|
|
571
|
+
insideFence = result.inFence;
|
|
572
|
+
let madeProgress = false;
|
|
573
|
+
if (!wasInsideFence && result.inFence) {
|
|
574
|
+
if (result.safeContent) {
|
|
575
|
+
emitTextDelta(result.safeContent);
|
|
576
|
+
madeProgress = true;
|
|
577
|
+
}
|
|
578
|
+
currentToolCallId = generateToolCallId2();
|
|
579
|
+
toolInputStartEmitted = false;
|
|
580
|
+
accumulatedFenceContent = "";
|
|
581
|
+
argumentsStreamState = createArgumentsStreamState();
|
|
582
|
+
insideFence = true;
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
if (result.completeFence) {
|
|
586
|
+
madeProgress = true;
|
|
587
|
+
if (result.safeContent) {
|
|
588
|
+
accumulatedFenceContent += result.safeContent;
|
|
589
|
+
}
|
|
590
|
+
if (toolInputStartEmitted && currentToolCallId) {
|
|
591
|
+
const delta = extractArgumentsDelta(
|
|
592
|
+
accumulatedFenceContent,
|
|
593
|
+
argumentsStreamState
|
|
594
|
+
);
|
|
595
|
+
if (delta.length > 0) {
|
|
596
|
+
controller.enqueue({
|
|
597
|
+
type: "tool-input-delta",
|
|
598
|
+
id: currentToolCallId,
|
|
599
|
+
delta
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
const parsed = parseJsonFunctionCalls(result.completeFence);
|
|
604
|
+
const selectedToolCalls = parsed.toolCalls.slice(0, 1);
|
|
605
|
+
if (selectedToolCalls.length === 0) {
|
|
606
|
+
emitTextDelta(result.completeFence);
|
|
607
|
+
if (result.textAfterFence) {
|
|
608
|
+
emitTextDelta(result.textAfterFence);
|
|
609
|
+
}
|
|
610
|
+
resetFenceState();
|
|
611
|
+
continue;
|
|
612
|
+
}
|
|
613
|
+
if (currentToolCallId) {
|
|
614
|
+
selectedToolCalls[0].toolCallId = currentToolCallId;
|
|
615
|
+
}
|
|
616
|
+
for (const [index, call] of selectedToolCalls.entries()) {
|
|
617
|
+
const toolCallId = index === 0 && currentToolCallId ? currentToolCallId : call.toolCallId;
|
|
618
|
+
const toolName = call.toolName;
|
|
619
|
+
const argsJson = JSON.stringify(call.args ?? {});
|
|
620
|
+
if (toolCallId === currentToolCallId) {
|
|
621
|
+
if (!toolInputStartEmitted) {
|
|
622
|
+
controller.enqueue({
|
|
623
|
+
type: "tool-input-start",
|
|
624
|
+
id: toolCallId,
|
|
625
|
+
toolName
|
|
626
|
+
});
|
|
627
|
+
toolInputStartEmitted = true;
|
|
628
|
+
}
|
|
629
|
+
const delta = extractArgumentsDelta(
|
|
630
|
+
accumulatedFenceContent,
|
|
631
|
+
argumentsStreamState
|
|
632
|
+
);
|
|
633
|
+
if (delta.length > 0) {
|
|
634
|
+
controller.enqueue({
|
|
635
|
+
type: "tool-input-delta",
|
|
636
|
+
id: toolCallId,
|
|
637
|
+
delta
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
} else {
|
|
641
|
+
controller.enqueue({
|
|
642
|
+
type: "tool-input-start",
|
|
643
|
+
id: toolCallId,
|
|
644
|
+
toolName
|
|
645
|
+
});
|
|
646
|
+
if (argsJson.length > 0) {
|
|
647
|
+
controller.enqueue({
|
|
648
|
+
type: "tool-input-delta",
|
|
649
|
+
id: toolCallId,
|
|
650
|
+
delta: argsJson
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
controller.enqueue({ type: "tool-input-end", id: toolCallId });
|
|
655
|
+
controller.enqueue({
|
|
656
|
+
type: "tool-call",
|
|
657
|
+
toolCallId,
|
|
658
|
+
toolName,
|
|
659
|
+
input: argsJson,
|
|
660
|
+
providerExecuted: false
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
trailingText = result.textAfterFence ?? "";
|
|
664
|
+
toolCalls = selectedToolCalls;
|
|
665
|
+
toolCallDetected = true;
|
|
666
|
+
resetFenceState();
|
|
667
|
+
break;
|
|
668
|
+
}
|
|
669
|
+
if (insideFence) {
|
|
670
|
+
if (result.safeContent) {
|
|
671
|
+
accumulatedFenceContent += result.safeContent;
|
|
672
|
+
madeProgress = true;
|
|
673
|
+
const toolName = extractToolName(accumulatedFenceContent);
|
|
674
|
+
if (toolName && !toolInputStartEmitted && currentToolCallId) {
|
|
675
|
+
controller.enqueue({
|
|
676
|
+
type: "tool-input-start",
|
|
677
|
+
id: currentToolCallId,
|
|
678
|
+
toolName
|
|
679
|
+
});
|
|
680
|
+
toolInputStartEmitted = true;
|
|
681
|
+
}
|
|
682
|
+
if (toolInputStartEmitted && currentToolCallId) {
|
|
683
|
+
const delta = extractArgumentsDelta(
|
|
684
|
+
accumulatedFenceContent,
|
|
685
|
+
argumentsStreamState
|
|
686
|
+
);
|
|
687
|
+
if (delta.length > 0) {
|
|
688
|
+
controller.enqueue({
|
|
689
|
+
type: "tool-input-delta",
|
|
690
|
+
id: currentToolCallId,
|
|
691
|
+
delta
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
continue;
|
|
697
|
+
}
|
|
698
|
+
if (!insideFence && result.safeContent) {
|
|
699
|
+
emitTextDelta(result.safeContent);
|
|
700
|
+
madeProgress = true;
|
|
701
|
+
}
|
|
702
|
+
if (!madeProgress) {
|
|
703
|
+
break;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
if (toolCallDetected && options?.stopEarlyOnToolCall) {
|
|
707
|
+
break;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
if (!toolCallDetected && fenceDetector.hasContent()) {
|
|
711
|
+
emitTextDelta(fenceDetector.getBuffer());
|
|
712
|
+
fenceDetector.clearBuffer();
|
|
713
|
+
}
|
|
714
|
+
return { toolCallDetected, toolCalls, trailingText };
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// src/utils/convert-to-browser-ai-messages.ts
|
|
458
718
|
import {
|
|
459
719
|
UnsupportedFunctionalityError
|
|
460
720
|
} from "@ai-sdk/provider";
|
|
@@ -761,7 +1021,7 @@ function getExpectedInputs(prompt) {
|
|
|
761
1021
|
return Array.from(inputs).map((type) => ({ type }));
|
|
762
1022
|
}
|
|
763
1023
|
|
|
764
|
-
// src/
|
|
1024
|
+
// src/chat/session-manager.ts
|
|
765
1025
|
import { LoadSettingError } from "@ai-sdk/provider";
|
|
766
1026
|
var SessionManager = class {
|
|
767
1027
|
/**
|
|
@@ -945,67 +1205,10 @@ var SessionManager = class {
|
|
|
945
1205
|
}
|
|
946
1206
|
};
|
|
947
1207
|
|
|
948
|
-
// src/browser-ai-language-model.ts
|
|
1208
|
+
// src/chat/browser-ai-language-model.ts
|
|
949
1209
|
function doesBrowserSupportBrowserAI() {
|
|
950
1210
|
return typeof LanguageModel !== "undefined";
|
|
951
1211
|
}
|
|
952
|
-
function extractToolName(content) {
|
|
953
|
-
const jsonMatch = content.match(/\{\s*"name"\s*:\s*"([^"]+)"/);
|
|
954
|
-
if (jsonMatch) {
|
|
955
|
-
return jsonMatch[1];
|
|
956
|
-
}
|
|
957
|
-
return null;
|
|
958
|
-
}
|
|
959
|
-
function extractArgumentsContent(content) {
|
|
960
|
-
const match = content.match(/"arguments"\s*:\s*/);
|
|
961
|
-
if (!match || match.index === void 0) {
|
|
962
|
-
return "";
|
|
963
|
-
}
|
|
964
|
-
const startIndex = match.index + match[0].length;
|
|
965
|
-
let result = "";
|
|
966
|
-
let depth = 0;
|
|
967
|
-
let inString = false;
|
|
968
|
-
let escaped = false;
|
|
969
|
-
let started = false;
|
|
970
|
-
for (let i = startIndex; i < content.length; i++) {
|
|
971
|
-
const char = content[i];
|
|
972
|
-
result += char;
|
|
973
|
-
if (!started) {
|
|
974
|
-
if (!/\s/.test(char)) {
|
|
975
|
-
started = true;
|
|
976
|
-
if (char === "{" || char === "[") {
|
|
977
|
-
depth = 1;
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
continue;
|
|
981
|
-
}
|
|
982
|
-
if (escaped) {
|
|
983
|
-
escaped = false;
|
|
984
|
-
continue;
|
|
985
|
-
}
|
|
986
|
-
if (char === "\\") {
|
|
987
|
-
escaped = true;
|
|
988
|
-
continue;
|
|
989
|
-
}
|
|
990
|
-
if (char === '"') {
|
|
991
|
-
inString = !inString;
|
|
992
|
-
continue;
|
|
993
|
-
}
|
|
994
|
-
if (!inString) {
|
|
995
|
-
if (char === "{" || char === "[") {
|
|
996
|
-
depth += 1;
|
|
997
|
-
} else if (char === "}" || char === "]") {
|
|
998
|
-
if (depth > 0) {
|
|
999
|
-
depth -= 1;
|
|
1000
|
-
if (depth === 0) {
|
|
1001
|
-
break;
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
return result;
|
|
1008
|
-
}
|
|
1009
1212
|
var BrowserAIChatLanguageModel = class {
|
|
1010
1213
|
constructor(modelId, options = {}) {
|
|
1011
1214
|
this.specificationVersion = "v3";
|
|
@@ -1339,226 +1542,40 @@ var BrowserAIChatLanguageModel = class {
|
|
|
1339
1542
|
if (options.abortSignal) {
|
|
1340
1543
|
options.abortSignal.addEventListener("abort", abortHandler);
|
|
1341
1544
|
}
|
|
1342
|
-
const maxIterations = 10;
|
|
1343
|
-
let iteration = 0;
|
|
1344
1545
|
try {
|
|
1345
|
-
const
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
);
|
|
1352
|
-
currentReader = promptStream.getReader();
|
|
1353
|
-
let toolCalls = [];
|
|
1354
|
-
let toolBlockDetected = false;
|
|
1355
|
-
let trailingTextAfterBlock = "";
|
|
1356
|
-
let currentToolCallId = null;
|
|
1357
|
-
let toolInputStartEmitted = false;
|
|
1358
|
-
let accumulatedFenceContent = "";
|
|
1359
|
-
let streamedArgumentsLength = 0;
|
|
1360
|
-
let insideFence = false;
|
|
1546
|
+
const promptStream = session.promptStreaming(
|
|
1547
|
+
conversationHistory,
|
|
1548
|
+
streamOptions
|
|
1549
|
+
);
|
|
1550
|
+
currentReader = promptStream.getReader();
|
|
1551
|
+
const chunks = (async function* () {
|
|
1361
1552
|
while (!aborted) {
|
|
1362
1553
|
const { done, value } = await currentReader.read();
|
|
1363
|
-
if (done)
|
|
1364
|
-
|
|
1365
|
-
}
|
|
1366
|
-
fenceDetector.addChunk(value);
|
|
1367
|
-
while (fenceDetector.hasContent()) {
|
|
1368
|
-
const wasInsideFence = insideFence;
|
|
1369
|
-
const result = fenceDetector.detectStreamingFence();
|
|
1370
|
-
insideFence = result.inFence;
|
|
1371
|
-
let madeProgress = false;
|
|
1372
|
-
if (!wasInsideFence && result.inFence) {
|
|
1373
|
-
if (result.safeContent) {
|
|
1374
|
-
emitTextDelta(result.safeContent);
|
|
1375
|
-
madeProgress = true;
|
|
1376
|
-
}
|
|
1377
|
-
currentToolCallId = `call_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
1378
|
-
toolInputStartEmitted = false;
|
|
1379
|
-
accumulatedFenceContent = "";
|
|
1380
|
-
streamedArgumentsLength = 0;
|
|
1381
|
-
insideFence = true;
|
|
1382
|
-
continue;
|
|
1383
|
-
}
|
|
1384
|
-
if (result.completeFence) {
|
|
1385
|
-
madeProgress = true;
|
|
1386
|
-
if (result.safeContent) {
|
|
1387
|
-
accumulatedFenceContent += result.safeContent;
|
|
1388
|
-
}
|
|
1389
|
-
if (toolInputStartEmitted && currentToolCallId) {
|
|
1390
|
-
const argsContent = extractArgumentsContent(
|
|
1391
|
-
accumulatedFenceContent
|
|
1392
|
-
);
|
|
1393
|
-
if (argsContent.length > streamedArgumentsLength) {
|
|
1394
|
-
const delta = argsContent.slice(streamedArgumentsLength);
|
|
1395
|
-
streamedArgumentsLength = argsContent.length;
|
|
1396
|
-
if (delta.length > 0) {
|
|
1397
|
-
controller.enqueue({
|
|
1398
|
-
type: "tool-input-delta",
|
|
1399
|
-
id: currentToolCallId,
|
|
1400
|
-
delta
|
|
1401
|
-
});
|
|
1402
|
-
}
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
const parsed = parseJsonFunctionCalls(result.completeFence);
|
|
1406
|
-
const parsedToolCalls = parsed.toolCalls;
|
|
1407
|
-
const selectedToolCalls = parsedToolCalls.slice(0, 1);
|
|
1408
|
-
if (selectedToolCalls.length === 0) {
|
|
1409
|
-
toolCalls = [];
|
|
1410
|
-
toolBlockDetected = false;
|
|
1411
|
-
emitTextDelta(result.completeFence);
|
|
1412
|
-
if (result.textAfterFence) {
|
|
1413
|
-
emitTextDelta(result.textAfterFence);
|
|
1414
|
-
}
|
|
1415
|
-
currentToolCallId = null;
|
|
1416
|
-
toolInputStartEmitted = false;
|
|
1417
|
-
accumulatedFenceContent = "";
|
|
1418
|
-
streamedArgumentsLength = 0;
|
|
1419
|
-
insideFence = false;
|
|
1420
|
-
continue;
|
|
1421
|
-
}
|
|
1422
|
-
if (selectedToolCalls.length > 0 && currentToolCallId) {
|
|
1423
|
-
selectedToolCalls[0].toolCallId = currentToolCallId;
|
|
1424
|
-
}
|
|
1425
|
-
toolCalls = selectedToolCalls;
|
|
1426
|
-
toolBlockDetected = toolCalls.length > 0;
|
|
1427
|
-
for (const [index, call] of toolCalls.entries()) {
|
|
1428
|
-
const toolCallId = index === 0 && currentToolCallId ? currentToolCallId : call.toolCallId;
|
|
1429
|
-
const toolName = call.toolName;
|
|
1430
|
-
const argsJson = JSON.stringify(call.args ?? {});
|
|
1431
|
-
if (toolCallId === currentToolCallId) {
|
|
1432
|
-
if (!toolInputStartEmitted) {
|
|
1433
|
-
controller.enqueue({
|
|
1434
|
-
type: "tool-input-start",
|
|
1435
|
-
id: toolCallId,
|
|
1436
|
-
toolName
|
|
1437
|
-
});
|
|
1438
|
-
toolInputStartEmitted = true;
|
|
1439
|
-
}
|
|
1440
|
-
const argsContent = extractArgumentsContent(
|
|
1441
|
-
accumulatedFenceContent
|
|
1442
|
-
);
|
|
1443
|
-
if (argsContent.length > streamedArgumentsLength) {
|
|
1444
|
-
const delta = argsContent.slice(
|
|
1445
|
-
streamedArgumentsLength
|
|
1446
|
-
);
|
|
1447
|
-
streamedArgumentsLength = argsContent.length;
|
|
1448
|
-
if (delta.length > 0) {
|
|
1449
|
-
controller.enqueue({
|
|
1450
|
-
type: "tool-input-delta",
|
|
1451
|
-
id: toolCallId,
|
|
1452
|
-
delta
|
|
1453
|
-
});
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
} else {
|
|
1457
|
-
controller.enqueue({
|
|
1458
|
-
type: "tool-input-start",
|
|
1459
|
-
id: toolCallId,
|
|
1460
|
-
toolName
|
|
1461
|
-
});
|
|
1462
|
-
if (argsJson.length > 0) {
|
|
1463
|
-
controller.enqueue({
|
|
1464
|
-
type: "tool-input-delta",
|
|
1465
|
-
id: toolCallId,
|
|
1466
|
-
delta: argsJson
|
|
1467
|
-
});
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
controller.enqueue({
|
|
1471
|
-
type: "tool-input-end",
|
|
1472
|
-
id: toolCallId
|
|
1473
|
-
});
|
|
1474
|
-
controller.enqueue({
|
|
1475
|
-
type: "tool-call",
|
|
1476
|
-
toolCallId,
|
|
1477
|
-
toolName,
|
|
1478
|
-
input: argsJson,
|
|
1479
|
-
providerExecuted: false
|
|
1480
|
-
});
|
|
1481
|
-
}
|
|
1482
|
-
trailingTextAfterBlock += result.textAfterFence;
|
|
1483
|
-
madeProgress = true;
|
|
1484
|
-
if (toolBlockDetected && currentReader) {
|
|
1485
|
-
await currentReader.cancel().catch(() => void 0);
|
|
1486
|
-
break;
|
|
1487
|
-
}
|
|
1488
|
-
currentToolCallId = null;
|
|
1489
|
-
toolInputStartEmitted = false;
|
|
1490
|
-
accumulatedFenceContent = "";
|
|
1491
|
-
streamedArgumentsLength = 0;
|
|
1492
|
-
insideFence = false;
|
|
1493
|
-
continue;
|
|
1494
|
-
}
|
|
1495
|
-
if (insideFence) {
|
|
1496
|
-
if (result.safeContent) {
|
|
1497
|
-
accumulatedFenceContent += result.safeContent;
|
|
1498
|
-
madeProgress = true;
|
|
1499
|
-
const toolName = extractToolName(accumulatedFenceContent);
|
|
1500
|
-
if (toolName && !toolInputStartEmitted && currentToolCallId) {
|
|
1501
|
-
controller.enqueue({
|
|
1502
|
-
type: "tool-input-start",
|
|
1503
|
-
id: currentToolCallId,
|
|
1504
|
-
toolName
|
|
1505
|
-
});
|
|
1506
|
-
toolInputStartEmitted = true;
|
|
1507
|
-
}
|
|
1508
|
-
if (toolInputStartEmitted && currentToolCallId) {
|
|
1509
|
-
const argsContent = extractArgumentsContent(
|
|
1510
|
-
accumulatedFenceContent
|
|
1511
|
-
);
|
|
1512
|
-
if (argsContent.length > streamedArgumentsLength) {
|
|
1513
|
-
const delta = argsContent.slice(
|
|
1514
|
-
streamedArgumentsLength
|
|
1515
|
-
);
|
|
1516
|
-
streamedArgumentsLength = argsContent.length;
|
|
1517
|
-
if (delta.length > 0) {
|
|
1518
|
-
controller.enqueue({
|
|
1519
|
-
type: "tool-input-delta",
|
|
1520
|
-
id: currentToolCallId,
|
|
1521
|
-
delta
|
|
1522
|
-
});
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
continue;
|
|
1528
|
-
}
|
|
1529
|
-
if (!insideFence && result.safeContent) {
|
|
1530
|
-
emitTextDelta(result.safeContent);
|
|
1531
|
-
madeProgress = true;
|
|
1532
|
-
}
|
|
1533
|
-
if (!madeProgress) {
|
|
1534
|
-
break;
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
if (toolBlockDetected) {
|
|
1538
|
-
break;
|
|
1539
|
-
}
|
|
1554
|
+
if (done) break;
|
|
1555
|
+
yield value;
|
|
1540
1556
|
}
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
finishStream({ unified: "
|
|
1557
|
+
})();
|
|
1558
|
+
const result = await processToolCallStream(
|
|
1559
|
+
chunks,
|
|
1560
|
+
emitTextDelta,
|
|
1561
|
+
controller,
|
|
1562
|
+
{ stopEarlyOnToolCall: true }
|
|
1563
|
+
);
|
|
1564
|
+
if (result.toolCallDetected && currentReader) {
|
|
1565
|
+
await currentReader.cancel().catch(() => void 0);
|
|
1566
|
+
}
|
|
1567
|
+
currentReader = null;
|
|
1568
|
+
if (aborted) {
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1571
|
+
if (!result.toolCallDetected || result.toolCalls.length === 0) {
|
|
1572
|
+
finishStream({ unified: "stop", raw: "stop" });
|
|
1557
1573
|
return;
|
|
1558
1574
|
}
|
|
1559
|
-
if (
|
|
1560
|
-
|
|
1575
|
+
if (result.trailingText) {
|
|
1576
|
+
emitTextDelta(result.trailingText);
|
|
1561
1577
|
}
|
|
1578
|
+
finishStream({ unified: "tool-calls", raw: "tool-calls" });
|
|
1562
1579
|
} catch (error) {
|
|
1563
1580
|
controller.enqueue({ type: "error", error });
|
|
1564
1581
|
controller.close();
|
|
@@ -1576,7 +1593,7 @@ var BrowserAIChatLanguageModel = class {
|
|
|
1576
1593
|
}
|
|
1577
1594
|
};
|
|
1578
1595
|
|
|
1579
|
-
// src/browser-ai-embedding-model.ts
|
|
1596
|
+
// src/embedding/browser-ai-embedding-model.ts
|
|
1580
1597
|
import { TextEmbedder } from "@mediapipe/tasks-text";
|
|
1581
1598
|
var BrowserAIEmbeddingModel = class {
|
|
1582
1599
|
constructor(settings = {}) {
|