@browser-ai/web-llm 2.1.3 → 2.1.5
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 +283 -261
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +283 -261
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -804,7 +804,267 @@ var ToolCallFenceDetector = class {
|
|
|
804
804
|
}
|
|
805
805
|
};
|
|
806
806
|
|
|
807
|
-
// src/
|
|
807
|
+
// ../shared/src/streaming/tool-call-stream-utils.ts
|
|
808
|
+
function extractToolName(content) {
|
|
809
|
+
const jsonMatch = content.match(/\{\s*"name"\s*:\s*"([^"]+)"/);
|
|
810
|
+
if (jsonMatch) {
|
|
811
|
+
return jsonMatch[1];
|
|
812
|
+
}
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
var ARGUMENTS_FIELD_REGEX = /"arguments"\s*:\s*/g;
|
|
816
|
+
var ARGUMENTS_SEARCH_OVERLAP = 32;
|
|
817
|
+
function createArgumentsStreamState() {
|
|
818
|
+
return {
|
|
819
|
+
searchFrom: 0,
|
|
820
|
+
valueStartIndex: null,
|
|
821
|
+
parseIndex: 0,
|
|
822
|
+
started: false,
|
|
823
|
+
depth: 0,
|
|
824
|
+
inString: false,
|
|
825
|
+
escaped: false,
|
|
826
|
+
complete: false
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
function extractArgumentsDelta(content, state) {
|
|
830
|
+
if (state.complete) {
|
|
831
|
+
return "";
|
|
832
|
+
}
|
|
833
|
+
if (state.valueStartIndex === null) {
|
|
834
|
+
ARGUMENTS_FIELD_REGEX.lastIndex = state.searchFrom;
|
|
835
|
+
const match = ARGUMENTS_FIELD_REGEX.exec(content);
|
|
836
|
+
ARGUMENTS_FIELD_REGEX.lastIndex = 0;
|
|
837
|
+
if (!match || match.index === void 0) {
|
|
838
|
+
state.searchFrom = Math.max(0, content.length - ARGUMENTS_SEARCH_OVERLAP);
|
|
839
|
+
return "";
|
|
840
|
+
}
|
|
841
|
+
state.valueStartIndex = match.index + match[0].length;
|
|
842
|
+
state.parseIndex = state.valueStartIndex;
|
|
843
|
+
state.searchFrom = state.valueStartIndex;
|
|
844
|
+
}
|
|
845
|
+
if (state.parseIndex >= content.length) {
|
|
846
|
+
return "";
|
|
847
|
+
}
|
|
848
|
+
let delta = "";
|
|
849
|
+
for (let i = state.parseIndex; i < content.length; i++) {
|
|
850
|
+
const char = content[i];
|
|
851
|
+
delta += char;
|
|
852
|
+
if (!state.started) {
|
|
853
|
+
if (!/\s/.test(char)) {
|
|
854
|
+
state.started = true;
|
|
855
|
+
if (char === "{" || char === "[") {
|
|
856
|
+
state.depth = 1;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
continue;
|
|
860
|
+
}
|
|
861
|
+
if (state.escaped) {
|
|
862
|
+
state.escaped = false;
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
865
|
+
if (char === "\\") {
|
|
866
|
+
state.escaped = true;
|
|
867
|
+
continue;
|
|
868
|
+
}
|
|
869
|
+
if (char === '"') {
|
|
870
|
+
state.inString = !state.inString;
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
if (!state.inString) {
|
|
874
|
+
if (char === "{" || char === "[") {
|
|
875
|
+
state.depth += 1;
|
|
876
|
+
} else if (char === "}" || char === "]") {
|
|
877
|
+
if (state.depth > 0) {
|
|
878
|
+
state.depth -= 1;
|
|
879
|
+
if (state.depth === 0) {
|
|
880
|
+
state.parseIndex = i + 1;
|
|
881
|
+
state.complete = true;
|
|
882
|
+
return delta;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
state.parseIndex = content.length;
|
|
889
|
+
return delta;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
// ../shared/src/streaming/stream-processor.ts
|
|
893
|
+
function generateToolCallId2() {
|
|
894
|
+
return `call_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
895
|
+
}
|
|
896
|
+
async function processToolCallStream(chunks, emitTextDelta, controller, options) {
|
|
897
|
+
const fenceDetector = new ToolCallFenceDetector();
|
|
898
|
+
let currentToolCallId = null;
|
|
899
|
+
let toolInputStartEmitted = false;
|
|
900
|
+
let accumulatedFenceContent = "";
|
|
901
|
+
let argumentsStreamState = createArgumentsStreamState();
|
|
902
|
+
let insideFence = false;
|
|
903
|
+
let toolCallDetected = false;
|
|
904
|
+
let toolCalls = [];
|
|
905
|
+
let trailingText = "";
|
|
906
|
+
const resetFenceState = () => {
|
|
907
|
+
currentToolCallId = null;
|
|
908
|
+
toolInputStartEmitted = false;
|
|
909
|
+
accumulatedFenceContent = "";
|
|
910
|
+
argumentsStreamState = createArgumentsStreamState();
|
|
911
|
+
insideFence = false;
|
|
912
|
+
};
|
|
913
|
+
for await (const chunk of chunks) {
|
|
914
|
+
if (toolCallDetected) {
|
|
915
|
+
continue;
|
|
916
|
+
}
|
|
917
|
+
fenceDetector.addChunk(chunk);
|
|
918
|
+
while (fenceDetector.hasContent()) {
|
|
919
|
+
const wasInsideFence = insideFence;
|
|
920
|
+
const result = fenceDetector.detectStreamingFence();
|
|
921
|
+
insideFence = result.inFence;
|
|
922
|
+
let madeProgress = false;
|
|
923
|
+
if (!wasInsideFence && result.inFence) {
|
|
924
|
+
if (result.safeContent) {
|
|
925
|
+
emitTextDelta(result.safeContent);
|
|
926
|
+
madeProgress = true;
|
|
927
|
+
}
|
|
928
|
+
currentToolCallId = generateToolCallId2();
|
|
929
|
+
toolInputStartEmitted = false;
|
|
930
|
+
accumulatedFenceContent = "";
|
|
931
|
+
argumentsStreamState = createArgumentsStreamState();
|
|
932
|
+
insideFence = true;
|
|
933
|
+
continue;
|
|
934
|
+
}
|
|
935
|
+
if (result.completeFence) {
|
|
936
|
+
madeProgress = true;
|
|
937
|
+
if (result.safeContent) {
|
|
938
|
+
accumulatedFenceContent += result.safeContent;
|
|
939
|
+
}
|
|
940
|
+
if (toolInputStartEmitted && currentToolCallId) {
|
|
941
|
+
const delta = extractArgumentsDelta(
|
|
942
|
+
accumulatedFenceContent,
|
|
943
|
+
argumentsStreamState
|
|
944
|
+
);
|
|
945
|
+
if (delta.length > 0) {
|
|
946
|
+
controller.enqueue({
|
|
947
|
+
type: "tool-input-delta",
|
|
948
|
+
id: currentToolCallId,
|
|
949
|
+
delta
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
const parsed = parseJsonFunctionCalls(result.completeFence);
|
|
954
|
+
const selectedToolCalls = parsed.toolCalls.slice(0, 1);
|
|
955
|
+
if (selectedToolCalls.length === 0) {
|
|
956
|
+
emitTextDelta(result.completeFence);
|
|
957
|
+
if (result.textAfterFence) {
|
|
958
|
+
emitTextDelta(result.textAfterFence);
|
|
959
|
+
}
|
|
960
|
+
resetFenceState();
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
963
|
+
if (currentToolCallId) {
|
|
964
|
+
selectedToolCalls[0].toolCallId = currentToolCallId;
|
|
965
|
+
}
|
|
966
|
+
for (const [index, call] of selectedToolCalls.entries()) {
|
|
967
|
+
const toolCallId = index === 0 && currentToolCallId ? currentToolCallId : call.toolCallId;
|
|
968
|
+
const toolName = call.toolName;
|
|
969
|
+
const argsJson = JSON.stringify(call.args ?? {});
|
|
970
|
+
if (toolCallId === currentToolCallId) {
|
|
971
|
+
if (!toolInputStartEmitted) {
|
|
972
|
+
controller.enqueue({
|
|
973
|
+
type: "tool-input-start",
|
|
974
|
+
id: toolCallId,
|
|
975
|
+
toolName
|
|
976
|
+
});
|
|
977
|
+
toolInputStartEmitted = true;
|
|
978
|
+
}
|
|
979
|
+
const delta = extractArgumentsDelta(
|
|
980
|
+
accumulatedFenceContent,
|
|
981
|
+
argumentsStreamState
|
|
982
|
+
);
|
|
983
|
+
if (delta.length > 0) {
|
|
984
|
+
controller.enqueue({
|
|
985
|
+
type: "tool-input-delta",
|
|
986
|
+
id: toolCallId,
|
|
987
|
+
delta
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
} else {
|
|
991
|
+
controller.enqueue({
|
|
992
|
+
type: "tool-input-start",
|
|
993
|
+
id: toolCallId,
|
|
994
|
+
toolName
|
|
995
|
+
});
|
|
996
|
+
if (argsJson.length > 0) {
|
|
997
|
+
controller.enqueue({
|
|
998
|
+
type: "tool-input-delta",
|
|
999
|
+
id: toolCallId,
|
|
1000
|
+
delta: argsJson
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
controller.enqueue({ type: "tool-input-end", id: toolCallId });
|
|
1005
|
+
controller.enqueue({
|
|
1006
|
+
type: "tool-call",
|
|
1007
|
+
toolCallId,
|
|
1008
|
+
toolName,
|
|
1009
|
+
input: argsJson,
|
|
1010
|
+
providerExecuted: false
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
trailingText = result.textAfterFence ?? "";
|
|
1014
|
+
toolCalls = selectedToolCalls;
|
|
1015
|
+
toolCallDetected = true;
|
|
1016
|
+
resetFenceState();
|
|
1017
|
+
break;
|
|
1018
|
+
}
|
|
1019
|
+
if (insideFence) {
|
|
1020
|
+
if (result.safeContent) {
|
|
1021
|
+
accumulatedFenceContent += result.safeContent;
|
|
1022
|
+
madeProgress = true;
|
|
1023
|
+
const toolName = extractToolName(accumulatedFenceContent);
|
|
1024
|
+
if (toolName && !toolInputStartEmitted && currentToolCallId) {
|
|
1025
|
+
controller.enqueue({
|
|
1026
|
+
type: "tool-input-start",
|
|
1027
|
+
id: currentToolCallId,
|
|
1028
|
+
toolName
|
|
1029
|
+
});
|
|
1030
|
+
toolInputStartEmitted = true;
|
|
1031
|
+
}
|
|
1032
|
+
if (toolInputStartEmitted && currentToolCallId) {
|
|
1033
|
+
const delta = extractArgumentsDelta(
|
|
1034
|
+
accumulatedFenceContent,
|
|
1035
|
+
argumentsStreamState
|
|
1036
|
+
);
|
|
1037
|
+
if (delta.length > 0) {
|
|
1038
|
+
controller.enqueue({
|
|
1039
|
+
type: "tool-input-delta",
|
|
1040
|
+
id: currentToolCallId,
|
|
1041
|
+
delta
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
continue;
|
|
1047
|
+
}
|
|
1048
|
+
if (!insideFence && result.safeContent) {
|
|
1049
|
+
emitTextDelta(result.safeContent);
|
|
1050
|
+
madeProgress = true;
|
|
1051
|
+
}
|
|
1052
|
+
if (!madeProgress) {
|
|
1053
|
+
break;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
if (toolCallDetected && options?.stopEarlyOnToolCall) {
|
|
1057
|
+
break;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
if (!toolCallDetected && fenceDetector.hasContent()) {
|
|
1061
|
+
emitTextDelta(fenceDetector.getBuffer());
|
|
1062
|
+
fenceDetector.clearBuffer();
|
|
1063
|
+
}
|
|
1064
|
+
return { toolCallDetected, toolCalls, trailingText };
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// src/utils/convert-to-webllm-messages.tsx
|
|
808
1068
|
function convertToolResultOutput(output) {
|
|
809
1069
|
switch (output.type) {
|
|
810
1070
|
case "text":
|
|
@@ -943,7 +1203,7 @@ function convertToWebLLMMessages(prompt) {
|
|
|
943
1203
|
return messages;
|
|
944
1204
|
}
|
|
945
1205
|
|
|
946
|
-
// src/web-llm-language-model.ts
|
|
1206
|
+
// src/chat/web-llm-language-model.ts
|
|
947
1207
|
var import_web_llm = require("@mlc-ai/web-llm");
|
|
948
1208
|
|
|
949
1209
|
// src/utils/prompt-utils.ts
|
|
@@ -1003,64 +1263,7 @@ function doesBrowserSupportWebLLM() {
|
|
|
1003
1263
|
return checkWebGPU();
|
|
1004
1264
|
}
|
|
1005
1265
|
|
|
1006
|
-
// src/web-llm-language-model.ts
|
|
1007
|
-
function extractToolName(content) {
|
|
1008
|
-
const jsonMatch = content.match(/\{\s*"name"\s*:\s*"([^"]+)"/);
|
|
1009
|
-
if (jsonMatch) {
|
|
1010
|
-
return jsonMatch[1];
|
|
1011
|
-
}
|
|
1012
|
-
return null;
|
|
1013
|
-
}
|
|
1014
|
-
function extractArgumentsContent(content) {
|
|
1015
|
-
const match = content.match(/"arguments"\s*:\s*/);
|
|
1016
|
-
if (!match || match.index === void 0) {
|
|
1017
|
-
return "";
|
|
1018
|
-
}
|
|
1019
|
-
const startIndex = match.index + match[0].length;
|
|
1020
|
-
let result = "";
|
|
1021
|
-
let depth = 0;
|
|
1022
|
-
let inString = false;
|
|
1023
|
-
let escaped = false;
|
|
1024
|
-
let started = false;
|
|
1025
|
-
for (let i = startIndex; i < content.length; i++) {
|
|
1026
|
-
const char = content[i];
|
|
1027
|
-
result += char;
|
|
1028
|
-
if (!started) {
|
|
1029
|
-
if (!/\s/.test(char)) {
|
|
1030
|
-
started = true;
|
|
1031
|
-
if (char === "{" || char === "[") {
|
|
1032
|
-
depth = 1;
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
continue;
|
|
1036
|
-
}
|
|
1037
|
-
if (escaped) {
|
|
1038
|
-
escaped = false;
|
|
1039
|
-
continue;
|
|
1040
|
-
}
|
|
1041
|
-
if (char === "\\") {
|
|
1042
|
-
escaped = true;
|
|
1043
|
-
continue;
|
|
1044
|
-
}
|
|
1045
|
-
if (char === '"') {
|
|
1046
|
-
inString = !inString;
|
|
1047
|
-
continue;
|
|
1048
|
-
}
|
|
1049
|
-
if (!inString) {
|
|
1050
|
-
if (char === "{" || char === "[") {
|
|
1051
|
-
depth += 1;
|
|
1052
|
-
} else if (char === "}" || char === "]") {
|
|
1053
|
-
if (depth > 0) {
|
|
1054
|
-
depth -= 1;
|
|
1055
|
-
if (depth === 0) {
|
|
1056
|
-
break;
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
return result;
|
|
1063
|
-
}
|
|
1266
|
+
// src/chat/web-llm-language-model.ts
|
|
1064
1267
|
var WebLLMLanguageModel = class {
|
|
1065
1268
|
constructor(modelId, options = {}) {
|
|
1066
1269
|
this.specificationVersion = "v3";
|
|
@@ -1504,208 +1707,27 @@ var WebLLMLanguageModel = class {
|
|
|
1504
1707
|
...options.abortSignal && !useWorker && { signal: options.abortSignal }
|
|
1505
1708
|
};
|
|
1506
1709
|
const response = await engine.chat.completions.create(streamingRequest);
|
|
1507
|
-
|
|
1508
|
-
let
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
if (!choice) continue;
|
|
1517
|
-
if (choice.delta.content) {
|
|
1518
|
-
const delta = choice.delta.content;
|
|
1519
|
-
accumulatedText += delta;
|
|
1520
|
-
fenceDetector.addChunk(delta);
|
|
1521
|
-
while (fenceDetector.hasContent()) {
|
|
1522
|
-
const wasInsideFence = insideFence;
|
|
1523
|
-
const result = fenceDetector.detectStreamingFence();
|
|
1524
|
-
insideFence = result.inFence;
|
|
1525
|
-
let madeProgress = false;
|
|
1526
|
-
if (!wasInsideFence && result.inFence) {
|
|
1527
|
-
if (result.safeContent) {
|
|
1528
|
-
emitTextDelta(result.safeContent);
|
|
1529
|
-
madeProgress = true;
|
|
1530
|
-
}
|
|
1531
|
-
currentToolCallId = `call_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
1532
|
-
toolInputStartEmitted = false;
|
|
1533
|
-
accumulatedFenceContent = "";
|
|
1534
|
-
streamedArgumentsLength = 0;
|
|
1535
|
-
insideFence = true;
|
|
1536
|
-
continue;
|
|
1537
|
-
}
|
|
1538
|
-
if (result.completeFence) {
|
|
1539
|
-
madeProgress = true;
|
|
1540
|
-
if (result.safeContent) {
|
|
1541
|
-
accumulatedFenceContent += result.safeContent;
|
|
1542
|
-
}
|
|
1543
|
-
if (toolInputStartEmitted && currentToolCallId) {
|
|
1544
|
-
const argsContent = extractArgumentsContent(
|
|
1545
|
-
accumulatedFenceContent
|
|
1546
|
-
);
|
|
1547
|
-
if (argsContent.length > streamedArgumentsLength) {
|
|
1548
|
-
const delta2 = argsContent.slice(streamedArgumentsLength);
|
|
1549
|
-
streamedArgumentsLength = argsContent.length;
|
|
1550
|
-
if (delta2.length > 0) {
|
|
1551
|
-
controller.enqueue({
|
|
1552
|
-
type: "tool-input-delta",
|
|
1553
|
-
id: currentToolCallId,
|
|
1554
|
-
delta: delta2
|
|
1555
|
-
});
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
const parsed = parseJsonFunctionCalls(result.completeFence);
|
|
1560
|
-
const parsedToolCalls = parsed.toolCalls;
|
|
1561
|
-
const selectedToolCalls = parsedToolCalls.slice(0, 1);
|
|
1562
|
-
if (selectedToolCalls.length === 0) {
|
|
1563
|
-
emitTextDelta(result.completeFence);
|
|
1564
|
-
if (result.textAfterFence) {
|
|
1565
|
-
emitTextDelta(result.textAfterFence);
|
|
1566
|
-
}
|
|
1567
|
-
currentToolCallId = null;
|
|
1568
|
-
toolInputStartEmitted = false;
|
|
1569
|
-
accumulatedFenceContent = "";
|
|
1570
|
-
streamedArgumentsLength = 0;
|
|
1571
|
-
insideFence = false;
|
|
1572
|
-
continue;
|
|
1573
|
-
}
|
|
1574
|
-
if (selectedToolCalls.length > 0 && currentToolCallId) {
|
|
1575
|
-
selectedToolCalls[0].toolCallId = currentToolCallId;
|
|
1576
|
-
}
|
|
1577
|
-
for (const [index, call] of selectedToolCalls.entries()) {
|
|
1578
|
-
const toolCallId = index === 0 && currentToolCallId ? currentToolCallId : call.toolCallId;
|
|
1579
|
-
const toolName = call.toolName;
|
|
1580
|
-
const argsJson = JSON.stringify(call.args ?? {});
|
|
1581
|
-
if (toolCallId === currentToolCallId) {
|
|
1582
|
-
if (!toolInputStartEmitted) {
|
|
1583
|
-
controller.enqueue({
|
|
1584
|
-
type: "tool-input-start",
|
|
1585
|
-
id: toolCallId,
|
|
1586
|
-
toolName
|
|
1587
|
-
});
|
|
1588
|
-
toolInputStartEmitted = true;
|
|
1589
|
-
}
|
|
1590
|
-
const argsContent = extractArgumentsContent(
|
|
1591
|
-
accumulatedFenceContent
|
|
1592
|
-
);
|
|
1593
|
-
if (argsContent.length > streamedArgumentsLength) {
|
|
1594
|
-
const delta2 = argsContent.slice(
|
|
1595
|
-
streamedArgumentsLength
|
|
1596
|
-
);
|
|
1597
|
-
streamedArgumentsLength = argsContent.length;
|
|
1598
|
-
if (delta2.length > 0) {
|
|
1599
|
-
controller.enqueue({
|
|
1600
|
-
type: "tool-input-delta",
|
|
1601
|
-
id: toolCallId,
|
|
1602
|
-
delta: delta2
|
|
1603
|
-
});
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
} else {
|
|
1607
|
-
controller.enqueue({
|
|
1608
|
-
type: "tool-input-start",
|
|
1609
|
-
id: toolCallId,
|
|
1610
|
-
toolName
|
|
1611
|
-
});
|
|
1612
|
-
if (argsJson.length > 0) {
|
|
1613
|
-
controller.enqueue({
|
|
1614
|
-
type: "tool-input-delta",
|
|
1615
|
-
id: toolCallId,
|
|
1616
|
-
delta: argsJson
|
|
1617
|
-
});
|
|
1618
|
-
}
|
|
1619
|
-
}
|
|
1620
|
-
controller.enqueue({
|
|
1621
|
-
type: "tool-input-end",
|
|
1622
|
-
id: toolCallId
|
|
1623
|
-
});
|
|
1624
|
-
controller.enqueue({
|
|
1625
|
-
type: "tool-call",
|
|
1626
|
-
toolCallId,
|
|
1627
|
-
toolName,
|
|
1628
|
-
input: argsJson,
|
|
1629
|
-
providerExecuted: false
|
|
1630
|
-
});
|
|
1631
|
-
}
|
|
1632
|
-
if (result.textAfterFence) {
|
|
1633
|
-
emitTextDelta(result.textAfterFence);
|
|
1634
|
-
}
|
|
1635
|
-
madeProgress = true;
|
|
1636
|
-
currentToolCallId = null;
|
|
1637
|
-
toolInputStartEmitted = false;
|
|
1638
|
-
accumulatedFenceContent = "";
|
|
1639
|
-
streamedArgumentsLength = 0;
|
|
1640
|
-
insideFence = false;
|
|
1641
|
-
continue;
|
|
1642
|
-
}
|
|
1643
|
-
if (insideFence) {
|
|
1644
|
-
if (result.safeContent) {
|
|
1645
|
-
accumulatedFenceContent += result.safeContent;
|
|
1646
|
-
madeProgress = true;
|
|
1647
|
-
const toolName = extractToolName(accumulatedFenceContent);
|
|
1648
|
-
if (toolName && !toolInputStartEmitted && currentToolCallId) {
|
|
1649
|
-
controller.enqueue({
|
|
1650
|
-
type: "tool-input-start",
|
|
1651
|
-
id: currentToolCallId,
|
|
1652
|
-
toolName
|
|
1653
|
-
});
|
|
1654
|
-
toolInputStartEmitted = true;
|
|
1655
|
-
}
|
|
1656
|
-
if (toolInputStartEmitted && currentToolCallId) {
|
|
1657
|
-
const argsContent = extractArgumentsContent(
|
|
1658
|
-
accumulatedFenceContent
|
|
1659
|
-
);
|
|
1660
|
-
if (argsContent.length > streamedArgumentsLength) {
|
|
1661
|
-
const delta2 = argsContent.slice(
|
|
1662
|
-
streamedArgumentsLength
|
|
1663
|
-
);
|
|
1664
|
-
streamedArgumentsLength = argsContent.length;
|
|
1665
|
-
if (delta2.length > 0) {
|
|
1666
|
-
controller.enqueue({
|
|
1667
|
-
type: "tool-input-delta",
|
|
1668
|
-
id: currentToolCallId,
|
|
1669
|
-
delta: delta2
|
|
1670
|
-
});
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
continue;
|
|
1676
|
-
}
|
|
1677
|
-
if (!insideFence && result.safeContent) {
|
|
1678
|
-
emitTextDelta(result.safeContent);
|
|
1679
|
-
madeProgress = true;
|
|
1680
|
-
}
|
|
1681
|
-
if (!madeProgress) {
|
|
1682
|
-
break;
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
if (choice.finish_reason) {
|
|
1687
|
-
if (fenceDetector.hasContent()) {
|
|
1688
|
-
emitTextDelta(fenceDetector.getBuffer());
|
|
1689
|
-
fenceDetector.clearBuffer();
|
|
1690
|
-
}
|
|
1691
|
-
let finishReason = {
|
|
1692
|
-
unified: "stop",
|
|
1693
|
-
raw: "stop"
|
|
1694
|
-
};
|
|
1695
|
-
if (choice.finish_reason === "abort") {
|
|
1696
|
-
finishReason = { unified: "other", raw: "abort" };
|
|
1697
|
-
} else {
|
|
1698
|
-
const { toolCalls } = parseJsonFunctionCalls(accumulatedText);
|
|
1699
|
-
if (toolCalls.length > 0) {
|
|
1700
|
-
finishReason = { unified: "tool-calls", raw: "tool-calls" };
|
|
1701
|
-
}
|
|
1702
|
-
}
|
|
1703
|
-
finishStream(finishReason, chunk.usage);
|
|
1710
|
+
let lastUsage;
|
|
1711
|
+
let isAbort = false;
|
|
1712
|
+
const chunks = (async function* () {
|
|
1713
|
+
for await (const chunk of response) {
|
|
1714
|
+
const choice = chunk.choices[0];
|
|
1715
|
+
if (!choice) continue;
|
|
1716
|
+
if (choice.delta.content) yield choice.delta.content;
|
|
1717
|
+
if (chunk.usage) lastUsage = chunk.usage;
|
|
1718
|
+
if (choice.finish_reason === "abort") isAbort = true;
|
|
1704
1719
|
}
|
|
1720
|
+
})();
|
|
1721
|
+
const result = await processToolCallStream(
|
|
1722
|
+
chunks,
|
|
1723
|
+
emitTextDelta,
|
|
1724
|
+
controller
|
|
1725
|
+
);
|
|
1726
|
+
if (result.trailingText) {
|
|
1727
|
+
emitTextDelta(result.trailingText);
|
|
1705
1728
|
}
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
}
|
|
1729
|
+
const finishReason = isAbort ? { unified: "other", raw: "abort" } : result.toolCallDetected ? { unified: "tool-calls", raw: "tool-calls" } : { unified: "stop", raw: "stop" };
|
|
1730
|
+
finishStream(finishReason, lastUsage);
|
|
1709
1731
|
} catch (error) {
|
|
1710
1732
|
controller.error(error);
|
|
1711
1733
|
} finally {
|
|
@@ -1725,7 +1747,7 @@ var WebLLMLanguageModel = class {
|
|
|
1725
1747
|
}
|
|
1726
1748
|
};
|
|
1727
1749
|
|
|
1728
|
-
// src/web-llm-embedding-model.ts
|
|
1750
|
+
// src/embedding/web-llm-embedding-model.ts
|
|
1729
1751
|
var import_web_llm2 = require("@mlc-ai/web-llm");
|
|
1730
1752
|
var WebLLMEmbeddingModel = class {
|
|
1731
1753
|
constructor(modelId, options = {}) {
|