fluxflow-cli 3.2.4 → 3.2.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/fluxflow.js +373 -133
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -326,7 +326,8 @@ var init_settings = __esm({
|
|
|
326
326
|
useExternalData: false,
|
|
327
327
|
externalDataPath: "",
|
|
328
328
|
preserveThinking: true,
|
|
329
|
-
loadingPhrases: true
|
|
329
|
+
loadingPhrases: true,
|
|
330
|
+
progressiveRendering: false
|
|
330
331
|
},
|
|
331
332
|
profileData: {
|
|
332
333
|
name: null,
|
|
@@ -2544,7 +2545,7 @@ var init_text = __esm({
|
|
|
2544
2545
|
};
|
|
2545
2546
|
parseMessageToBlocks = (msg, columns) => {
|
|
2546
2547
|
if (!msg) return { completed: [], active: [] };
|
|
2547
|
-
const cacheKey = `${msg.id}-${msg.text?.length || 0}-${columns}-${msg.isStreaming}`;
|
|
2548
|
+
const cacheKey = `${msg.id}-${msg.text?.length || 0}-${columns}-${msg.isStreaming}-${msg.workedDuration || 0}-${msg.memoryUpdated ? 1 : 0}-${msg.color || ""}`;
|
|
2548
2549
|
if (!msg.isStreaming && blocksCache.has(cacheKey)) {
|
|
2549
2550
|
return blocksCache.get(cacheKey);
|
|
2550
2551
|
}
|
|
@@ -4002,7 +4003,7 @@ ${coloredArt[7]}`;
|
|
|
4002
4003
|
import React4, { useState as useState4, useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
4003
4004
|
import { Box as Box3, Text as Text4 } from "ink";
|
|
4004
4005
|
import { diffWordsWithSpace } from "diff";
|
|
4005
|
-
var useStreamingText, formatThinkText, REGEX_MD_TOKENS, REGEX_LATEX_FRAC, REGEX_LATEX_STYLE, parseMathSymbols, SYNTAX_KEYWORDS, SYNTAX_RULES,
|
|
4006
|
+
var useStreamingText, formatThinkText, REGEX_MD_TOKENS, REGEX_LATEX_FRAC, REGEX_LATEX_STYLE, parseMathSymbols, SYNTAX_KEYWORDS, SYNTAX_RULES, tokenCache, MAX_TOKEN_CACHE_SIZE, tokenizeLine, renderHighlightedLine, renderLatexText, InlineMarkdown, TableRenderer, MarkdownText, DiffLine, DiffBlock, CodeRenderer, formatThinkingDuration, MessageItem, BlockItem, ChatLayout;
|
|
4006
4007
|
var init_ChatLayout = __esm({
|
|
4007
4008
|
"src/components/ChatLayout.jsx"() {
|
|
4008
4009
|
init_TerminalBox();
|
|
@@ -4058,7 +4059,6 @@ var init_ChatLayout = __esm({
|
|
|
4058
4059
|
/\b(true|false|null|undefined|nil|None)\b/.source,
|
|
4059
4060
|
/\b(\d+(?:\.\d+)?|0x[0-9a-fA-F]+)\b/.source
|
|
4060
4061
|
];
|
|
4061
|
-
REGEX_SYNTAX = new RegExp(SYNTAX_RULES.join("|"), "g");
|
|
4062
4062
|
tokenCache = /* @__PURE__ */ new Map();
|
|
4063
4063
|
MAX_TOKEN_CACHE_SIZE = 1e3;
|
|
4064
4064
|
tokenizeLine = (line, lang) => {
|
|
@@ -4070,8 +4070,8 @@ var init_ChatLayout = __esm({
|
|
|
4070
4070
|
let lastIndex = 0;
|
|
4071
4071
|
const tokens = [];
|
|
4072
4072
|
let match;
|
|
4073
|
-
|
|
4074
|
-
while ((match =
|
|
4073
|
+
const localRegex = new RegExp(SYNTAX_RULES.join("|"), "g");
|
|
4074
|
+
while ((match = localRegex.exec(line)) !== null) {
|
|
4075
4075
|
const matchText = match[0];
|
|
4076
4076
|
const matchIndex = match.index;
|
|
4077
4077
|
if (matchIndex > lastIndex) {
|
|
@@ -4094,7 +4094,7 @@ var init_ChatLayout = __esm({
|
|
|
4094
4094
|
color = "#ff9e64";
|
|
4095
4095
|
}
|
|
4096
4096
|
tokens.push({ text: matchText, color, bold });
|
|
4097
|
-
lastIndex =
|
|
4097
|
+
lastIndex = localRegex.lastIndex;
|
|
4098
4098
|
}
|
|
4099
4099
|
if (lastIndex < line.length) {
|
|
4100
4100
|
tokens.push({ text: line.substring(lastIndex) });
|
|
@@ -5966,6 +5966,7 @@ function SettingsMenu({
|
|
|
5966
5966
|
{ label: "Key Strategy", value: "apiTier", status: apiTier === "Free" ? "Free" : quotas?.providerBudgets?.__useProvider ? "Paid" : "Paid" },
|
|
5967
5967
|
{ label: "Preserve Thinking", value: "preserveThinking", status: systemSettings.preserveThinking !== false ? "ON" : "OFF" },
|
|
5968
5968
|
{ label: "Loading Phrases", value: "loadingPhrases", status: systemSettings.loadingPhrases !== false ? "ON" : "OFF" },
|
|
5969
|
+
{ label: "Progressive Rendering [EXPERIMENTAL]", value: "progressiveRendering", status: systemSettings.progressiveRendering ? "ON" : "OFF" },
|
|
5969
5970
|
{ label: "Download Language Parsers", value: "parserDownload", status: "ACTION" }
|
|
5970
5971
|
];
|
|
5971
5972
|
default:
|
|
@@ -6134,6 +6135,12 @@ function SettingsMenu({
|
|
|
6134
6135
|
saveSettings2({ systemSettings: newSysSettings, apiTier, quotas });
|
|
6135
6136
|
return newSysSettings;
|
|
6136
6137
|
});
|
|
6138
|
+
} else if (item.value === "progressiveRendering") {
|
|
6139
|
+
setSystemSettings((s) => {
|
|
6140
|
+
const newSysSettings = { ...s, progressiveRendering: !s.progressiveRendering };
|
|
6141
|
+
saveSettings2({ systemSettings: newSysSettings, apiTier, quotas });
|
|
6142
|
+
return newSysSettings;
|
|
6143
|
+
});
|
|
6137
6144
|
}
|
|
6138
6145
|
};
|
|
6139
6146
|
return /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "white", padding: 0, width: "100%", minHeight: 32 }, /* @__PURE__ */ React7.createElement(Box6, { paddingX: 1, paddingY: 0, marginBottom: 0, borderStyle: "single", borderColor: "gray", width: "100%" }, /* @__PURE__ */ React7.createElement(Text7, { color: "white", bold: true }, "SYSTEM CONFIGURATION")), /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "row", width: "100%", minHeight: 26 }, /* @__PURE__ */ React7.createElement(Box6, { flexDirection: "column", width: "30%", borderStyle: "round", borderColor: activeColumn === "categories" ? "white" : "grey", padding: 1, paddingY: 0 }, /* @__PURE__ */ React7.createElement(Box6, { marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: activeColumn === "categories" ? "white" : "grey", bold: true, underline: true }, "CATEGORIES")), CATEGORIES.map((cat, index) => {
|
|
@@ -6170,7 +6177,7 @@ function SettingsMenu({
|
|
|
6170
6177
|
currentItems.forEach((item, index) => {
|
|
6171
6178
|
const isSelected = activeColumn === "items" && selectedItemIndex === index;
|
|
6172
6179
|
const labelLength = item.label.length;
|
|
6173
|
-
const dotsCount = Math.max(2,
|
|
6180
|
+
const dotsCount = Math.max(2, 38 - labelLength);
|
|
6174
6181
|
const dots = ".".repeat(dotsCount);
|
|
6175
6182
|
const getStatusColor = (item2) => {
|
|
6176
6183
|
if (currentCatId === "security") {
|
|
@@ -6218,7 +6225,7 @@ function SettingsMenu({
|
|
|
6218
6225
|
});
|
|
6219
6226
|
if (currentCatId === "other") {
|
|
6220
6227
|
elements.push(
|
|
6221
|
-
/* @__PURE__ */ React7.createElement(Box6, { key: "pty-notice", marginTop:
|
|
6228
|
+
/* @__PURE__ */ React7.createElement(Box6, { key: "pty-notice", marginTop: 14, paddingX: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "white" }, isPtyAvailable ? "\u2713 Advance Interactive Terminal Supported" : "\u26A0 Interactive Terminal is Limited"))
|
|
6222
6229
|
);
|
|
6223
6230
|
elements.push(
|
|
6224
6231
|
/* @__PURE__ */ React7.createElement(Box6, { key: "memory-load-2026", paddingX: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray" }, "Memory Load: ", currentMemory, "/", maxMemory, " ", memoryUnit))
|
|
@@ -16473,8 +16480,8 @@ function App({ args = [] }) {
|
|
|
16473
16480
|
defaultModel = "deepseek-v4-flash";
|
|
16474
16481
|
modelDisplayName = "DeepSeek Flash (Free default)";
|
|
16475
16482
|
} else if (aiProvider === "NVIDIA") {
|
|
16476
|
-
defaultModel = "
|
|
16477
|
-
modelDisplayName = "
|
|
16483
|
+
defaultModel = "stepfun-ai/step-3.7-flash";
|
|
16484
|
+
modelDisplayName = "Step 3.7 Flash (NVIDIA)";
|
|
16478
16485
|
} else {
|
|
16479
16486
|
defaultModel = "google/gemma-4-31b-it:free";
|
|
16480
16487
|
modelDisplayName = "Gemma 4 (Free default)";
|
|
@@ -16487,8 +16494,8 @@ function App({ args = [] }) {
|
|
|
16487
16494
|
defaultModel = "deepseek-v4-flash";
|
|
16488
16495
|
modelDisplayName = "DeepSeek Flash";
|
|
16489
16496
|
} else if (aiProvider === "NVIDIA") {
|
|
16490
|
-
defaultModel = "
|
|
16491
|
-
modelDisplayName = "
|
|
16497
|
+
defaultModel = "stepfun-ai/step-3.7-flash";
|
|
16498
|
+
modelDisplayName = "Step 3.7 Flash (NVIDIA)";
|
|
16492
16499
|
} else {
|
|
16493
16500
|
defaultModel = "deepseek/deepseek-v4-flash";
|
|
16494
16501
|
modelDisplayName = "DeepSeek Flash";
|
|
@@ -16549,7 +16556,7 @@ function App({ args = [] }) {
|
|
|
16549
16556
|
const [wittyPhrase, setWittyPhrase] = useState15("");
|
|
16550
16557
|
const [hasPasteBlock, setHasPasteBlock] = useState15(false);
|
|
16551
16558
|
const [activeTime, setActiveTime] = useState15(0);
|
|
16552
|
-
|
|
16559
|
+
const activeTimeIntervalRef = useRef4(null);
|
|
16553
16560
|
useEffect12(() => {
|
|
16554
16561
|
let interval;
|
|
16555
16562
|
if (statusText && systemSettings.loadingPhrases !== false) {
|
|
@@ -16660,6 +16667,11 @@ function App({ args = [] }) {
|
|
|
16660
16667
|
}, [messages]);
|
|
16661
16668
|
const [completedIndex, setCompletedIndex] = useState15(messages.length);
|
|
16662
16669
|
const [clearKey, setClearKey] = useState15(0);
|
|
16670
|
+
const [activeStreamMessages, setActiveStreamMessages] = useState15([]);
|
|
16671
|
+
const activeStreamMessagesRef = useRef4([]);
|
|
16672
|
+
const typewriterQueueRef = useRef4([]);
|
|
16673
|
+
const typewriterIntervalRef = useRef4(null);
|
|
16674
|
+
const streamFinishedRef = useRef4(false);
|
|
16663
16675
|
const lastCompletedBlocksRef = useRef4([]);
|
|
16664
16676
|
const cachedHistoryRef = useRef4({
|
|
16665
16677
|
completedIndex: 0,
|
|
@@ -16733,7 +16745,7 @@ function App({ args = [] }) {
|
|
|
16733
16745
|
};
|
|
16734
16746
|
}
|
|
16735
16747
|
}
|
|
16736
|
-
const activeMsgs =
|
|
16748
|
+
const activeMsgs = activeStreamMessages;
|
|
16737
16749
|
const streamingCompletedBlocks = [];
|
|
16738
16750
|
const activeBlocks = [];
|
|
16739
16751
|
for (let i = 0; i < activeMsgs.length; i++) {
|
|
@@ -16749,7 +16761,15 @@ function App({ args = [] }) {
|
|
|
16749
16761
|
for (let j = 0; j < parsed.completed.length; j++) streamingCompletedBlocks.push(parsed.completed[j]);
|
|
16750
16762
|
for (let j = 0; j < parsed.active.length; j++) activeBlocks.push(parsed.active[j]);
|
|
16751
16763
|
}
|
|
16752
|
-
const finalCompleted =
|
|
16764
|
+
const finalCompleted = historicalBlocks.map((block) => {
|
|
16765
|
+
if (block.type === "full-message" && block.msg) {
|
|
16766
|
+
const latestMsg = messages.find((m) => m.id === block.msg.id);
|
|
16767
|
+
if (latestMsg && latestMsg !== block.msg) {
|
|
16768
|
+
return { ...block, msg: latestMsg };
|
|
16769
|
+
}
|
|
16770
|
+
}
|
|
16771
|
+
return block;
|
|
16772
|
+
});
|
|
16753
16773
|
for (let j = 0; j < streamingCompletedBlocks.length; j++) {
|
|
16754
16774
|
finalCompleted.push(streamingCompletedBlocks[j]);
|
|
16755
16775
|
}
|
|
@@ -16769,7 +16789,7 @@ function App({ args = [] }) {
|
|
|
16769
16789
|
completed: finalCompleted,
|
|
16770
16790
|
active: activeBlocks
|
|
16771
16791
|
};
|
|
16772
|
-
}, [messages, completedIndex, terminalSize.columns, clearKey, chatId]);
|
|
16792
|
+
}, [messages, activeStreamMessages, completedIndex, terminalSize.columns, clearKey, chatId]);
|
|
16773
16793
|
const isTerminalWaitingForInput = useMemo2(() => {
|
|
16774
16794
|
if (!activeCommand || !execOutput) return false;
|
|
16775
16795
|
const lastChunk = execOutput.trim();
|
|
@@ -17067,7 +17087,7 @@ function App({ args = [] }) {
|
|
|
17067
17087
|
} else if (startupProvider === "OpenRouter") {
|
|
17068
17088
|
defaultModel = "google/gemma-4-31b-it:free";
|
|
17069
17089
|
} else if (startupProvider === "NVIDIA") {
|
|
17070
|
-
defaultModel = "
|
|
17090
|
+
defaultModel = "stepfun-ai/step-3.7-flash";
|
|
17071
17091
|
}
|
|
17072
17092
|
} else {
|
|
17073
17093
|
if (startupProvider === "Google") {
|
|
@@ -17077,7 +17097,7 @@ function App({ args = [] }) {
|
|
|
17077
17097
|
} else if (startupProvider === "OpenRouter") {
|
|
17078
17098
|
defaultModel = "deepseek/deepseek-v4-flash";
|
|
17079
17099
|
} else if (startupProvider === "NVIDIA") {
|
|
17080
|
-
defaultModel = "
|
|
17100
|
+
defaultModel = "stepfun-ai/step-3.7-flash";
|
|
17081
17101
|
}
|
|
17082
17102
|
}
|
|
17083
17103
|
setActiveModel(defaultModel);
|
|
@@ -17294,7 +17314,7 @@ function App({ args = [] }) {
|
|
|
17294
17314
|
} else if (aiProvider === "DeepSeek") {
|
|
17295
17315
|
defaultModel = "deepseek-v4-flash";
|
|
17296
17316
|
} else if (aiProvider === "NVIDIA") {
|
|
17297
|
-
defaultModel = "
|
|
17317
|
+
defaultModel = "stepfun-ai/step-3.7-flash";
|
|
17298
17318
|
}
|
|
17299
17319
|
setActiveModel(defaultModel);
|
|
17300
17320
|
setMessages((prev) => [...prev, { role: "system", text: `${aiProvider} API Key saved successfully! Model set to ${defaultModel}. Initialization complete.`, isMeta: true }]);
|
|
@@ -17853,7 +17873,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
17853
17873
|
setTimeout(() => {
|
|
17854
17874
|
if (global.gc) {
|
|
17855
17875
|
const gCAsync = async () => {
|
|
17856
|
-
for (let i = 0; i <
|
|
17876
|
+
for (let i = 0; i < 3; i++) {
|
|
17857
17877
|
global.gc();
|
|
17858
17878
|
await new Promise((resolve) => setImmediate(resolve));
|
|
17859
17879
|
}
|
|
@@ -17880,7 +17900,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
17880
17900
|
setTimeout(() => {
|
|
17881
17901
|
if (global.gc) {
|
|
17882
17902
|
const gCAsync = async () => {
|
|
17883
|
-
for (let i = 0; i <
|
|
17903
|
+
for (let i = 0; i < 3; i++) {
|
|
17884
17904
|
global.gc();
|
|
17885
17905
|
await new Promise((resolve) => setImmediate(resolve));
|
|
17886
17906
|
}
|
|
@@ -18503,12 +18523,24 @@ ${timestamp}` };
|
|
|
18503
18523
|
const appendCancelMessage = () => {
|
|
18504
18524
|
if (didAppendCancel) return;
|
|
18505
18525
|
didAppendCancel = true;
|
|
18526
|
+
const dangling = activeStreamMessagesRef.current;
|
|
18527
|
+
activeStreamMessagesRef.current = [];
|
|
18528
|
+
setActiveStreamMessages([]);
|
|
18529
|
+
if (typewriterIntervalRef.current) {
|
|
18530
|
+
clearInterval(typewriterIntervalRef.current);
|
|
18531
|
+
typewriterIntervalRef.current = null;
|
|
18532
|
+
}
|
|
18533
|
+
typewriterQueueRef.current = [];
|
|
18506
18534
|
setMessages((prev) => {
|
|
18507
18535
|
const lastMsg = prev[prev.length - 1];
|
|
18508
18536
|
if (lastMsg && lastMsg.text && lastMsg.text.includes("Request Cancelled")) {
|
|
18509
18537
|
return prev;
|
|
18510
18538
|
}
|
|
18511
|
-
const
|
|
18539
|
+
const flushed = dangling.map((m) => {
|
|
18540
|
+
const flatText = m.text ? (" " + m.text).slice(1) : m.text;
|
|
18541
|
+
return { ...m, isStreaming: false, text: flatText };
|
|
18542
|
+
});
|
|
18543
|
+
const updatedPrev = [...prev, ...flushed].map((m) => m.isStreaming ? { ...m, isStreaming: false } : m);
|
|
18512
18544
|
const newMsgs = [...updatedPrev, {
|
|
18513
18545
|
id: "cancel-" + Date.now(),
|
|
18514
18546
|
role: "system",
|
|
@@ -18519,6 +18551,159 @@ ${timestamp}` };
|
|
|
18519
18551
|
return newMsgs;
|
|
18520
18552
|
});
|
|
18521
18553
|
};
|
|
18554
|
+
const finalizeTurn = async (apiStartVal) => {
|
|
18555
|
+
const dangling = activeStreamMessagesRef.current;
|
|
18556
|
+
if (dangling.length > 0) {
|
|
18557
|
+
activeStreamMessagesRef.current = [];
|
|
18558
|
+
setActiveStreamMessages([]);
|
|
18559
|
+
setMessages((prev) => {
|
|
18560
|
+
const totalDuration = Date.now() - apiStartVal;
|
|
18561
|
+
const flushed = dangling.map((m) => {
|
|
18562
|
+
const flatText = m.text ? (" " + m.text).slice(1) : m.text;
|
|
18563
|
+
return {
|
|
18564
|
+
...m,
|
|
18565
|
+
isStreaming: false,
|
|
18566
|
+
text: flatText,
|
|
18567
|
+
workedDuration: m.role === "agent" ? totalDuration : m.workedDuration
|
|
18568
|
+
};
|
|
18569
|
+
});
|
|
18570
|
+
const newMsgs = [...prev, ...flushed];
|
|
18571
|
+
setCompletedIndex(newMsgs.length);
|
|
18572
|
+
return newMsgs;
|
|
18573
|
+
});
|
|
18574
|
+
}
|
|
18575
|
+
setIsProcessing(false);
|
|
18576
|
+
setStatusText(null);
|
|
18577
|
+
setActiveTime(0);
|
|
18578
|
+
clearInterval(activeTimeIntervalRef.current);
|
|
18579
|
+
if (didSignalTerminationRef.current) {
|
|
18580
|
+
appendCancelMessage();
|
|
18581
|
+
}
|
|
18582
|
+
clearBlocksCache();
|
|
18583
|
+
if (global.gc) {
|
|
18584
|
+
try {
|
|
18585
|
+
for (let i = 0; i < 3; i++) {
|
|
18586
|
+
global.gc();
|
|
18587
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
18588
|
+
}
|
|
18589
|
+
lastGCTime = Date.now();
|
|
18590
|
+
} catch (e) {
|
|
18591
|
+
}
|
|
18592
|
+
}
|
|
18593
|
+
if (!hasFiredJanitor) {
|
|
18594
|
+
if (process.stdout.isTTY) {
|
|
18595
|
+
process.stdout.write("\x1B]0;FluxFlow | Idle\x07");
|
|
18596
|
+
process.stdout.write("\x1B]633;P;TerminalTitle=FluxFlow | Idle\x07");
|
|
18597
|
+
}
|
|
18598
|
+
}
|
|
18599
|
+
if (queuedPromptRef.current) {
|
|
18600
|
+
setResolutionData(queuedPromptRef.current);
|
|
18601
|
+
setQueuedPrompt(null);
|
|
18602
|
+
const hintToResolve = queuedPromptRef.current;
|
|
18603
|
+
queuedPromptRef.current = null;
|
|
18604
|
+
setMessages((prev) => {
|
|
18605
|
+
const newMsgs = [...prev];
|
|
18606
|
+
const hintMsg = newMsgs.reverse().find((m) => m.text?.includes("[STEERING HINT: QUEUED]") || m.text?.includes("[QUESTION: QUEUED]"));
|
|
18607
|
+
if (hintMsg) {
|
|
18608
|
+
if (hintMsg.text.includes("[STEERING HINT: QUEUED]")) {
|
|
18609
|
+
hintMsg.text = hintMsg.text.replace("[STEERING HINT: QUEUED]", "[STEERING HINT: FINISHED_TURN]");
|
|
18610
|
+
} else if (hintMsg.text.includes("[QUESTION: QUEUED]")) {
|
|
18611
|
+
hintMsg.text = hintMsg.text.replace("[QUESTION: QUEUED]", "[QUESTION: FINISHED_TURN]");
|
|
18612
|
+
}
|
|
18613
|
+
}
|
|
18614
|
+
return newMsgs.reverse();
|
|
18615
|
+
});
|
|
18616
|
+
setActiveView("resolution");
|
|
18617
|
+
}
|
|
18618
|
+
setMessages((prev) => {
|
|
18619
|
+
const totalDuration = Date.now() - apiStartVal;
|
|
18620
|
+
let foundLastAgent = false;
|
|
18621
|
+
const newMsgs = [...prev].reverse().map((m) => {
|
|
18622
|
+
let updated = m.isStreaming ? { ...m, isStreaming: false } : m;
|
|
18623
|
+
if (updated.text) {
|
|
18624
|
+
updated.text = (" " + updated.text).slice(1);
|
|
18625
|
+
}
|
|
18626
|
+
if (!foundLastAgent && updated.role === "agent") {
|
|
18627
|
+
foundLastAgent = true;
|
|
18628
|
+
updated = { ...updated, workedDuration: totalDuration };
|
|
18629
|
+
}
|
|
18630
|
+
return updated;
|
|
18631
|
+
}).reverse();
|
|
18632
|
+
const historyToSave = newMsgs.filter((m) => !String(m.id).startsWith("welcome") && (!m.isMeta || m.text && m.text.includes("Request Cancelled")));
|
|
18633
|
+
saveChat(chatId, null, historyToSave);
|
|
18634
|
+
setCompletedIndex(newMsgs.length);
|
|
18635
|
+
return newMsgs;
|
|
18636
|
+
});
|
|
18637
|
+
};
|
|
18638
|
+
const pushTokenText = (id, text) => {
|
|
18639
|
+
if (systemSettings.progressiveRendering) {
|
|
18640
|
+
const tokens = text.split(/(\s+)/).filter(Boolean);
|
|
18641
|
+
for (const tok of tokens) {
|
|
18642
|
+
typewriterQueueRef.current.push({ type: "text", id, text: tok });
|
|
18643
|
+
}
|
|
18644
|
+
}
|
|
18645
|
+
};
|
|
18646
|
+
const startTypewriter = (apiStartVal) => {
|
|
18647
|
+
if (typewriterIntervalRef.current) {
|
|
18648
|
+
clearInterval(typewriterIntervalRef.current);
|
|
18649
|
+
}
|
|
18650
|
+
streamFinishedRef.current = false;
|
|
18651
|
+
typewriterQueueRef.current = [];
|
|
18652
|
+
typewriterIntervalRef.current = setInterval(() => {
|
|
18653
|
+
const queue = typewriterQueueRef.current;
|
|
18654
|
+
if (queue.length > 0) {
|
|
18655
|
+
let batchSize = 1;
|
|
18656
|
+
if (queue.length > 35) batchSize = 5;
|
|
18657
|
+
else if (queue.length > 15) batchSize = 3;
|
|
18658
|
+
else if (queue.length > 5) batchSize = 2;
|
|
18659
|
+
let changed = false;
|
|
18660
|
+
const nextMsgs = [...activeStreamMessagesRef.current];
|
|
18661
|
+
const clonedIndices = /* @__PURE__ */ new Set();
|
|
18662
|
+
for (let i = 0; i < batchSize; i++) {
|
|
18663
|
+
if (queue.length === 0) break;
|
|
18664
|
+
const task = queue.shift();
|
|
18665
|
+
if (task.type === "create") {
|
|
18666
|
+
nextMsgs.push(task.msg);
|
|
18667
|
+
changed = true;
|
|
18668
|
+
} else if (task.type === "text") {
|
|
18669
|
+
const idx = nextMsgs.findIndex((m) => m.id === task.id);
|
|
18670
|
+
if (idx !== -1) {
|
|
18671
|
+
if (!clonedIndices.has(idx)) {
|
|
18672
|
+
nextMsgs[idx] = { ...nextMsgs[idx] };
|
|
18673
|
+
clonedIndices.add(idx);
|
|
18674
|
+
}
|
|
18675
|
+
nextMsgs[idx].text += task.text;
|
|
18676
|
+
changed = true;
|
|
18677
|
+
}
|
|
18678
|
+
} else if (task.type === "finalize-think") {
|
|
18679
|
+
const idx = nextMsgs.findIndex((m) => m.id === task.id);
|
|
18680
|
+
if (idx !== -1) {
|
|
18681
|
+
if (!clonedIndices.has(idx)) {
|
|
18682
|
+
nextMsgs[idx] = { ...nextMsgs[idx] };
|
|
18683
|
+
clonedIndices.add(idx);
|
|
18684
|
+
}
|
|
18685
|
+
nextMsgs[idx].isStreaming = false;
|
|
18686
|
+
nextMsgs[idx].duration = task.duration;
|
|
18687
|
+
changed = true;
|
|
18688
|
+
}
|
|
18689
|
+
}
|
|
18690
|
+
}
|
|
18691
|
+
if (changed) {
|
|
18692
|
+
activeStreamMessagesRef.current = nextMsgs;
|
|
18693
|
+
setActiveStreamMessages(nextMsgs);
|
|
18694
|
+
}
|
|
18695
|
+
} else if (streamFinishedRef.current) {
|
|
18696
|
+
clearInterval(typewriterIntervalRef.current);
|
|
18697
|
+
typewriterIntervalRef.current = null;
|
|
18698
|
+
finalizeTurn(apiStartVal);
|
|
18699
|
+
}
|
|
18700
|
+
}, 35);
|
|
18701
|
+
};
|
|
18702
|
+
const awaitTypewriter = async () => {
|
|
18703
|
+
while (systemSettings.progressiveRendering && typewriterQueueRef.current.length > 0) {
|
|
18704
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
18705
|
+
}
|
|
18706
|
+
};
|
|
18522
18707
|
let hasFiredJanitor = false;
|
|
18523
18708
|
setIsProcessing(true);
|
|
18524
18709
|
setLastChunkTime(Date.now());
|
|
@@ -18740,27 +18925,29 @@ Selection: ${val}`,
|
|
|
18740
18925
|
let inToolCallString = null;
|
|
18741
18926
|
const signalRegex = /\[?\s*turn\s*:\s*.*?\s*\]?/gi;
|
|
18742
18927
|
for await (const packet of stream) {
|
|
18743
|
-
await new Promise((resolve) => setTimeout(resolve, 3));
|
|
18744
18928
|
if (packet.type === "text") {
|
|
18745
18929
|
setLastChunkTime(Date.now());
|
|
18746
18930
|
}
|
|
18747
18931
|
if (isFirstPacket && packet.type === "text") {
|
|
18748
18932
|
apiStart = Date.now();
|
|
18749
18933
|
isFirstPacket = false;
|
|
18934
|
+
if (systemSettings.progressiveRendering) {
|
|
18935
|
+
startTypewriter(apiStart);
|
|
18936
|
+
}
|
|
18750
18937
|
}
|
|
18751
18938
|
if (packet.type === "status") {
|
|
18752
18939
|
if (!packet.content?.includes("[start]")) {
|
|
18753
18940
|
setStatusText(packet.content);
|
|
18754
18941
|
}
|
|
18755
18942
|
if (packet.content?.includes("[start]")) {
|
|
18756
|
-
clearInterval(
|
|
18943
|
+
clearInterval(activeTimeIntervalRef.current);
|
|
18757
18944
|
setActiveTime(0);
|
|
18758
|
-
|
|
18945
|
+
activeTimeIntervalRef.current = setInterval(() => {
|
|
18759
18946
|
setActiveTime((prev) => prev + 1);
|
|
18760
18947
|
}, 1e3);
|
|
18761
18948
|
} else if (packet.content?.includes("[end]")) {
|
|
18762
18949
|
setActiveTime(0);
|
|
18763
|
-
clearInterval(
|
|
18950
|
+
clearInterval(activeTimeIntervalRef.current);
|
|
18764
18951
|
}
|
|
18765
18952
|
if (isBridgeConnected()) {
|
|
18766
18953
|
sendStatus(packet.content);
|
|
@@ -18793,6 +18980,9 @@ Selection: ${val}`,
|
|
|
18793
18980
|
continue;
|
|
18794
18981
|
}
|
|
18795
18982
|
if (packet.type === "turn_reset") {
|
|
18983
|
+
if (systemSettings.progressiveRendering) {
|
|
18984
|
+
await awaitTypewriter();
|
|
18985
|
+
}
|
|
18796
18986
|
currentThinkId = null;
|
|
18797
18987
|
currentAgentId = null;
|
|
18798
18988
|
inThinkMode = false;
|
|
@@ -18800,21 +18990,29 @@ Selection: ${val}`,
|
|
|
18800
18990
|
inToolCall = false;
|
|
18801
18991
|
toolCallEncounteredInTurn = false;
|
|
18802
18992
|
thinkConsumedInTurn = false;
|
|
18993
|
+
const streamingMsgs = activeStreamMessagesRef.current;
|
|
18994
|
+
activeStreamMessagesRef.current = [];
|
|
18995
|
+
setActiveStreamMessages([]);
|
|
18803
18996
|
setMessages((prev) => {
|
|
18804
|
-
const
|
|
18805
|
-
|
|
18806
|
-
|
|
18807
|
-
|
|
18808
|
-
|
|
18809
|
-
|
|
18810
|
-
|
|
18997
|
+
const totalDuration = Date.now() - apiStart;
|
|
18998
|
+
const flushed = streamingMsgs.map((m) => {
|
|
18999
|
+
const flatText = m.text ? (" " + m.text).slice(1) : m.text;
|
|
19000
|
+
const flatFullText = m.fullText ? (" " + m.fullText).slice(1) : m.fullText;
|
|
19001
|
+
return {
|
|
19002
|
+
...m,
|
|
19003
|
+
isStreaming: false,
|
|
19004
|
+
text: flatText,
|
|
19005
|
+
fullText: flatFullText,
|
|
19006
|
+
workedDuration: m.role === "agent" ? totalDuration : m.workedDuration
|
|
19007
|
+
};
|
|
18811
19008
|
});
|
|
19009
|
+
const newMsgs = [...prev, ...flushed];
|
|
18812
19010
|
setCompletedIndex(newMsgs.length);
|
|
18813
19011
|
return newMsgs;
|
|
18814
19012
|
});
|
|
18815
19013
|
clearBlocksCache();
|
|
18816
19014
|
if (global.gc) {
|
|
18817
|
-
for (let i = 0; i <
|
|
19015
|
+
for (let i = 0; i < 1; i++) {
|
|
18818
19016
|
global.gc();
|
|
18819
19017
|
await new Promise((resolve) => setImmediate(resolve));
|
|
18820
19018
|
}
|
|
@@ -18825,7 +19023,7 @@ Selection: ${val}`,
|
|
|
18825
19023
|
if (packet.type === "interactive_turn_finished") {
|
|
18826
19024
|
setIsProcessing(false);
|
|
18827
19025
|
setActiveTime(0);
|
|
18828
|
-
clearInterval(
|
|
19026
|
+
clearInterval(activeTimeIntervalRef.current);
|
|
18829
19027
|
if (isBridgeConnected()) {
|
|
18830
19028
|
sendStatus(null);
|
|
18831
19029
|
}
|
|
@@ -18848,9 +19046,15 @@ Selection: ${val}`,
|
|
|
18848
19046
|
continue;
|
|
18849
19047
|
}
|
|
18850
19048
|
if (packet.type === "visual_feedback") {
|
|
19049
|
+
if (systemSettings.progressiveRendering) {
|
|
19050
|
+
await awaitTypewriter();
|
|
19051
|
+
}
|
|
19052
|
+
const streamingMsgs = activeStreamMessagesRef.current;
|
|
19053
|
+
activeStreamMessagesRef.current = [];
|
|
19054
|
+
setActiveStreamMessages([]);
|
|
18851
19055
|
setMessages((prev) => {
|
|
18852
|
-
const
|
|
18853
|
-
const newMsgs = [...
|
|
19056
|
+
const flushed = streamingMsgs.map((m) => ({ ...m, isStreaming: false }));
|
|
19057
|
+
const newMsgs = [...prev, ...flushed, {
|
|
18854
19058
|
id: "feedback-" + Date.now() + "-" + Math.random().toString(36).substring(2, 9),
|
|
18855
19059
|
role: "system",
|
|
18856
19060
|
text: packet.content,
|
|
@@ -18888,9 +19092,15 @@ Selection: ${val}`,
|
|
|
18888
19092
|
continue;
|
|
18889
19093
|
}
|
|
18890
19094
|
if (packet.type === "tool_result") {
|
|
19095
|
+
if (systemSettings.progressiveRendering) {
|
|
19096
|
+
await awaitTypewriter();
|
|
19097
|
+
}
|
|
19098
|
+
const streamingMsgs = activeStreamMessagesRef.current;
|
|
19099
|
+
activeStreamMessagesRef.current = [];
|
|
19100
|
+
setActiveStreamMessages([]);
|
|
18891
19101
|
setMessages((prev) => {
|
|
18892
|
-
const
|
|
18893
|
-
const newMsgs = [...
|
|
19102
|
+
const flushed = streamingMsgs.map((m) => ({ ...m, isStreaming: false }));
|
|
19103
|
+
const newMsgs = [...prev, ...flushed, {
|
|
18894
19104
|
id: "tool-" + Date.now(),
|
|
18895
19105
|
role: "system",
|
|
18896
19106
|
text: packet.content,
|
|
@@ -18956,7 +19166,7 @@ Selection: ${val}`,
|
|
|
18956
19166
|
let chunkText = packet.content;
|
|
18957
19167
|
if (packet.type === "text" && chunkText.includes("Request Cancelled")) {
|
|
18958
19168
|
if (global.gc) {
|
|
18959
|
-
for (let i = 0; i <
|
|
19169
|
+
for (let i = 0; i < 3; i++) {
|
|
18960
19170
|
global.gc();
|
|
18961
19171
|
await new Promise((resolve) => setImmediate(resolve));
|
|
18962
19172
|
}
|
|
@@ -18999,26 +19209,62 @@ Selection: ${val}`,
|
|
|
18999
19209
|
if (beforeText) {
|
|
19000
19210
|
if (!currentAgentId) {
|
|
19001
19211
|
currentAgentId = "agent-" + Date.now();
|
|
19002
|
-
|
|
19212
|
+
const newMsg = { id: currentAgentId, role: "agent", text: beforeText, isStreaming: true };
|
|
19213
|
+
if (systemSettings.progressiveRendering) {
|
|
19214
|
+
typewriterQueueRef.current.push({ type: "create", msg: { ...newMsg, text: "" } });
|
|
19215
|
+
pushTokenText(currentAgentId, beforeText);
|
|
19216
|
+
} else {
|
|
19217
|
+
activeStreamMessagesRef.current = [...activeStreamMessagesRef.current, newMsg];
|
|
19218
|
+
}
|
|
19003
19219
|
} else {
|
|
19004
|
-
|
|
19005
|
-
(
|
|
19006
|
-
|
|
19220
|
+
if (systemSettings.progressiveRendering) {
|
|
19221
|
+
pushTokenText(currentAgentId, beforeText);
|
|
19222
|
+
} else {
|
|
19223
|
+
activeStreamMessagesRef.current = activeStreamMessagesRef.current.map(
|
|
19224
|
+
(m) => m.id === currentAgentId ? { ...m, text: m.text + beforeText, isStreaming: true } : m
|
|
19225
|
+
);
|
|
19226
|
+
}
|
|
19227
|
+
}
|
|
19228
|
+
if (!systemSettings.progressiveRendering) {
|
|
19229
|
+
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19007
19230
|
}
|
|
19008
19231
|
}
|
|
19009
19232
|
inThinkMode = true;
|
|
19010
19233
|
thinkConsumedInTurn = true;
|
|
19011
19234
|
let thinkStartText = afterText.replace(/<(think|thought)>/gi, "");
|
|
19012
19235
|
currentThinkId = "think-" + Date.now();
|
|
19013
|
-
|
|
19236
|
+
const thinkMsg = { id: currentThinkId, role: "think", text: thinkStartText, isStreaming: true, startTime: Date.now() };
|
|
19237
|
+
if (systemSettings.progressiveRendering) {
|
|
19238
|
+
typewriterQueueRef.current.push({ type: "create", msg: { ...thinkMsg, text: "", startTime: Date.now() } });
|
|
19239
|
+
if (thinkStartText) {
|
|
19240
|
+
pushTokenText(currentThinkId, thinkStartText);
|
|
19241
|
+
}
|
|
19242
|
+
} else {
|
|
19243
|
+
activeStreamMessagesRef.current = [...activeStreamMessagesRef.current, thinkMsg];
|
|
19244
|
+
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19245
|
+
}
|
|
19014
19246
|
continue;
|
|
19015
19247
|
}
|
|
19016
19248
|
if ((chunkLower.includes("</think>") || chunkLower.includes("</thought>")) && currentThinkId) {
|
|
19017
19249
|
const parts = chunkText.split(/<\/(think|thought)>/gi);
|
|
19018
19250
|
const thinkPart = parts[0] || "";
|
|
19019
19251
|
const agentPart = parts.slice(2).join("").replace(/<\/?(think|thought)>/gi, "");
|
|
19020
|
-
|
|
19021
|
-
|
|
19252
|
+
inThinkMode = false;
|
|
19253
|
+
currentAgentId = "agent-" + Date.now();
|
|
19254
|
+
if (systemSettings.progressiveRendering) {
|
|
19255
|
+
if (thinkPart) {
|
|
19256
|
+
pushTokenText(currentThinkId, thinkPart);
|
|
19257
|
+
}
|
|
19258
|
+
const startTime = parseInt(currentThinkId.split("-")[1]) || Date.now();
|
|
19259
|
+
const duration = Date.now() - startTime;
|
|
19260
|
+
typewriterQueueRef.current.push({ type: "finalize-think", id: currentThinkId, duration });
|
|
19261
|
+
const newAgentMsg = { id: currentAgentId, role: "agent", text: "", isStreaming: true };
|
|
19262
|
+
typewriterQueueRef.current.push({ type: "create", msg: newAgentMsg });
|
|
19263
|
+
if (agentPart) {
|
|
19264
|
+
pushTokenText(currentAgentId, agentPart);
|
|
19265
|
+
}
|
|
19266
|
+
} else {
|
|
19267
|
+
activeStreamMessagesRef.current = activeStreamMessagesRef.current.map((m) => {
|
|
19022
19268
|
if (m.id === currentThinkId && typeof m.id === "string") {
|
|
19023
19269
|
const startTime = m.startTime || parseInt(m.id.split("-")[1]) || Date.now();
|
|
19024
19270
|
const duration = Date.now() - startTime;
|
|
@@ -19026,40 +19272,56 @@ Selection: ${val}`,
|
|
|
19026
19272
|
}
|
|
19027
19273
|
return m;
|
|
19028
19274
|
});
|
|
19029
|
-
|
|
19030
|
-
|
|
19031
|
-
|
|
19032
|
-
});
|
|
19275
|
+
activeStreamMessagesRef.current = [...activeStreamMessagesRef.current, { id: currentAgentId, role: "agent", text: agentPart, isStreaming: true }];
|
|
19276
|
+
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19277
|
+
}
|
|
19033
19278
|
continue;
|
|
19034
19279
|
}
|
|
19035
19280
|
if (inThinkMode && currentThinkId) {
|
|
19036
|
-
|
|
19037
|
-
|
|
19038
|
-
|
|
19039
|
-
|
|
19040
|
-
|
|
19041
|
-
|
|
19042
|
-
|
|
19281
|
+
let transitioning = false;
|
|
19282
|
+
let transitionContent = "";
|
|
19283
|
+
if (systemSettings.progressiveRendering) {
|
|
19284
|
+
if (chunkText.toLowerCase().includes("</think>")) {
|
|
19285
|
+
transitioning = true;
|
|
19286
|
+
const parts = chunkText.split(/<\/think>/gi);
|
|
19287
|
+
const thinkPart = parts[0] || "";
|
|
19288
|
+
transitionContent = parts.slice(1).join("</think>") || "";
|
|
19289
|
+
if (thinkPart) pushTokenText(currentThinkId, thinkPart);
|
|
19290
|
+
const startTime = parseInt(currentThinkId.split("-")[1]) || Date.now();
|
|
19291
|
+
const duration = Date.now() - startTime;
|
|
19292
|
+
typewriterQueueRef.current.push({ type: "finalize-think", id: currentThinkId, duration });
|
|
19293
|
+
inThinkMode = false;
|
|
19294
|
+
currentAgentId = "agent-" + Date.now();
|
|
19295
|
+
typewriterQueueRef.current.push({ type: "create", msg: { id: currentAgentId, role: "agent", text: "", isStreaming: true } });
|
|
19296
|
+
if (transitionContent) {
|
|
19297
|
+
pushTokenText(currentAgentId, transitionContent.replace(/<\/?(think|thought)>/gi, ""));
|
|
19298
|
+
}
|
|
19299
|
+
} else {
|
|
19300
|
+
pushTokenText(currentThinkId, chunkText);
|
|
19301
|
+
}
|
|
19302
|
+
} else {
|
|
19303
|
+
activeStreamMessagesRef.current = activeStreamMessagesRef.current.map((m) => {
|
|
19304
|
+
if (m.id === currentThinkId) {
|
|
19305
|
+
const newText = m.text + chunkText;
|
|
19043
19306
|
if (newText.toLowerCase().includes("</think>")) {
|
|
19044
19307
|
transitioning = true;
|
|
19045
19308
|
const parts = newText.split(/<\/think>/gi);
|
|
19046
19309
|
transitionContent = parts.slice(1).join("</think>") || "";
|
|
19047
|
-
const startTime =
|
|
19310
|
+
const startTime = m.startTime || parseInt(String(m.id).split("-")[1]) || Date.now();
|
|
19048
19311
|
const duration = Date.now() - startTime;
|
|
19049
|
-
|
|
19050
|
-
} else {
|
|
19051
|
-
next[i] = { ...next[i], text: newText, isStreaming: true };
|
|
19312
|
+
return { ...m, text: parts[0], isStreaming: false, duration };
|
|
19052
19313
|
}
|
|
19053
|
-
|
|
19314
|
+
return { ...m, text: newText, isStreaming: true };
|
|
19054
19315
|
}
|
|
19055
|
-
|
|
19316
|
+
return m;
|
|
19317
|
+
});
|
|
19056
19318
|
if (transitioning) {
|
|
19057
19319
|
inThinkMode = false;
|
|
19058
19320
|
currentAgentId = "agent-" + Date.now();
|
|
19059
|
-
|
|
19321
|
+
activeStreamMessagesRef.current = [...activeStreamMessagesRef.current, { id: currentAgentId, role: "agent", text: transitionContent.replace(/<\/?(think|thought)>/gi, ""), isStreaming: true }];
|
|
19060
19322
|
}
|
|
19061
|
-
|
|
19062
|
-
}
|
|
19323
|
+
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19324
|
+
}
|
|
19063
19325
|
} else if (!inThinkMode) {
|
|
19064
19326
|
const chunkLower2 = chunkText.toLowerCase();
|
|
19065
19327
|
if (!toolCallEncounteredInTurn && (chunkLower2.includes("tool:functions.") || chunkLower2.includes("agent:generalist."))) {
|
|
@@ -19067,91 +19329,69 @@ Selection: ${val}`,
|
|
|
19067
19329
|
}
|
|
19068
19330
|
if (!currentAgentId) {
|
|
19069
19331
|
currentAgentId = "agent-" + Date.now();
|
|
19070
|
-
|
|
19332
|
+
const newMsg = { id: currentAgentId, role: "agent", text: chunkText, isStreaming: true };
|
|
19333
|
+
if (systemSettings.progressiveRendering) {
|
|
19334
|
+
typewriterQueueRef.current.push({ type: "create", msg: { ...newMsg, text: "" } });
|
|
19335
|
+
pushTokenText(currentAgentId, chunkText);
|
|
19336
|
+
} else {
|
|
19337
|
+
activeStreamMessagesRef.current = [...activeStreamMessagesRef.current, newMsg];
|
|
19338
|
+
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19339
|
+
}
|
|
19071
19340
|
} else {
|
|
19072
|
-
|
|
19073
|
-
|
|
19341
|
+
if (systemSettings.progressiveRendering) {
|
|
19342
|
+
pushTokenText(currentAgentId, chunkText);
|
|
19343
|
+
} else {
|
|
19344
|
+
const next = [...activeStreamMessagesRef.current];
|
|
19074
19345
|
for (let i = next.length - 1; i >= 0; i--) {
|
|
19075
19346
|
if (next[i].id === currentAgentId) {
|
|
19076
19347
|
next[i] = { ...next[i], text: next[i].text + chunkText, isStreaming: true };
|
|
19077
19348
|
break;
|
|
19078
19349
|
}
|
|
19079
19350
|
}
|
|
19080
|
-
|
|
19081
|
-
|
|
19351
|
+
activeStreamMessagesRef.current = next;
|
|
19352
|
+
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19353
|
+
}
|
|
19082
19354
|
}
|
|
19083
19355
|
}
|
|
19084
19356
|
}
|
|
19357
|
+
if (systemSettings.progressiveRendering) {
|
|
19358
|
+
streamFinishedRef.current = true;
|
|
19359
|
+
} else {
|
|
19360
|
+
await finalizeTurn(apiStart);
|
|
19361
|
+
}
|
|
19085
19362
|
const apiEnd = Date.now();
|
|
19086
19363
|
setSessionApiTime((prev) => prev + (apiEnd - apiStart));
|
|
19087
19364
|
} catch (err) {
|
|
19365
|
+
if (typewriterIntervalRef.current) {
|
|
19366
|
+
clearInterval(typewriterIntervalRef.current);
|
|
19367
|
+
typewriterIntervalRef.current = null;
|
|
19368
|
+
}
|
|
19369
|
+
typewriterQueueRef.current = [];
|
|
19088
19370
|
setMessages((prev) => {
|
|
19089
19371
|
setCompletedIndex(prev.length + 1);
|
|
19090
19372
|
return [...prev, { id: "error-" + Date.now(), role: "system", text: `\u274C ERROR: ${err.message}` }];
|
|
19091
19373
|
});
|
|
19092
19374
|
} finally {
|
|
19093
|
-
|
|
19094
|
-
|
|
19095
|
-
|
|
19096
|
-
|
|
19097
|
-
|
|
19098
|
-
|
|
19099
|
-
|
|
19100
|
-
clearBlocksCache();
|
|
19101
|
-
if (global.gc) {
|
|
19102
|
-
try {
|
|
19103
|
-
for (let i = 0; i < 5; i++) {
|
|
19104
|
-
global.gc();
|
|
19105
|
-
await new Promise((resolve) => setImmediate(resolve));
|
|
19106
|
-
}
|
|
19107
|
-
lastGCTime = Date.now();
|
|
19108
|
-
} catch (e) {
|
|
19109
|
-
}
|
|
19110
|
-
}
|
|
19111
|
-
if (!hasFiredJanitor) {
|
|
19112
|
-
if (process.stdout.isTTY) {
|
|
19113
|
-
process.stdout.write("\x1B]0;FluxFlow | Idle\x07");
|
|
19114
|
-
process.stdout.write("\x1B]633;P;TerminalTitle=FluxFlow | Idle\x07");
|
|
19375
|
+
if (!systemSettings.progressiveRendering) {
|
|
19376
|
+
setIsProcessing(false);
|
|
19377
|
+
setStatusText(null);
|
|
19378
|
+
setActiveTime(0);
|
|
19379
|
+
clearInterval(activeTimeIntervalRef.current);
|
|
19380
|
+
if (didSignalTerminationRef.current) {
|
|
19381
|
+
appendCancelMessage();
|
|
19115
19382
|
}
|
|
19116
|
-
|
|
19117
|
-
|
|
19118
|
-
|
|
19119
|
-
|
|
19120
|
-
|
|
19121
|
-
|
|
19122
|
-
setMessages((prev) => {
|
|
19123
|
-
const newMsgs = [...prev];
|
|
19124
|
-
const hintMsg = newMsgs.reverse().find((m) => m.text?.includes("[STEERING HINT: QUEUED]") || m.text?.includes("[QUESTION: QUEUED]"));
|
|
19125
|
-
if (hintMsg) {
|
|
19126
|
-
if (hintMsg.text.includes("[STEERING HINT: QUEUED]")) {
|
|
19127
|
-
hintMsg.text = hintMsg.text.replace("[STEERING HINT: QUEUED]", "[STEERING HINT: FINISHED_TURN]");
|
|
19128
|
-
} else if (hintMsg.text.includes("[QUESTION: QUEUED]")) {
|
|
19129
|
-
hintMsg.text = hintMsg.text.replace("[QUESTION: QUEUED]", "[QUESTION: FINISHED_TURN]");
|
|
19383
|
+
clearBlocksCache();
|
|
19384
|
+
if (global.gc) {
|
|
19385
|
+
try {
|
|
19386
|
+
for (let i = 0; i < 3; i++) {
|
|
19387
|
+
global.gc();
|
|
19388
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
19130
19389
|
}
|
|
19390
|
+
lastGCTime = Date.now();
|
|
19391
|
+
} catch (e) {
|
|
19131
19392
|
}
|
|
19132
|
-
|
|
19133
|
-
});
|
|
19134
|
-
setActiveView("resolution");
|
|
19393
|
+
}
|
|
19135
19394
|
}
|
|
19136
|
-
setMessages((prev) => {
|
|
19137
|
-
const totalDuration = Date.now() - apiStart;
|
|
19138
|
-
let foundLastAgent = false;
|
|
19139
|
-
const newMsgs = [...prev].reverse().map((m) => {
|
|
19140
|
-
let updated = m.isStreaming ? { ...m, isStreaming: false } : m;
|
|
19141
|
-
if (updated.text) {
|
|
19142
|
-
updated.text = (" " + updated.text).slice(1);
|
|
19143
|
-
}
|
|
19144
|
-
if (!foundLastAgent && updated.role === "agent") {
|
|
19145
|
-
foundLastAgent = true;
|
|
19146
|
-
updated = { ...updated, workedDuration: totalDuration };
|
|
19147
|
-
}
|
|
19148
|
-
return updated;
|
|
19149
|
-
}).reverse();
|
|
19150
|
-
const historyToSave = newMsgs.filter((m) => !String(m.id).startsWith("welcome") && (!m.isMeta || m.text && m.text.includes("Request Cancelled")));
|
|
19151
|
-
saveChat(chatId, null, historyToSave);
|
|
19152
|
-
setCompletedIndex(newMsgs.length);
|
|
19153
|
-
return newMsgs;
|
|
19154
|
-
});
|
|
19155
19395
|
}
|
|
19156
19396
|
};
|
|
19157
19397
|
streamChat();
|
|
@@ -19385,7 +19625,7 @@ Selection: ${val}`,
|
|
|
19385
19625
|
} else if (selectedProvider === "DeepSeek") {
|
|
19386
19626
|
defaultModel = "deepseek-v4-flash";
|
|
19387
19627
|
} else if (selectedProvider === "NVIDIA") {
|
|
19388
|
-
defaultModel = "
|
|
19628
|
+
defaultModel = "stepfun-ai/step-3.7-flash";
|
|
19389
19629
|
}
|
|
19390
19630
|
setActiveModel(defaultModel);
|
|
19391
19631
|
const targetTier = (quotas.providerTiers || {})[selectedProvider] || "Free";
|
|
@@ -19713,7 +19953,7 @@ Selection: ${val}`,
|
|
|
19713
19953
|
} else if (prov === "DeepSeek") {
|
|
19714
19954
|
defaultModel = "deepseek-v4-flash";
|
|
19715
19955
|
} else if (prov === "NVIDIA") {
|
|
19716
|
-
defaultModel = "
|
|
19956
|
+
defaultModel = "stepfun-ai/step-3.7-flash";
|
|
19717
19957
|
}
|
|
19718
19958
|
setActiveModel(defaultModel);
|
|
19719
19959
|
const targetTier = (quotas.providerTiers || {})[prov] || "Free";
|