fluxflow-cli 3.2.6 → 3.3.0
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 +378 -465
- package/package.json +2 -2
package/dist/fluxflow.js
CHANGED
|
@@ -2111,10 +2111,14 @@ var init_build = __esm({
|
|
|
2111
2111
|
|
|
2112
2112
|
// src/utils/text.js
|
|
2113
2113
|
import os2 from "os";
|
|
2114
|
-
var wrapText, formatTokens, truncatePath, parsePatchPairs, applyPatches, generateHighFidelityDiff, parseLineInfo, getSimilarity, alignChangeGroup, blocksCache, streamingBlocksCache, MAX_CACHE_SIZE, CHUNK_SIZE, indexBlockIntoMap, parseMessageToBlocks, TOOL_LABELS, REGEX_INITIAL_THINK, REGEX_INITIAL_TOOL, REGEX_CLEAN_SIGNALS, REGEX_ARROWS_ALL, REGEX_TOOLS, cleanSignals, clearBlocksCache;
|
|
2114
|
+
var flattenString, wrapText, formatTokens, truncatePath, parsePatchPairs, applyPatches, generateHighFidelityDiff, parseLineInfo, getSimilarity, alignChangeGroup, blocksCache, streamingBlocksCache, MAX_CACHE_SIZE, CHUNK_SIZE, indexBlockIntoMap, parseMessageToBlocks, TOOL_LABELS, REGEX_INITIAL_THINK, REGEX_INITIAL_TOOL, REGEX_CLEAN_SIGNALS, REGEX_ARROWS_ALL, REGEX_TOOLS, cleanSignals, clearBlocksCache;
|
|
2115
2115
|
var init_text = __esm({
|
|
2116
2116
|
"src/utils/text.js"() {
|
|
2117
2117
|
init_paths();
|
|
2118
|
+
flattenString = (str) => {
|
|
2119
|
+
if (typeof str !== "string") return str;
|
|
2120
|
+
return str.length > 12 ? (str + "").replace("", "") : str;
|
|
2121
|
+
};
|
|
2118
2122
|
wrapText = (text, width) => {
|
|
2119
2123
|
if (!text) return "";
|
|
2120
2124
|
const ansiRegex = /\x1B\[[0-?]*[ -/]*[@-~]/g;
|
|
@@ -2166,7 +2170,7 @@ var init_text = __esm({
|
|
|
2166
2170
|
finalLines.push(currentLine.trimEnd());
|
|
2167
2171
|
}
|
|
2168
2172
|
});
|
|
2169
|
-
return finalLines.join("\n");
|
|
2173
|
+
return flattenString(finalLines.join("\n"));
|
|
2170
2174
|
};
|
|
2171
2175
|
formatTokens = (tokens) => {
|
|
2172
2176
|
if (!tokens && tokens !== 0) return "0.0k";
|
|
@@ -2181,9 +2185,9 @@ var init_text = __esm({
|
|
|
2181
2185
|
truncatePath = (p, maxLength = 40) => {
|
|
2182
2186
|
let data_dir = DATA_DIR.replaceAll("\\\\", "\\");
|
|
2183
2187
|
p = p.replace(os2.homedir(), "~").replace(data_dir, "FluxFlow").replaceAll("\\", "/");
|
|
2184
|
-
if (!p || p.length <= maxLength) return p;
|
|
2188
|
+
if (!p || p.length <= maxLength) return flattenString(p);
|
|
2185
2189
|
const half = Math.floor((maxLength - 3) / 2);
|
|
2186
|
-
return p.substring(0, half) + "..." + p.substring(p.length - half).replaceAll("\\", "/");
|
|
2190
|
+
return flattenString(p.substring(0, half) + "..." + p.substring(p.length - half).replaceAll("\\", "/"));
|
|
2187
2191
|
};
|
|
2188
2192
|
parsePatchPairs = (args) => {
|
|
2189
2193
|
const patchPairs = [];
|
|
@@ -2438,7 +2442,7 @@ var init_text = __esm({
|
|
|
2438
2442
|
}
|
|
2439
2443
|
}
|
|
2440
2444
|
diffText += `[DIFF_END]`;
|
|
2441
|
-
return diffText;
|
|
2445
|
+
return flattenString(diffText);
|
|
2442
2446
|
};
|
|
2443
2447
|
parseLineInfo = (l) => {
|
|
2444
2448
|
if (!l) return null;
|
|
@@ -2448,8 +2452,8 @@ var init_text = __esm({
|
|
|
2448
2452
|
let rest = isR || isA ? clean.substring(1) : clean;
|
|
2449
2453
|
rest = rest.trim();
|
|
2450
2454
|
const splitIdx = rest.indexOf("|");
|
|
2451
|
-
const num = splitIdx !== -1 ? rest.substring(0, splitIdx).trim() : "";
|
|
2452
|
-
const content = splitIdx !== -1 ? rest.substring(splitIdx + 1) : rest;
|
|
2455
|
+
const num = splitIdx !== -1 ? flattenString(rest.substring(0, splitIdx).trim()) : "";
|
|
2456
|
+
const content = splitIdx !== -1 ? flattenString(rest.substring(splitIdx + 1)) : flattenString(rest);
|
|
2453
2457
|
return { isR, isA, num, content };
|
|
2454
2458
|
};
|
|
2455
2459
|
getSimilarity = (s1, s2) => {
|
|
@@ -2457,21 +2461,35 @@ var init_text = __esm({
|
|
|
2457
2461
|
if (!s1 || !s2) return 0;
|
|
2458
2462
|
const l1 = s1.length;
|
|
2459
2463
|
const l2 = s2.length;
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2464
|
+
let str1 = s1;
|
|
2465
|
+
let str2 = s2;
|
|
2466
|
+
if (l1 < l2) {
|
|
2467
|
+
str1 = s2;
|
|
2468
|
+
str2 = s1;
|
|
2469
|
+
}
|
|
2470
|
+
const n = str1.length;
|
|
2471
|
+
const m = str2.length;
|
|
2472
|
+
const prevRow = new Int32Array(m + 1);
|
|
2473
|
+
const currRow = new Int32Array(m + 1);
|
|
2474
|
+
for (let j = 0; j <= m; j++) {
|
|
2475
|
+
prevRow[j] = j;
|
|
2476
|
+
}
|
|
2477
|
+
for (let i = 1; i <= n; i++) {
|
|
2478
|
+
currRow[0] = i;
|
|
2479
|
+
const char1 = str1[i - 1];
|
|
2480
|
+
for (let j = 1; j <= m; j++) {
|
|
2481
|
+
if (char1 === str2[j - 1]) {
|
|
2482
|
+
currRow[j] = prevRow[j - 1];
|
|
2467
2483
|
} else {
|
|
2468
|
-
|
|
2484
|
+
currRow[j] = Math.min(prevRow[j], currRow[j - 1], prevRow[j - 1]) + 1;
|
|
2469
2485
|
}
|
|
2470
2486
|
}
|
|
2487
|
+
prevRow.set(currRow);
|
|
2471
2488
|
}
|
|
2489
|
+
const dist = prevRow[m];
|
|
2472
2490
|
const maxLen = Math.max(l1, l2);
|
|
2473
2491
|
if (maxLen === 0) return 1;
|
|
2474
|
-
return 1 -
|
|
2492
|
+
return 1 - dist / maxLen;
|
|
2475
2493
|
};
|
|
2476
2494
|
alignChangeGroup = (group) => {
|
|
2477
2495
|
const removals = [];
|
|
@@ -2545,11 +2563,11 @@ var init_text = __esm({
|
|
|
2545
2563
|
};
|
|
2546
2564
|
parseMessageToBlocks = (msg, columns) => {
|
|
2547
2565
|
if (!msg) return { completed: [], active: [] };
|
|
2548
|
-
const cacheKey = `${msg.id}-${msg.text?.length || 0}-${columns}-${msg.isStreaming}-${msg.workedDuration || 0}
|
|
2566
|
+
const cacheKey = `${msg.id}-${msg.text?.length || 0}-${columns}-${msg.isStreaming}-${msg.workedDuration || 0}`;
|
|
2549
2567
|
if (!msg.isStreaming && blocksCache.has(cacheKey)) {
|
|
2550
2568
|
return blocksCache.get(cacheKey);
|
|
2551
2569
|
}
|
|
2552
|
-
const text = cleanSignals(msg.text || "");
|
|
2570
|
+
const text = flattenString(cleanSignals(msg.text || ""));
|
|
2553
2571
|
const streamCacheKey = `${msg.id}-${columns}`;
|
|
2554
2572
|
let cachedBlocks = /* @__PURE__ */ new Map();
|
|
2555
2573
|
if (msg.isStreaming) {
|
|
@@ -2563,13 +2581,13 @@ var init_text = __esm({
|
|
|
2563
2581
|
if (existing && existing.text === textContent && existing.type === type && !!existing.isActiveBlock === !!extra.isActiveBlock && !!existing.isStreaming === !!extra.isStreaming && existing.pairContent === extra.pairContent) {
|
|
2564
2582
|
return existing;
|
|
2565
2583
|
}
|
|
2566
|
-
const flatText =
|
|
2584
|
+
const flatText = flattenString(textContent);
|
|
2567
2585
|
const flatExtra = { ...extra };
|
|
2568
2586
|
if (typeof flatExtra.pairContent === "string") {
|
|
2569
|
-
flatExtra.pairContent = (
|
|
2587
|
+
flatExtra.pairContent = flattenString(flatExtra.pairContent);
|
|
2570
2588
|
}
|
|
2571
2589
|
if (Array.isArray(flatExtra.wrappedLines)) {
|
|
2572
|
-
flatExtra.wrappedLines = flatExtra.wrappedLines.map(
|
|
2590
|
+
flatExtra.wrappedLines = flatExtra.wrappedLines.map(flattenString);
|
|
2573
2591
|
}
|
|
2574
2592
|
return {
|
|
2575
2593
|
key,
|
|
@@ -4003,7 +4021,7 @@ ${coloredArt[7]}`;
|
|
|
4003
4021
|
import React4, { useState as useState4, useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
4004
4022
|
import { Box as Box3, Text as Text4 } from "ink";
|
|
4005
4023
|
import { diffWordsWithSpace } from "diff";
|
|
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;
|
|
4024
|
+
var useStreamingText, formatThinkText, REGEX_MD_TOKENS, REGEX_LATEX_FRAC, REGEX_LATEX_STYLE, parseMathSymbols, SYNTAX_KEYWORDS, SYNTAX_RULES, REGEX_SYNTAX, tokenCache, MAX_TOKEN_CACHE_SIZE, tokenizeLine, renderHighlightedLine, renderLatexText, InlineMarkdown, TableRenderer, MarkdownText, DiffLine, DiffBlock, CodeRenderer, formatThinkingDuration, MessageItem, BlockItem, ChatLayout;
|
|
4007
4025
|
var init_ChatLayout = __esm({
|
|
4008
4026
|
"src/components/ChatLayout.jsx"() {
|
|
4009
4027
|
init_TerminalBox();
|
|
@@ -4059,6 +4077,7 @@ var init_ChatLayout = __esm({
|
|
|
4059
4077
|
/\b(true|false|null|undefined|nil|None)\b/.source,
|
|
4060
4078
|
/\b(\d+(?:\.\d+)?|0x[0-9a-fA-F]+)\b/.source
|
|
4061
4079
|
];
|
|
4080
|
+
REGEX_SYNTAX = new RegExp(SYNTAX_RULES.join("|"), "g");
|
|
4062
4081
|
tokenCache = /* @__PURE__ */ new Map();
|
|
4063
4082
|
MAX_TOKEN_CACHE_SIZE = 1e3;
|
|
4064
4083
|
tokenizeLine = (line, lang) => {
|
|
@@ -4070,12 +4089,12 @@ var init_ChatLayout = __esm({
|
|
|
4070
4089
|
let lastIndex = 0;
|
|
4071
4090
|
const tokens = [];
|
|
4072
4091
|
let match;
|
|
4073
|
-
|
|
4074
|
-
while ((match =
|
|
4092
|
+
REGEX_SYNTAX.lastIndex = 0;
|
|
4093
|
+
while ((match = REGEX_SYNTAX.exec(line)) !== null) {
|
|
4075
4094
|
const matchText = match[0];
|
|
4076
4095
|
const matchIndex = match.index;
|
|
4077
4096
|
if (matchIndex > lastIndex) {
|
|
4078
|
-
tokens.push({ text: line.substring(lastIndex, matchIndex) });
|
|
4097
|
+
tokens.push({ text: flattenString(line.substring(lastIndex, matchIndex)) });
|
|
4079
4098
|
}
|
|
4080
4099
|
let color = void 0;
|
|
4081
4100
|
let bold = false;
|
|
@@ -4093,11 +4112,11 @@ var init_ChatLayout = __esm({
|
|
|
4093
4112
|
} else if (match[7] || match[8]) {
|
|
4094
4113
|
color = "#ff9e64";
|
|
4095
4114
|
}
|
|
4096
|
-
tokens.push({ text: matchText, color, bold });
|
|
4097
|
-
lastIndex =
|
|
4115
|
+
tokens.push({ text: flattenString(matchText), color, bold });
|
|
4116
|
+
lastIndex = REGEX_SYNTAX.lastIndex;
|
|
4098
4117
|
}
|
|
4099
4118
|
if (lastIndex < line.length) {
|
|
4100
|
-
tokens.push({ text: line.substring(lastIndex) });
|
|
4119
|
+
tokens.push({ text: flattenString(line.substring(lastIndex)) });
|
|
4101
4120
|
}
|
|
4102
4121
|
if (tokenCache.size >= MAX_TOKEN_CACHE_SIZE) {
|
|
4103
4122
|
const firstKey = tokenCache.keys().next().value;
|
|
@@ -4106,10 +4125,10 @@ var init_ChatLayout = __esm({
|
|
|
4106
4125
|
tokenCache.set(cacheKey, tokens);
|
|
4107
4126
|
return tokens;
|
|
4108
4127
|
};
|
|
4109
|
-
renderHighlightedLine = (line, lang, defaultColor = void 0) => {
|
|
4110
|
-
if (!line) return /* @__PURE__ */ React4.createElement(Text4,
|
|
4128
|
+
renderHighlightedLine = (line, lang, defaultColor = void 0, defaultBgColor = void 0) => {
|
|
4129
|
+
if (!line) return /* @__PURE__ */ React4.createElement(Text4, { backgroundColor: defaultBgColor }, " ");
|
|
4111
4130
|
const tokens = tokenizeLine(line, lang);
|
|
4112
|
-
return /* @__PURE__ */ React4.createElement(Text4, { color: defaultColor }, tokens.map((token, idx) => /* @__PURE__ */ React4.createElement(Text4, { key: idx, color: token.color || defaultColor, bold: token.bold }, token.text)));
|
|
4131
|
+
return /* @__PURE__ */ React4.createElement(Text4, { color: defaultColor, backgroundColor: defaultBgColor }, tokens.map((token, idx) => /* @__PURE__ */ React4.createElement(Text4, { key: idx, color: token.color || defaultColor, backgroundColor: defaultBgColor, bold: token.bold }, token.text)));
|
|
4113
4132
|
};
|
|
4114
4133
|
renderLatexText = (content, key) => {
|
|
4115
4134
|
if (!content) return null;
|
|
@@ -4239,7 +4258,7 @@ var init_ChatLayout = __esm({
|
|
|
4239
4258
|
const level = headingMatch[1].length;
|
|
4240
4259
|
const hText = headingMatch[2];
|
|
4241
4260
|
result.push(
|
|
4242
|
-
/* @__PURE__ */ React4.createElement(Box3, { key: i, marginTop: 1, marginBottom: 0, width: "100%" }, /* @__PURE__ */ React4.createElement(Text4, { bold: true, color: level === 1 ? "cyan" : level === 2 ? "purple" : level === 3 ? "yellow" : level === 4 ? "green" : level === 5 ? "blue" : "white", underline: true }, hText
|
|
4261
|
+
/* @__PURE__ */ React4.createElement(Box3, { key: i, marginTop: 1, marginBottom: 0, width: "100%" }, /* @__PURE__ */ React4.createElement(Text4, { bold: true, color: level === 1 ? "cyan" : level === 2 ? "purple" : level === 3 ? "yellow" : level === 4 ? "green" : level === 5 ? "blue" : "white", underline: true }, hText))
|
|
4243
4262
|
);
|
|
4244
4263
|
return;
|
|
4245
4264
|
}
|
|
@@ -4295,14 +4314,16 @@ var init_ChatLayout = __esm({
|
|
|
4295
4314
|
const displayPrefix = isRemoval ? "-" : isAddition ? "+" : " ";
|
|
4296
4315
|
const renderInlineDiff = () => {
|
|
4297
4316
|
if (isPureUnpairedBlock) {
|
|
4298
|
-
const blockColor = isRemoval ? "#
|
|
4317
|
+
const blockColor = isRemoval ? "#ff3333" : "#33ff66";
|
|
4318
|
+
const textBgColor = isRemoval ? "#5a1818" : "#185a25";
|
|
4299
4319
|
const wrappedLines = wrapText(content, columns - 15).split("\n");
|
|
4300
|
-
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column" }, wrappedLines.map((wl, idx) => /* @__PURE__ */ React4.createElement(Box3, { key: idx }, renderHighlightedLine(wl, extension, blockColor))));
|
|
4320
|
+
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column" }, wrappedLines.map((wl, idx) => /* @__PURE__ */ React4.createElement(Box3, { key: idx }, renderHighlightedLine(wl, extension, blockColor, textBgColor))));
|
|
4301
4321
|
}
|
|
4302
4322
|
if (!(isRemoval || isAddition) || words.length === 0 || !hasInlineChange) {
|
|
4303
4323
|
const textColor = isRemoval ? "#885555" : isAddition ? "#558866" : "gray";
|
|
4324
|
+
const textBgColor = void 0;
|
|
4304
4325
|
const wrappedLines = wrapText(content, columns - 15).split("\n");
|
|
4305
|
-
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column" }, wrappedLines.map((wl, idx) => /* @__PURE__ */ React4.createElement(Box3, { key: idx }, renderHighlightedLine(wl, extension, textColor))));
|
|
4326
|
+
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column" }, wrappedLines.map((wl, idx) => /* @__PURE__ */ React4.createElement(Box3, { key: idx }, renderHighlightedLine(wl, extension, textColor, textBgColor))));
|
|
4306
4327
|
}
|
|
4307
4328
|
return /* @__PURE__ */ React4.createElement(Text4, { wrap: "anywhere" }, words.map((part, idx) => {
|
|
4308
4329
|
const isWhitespace = /^\s+$/.test(part.value);
|
|
@@ -4951,7 +4972,11 @@ var init_StatusBar = __esm({
|
|
|
4951
4972
|
},
|
|
4952
4973
|
/* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Box4, { marginRight: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "white", bold: true }, mode.toUpperCase())), /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, "\u2503"), /* @__PURE__ */ React5.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "white", bold: true }, thinkingLevel.toUpperCase())), /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, "\u2503"), /* @__PURE__ */ React5.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", bold: true }, "MEM: "), /* @__PURE__ */ React5.createElement(Text5, { color: "white", bold: true }, isMemoryEnabled ? "ON" : "OFF"))),
|
|
4953
4974
|
/* @__PURE__ */ React5.createElement(Box4, { flexGrow: 1, justifyContent: "center", paddingX: 2 }, /* @__PURE__ */ React5.createElement(Text5, { color: "white", italic: true }, truncatePath(process.cwd(), 35))),
|
|
4954
|
-
/* @__PURE__ */ React5.createElement(Box4, null, isProcessing ? /* @__PURE__ */ React5.createElement(Box4, { marginRight: 0 }, /* @__PURE__ */ React5.createElement(Text5, { color: dotColor }, "\u25CF")) : /* @__PURE__ */ React5.createElement(Text5, null, " "), /* @__PURE__ */ React5.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "white" }, formatTokens(tokensTotal), " ",
|
|
4975
|
+
/* @__PURE__ */ React5.createElement(Box4, null, isProcessing ? /* @__PURE__ */ React5.createElement(Box4, { marginRight: 0 }, /* @__PURE__ */ React5.createElement(Text5, { color: dotColor }, "\u25CF")) : /* @__PURE__ */ React5.createElement(Text5, null, " "), /* @__PURE__ */ React5.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "white" }, formatTokens(tokensTotal), " ", (() => {
|
|
4976
|
+
const pct = tokens / maxLimit * 100;
|
|
4977
|
+
const color = pct < 60 ? "white" : pct < 80 ? "yellow" : "red";
|
|
4978
|
+
return /* @__PURE__ */ React5.createElement(Text5, { color, dimColor: true }, pct.toFixed(0), "%");
|
|
4979
|
+
})())), /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, "\u2503"), /* @__PURE__ */ React5.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "grey", bold: true }, memoryUsage, "/", memoryLimit, " ", memoryUnit)), /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, "\u2503"), /* @__PURE__ */ React5.createElement(Box4, { marginLeft: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", bold: true }, chatId), (apiTier === "Custom" || apiTier === "Paid") && /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, " \u2503 "), /* @__PURE__ */ React5.createElement(Text5, { color: "gray", bold: true }, "PAID"))))
|
|
4955
4980
|
);
|
|
4956
4981
|
});
|
|
4957
4982
|
StatusBar_default = StatusBar;
|
|
@@ -5187,7 +5212,7 @@ ${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative to CWD & WILL BE FIRST A
|
|
|
5187
5212
|
3. [tool:functions.FileMap(path="path/file")]. Shows file structure, functions, class, import/export, variable
|
|
5188
5213
|
4. [tool:functions.PatchFile(path="...", replaceContent1="full line/block", newContent1="...", ...MAX 6)]. Surgical Patch. **Multiple patch on same file/path? Use replaceContent2, newContent2 etc >>> multiple spams**. Unsure? ReadFile >> guessing. **MUST VERIFY DIFF**
|
|
5189
5214
|
5. [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile. Verify Imports
|
|
5190
|
-
6. [tool:functions.SearchKeyword(keyword="...", file="optional", subString="true/false optional", regex="
|
|
5215
|
+
6. [tool:functions.SearchKeyword(keyword="...", file="optional", subString="true/false optional", regex="optional, false for keyword")]. Global project search. If 'file' is provided, searches only that file. Finds definitions/logic without reading every file. Usage: Can search for relevent lines/logic area to read specifically for edit. defaults subString: false, regex: auto-detect
|
|
5191
5216
|
7. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL ONLY` : `WINDOWS CMD ONLY` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user
|
|
5192
5217
|
8. [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASK STRINGS])]. Task List, NO Markdown IN ARRAY. USAGE: ANALYZE USER REQUEST **IF** MULTIPLE TASK \u2192 BREAK DOWN TASK \u2192 CREATE TODO **BEFORE** DIVING IN. 'tasks' & 'markDone' OPTIONAL PARAMETERS WITH method 'get'. USE 'get' method WITH 'markDone' to mark task completed. **EVERY TURN UPDATE POLICY**
|
|
5193
5218
|
9. [tool:functions.Await(time="seconds")]. For waiting without exiting agent loop, 15s - 180s
|
|
@@ -8912,8 +8937,15 @@ var init_search_keyword = __esm({
|
|
|
8912
8937
|
const { keyword, file, subString, regex } = parseArgs(args);
|
|
8913
8938
|
if (!keyword) return 'ERROR: Missing "keyword" argument.';
|
|
8914
8939
|
const toBool = (v) => v === true || v === "true" || v === 1 || v === "1" || v === "yes";
|
|
8915
|
-
const
|
|
8916
|
-
|
|
8940
|
+
const regexExplicitlyFalse = regex === false || regex === "false" || regex === 0 || regex === "0" || regex === "no";
|
|
8941
|
+
let matchRegex = toBool(regex);
|
|
8942
|
+
let matchSubstring = !matchRegex && toBool(subString);
|
|
8943
|
+
const hasRegexIndicators = /[|]/.test(keyword) || /\\([*+?{}()|[\]\^$])/.test(keyword);
|
|
8944
|
+
let isAutoRegex = false;
|
|
8945
|
+
if (!matchRegex && !regexExplicitlyFalse && hasRegexIndicators) {
|
|
8946
|
+
matchRegex = true;
|
|
8947
|
+
isAutoRegex = true;
|
|
8948
|
+
}
|
|
8917
8949
|
let regexPattern;
|
|
8918
8950
|
let wordRegex;
|
|
8919
8951
|
if (matchRegex) {
|
|
@@ -8990,7 +9022,7 @@ var init_search_keyword = __esm({
|
|
|
8990
9022
|
if (typeof global.gc === "function") {
|
|
8991
9023
|
global.gc();
|
|
8992
9024
|
}
|
|
8993
|
-
const modeLabel = matchRegex ? "(regex mode)" : matchSubstring ? "(subString mode)" : "";
|
|
9025
|
+
const modeLabel = matchRegex ? isAutoRegex ? "(regex mode)" : "(keyword mode)" : matchSubstring ? "(subString mode)" : "";
|
|
8994
9026
|
if (fileGroups.length === 0) {
|
|
8995
9027
|
return `Found 0 matches for keyword: "${keyword}"${file ? ` in file: ${file}` : ". Try to specify files"} ${modeLabel}`;
|
|
8996
9028
|
}
|
|
@@ -10809,10 +10841,18 @@ var init_ai = __esm({
|
|
|
10809
10841
|
throw new DOMException("The user aborted a request.", "AbortError");
|
|
10810
10842
|
}
|
|
10811
10843
|
try {
|
|
10812
|
-
const
|
|
10813
|
-
if (
|
|
10814
|
-
|
|
10844
|
+
const response2 = await fetch(url, options);
|
|
10845
|
+
if (typeof performance !== "undefined" && performance.clearMeasures) {
|
|
10846
|
+
performance.clearMeasures();
|
|
10847
|
+
performance.clearMarks();
|
|
10848
|
+
}
|
|
10849
|
+
if (response2.ok) return response2;
|
|
10850
|
+
if (response2.status !== 429 && response2.status < 500) return response2;
|
|
10815
10851
|
} catch (e) {
|
|
10852
|
+
if (typeof performance !== "undefined" && performance.clearMeasures) {
|
|
10853
|
+
performance.clearMeasures();
|
|
10854
|
+
performance.clearMarks();
|
|
10855
|
+
}
|
|
10816
10856
|
if (e.name === "AbortError" || signal?.aborted) throw e;
|
|
10817
10857
|
if (i === retries - 1) throw e;
|
|
10818
10858
|
}
|
|
@@ -10835,7 +10875,12 @@ var init_ai = __esm({
|
|
|
10835
10875
|
if (signal?.aborted) {
|
|
10836
10876
|
throw new DOMException("The user aborted a request.", "AbortError");
|
|
10837
10877
|
}
|
|
10838
|
-
|
|
10878
|
+
const response = await fetch(url, options);
|
|
10879
|
+
if (typeof performance !== "undefined" && performance.clearMeasures) {
|
|
10880
|
+
performance.clearMeasures();
|
|
10881
|
+
performance.clearMarks();
|
|
10882
|
+
}
|
|
10883
|
+
return response;
|
|
10839
10884
|
};
|
|
10840
10885
|
getDeepSeekStream = async function* (apiKey, model, contents, systemInstruction, thinkingLevel, mode, isMultiModal, signal, temperature = 0.99) {
|
|
10841
10886
|
const messages = [];
|
|
@@ -11546,7 +11591,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
11546
11591
|
} else if (aiProvider === "NVIDIA") {
|
|
11547
11592
|
const stream = getNVIDIAStream(
|
|
11548
11593
|
apiKey,
|
|
11549
|
-
"
|
|
11594
|
+
"deepseek-ai/deepseek-v4-flash",
|
|
11550
11595
|
janitorContents,
|
|
11551
11596
|
janitorPrompt,
|
|
11552
11597
|
"Fast",
|
|
@@ -11984,6 +12029,32 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
11984
12029
|
if (!apiKey) return null;
|
|
11985
12030
|
globalSettings = settings;
|
|
11986
12031
|
client = new GoogleGenAI({ apiKey });
|
|
12032
|
+
if (!globalThis.__perfCleanupInstalled) {
|
|
12033
|
+
globalThis.__perfCleanupInstalled = true;
|
|
12034
|
+
setInterval(() => {
|
|
12035
|
+
if (typeof performance !== "undefined" && performance.clearMeasures) {
|
|
12036
|
+
performance.clearMeasures();
|
|
12037
|
+
performance.clearMarks();
|
|
12038
|
+
}
|
|
12039
|
+
}, 6e4);
|
|
12040
|
+
const originalFetch = globalThis.fetch;
|
|
12041
|
+
globalThis.fetch = async (...args) => {
|
|
12042
|
+
try {
|
|
12043
|
+
const response = await originalFetch(...args);
|
|
12044
|
+
if (typeof performance !== "undefined" && performance.clearMeasures) {
|
|
12045
|
+
performance.clearMeasures();
|
|
12046
|
+
performance.clearMarks();
|
|
12047
|
+
}
|
|
12048
|
+
return response;
|
|
12049
|
+
} catch (e) {
|
|
12050
|
+
if (typeof performance !== "undefined" && performance.clearMeasures) {
|
|
12051
|
+
performance.clearMeasures();
|
|
12052
|
+
performance.clearMarks();
|
|
12053
|
+
}
|
|
12054
|
+
throw e;
|
|
12055
|
+
}
|
|
12056
|
+
};
|
|
12057
|
+
}
|
|
11987
12058
|
return client;
|
|
11988
12059
|
};
|
|
11989
12060
|
generateSimpleContent = async (settings, model, contents, systemInstruction, thinkingLevel = "Fast", temperature = 0.75, usageKey = "agent") => {
|
|
@@ -12141,7 +12212,7 @@ ${newMemoryListStr}
|
|
|
12141
12212
|
let targetModel = "gemma-4-26b-a4b-it";
|
|
12142
12213
|
if (aiProvider === "OpenRouter") targetModel = "google/gemma-4-26b-a4b-it:free";
|
|
12143
12214
|
if (aiProvider === "DeepSeek") targetModel = "deepseek-v4-flash";
|
|
12144
|
-
if (aiProvider === "NVIDIA") targetModel = "
|
|
12215
|
+
if (aiProvider === "NVIDIA") targetModel = "deepseek-ai/deepseek-v4-flash";
|
|
12145
12216
|
while (attempts <= maxAttempts && !success) {
|
|
12146
12217
|
attempts++;
|
|
12147
12218
|
try {
|
|
@@ -12208,7 +12279,7 @@ Provide a consolidated summary of the entire session.`;
|
|
|
12208
12279
|
let targetModel = "gemma-4-26b-a4b-it";
|
|
12209
12280
|
if (aiProvider === "OpenRouter") targetModel = "google/gemma-4-26b-a4b-it:free";
|
|
12210
12281
|
if (aiProvider === "DeepSeek") targetModel = "deepseek-v4-flash";
|
|
12211
|
-
if (aiProvider === "NVIDIA") targetModel = "
|
|
12282
|
+
if (aiProvider === "NVIDIA") targetModel = "deepseek-ai/deepseek-v4-flash";
|
|
12212
12283
|
let attempts = 0;
|
|
12213
12284
|
let success = false;
|
|
12214
12285
|
let response = null;
|
|
@@ -12900,7 +12971,7 @@ ${boxMid}
|
|
|
12900
12971
|
}
|
|
12901
12972
|
let taggedContextStr = "";
|
|
12902
12973
|
if (taggedContextBlocks.length > 0) {
|
|
12903
|
-
taggedContextStr = "[TAGGED
|
|
12974
|
+
taggedContextStr = "[TAGGED FILE CONTENTS] Auto Read, System Provided Context\n" + taggedContextBlocks.join("\n\n") + "\n[/TAGGED FILE CONTENTS]\n";
|
|
12904
12975
|
}
|
|
12905
12976
|
const osDetected = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
12906
12977
|
const firstUserMsg = `[SYSTEM METADATA (PRIORITY: DYNAMIC), Chat Context >> Metadata] Time: ${dateTimeStr}
|
|
@@ -12908,7 +12979,7 @@ OS: ${osDetected}
|
|
|
12908
12979
|
CWD: ${process.cwd()}${isPlayground ? " [PLAYGROUND MODE]" : ""}${cwdMismatch ? ` (WARNING: CWD Mismatch! Previous Path: ${lastCwd})` : ""}
|
|
12909
12980
|
**DIRECTORY STRUCTURE**
|
|
12910
12981
|
${dirStructure}${memoryPrompt}${ideBlock}
|
|
12911
|
-
${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS
|
|
12982
|
+
${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGH PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : "\n"}${taggedContextStr}[USER PROMPT] ${cleanAgentText.trim()} [/USER PROMPT]`.trim();
|
|
12912
12983
|
const userMsgObj = { role: "user", text: firstUserMsg };
|
|
12913
12984
|
if (attachedBinaryPart) {
|
|
12914
12985
|
userMsgObj.binaryPart = attachedBinaryPart;
|
|
@@ -12954,7 +13025,7 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
|
|
|
12954
13025
|
[SYSTEM] USER QUESTION. RESOLVE THIS SPECIFIC QUERY WITHIN '[ANSWER] ... [/ANSWER]' CONCISELY, NATURALLY [/SYSTEM]
|
|
12955
13026
|
[QUESTION] ${hint.replace("/btw", "").trim()} [/QUESTION]`;
|
|
12956
13027
|
} else {
|
|
12957
|
-
modifiedHistory.push({ role: "user", text: `${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] USER QUESTION. RESOLVE THIS SPECIFIC QUERY WITHIN '[ANSWER] ... [/ANSWER]' CONCISELY, NATURALLY\n**STRICTLY FOLLOW THINKING POLICY AS
|
|
13028
|
+
modifiedHistory.push({ role: "user", text: `${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] USER QUESTION. RESOLVE THIS SPECIFIC QUERY WITHIN '[ANSWER] ... [/ANSWER]' CONCISELY, NATURALLY\n**STRICTLY FOLLOW THINKING POLICY AS HIGH PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : ""}[QUESTION] ${hint.replace("/btw", "").trim()} [/QUESTION]` });
|
|
12958
13029
|
}
|
|
12959
13030
|
} else {
|
|
12960
13031
|
if (modifiedHistory.length > 0 && modifiedHistory[modifiedHistory.length - 1].role === "user") {
|
|
@@ -12962,7 +13033,7 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
|
|
|
12962
13033
|
|
|
12963
13034
|
[STEERING HINT] ${hint.trim()} [/STEERING HINT]`;
|
|
12964
13035
|
} else {
|
|
12965
|
-
modifiedHistory.push({ role: "user", text: `${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS
|
|
13036
|
+
modifiedHistory.push({ role: "user", text: `${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" && aiProvider === "Google" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGH PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : ""}[STEERING HINT] ${hint.trim()} [/STEERING HINT]` });
|
|
12966
13037
|
}
|
|
12967
13038
|
}
|
|
12968
13039
|
yield { type: "status", content: `${hint.startsWith("/btw") ? "Question Forwarded..." : "Steering Hint Injected..."}` };
|
|
@@ -14904,8 +14975,8 @@ Error Log can be found in ${path21.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
14904
14975
|
|
|
14905
14976
|
[SYSTEM] USER QUESTION. RESOLVE THIS SPECIFIC QUERY WITHIN '[ANSWER] ... [/ANSWER]' CONCISELY, NATURALLY [/SYSTEM]
|
|
14906
14977
|
`, "").replace(`[SYSTEM] USER QUESTION. RESOLVE THIS SPECIFIC QUERY WITHIN '[ANSWER] ... [/ANSWER]' CONCISELY, NATURALLY
|
|
14907
|
-
**STRICTLY FOLLOW THINKING POLICY AS
|
|
14908
|
-
`, "").replace(`[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS
|
|
14978
|
+
**STRICTLY FOLLOW THINKING POLICY AS HIGH PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]
|
|
14979
|
+
`, "").replace(`[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGH PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]
|
|
14909
14980
|
`, "");
|
|
14910
14981
|
if (modelName && modelName.toLowerCase().startsWith("gemma") && aiProvider === "Google" && msg.text.startsWith("[TOOL RESULT]")) {
|
|
14911
14982
|
const jitInstructionFast = `
|
|
@@ -14942,6 +15013,10 @@ Error Log can be found in ${path21.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
14942
15013
|
clearInterval(connectionPollInterval);
|
|
14943
15014
|
connectionPollInterval = null;
|
|
14944
15015
|
}
|
|
15016
|
+
if (typeof performance !== "undefined" && performance.clearMeasures) {
|
|
15017
|
+
performance.clearMeasures();
|
|
15018
|
+
performance.clearMarks();
|
|
15019
|
+
}
|
|
14945
15020
|
await RevertManager.commitTransaction();
|
|
14946
15021
|
if (systemSettings?.advanceRollback) {
|
|
14947
15022
|
await AdvanceRevertManager.cleanup(chatId);
|
|
@@ -14959,7 +15034,7 @@ Error Log can be found in ${path21.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
14959
15034
|
"filemap": '- [tool:functions.FileMap(path="path/file")]. Shows file structure, functions, classes, imports/exports',
|
|
14960
15035
|
"patchfile": '- [tool:functions.PatchFile(path="...", replaceContent1="...", newContent1="...")]. Surgical block replacement for editing files',
|
|
14961
15036
|
"writefile": '- [tool:functions.WriteFile(path="...", content="...")]. Creates or overwrites a file',
|
|
14962
|
-
"searchkeyword": `- [tool:functions.SearchKeyword(keyword="...", file="optional", subString="true/false optional", regex="
|
|
15037
|
+
"searchkeyword": `- [tool:functions.SearchKeyword(keyword="...", file="optional", subString="true/false optional", regex="optional, false for keyword")]. Global project search. If 'file' is provided, searches only that file. Finds definitions/logic without reading every file. Usage: Can search for relevent lines/logic area to read specifically for edit. defaults subString: false, regex: auto-detect`,
|
|
14963
15038
|
"websearch": '- [tool:functions.WebSearch(query="...", limit=number)]. Web Search',
|
|
14964
15039
|
"webscrape": '- [tool:functions.WebScrape(url="...")]. Web Scrape',
|
|
14965
15040
|
"ask": `- [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish/guess. Suggest best options; don't ask for preferences. 'option' SHOULD be short`
|
|
@@ -15051,17 +15126,20 @@ ${cleanResponse}
|
|
|
15051
15126
|
} else if (normalizedToolName === "web_scrape" || normalizedToolName === "webscrape") {
|
|
15052
15127
|
label = `\u2714 \x1B[95mScraped\x1B[0m`;
|
|
15053
15128
|
} else if (normalizedToolName === "view_file" || normalizedToolName === "viewfile" || normalizedToolName === "readfile") {
|
|
15054
|
-
|
|
15129
|
+
const path23 = parseArgs(toolCall.args).path || "";
|
|
15130
|
+
label = `\u2714 \x1B[95mRead File\x1B[0m: ${path23}`;
|
|
15055
15131
|
} else if (normalizedToolName === "list_files" || normalizedToolName === "read_folder" || normalizedToolName === "readfolder") {
|
|
15056
|
-
|
|
15132
|
+
const path23 = parseArgs(toolCall.args).path || "";
|
|
15133
|
+
label = `\u2714 \x1B[95mBrowsed Folder\x1B[0m: ${path23}`;
|
|
15057
15134
|
} else if (normalizedToolName === "write_file" || normalizedToolName === "writefile") {
|
|
15058
|
-
const path23 = parseArgs(toolCall.args).path || "
|
|
15135
|
+
const path23 = parseArgs(toolCall.args).path || "";
|
|
15059
15136
|
label = `\u2714 \x1B[95mFile Created\x1B[0m: ${path23}`;
|
|
15060
15137
|
} else if (normalizedToolName === "update_file" || normalizedToolName === "updatefile" || normalizedToolName === "patchfile" || normalizedToolName === "patch_file" || normalizedToolName === "patchfile" || normalizedToolName === "updatefile") {
|
|
15061
|
-
const path23 = parseArgs(toolCall.args).path || "
|
|
15138
|
+
const path23 = parseArgs(toolCall.args).path || "";
|
|
15062
15139
|
label = `\u2714 \x1B[95mFile Edited\x1B[0m: ${path23}`;
|
|
15063
15140
|
} else if (normalizedToolName === "file_map" || normalizedToolName === "filemap") {
|
|
15064
|
-
|
|
15141
|
+
const path23 = parseArgs(toolCall.args).path || "";
|
|
15142
|
+
label = `\u2714 \x1B[95mIndexed\x1B[0m: ${path23}`;
|
|
15065
15143
|
} else if (normalizedToolName === "await") {
|
|
15066
15144
|
const { time } = parseArgs(toolCall.args);
|
|
15067
15145
|
let sec = parseFloat(time) || 0;
|
|
@@ -16084,7 +16162,7 @@ import TextInput4 from "ink-text-input";
|
|
|
16084
16162
|
import SelectInput2 from "ink-select-input";
|
|
16085
16163
|
import gradient2 from "gradient-string";
|
|
16086
16164
|
function App({ args = [] }) {
|
|
16087
|
-
|
|
16165
|
+
const lastGCTimeRef = useRef4(1);
|
|
16088
16166
|
const [confirmExit, setConfirmExit] = useState15(false);
|
|
16089
16167
|
const [exitCountdown, setExitCountdown] = useState15(10);
|
|
16090
16168
|
const { stdout } = useStdout2();
|
|
@@ -16102,6 +16180,78 @@ function App({ args = [] }) {
|
|
|
16102
16180
|
const [promoSelectedIndex, setPromoSelectedIndex] = useState15(0);
|
|
16103
16181
|
const suggestionOffsetRef = useRef4(0);
|
|
16104
16182
|
const persistedModelRef = useRef4(null);
|
|
16183
|
+
const activeStreamingMsgRef = useRef4(null);
|
|
16184
|
+
const [renderTick, setRenderTick] = useState15(0);
|
|
16185
|
+
const forceRender = () => setRenderTick((t) => t + 1);
|
|
16186
|
+
const typewriterQueueRef = useRef4([]);
|
|
16187
|
+
const typewriterTickRef = useRef4(null);
|
|
16188
|
+
const commitActiveStreamingMessage = () => {
|
|
16189
|
+
if (activeStreamingMsgRef.current) {
|
|
16190
|
+
const msg = {
|
|
16191
|
+
...activeStreamingMsgRef.current,
|
|
16192
|
+
text: flattenString(activeStreamingMsgRef.current.text),
|
|
16193
|
+
isStreaming: false
|
|
16194
|
+
};
|
|
16195
|
+
setMessages((prev) => {
|
|
16196
|
+
const next = [...prev, msg];
|
|
16197
|
+
setCompletedIndex(next.length);
|
|
16198
|
+
return next;
|
|
16199
|
+
});
|
|
16200
|
+
activeStreamingMsgRef.current = null;
|
|
16201
|
+
}
|
|
16202
|
+
};
|
|
16203
|
+
const startTypewriter = () => {
|
|
16204
|
+
if (typewriterTickRef.current) {
|
|
16205
|
+
clearInterval(typewriterTickRef.current);
|
|
16206
|
+
}
|
|
16207
|
+
typewriterQueueRef.current = [];
|
|
16208
|
+
typewriterTickRef.current = setInterval(() => {
|
|
16209
|
+
const queue = typewriterQueueRef.current;
|
|
16210
|
+
if (queue.length > 0 && activeStreamingMsgRef.current) {
|
|
16211
|
+
let batchSize = 2;
|
|
16212
|
+
if (queue.length > 65) batchSize = 16;
|
|
16213
|
+
else if (queue.length > 50) batchSize = 12;
|
|
16214
|
+
else if (queue.length > 35) batchSize = 8;
|
|
16215
|
+
else if (queue.length > 15) batchSize = 6;
|
|
16216
|
+
else if (queue.length > 5) batchSize = 4;
|
|
16217
|
+
let batchedText = "";
|
|
16218
|
+
for (let i = 0; i < batchSize && queue.length > 0; i++) {
|
|
16219
|
+
batchedText += queue.shift();
|
|
16220
|
+
}
|
|
16221
|
+
activeStreamingMsgRef.current.text = flattenString(activeStreamingMsgRef.current.text + batchedText);
|
|
16222
|
+
forceRender();
|
|
16223
|
+
}
|
|
16224
|
+
}, 100);
|
|
16225
|
+
};
|
|
16226
|
+
const awaitTypewriter = async () => {
|
|
16227
|
+
while (systemSettings.progressiveRendering && typewriterQueueRef.current.length > 0) {
|
|
16228
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
16229
|
+
}
|
|
16230
|
+
};
|
|
16231
|
+
const flushTypewriterNow = () => {
|
|
16232
|
+
const queue = typewriterQueueRef.current;
|
|
16233
|
+
if (queue.length > 0 && activeStreamingMsgRef.current) {
|
|
16234
|
+
const remaining = queue.join("");
|
|
16235
|
+
queue.length = 0;
|
|
16236
|
+
activeStreamingMsgRef.current.text = flattenString(activeStreamingMsgRef.current.text + remaining);
|
|
16237
|
+
forceRender();
|
|
16238
|
+
}
|
|
16239
|
+
};
|
|
16240
|
+
const appendStreamText = (chunkText) => {
|
|
16241
|
+
if (systemSettings.progressiveRendering && typewriterTickRef.current) {
|
|
16242
|
+
const tokens = chunkText.split(/(\s+)/).filter(Boolean);
|
|
16243
|
+
for (const tok of tokens) {
|
|
16244
|
+
typewriterQueueRef.current.push(tok);
|
|
16245
|
+
}
|
|
16246
|
+
} else {
|
|
16247
|
+
if (!activeStreamingMsgRef.current) {
|
|
16248
|
+
activeStreamingMsgRef.current = { id: "agent-" + Date.now(), role: "agent", text: flattenString(chunkText), isStreaming: true };
|
|
16249
|
+
} else {
|
|
16250
|
+
activeStreamingMsgRef.current.text = flattenString(activeStreamingMsgRef.current.text + chunkText);
|
|
16251
|
+
}
|
|
16252
|
+
forceRender();
|
|
16253
|
+
}
|
|
16254
|
+
};
|
|
16105
16255
|
useEffect12(() => {
|
|
16106
16256
|
const ideName = getIDEName();
|
|
16107
16257
|
const isIDE = !["Terminal", "Windows Terminal"].includes(ideName) || !!process.env.VSC_TERMINAL_URL;
|
|
@@ -16115,10 +16265,10 @@ function App({ args = [] }) {
|
|
|
16115
16265
|
setShowBridgePromo(false);
|
|
16116
16266
|
}
|
|
16117
16267
|
}, 1e3);
|
|
16118
|
-
|
|
16268
|
+
lastGCTimeRef.current = Date.now();
|
|
16119
16269
|
const memInterval = setInterval(() => {
|
|
16120
|
-
if (
|
|
16121
|
-
const diff = Date.now() -
|
|
16270
|
+
if (lastGCTimeRef.current) {
|
|
16271
|
+
const diff = Date.now() - lastGCTimeRef.current || 0;
|
|
16122
16272
|
if (diff > 3e4) {
|
|
16123
16273
|
if (global.gc) {
|
|
16124
16274
|
const gCAsync = async () => {
|
|
@@ -16126,7 +16276,7 @@ function App({ args = [] }) {
|
|
|
16126
16276
|
global.gc();
|
|
16127
16277
|
await new Promise((resolve) => setImmediate(resolve));
|
|
16128
16278
|
}
|
|
16129
|
-
|
|
16279
|
+
lastGCTimeRef.current = Date.now();
|
|
16130
16280
|
};
|
|
16131
16281
|
gCAsync();
|
|
16132
16282
|
}
|
|
@@ -16480,8 +16630,8 @@ function App({ args = [] }) {
|
|
|
16480
16630
|
defaultModel = "deepseek-v4-flash";
|
|
16481
16631
|
modelDisplayName = "DeepSeek Flash (Free default)";
|
|
16482
16632
|
} else if (aiProvider === "NVIDIA") {
|
|
16483
|
-
defaultModel = "
|
|
16484
|
-
modelDisplayName = "
|
|
16633
|
+
defaultModel = "deepseek-ai/deepseek-v4-flash";
|
|
16634
|
+
modelDisplayName = "DeepSeek V4 Flash (NVIDIA)";
|
|
16485
16635
|
} else {
|
|
16486
16636
|
defaultModel = "google/gemma-4-31b-it:free";
|
|
16487
16637
|
modelDisplayName = "Gemma 4 (Free default)";
|
|
@@ -16494,8 +16644,8 @@ function App({ args = [] }) {
|
|
|
16494
16644
|
defaultModel = "deepseek-v4-flash";
|
|
16495
16645
|
modelDisplayName = "DeepSeek Flash";
|
|
16496
16646
|
} else if (aiProvider === "NVIDIA") {
|
|
16497
|
-
defaultModel = "
|
|
16498
|
-
modelDisplayName = "
|
|
16647
|
+
defaultModel = "deepseek-ai/deepseek-v4-flash";
|
|
16648
|
+
modelDisplayName = "DeepSeek V4 Flash (NVIDIA)";
|
|
16499
16649
|
} else {
|
|
16500
16650
|
defaultModel = "deepseek/deepseek-v4-flash";
|
|
16501
16651
|
modelDisplayName = "DeepSeek Flash";
|
|
@@ -16556,7 +16706,7 @@ function App({ args = [] }) {
|
|
|
16556
16706
|
const [wittyPhrase, setWittyPhrase] = useState15("");
|
|
16557
16707
|
const [hasPasteBlock, setHasPasteBlock] = useState15(false);
|
|
16558
16708
|
const [activeTime, setActiveTime] = useState15(0);
|
|
16559
|
-
|
|
16709
|
+
let interval_for_timer;
|
|
16560
16710
|
useEffect12(() => {
|
|
16561
16711
|
let interval;
|
|
16562
16712
|
if (statusText && systemSettings.loadingPhrases !== false) {
|
|
@@ -16667,11 +16817,6 @@ function App({ args = [] }) {
|
|
|
16667
16817
|
}, [messages]);
|
|
16668
16818
|
const [completedIndex, setCompletedIndex] = useState15(messages.length);
|
|
16669
16819
|
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);
|
|
16675
16820
|
const lastCompletedBlocksRef = useRef4([]);
|
|
16676
16821
|
const cachedHistoryRef = useRef4({
|
|
16677
16822
|
completedIndex: 0,
|
|
@@ -16745,7 +16890,7 @@ function App({ args = [] }) {
|
|
|
16745
16890
|
};
|
|
16746
16891
|
}
|
|
16747
16892
|
}
|
|
16748
|
-
const activeMsgs =
|
|
16893
|
+
const activeMsgs = messages.slice(completedIndex);
|
|
16749
16894
|
const streamingCompletedBlocks = [];
|
|
16750
16895
|
const activeBlocks = [];
|
|
16751
16896
|
for (let i = 0; i < activeMsgs.length; i++) {
|
|
@@ -16761,19 +16906,14 @@ function App({ args = [] }) {
|
|
|
16761
16906
|
for (let j = 0; j < parsed.completed.length; j++) streamingCompletedBlocks.push(parsed.completed[j]);
|
|
16762
16907
|
for (let j = 0; j < parsed.active.length; j++) activeBlocks.push(parsed.active[j]);
|
|
16763
16908
|
}
|
|
16764
|
-
|
|
16765
|
-
|
|
16766
|
-
|
|
16767
|
-
|
|
16768
|
-
return { ...block, msg: latestMsg };
|
|
16769
|
-
}
|
|
16770
|
-
}
|
|
16771
|
-
return block;
|
|
16772
|
-
});
|
|
16773
|
-
for (let j = 0; j < streamingCompletedBlocks.length; j++) {
|
|
16774
|
-
finalCompleted.push(streamingCompletedBlocks[j]);
|
|
16909
|
+
if (activeStreamingMsgRef.current) {
|
|
16910
|
+
const parsed = parseMessageToBlocks(activeStreamingMsgRef.current, columns);
|
|
16911
|
+
for (let j = 0; j < parsed.completed.length; j++) streamingCompletedBlocks.push(parsed.completed[j]);
|
|
16912
|
+
for (let j = 0; j < parsed.active.length; j++) activeBlocks.push(parsed.active[j]);
|
|
16775
16913
|
}
|
|
16914
|
+
let finalCompleted = streamingCompletedBlocks.length === 0 ? historicalBlocks : historicalBlocks.concat(streamingCompletedBlocks);
|
|
16776
16915
|
if (finalCompleted.length >= 75e3) {
|
|
16916
|
+
finalCompleted = [...finalCompleted];
|
|
16777
16917
|
finalCompleted.push({
|
|
16778
16918
|
key: `memory-warning-block-${finalCompleted.length}`,
|
|
16779
16919
|
msg: {
|
|
@@ -16789,7 +16929,7 @@ function App({ args = [] }) {
|
|
|
16789
16929
|
completed: finalCompleted,
|
|
16790
16930
|
active: activeBlocks
|
|
16791
16931
|
};
|
|
16792
|
-
}, [messages,
|
|
16932
|
+
}, [messages, completedIndex, terminalSize.columns, clearKey, chatId, renderTick]);
|
|
16793
16933
|
const isTerminalWaitingForInput = useMemo2(() => {
|
|
16794
16934
|
if (!activeCommand || !execOutput) return false;
|
|
16795
16935
|
const lastChunk = execOutput.trim();
|
|
@@ -17087,7 +17227,7 @@ function App({ args = [] }) {
|
|
|
17087
17227
|
} else if (startupProvider === "OpenRouter") {
|
|
17088
17228
|
defaultModel = "google/gemma-4-31b-it:free";
|
|
17089
17229
|
} else if (startupProvider === "NVIDIA") {
|
|
17090
|
-
defaultModel = "
|
|
17230
|
+
defaultModel = "deepseek-ai/deepseek-v4-flash";
|
|
17091
17231
|
}
|
|
17092
17232
|
} else {
|
|
17093
17233
|
if (startupProvider === "Google") {
|
|
@@ -17097,7 +17237,7 @@ function App({ args = [] }) {
|
|
|
17097
17237
|
} else if (startupProvider === "OpenRouter") {
|
|
17098
17238
|
defaultModel = "deepseek/deepseek-v4-flash";
|
|
17099
17239
|
} else if (startupProvider === "NVIDIA") {
|
|
17100
|
-
defaultModel = "
|
|
17240
|
+
defaultModel = "deepseek-ai/deepseek-v4-flash";
|
|
17101
17241
|
}
|
|
17102
17242
|
}
|
|
17103
17243
|
setActiveModel(defaultModel);
|
|
@@ -17314,7 +17454,7 @@ function App({ args = [] }) {
|
|
|
17314
17454
|
} else if (aiProvider === "DeepSeek") {
|
|
17315
17455
|
defaultModel = "deepseek-v4-flash";
|
|
17316
17456
|
} else if (aiProvider === "NVIDIA") {
|
|
17317
|
-
defaultModel = "
|
|
17457
|
+
defaultModel = "deepseek-ai/deepseek-v4-flash";
|
|
17318
17458
|
}
|
|
17319
17459
|
setActiveModel(defaultModel);
|
|
17320
17460
|
setMessages((prev) => [...prev, { role: "system", text: `${aiProvider} API Key saved successfully! Model set to ${defaultModel}. Initialization complete.`, isMeta: true }]);
|
|
@@ -17491,10 +17631,6 @@ function App({ args = [] }) {
|
|
|
17491
17631
|
cmd: "moonshotai/kimi-k2.7",
|
|
17492
17632
|
desc: "Multimodal"
|
|
17493
17633
|
},
|
|
17494
|
-
{
|
|
17495
|
-
cmd: "moonshotai/kimi-k2.6",
|
|
17496
|
-
desc: "[DEPRICATED]"
|
|
17497
|
-
},
|
|
17498
17634
|
// --- DeepSeek Family ---
|
|
17499
17635
|
{
|
|
17500
17636
|
cmd: "deepseek-ai/deepseek-v4-flash",
|
|
@@ -17877,7 +18013,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
17877
18013
|
global.gc();
|
|
17878
18014
|
await new Promise((resolve) => setImmediate(resolve));
|
|
17879
18015
|
}
|
|
17880
|
-
|
|
18016
|
+
lastGCTimeRef.current = Date.now();
|
|
17881
18017
|
};
|
|
17882
18018
|
gCAsync();
|
|
17883
18019
|
}
|
|
@@ -17904,7 +18040,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
17904
18040
|
global.gc();
|
|
17905
18041
|
await new Promise((resolve) => setImmediate(resolve));
|
|
17906
18042
|
}
|
|
17907
|
-
|
|
18043
|
+
lastGCTimeRef.current = Date.now();
|
|
17908
18044
|
};
|
|
17909
18045
|
gCAsync();
|
|
17910
18046
|
}
|
|
@@ -18523,27 +18659,15 @@ ${timestamp}` };
|
|
|
18523
18659
|
const appendCancelMessage = () => {
|
|
18524
18660
|
if (didAppendCancel) return;
|
|
18525
18661
|
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 = [];
|
|
18534
18662
|
setMessages((prev) => {
|
|
18535
18663
|
const lastMsg = prev[prev.length - 1];
|
|
18536
18664
|
if (lastMsg && lastMsg.text && lastMsg.text.includes("Request Cancelled")) {
|
|
18537
18665
|
return prev;
|
|
18538
18666
|
}
|
|
18539
|
-
const
|
|
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);
|
|
18667
|
+
const updatedPrev = prev.map((m) => m.isStreaming ? { ...m, isStreaming: false } : m);
|
|
18544
18668
|
const newMsgs = [...updatedPrev, {
|
|
18545
18669
|
id: "cancel-" + Date.now(),
|
|
18546
|
-
role: "
|
|
18670
|
+
role: "agent",
|
|
18547
18671
|
text: "\n\n\x1B[33m\u24D8 Request Cancelled\x1B[0m",
|
|
18548
18672
|
isMeta: false
|
|
18549
18673
|
}];
|
|
@@ -18551,161 +18675,6 @@ ${timestamp}` };
|
|
|
18551
18675
|
return newMsgs;
|
|
18552
18676
|
});
|
|
18553
18677
|
};
|
|
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 = 2;
|
|
18656
|
-
if (queue.length > 65) batchSize = 16;
|
|
18657
|
-
else if (queue.length > 50) batchSize = 12;
|
|
18658
|
-
else if (queue.length > 35) batchSize = 8;
|
|
18659
|
-
else if (queue.length > 15) batchSize = 6;
|
|
18660
|
-
else if (queue.length > 5) batchSize = 4;
|
|
18661
|
-
let changed = false;
|
|
18662
|
-
const nextMsgs = [...activeStreamMessagesRef.current];
|
|
18663
|
-
const clonedIndices = /* @__PURE__ */ new Set();
|
|
18664
|
-
for (let i = 0; i < batchSize; i++) {
|
|
18665
|
-
if (queue.length === 0) break;
|
|
18666
|
-
const task = queue.shift();
|
|
18667
|
-
if (task.type === "create") {
|
|
18668
|
-
nextMsgs.push(task.msg);
|
|
18669
|
-
changed = true;
|
|
18670
|
-
} else if (task.type === "text") {
|
|
18671
|
-
const idx = nextMsgs.findIndex((m) => m.id === task.id);
|
|
18672
|
-
if (idx !== -1) {
|
|
18673
|
-
if (!clonedIndices.has(idx)) {
|
|
18674
|
-
nextMsgs[idx] = { ...nextMsgs[idx] };
|
|
18675
|
-
clonedIndices.add(idx);
|
|
18676
|
-
}
|
|
18677
|
-
nextMsgs[idx].text += task.text;
|
|
18678
|
-
changed = true;
|
|
18679
|
-
}
|
|
18680
|
-
} else if (task.type === "finalize-think") {
|
|
18681
|
-
const idx = nextMsgs.findIndex((m) => m.id === task.id);
|
|
18682
|
-
if (idx !== -1) {
|
|
18683
|
-
if (!clonedIndices.has(idx)) {
|
|
18684
|
-
nextMsgs[idx] = { ...nextMsgs[idx] };
|
|
18685
|
-
clonedIndices.add(idx);
|
|
18686
|
-
}
|
|
18687
|
-
nextMsgs[idx].isStreaming = false;
|
|
18688
|
-
nextMsgs[idx].duration = task.duration;
|
|
18689
|
-
changed = true;
|
|
18690
|
-
}
|
|
18691
|
-
}
|
|
18692
|
-
}
|
|
18693
|
-
if (changed) {
|
|
18694
|
-
activeStreamMessagesRef.current = nextMsgs;
|
|
18695
|
-
setActiveStreamMessages(nextMsgs);
|
|
18696
|
-
}
|
|
18697
|
-
} else if (streamFinishedRef.current) {
|
|
18698
|
-
clearInterval(typewriterIntervalRef.current);
|
|
18699
|
-
typewriterIntervalRef.current = null;
|
|
18700
|
-
finalizeTurn(apiStartVal);
|
|
18701
|
-
}
|
|
18702
|
-
}, 100);
|
|
18703
|
-
};
|
|
18704
|
-
const awaitTypewriter = async () => {
|
|
18705
|
-
while (systemSettings.progressiveRendering && typewriterQueueRef.current.length > 0) {
|
|
18706
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
18707
|
-
}
|
|
18708
|
-
};
|
|
18709
18678
|
let hasFiredJanitor = false;
|
|
18710
18679
|
setIsProcessing(true);
|
|
18711
18680
|
setLastChunkTime(Date.now());
|
|
@@ -18797,6 +18766,8 @@ ${timestamp}` };
|
|
|
18797
18766
|
setActiveCommand(null);
|
|
18798
18767
|
setIsTerminalFocused(false);
|
|
18799
18768
|
setExecOutput("");
|
|
18769
|
+
activeCommandRef.current = null;
|
|
18770
|
+
execOutputRef.current = "";
|
|
18800
18771
|
},
|
|
18801
18772
|
onToolResult: (status, toolName) => {
|
|
18802
18773
|
if (status === "success") {
|
|
@@ -18927,6 +18898,7 @@ Selection: ${val}`,
|
|
|
18927
18898
|
let inToolCallString = null;
|
|
18928
18899
|
const signalRegex = /\[?\s*turn\s*:\s*.*?\s*\]?/gi;
|
|
18929
18900
|
for await (const packet of stream) {
|
|
18901
|
+
await new Promise((resolve) => setTimeout(resolve, 3));
|
|
18930
18902
|
if (packet.type === "text") {
|
|
18931
18903
|
setLastChunkTime(Date.now());
|
|
18932
18904
|
}
|
|
@@ -18934,7 +18906,7 @@ Selection: ${val}`,
|
|
|
18934
18906
|
apiStart = Date.now();
|
|
18935
18907
|
isFirstPacket = false;
|
|
18936
18908
|
if (systemSettings.progressiveRendering) {
|
|
18937
|
-
startTypewriter(
|
|
18909
|
+
startTypewriter();
|
|
18938
18910
|
}
|
|
18939
18911
|
}
|
|
18940
18912
|
if (packet.type === "status") {
|
|
@@ -18942,19 +18914,21 @@ Selection: ${val}`,
|
|
|
18942
18914
|
setStatusText(packet.content);
|
|
18943
18915
|
}
|
|
18944
18916
|
if (packet.content?.includes("[start]")) {
|
|
18945
|
-
clearInterval(
|
|
18917
|
+
clearInterval(interval_for_timer);
|
|
18946
18918
|
setActiveTime(0);
|
|
18947
|
-
|
|
18919
|
+
interval_for_timer = setInterval(() => {
|
|
18948
18920
|
setActiveTime((prev) => prev + 1);
|
|
18949
18921
|
}, 1e3);
|
|
18950
18922
|
} else if (packet.content?.includes("[end]")) {
|
|
18951
18923
|
setActiveTime(0);
|
|
18952
|
-
clearInterval(
|
|
18924
|
+
clearInterval(interval_for_timer);
|
|
18953
18925
|
}
|
|
18954
18926
|
if (isBridgeConnected()) {
|
|
18955
18927
|
sendStatus(packet.content);
|
|
18956
18928
|
}
|
|
18957
18929
|
if (packet.content === "Request Cancelled") {
|
|
18930
|
+
flushTypewriterNow();
|
|
18931
|
+
commitActiveStreamingMessage();
|
|
18958
18932
|
appendCancelMessage();
|
|
18959
18933
|
}
|
|
18960
18934
|
continue;
|
|
@@ -18982,9 +18956,7 @@ Selection: ${val}`,
|
|
|
18982
18956
|
continue;
|
|
18983
18957
|
}
|
|
18984
18958
|
if (packet.type === "turn_reset") {
|
|
18985
|
-
|
|
18986
|
-
await awaitTypewriter();
|
|
18987
|
-
}
|
|
18959
|
+
flushTypewriterNow();
|
|
18988
18960
|
currentThinkId = null;
|
|
18989
18961
|
currentAgentId = null;
|
|
18990
18962
|
inThinkMode = false;
|
|
@@ -18992,40 +18964,32 @@ Selection: ${val}`,
|
|
|
18992
18964
|
inToolCall = false;
|
|
18993
18965
|
toolCallEncounteredInTurn = false;
|
|
18994
18966
|
thinkConsumedInTurn = false;
|
|
18995
|
-
const streamingMsgs = activeStreamMessagesRef.current;
|
|
18996
|
-
activeStreamMessagesRef.current = [];
|
|
18997
|
-
setActiveStreamMessages([]);
|
|
18998
18967
|
setMessages((prev) => {
|
|
18999
|
-
const
|
|
19000
|
-
|
|
19001
|
-
|
|
19002
|
-
|
|
19003
|
-
|
|
19004
|
-
|
|
19005
|
-
|
|
19006
|
-
text: flatText,
|
|
19007
|
-
fullText: flatFullText,
|
|
19008
|
-
workedDuration: m.role === "agent" ? totalDuration : m.workedDuration
|
|
19009
|
-
};
|
|
18968
|
+
const newMsgs = prev.map((m) => {
|
|
18969
|
+
if (m.isStreaming) {
|
|
18970
|
+
const flatText = m.text ? flattenString(m.text) : m.text;
|
|
18971
|
+
const flatFullText = m.fullText ? flattenString(m.fullText) : m.fullText;
|
|
18972
|
+
return { ...m, isStreaming: false, text: flatText, fullText: flatFullText };
|
|
18973
|
+
}
|
|
18974
|
+
return m;
|
|
19010
18975
|
});
|
|
19011
|
-
const newMsgs = [...prev, ...flushed];
|
|
19012
18976
|
setCompletedIndex(newMsgs.length);
|
|
19013
18977
|
return newMsgs;
|
|
19014
18978
|
});
|
|
19015
18979
|
clearBlocksCache();
|
|
19016
18980
|
if (global.gc) {
|
|
19017
|
-
for (let i = 0; i <
|
|
18981
|
+
for (let i = 0; i < 2; i++) {
|
|
19018
18982
|
global.gc();
|
|
19019
18983
|
await new Promise((resolve) => setImmediate(resolve));
|
|
19020
18984
|
}
|
|
19021
|
-
|
|
18985
|
+
lastGCTimeRef.current = Date.now();
|
|
19022
18986
|
}
|
|
19023
18987
|
continue;
|
|
19024
18988
|
}
|
|
19025
18989
|
if (packet.type === "interactive_turn_finished") {
|
|
19026
18990
|
setIsProcessing(false);
|
|
19027
18991
|
setActiveTime(0);
|
|
19028
|
-
clearInterval(
|
|
18992
|
+
clearInterval(interval_for_timer);
|
|
19029
18993
|
if (isBridgeConnected()) {
|
|
19030
18994
|
sendStatus(null);
|
|
19031
18995
|
}
|
|
@@ -19048,18 +19012,13 @@ Selection: ${val}`,
|
|
|
19048
19012
|
continue;
|
|
19049
19013
|
}
|
|
19050
19014
|
if (packet.type === "visual_feedback") {
|
|
19051
|
-
|
|
19052
|
-
|
|
19053
|
-
}
|
|
19054
|
-
const streamingMsgs = activeStreamMessagesRef.current;
|
|
19055
|
-
activeStreamMessagesRef.current = [];
|
|
19056
|
-
setActiveStreamMessages([]);
|
|
19015
|
+
flushTypewriterNow();
|
|
19016
|
+
commitActiveStreamingMessage();
|
|
19057
19017
|
setMessages((prev) => {
|
|
19058
|
-
const
|
|
19059
|
-
const newMsgs = [...prev, ...flushed, {
|
|
19018
|
+
const newMsgs = [...prev, {
|
|
19060
19019
|
id: "feedback-" + Date.now() + "-" + Math.random().toString(36).substring(2, 9),
|
|
19061
19020
|
role: "system",
|
|
19062
|
-
text: packet.content,
|
|
19021
|
+
text: flattenString(packet.content),
|
|
19063
19022
|
isVisualFeedback: true
|
|
19064
19023
|
}];
|
|
19065
19024
|
setCompletedIndex(newMsgs.length);
|
|
@@ -19094,19 +19053,13 @@ Selection: ${val}`,
|
|
|
19094
19053
|
continue;
|
|
19095
19054
|
}
|
|
19096
19055
|
if (packet.type === "tool_result") {
|
|
19097
|
-
|
|
19098
|
-
await awaitTypewriter();
|
|
19099
|
-
}
|
|
19100
|
-
const streamingMsgs = activeStreamMessagesRef.current;
|
|
19101
|
-
activeStreamMessagesRef.current = [];
|
|
19102
|
-
setActiveStreamMessages([]);
|
|
19056
|
+
commitActiveStreamingMessage();
|
|
19103
19057
|
setMessages((prev) => {
|
|
19104
|
-
const
|
|
19105
|
-
const newMsgs = [...prev, ...flushed, {
|
|
19058
|
+
const newMsgs = [...prev, {
|
|
19106
19059
|
id: "tool-" + Date.now(),
|
|
19107
19060
|
role: "system",
|
|
19108
|
-
text: packet.content,
|
|
19109
|
-
fullText: packet.aiContent,
|
|
19061
|
+
text: flattenString(packet.content),
|
|
19062
|
+
fullText: flattenString(packet.aiContent),
|
|
19110
19063
|
// Preserve raw data for next turn
|
|
19111
19064
|
binaryPart: packet.binaryPart,
|
|
19112
19065
|
// v1.5.0 Multimodal Support
|
|
@@ -19172,7 +19125,7 @@ Selection: ${val}`,
|
|
|
19172
19125
|
global.gc();
|
|
19173
19126
|
await new Promise((resolve) => setImmediate(resolve));
|
|
19174
19127
|
}
|
|
19175
|
-
|
|
19128
|
+
lastGCTimeRef.current = Date.now();
|
|
19176
19129
|
}
|
|
19177
19130
|
continue;
|
|
19178
19131
|
}
|
|
@@ -19209,191 +19162,149 @@ Selection: ${val}`,
|
|
|
19209
19162
|
const beforeText = chunkText.substring(0, tagIndex);
|
|
19210
19163
|
const afterText = chunkText.substring(tagIndex);
|
|
19211
19164
|
if (beforeText) {
|
|
19212
|
-
if (!
|
|
19213
|
-
|
|
19214
|
-
const newMsg = { id: currentAgentId, role: "agent", text: beforeText, isStreaming: true };
|
|
19215
|
-
if (systemSettings.progressiveRendering) {
|
|
19216
|
-
typewriterQueueRef.current.push({ type: "create", msg: { ...newMsg, text: "" } });
|
|
19217
|
-
pushTokenText(currentAgentId, beforeText);
|
|
19218
|
-
} else {
|
|
19219
|
-
activeStreamMessagesRef.current = [...activeStreamMessagesRef.current, newMsg];
|
|
19220
|
-
}
|
|
19165
|
+
if (!activeStreamingMsgRef.current || activeStreamingMsgRef.current.role !== "agent") {
|
|
19166
|
+
activeStreamingMsgRef.current = { id: "agent-" + Date.now(), role: "agent", text: flattenString(beforeText), isStreaming: true };
|
|
19221
19167
|
} else {
|
|
19222
|
-
|
|
19223
|
-
pushTokenText(currentAgentId, beforeText);
|
|
19224
|
-
} else {
|
|
19225
|
-
activeStreamMessagesRef.current = activeStreamMessagesRef.current.map(
|
|
19226
|
-
(m) => m.id === currentAgentId ? { ...m, text: m.text + beforeText, isStreaming: true } : m
|
|
19227
|
-
);
|
|
19228
|
-
}
|
|
19229
|
-
}
|
|
19230
|
-
if (!systemSettings.progressiveRendering) {
|
|
19231
|
-
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19168
|
+
activeStreamingMsgRef.current.text = flattenString(activeStreamingMsgRef.current.text + beforeText);
|
|
19232
19169
|
}
|
|
19233
19170
|
}
|
|
19171
|
+
flushTypewriterNow();
|
|
19172
|
+
commitActiveStreamingMessage();
|
|
19234
19173
|
inThinkMode = true;
|
|
19235
19174
|
thinkConsumedInTurn = true;
|
|
19236
19175
|
let thinkStartText = afterText.replace(/<(think|thought)>/gi, "");
|
|
19237
19176
|
currentThinkId = "think-" + Date.now();
|
|
19238
|
-
|
|
19239
|
-
|
|
19240
|
-
typewriterQueueRef.current.push({ type: "create", msg: { ...thinkMsg, text: "", startTime: Date.now() } });
|
|
19241
|
-
if (thinkStartText) {
|
|
19242
|
-
pushTokenText(currentThinkId, thinkStartText);
|
|
19243
|
-
}
|
|
19244
|
-
} else {
|
|
19245
|
-
activeStreamMessagesRef.current = [...activeStreamMessagesRef.current, thinkMsg];
|
|
19246
|
-
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19247
|
-
}
|
|
19177
|
+
activeStreamingMsgRef.current = { id: currentThinkId, role: "think", text: "", isStreaming: true, startTime: Date.now() };
|
|
19178
|
+
appendStreamText(thinkStartText);
|
|
19248
19179
|
continue;
|
|
19249
19180
|
}
|
|
19250
|
-
if ((chunkLower.includes("</think>") || chunkLower.includes("</thought>")) &&
|
|
19181
|
+
if ((chunkLower.includes("</think>") || chunkLower.includes("</thought>")) && activeStreamingMsgRef.current?.role === "think") {
|
|
19251
19182
|
const parts = chunkText.split(/<\/(think|thought)>/gi);
|
|
19252
19183
|
const thinkPart = parts[0] || "";
|
|
19253
19184
|
const agentPart = parts.slice(2).join("").replace(/<\/?(think|thought)>/gi, "");
|
|
19185
|
+
activeStreamingMsgRef.current.text = flattenString(activeStreamingMsgRef.current.text + thinkPart);
|
|
19186
|
+
const startTime = activeStreamingMsgRef.current.startTime || Date.now();
|
|
19187
|
+
activeStreamingMsgRef.current.duration = Date.now() - startTime;
|
|
19188
|
+
flushTypewriterNow();
|
|
19189
|
+
commitActiveStreamingMessage();
|
|
19254
19190
|
inThinkMode = false;
|
|
19255
19191
|
currentAgentId = "agent-" + Date.now();
|
|
19256
|
-
|
|
19257
|
-
|
|
19258
|
-
pushTokenText(currentThinkId, thinkPart);
|
|
19259
|
-
}
|
|
19260
|
-
const startTime = parseInt(currentThinkId.split("-")[1]) || Date.now();
|
|
19261
|
-
const duration = Date.now() - startTime;
|
|
19262
|
-
typewriterQueueRef.current.push({ type: "finalize-think", id: currentThinkId, duration });
|
|
19263
|
-
const newAgentMsg = { id: currentAgentId, role: "agent", text: "", isStreaming: true };
|
|
19264
|
-
typewriterQueueRef.current.push({ type: "create", msg: newAgentMsg });
|
|
19265
|
-
if (agentPart) {
|
|
19266
|
-
pushTokenText(currentAgentId, agentPart);
|
|
19267
|
-
}
|
|
19268
|
-
} else {
|
|
19269
|
-
activeStreamMessagesRef.current = activeStreamMessagesRef.current.map((m) => {
|
|
19270
|
-
if (m.id === currentThinkId && typeof m.id === "string") {
|
|
19271
|
-
const startTime = m.startTime || parseInt(m.id.split("-")[1]) || Date.now();
|
|
19272
|
-
const duration = Date.now() - startTime;
|
|
19273
|
-
return { ...m, text: m.text + thinkPart, isStreaming: false, duration };
|
|
19274
|
-
}
|
|
19275
|
-
return m;
|
|
19276
|
-
});
|
|
19277
|
-
activeStreamMessagesRef.current = [...activeStreamMessagesRef.current, { id: currentAgentId, role: "agent", text: agentPart, isStreaming: true }];
|
|
19278
|
-
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19279
|
-
}
|
|
19192
|
+
activeStreamingMsgRef.current = { id: currentAgentId, role: "agent", text: "", isStreaming: true };
|
|
19193
|
+
appendStreamText(agentPart);
|
|
19280
19194
|
continue;
|
|
19281
19195
|
}
|
|
19282
|
-
if (inThinkMode &&
|
|
19283
|
-
|
|
19284
|
-
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
|
|
19288
|
-
|
|
19289
|
-
|
|
19290
|
-
|
|
19291
|
-
|
|
19292
|
-
|
|
19293
|
-
|
|
19294
|
-
|
|
19295
|
-
|
|
19296
|
-
|
|
19297
|
-
typewriterQueueRef.current.push({ type: "create", msg: { id: currentAgentId, role: "agent", text: "", isStreaming: true } });
|
|
19298
|
-
if (transitionContent) {
|
|
19299
|
-
pushTokenText(currentAgentId, transitionContent.replace(/<\/?(think|thought)>/gi, ""));
|
|
19300
|
-
}
|
|
19301
|
-
} else {
|
|
19302
|
-
pushTokenText(currentThinkId, chunkText);
|
|
19303
|
-
}
|
|
19196
|
+
if (inThinkMode && activeStreamingMsgRef.current?.role === "think") {
|
|
19197
|
+
const newText = activeStreamingMsgRef.current.text + chunkText;
|
|
19198
|
+
if (newText.toLowerCase().includes("</think>")) {
|
|
19199
|
+
const parts = newText.split(/<\/think>/gi);
|
|
19200
|
+
const thinkPart = parts[0] || "";
|
|
19201
|
+
const agentPart = parts.slice(1).join("</think>") || "";
|
|
19202
|
+
activeStreamingMsgRef.current.text = flattenString(thinkPart);
|
|
19203
|
+
const startTime = activeStreamingMsgRef.current.startTime || Date.now();
|
|
19204
|
+
activeStreamingMsgRef.current.duration = Date.now() - startTime;
|
|
19205
|
+
flushTypewriterNow();
|
|
19206
|
+
commitActiveStreamingMessage();
|
|
19207
|
+
inThinkMode = false;
|
|
19208
|
+
currentAgentId = "agent-" + Date.now();
|
|
19209
|
+
activeStreamingMsgRef.current = { id: currentAgentId, role: "agent", text: "", isStreaming: true };
|
|
19210
|
+
appendStreamText(agentPart.replace(/<\/?(think|thought)>/gi, ""));
|
|
19304
19211
|
} else {
|
|
19305
|
-
|
|
19306
|
-
if (m.id === currentThinkId) {
|
|
19307
|
-
const newText = m.text + chunkText;
|
|
19308
|
-
if (newText.toLowerCase().includes("</think>")) {
|
|
19309
|
-
transitioning = true;
|
|
19310
|
-
const parts = newText.split(/<\/think>/gi);
|
|
19311
|
-
transitionContent = parts.slice(1).join("</think>") || "";
|
|
19312
|
-
const startTime = m.startTime || parseInt(String(m.id).split("-")[1]) || Date.now();
|
|
19313
|
-
const duration = Date.now() - startTime;
|
|
19314
|
-
return { ...m, text: parts[0], isStreaming: false, duration };
|
|
19315
|
-
}
|
|
19316
|
-
return { ...m, text: newText, isStreaming: true };
|
|
19317
|
-
}
|
|
19318
|
-
return m;
|
|
19319
|
-
});
|
|
19320
|
-
if (transitioning) {
|
|
19321
|
-
inThinkMode = false;
|
|
19322
|
-
currentAgentId = "agent-" + Date.now();
|
|
19323
|
-
activeStreamMessagesRef.current = [...activeStreamMessagesRef.current, { id: currentAgentId, role: "agent", text: transitionContent.replace(/<\/?(think|thought)>/gi, ""), isStreaming: true }];
|
|
19324
|
-
}
|
|
19325
|
-
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19212
|
+
appendStreamText(chunkText);
|
|
19326
19213
|
}
|
|
19327
19214
|
} else if (!inThinkMode) {
|
|
19328
19215
|
const chunkLower2 = chunkText.toLowerCase();
|
|
19329
19216
|
if (!toolCallEncounteredInTurn && (chunkLower2.includes("tool:functions.") || chunkLower2.includes("agent:generalist."))) {
|
|
19330
19217
|
toolCallEncounteredInTurn = true;
|
|
19331
19218
|
}
|
|
19332
|
-
if (!
|
|
19219
|
+
if (!activeStreamingMsgRef.current || activeStreamingMsgRef.current.role !== "agent") {
|
|
19333
19220
|
currentAgentId = "agent-" + Date.now();
|
|
19334
|
-
|
|
19335
|
-
|
|
19336
|
-
typewriterQueueRef.current.push({ type: "create", msg: { ...newMsg, text: "" } });
|
|
19337
|
-
pushTokenText(currentAgentId, chunkText);
|
|
19338
|
-
} else {
|
|
19339
|
-
activeStreamMessagesRef.current = [...activeStreamMessagesRef.current, newMsg];
|
|
19340
|
-
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19341
|
-
}
|
|
19221
|
+
activeStreamingMsgRef.current = { id: currentAgentId, role: "agent", text: flattenString(chunkText), isStreaming: true };
|
|
19222
|
+
forceRender();
|
|
19342
19223
|
} else {
|
|
19343
|
-
|
|
19344
|
-
pushTokenText(currentAgentId, chunkText);
|
|
19345
|
-
} else {
|
|
19346
|
-
const next = [...activeStreamMessagesRef.current];
|
|
19347
|
-
for (let i = next.length - 1; i >= 0; i--) {
|
|
19348
|
-
if (next[i].id === currentAgentId) {
|
|
19349
|
-
next[i] = { ...next[i], text: next[i].text + chunkText, isStreaming: true };
|
|
19350
|
-
break;
|
|
19351
|
-
}
|
|
19352
|
-
}
|
|
19353
|
-
activeStreamMessagesRef.current = next;
|
|
19354
|
-
setActiveStreamMessages([...activeStreamMessagesRef.current]);
|
|
19355
|
-
}
|
|
19224
|
+
appendStreamText(chunkText);
|
|
19356
19225
|
}
|
|
19357
19226
|
}
|
|
19358
19227
|
}
|
|
19359
|
-
if (systemSettings.progressiveRendering) {
|
|
19360
|
-
streamFinishedRef.current = true;
|
|
19361
|
-
} else {
|
|
19362
|
-
await finalizeTurn(apiStart);
|
|
19363
|
-
}
|
|
19364
19228
|
const apiEnd = Date.now();
|
|
19365
19229
|
setSessionApiTime((prev) => prev + (apiEnd - apiStart));
|
|
19366
19230
|
} catch (err) {
|
|
19367
|
-
if (typewriterIntervalRef.current) {
|
|
19368
|
-
clearInterval(typewriterIntervalRef.current);
|
|
19369
|
-
typewriterIntervalRef.current = null;
|
|
19370
|
-
}
|
|
19371
|
-
typewriterQueueRef.current = [];
|
|
19372
19231
|
setMessages((prev) => {
|
|
19373
19232
|
setCompletedIndex(prev.length + 1);
|
|
19374
19233
|
return [...prev, { id: "error-" + Date.now(), role: "system", text: `\u274C ERROR: ${err.message}` }];
|
|
19375
19234
|
});
|
|
19376
19235
|
} finally {
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19381
|
-
|
|
19382
|
-
|
|
19383
|
-
|
|
19236
|
+
const totalDuration = Date.now() - apiStart;
|
|
19237
|
+
if (activeStreamingMsgRef.current) {
|
|
19238
|
+
activeStreamingMsgRef.current.workedDuration = totalDuration;
|
|
19239
|
+
}
|
|
19240
|
+
if (typewriterTickRef.current) {
|
|
19241
|
+
await awaitTypewriter();
|
|
19242
|
+
clearInterval(typewriterTickRef.current);
|
|
19243
|
+
typewriterTickRef.current = null;
|
|
19244
|
+
}
|
|
19245
|
+
setIsProcessing(false);
|
|
19246
|
+
setStatusText(null);
|
|
19247
|
+
setActiveTime(0);
|
|
19248
|
+
clearInterval(interval_for_timer);
|
|
19249
|
+
commitActiveStreamingMessage();
|
|
19250
|
+
if (didSignalTerminationRef.current) {
|
|
19251
|
+
appendCancelMessage();
|
|
19252
|
+
}
|
|
19253
|
+
clearBlocksCache();
|
|
19254
|
+
if (global.gc) {
|
|
19255
|
+
try {
|
|
19256
|
+
for (let i = 0; i < 3; i++) {
|
|
19257
|
+
global.gc();
|
|
19258
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
19259
|
+
}
|
|
19260
|
+
lastGCTimeRef.current = Date.now();
|
|
19261
|
+
} catch (e) {
|
|
19384
19262
|
}
|
|
19385
|
-
|
|
19386
|
-
|
|
19387
|
-
|
|
19388
|
-
|
|
19389
|
-
|
|
19390
|
-
|
|
19263
|
+
}
|
|
19264
|
+
if (!hasFiredJanitor) {
|
|
19265
|
+
if (process.stdout.isTTY) {
|
|
19266
|
+
process.stdout.write("\x1B]0;FluxFlow | Idle\x07");
|
|
19267
|
+
process.stdout.write("\x1B]633;P;TerminalTitle=FluxFlow | Idle\x07");
|
|
19268
|
+
}
|
|
19269
|
+
}
|
|
19270
|
+
if (queuedPromptRef.current) {
|
|
19271
|
+
setResolutionData(queuedPromptRef.current);
|
|
19272
|
+
setQueuedPrompt(null);
|
|
19273
|
+
const hintToResolve = queuedPromptRef.current;
|
|
19274
|
+
queuedPromptRef.current = null;
|
|
19275
|
+
setMessages((prev) => {
|
|
19276
|
+
const newMsgs = [...prev];
|
|
19277
|
+
const hintMsg = newMsgs.reverse().find((m) => m.text?.includes("[STEERING HINT: QUEUED]") || m.text?.includes("[QUESTION: QUEUED]"));
|
|
19278
|
+
if (hintMsg) {
|
|
19279
|
+
if (hintMsg.text.includes("[STEERING HINT: QUEUED]")) {
|
|
19280
|
+
hintMsg.text = hintMsg.text.replace("[STEERING HINT: QUEUED]", "[STEERING HINT: FINISHED_TURN]");
|
|
19281
|
+
} else if (hintMsg.text.includes("[QUESTION: QUEUED]")) {
|
|
19282
|
+
hintMsg.text = hintMsg.text.replace("[QUESTION: QUEUED]", "[QUESTION: FINISHED_TURN]");
|
|
19391
19283
|
}
|
|
19392
|
-
lastGCTime = Date.now();
|
|
19393
|
-
} catch (e) {
|
|
19394
19284
|
}
|
|
19395
|
-
|
|
19285
|
+
return newMsgs.reverse();
|
|
19286
|
+
});
|
|
19287
|
+
setActiveView("resolution");
|
|
19396
19288
|
}
|
|
19289
|
+
setMessages((prev) => {
|
|
19290
|
+
const totalDuration2 = Date.now() - apiStart;
|
|
19291
|
+
let foundLastAgent = false;
|
|
19292
|
+
const newMsgs = [...prev].reverse().map((m) => {
|
|
19293
|
+
let updated = m.isStreaming ? { ...m, isStreaming: false } : m;
|
|
19294
|
+
if (updated.text) {
|
|
19295
|
+
updated.text = (" " + updated.text).slice(1);
|
|
19296
|
+
}
|
|
19297
|
+
if (!foundLastAgent && updated.role === "agent") {
|
|
19298
|
+
foundLastAgent = true;
|
|
19299
|
+
updated = { ...updated, workedDuration: totalDuration2 };
|
|
19300
|
+
}
|
|
19301
|
+
return updated;
|
|
19302
|
+
}).reverse();
|
|
19303
|
+
const historyToSave = newMsgs.filter((m) => !String(m.id).startsWith("welcome") && (!m.isMeta || m.text && m.text.includes("Request Cancelled")));
|
|
19304
|
+
saveChat(chatId, null, historyToSave);
|
|
19305
|
+
setCompletedIndex(newMsgs.length);
|
|
19306
|
+
return newMsgs;
|
|
19307
|
+
});
|
|
19397
19308
|
}
|
|
19398
19309
|
};
|
|
19399
19310
|
streamChat();
|
|
@@ -19627,7 +19538,7 @@ Selection: ${val}`,
|
|
|
19627
19538
|
} else if (selectedProvider === "DeepSeek") {
|
|
19628
19539
|
defaultModel = "deepseek-v4-flash";
|
|
19629
19540
|
} else if (selectedProvider === "NVIDIA") {
|
|
19630
|
-
defaultModel = "
|
|
19541
|
+
defaultModel = "deepseek-ai/deepseek-v4-flash";
|
|
19631
19542
|
}
|
|
19632
19543
|
setActiveModel(defaultModel);
|
|
19633
19544
|
const targetTier = (quotas.providerTiers || {})[selectedProvider] || "Free";
|
|
@@ -19955,7 +19866,7 @@ Selection: ${val}`,
|
|
|
19955
19866
|
} else if (prov === "DeepSeek") {
|
|
19956
19867
|
defaultModel = "deepseek-v4-flash";
|
|
19957
19868
|
} else if (prov === "NVIDIA") {
|
|
19958
|
-
defaultModel = "
|
|
19869
|
+
defaultModel = "moonshotai/kimi-k2.6";
|
|
19959
19870
|
}
|
|
19960
19871
|
setActiveModel(defaultModel);
|
|
19961
19872
|
const targetTier = (quotas.providerTiers || {})[prov] || "Free";
|
|
@@ -20800,15 +20711,15 @@ var init_app = __esm({
|
|
|
20800
20711
|
}
|
|
20801
20712
|
}
|
|
20802
20713
|
if (endIdx !== -1) {
|
|
20803
|
-
const beforeText = text.substring(lastIdx, match.index);
|
|
20714
|
+
const beforeText = flattenString(text.substring(lastIdx, match.index));
|
|
20804
20715
|
if (beforeText.trim()) {
|
|
20805
20716
|
blocks.push({ type: "output", content: beforeText });
|
|
20806
20717
|
}
|
|
20807
|
-
const finalArgsText = text.substring(startIdx + 1, closingParenIdx);
|
|
20718
|
+
const finalArgsText = flattenString(text.substring(startIdx + 1, closingParenIdx));
|
|
20808
20719
|
blocks.push({
|
|
20809
20720
|
type: "tool",
|
|
20810
|
-
toolName: toolName.trim(),
|
|
20811
|
-
args: finalArgsText.trim()
|
|
20721
|
+
toolName: flattenString(toolName.trim()),
|
|
20722
|
+
args: flattenString(finalArgsText.trim())
|
|
20812
20723
|
});
|
|
20813
20724
|
lastIdx = endIdx + 1;
|
|
20814
20725
|
toolRegex.lastIndex = lastIdx;
|
|
@@ -20817,7 +20728,7 @@ var init_app = __esm({
|
|
|
20817
20728
|
}
|
|
20818
20729
|
}
|
|
20819
20730
|
if (lastIdx < text.length) {
|
|
20820
|
-
const remainingText = text.substring(lastIdx);
|
|
20731
|
+
const remainingText = flattenString(text.substring(lastIdx));
|
|
20821
20732
|
if (remainingText.trim()) {
|
|
20822
20733
|
blocks.push({ type: "output", content: remainingText });
|
|
20823
20734
|
}
|
|
@@ -20829,14 +20740,16 @@ var init_app = __esm({
|
|
|
20829
20740
|
let lastScanTime = 0;
|
|
20830
20741
|
return (dir) => {
|
|
20831
20742
|
const now = Date.now();
|
|
20832
|
-
if (cachedFiles && now - lastScanTime <
|
|
20743
|
+
if (cachedFiles && now - lastScanTime < 1e4) {
|
|
20833
20744
|
return cachedFiles;
|
|
20834
20745
|
}
|
|
20835
20746
|
const fileList = [];
|
|
20836
20747
|
const scan = (currentDir) => {
|
|
20748
|
+
if (fileList.length >= 2e3) return;
|
|
20837
20749
|
try {
|
|
20838
20750
|
const files = fs24.readdirSync(currentDir);
|
|
20839
20751
|
for (const file of files) {
|
|
20752
|
+
if (fileList.length >= 2e3) return;
|
|
20840
20753
|
if (["node_modules", ".git", ".gemini", "dist", "build", ".next", ".cache", "out"].includes(file)) {
|
|
20841
20754
|
continue;
|
|
20842
20755
|
}
|
|
@@ -20846,8 +20759,8 @@ var init_app = __esm({
|
|
|
20846
20759
|
scan(filePath);
|
|
20847
20760
|
} else {
|
|
20848
20761
|
fileList.push({
|
|
20849
|
-
name: file,
|
|
20850
|
-
relativePath: path22.relative(process.cwd(), filePath)
|
|
20762
|
+
name: flattenString(file),
|
|
20763
|
+
relativePath: flattenString(path22.relative(process.cwd(), filePath))
|
|
20851
20764
|
});
|
|
20852
20765
|
}
|
|
20853
20766
|
}
|