fluxflow-cli 2.13.5 → 2.14.1
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 +1074 -666
- package/package.json +2 -2
package/dist/fluxflow.js
CHANGED
|
@@ -40,6 +40,7 @@ __export(paths_exports, {
|
|
|
40
40
|
CONTEXT_FILE: () => CONTEXT_FILE,
|
|
41
41
|
DATA_DIR: () => DATA_DIR,
|
|
42
42
|
FLUXFLOW_DIR: () => FLUXFLOW_DIR,
|
|
43
|
+
HISTORY_DIR: () => HISTORY_DIR,
|
|
43
44
|
HISTORY_FILE: () => HISTORY_FILE,
|
|
44
45
|
LEDGER_FILE: () => LEDGER_FILE,
|
|
45
46
|
LOGS_DIR: () => LOGS_DIR,
|
|
@@ -56,7 +57,7 @@ import os from "os";
|
|
|
56
57
|
import path from "path";
|
|
57
58
|
import fs from "fs";
|
|
58
59
|
import crypto from "crypto";
|
|
59
|
-
var FLUXFLOW_DIR, SETTINGS_FILE, externalDir, DATA_DIR, LOGS_DIR, SECRET_DIR, HISTORY_FILE, USAGE_FILE, MEMORIES_FILE, TEMP_MEM_FILE, TEMP_MEM_CHAT_FILE, BACKUPS_DIR, LEDGER_FILE, ACTIVE_TX_FILE, PATHS_FILE, CONTEXT_FILE, PARSER_DIR;
|
|
60
|
+
var FLUXFLOW_DIR, SETTINGS_FILE, externalDir, DATA_DIR, LOGS_DIR, SECRET_DIR, HISTORY_FILE, HISTORY_DIR, USAGE_FILE, MEMORIES_FILE, TEMP_MEM_FILE, TEMP_MEM_CHAT_FILE, BACKUPS_DIR, LEDGER_FILE, ACTIVE_TX_FILE, PATHS_FILE, CONTEXT_FILE, PARSER_DIR;
|
|
60
61
|
var init_paths = __esm({
|
|
61
62
|
"src/utils/paths.js"() {
|
|
62
63
|
FLUXFLOW_DIR = path.join(os.homedir(), ".fluxflow");
|
|
@@ -93,6 +94,7 @@ var init_paths = __esm({
|
|
|
93
94
|
LOGS_DIR = path.join(DATA_DIR, "logs");
|
|
94
95
|
SECRET_DIR = path.join(DATA_DIR, "secret");
|
|
95
96
|
HISTORY_FILE = path.join(SECRET_DIR, "history.json");
|
|
97
|
+
HISTORY_DIR = path.join(SECRET_DIR, "history");
|
|
96
98
|
USAGE_FILE = path.join(FLUXFLOW_DIR, "usage.json");
|
|
97
99
|
MEMORIES_FILE = path.join(SECRET_DIR, "memories.json");
|
|
98
100
|
TEMP_MEM_FILE = path.join(SECRET_DIR, "memory-temp.json");
|
|
@@ -114,7 +116,7 @@ var XOR_KEY, bypass, xorTransform, AES_ALGORITHM, AES_KEY, encryptAes, decryptAe
|
|
|
114
116
|
var init_crypto = __esm({
|
|
115
117
|
"src/utils/crypto.js"() {
|
|
116
118
|
XOR_KEY = 66;
|
|
117
|
-
bypass =
|
|
119
|
+
bypass = true;
|
|
118
120
|
xorTransform = (data) => {
|
|
119
121
|
const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
120
122
|
const result = Buffer.alloc(buffer.length);
|
|
@@ -2089,7 +2091,7 @@ var init_build = __esm({
|
|
|
2089
2091
|
|
|
2090
2092
|
// src/utils/text.js
|
|
2091
2093
|
import os2 from "os";
|
|
2092
|
-
var wrapText, formatTokens, truncatePath, parsePatchPairs, applyPatches, generateHighFidelityDiff, parseMessageToBlocks, TOOL_LABELS, cleanSignals;
|
|
2094
|
+
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_SYSTEM, REGEX_THINK, REGEX_ANSWER, REGEX_TOOL_RES, REGEX_SUCCESS_ERROR, REGEX_TURN_1, REGEX_END, REGEX_TURN_2, REGEX_TURN_3, REGEX_OPEN_BRACKET, REGEX_RESPONDED, REGEX_PROMPTED, REGEX_ARROWS, REGEX_ARROWS_L, REGEX_ARROWS_U, REGEX_ARROWS_D, REGEX_ARROWS_LR, REGEX_TERMINAL, REGEX_TOOLS, cleanSignals, clearBlocksCache;
|
|
2093
2095
|
var init_text = __esm({
|
|
2094
2096
|
"src/utils/text.js"() {
|
|
2095
2097
|
init_paths();
|
|
@@ -2433,223 +2435,348 @@ var init_text = __esm({
|
|
|
2433
2435
|
diffText += `[DIFF_END]`;
|
|
2434
2436
|
return diffText;
|
|
2435
2437
|
};
|
|
2438
|
+
parseLineInfo = (l) => {
|
|
2439
|
+
if (!l) return null;
|
|
2440
|
+
const clean = l.replace("[UI_CONTEXT]", "").replace(/\r/g, "");
|
|
2441
|
+
const isR = clean.startsWith("-");
|
|
2442
|
+
const isA = clean.startsWith("+");
|
|
2443
|
+
let rest = isR || isA ? clean.substring(1) : clean;
|
|
2444
|
+
rest = rest.trim();
|
|
2445
|
+
const splitIdx = rest.indexOf("|");
|
|
2446
|
+
const num = splitIdx !== -1 ? rest.substring(0, splitIdx).trim() : "";
|
|
2447
|
+
const content = splitIdx !== -1 ? rest.substring(splitIdx + 1) : rest;
|
|
2448
|
+
return { isR, isA, num, content };
|
|
2449
|
+
};
|
|
2450
|
+
getSimilarity = (s1, s2) => {
|
|
2451
|
+
if (!s1 && !s2) return 1;
|
|
2452
|
+
if (!s1 || !s2) return 0;
|
|
2453
|
+
const l1 = s1.length;
|
|
2454
|
+
const l2 = s2.length;
|
|
2455
|
+
const dp = Array.from({ length: l1 + 1 }, () => Array(l2 + 1).fill(0));
|
|
2456
|
+
for (let i = 0; i <= l1; i++) dp[i][0] = i;
|
|
2457
|
+
for (let j = 0; j <= l2; j++) dp[0][j] = j;
|
|
2458
|
+
for (let i = 1; i <= l1; i++) {
|
|
2459
|
+
for (let j = 1; j <= l2; j++) {
|
|
2460
|
+
if (s1[i - 1] === s2[j - 1]) {
|
|
2461
|
+
dp[i][j] = dp[i - 1][j - 1];
|
|
2462
|
+
} else {
|
|
2463
|
+
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1;
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
const maxLen = Math.max(l1, l2);
|
|
2468
|
+
if (maxLen === 0) return 1;
|
|
2469
|
+
return 1 - dp[l1][l2] / maxLen;
|
|
2470
|
+
};
|
|
2471
|
+
alignChangeGroup = (group) => {
|
|
2472
|
+
const removals = [];
|
|
2473
|
+
const additions = [];
|
|
2474
|
+
group.forEach((item, index) => {
|
|
2475
|
+
if (item.parsed.isR) {
|
|
2476
|
+
removals.push({ index, content: item.parsed.content });
|
|
2477
|
+
} else if (item.parsed.isA) {
|
|
2478
|
+
additions.push({ index, content: item.parsed.content });
|
|
2479
|
+
}
|
|
2480
|
+
});
|
|
2481
|
+
const N = removals.length;
|
|
2482
|
+
const M = additions.length;
|
|
2483
|
+
if (N === 0 || M === 0) return;
|
|
2484
|
+
const dp = Array.from({ length: N + 1 }, () => Array(M + 1).fill(0));
|
|
2485
|
+
const choices = Array.from({ length: N + 1 }, () => Array(M + 1).fill(""));
|
|
2486
|
+
for (let i2 = 1; i2 <= N; i2++) choices[i2][0] = "up";
|
|
2487
|
+
for (let j2 = 1; j2 <= M; j2++) choices[0][j2] = "left";
|
|
2488
|
+
const simMatrix = Array.from({ length: N }, () => Array(M).fill(0));
|
|
2489
|
+
for (let i2 = 0; i2 < N; i2++) {
|
|
2490
|
+
for (let j2 = 0; j2 < M; j2++) {
|
|
2491
|
+
simMatrix[i2][j2] = getSimilarity(removals[i2].content.trim(), additions[j2].content.trim());
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
for (let i2 = 1; i2 <= N; i2++) {
|
|
2495
|
+
for (let j2 = 1; j2 <= M; j2++) {
|
|
2496
|
+
const matchScore = simMatrix[i2 - 1][j2 - 1];
|
|
2497
|
+
const score = matchScore >= 0.2 ? matchScore : -10;
|
|
2498
|
+
const diag = dp[i2 - 1][j2 - 1] + score;
|
|
2499
|
+
const up = dp[i2 - 1][j2];
|
|
2500
|
+
const left = dp[i2][j2 - 1];
|
|
2501
|
+
if (diag >= up && diag >= left) {
|
|
2502
|
+
dp[i2][j2] = diag;
|
|
2503
|
+
choices[i2][j2] = "diag";
|
|
2504
|
+
} else if (up >= left) {
|
|
2505
|
+
dp[i2][j2] = up;
|
|
2506
|
+
choices[i2][j2] = "up";
|
|
2507
|
+
} else {
|
|
2508
|
+
dp[i2][j2] = left;
|
|
2509
|
+
choices[i2][j2] = "left";
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
let i = N;
|
|
2514
|
+
let j = M;
|
|
2515
|
+
while (i > 0 || j > 0) {
|
|
2516
|
+
if (choices[i][j] === "diag") {
|
|
2517
|
+
const matchScore = simMatrix[i - 1][j - 1];
|
|
2518
|
+
if (matchScore >= 0.2) {
|
|
2519
|
+
const rIdx = removals[i - 1].index;
|
|
2520
|
+
const aIdx = additions[j - 1].index;
|
|
2521
|
+
group[rIdx].pairContent = group[aIdx].parsed.content;
|
|
2522
|
+
group[aIdx].pairContent = group[rIdx].parsed.content;
|
|
2523
|
+
}
|
|
2524
|
+
i--;
|
|
2525
|
+
j--;
|
|
2526
|
+
} else if (choices[i][j] === "up") {
|
|
2527
|
+
i--;
|
|
2528
|
+
} else {
|
|
2529
|
+
j--;
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
};
|
|
2533
|
+
blocksCache = /* @__PURE__ */ new Map();
|
|
2534
|
+
streamingBlocksCache = /* @__PURE__ */ new Map();
|
|
2535
|
+
MAX_CACHE_SIZE = 200;
|
|
2536
|
+
CHUNK_SIZE = 6;
|
|
2537
|
+
indexBlockIntoMap = (b, map) => {
|
|
2538
|
+
map.set(b.key, b);
|
|
2539
|
+
if (b.type === "chunk" && b.blocks) b.blocks.forEach((sub) => indexBlockIntoMap(sub, map));
|
|
2540
|
+
};
|
|
2436
2541
|
parseMessageToBlocks = (msg, columns) => {
|
|
2542
|
+
if (!msg) return { completed: [], active: [] };
|
|
2543
|
+
const cacheKey = `${msg.id}-${msg.text?.length || 0}-${columns}-${msg.isStreaming}`;
|
|
2544
|
+
if (!msg.isStreaming && blocksCache.has(cacheKey)) {
|
|
2545
|
+
return blocksCache.get(cacheKey);
|
|
2546
|
+
}
|
|
2437
2547
|
const text = cleanSignals(msg.text || "");
|
|
2548
|
+
const streamCacheKey = `${msg.id}-${columns}`;
|
|
2549
|
+
let cachedBlocks = /* @__PURE__ */ new Map();
|
|
2550
|
+
if (msg.isStreaming) {
|
|
2551
|
+
const cached = streamingBlocksCache.get(streamCacheKey);
|
|
2552
|
+
if (cached && text.startsWith(cached.text)) {
|
|
2553
|
+
cachedBlocks = cached.blocksMap;
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
const getBlock = (key, type, textContent, extra = {}) => {
|
|
2557
|
+
const existing = cachedBlocks.get(key);
|
|
2558
|
+
if (existing && existing.text === textContent && existing.type === type && !!existing.isActiveBlock === !!extra.isActiveBlock && !!existing.isStreaming === !!extra.isStreaming && existing.pairContent === extra.pairContent) {
|
|
2559
|
+
return existing;
|
|
2560
|
+
}
|
|
2561
|
+
return {
|
|
2562
|
+
key,
|
|
2563
|
+
msg,
|
|
2564
|
+
type,
|
|
2565
|
+
text: textContent,
|
|
2566
|
+
...extra
|
|
2567
|
+
};
|
|
2568
|
+
};
|
|
2438
2569
|
if (text.includes("- Content Preview:")) {
|
|
2439
2570
|
const mainParts = text.split("- Content Preview:");
|
|
2440
|
-
const headerText = mainParts[0] || "";
|
|
2441
2571
|
const contentPart = mainParts[1] || "";
|
|
2442
2572
|
const footerMarker = "[SYSTEM] Check the content preview for verification [/SYSTEM]";
|
|
2443
|
-
const
|
|
2444
|
-
const content = contentAndFooter[0]?.trim() || "";
|
|
2445
|
-
const footer = contentAndFooter[1] ? `${footerMarker}${contentAndFooter[1]}` : "";
|
|
2573
|
+
const content = contentPart.split(footerMarker)[0]?.trim() || "";
|
|
2446
2574
|
const codeLines = content.split("\n").map((l) => l.replace(/\r$/, ""));
|
|
2447
2575
|
const gutterWidth = String(codeLines.length).length;
|
|
2448
2576
|
const completedBlocks2 = [];
|
|
2449
2577
|
let activeBlock2 = null;
|
|
2578
|
+
let writeChunk = [];
|
|
2579
|
+
const flushWrite = () => {
|
|
2580
|
+
if (!writeChunk.length) return;
|
|
2581
|
+
const batch = writeChunk;
|
|
2582
|
+
writeChunk = [];
|
|
2583
|
+
completedBlocks2.push(batch.length === 1 ? batch[0] : {
|
|
2584
|
+
key: `${batch[0].key}-chunk`,
|
|
2585
|
+
msg,
|
|
2586
|
+
type: "chunk",
|
|
2587
|
+
blocks: batch
|
|
2588
|
+
});
|
|
2589
|
+
};
|
|
2450
2590
|
codeLines.forEach((line, idx) => {
|
|
2451
2591
|
const isLast = idx === codeLines.length - 1;
|
|
2452
|
-
const block = {
|
|
2453
|
-
key: `${msg.id || Date.now()}-write-line-${idx}`,
|
|
2454
|
-
msg,
|
|
2455
|
-
type: "write-line",
|
|
2456
|
-
text: line,
|
|
2592
|
+
const block = getBlock(`${msg.id || Date.now()}-write-line-${idx}`, "write-line", line, {
|
|
2457
2593
|
gutterWidth,
|
|
2458
2594
|
lineNum: idx + 1,
|
|
2459
2595
|
isFirstLine: idx === 0,
|
|
2460
2596
|
isLastLine: isLast
|
|
2461
|
-
};
|
|
2597
|
+
});
|
|
2462
2598
|
if (isLast && msg.isStreaming) {
|
|
2599
|
+
flushWrite();
|
|
2463
2600
|
activeBlock2 = block;
|
|
2464
2601
|
} else {
|
|
2465
|
-
|
|
2602
|
+
writeChunk.push(block);
|
|
2603
|
+
if (writeChunk.length >= CHUNK_SIZE) flushWrite();
|
|
2466
2604
|
}
|
|
2467
2605
|
});
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
active: activeBlock2 ? [activeBlock2] : []
|
|
2471
|
-
};
|
|
2606
|
+
flushWrite();
|
|
2607
|
+
return { completed: completedBlocks2, active: activeBlock2 ? [activeBlock2] : [] };
|
|
2472
2608
|
}
|
|
2473
2609
|
if (text.includes("[DIFF_START]")) {
|
|
2474
2610
|
const match = text.match(/\[DIFF_START\]([\s\S]*?)(?:\[DIFF_END\]|$)/);
|
|
2475
2611
|
const diffBody = match ? match[1].trim() : "";
|
|
2476
2612
|
const diffLines = diffBody.split("\n").map((l) => l.replace(/\r$/, ""));
|
|
2613
|
+
const parsedLines = diffLines.map((line) => ({ line, parsed: parseLineInfo(line), pairContent: null }));
|
|
2614
|
+
let currentGroup = [];
|
|
2615
|
+
for (let i = 0; i < parsedLines.length; i++) {
|
|
2616
|
+
const item = parsedLines[i];
|
|
2617
|
+
if (item.parsed && (item.parsed.isR || item.parsed.isA)) {
|
|
2618
|
+
currentGroup.push(item);
|
|
2619
|
+
} else {
|
|
2620
|
+
if (currentGroup.length > 0) {
|
|
2621
|
+
alignChangeGroup(currentGroup);
|
|
2622
|
+
currentGroup = [];
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
if (currentGroup.length > 0) alignChangeGroup(currentGroup);
|
|
2477
2627
|
const completedBlocks2 = [];
|
|
2478
2628
|
let activeBlock2 = null;
|
|
2629
|
+
let diffChunk = [];
|
|
2630
|
+
const flushDiff = () => {
|
|
2631
|
+
if (!diffChunk.length) return;
|
|
2632
|
+
const batch = diffChunk;
|
|
2633
|
+
diffChunk = [];
|
|
2634
|
+
completedBlocks2.push(batch.length === 1 ? batch[0] : {
|
|
2635
|
+
key: `${batch[0].key}-chunk`,
|
|
2636
|
+
msg,
|
|
2637
|
+
type: "chunk",
|
|
2638
|
+
blocks: batch
|
|
2639
|
+
});
|
|
2640
|
+
};
|
|
2479
2641
|
diffLines.forEach((line, i) => {
|
|
2480
2642
|
const isLast = i === diffLines.length - 1;
|
|
2481
|
-
const block = {
|
|
2482
|
-
key: `${msg.id || Date.now()}-diff-${i}`,
|
|
2483
|
-
msg,
|
|
2484
|
-
type: "diff-line",
|
|
2485
|
-
text: line,
|
|
2643
|
+
const block = getBlock(`${msg.id || Date.now()}-diff-${i}`, "diff-line", line, {
|
|
2486
2644
|
isFirstLine: i === 0,
|
|
2487
|
-
isLastLine: isLast
|
|
2488
|
-
|
|
2645
|
+
isLastLine: isLast,
|
|
2646
|
+
pairContent: parsedLines[i].pairContent
|
|
2647
|
+
});
|
|
2489
2648
|
if (isLast && msg.isStreaming) {
|
|
2649
|
+
flushDiff();
|
|
2490
2650
|
activeBlock2 = block;
|
|
2491
2651
|
} else {
|
|
2492
|
-
|
|
2652
|
+
diffChunk.push(block);
|
|
2653
|
+
if (diffChunk.length >= CHUNK_SIZE) flushDiff();
|
|
2493
2654
|
}
|
|
2494
2655
|
});
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
active: activeBlock2 ? [activeBlock2] : []
|
|
2498
|
-
};
|
|
2656
|
+
flushDiff();
|
|
2657
|
+
return { completed: completedBlocks2, active: activeBlock2 ? [activeBlock2] : [] };
|
|
2499
2658
|
}
|
|
2500
2659
|
if (msg.role === "system" || msg.isLogo || msg.isHelpRecord || msg.isTerminalRecord || msg.isHomeWarning || msg.isImageStats || msg.isAskRecord || msg.isAboutRecord || msg.isUpdateNotification || msg.role === "user") {
|
|
2501
2660
|
return {
|
|
2502
|
-
completed: [{
|
|
2503
|
-
key: `${msg.id || Date.now()}-full`,
|
|
2504
|
-
msg,
|
|
2505
|
-
type: "full-message",
|
|
2506
|
-
text
|
|
2507
|
-
}],
|
|
2661
|
+
completed: [getBlock(`${msg.id || Date.now()}-full`, "full-message", text)],
|
|
2508
2662
|
active: []
|
|
2509
2663
|
};
|
|
2510
2664
|
}
|
|
2511
2665
|
const completedBlocks = [];
|
|
2512
2666
|
let activeBlock = null;
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2667
|
+
let pendingChunk = [];
|
|
2668
|
+
let pendingChunkType = null;
|
|
2669
|
+
const flushPending = () => {
|
|
2670
|
+
if (!pendingChunk.length) return;
|
|
2671
|
+
const batch = pendingChunk;
|
|
2672
|
+
pendingChunk = [];
|
|
2673
|
+
pendingChunkType = null;
|
|
2674
|
+
completedBlocks.push(batch.length === 1 ? batch[0] : {
|
|
2675
|
+
key: `${msg.id || "x"}-chunk-${batch[0].key}`,
|
|
2516
2676
|
msg,
|
|
2517
|
-
type: "
|
|
2518
|
-
|
|
2677
|
+
type: "chunk",
|
|
2678
|
+
blocks: batch
|
|
2519
2679
|
});
|
|
2680
|
+
};
|
|
2681
|
+
const enqueue = (block) => {
|
|
2682
|
+
if (pendingChunkType !== null && pendingChunkType !== block.type) flushPending();
|
|
2683
|
+
pendingChunk.push(block);
|
|
2684
|
+
pendingChunkType = block.type;
|
|
2685
|
+
if (pendingChunk.length >= CHUNK_SIZE) flushPending();
|
|
2686
|
+
};
|
|
2687
|
+
if (msg.role === "think") {
|
|
2688
|
+
completedBlocks.push(getBlock(`${msg.id}-header`, "think-header", ""));
|
|
2520
2689
|
const lines = text.split("\n");
|
|
2521
2690
|
lines.forEach((line, idx) => {
|
|
2522
|
-
|
|
2523
|
-
const block = {
|
|
2524
|
-
key: `${msg.id}-${idx}`,
|
|
2525
|
-
msg,
|
|
2526
|
-
type: "think-line",
|
|
2527
|
-
text: line
|
|
2528
|
-
};
|
|
2529
|
-
if (isLast && msg.isStreaming) {
|
|
2530
|
-
block.isActiveBlock = true;
|
|
2531
|
-
activeBlock = block;
|
|
2532
|
-
} else {
|
|
2533
|
-
completedBlocks.push(block);
|
|
2534
|
-
}
|
|
2691
|
+
enqueue(getBlock(`${msg.id}-${idx}`, "think-line", line, {}));
|
|
2535
2692
|
});
|
|
2536
2693
|
if (!msg.isStreaming) {
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
msg,
|
|
2540
|
-
type: "think-footer-padding",
|
|
2541
|
-
text: ""
|
|
2542
|
-
});
|
|
2694
|
+
flushPending();
|
|
2695
|
+
completedBlocks.push({ key: `${msg.id}-footer-padding`, msg, type: "think-footer-padding", text: "" });
|
|
2543
2696
|
}
|
|
2544
2697
|
} else {
|
|
2545
2698
|
const lines = text.split("\n");
|
|
2546
2699
|
let inTable = false;
|
|
2547
2700
|
let tableLines = [];
|
|
2548
2701
|
let inCodeBlock = false;
|
|
2549
|
-
let
|
|
2702
|
+
let codeLineNum = 0;
|
|
2703
|
+
let codeStartIdx = 0;
|
|
2550
2704
|
lines.forEach((line, idx) => {
|
|
2551
2705
|
const isLast = idx === lines.length - 1;
|
|
2552
2706
|
const isTableRow = line.trim().startsWith("|");
|
|
2553
2707
|
const isCodeBlockMarker = line.trim().startsWith("```");
|
|
2554
2708
|
if (inCodeBlock) {
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
msg,
|
|
2562
|
-
type: "agent-line",
|
|
2563
|
-
text: codeLines.join("\n")
|
|
2564
|
-
};
|
|
2565
|
-
if (isLast && msg.isStreaming && inCodeBlock) {
|
|
2566
|
-
block.isActiveBlock = true;
|
|
2567
|
-
activeBlock = block;
|
|
2568
|
-
} else {
|
|
2569
|
-
completedBlocks.push(block);
|
|
2570
|
-
}
|
|
2571
|
-
codeLines = [];
|
|
2572
|
-
}
|
|
2709
|
+
if (isCodeBlockMarker) {
|
|
2710
|
+
inCodeBlock = false;
|
|
2711
|
+
enqueue(getBlock(`${msg.id}-code-close-${codeStartIdx}`, "code-fence-close", "", {}));
|
|
2712
|
+
} else {
|
|
2713
|
+
codeLineNum++;
|
|
2714
|
+
enqueue(getBlock(`${msg.id}-code-line-${idx}`, "code-line", line, { lineNum: codeLineNum }));
|
|
2573
2715
|
}
|
|
2574
2716
|
} else if (isCodeBlockMarker) {
|
|
2575
2717
|
inCodeBlock = true;
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
msg,
|
|
2581
|
-
type: "agent-line",
|
|
2582
|
-
text: codeLines.join("\n")
|
|
2583
|
-
};
|
|
2584
|
-
if (msg.isStreaming) {
|
|
2585
|
-
block.isActiveBlock = true;
|
|
2586
|
-
activeBlock = block;
|
|
2587
|
-
} else {
|
|
2588
|
-
completedBlocks.push(block);
|
|
2589
|
-
}
|
|
2590
|
-
}
|
|
2718
|
+
codeStartIdx = idx;
|
|
2719
|
+
codeLineNum = 0;
|
|
2720
|
+
const lang = line.trim().replace(/^```/, "").trim();
|
|
2721
|
+
enqueue(getBlock(`${msg.id}-code-open-${idx}`, "code-fence-open", lang, {}));
|
|
2591
2722
|
} else if (isTableRow) {
|
|
2592
2723
|
inTable = true;
|
|
2593
2724
|
tableLines.push(line);
|
|
2594
2725
|
if (isLast) {
|
|
2726
|
+
flushPending();
|
|
2595
2727
|
if (msg.isStreaming) {
|
|
2596
|
-
activeBlock = {
|
|
2597
|
-
key: `${msg.id}-table-${idx}`,
|
|
2598
|
-
msg,
|
|
2599
|
-
type: "table",
|
|
2600
|
-
text: tableLines.join("\n"),
|
|
2601
|
-
isStreaming: true,
|
|
2602
|
-
isActiveBlock: true
|
|
2603
|
-
};
|
|
2728
|
+
activeBlock = getBlock(`${msg.id}-table-${idx}`, "table", tableLines.join("\n"), { isStreaming: true });
|
|
2604
2729
|
} else {
|
|
2605
|
-
completedBlocks.push({
|
|
2606
|
-
key: `${msg.id}-table-${idx}`,
|
|
2607
|
-
msg,
|
|
2608
|
-
type: "table",
|
|
2609
|
-
text: tableLines.join("\n"),
|
|
2610
|
-
isStreaming: false
|
|
2611
|
-
});
|
|
2730
|
+
completedBlocks.push(getBlock(`${msg.id}-table-${idx}`, "table", tableLines.join("\n"), { isStreaming: false }));
|
|
2612
2731
|
}
|
|
2613
2732
|
}
|
|
2614
2733
|
} else {
|
|
2615
2734
|
if (inTable) {
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
msg,
|
|
2619
|
-
type: "table",
|
|
2620
|
-
text: tableLines.join("\n"),
|
|
2621
|
-
isStreaming: false
|
|
2622
|
-
});
|
|
2735
|
+
flushPending();
|
|
2736
|
+
completedBlocks.push(getBlock(`${msg.id}-table-${idx}`, "table", tableLines.join("\n"), { isStreaming: false }));
|
|
2623
2737
|
inTable = false;
|
|
2624
2738
|
tableLines = [];
|
|
2625
2739
|
}
|
|
2626
|
-
|
|
2627
|
-
key: `${msg.id}-${idx}`,
|
|
2628
|
-
msg,
|
|
2629
|
-
type: "agent-line",
|
|
2630
|
-
text: line
|
|
2631
|
-
};
|
|
2632
|
-
if (isLast && msg.isStreaming) {
|
|
2633
|
-
block.isActiveBlock = true;
|
|
2634
|
-
activeBlock = block;
|
|
2635
|
-
} else {
|
|
2636
|
-
completedBlocks.push(block);
|
|
2637
|
-
}
|
|
2740
|
+
enqueue(getBlock(`${msg.id}-${idx}`, "agent-line", line, {}));
|
|
2638
2741
|
}
|
|
2639
2742
|
});
|
|
2640
2743
|
if (!msg.isStreaming && msg.workedDuration) {
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
msg,
|
|
2644
|
-
type: "worked-duration",
|
|
2645
|
-
text: ""
|
|
2646
|
-
});
|
|
2744
|
+
flushPending();
|
|
2745
|
+
completedBlocks.push(getBlock(`${msg.id}-worked-duration`, "worked-duration", ""));
|
|
2647
2746
|
}
|
|
2648
2747
|
}
|
|
2649
|
-
|
|
2748
|
+
if (msg.isStreaming && pendingChunk.length > 0) {
|
|
2749
|
+
activeBlock = pendingChunk.length === 1 ? pendingChunk[0] : {
|
|
2750
|
+
key: `${msg.id || "x"}-chunk-active-${pendingChunk[0].key}`,
|
|
2751
|
+
msg,
|
|
2752
|
+
type: "chunk",
|
|
2753
|
+
blocks: pendingChunk
|
|
2754
|
+
};
|
|
2755
|
+
} else {
|
|
2756
|
+
flushPending();
|
|
2757
|
+
}
|
|
2758
|
+
const result = {
|
|
2650
2759
|
completed: completedBlocks,
|
|
2651
2760
|
active: activeBlock ? [activeBlock] : []
|
|
2652
2761
|
};
|
|
2762
|
+
if (!msg.isStreaming) {
|
|
2763
|
+
blocksCache.set(cacheKey, result);
|
|
2764
|
+
if (blocksCache.size > MAX_CACHE_SIZE) {
|
|
2765
|
+
const firstKey = blocksCache.keys().next().value;
|
|
2766
|
+
blocksCache.delete(firstKey);
|
|
2767
|
+
}
|
|
2768
|
+
streamingBlocksCache.delete(streamCacheKey);
|
|
2769
|
+
} else {
|
|
2770
|
+
const blocksMap = /* @__PURE__ */ new Map();
|
|
2771
|
+
completedBlocks.forEach((b) => indexBlockIntoMap(b, blocksMap));
|
|
2772
|
+
if (activeBlock) indexBlockIntoMap(activeBlock, blocksMap);
|
|
2773
|
+
streamingBlocksCache.set(streamCacheKey, { text, blocksMap });
|
|
2774
|
+
if (streamingBlocksCache.size > MAX_CACHE_SIZE) {
|
|
2775
|
+
const firstKey = streamingBlocksCache.keys().next().value;
|
|
2776
|
+
streamingBlocksCache.delete(firstKey);
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
return result;
|
|
2653
2780
|
};
|
|
2654
2781
|
TOOL_LABELS = {
|
|
2655
2782
|
"write_file": "WriteFile",
|
|
@@ -2678,61 +2805,88 @@ var init_text = __esm({
|
|
|
2678
2805
|
"Chat": "Chat",
|
|
2679
2806
|
"GenerateImage": "GenerateImage"
|
|
2680
2807
|
};
|
|
2808
|
+
REGEX_INITIAL_THINK = /<\/think>(\r?\n){2}/gi;
|
|
2809
|
+
REGEX_INITIAL_TOOL = /(\r?\n){2}(?=\[?(?:tool:functions|tool\.functions|\s*turn\s*:))/gi;
|
|
2810
|
+
REGEX_SYSTEM = /\[SYSTEM\][\s\S]*?\[\/SYSTEM\]/gi;
|
|
2811
|
+
REGEX_THINK = /<(think|thought)>[\s\S]*?(?:<\/(think|thought)>|$)/gi;
|
|
2812
|
+
REGEX_ANSWER = /\[ANSWER\][\s\S]*?(?:\[\/ANSWER\]|$)/gi;
|
|
2813
|
+
REGEX_TOOL_RES = /\[TOOL RESULT\]:?\s*/gi;
|
|
2814
|
+
REGEX_SUCCESS_ERROR = /^\s*(SUCCESS|ERROR):.*(\r?\n)?/gm;
|
|
2815
|
+
REGEX_TURN_1 = /\[\s*turn\s*:\s*(continue|finish)\s*\]/gi;
|
|
2816
|
+
REGEX_END = /\[\[END\]\]/gi;
|
|
2817
|
+
REGEX_TURN_2 = /\[\s*turn\s*:?.*?$/gi;
|
|
2818
|
+
REGEX_TURN_3 = /\n\s*turn\s*:?.*?$/gi;
|
|
2819
|
+
REGEX_OPEN_BRACKET = /\[\s*$/gi;
|
|
2820
|
+
REGEX_RESPONDED = /\n\nResponded on .*/g;
|
|
2821
|
+
REGEX_PROMPTED = /\n\n\[Prompted on: .*\]/g;
|
|
2822
|
+
REGEX_ARROWS = /(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)/gi;
|
|
2823
|
+
REGEX_ARROWS_L = /(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)/gi;
|
|
2824
|
+
REGEX_ARROWS_U = /(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)/gi;
|
|
2825
|
+
REGEX_ARROWS_D = /(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)/gi;
|
|
2826
|
+
REGEX_ARROWS_LR = /(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi;
|
|
2827
|
+
REGEX_TERMINAL = /@\[TerminalName:.*?, ProcessId:.*?\]/gi;
|
|
2828
|
+
REGEX_TOOLS = /\b(write_file|update_file|read_folder|view_file|exec_command|web_search|web_scrape|search_keyword|write_pdf|write_docx|generate_image)\b/gi;
|
|
2681
2829
|
cleanSignals = (text) => {
|
|
2682
2830
|
if (!text) return text;
|
|
2683
|
-
let result = text.replace(
|
|
2831
|
+
let result = text.replace(REGEX_INITIAL_THINK, "</think>").replace(REGEX_INITIAL_TOOL, "");
|
|
2684
2832
|
const trigger = "tool:functions.";
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
let balance = 0;
|
|
2698
|
-
let foundStart = false;
|
|
2699
|
-
let inString = null;
|
|
2700
|
-
let j = triggerIdx;
|
|
2701
|
-
while (j < result.length) {
|
|
2702
|
-
const char = result[j];
|
|
2703
|
-
if (!inString && (char === "'" || char === '"' || char === "`")) {
|
|
2704
|
-
inString = char;
|
|
2705
|
-
} else if (inString && char === inString && result[j - 1] !== "\\") {
|
|
2706
|
-
inString = null;
|
|
2833
|
+
if (result.toLowerCase().includes(trigger)) {
|
|
2834
|
+
while (true) {
|
|
2835
|
+
const lowerResult = result.toLowerCase();
|
|
2836
|
+
let triggerIdx = lowerResult.indexOf(trigger);
|
|
2837
|
+
if (triggerIdx === -1) break;
|
|
2838
|
+
let startIdx = triggerIdx;
|
|
2839
|
+
let hasOuterBracket = false;
|
|
2840
|
+
let k = triggerIdx - 1;
|
|
2841
|
+
while (k >= 0 && /\s/.test(result[k])) k--;
|
|
2842
|
+
if (k >= 0 && result[k] === "[") {
|
|
2843
|
+
startIdx = k;
|
|
2844
|
+
hasOuterBracket = true;
|
|
2707
2845
|
}
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2846
|
+
let balance = 0;
|
|
2847
|
+
let foundStart = false;
|
|
2848
|
+
let inString = null;
|
|
2849
|
+
let j = triggerIdx;
|
|
2850
|
+
while (j < result.length) {
|
|
2851
|
+
const char = result[j];
|
|
2852
|
+
if (!inString && (char === "'" || char === '"' || char === "`")) {
|
|
2853
|
+
inString = char;
|
|
2854
|
+
} else if (inString && char === inString && result[j - 1] !== "\\") {
|
|
2855
|
+
inString = null;
|
|
2714
2856
|
}
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
if (m < result.length && result[m] === "]") {
|
|
2722
|
-
endIdx = m;
|
|
2857
|
+
if (!inString) {
|
|
2858
|
+
if (char === "(") {
|
|
2859
|
+
balance++;
|
|
2860
|
+
foundStart = true;
|
|
2861
|
+
} else if (char === ")") {
|
|
2862
|
+
balance--;
|
|
2723
2863
|
}
|
|
2724
2864
|
}
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2865
|
+
if (foundStart && balance === 0 && !inString) {
|
|
2866
|
+
let endIdx = j;
|
|
2867
|
+
if (hasOuterBracket) {
|
|
2868
|
+
let m = j + 1;
|
|
2869
|
+
while (m < result.length && /\s/.test(result[m])) m++;
|
|
2870
|
+
if (m < result.length && result[m] === "]") {
|
|
2871
|
+
endIdx = m;
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
result = result.substring(0, startIdx) + result.substring(endIdx + 1);
|
|
2875
|
+
break;
|
|
2876
|
+
}
|
|
2877
|
+
j++;
|
|
2878
|
+
if (j === result.length) {
|
|
2879
|
+
result = result.substring(0, startIdx);
|
|
2880
|
+
return result;
|
|
2881
|
+
}
|
|
2732
2882
|
}
|
|
2733
2883
|
}
|
|
2734
2884
|
}
|
|
2735
|
-
return result.replaceAll(
|
|
2885
|
+
return result.replaceAll(REGEX_SYSTEM, "").replaceAll(REGEX_THINK, "").replace(REGEX_ANSWER, "").replaceAll(REGEX_TOOL_RES, "").replaceAll(REGEX_SUCCESS_ERROR, "").replaceAll(REGEX_TURN_1, "").replaceAll(REGEX_END, "").replaceAll(REGEX_TURN_2, "").replaceAll(REGEX_TURN_3, "").replaceAll(REGEX_OPEN_BRACKET, "").replaceAll(REGEX_RESPONDED, "").replaceAll(REGEX_PROMPTED, "").replaceAll(REGEX_ARROWS, "\u2192").replaceAll(REGEX_ARROWS_L, "\u2190").replaceAll(REGEX_ARROWS_U, "\u2191").replaceAll(REGEX_ARROWS_D, "\u2193").replaceAll(REGEX_ARROWS_LR, "\u2194").replaceAll(REGEX_TERMINAL, "").replaceAll(REGEX_TOOLS, (match) => TOOL_LABELS[match.toLowerCase()] || match).trim();
|
|
2886
|
+
};
|
|
2887
|
+
clearBlocksCache = () => {
|
|
2888
|
+
blocksCache.clear();
|
|
2889
|
+
streamingBlocksCache.clear();
|
|
2736
2890
|
};
|
|
2737
2891
|
}
|
|
2738
2892
|
});
|
|
@@ -3812,75 +3966,14 @@ ${coloredArt[7]}`;
|
|
|
3812
3966
|
import React4, { useState as useState4, useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
3813
3967
|
import { Box as Box3, Text as Text4 } from "ink";
|
|
3814
3968
|
import { diffWordsWithSpace } from "diff";
|
|
3815
|
-
var useStreamingText, formatThinkText, parseMathSymbols, renderLatexText, InlineMarkdown, TableRenderer, MarkdownText,
|
|
3969
|
+
var useStreamingText, formatThinkText, REGEX_MD_TOKENS, REGEX_LATEX_FRAC, REGEX_LATEX_STYLE, parseMathSymbols, renderLatexText, InlineMarkdown, TableRenderer, MarkdownText, DiffLine, DiffBlock, CodeRenderer, formatThinkingDuration, MessageItem, BlockItem, ChatLayout;
|
|
3816
3970
|
var init_ChatLayout = __esm({
|
|
3817
3971
|
"src/components/ChatLayout.jsx"() {
|
|
3818
3972
|
init_TerminalBox();
|
|
3819
3973
|
init_text();
|
|
3820
3974
|
init_terminal();
|
|
3821
3975
|
useStreamingText = (targetText, isStreaming, isActiveBlock) => {
|
|
3822
|
-
|
|
3823
|
-
const targetTextRef = useRef2(targetText);
|
|
3824
|
-
useEffect3(() => {
|
|
3825
|
-
targetTextRef.current = targetText;
|
|
3826
|
-
}, [targetText]);
|
|
3827
|
-
useEffect3(() => {
|
|
3828
|
-
if (!isActiveBlock) {
|
|
3829
|
-
setDisplayedText(targetText);
|
|
3830
|
-
return;
|
|
3831
|
-
}
|
|
3832
|
-
if (!isStreaming && displayedText === targetText) {
|
|
3833
|
-
return;
|
|
3834
|
-
}
|
|
3835
|
-
const interval = setInterval(() => {
|
|
3836
|
-
setDisplayedText((current) => {
|
|
3837
|
-
const target = targetTextRef.current;
|
|
3838
|
-
if (current.length >= target.length) {
|
|
3839
|
-
if (!isStreaming) {
|
|
3840
|
-
clearInterval(interval);
|
|
3841
|
-
}
|
|
3842
|
-
return current;
|
|
3843
|
-
}
|
|
3844
|
-
if (!target.startsWith(current)) {
|
|
3845
|
-
return target;
|
|
3846
|
-
}
|
|
3847
|
-
const remaining = target.substring(current.length);
|
|
3848
|
-
const words = remaining.split(/(\s+)/);
|
|
3849
|
-
if (words.length <= 1) {
|
|
3850
|
-
if (!isStreaming) {
|
|
3851
|
-
clearInterval(interval);
|
|
3852
|
-
}
|
|
3853
|
-
return target;
|
|
3854
|
-
}
|
|
3855
|
-
const currentWordsCount = current.split(/\s+/).filter(Boolean).length;
|
|
3856
|
-
const targetWordsCount = target.split(/\s+/).filter(Boolean).length;
|
|
3857
|
-
const diff = targetWordsCount - currentWordsCount;
|
|
3858
|
-
let wordsToAdd = 1;
|
|
3859
|
-
if (diff > 15) {
|
|
3860
|
-
wordsToAdd = 4;
|
|
3861
|
-
} else if (diff > 8) {
|
|
3862
|
-
wordsToAdd = 3;
|
|
3863
|
-
} else if (diff > 3) {
|
|
3864
|
-
wordsToAdd = 2;
|
|
3865
|
-
}
|
|
3866
|
-
let addedText = "";
|
|
3867
|
-
let wordCount = 0;
|
|
3868
|
-
for (let i = 0; i < words.length; i++) {
|
|
3869
|
-
const w = words[i];
|
|
3870
|
-
addedText += w;
|
|
3871
|
-
if (/\S/.test(w)) {
|
|
3872
|
-
wordCount++;
|
|
3873
|
-
if (wordCount >= wordsToAdd) {
|
|
3874
|
-
break;
|
|
3875
|
-
}
|
|
3876
|
-
}
|
|
3877
|
-
}
|
|
3878
|
-
return current + addedText;
|
|
3879
|
-
});
|
|
3880
|
-
}, 100);
|
|
3881
|
-
return () => clearInterval(interval);
|
|
3882
|
-
}, [isStreaming, isActiveBlock, targetText, displayedText]);
|
|
3883
|
-
return displayedText;
|
|
3976
|
+
return targetText;
|
|
3884
3977
|
};
|
|
3885
3978
|
formatThinkText = (cleaned, columns = 80) => {
|
|
3886
3979
|
if (!cleaned) return null;
|
|
@@ -3908,14 +4001,17 @@ var init_ChatLayout = __esm({
|
|
|
3908
4001
|
return /* @__PURE__ */ React4.createElement(MarkdownText, { key: i, text: cleanPart, color: "gray", columns: availableWidth, italic: true });
|
|
3909
4002
|
}));
|
|
3910
4003
|
};
|
|
4004
|
+
REGEX_MD_TOKENS = /(```[\s\S]*?```|`[^`]+`|@\[.*?\]|\*\*.*?\*\*|\*.*?\*|\$.*?\$|\[.*?\]\s*\(.*?\)|\[.*?\]\s*\[.*?\]|https?:\/\/[^\s]+)/g;
|
|
4005
|
+
REGEX_LATEX_FRAC = /\\frac\s*\{([^{}]*)\}\s*\{([^{}]*)\}/g;
|
|
4006
|
+
REGEX_LATEX_STYLE = /(\\(?:mathbf|textbf|textit|underline|texttt)\{[^{}]*\})/g;
|
|
3911
4007
|
parseMathSymbols = (content) => {
|
|
3912
4008
|
return content.replace(/\\multiply|\\mul|\\times/g, "\xD7").replace(/\\div/g, "\xF7").replace(/\\cdot/g, "\u22C5").replace(/\\infty/g, "\u221E").replace(/\\pm/g, "\xB1").replace(/\\leq/g, "\u2264").replace(/\\geq/g, "\u2265").replace(/\\neq/g, "\u2260").replace(/\\sqrt\s*\{([^}]+)\}/g, "\u221A($1)").replace(/\\sqrt\s*(\w+|\d+)/g, "\u221A($1)").replace(/\\alpha/g, "\u03B1").replace(/\\beta/g, "\u03B2").replace(/\\theta/g, "\u03B8").replace(/\\pi/g, "\u03C0").replace(/\\approx/g, "\u2248").replace(/\\Delta/g, "\u0394").replace(/\\sigma/g, "\u03C3").replace(/\\sum/g, "\u03A3").replace(/\\prod/g, "\u03A0").replace(/\\rightarrow|\\to/g, "\u2192").replace(/\\left\b|\\right\b/g, "").replace(/\\left\(|\\right\)/g, (match) => match.includes("left") ? "(" : ")").replace(/\\left\[|\\right\]/g, (match) => match.includes("left") ? "[" : "]").replace(/\\\{|\\\}/g, (match) => match.includes("{") ? "{" : "}").replace(/\\text\s*\{([^}]+)\}/g, "$1").replace(/\\text\s+(\w+)/g, "$1").replace(/\\%/g, "%");
|
|
3913
4009
|
};
|
|
3914
4010
|
renderLatexText = (content, key) => {
|
|
3915
4011
|
if (!content) return null;
|
|
3916
|
-
let formatted = content.replace(
|
|
4012
|
+
let formatted = content.replace(REGEX_LATEX_FRAC, "($1/$2)");
|
|
3917
4013
|
formatted = parseMathSymbols(formatted);
|
|
3918
|
-
const parts = formatted.split(
|
|
4014
|
+
const parts = formatted.split(REGEX_LATEX_STYLE);
|
|
3919
4015
|
return /* @__PURE__ */ React4.createElement(React4.Fragment, { key }, parts.map((p, idx) => {
|
|
3920
4016
|
if (p.startsWith("\\")) {
|
|
3921
4017
|
const match = p.match(/\\(\w+)\{([^{}]*)\}/);
|
|
@@ -3934,7 +4030,7 @@ var init_ChatLayout = __esm({
|
|
|
3934
4030
|
};
|
|
3935
4031
|
InlineMarkdown = React4.memo(({ text, color, italic }) => {
|
|
3936
4032
|
if (!text) return null;
|
|
3937
|
-
const parts = text.split(
|
|
4033
|
+
const parts = text.split(REGEX_MD_TOKENS);
|
|
3938
4034
|
return /* @__PURE__ */ React4.createElement(Text4, { color, wrap: "anywhere", italic }, parts.map((part, j) => {
|
|
3939
4035
|
if (!part) return null;
|
|
3940
4036
|
if (part.startsWith("```") && part.endsWith("```")) {
|
|
@@ -4065,40 +4161,47 @@ var init_ChatLayout = __esm({
|
|
|
4065
4161
|
flushBuffers("final");
|
|
4066
4162
|
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", width: columns - 2 }, result);
|
|
4067
4163
|
});
|
|
4068
|
-
parseLineInfo = (l) => {
|
|
4069
|
-
if (!l) return null;
|
|
4070
|
-
const clean = l.replace("[UI_CONTEXT]", "").replace(/\r/g, "");
|
|
4071
|
-
const isR = clean.startsWith("-");
|
|
4072
|
-
const isA = clean.startsWith("+");
|
|
4073
|
-
let rest = isR || isA ? clean.substring(1) : clean;
|
|
4074
|
-
rest = rest.trim();
|
|
4075
|
-
const splitIdx = rest.indexOf("|");
|
|
4076
|
-
const num = splitIdx !== -1 ? rest.substring(0, splitIdx).trim() : "";
|
|
4077
|
-
const content = splitIdx !== -1 ? rest.substring(splitIdx + 1) : rest;
|
|
4078
|
-
return { isR, isA, num, content };
|
|
4079
|
-
};
|
|
4080
4164
|
DiffLine = React4.memo(({ line, pairContent, parentText, columns = 80 }) => {
|
|
4081
4165
|
const isContext = line.includes("[UI_CONTEXT]");
|
|
4082
4166
|
const cleanLine = line.replace("[UI_CONTEXT]", "");
|
|
4083
4167
|
if (isContext && cleanLine.includes("\u2550")) {
|
|
4084
|
-
return /* @__PURE__ */ React4.createElement(Box3, { paddingX: 1, width: columns }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray" }, "\u2550".repeat(Math.max(10, columns - 4))));
|
|
4168
|
+
return /* @__PURE__ */ React4.createElement(Box3, { backgroundColor: "#1a1a1a", paddingX: 1, width: columns }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray" }, "\u2550".repeat(Math.max(10, columns - 4))));
|
|
4085
4169
|
}
|
|
4086
4170
|
const parsedCurrent = parseLineInfo(line);
|
|
4087
4171
|
if (!parsedCurrent) {
|
|
4088
4172
|
return /* @__PURE__ */ React4.createElement(Box3, { backgroundColor: "#1a1a1a", paddingX: 1, width: columns }, /* @__PURE__ */ React4.createElement(Box3, { width: 3, flexShrink: 0 }), /* @__PURE__ */ React4.createElement(Box3, { width: 1, flexShrink: 0, marginLeft: 1 }), /* @__PURE__ */ React4.createElement(Box3, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray" }, wrapText(cleanLine, columns - 14))));
|
|
4089
4173
|
}
|
|
4090
4174
|
const { isR: isRemoval, isA: isAddition, num: lineNum, content } = parsedCurrent;
|
|
4091
|
-
const innerBgColor = isRemoval ? "#3a0c0c" : isAddition ? "#0c3a1a" : void 0;
|
|
4092
4175
|
let finalPairContent = pairContent;
|
|
4093
4176
|
if (!finalPairContent && parentText && (isRemoval || isAddition)) {
|
|
4094
|
-
const
|
|
4095
|
-
const
|
|
4096
|
-
const
|
|
4097
|
-
|
|
4098
|
-
return
|
|
4177
|
+
const match = parentText.match(/\[DIFF_START\]([\s\S]*?)(?:\[DIFF_END\]|$)/);
|
|
4178
|
+
const diffBody = match ? match[1].trim() : "";
|
|
4179
|
+
const diffLines = diffBody.split("\n").map((l) => l.replace(/\r$/, ""));
|
|
4180
|
+
const parsedLines = diffLines.map((l) => {
|
|
4181
|
+
return {
|
|
4182
|
+
line: l,
|
|
4183
|
+
parsed: parseLineInfo(l),
|
|
4184
|
+
pairContent: null
|
|
4185
|
+
};
|
|
4099
4186
|
});
|
|
4100
|
-
|
|
4101
|
-
|
|
4187
|
+
let currentGroup = [];
|
|
4188
|
+
for (let idx = 0; idx < parsedLines.length; idx++) {
|
|
4189
|
+
const item = parsedLines[idx];
|
|
4190
|
+
if (item.parsed && (item.parsed.isR || item.parsed.isA)) {
|
|
4191
|
+
currentGroup.push(item);
|
|
4192
|
+
} else {
|
|
4193
|
+
if (currentGroup.length > 0) {
|
|
4194
|
+
alignChangeGroup(currentGroup);
|
|
4195
|
+
currentGroup = [];
|
|
4196
|
+
}
|
|
4197
|
+
}
|
|
4198
|
+
}
|
|
4199
|
+
if (currentGroup.length > 0) {
|
|
4200
|
+
alignChangeGroup(currentGroup);
|
|
4201
|
+
}
|
|
4202
|
+
const matchedItem = parsedLines.find((item) => item.parsed && item.parsed.num === lineNum && item.parsed.isR === isRemoval);
|
|
4203
|
+
if (matchedItem) {
|
|
4204
|
+
finalPairContent = matchedItem.pairContent;
|
|
4102
4205
|
}
|
|
4103
4206
|
}
|
|
4104
4207
|
let words = [];
|
|
@@ -4113,7 +4216,7 @@ var init_ChatLayout = __esm({
|
|
|
4113
4216
|
}
|
|
4114
4217
|
const hasInlineChange = words.some((part) => isRemoval && part.removed || isAddition && part.added);
|
|
4115
4218
|
const isPureUnpairedBlock = !finalPairContent && (isRemoval || isAddition);
|
|
4116
|
-
const
|
|
4219
|
+
const innerBgColor = isRemoval ? "#3a0c0c" : isAddition ? "#0c3a1a" : void 0;
|
|
4117
4220
|
const finalNumColor = isRemoval || isAddition ? isRemoval ? "#d96868" : "#68d98c" : "gray";
|
|
4118
4221
|
const finalPrefixColor = isRemoval ? "#ff4d4d" : "#4dff88";
|
|
4119
4222
|
const displayPrefix = isRemoval ? "-" : isAddition ? "+" : " ";
|
|
@@ -4123,7 +4226,7 @@ var init_ChatLayout = __esm({
|
|
|
4123
4226
|
return /* @__PURE__ */ React4.createElement(Text4, { color: blockColor }, wrapText(content, columns - 14));
|
|
4124
4227
|
}
|
|
4125
4228
|
if (!(isRemoval || isAddition) || words.length === 0 || !hasInlineChange) {
|
|
4126
|
-
const textColor = isRemoval ? "#
|
|
4229
|
+
const textColor = isRemoval ? "#885555" : isAddition ? "#558866" : "gray";
|
|
4127
4230
|
return /* @__PURE__ */ React4.createElement(Text4, { color: textColor }, wrapText(content, columns - 14));
|
|
4128
4231
|
}
|
|
4129
4232
|
return /* @__PURE__ */ React4.createElement(Text4, { wrap: "anywhere" }, words.map((part, idx) => {
|
|
@@ -4134,7 +4237,7 @@ var init_ChatLayout = __esm({
|
|
|
4134
4237
|
return /* @__PURE__ */ React4.createElement(Text4, { key: idx, color: "#ff3333" }, part.value);
|
|
4135
4238
|
}
|
|
4136
4239
|
if (part.added) return null;
|
|
4137
|
-
return /* @__PURE__ */ React4.createElement(Text4, { key: idx, color: "#
|
|
4240
|
+
return /* @__PURE__ */ React4.createElement(Text4, { key: idx, color: "#885555" }, part.value);
|
|
4138
4241
|
}
|
|
4139
4242
|
if (isAddition) {
|
|
4140
4243
|
const isSurroundedByAddition = words[idx - 1]?.added || words[idx + 1]?.added;
|
|
@@ -4142,7 +4245,7 @@ var init_ChatLayout = __esm({
|
|
|
4142
4245
|
return /* @__PURE__ */ React4.createElement(Text4, { key: idx, color: "#33ff66" }, part.value);
|
|
4143
4246
|
}
|
|
4144
4247
|
if (part.removed) return null;
|
|
4145
|
-
return /* @__PURE__ */ React4.createElement(Text4, { key: idx, color: "#
|
|
4248
|
+
return /* @__PURE__ */ React4.createElement(Text4, { key: idx, color: "#558866" }, part.value);
|
|
4146
4249
|
}
|
|
4147
4250
|
return /* @__PURE__ */ React4.createElement(Text4, { key: idx, color: "gray" }, part.value);
|
|
4148
4251
|
}));
|
|
@@ -4153,7 +4256,37 @@ var init_ChatLayout = __esm({
|
|
|
4153
4256
|
const match = text.match(/\[DIFF_START\]([\s\S]*?)\[DIFF_END\]/);
|
|
4154
4257
|
const diffBody = match ? match[1].trim() : "";
|
|
4155
4258
|
const diffLines = diffBody.split("\n");
|
|
4156
|
-
|
|
4259
|
+
const parsedLines = diffLines.map((line) => {
|
|
4260
|
+
return {
|
|
4261
|
+
line,
|
|
4262
|
+
parsed: parseLineInfo(line),
|
|
4263
|
+
pairContent: null
|
|
4264
|
+
};
|
|
4265
|
+
});
|
|
4266
|
+
let currentGroup = [];
|
|
4267
|
+
for (let i = 0; i < parsedLines.length; i++) {
|
|
4268
|
+
const item = parsedLines[i];
|
|
4269
|
+
if (item.parsed && (item.parsed.isR || item.parsed.isA)) {
|
|
4270
|
+
currentGroup.push(item);
|
|
4271
|
+
} else {
|
|
4272
|
+
if (currentGroup.length > 0) {
|
|
4273
|
+
alignChangeGroup(currentGroup);
|
|
4274
|
+
currentGroup = [];
|
|
4275
|
+
}
|
|
4276
|
+
}
|
|
4277
|
+
}
|
|
4278
|
+
if (currentGroup.length > 0) {
|
|
4279
|
+
alignChangeGroup(currentGroup);
|
|
4280
|
+
}
|
|
4281
|
+
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", width: columns - 3, marginBottom: 1 }, /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", paddingY: 0, width: "100%" }, /* @__PURE__ */ React4.createElement(Box3, { backgroundColor: "#1a1a1a", paddingX: 1, width: "100%" }, /* @__PURE__ */ React4.createElement(Box3, { width: 3, flexShrink: 0 }), /* @__PURE__ */ React4.createElement(Box3, { width: 1, flexShrink: 0, marginLeft: 1 }), /* @__PURE__ */ React4.createElement(Box3, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React4.createElement(Text4, null, " "))), parsedLines.map((item, i) => /* @__PURE__ */ React4.createElement(
|
|
4282
|
+
DiffLine,
|
|
4283
|
+
{
|
|
4284
|
+
key: i,
|
|
4285
|
+
line: item.line,
|
|
4286
|
+
pairContent: item.pairContent,
|
|
4287
|
+
columns: columns - 3
|
|
4288
|
+
}
|
|
4289
|
+
)), /* @__PURE__ */ React4.createElement(Box3, { backgroundColor: "#1a1a1a", paddingX: 1, width: "100%" }, /* @__PURE__ */ React4.createElement(Box3, { width: 3, flexShrink: 0 }), /* @__PURE__ */ React4.createElement(Box3, { width: 1, flexShrink: 0, marginLeft: 1 }), /* @__PURE__ */ React4.createElement(Box3, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React4.createElement(Text4, null, " ")))));
|
|
4157
4290
|
});
|
|
4158
4291
|
CodeRenderer = React4.memo(({ text, columns = 80 }) => {
|
|
4159
4292
|
if (!text) return null;
|
|
@@ -4408,6 +4541,19 @@ var init_ChatLayout = __esm({
|
|
|
4408
4541
|
});
|
|
4409
4542
|
BlockItem = React4.memo(({ block, columns = 80, showFullThinking, aiProvider, version }) => {
|
|
4410
4543
|
const { msg, type, text, isStreaming } = block;
|
|
4544
|
+
if (type === "chunk") {
|
|
4545
|
+
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", width: "100%" }, block.blocks.map((b) => /* @__PURE__ */ React4.createElement(
|
|
4546
|
+
BlockItem,
|
|
4547
|
+
{
|
|
4548
|
+
key: b.key,
|
|
4549
|
+
block: b,
|
|
4550
|
+
columns,
|
|
4551
|
+
showFullThinking,
|
|
4552
|
+
aiProvider,
|
|
4553
|
+
version
|
|
4554
|
+
}
|
|
4555
|
+
)));
|
|
4556
|
+
}
|
|
4411
4557
|
if (type === "full-message") {
|
|
4412
4558
|
return /* @__PURE__ */ React4.createElement(
|
|
4413
4559
|
MessageItem,
|
|
@@ -4471,6 +4617,56 @@ var init_ChatLayout = __esm({
|
|
|
4471
4617
|
}
|
|
4472
4618
|
), isLastLine && renderPaddingLine(true));
|
|
4473
4619
|
}
|
|
4620
|
+
if (type === "code-fence-open") {
|
|
4621
|
+
const borderProps = {
|
|
4622
|
+
borderStyle: "single",
|
|
4623
|
+
borderLeft: true,
|
|
4624
|
+
borderRight: false,
|
|
4625
|
+
borderTop: false,
|
|
4626
|
+
borderBottom: false,
|
|
4627
|
+
borderColor: "#444444",
|
|
4628
|
+
paddingLeft: 2,
|
|
4629
|
+
width: "100%"
|
|
4630
|
+
};
|
|
4631
|
+
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", marginTop: 1, width: "100%" }, /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "row", ...borderProps }, /* @__PURE__ */ React4.createElement(Text4, null, " ")), /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "row", ...borderProps }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray", bold: true }, "\u25B6_ ", (text || "CODE").toUpperCase())));
|
|
4632
|
+
}
|
|
4633
|
+
if (type === "code-line") {
|
|
4634
|
+
const { lineNum } = block;
|
|
4635
|
+
return /* @__PURE__ */ React4.createElement(
|
|
4636
|
+
Box3,
|
|
4637
|
+
{
|
|
4638
|
+
flexDirection: "row",
|
|
4639
|
+
borderStyle: "single",
|
|
4640
|
+
borderLeft: true,
|
|
4641
|
+
borderRight: false,
|
|
4642
|
+
borderTop: false,
|
|
4643
|
+
borderBottom: false,
|
|
4644
|
+
borderColor: "#444444",
|
|
4645
|
+
paddingLeft: 2,
|
|
4646
|
+
width: "100%"
|
|
4647
|
+
},
|
|
4648
|
+
/* @__PURE__ */ React4.createElement(Box3, { width: 4, flexShrink: 0 }, /* @__PURE__ */ React4.createElement(Text4, { color: "gray", dimColor: true }, String(lineNum).padStart(3, " "), " ")),
|
|
4649
|
+
/* @__PURE__ */ React4.createElement(Box3, { flexGrow: 1 }, /* @__PURE__ */ React4.createElement(Text4, { color: "#fcfca4ff" }, text))
|
|
4650
|
+
);
|
|
4651
|
+
}
|
|
4652
|
+
if (type === "code-fence-close") {
|
|
4653
|
+
return /* @__PURE__ */ React4.createElement(
|
|
4654
|
+
Box3,
|
|
4655
|
+
{
|
|
4656
|
+
flexDirection: "row",
|
|
4657
|
+
borderStyle: "single",
|
|
4658
|
+
borderLeft: true,
|
|
4659
|
+
borderRight: false,
|
|
4660
|
+
borderTop: false,
|
|
4661
|
+
borderBottom: false,
|
|
4662
|
+
borderColor: "#444444",
|
|
4663
|
+
paddingLeft: 2,
|
|
4664
|
+
marginBottom: 1,
|
|
4665
|
+
width: "100%"
|
|
4666
|
+
},
|
|
4667
|
+
/* @__PURE__ */ React4.createElement(Text4, null, " ")
|
|
4668
|
+
);
|
|
4669
|
+
}
|
|
4474
4670
|
if (type === "write-header") {
|
|
4475
4671
|
return /* @__PURE__ */ React4.createElement(Box3, { flexDirection: "column", paddingX: 1, width: columns }, /* @__PURE__ */ React4.createElement(MarkdownText, { text, columns }));
|
|
4476
4672
|
}
|
|
@@ -4541,12 +4737,35 @@ var init_ChatLayout = __esm({
|
|
|
4541
4737
|
// src/components/StatusBar.jsx
|
|
4542
4738
|
import React5 from "react";
|
|
4543
4739
|
import { Box as Box4, Text as Text5 } from "ink";
|
|
4740
|
+
import { useState as useState5, useEffect as useEffect4 } from "react";
|
|
4544
4741
|
var StatusBar, StatusBar_default;
|
|
4545
4742
|
var init_StatusBar = __esm({
|
|
4546
4743
|
"src/components/StatusBar.jsx"() {
|
|
4547
4744
|
init_text();
|
|
4548
4745
|
StatusBar = React5.memo(({ mode, thinkingLevel, tokens = "0.0k", tokensTotal = "0.0k", chatId = "NEW-SESSION", isMemoryEnabled = true, apiTier = "Free", aiProvider = "Google" }) => {
|
|
4549
4746
|
const modeIcon = mode === "Flux" ? "" : "";
|
|
4747
|
+
const [memoryUsage, setMemoryUsage] = useState5(0);
|
|
4748
|
+
const [memoryLimit, setMemoryLimit] = useState5(0);
|
|
4749
|
+
const [memoryUnit, setMemoryUnit] = useState5("MB");
|
|
4750
|
+
useEffect4(() => {
|
|
4751
|
+
const getMemoryInfo = () => {
|
|
4752
|
+
const usage = process.memoryUsage();
|
|
4753
|
+
const isGB = usage.heapTotal / (1024 * 1024) >= 1024;
|
|
4754
|
+
const currentUnit = isGB ? "GB" : "MB";
|
|
4755
|
+
const formatToNumber = (bytes, toGB) => {
|
|
4756
|
+
const converted = bytes / (1024 * 1024 * (toGB ? 1024 : 1));
|
|
4757
|
+
return toGB ? parseFloat(converted.toFixed(2)) : Math.round(converted);
|
|
4758
|
+
};
|
|
4759
|
+
setMemoryUnit(currentUnit);
|
|
4760
|
+
setMemoryLimit(formatToNumber(usage.heapTotal, isGB));
|
|
4761
|
+
setMemoryUsage(formatToNumber(usage.heapUsed, isGB));
|
|
4762
|
+
};
|
|
4763
|
+
getMemoryInfo();
|
|
4764
|
+
const interval = setInterval(() => {
|
|
4765
|
+
getMemoryInfo();
|
|
4766
|
+
}, 3e3);
|
|
4767
|
+
return () => clearInterval(interval);
|
|
4768
|
+
}, []);
|
|
4550
4769
|
let maxLimit = 256e3;
|
|
4551
4770
|
if (aiProvider === "DeepSeek" || aiProvider === "Google" && apiTier === "Paid") {
|
|
4552
4771
|
maxLimit = 4e5;
|
|
@@ -4561,7 +4780,7 @@ var init_StatusBar = __esm({
|
|
|
4561
4780
|
},
|
|
4562
4781
|
/* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Box4, { marginRight: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "white", bold: true }, modeIcon, " ", 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" }, "MEM: "), /* @__PURE__ */ React5.createElement(Text5, { color: "white", bold: true }, isMemoryEnabled ? "ON" : "OFF"))),
|
|
4563
4782
|
/* @__PURE__ */ React5.createElement(Box4, { flexGrow: 1, justifyContent: "center", paddingX: 2 }, /* @__PURE__ */ React5.createElement(Text5, { color: "white", italic: true }, " ", truncatePath(process.cwd(), 35))),
|
|
4564
|
-
/* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, "\u2503 "), /* @__PURE__ */ React5.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "white" }, " ", formatTokens(tokensTotal), " ", /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, (tokens / maxLimit * 100).toFixed(0), "%"))), /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, "\u2503 "), /* @__PURE__ */ React5.createElement(Box4, { marginLeft: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", italic: true }, " ", chatId), (apiTier === "Custom" || apiTier === "Paid") && /* @__PURE__ */ React5.createElement(Text5, { color: "white" }, " | ", /* @__PURE__ */ React5.createElement(Text5, { color: "gray", bold: true }, "CUSTOM"))))
|
|
4783
|
+
/* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text5, { color: "gray", dimColor: true }, "\u2503 "), /* @__PURE__ */ React5.createElement(Box4, { marginX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { color: "white" }, " ", formatTokens(tokensTotal), " ", /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, (tokens / maxLimit * 100).toFixed(0), "%"))), /* @__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", italic: true }, " ", chatId), (apiTier === "Custom" || apiTier === "Paid") && /* @__PURE__ */ React5.createElement(Text5, { color: "white" }, " | ", /* @__PURE__ */ React5.createElement(Text5, { color: "gray", bold: true }, "CUSTOM"))))
|
|
4565
4784
|
);
|
|
4566
4785
|
});
|
|
4567
4786
|
StatusBar_default = StatusBar;
|
|
@@ -4797,7 +5016,7 @@ ${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative to CWD & WILL BE FIRST A
|
|
|
4797
5016
|
3. [tool:functions.FileMap(path="path/file")]. Shows file structure, functions, class, import/export, variable
|
|
4798
5017
|
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**
|
|
4799
5018
|
5. [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile. Verify Imports
|
|
4800
|
-
6. [tool:functions.SearchKeyword(keyword="...", file="optional")]. 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
|
|
5019
|
+
6. [tool:functions.SearchKeyword(keyword="...", file="optional", subString="true/false optional")]. 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
|
|
4801
5020
|
7. [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL ONLY` : `WINDOWS CMD ONLY` : `BASH`} command. Destructive/Irreversible ops -> Ask user
|
|
4802
5021
|
8. [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASK STRINGS])]. Task List, Markdown IN ARRAY NOT ALLOWED. 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`.trim() : `- CREATIVE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
|
|
4803
5022
|
1. [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout
|
|
@@ -5456,9 +5675,10 @@ ${finalOutput}`);
|
|
|
5456
5675
|
});
|
|
5457
5676
|
|
|
5458
5677
|
// src/components/SettingsMenu.jsx
|
|
5459
|
-
import React7, { useState as
|
|
5678
|
+
import React7, { useState as useState6, useEffect as useEffect5 } from "react";
|
|
5460
5679
|
import { Box as Box6, Text as Text7, useInput as useInput3 } from "ink";
|
|
5461
5680
|
import TextInput from "ink-text-input";
|
|
5681
|
+
import v8 from "v8";
|
|
5462
5682
|
function SettingsMenu({
|
|
5463
5683
|
systemSettings,
|
|
5464
5684
|
setSystemSettings,
|
|
@@ -5470,11 +5690,34 @@ function SettingsMenu({
|
|
|
5470
5690
|
setMessages,
|
|
5471
5691
|
aiProvider
|
|
5472
5692
|
}) {
|
|
5473
|
-
const [activeColumn, setActiveColumn] =
|
|
5474
|
-
const [selectedCategoryIndex, setSelectedCategoryIndex] =
|
|
5475
|
-
const [selectedItemIndex, setSelectedItemIndex] =
|
|
5476
|
-
const [editingItem, setEditingItem] =
|
|
5477
|
-
const [editValue, setEditValue] =
|
|
5693
|
+
const [activeColumn, setActiveColumn] = useState6("categories");
|
|
5694
|
+
const [selectedCategoryIndex, setSelectedCategoryIndex] = useState6(0);
|
|
5695
|
+
const [selectedItemIndex, setSelectedItemIndex] = useState6(0);
|
|
5696
|
+
const [editingItem, setEditingItem] = useState6(null);
|
|
5697
|
+
const [editValue, setEditValue] = useState6("");
|
|
5698
|
+
const [currentMemory, setCurrentMemory] = useState6(0);
|
|
5699
|
+
const [maxMemory, setMaxMemory] = useState6(0);
|
|
5700
|
+
const [memoryUnit, setMemoryUnit] = useState6("MB");
|
|
5701
|
+
useEffect5(() => {
|
|
5702
|
+
const maxLimitBytes = v8.getHeapStatistics().heap_size_limit;
|
|
5703
|
+
const isGB = maxLimitBytes >= 1024 * 1024 * 1024;
|
|
5704
|
+
const unitLabel = isGB ? "GB" : "MB";
|
|
5705
|
+
const divisor = isGB ? 1024 * 1024 * 1024 : 1024 * 1024;
|
|
5706
|
+
setMaxMemory(parseFloat((maxLimitBytes / divisor).toFixed(2)));
|
|
5707
|
+
setMemoryUnit(unitLabel);
|
|
5708
|
+
const getMemoryStats = () => {
|
|
5709
|
+
const usage = process.memoryUsage();
|
|
5710
|
+
const targetBytes = usage.rss;
|
|
5711
|
+
const converted = targetBytes / divisor;
|
|
5712
|
+
const formattedCurrent = isGB ? parseFloat(converted.toFixed(2)) : Math.round(converted);
|
|
5713
|
+
setCurrentMemory(formattedCurrent);
|
|
5714
|
+
};
|
|
5715
|
+
getMemoryStats();
|
|
5716
|
+
const interval = setInterval(() => {
|
|
5717
|
+
getMemoryStats();
|
|
5718
|
+
}, 5e3);
|
|
5719
|
+
return () => clearInterval(interval);
|
|
5720
|
+
}, []);
|
|
5478
5721
|
const getCategoryItems = (catId) => {
|
|
5479
5722
|
switch (catId) {
|
|
5480
5723
|
case "memory":
|
|
@@ -5734,7 +5977,10 @@ function SettingsMenu({
|
|
|
5734
5977
|
});
|
|
5735
5978
|
if (currentCatId === "other") {
|
|
5736
5979
|
elements.push(
|
|
5737
|
-
/* @__PURE__ */ React7.createElement(Box6, { key: "pty-notice", marginTop:
|
|
5980
|
+
/* @__PURE__ */ React7.createElement(Box6, { key: "pty-notice", marginTop: 17, paddingX: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "white" }, isPtyAvailable ? "\u2713 Advance Interactive Terminal Supported" : "\u26A0 Interactive Terminal is Limited"))
|
|
5981
|
+
);
|
|
5982
|
+
elements.push(
|
|
5983
|
+
/* @__PURE__ */ React7.createElement(Box6, { key: "memory-load-2026", paddingX: 1 }, /* @__PURE__ */ React7.createElement(Text7, { color: "gray" }, "Memory Load: ", currentMemory, "/", maxMemory, " ", memoryUnit))
|
|
5738
5984
|
);
|
|
5739
5985
|
}
|
|
5740
5986
|
if (hasConflict) {
|
|
@@ -5777,13 +6023,13 @@ var init_SettingsMenu = __esm({
|
|
|
5777
6023
|
});
|
|
5778
6024
|
|
|
5779
6025
|
// src/components/ProfileForm.jsx
|
|
5780
|
-
import React8, { useState as
|
|
6026
|
+
import React8, { useState as useState7, useEffect as useEffect6 } from "react";
|
|
5781
6027
|
import { Box as Box7, Text as Text8 } from "ink";
|
|
5782
6028
|
import TextInput2 from "ink-text-input";
|
|
5783
6029
|
function ProfileForm({ initialData, onSave, onCancel }) {
|
|
5784
|
-
const [step, setStep] =
|
|
5785
|
-
const [currentInput, setCurrentInput] =
|
|
5786
|
-
const [profile, setProfile] =
|
|
6030
|
+
const [step, setStep] = useState7(0);
|
|
6031
|
+
const [currentInput, setCurrentInput] = useState7("");
|
|
6032
|
+
const [profile, setProfile] = useState7(() => ({
|
|
5787
6033
|
name: initialData?.name || "",
|
|
5788
6034
|
nickname: initialData?.nickname || "",
|
|
5789
6035
|
instructions: initialData?.instructions || ""
|
|
@@ -5793,7 +6039,7 @@ function ProfileForm({ initialData, onSave, onCancel }) {
|
|
|
5793
6039
|
{ key: "nickname", label: "Enter a Nickname (Agent will use this): " },
|
|
5794
6040
|
{ key: "instructions", label: "System Instructions (Persona overrides): " }
|
|
5795
6041
|
];
|
|
5796
|
-
|
|
6042
|
+
useEffect6(() => {
|
|
5797
6043
|
const currentKey = steps[step].key;
|
|
5798
6044
|
setCurrentInput(profile[currentKey] || "");
|
|
5799
6045
|
}, [step, profile]);
|
|
@@ -5841,7 +6087,7 @@ var init_ProfileForm = __esm({
|
|
|
5841
6087
|
});
|
|
5842
6088
|
|
|
5843
6089
|
// src/components/AskUserModal.jsx
|
|
5844
|
-
import React9, { useState as
|
|
6090
|
+
import React9, { useState as useState8 } from "react";
|
|
5845
6091
|
import { Box as Box8, Text as Text9, useInput as useInput4 } from "ink";
|
|
5846
6092
|
import TextInput3 from "ink-text-input";
|
|
5847
6093
|
var AskUserModal, AskUserModal_default;
|
|
@@ -5849,9 +6095,9 @@ var init_AskUserModal = __esm({
|
|
|
5849
6095
|
"src/components/AskUserModal.jsx"() {
|
|
5850
6096
|
init_terminal();
|
|
5851
6097
|
AskUserModal = ({ question, options, onResolve }) => {
|
|
5852
|
-
const [isSuggestingElse, setIsSuggestingElse] =
|
|
5853
|
-
const [customInput, setCustomInput] =
|
|
5854
|
-
const [selectedIndex, setSelectedIndex] =
|
|
6098
|
+
const [isSuggestingElse, setIsSuggestingElse] = useState8(false);
|
|
6099
|
+
const [customInput, setCustomInput] = useState8("");
|
|
6100
|
+
const [selectedIndex, setSelectedIndex] = useState8(0);
|
|
5855
6101
|
const allOptions = [...options, { id: "CUSTOM", label: "Suggest something else...", description: "Provide a custom response" }];
|
|
5856
6102
|
useInput4((input, key) => {
|
|
5857
6103
|
if (isSuggestingElse) return;
|
|
@@ -6084,6 +6330,7 @@ ${projectContextBlock}
|
|
|
6084
6330
|
-- FORMATTING --
|
|
6085
6331
|
- GFM Supported
|
|
6086
6332
|
- NO CHAT **AFTER** FIRING TOOLS IN CURRENT TURN
|
|
6333
|
+
- Short headsup about actions before firing tools
|
|
6087
6334
|
- Task Complete & Results Verified? End response with summary of changes made and files edited
|
|
6088
6335
|
- Basic LaTeX${mode === "Flux" ? "" : ". Kaomojis"}
|
|
6089
6336
|
=== END SYSTEM PROMPT ===`.trim();
|
|
@@ -6322,27 +6569,61 @@ var init_history = __esm({
|
|
|
6322
6569
|
return nextLock;
|
|
6323
6570
|
};
|
|
6324
6571
|
loadHistory = async () => {
|
|
6572
|
+
await fs7.ensureDir(HISTORY_DIR);
|
|
6573
|
+
let history = {};
|
|
6325
6574
|
if (await fs7.pathExists(HISTORY_FILE)) {
|
|
6326
6575
|
try {
|
|
6327
|
-
|
|
6576
|
+
history = readEncryptedJson(HISTORY_FILE, {});
|
|
6328
6577
|
} catch (e) {
|
|
6329
|
-
|
|
6578
|
+
history = {};
|
|
6330
6579
|
}
|
|
6331
6580
|
}
|
|
6332
|
-
|
|
6581
|
+
for (const id in history) {
|
|
6582
|
+
const chatFile = path6.join(HISTORY_DIR, `${id}.json`);
|
|
6583
|
+
Object.defineProperty(history[id], "messages", {
|
|
6584
|
+
get: () => {
|
|
6585
|
+
if (fs7.existsSync(chatFile)) {
|
|
6586
|
+
try {
|
|
6587
|
+
return readEncryptedJson(chatFile, []);
|
|
6588
|
+
} catch (e) {
|
|
6589
|
+
return [];
|
|
6590
|
+
}
|
|
6591
|
+
}
|
|
6592
|
+
return [];
|
|
6593
|
+
},
|
|
6594
|
+
set: (msgs) => {
|
|
6595
|
+
try {
|
|
6596
|
+
writeEncryptedJson(chatFile, msgs);
|
|
6597
|
+
} catch (e) {
|
|
6598
|
+
}
|
|
6599
|
+
},
|
|
6600
|
+
enumerable: false,
|
|
6601
|
+
configurable: true
|
|
6602
|
+
});
|
|
6603
|
+
}
|
|
6604
|
+
return history;
|
|
6333
6605
|
};
|
|
6334
6606
|
saveChat = async (id, name, messages) => {
|
|
6335
6607
|
return withLock(async () => {
|
|
6608
|
+
await fs7.ensureDir(HISTORY_DIR);
|
|
6336
6609
|
const history = await loadHistory();
|
|
6337
6610
|
const existingChat = history[id];
|
|
6338
6611
|
const persistentMessages = (messages || []).filter((m) => !m.isUpdateNotification && !m.isMeta);
|
|
6339
6612
|
const finalName = name || (existingChat ? existingChat.name : `Session ${id.slice(-6)}`);
|
|
6613
|
+
const chatFile = path6.join(HISTORY_DIR, `${id}.json`);
|
|
6614
|
+
writeEncryptedJson(chatFile, persistentMessages);
|
|
6340
6615
|
history[id] = {
|
|
6341
6616
|
name: finalName,
|
|
6342
|
-
messages: persistentMessages,
|
|
6343
6617
|
updatedAt: Date.now()
|
|
6344
6618
|
};
|
|
6345
|
-
|
|
6619
|
+
const indexHistory = {};
|
|
6620
|
+
for (const chatId in history) {
|
|
6621
|
+
indexHistory[chatId] = {
|
|
6622
|
+
name: history[chatId].name,
|
|
6623
|
+
updatedAt: history[chatId].updatedAt
|
|
6624
|
+
};
|
|
6625
|
+
}
|
|
6626
|
+
writeEncryptedJson(HISTORY_FILE, indexHistory);
|
|
6346
6627
|
});
|
|
6347
6628
|
};
|
|
6348
6629
|
saveChatTitle = async (id, title) => {
|
|
@@ -6352,16 +6633,30 @@ var init_history = __esm({
|
|
|
6352
6633
|
history[id].name = title;
|
|
6353
6634
|
history[id].updatedAt = Date.now();
|
|
6354
6635
|
} else {
|
|
6355
|
-
history[id] = { name: title,
|
|
6636
|
+
history[id] = { name: title, updatedAt: Date.now() };
|
|
6356
6637
|
}
|
|
6357
|
-
|
|
6638
|
+
const indexHistory = {};
|
|
6639
|
+
for (const chatId in history) {
|
|
6640
|
+
indexHistory[chatId] = {
|
|
6641
|
+
name: history[chatId].name,
|
|
6642
|
+
updatedAt: history[chatId].updatedAt
|
|
6643
|
+
};
|
|
6644
|
+
}
|
|
6645
|
+
writeEncryptedJson(HISTORY_FILE, indexHistory);
|
|
6358
6646
|
});
|
|
6359
6647
|
};
|
|
6360
6648
|
deleteChat = async (id) => {
|
|
6361
6649
|
return withLock(async () => {
|
|
6362
6650
|
const history = await loadHistory();
|
|
6363
6651
|
delete history[id];
|
|
6364
|
-
|
|
6652
|
+
const indexHistory = {};
|
|
6653
|
+
for (const chatId in history) {
|
|
6654
|
+
indexHistory[chatId] = {
|
|
6655
|
+
name: history[chatId].name,
|
|
6656
|
+
updatedAt: history[chatId].updatedAt
|
|
6657
|
+
};
|
|
6658
|
+
}
|
|
6659
|
+
writeEncryptedJson(HISTORY_FILE, indexHistory);
|
|
6365
6660
|
if (await fs7.pathExists(CONTEXT_FILE)) {
|
|
6366
6661
|
try {
|
|
6367
6662
|
const contextData = readEncryptedJson(CONTEXT_FILE, []);
|
|
@@ -6383,6 +6678,13 @@ var init_history = __esm({
|
|
|
6383
6678
|
writeEncryptedJson(TEMP_MEM_CHAT_FILE, cache);
|
|
6384
6679
|
}
|
|
6385
6680
|
await RevertManager.deleteChatBackups(id);
|
|
6681
|
+
const chatFile = path6.join(HISTORY_DIR, `${id}.json`);
|
|
6682
|
+
if (await fs7.pathExists(chatFile)) {
|
|
6683
|
+
try {
|
|
6684
|
+
await fs7.remove(chatFile);
|
|
6685
|
+
} catch (e) {
|
|
6686
|
+
}
|
|
6687
|
+
}
|
|
6386
6688
|
return history;
|
|
6387
6689
|
});
|
|
6388
6690
|
};
|
|
@@ -8085,8 +8387,10 @@ var init_search_keyword = __esm({
|
|
|
8085
8387
|
"src/tools/search_keyword.js"() {
|
|
8086
8388
|
init_arg_parser();
|
|
8087
8389
|
search_keyword = async (args) => {
|
|
8088
|
-
const { keyword, file } = parseArgs(args);
|
|
8390
|
+
const { keyword, file, subString } = parseArgs(args);
|
|
8089
8391
|
if (!keyword) return 'ERROR: Missing "keyword" argument.';
|
|
8392
|
+
const matchSubstring = subString === true || subString === "true" || subString === 1 || subString === "1" || subString === "true";
|
|
8393
|
+
const wordRegex = new RegExp(`(?<![\\w])${keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![\\w])`, "i");
|
|
8090
8394
|
const excludes = [
|
|
8091
8395
|
"node_modules",
|
|
8092
8396
|
".git",
|
|
@@ -8126,7 +8430,8 @@ var init_search_keyword = __esm({
|
|
|
8126
8430
|
const lines = content.split(/\r?\n/);
|
|
8127
8431
|
const fileMatches = [];
|
|
8128
8432
|
for (let i = 0; i < lines.length; i++) {
|
|
8129
|
-
|
|
8433
|
+
const matched = matchSubstring ? lines[i].toLowerCase().includes(keyword.toLowerCase()) : wordRegex.test(lines[i]);
|
|
8434
|
+
if (matched) {
|
|
8130
8435
|
const displayPath = fileObj.relativePath.replace(/\\/g, "/");
|
|
8131
8436
|
fileMatches.push(`${displayPath} \u2192 ${i + 1}`);
|
|
8132
8437
|
}
|
|
@@ -8142,9 +8447,9 @@ var init_search_keyword = __esm({
|
|
|
8142
8447
|
global.gc();
|
|
8143
8448
|
}
|
|
8144
8449
|
if (matches.length === 0) {
|
|
8145
|
-
return `Found 0 matches for keyword: "${keyword}"${file ? ` in file: ${file}` : ". Try to specify files"}`;
|
|
8450
|
+
return `Found 0 matches for keyword: "${keyword}"${file ? ` in file: ${file}` : ". Try to specify files"} ${matchSubstring ? "(subString mode)" : ""}`;
|
|
8146
8451
|
}
|
|
8147
|
-
let output = `Found ${matches.length} matches:
|
|
8452
|
+
let output = `Found ${matches.length} matches ${matchSubstring ? "(subString mode)" : ""}:
|
|
8148
8453
|
|
|
8149
8454
|
`;
|
|
8150
8455
|
output += matches.join("\n");
|
|
@@ -9142,7 +9447,7 @@ var init_ai = __esm({
|
|
|
9142
9447
|
colorMainWords = (label2) => {
|
|
9143
9448
|
if (!label2) return label2;
|
|
9144
9449
|
return label2.replace(/(?:(\x1b\[\d+m))?([✔✗✖🔍📖→➕↻•])(?:(\x1b\[\d+m))?\s*\b(Created|Read|Edited|Viewed|Auto-Read|List|Generated|Written|Searched|Get Map|Write Canceled|Edit Canceled|Write Cancelled|Edit Denied|Visited|Updated|Reviewed)\b/ig, (match, ansiBefore, icon, ansiAfter, word) => {
|
|
9145
|
-
return `${ansiBefore || ""}${icon}${ansiAfter || ""}
|
|
9450
|
+
return `${ansiBefore || ""}${icon}${ansiAfter || ""} \x1B[95m${word}\x1B[0m`;
|
|
9146
9451
|
});
|
|
9147
9452
|
};
|
|
9148
9453
|
TERMINATION_SIGNAL = false;
|
|
@@ -9162,13 +9467,11 @@ var init_ai = __esm({
|
|
|
9162
9467
|
"moonshotai/kimi-k2.6",
|
|
9163
9468
|
// NVIDIA vision models
|
|
9164
9469
|
"moonshotai/kimi-k2.6",
|
|
9470
|
+
"stepfun-ai/step-3.7-flash",
|
|
9471
|
+
"google/gemma-4-31b-it",
|
|
9472
|
+
"mistralai/mistral-medium-3.5-128b"
|
|
9165
9473
|
// Google models
|
|
9166
|
-
|
|
9167
|
-
"gemini-2.5-flash",
|
|
9168
|
-
"gemini-3-flash-preview",
|
|
9169
|
-
"gemini-3.5-flash",
|
|
9170
|
-
"gemini-3.1-flash-lite",
|
|
9171
|
-
"gemini-3.1-pro-preview"
|
|
9474
|
+
// No need. All models on Gemini API is Multimodal
|
|
9172
9475
|
];
|
|
9173
9476
|
isModelMultimodal = (model) => {
|
|
9174
9477
|
if (!model) return false;
|
|
@@ -9232,7 +9535,7 @@ var init_ai = __esm({
|
|
|
9232
9535
|
}
|
|
9233
9536
|
return fetch(url, options);
|
|
9234
9537
|
};
|
|
9235
|
-
getDeepSeekStream = async function* (apiKey, model, contents, systemInstruction, thinkingLevel, mode, isMultiModal, signal, temperature = 0.
|
|
9538
|
+
getDeepSeekStream = async function* (apiKey, model, contents, systemInstruction, thinkingLevel, mode, isMultiModal, signal, temperature = 0.99) {
|
|
9236
9539
|
const messages = [];
|
|
9237
9540
|
if (systemInstruction) {
|
|
9238
9541
|
messages.push({ role: "system", content: systemInstruction });
|
|
@@ -9364,7 +9667,7 @@ var init_ai = __esm({
|
|
|
9364
9667
|
}
|
|
9365
9668
|
}
|
|
9366
9669
|
};
|
|
9367
|
-
getNVIDIAStream = async function* (apiKey, model, contents, systemInstruction, thinkingLevel, mode, isMultiModal = false, signal, temperature = 0.
|
|
9670
|
+
getNVIDIAStream = async function* (apiKey, model, contents, systemInstruction, thinkingLevel, mode, isMultiModal = false, signal, temperature = 0.99) {
|
|
9368
9671
|
const messages = [];
|
|
9369
9672
|
if (systemInstruction) {
|
|
9370
9673
|
messages.push({ role: "system", content: systemInstruction });
|
|
@@ -9380,7 +9683,7 @@ var init_ai = __esm({
|
|
|
9380
9683
|
const mimeType = part.inlineData.mimeType;
|
|
9381
9684
|
const data = part.inlineData.data;
|
|
9382
9685
|
const isImage = mimeType.startsWith("image/");
|
|
9383
|
-
if (isImage) {
|
|
9686
|
+
if (isImage && MULTIMODAL_MODELS.includes(model)) {
|
|
9384
9687
|
msgContent.push({
|
|
9385
9688
|
type: "image_url",
|
|
9386
9689
|
image_url: {
|
|
@@ -9404,7 +9707,7 @@ var init_ai = __esm({
|
|
|
9404
9707
|
"High": "High",
|
|
9405
9708
|
"xHigh": "High"
|
|
9406
9709
|
};
|
|
9407
|
-
const apiLevel = thinkingLevelMap[thinkingLevel] || "
|
|
9710
|
+
const apiLevel = thinkingLevelMap[thinkingLevel] || "High";
|
|
9408
9711
|
const isThinking = apiLevel !== "Fast";
|
|
9409
9712
|
const isKimi = model.includes("kimi");
|
|
9410
9713
|
const isGemma = model.includes("gemma");
|
|
@@ -9412,6 +9715,15 @@ var init_ai = __esm({
|
|
|
9412
9715
|
const isGlm = model.includes("glm");
|
|
9413
9716
|
const isMistral = model.includes("mistral");
|
|
9414
9717
|
const isMinimax = model.includes("minimax");
|
|
9718
|
+
const isGPT = model.includes("gpt");
|
|
9719
|
+
const GPT_THINKING_LEVELS = {
|
|
9720
|
+
"Fast": "low",
|
|
9721
|
+
"Low": "low",
|
|
9722
|
+
"Medium": "medium",
|
|
9723
|
+
"Standard": "medium",
|
|
9724
|
+
"High": "high",
|
|
9725
|
+
"xHigh": "high"
|
|
9726
|
+
};
|
|
9415
9727
|
const maxTokens = isMinimax || isDeepSeek ? 16384 : 32768;
|
|
9416
9728
|
const body = {
|
|
9417
9729
|
model,
|
|
@@ -9419,7 +9731,8 @@ var init_ai = __esm({
|
|
|
9419
9731
|
max_tokens: maxTokens,
|
|
9420
9732
|
stream: true,
|
|
9421
9733
|
stream_options: { include_usage: true },
|
|
9422
|
-
temperature
|
|
9734
|
+
temperature,
|
|
9735
|
+
...isGPT && { thinking: GPT_THINKING_LEVELS[thinkingLevel] || "high" }
|
|
9423
9736
|
};
|
|
9424
9737
|
if (isKimi) {
|
|
9425
9738
|
body.chat_template_kwargs = { thinking: isThinking };
|
|
@@ -9516,7 +9829,7 @@ var init_ai = __esm({
|
|
|
9516
9829
|
}
|
|
9517
9830
|
}
|
|
9518
9831
|
};
|
|
9519
|
-
getOpenRouterStream = async function* (apiKey, model, contents, systemInstruction, thinkingLevel, mode, isMultiModal, signal, temperature = 0.
|
|
9832
|
+
getOpenRouterStream = async function* (apiKey, model, contents, systemInstruction, thinkingLevel, mode, isMultiModal, signal, temperature = 0.95) {
|
|
9520
9833
|
const messages = [];
|
|
9521
9834
|
if (systemInstruction) {
|
|
9522
9835
|
messages.push({ role: "system", content: systemInstruction });
|
|
@@ -9763,7 +10076,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
9763
10076
|
mode,
|
|
9764
10077
|
false,
|
|
9765
10078
|
null,
|
|
9766
|
-
0.
|
|
10079
|
+
0.75
|
|
9767
10080
|
);
|
|
9768
10081
|
const iterator2 = stream[Symbol.asyncIterator]();
|
|
9769
10082
|
const firstResult2 = await iterator2.next();
|
|
@@ -9779,7 +10092,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
9779
10092
|
mode,
|
|
9780
10093
|
false,
|
|
9781
10094
|
null,
|
|
9782
|
-
0.
|
|
10095
|
+
0.75
|
|
9783
10096
|
);
|
|
9784
10097
|
const iterator2 = stream[Symbol.asyncIterator]();
|
|
9785
10098
|
const firstResult2 = await iterator2.next();
|
|
@@ -9795,7 +10108,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
9795
10108
|
mode,
|
|
9796
10109
|
false,
|
|
9797
10110
|
null,
|
|
9798
|
-
0.
|
|
10111
|
+
0.75
|
|
9799
10112
|
);
|
|
9800
10113
|
const iterator2 = stream[Symbol.asyncIterator]();
|
|
9801
10114
|
const firstResult2 = await iterator2.next();
|
|
@@ -9807,7 +10120,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
9807
10120
|
config: {
|
|
9808
10121
|
systemInstruction: janitorPrompt,
|
|
9809
10122
|
maxOutputTokens: 512,
|
|
9810
|
-
temperature: 0.
|
|
10123
|
+
temperature: 0.75,
|
|
9811
10124
|
safetySettings: [
|
|
9812
10125
|
{ category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
9813
10126
|
{ category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
@@ -10227,7 +10540,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
10227
10540
|
client = new GoogleGenAI({ apiKey });
|
|
10228
10541
|
return client;
|
|
10229
10542
|
};
|
|
10230
|
-
generateSimpleContent = async (settings, model, contents, systemInstruction, thinkingLevel = "Fast", temperature = 0.
|
|
10543
|
+
generateSimpleContent = async (settings, model, contents, systemInstruction, thinkingLevel = "Fast", temperature = 0.75) => {
|
|
10231
10544
|
const { aiProvider = "Google", apiKey, mode } = settings;
|
|
10232
10545
|
let fullText = "";
|
|
10233
10546
|
let usageMetadata = null;
|
|
@@ -10245,7 +10558,6 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
10245
10558
|
contents: normalizedContents,
|
|
10246
10559
|
config: {
|
|
10247
10560
|
systemInstruction,
|
|
10248
|
-
maxOutputTokens: 2048,
|
|
10249
10561
|
temperature,
|
|
10250
10562
|
thinkingConfig: { includeThoughts: false, thinkingLevel: ThinkingLevel.MINIMAL }
|
|
10251
10563
|
}
|
|
@@ -11162,6 +11474,7 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
|
|
|
11162
11474
|
let isStutteringLoop = false;
|
|
11163
11475
|
let isGeneralLoop = false;
|
|
11164
11476
|
let isInitialAttempt = true;
|
|
11477
|
+
let lastLoopCheckLen = 0;
|
|
11165
11478
|
let accumulatedContext = "";
|
|
11166
11479
|
let dedupeBuffer = "";
|
|
11167
11480
|
let isDedupeActive = false;
|
|
@@ -11266,7 +11579,7 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
|
|
|
11266
11579
|
} else if (retryCount > 0) {
|
|
11267
11580
|
yield { type: "model_update", content: null };
|
|
11268
11581
|
}
|
|
11269
|
-
currentSystemInstruction = getSystemInstruction(profile, !(targetModel || "gemma").toLowerCase().startsWith("gemma") ? "GEM" : thinkingLevel, mode, systemSettings, isMemoryEnabled, isFirstPrompt, aiProvider, isMultiModal);
|
|
11582
|
+
currentSystemInstruction = getSystemInstruction(profile, !(targetModel || "gemma").toLowerCase().startsWith("gemma") ? "GEM" : thinkingLevel, mode, systemSettings, isMemoryEnabled, isFirstPrompt, aiProvider, aiProvider === "Google" ? true : isMultiModal);
|
|
11270
11583
|
const lastUserMsg = contents[contents.length - 1];
|
|
11271
11584
|
if (isBridgeConnected() & loop > 0) {
|
|
11272
11585
|
yield { type: "status", content: "Checking Code..." };
|
|
@@ -11314,7 +11627,7 @@ ${ideErr} [/ERROR]`;
|
|
|
11314
11627
|
mode,
|
|
11315
11628
|
isMultiModal,
|
|
11316
11629
|
abortController.signal,
|
|
11317
|
-
0.
|
|
11630
|
+
0.95
|
|
11318
11631
|
);
|
|
11319
11632
|
} else if (aiProvider === "DeepSeek") {
|
|
11320
11633
|
stream = getDeepSeekStream(
|
|
@@ -11326,7 +11639,7 @@ ${ideErr} [/ERROR]`;
|
|
|
11326
11639
|
mode,
|
|
11327
11640
|
isMultiModal,
|
|
11328
11641
|
abortController.signal,
|
|
11329
|
-
0.
|
|
11642
|
+
0.99
|
|
11330
11643
|
);
|
|
11331
11644
|
} else if (aiProvider === "NVIDIA") {
|
|
11332
11645
|
stream = getNVIDIAStream(
|
|
@@ -11338,7 +11651,7 @@ ${ideErr} [/ERROR]`;
|
|
|
11338
11651
|
mode,
|
|
11339
11652
|
isMultiModal,
|
|
11340
11653
|
abortController.signal,
|
|
11341
|
-
0.
|
|
11654
|
+
0.99
|
|
11342
11655
|
);
|
|
11343
11656
|
} else {
|
|
11344
11657
|
const apiCallPromise = client.models.generateContentStream({
|
|
@@ -11347,7 +11660,7 @@ ${ideErr} [/ERROR]`;
|
|
|
11347
11660
|
config: {
|
|
11348
11661
|
systemInstruction: currentSystemInstruction,
|
|
11349
11662
|
mediaResolution: "MEDIA_RESOLUTION_MEDIUM",
|
|
11350
|
-
temperature: 1
|
|
11663
|
+
temperature: 1,
|
|
11351
11664
|
safetySettings: [
|
|
11352
11665
|
{ category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
11353
11666
|
{ category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
@@ -11641,7 +11954,6 @@ ${ideErr} [/ERROR]`;
|
|
|
11641
11954
|
for (const m of msgs) yield m;
|
|
11642
11955
|
}
|
|
11643
11956
|
}
|
|
11644
|
-
const signalSafeText3 = getSanitizedText(turnText);
|
|
11645
11957
|
const toolContext = getActiveToolContext(turnText);
|
|
11646
11958
|
if (toolContext.inside) {
|
|
11647
11959
|
if (!lastToolEventTime) lastToolEventTime = Date.now();
|
|
@@ -11712,78 +12024,60 @@ ${ideErr} [/ERROR]`;
|
|
|
11712
12024
|
}
|
|
11713
12025
|
}
|
|
11714
12026
|
}
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
|
|
11727
|
-
|
|
11728
|
-
|
|
11729
|
-
|
|
11730
|
-
|
|
11731
|
-
|
|
11732
|
-
|
|
11733
|
-
|
|
11734
|
-
|
|
11735
|
-
|
|
11736
|
-
|
|
11737
|
-
const reason = repetitionRatio > repetitionThresholdThinking ? "Reasoning Loop Detected" : "Thinking Budget Exceeded";
|
|
11738
|
-
yield { type: "status", content: `${reason}. Re-centering...` };
|
|
11739
|
-
isThinkingLoop = true;
|
|
11740
|
-
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
11741
|
-
break;
|
|
11742
|
-
}
|
|
11743
|
-
const responseContent = signalSafeText3.trim();
|
|
11744
|
-
const respSentences = responseContent.split(/[.!?]\s+/);
|
|
11745
|
-
const uniqueRespSentences = new Set(respSentences);
|
|
11746
|
-
const respRepetitionRatio = respSentences.length > 10 ? (respSentences.length - uniqueRespSentences.size) / respSentences.length : 0;
|
|
11747
|
-
if (respRepetitionRatio > repetitionThresholdResponse) {
|
|
11748
|
-
yield { type: "status", content: `Response Loop Detected. Re-centering...` };
|
|
11749
|
-
isThinkingLoop = false;
|
|
11750
|
-
isGeneralLoop = true;
|
|
11751
|
-
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
11752
|
-
break;
|
|
11753
|
-
}
|
|
11754
|
-
const allWords = contextSafeText.toLowerCase().split(/\s+/).filter((w) => w.length > 0);
|
|
11755
|
-
let stutterDetected = false;
|
|
11756
|
-
if (allWords.length > 5) {
|
|
11757
|
-
for (let p = 1; p <= 15; p++) {
|
|
11758
|
-
const R = Math.max(3, Math.ceil(8 / p));
|
|
11759
|
-
if (allWords.length < p * R) continue;
|
|
11760
|
-
let isRepeating = true;
|
|
11761
|
-
const pattern = allWords.slice(allWords.length - p);
|
|
11762
|
-
const patternStr = pattern.join(" ");
|
|
11763
|
-
for (let r = 1; r < R; r++) {
|
|
11764
|
-
const prevPattern = allWords.slice(allWords.length - p * (r + 1), allWords.length - p * r);
|
|
11765
|
-
if (prevPattern.join(" ") !== patternStr) {
|
|
11766
|
-
isRepeating = false;
|
|
11767
|
-
break;
|
|
11768
|
-
}
|
|
11769
|
-
}
|
|
11770
|
-
if (isRepeating) {
|
|
11771
|
-
stutterDetected = true;
|
|
11772
|
-
break;
|
|
11773
|
-
}
|
|
12027
|
+
if (turnText.length - lastLoopCheckLen > 150) {
|
|
12028
|
+
lastLoopCheckLen = turnText.length;
|
|
12029
|
+
const contextSafeText = getContextSafeText(turnText, false);
|
|
12030
|
+
const thinkBlocks = contextSafeText.match(/(?:<think>|\[think\])([\s\S]*?)(?:<\/think>|\[\/think\]|$)/gi) || [];
|
|
12031
|
+
const thinkContent = thinkBlocks.join("").trim();
|
|
12032
|
+
const sentences = thinkContent.split(/[.!?]\s+/);
|
|
12033
|
+
const uniqueSentences = new Set(sentences);
|
|
12034
|
+
const repetitionRatio = sentences.length > 10 ? (sentences.length - uniqueSentences.size) / sentences.length : 0;
|
|
12035
|
+
const wordCount = thinkContent.split(/\s+/).filter((w) => w.length > 0).length;
|
|
12036
|
+
let repetitionThresholdThinking = 0.4;
|
|
12037
|
+
let repetitionThresholdResponse = 0.6;
|
|
12038
|
+
let isOverVerboseThinking = false;
|
|
12039
|
+
if ((targetModel || "").toLowerCase().startsWith("gemma")) {
|
|
12040
|
+
const thinkingCaps = {
|
|
12041
|
+
"low": 256,
|
|
12042
|
+
"medium": 768,
|
|
12043
|
+
"high": 2048,
|
|
12044
|
+
"max": 4096,
|
|
12045
|
+
"xhigh": 4096
|
|
12046
|
+
};
|
|
12047
|
+
const cap = thinkingCaps[thinkingLevel?.toLowerCase()] || 2500;
|
|
12048
|
+
isOverVerboseThinking = wordCount > cap;
|
|
11774
12049
|
}
|
|
11775
|
-
|
|
11776
|
-
|
|
11777
|
-
|
|
11778
|
-
|
|
11779
|
-
|
|
11780
|
-
|
|
11781
|
-
|
|
11782
|
-
|
|
12050
|
+
if (repetitionRatio > repetitionThresholdThinking || isOverVerboseThinking) {
|
|
12051
|
+
const reason = repetitionRatio > repetitionThresholdThinking ? "Reasoning Loop Detected" : "Thinking Budget Exceeded";
|
|
12052
|
+
yield { type: "status", content: `${reason}. Re-centering...` };
|
|
12053
|
+
isThinkingLoop = true;
|
|
12054
|
+
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
12055
|
+
break;
|
|
12056
|
+
}
|
|
12057
|
+
const signalSafeText3 = getSanitizedText(turnText);
|
|
12058
|
+
const responseContent = signalSafeText3.trim();
|
|
12059
|
+
const respSentences = responseContent.split(/[.!?]\s+/);
|
|
12060
|
+
const uniqueRespSentences = new Set(respSentences);
|
|
12061
|
+
const respRepetitionRatio = respSentences.length > 10 ? (respSentences.length - uniqueRespSentences.size) / respSentences.length : 0;
|
|
12062
|
+
if (respRepetitionRatio > repetitionThresholdResponse) {
|
|
12063
|
+
yield { type: "status", content: `Response Loop Detected. Re-centering...` };
|
|
12064
|
+
isThinkingLoop = false;
|
|
12065
|
+
isGeneralLoop = true;
|
|
12066
|
+
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
12067
|
+
break;
|
|
12068
|
+
}
|
|
12069
|
+
const allWords = contextSafeText.toLowerCase().split(/\s+/).filter((w) => w.length > 0);
|
|
12070
|
+
let stutterDetected = false;
|
|
12071
|
+
if (allWords.length > 5) {
|
|
12072
|
+
for (let p = 1; p <= 15; p++) {
|
|
12073
|
+
const R = Math.max(3, Math.ceil(8 / p));
|
|
12074
|
+
if (allWords.length < p * R) continue;
|
|
11783
12075
|
let isRepeating = true;
|
|
12076
|
+
const pattern = allWords.slice(allWords.length - p);
|
|
12077
|
+
const patternStr = pattern.join(" ");
|
|
11784
12078
|
for (let r = 1; r < R; r++) {
|
|
11785
|
-
const prevPattern =
|
|
11786
|
-
if (prevPattern !==
|
|
12079
|
+
const prevPattern = allWords.slice(allWords.length - p * (r + 1), allWords.length - p * r);
|
|
12080
|
+
if (prevPattern.join(" ") !== patternStr) {
|
|
11787
12081
|
isRepeating = false;
|
|
11788
12082
|
break;
|
|
11789
12083
|
}
|
|
@@ -11794,13 +12088,35 @@ ${ideErr} [/ERROR]`;
|
|
|
11794
12088
|
}
|
|
11795
12089
|
}
|
|
11796
12090
|
}
|
|
11797
|
-
|
|
11798
|
-
|
|
11799
|
-
|
|
11800
|
-
|
|
11801
|
-
|
|
11802
|
-
|
|
11803
|
-
|
|
12091
|
+
if (!stutterDetected) {
|
|
12092
|
+
const cleanChars = contextSafeText.toLowerCase().replace(/[^a-z0-9]/gi, "");
|
|
12093
|
+
if (cleanChars.length >= 10) {
|
|
12094
|
+
for (let p = 1; p <= 10; p++) {
|
|
12095
|
+
const R = Math.max(4, Math.ceil(12 / p));
|
|
12096
|
+
if (cleanChars.length < p * R) continue;
|
|
12097
|
+
const pattern = cleanChars.substring(cleanChars.length - p);
|
|
12098
|
+
let isRepeating = true;
|
|
12099
|
+
for (let r = 1; r < R; r++) {
|
|
12100
|
+
const prevPattern = cleanChars.substring(cleanChars.length - p * (r + 1), cleanChars.length - p * r);
|
|
12101
|
+
if (prevPattern !== pattern) {
|
|
12102
|
+
isRepeating = false;
|
|
12103
|
+
break;
|
|
12104
|
+
}
|
|
12105
|
+
}
|
|
12106
|
+
if (isRepeating) {
|
|
12107
|
+
stutterDetected = true;
|
|
12108
|
+
break;
|
|
12109
|
+
}
|
|
12110
|
+
}
|
|
12111
|
+
}
|
|
12112
|
+
}
|
|
12113
|
+
if (stutterDetected) {
|
|
12114
|
+
yield { type: "status", content: `Stuttering Detected. Re-centering...` };
|
|
12115
|
+
isThinkingLoop = false;
|
|
12116
|
+
isStutteringLoop = true;
|
|
12117
|
+
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
12118
|
+
break;
|
|
12119
|
+
}
|
|
11804
12120
|
}
|
|
11805
12121
|
const toolActionableText = turnText.replace(/(?:<(think|thought|thoughts)>|\[(think|thought|thoughts)\])[\s\S]*?(?:<\/(think|thought|thoughts)>|\[\/(think|thought|thoughts)\]|$)/gi, "");
|
|
11806
12122
|
const allToolsFound = detectToolCalls(toolActionableText);
|
|
@@ -12952,13 +13268,13 @@ Error Log can be found in ${path19.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
12952
13268
|
});
|
|
12953
13269
|
|
|
12954
13270
|
// src/components/ResumeModal.jsx
|
|
12955
|
-
import React10, { useState as
|
|
13271
|
+
import React10, { useState as useState9, useEffect as useEffect7 } from "react";
|
|
12956
13272
|
import { Box as Box9, Text as Text10, useInput as useInput5 } from "ink";
|
|
12957
13273
|
function ResumeModal({ onSelect, onDelete, onClose }) {
|
|
12958
|
-
const [history, setHistory] =
|
|
12959
|
-
const [keys, setKeys] =
|
|
12960
|
-
const [selectedIndex, setSelectedIndex] =
|
|
12961
|
-
|
|
13274
|
+
const [history, setHistory] = useState9({});
|
|
13275
|
+
const [keys, setKeys] = useState9([]);
|
|
13276
|
+
const [selectedIndex, setSelectedIndex] = useState9(0);
|
|
13277
|
+
useEffect7(() => {
|
|
12962
13278
|
const fetchHistory = async () => {
|
|
12963
13279
|
const h = await loadHistory();
|
|
12964
13280
|
setHistory(h);
|
|
@@ -13044,14 +13360,14 @@ var init_ResumeModal = __esm({
|
|
|
13044
13360
|
});
|
|
13045
13361
|
|
|
13046
13362
|
// src/components/MemoryModal.jsx
|
|
13047
|
-
import React11, { useState as
|
|
13363
|
+
import React11, { useState as useState10, useEffect as useEffect8 } from "react";
|
|
13048
13364
|
import { Box as Box10, Text as Text11, useInput as useInput6, useStdout } from "ink";
|
|
13049
13365
|
function MemoryModal({ onClose }) {
|
|
13050
13366
|
const { stdout } = useStdout();
|
|
13051
13367
|
const columns = stdout?.columns || 80;
|
|
13052
|
-
const [memories, setMemories] =
|
|
13053
|
-
const [selectedIndex, setSelectedIndex] =
|
|
13054
|
-
const [isMemoryOn, setIsMemoryOn] =
|
|
13368
|
+
const [memories, setMemories] = useState10([]);
|
|
13369
|
+
const [selectedIndex, setSelectedIndex] = useState10(0);
|
|
13370
|
+
const [isMemoryOn, setIsMemoryOn] = useState10(true);
|
|
13055
13371
|
const loadMemories = () => {
|
|
13056
13372
|
const data = readEncryptedJson(MEMORIES_FILE, []);
|
|
13057
13373
|
setMemories(data);
|
|
@@ -13063,7 +13379,7 @@ function MemoryModal({ onClose }) {
|
|
|
13063
13379
|
setIsMemoryOn(true);
|
|
13064
13380
|
}
|
|
13065
13381
|
};
|
|
13066
|
-
|
|
13382
|
+
useEffect8(() => {
|
|
13067
13383
|
loadMemories();
|
|
13068
13384
|
}, []);
|
|
13069
13385
|
useInput6((input, key) => {
|
|
@@ -13165,7 +13481,7 @@ var init_MemoryModal = __esm({
|
|
|
13165
13481
|
});
|
|
13166
13482
|
|
|
13167
13483
|
// src/components/UpdateProcessor.jsx
|
|
13168
|
-
import React12, { useState as
|
|
13484
|
+
import React12, { useState as useState11, useEffect as useEffect9 } from "react";
|
|
13169
13485
|
import { Box as Box11, Text as Text12 } from "ink";
|
|
13170
13486
|
import { spawn as spawn2 } from "child_process";
|
|
13171
13487
|
var pty2, SPINNER_FRAMES, UpdateProcessor, UpdateProcessor_default;
|
|
@@ -13180,17 +13496,17 @@ var init_UpdateProcessor = __esm({
|
|
|
13180
13496
|
}
|
|
13181
13497
|
SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
13182
13498
|
UpdateProcessor = ({ latest, current, settings, onClose, onUpdateSettings, onSuccess }) => {
|
|
13183
|
-
const [status, setStatus] =
|
|
13184
|
-
const [log, setLog] =
|
|
13185
|
-
const [error, setError] =
|
|
13186
|
-
const [tick, setTick] =
|
|
13187
|
-
|
|
13499
|
+
const [status, setStatus] = useState11("initializing");
|
|
13500
|
+
const [log, setLog] = useState11("");
|
|
13501
|
+
const [error, setError] = useState11(null);
|
|
13502
|
+
const [tick, setTick] = useState11(0);
|
|
13503
|
+
useEffect9(() => {
|
|
13188
13504
|
const interval = setInterval(() => {
|
|
13189
13505
|
setTick((t) => (t + 1) % 1e3);
|
|
13190
13506
|
}, 33);
|
|
13191
13507
|
return () => clearInterval(interval);
|
|
13192
13508
|
}, []);
|
|
13193
|
-
|
|
13509
|
+
useEffect9(() => {
|
|
13194
13510
|
let child;
|
|
13195
13511
|
const runUpdate = async () => {
|
|
13196
13512
|
const manager = settings.updateManager || "npm";
|
|
@@ -13323,12 +13639,12 @@ var init_UpdateProcessor = __esm({
|
|
|
13323
13639
|
});
|
|
13324
13640
|
|
|
13325
13641
|
// src/components/ParserDownloadModal.jsx
|
|
13326
|
-
import React13, { useState as
|
|
13642
|
+
import React13, { useState as useState12, useEffect as useEffect10 } from "react";
|
|
13327
13643
|
import { Box as Box12, Text as Text13, useInput as useInput7 } from "ink";
|
|
13328
13644
|
function ParserDownloadModal({ onClose }) {
|
|
13329
|
-
const [selectedIndex, setSelectedIndex] =
|
|
13330
|
-
const [status, setStatus] =
|
|
13331
|
-
|
|
13645
|
+
const [selectedIndex, setSelectedIndex] = useState12(0);
|
|
13646
|
+
const [status, setStatus] = useState12({});
|
|
13647
|
+
useEffect10(() => {
|
|
13332
13648
|
const initialStatus = {};
|
|
13333
13649
|
EXTENSIONS.forEach((item) => {
|
|
13334
13650
|
if (isParserInstalled(item.file)) {
|
|
@@ -13829,10 +14145,10 @@ var init_dist = __esm({
|
|
|
13829
14145
|
});
|
|
13830
14146
|
|
|
13831
14147
|
// src/components/RevertModal.jsx
|
|
13832
|
-
import React14, { useState as
|
|
14148
|
+
import React14, { useState as useState13 } from "react";
|
|
13833
14149
|
import { Box as Box14, Text as Text15, useInput as useInput8 } from "ink";
|
|
13834
14150
|
function RevertModal({ prompts, onSelect, onClose }) {
|
|
13835
|
-
const [selectedIndex, setSelectedIndex] =
|
|
14151
|
+
const [selectedIndex, setSelectedIndex] = useState13(0);
|
|
13836
14152
|
useInput8((input, key) => {
|
|
13837
14153
|
if (key.escape) onClose();
|
|
13838
14154
|
if (key.upArrow) setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
@@ -13955,7 +14271,7 @@ __export(app_exports, {
|
|
|
13955
14271
|
default: () => App
|
|
13956
14272
|
});
|
|
13957
14273
|
import os4 from "os";
|
|
13958
|
-
import React15, { useState as
|
|
14274
|
+
import React15, { useState as useState14, useEffect as useEffect11, useRef as useRef3, useMemo as useMemo2 } from "react";
|
|
13959
14275
|
import { Box as Box15, Text as Text16, useInput as useInput9, useStdout as useStdout2, Static } from "ink";
|
|
13960
14276
|
import fs22 from "fs-extra";
|
|
13961
14277
|
import path20 from "path";
|
|
@@ -13965,24 +14281,24 @@ import TextInput4 from "ink-text-input";
|
|
|
13965
14281
|
import SelectInput2 from "ink-select-input";
|
|
13966
14282
|
import gradient2 from "gradient-string";
|
|
13967
14283
|
function App({ args = [] }) {
|
|
13968
|
-
const [confirmExit, setConfirmExit] =
|
|
13969
|
-
const [exitCountdown, setExitCountdown] =
|
|
14284
|
+
const [confirmExit, setConfirmExit] = useState14(false);
|
|
14285
|
+
const [exitCountdown, setExitCountdown] = useState14(10);
|
|
13970
14286
|
const { stdout } = useStdout2();
|
|
13971
|
-
const [input, setInput] =
|
|
13972
|
-
const [inputKey, setInputKey] =
|
|
13973
|
-
const [isExpanded, setIsExpanded] =
|
|
13974
|
-
const [mode, setMode] =
|
|
13975
|
-
const [terminalSize, setTerminalSize] =
|
|
14287
|
+
const [input, setInput] = useState14("");
|
|
14288
|
+
const [inputKey, setInputKey] = useState14(0);
|
|
14289
|
+
const [isExpanded, setIsExpanded] = useState14(false);
|
|
14290
|
+
const [mode, setMode] = useState14("Flux");
|
|
14291
|
+
const [terminalSize, setTerminalSize] = useState14({
|
|
13976
14292
|
columns: stdout?.columns || 80,
|
|
13977
14293
|
rows: stdout?.rows || 24
|
|
13978
14294
|
});
|
|
13979
|
-
const [selectedIndex, setSelectedIndex] =
|
|
13980
|
-
const [isFilePickerDismissed, setIsFilePickerDismissed] =
|
|
13981
|
-
const [showBridgePromo, setShowBridgePromo] =
|
|
13982
|
-
const [promoSelectedIndex, setPromoSelectedIndex] =
|
|
14295
|
+
const [selectedIndex, setSelectedIndex] = useState14(0);
|
|
14296
|
+
const [isFilePickerDismissed, setIsFilePickerDismissed] = useState14(false);
|
|
14297
|
+
const [showBridgePromo, setShowBridgePromo] = useState14(false);
|
|
14298
|
+
const [promoSelectedIndex, setPromoSelectedIndex] = useState14(0);
|
|
13983
14299
|
const suggestionOffsetRef = useRef3(0);
|
|
13984
14300
|
const persistedModelRef = useRef3(null);
|
|
13985
|
-
|
|
14301
|
+
useEffect11(() => {
|
|
13986
14302
|
const ideName = getIDEName();
|
|
13987
14303
|
const isIDE = !["Terminal", "Windows Terminal"].includes(ideName) || !!process.env.VSC_TERMINAL_URL;
|
|
13988
14304
|
const graceTimer = setTimeout(() => {
|
|
@@ -14157,7 +14473,7 @@ function App({ args = [] }) {
|
|
|
14157
14473
|
}
|
|
14158
14474
|
}
|
|
14159
14475
|
};
|
|
14160
|
-
|
|
14476
|
+
useEffect11(() => {
|
|
14161
14477
|
const handleResize = () => {
|
|
14162
14478
|
stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
14163
14479
|
setTerminalSize({
|
|
@@ -14170,18 +14486,18 @@ function App({ args = [] }) {
|
|
|
14170
14486
|
stdout.off("resize", handleResize);
|
|
14171
14487
|
};
|
|
14172
14488
|
}, [stdout]);
|
|
14173
|
-
const [thinkingLevel, setThinkingLevel] =
|
|
14174
|
-
const [aiProvider, setAiProvider] =
|
|
14175
|
-
const [setupStep, setSetupStep] =
|
|
14176
|
-
const [latestVer, setLatestVer] =
|
|
14177
|
-
const [showFullThinking, setShowFullThinking] =
|
|
14178
|
-
const [activeModel, setActiveModel] =
|
|
14179
|
-
const [janitorModel, setJanitorModel] =
|
|
14180
|
-
const [isInitializing, setIsInitializing] =
|
|
14181
|
-
const [isAppFocused, setIsAppFocused] =
|
|
14489
|
+
const [thinkingLevel, setThinkingLevel] = useState14("Medium");
|
|
14490
|
+
const [aiProvider, setAiProvider] = useState14("Google");
|
|
14491
|
+
const [setupStep, setSetupStep] = useState14(0);
|
|
14492
|
+
const [latestVer, setLatestVer] = useState14(null);
|
|
14493
|
+
const [showFullThinking, setShowFullThinking] = useState14(false);
|
|
14494
|
+
const [activeModel, setActiveModel] = useState14("gemma-4-31b-it");
|
|
14495
|
+
const [janitorModel, setJanitorModel] = useState14("gemma-4-26b-a4b-it");
|
|
14496
|
+
const [isInitializing, setIsInitializing] = useState14(true);
|
|
14497
|
+
const [isAppFocused, setIsAppFocused] = useState14(true);
|
|
14182
14498
|
const lastFocusEventTime = useRef3(0);
|
|
14183
|
-
const [apiKey, setApiKey] =
|
|
14184
|
-
const [tempKey, setTempKey] =
|
|
14499
|
+
const [apiKey, setApiKey] = useState14(null);
|
|
14500
|
+
const [tempKey, setTempKey] = useState14("");
|
|
14185
14501
|
const addShiftEnterBinding = async (ideName) => {
|
|
14186
14502
|
const kbPath = getKeybindingsPath(ideName);
|
|
14187
14503
|
if (!kbPath) return;
|
|
@@ -14232,35 +14548,35 @@ function App({ args = [] }) {
|
|
|
14232
14548
|
});
|
|
14233
14549
|
}
|
|
14234
14550
|
};
|
|
14235
|
-
const [activeView, setActiveView] =
|
|
14236
|
-
const [apiTier, setApiTier] =
|
|
14237
|
-
const [quotas, setQuotas] =
|
|
14238
|
-
const [inputConfig, setInputConfig] =
|
|
14239
|
-
const [systemSettings, setSystemSettings] =
|
|
14240
|
-
const [profileData, setProfileData] =
|
|
14241
|
-
const [imageSettings, setImageSettings] =
|
|
14242
|
-
const [sessionStats, setSessionStats] =
|
|
14243
|
-
const [sessionAgentCalls, setSessionAgentCalls] =
|
|
14244
|
-
const [sessionBackgroundCalls, setSessionBackgroundCalls] =
|
|
14245
|
-
const [sessionTotalTokens, setSessionTotalTokens] =
|
|
14246
|
-
const [chatTokens, setChatTokens] =
|
|
14551
|
+
const [activeView, setActiveView] = useState14("chat");
|
|
14552
|
+
const [apiTier, setApiTier] = useState14("Free");
|
|
14553
|
+
const [quotas, setQuotas] = useState14({ limitMode: "Daily", agentLimit: 99999999, tokenLimit: 99999999999999, backgroundLimit: 999999, searchLimit: 100, customModelId: "", customLimit: 0 });
|
|
14554
|
+
const [inputConfig, setInputConfig] = useState14(null);
|
|
14555
|
+
const [systemSettings, setSystemSettings] = useState14({ memory: true, compression: 0, autoExec: false, autoDeleteHistory: "7d", autoUpdate: false, updateManager: "npm", customUpdateCommand: "" });
|
|
14556
|
+
const [profileData, setProfileData] = useState14({ name: null, nickname: null, instructions: null });
|
|
14557
|
+
const [imageSettings, setImageSettings] = useState14({ keyType: "Default", quality: "Low-High", apiKey: "" });
|
|
14558
|
+
const [sessionStats, setSessionStats] = useState14({ tokens: 0 });
|
|
14559
|
+
const [sessionAgentCalls, setSessionAgentCalls] = useState14(0);
|
|
14560
|
+
const [sessionBackgroundCalls, setSessionBackgroundCalls] = useState14(0);
|
|
14561
|
+
const [sessionTotalTokens, setSessionTotalTokens] = useState14(0);
|
|
14562
|
+
const [chatTokens, setChatTokens] = useState14(0);
|
|
14247
14563
|
const chatTokenStartRef = useRef3(0);
|
|
14248
|
-
const [sessionTotalCachedTokens, setSessionTotalCachedTokens] =
|
|
14249
|
-
const [sessionTotalCandidateTokens, setSessionTotalCandidateTokens] =
|
|
14250
|
-
const [sessionToolSuccess, setSessionToolSuccess] =
|
|
14251
|
-
const [sessionToolFailure, setSessionToolFailure] =
|
|
14252
|
-
const [sessionToolDenied, setSessionToolDenied] =
|
|
14253
|
-
const [sessionApiTime, setSessionApiTime] =
|
|
14254
|
-
const [sessionToolTime, setSessionToolTime] =
|
|
14255
|
-
const [sessionImageCount, setSessionImageCount] =
|
|
14256
|
-
const [sessionImageCredits, setSessionImageCredits] =
|
|
14257
|
-
const [dailyUsage, setDailyUsage] =
|
|
14258
|
-
const [monthlyUsage, setMonthlyUsage] =
|
|
14259
|
-
const [customPeriodUsage, setCustomPeriodUsage] =
|
|
14260
|
-
const [statsMode, setStatsMode] =
|
|
14564
|
+
const [sessionTotalCachedTokens, setSessionTotalCachedTokens] = useState14(0);
|
|
14565
|
+
const [sessionTotalCandidateTokens, setSessionTotalCandidateTokens] = useState14(0);
|
|
14566
|
+
const [sessionToolSuccess, setSessionToolSuccess] = useState14(0);
|
|
14567
|
+
const [sessionToolFailure, setSessionToolFailure] = useState14(0);
|
|
14568
|
+
const [sessionToolDenied, setSessionToolDenied] = useState14(0);
|
|
14569
|
+
const [sessionApiTime, setSessionApiTime] = useState14(0);
|
|
14570
|
+
const [sessionToolTime, setSessionToolTime] = useState14(0);
|
|
14571
|
+
const [sessionImageCount, setSessionImageCount] = useState14(0);
|
|
14572
|
+
const [sessionImageCredits, setSessionImageCredits] = useState14(0);
|
|
14573
|
+
const [dailyUsage, setDailyUsage] = useState14(null);
|
|
14574
|
+
const [monthlyUsage, setMonthlyUsage] = useState14(null);
|
|
14575
|
+
const [customPeriodUsage, setCustomPeriodUsage] = useState14(null);
|
|
14576
|
+
const [statsMode, setStatsMode] = useState14("daily");
|
|
14261
14577
|
const PLAYGROUND_CHAT_ID = "flow-playground";
|
|
14262
|
-
const [chatId, setChatId] =
|
|
14263
|
-
|
|
14578
|
+
const [chatId, setChatId] = useState14(args.includes("--playground") ? PLAYGROUND_CHAT_ID : generateChatId());
|
|
14579
|
+
useEffect11(() => {
|
|
14264
14580
|
const nextTokens = sessionTotalTokens - chatTokenStartRef.current;
|
|
14265
14581
|
setChatTokens(nextTokens);
|
|
14266
14582
|
if (chatId) {
|
|
@@ -14268,7 +14584,7 @@ function App({ args = [] }) {
|
|
|
14268
14584
|
});
|
|
14269
14585
|
}
|
|
14270
14586
|
}, [sessionTotalTokens, chatId, sessionStats.tokens]);
|
|
14271
|
-
|
|
14587
|
+
useEffect11(() => {
|
|
14272
14588
|
if (activeView === "apiTier") {
|
|
14273
14589
|
const load = async () => {
|
|
14274
14590
|
const d = await getDailyUsage();
|
|
@@ -14281,17 +14597,17 @@ function App({ args = [] }) {
|
|
|
14281
14597
|
load();
|
|
14282
14598
|
}
|
|
14283
14599
|
}, [activeView, quotas.resetDay]);
|
|
14284
|
-
const [activeCommand, setActiveCommand] =
|
|
14285
|
-
const [execOutput, setExecOutput] =
|
|
14286
|
-
const [isTerminalFocused, setIsTerminalFocused] =
|
|
14287
|
-
const [tick, setTick] =
|
|
14600
|
+
const [activeCommand, setActiveCommand] = useState14(null);
|
|
14601
|
+
const [execOutput, setExecOutput] = useState14("");
|
|
14602
|
+
const [isTerminalFocused, setIsTerminalFocused] = useState14(false);
|
|
14603
|
+
const [tick, setTick] = useState14(0);
|
|
14288
14604
|
const isFirstRender = useRef3(true);
|
|
14289
14605
|
const isSecondRender = useRef3(true);
|
|
14290
14606
|
const isThirdRender = useRef3(true);
|
|
14291
14607
|
const prevProviderRef = useRef3(aiProvider);
|
|
14292
14608
|
const originalAllowExternalAccessRef = useRef3(false);
|
|
14293
14609
|
const originalMemoryRef = useRef3(true);
|
|
14294
|
-
|
|
14610
|
+
useEffect11(() => {
|
|
14295
14611
|
if (prevProviderRef.current !== aiProvider) {
|
|
14296
14612
|
prevProviderRef.current = aiProvider;
|
|
14297
14613
|
const hasStandard = aiProvider === "DeepSeek" || aiProvider === "NVIDIA";
|
|
@@ -14304,7 +14620,7 @@ function App({ args = [] }) {
|
|
|
14304
14620
|
}
|
|
14305
14621
|
}
|
|
14306
14622
|
}, [aiProvider, activeModel, thinkingLevel]);
|
|
14307
|
-
|
|
14623
|
+
useEffect11(() => {
|
|
14308
14624
|
if (!apiKey) return;
|
|
14309
14625
|
if (isFirstRender.current) {
|
|
14310
14626
|
isFirstRender.current = false;
|
|
@@ -14378,15 +14694,15 @@ function App({ args = [] }) {
|
|
|
14378
14694
|
}, []);
|
|
14379
14695
|
const activeCommandRef = useRef3(null);
|
|
14380
14696
|
const execOutputRef = useRef3("");
|
|
14381
|
-
|
|
14697
|
+
useEffect11(() => {
|
|
14382
14698
|
activeCommandRef.current = activeCommand;
|
|
14383
14699
|
}, [activeCommand]);
|
|
14384
|
-
|
|
14700
|
+
useEffect11(() => {
|
|
14385
14701
|
execOutputRef.current = execOutput;
|
|
14386
14702
|
}, [execOutput]);
|
|
14387
|
-
const [autoAcceptWrites, setAutoAcceptWrites] =
|
|
14388
|
-
const [pendingApproval, setPendingApproval] =
|
|
14389
|
-
const [pendingAsk, setPendingAsk] =
|
|
14703
|
+
const [autoAcceptWrites, setAutoAcceptWrites] = useState14(false);
|
|
14704
|
+
const [pendingApproval, setPendingApproval] = useState14(null);
|
|
14705
|
+
const [pendingAsk, setPendingAsk] = useState14(null);
|
|
14390
14706
|
const resetPendingApproval = (decision) => {
|
|
14391
14707
|
setPendingApproval(null);
|
|
14392
14708
|
setActiveView("chat");
|
|
@@ -14405,10 +14721,10 @@ function App({ args = [] }) {
|
|
|
14405
14721
|
if (ms < 1e3) return `${ms}ms`;
|
|
14406
14722
|
return formatDuration(Math.floor(ms / 1e3));
|
|
14407
14723
|
};
|
|
14408
|
-
const [statusText, setStatusText] =
|
|
14409
|
-
const [wittyPhrase, setWittyPhrase] =
|
|
14410
|
-
const [hasPasteBlock, setHasPasteBlock] =
|
|
14411
|
-
|
|
14724
|
+
const [statusText, setStatusText] = useState14(null);
|
|
14725
|
+
const [wittyPhrase, setWittyPhrase] = useState14("");
|
|
14726
|
+
const [hasPasteBlock, setHasPasteBlock] = useState14(false);
|
|
14727
|
+
useEffect11(() => {
|
|
14412
14728
|
let interval;
|
|
14413
14729
|
if (statusText) {
|
|
14414
14730
|
const updatePhrase = () => {
|
|
@@ -14422,20 +14738,20 @@ function App({ args = [] }) {
|
|
|
14422
14738
|
}
|
|
14423
14739
|
return () => clearInterval(interval);
|
|
14424
14740
|
}, [statusText]);
|
|
14425
|
-
const [isSpinnerActive, setIsSpinnerActive] =
|
|
14426
|
-
const [isProcessing, setIsProcessing] =
|
|
14427
|
-
const [isCompressing, setIsCompressing] =
|
|
14428
|
-
const [escPressed, setEscPressed] =
|
|
14429
|
-
const [escTimer, setEscTimer] =
|
|
14430
|
-
const [escPressCount, setEscPressCount] =
|
|
14431
|
-
const [recentPrompts, setRecentPrompts] =
|
|
14741
|
+
const [isSpinnerActive, setIsSpinnerActive] = useState14(true);
|
|
14742
|
+
const [isProcessing, setIsProcessing] = useState14(false);
|
|
14743
|
+
const [isCompressing, setIsCompressing] = useState14(false);
|
|
14744
|
+
const [escPressed, setEscPressed] = useState14(false);
|
|
14745
|
+
const [escTimer, setEscTimer] = useState14(null);
|
|
14746
|
+
const [escPressCount, setEscPressCount] = useState14(0);
|
|
14747
|
+
const [recentPrompts, setRecentPrompts] = useState14([]);
|
|
14432
14748
|
const escDoubleTimerRef = useRef3(null);
|
|
14433
14749
|
const didSignalTerminationRef = useRef3(false);
|
|
14434
|
-
const [queuedPrompt, setQueuedPrompt] =
|
|
14435
|
-
const [resolutionData, setResolutionData] =
|
|
14436
|
-
const [tempModelOverride, setTempModelOverride] =
|
|
14437
|
-
|
|
14438
|
-
const [messages, rawSetMessages] =
|
|
14750
|
+
const [queuedPrompt, setQueuedPrompt] = useState14(null);
|
|
14751
|
+
const [resolutionData, setResolutionData] = useState14(null);
|
|
14752
|
+
const [tempModelOverride, setTempModelOverride] = useState14(null);
|
|
14753
|
+
useEffect11(() => setEscPressCount(0), [input]);
|
|
14754
|
+
const [messages, rawSetMessages] = useState14(() => {
|
|
14439
14755
|
const logoMsg = { id: "logo-" + Date.now(), role: "system", isLogo: true, isMeta: true };
|
|
14440
14756
|
const isHomeDir = process.cwd() === os4.homedir();
|
|
14441
14757
|
const isSystemDir = (() => {
|
|
@@ -14473,24 +14789,22 @@ function App({ args = [] }) {
|
|
|
14473
14789
|
const setMessages = (value) => {
|
|
14474
14790
|
rawSetMessages((prev) => {
|
|
14475
14791
|
const next = typeof value === "function" ? value(prev) : value;
|
|
14476
|
-
|
|
14477
|
-
|
|
14478
|
-
const
|
|
14479
|
-
|
|
14480
|
-
|
|
14481
|
-
continue;
|
|
14792
|
+
if (next.length > 1) {
|
|
14793
|
+
const last = next[next.length - 1];
|
|
14794
|
+
const secondLast = next[next.length - 2];
|
|
14795
|
+
if (last?.text?.includes("Request Cancelled") && secondLast?.text?.includes("Request Cancelled")) {
|
|
14796
|
+
return next.slice(0, -1);
|
|
14482
14797
|
}
|
|
14483
|
-
cleaned.push(msg);
|
|
14484
14798
|
}
|
|
14485
|
-
return
|
|
14799
|
+
return next;
|
|
14486
14800
|
});
|
|
14487
14801
|
};
|
|
14488
14802
|
const queuedPromptRef = useRef3(null);
|
|
14489
|
-
const [btwResponse, setBtwResponse] =
|
|
14490
|
-
const [showBtwBox, setShowBtwBox] =
|
|
14803
|
+
const [btwResponse, setBtwResponse] = useState14("");
|
|
14804
|
+
const [showBtwBox, setShowBtwBox] = useState14(false);
|
|
14491
14805
|
const btwResponseRef = useRef3("");
|
|
14492
14806
|
const btwClosedRef = useRef3(null);
|
|
14493
|
-
|
|
14807
|
+
useEffect11(() => {
|
|
14494
14808
|
if (messages.length === 0) return;
|
|
14495
14809
|
const lastMsg = messages[messages.length - 1];
|
|
14496
14810
|
if (lastMsg && (lastMsg.role === "agent" || lastMsg.role === "assistant")) {
|
|
@@ -14508,59 +14822,105 @@ function App({ args = [] }) {
|
|
|
14508
14822
|
}
|
|
14509
14823
|
}
|
|
14510
14824
|
}, [messages]);
|
|
14511
|
-
const [completedIndex, setCompletedIndex] =
|
|
14512
|
-
const [clearKey, setClearKey] =
|
|
14825
|
+
const [completedIndex, setCompletedIndex] = useState14(messages.length);
|
|
14826
|
+
const [clearKey, setClearKey] = useState14(0);
|
|
14827
|
+
const lastCompletedBlocksRef = useRef3([]);
|
|
14828
|
+
const cachedHistoryRef = useRef3({
|
|
14829
|
+
completedIndex: 0,
|
|
14830
|
+
columns: 0,
|
|
14831
|
+
historicalBlocks: [],
|
|
14832
|
+
seenSelections: /* @__PURE__ */ new Set()
|
|
14833
|
+
});
|
|
14513
14834
|
const parsedBlocks = useMemo2(() => {
|
|
14514
|
-
const completed = [];
|
|
14515
|
-
const active = [];
|
|
14516
14835
|
const columns = terminalSize.columns || 80;
|
|
14517
|
-
const
|
|
14518
|
-
|
|
14519
|
-
|
|
14520
|
-
const
|
|
14521
|
-
|
|
14522
|
-
|
|
14523
|
-
|
|
14524
|
-
|
|
14525
|
-
|
|
14526
|
-
|
|
14527
|
-
|
|
14528
|
-
|
|
14836
|
+
const SELECTION_REGEX = /Selection: (.*)/;
|
|
14837
|
+
let historicalBlocks = [];
|
|
14838
|
+
let seenAskSelections = /* @__PURE__ */ new Set();
|
|
14839
|
+
const isResize = cachedHistoryRef.current.columns !== columns;
|
|
14840
|
+
const isClear = completedIndex < cachedHistoryRef.current.completedIndex;
|
|
14841
|
+
if (isResize || isClear) {
|
|
14842
|
+
const completedMsgs = messages.slice(0, completedIndex);
|
|
14843
|
+
for (let i = 0; i < completedMsgs.length; i++) {
|
|
14844
|
+
const msg = completedMsgs[i];
|
|
14845
|
+
if (msg.isAskRecord && msg.text) {
|
|
14846
|
+
const match = msg.text.match(SELECTION_REGEX);
|
|
14847
|
+
if (match && match[1].trim()) {
|
|
14848
|
+
const selection = match[1].trim();
|
|
14849
|
+
if (seenAskSelections.has(selection)) continue;
|
|
14529
14850
|
seenAskSelections.add(selection);
|
|
14530
14851
|
}
|
|
14531
14852
|
}
|
|
14532
|
-
|
|
14533
|
-
|
|
14534
|
-
|
|
14535
|
-
|
|
14536
|
-
|
|
14537
|
-
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
|
|
14542
|
-
|
|
14853
|
+
const parsed = parseMessageToBlocks(msg, columns);
|
|
14854
|
+
for (let j = 0; j < parsed.completed.length; j++) historicalBlocks.push(parsed.completed[j]);
|
|
14855
|
+
for (let j = 0; j < parsed.active.length; j++) historicalBlocks.push(parsed.active[j]);
|
|
14856
|
+
}
|
|
14857
|
+
cachedHistoryRef.current = {
|
|
14858
|
+
completedIndex,
|
|
14859
|
+
columns,
|
|
14860
|
+
historicalBlocks,
|
|
14861
|
+
seenSelections: new Set(seenAskSelections)
|
|
14862
|
+
};
|
|
14863
|
+
} else {
|
|
14864
|
+
historicalBlocks = cachedHistoryRef.current.historicalBlocks;
|
|
14865
|
+
seenAskSelections = cachedHistoryRef.current.seenSelections;
|
|
14866
|
+
if (completedIndex > cachedHistoryRef.current.completedIndex) {
|
|
14867
|
+
historicalBlocks = [...historicalBlocks];
|
|
14868
|
+
seenAskSelections = new Set(seenAskSelections);
|
|
14869
|
+
const newMsgs = messages.slice(cachedHistoryRef.current.completedIndex, completedIndex);
|
|
14870
|
+
for (let i = 0; i < newMsgs.length; i++) {
|
|
14871
|
+
const msg = newMsgs[i];
|
|
14872
|
+
if (msg.isAskRecord && msg.text) {
|
|
14873
|
+
const match = msg.text.match(SELECTION_REGEX);
|
|
14874
|
+
if (match && match[1].trim()) {
|
|
14875
|
+
const selection = match[1].trim();
|
|
14876
|
+
if (seenAskSelections.has(selection)) continue;
|
|
14877
|
+
seenAskSelections.add(selection);
|
|
14878
|
+
}
|
|
14879
|
+
}
|
|
14880
|
+
const parsed = parseMessageToBlocks(msg, columns);
|
|
14881
|
+
for (let j = 0; j < parsed.completed.length; j++) historicalBlocks.push(parsed.completed[j]);
|
|
14882
|
+
for (let j = 0; j < parsed.active.length; j++) historicalBlocks.push(parsed.active[j]);
|
|
14883
|
+
}
|
|
14884
|
+
cachedHistoryRef.current = {
|
|
14885
|
+
completedIndex,
|
|
14886
|
+
columns,
|
|
14887
|
+
historicalBlocks,
|
|
14888
|
+
seenSelections: seenAskSelections
|
|
14889
|
+
};
|
|
14890
|
+
}
|
|
14891
|
+
}
|
|
14892
|
+
const activeMsgs = messages.slice(completedIndex);
|
|
14893
|
+
const streamingCompletedBlocks = [];
|
|
14894
|
+
const activeBlocks = [];
|
|
14895
|
+
for (let i = 0; i < activeMsgs.length; i++) {
|
|
14896
|
+
const msg = activeMsgs[i];
|
|
14897
|
+
if (msg.isAskRecord && msg.text) {
|
|
14898
|
+
const match = msg.text.match(SELECTION_REGEX);
|
|
14899
|
+
if (match && match[1].trim()) {
|
|
14900
|
+
const selection = match[1].trim();
|
|
14901
|
+
if (seenAskSelections.has(selection)) continue;
|
|
14902
|
+
}
|
|
14903
|
+
}
|
|
14543
14904
|
const parsed = parseMessageToBlocks(msg, columns);
|
|
14544
|
-
completed.push(
|
|
14545
|
-
active.push(
|
|
14546
|
-
}
|
|
14547
|
-
const
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
key: "memory-warning-block",
|
|
14905
|
+
for (let j = 0; j < parsed.completed.length; j++) streamingCompletedBlocks.push(parsed.completed[j]);
|
|
14906
|
+
for (let j = 0; j < parsed.active.length; j++) activeBlocks.push(parsed.active[j]);
|
|
14907
|
+
}
|
|
14908
|
+
const finalCompleted = historicalBlocks.concat(streamingCompletedBlocks);
|
|
14909
|
+
if (finalCompleted.length >= 75e3) {
|
|
14910
|
+
finalCompleted.push({
|
|
14911
|
+
key: `memory-warning-block-${finalCompleted.length}`,
|
|
14552
14912
|
msg: {
|
|
14553
14913
|
role: "system",
|
|
14554
14914
|
text: `\u26A0\uFE0F MEMORY WARNING: CHAT IS GETTING VERY LONG`,
|
|
14555
|
-
subText: `This session has reached ${
|
|
14915
|
+
subText: `This session has reached ${finalCompleted.length} blocks. To maintain optimal performance and prevent high memory usage, it is highly recommended to save and start a clean chat with /clear.`,
|
|
14556
14916
|
isHomeWarning: true
|
|
14557
14917
|
},
|
|
14558
14918
|
type: "full-message"
|
|
14559
14919
|
});
|
|
14560
14920
|
}
|
|
14561
14921
|
return {
|
|
14562
|
-
completed:
|
|
14563
|
-
active
|
|
14922
|
+
completed: finalCompleted,
|
|
14923
|
+
active: activeBlocks
|
|
14564
14924
|
};
|
|
14565
14925
|
}, [messages, completedIndex, terminalSize.columns]);
|
|
14566
14926
|
const isTerminalWaitingForInput = useMemo2(() => {
|
|
@@ -14749,7 +15109,7 @@ function App({ args = [] }) {
|
|
|
14749
15109
|
setInput((prev) => prev.replace(/\\\r?$/, "").replace(/\r?$/, "") + "\n");
|
|
14750
15110
|
}
|
|
14751
15111
|
});
|
|
14752
|
-
|
|
15112
|
+
useEffect11(() => {
|
|
14753
15113
|
process.stdout.write("\x1B[?1004h");
|
|
14754
15114
|
const onData = (data) => {
|
|
14755
15115
|
const str = data.toString();
|
|
@@ -14767,7 +15127,7 @@ function App({ args = [] }) {
|
|
|
14767
15127
|
process.stdin.off("data", onData);
|
|
14768
15128
|
};
|
|
14769
15129
|
}, []);
|
|
14770
|
-
|
|
15130
|
+
useEffect11(() => {
|
|
14771
15131
|
async function init() {
|
|
14772
15132
|
try {
|
|
14773
15133
|
const pkg = JSON.parse(fs22.readFileSync(path20.join(process.cwd(), "package.json"), "utf8"));
|
|
@@ -14986,7 +15346,7 @@ function App({ args = [] }) {
|
|
|
14986
15346
|
}
|
|
14987
15347
|
init();
|
|
14988
15348
|
}, []);
|
|
14989
|
-
|
|
15349
|
+
useEffect11(() => {
|
|
14990
15350
|
let timer;
|
|
14991
15351
|
if (confirmExit) {
|
|
14992
15352
|
setExitCountdown(10);
|
|
@@ -15004,7 +15364,7 @@ function App({ args = [] }) {
|
|
|
15004
15364
|
if (timer) clearInterval(timer);
|
|
15005
15365
|
};
|
|
15006
15366
|
}, [confirmExit]);
|
|
15007
|
-
|
|
15367
|
+
useEffect11(() => {
|
|
15008
15368
|
if (!isInitializing) {
|
|
15009
15369
|
const modelToSave = parsedArgs.model && activeModel === parsedArgs.model ? persistedModelRef.current : activeModel;
|
|
15010
15370
|
let settingsToSave = systemSettings;
|
|
@@ -15054,7 +15414,7 @@ function App({ args = [] }) {
|
|
|
15054
15414
|
}
|
|
15055
15415
|
};
|
|
15056
15416
|
const lastSavedTimeRef = useRef3(SESSION_START_TIME);
|
|
15057
|
-
|
|
15417
|
+
useEffect11(() => {
|
|
15058
15418
|
if (activeView === "exit") {
|
|
15059
15419
|
const flush = async () => {
|
|
15060
15420
|
const now = Date.now();
|
|
@@ -15072,7 +15432,7 @@ function App({ args = [] }) {
|
|
|
15072
15432
|
return () => clearTimeout(timer);
|
|
15073
15433
|
}
|
|
15074
15434
|
}, [activeView]);
|
|
15075
|
-
|
|
15435
|
+
useEffect11(() => {
|
|
15076
15436
|
const interval = setInterval(async () => {
|
|
15077
15437
|
if (!isInitializing) {
|
|
15078
15438
|
const now = Date.now();
|
|
@@ -15082,7 +15442,7 @@ function App({ args = [] }) {
|
|
|
15082
15442
|
lastSavedTimeRef.current += deltaSecs * 1e3;
|
|
15083
15443
|
}
|
|
15084
15444
|
}
|
|
15085
|
-
},
|
|
15445
|
+
}, 2e3);
|
|
15086
15446
|
return () => clearInterval(interval);
|
|
15087
15447
|
}, [isInitializing]);
|
|
15088
15448
|
const COMMANDS = [
|
|
@@ -15098,32 +15458,6 @@ function App({ args = [] }) {
|
|
|
15098
15458
|
{ cmd: "/export", desc: "Export current chat in a .txt file" },
|
|
15099
15459
|
{ cmd: "/chats", desc: "List all chat sessions" },
|
|
15100
15460
|
{ cmd: "/btw", desc: "Ask a question without intefering with ongoing tasks" },
|
|
15101
|
-
// {
|
|
15102
|
-
// cmd: '/image', desc: 'Generate images using Pollinations', subs: [
|
|
15103
|
-
// {
|
|
15104
|
-
// cmd: 'setup', desc: 'Configure defaults', subs: [
|
|
15105
|
-
// {
|
|
15106
|
-
// cmd: 'key', desc: 'Set API key strategy', subs: [
|
|
15107
|
-
// { cmd: 'default', desc: 'Default (Quota: Dynamic 25 max/hr)' },
|
|
15108
|
-
// { cmd: 'custom', desc: 'Custom Key' }
|
|
15109
|
-
// ]
|
|
15110
|
-
// },
|
|
15111
|
-
// {
|
|
15112
|
-
// cmd: 'quality', desc: 'Set default quality', subs: [
|
|
15113
|
-
// { cmd: 'low', desc: imageSettings?.keyType === 'Custom' ? '(0.001/img)' : '(1/img)' },
|
|
15114
|
-
// { cmd: 'low-high', desc: imageSettings?.keyType === 'Custom' ? '(0.002/img)' : '(2/img)' },
|
|
15115
|
-
// { cmd: 'medium', desc: imageSettings?.keyType === 'Custom' ? '(0.008/img)' : '(8/img)' },
|
|
15116
|
-
// { cmd: 'medium-high', desc: imageSettings?.keyType === 'Custom' ? '(0.01/img)' : '(10/img)' },
|
|
15117
|
-
// { cmd: 'high', desc: imageSettings?.keyType === 'Custom' ? '(0.045/img)' : '(45/img)' },
|
|
15118
|
-
// { cmd: 'ultra', desc: imageSettings?.keyType === 'Custom' ? '(0.0488/img)' : '(49/img)' },
|
|
15119
|
-
// { cmd: 'premium', desc: imageSettings?.keyType === 'Custom' ? '(0.1/img)' : '(100/img)' }
|
|
15120
|
-
// ]
|
|
15121
|
-
// }
|
|
15122
|
-
// ]
|
|
15123
|
-
// },
|
|
15124
|
-
// { cmd: 'stats', desc: 'Show remaining credits or Pollinations balance status' }
|
|
15125
|
-
// ]
|
|
15126
|
-
// },
|
|
15127
15461
|
{
|
|
15128
15462
|
cmd: "/mode",
|
|
15129
15463
|
desc: "Toggle Flux/Flow modes",
|
|
@@ -15142,7 +15476,7 @@ function App({ args = [] }) {
|
|
|
15142
15476
|
] : aiProvider === "NVIDIA" ? [
|
|
15143
15477
|
{ cmd: "Fast", desc: "Reasoning Disabled" },
|
|
15144
15478
|
{ cmd: "Standard", desc: "Balanced Reasoning" },
|
|
15145
|
-
{ cmd: "High", desc: "Reasoning
|
|
15479
|
+
{ cmd: "High", desc: "Deep Reasoning" }
|
|
15146
15480
|
] : aiProvider === "OpenRouter" ? [
|
|
15147
15481
|
{ cmd: "Fast", desc: "Fastest" },
|
|
15148
15482
|
{ cmd: "Low", desc: "Quick Reasoning" },
|
|
@@ -15165,7 +15499,7 @@ function App({ args = [] }) {
|
|
|
15165
15499
|
},
|
|
15166
15500
|
{
|
|
15167
15501
|
cmd: "/model",
|
|
15168
|
-
desc: "
|
|
15502
|
+
desc: "Select Agent Model",
|
|
15169
15503
|
subs: aiProvider === "OpenRouter" ? apiTier === "Free" ? [
|
|
15170
15504
|
{
|
|
15171
15505
|
cmd: "google/gemma-4-31b-it:free",
|
|
@@ -15177,11 +15511,11 @@ function App({ args = [] }) {
|
|
|
15177
15511
|
},
|
|
15178
15512
|
{
|
|
15179
15513
|
cmd: "qwen/qwen3-coder:free",
|
|
15180
|
-
desc: ""
|
|
15514
|
+
desc: "Text Only"
|
|
15181
15515
|
},
|
|
15182
15516
|
{
|
|
15183
15517
|
cmd: "z-ai/glm-4.5-air:free",
|
|
15184
|
-
desc: ""
|
|
15518
|
+
desc: "Text Only"
|
|
15185
15519
|
}
|
|
15186
15520
|
] : [
|
|
15187
15521
|
{
|
|
@@ -15210,19 +15544,19 @@ function App({ args = [] }) {
|
|
|
15210
15544
|
},
|
|
15211
15545
|
{
|
|
15212
15546
|
cmd: "deepseek/deepseek-v4-pro",
|
|
15213
|
-
desc: ""
|
|
15547
|
+
desc: "Text Only"
|
|
15214
15548
|
},
|
|
15215
15549
|
{
|
|
15216
15550
|
cmd: "deepseek/deepseek-v4-flash",
|
|
15217
|
-
desc: ""
|
|
15551
|
+
desc: "Text Only"
|
|
15218
15552
|
},
|
|
15219
15553
|
{
|
|
15220
15554
|
cmd: "xiaomi/mimo-v2.5-pro",
|
|
15221
|
-
desc: ""
|
|
15555
|
+
desc: "Text Only"
|
|
15222
15556
|
},
|
|
15223
15557
|
{
|
|
15224
15558
|
cmd: "z-ai/glm-5",
|
|
15225
|
-
desc: ""
|
|
15559
|
+
desc: "Text Only"
|
|
15226
15560
|
},
|
|
15227
15561
|
{
|
|
15228
15562
|
cmd: "openai/gpt-5.2-codex",
|
|
@@ -15243,106 +15577,122 @@ function App({ args = [] }) {
|
|
|
15243
15577
|
] : aiProvider === "DeepSeek" ? [
|
|
15244
15578
|
{
|
|
15245
15579
|
cmd: "deepseek-v4-flash",
|
|
15246
|
-
desc: "Fast & Efficient"
|
|
15580
|
+
desc: "Fast & Efficient (Text Only)"
|
|
15247
15581
|
},
|
|
15248
15582
|
{
|
|
15249
15583
|
cmd: "deepseek-v4-pro",
|
|
15250
|
-
desc: "High-Intelligence Reasoning"
|
|
15584
|
+
desc: "High-Intelligence Reasoning (Text Only)"
|
|
15251
15585
|
}
|
|
15252
15586
|
] : aiProvider === "NVIDIA" ? [
|
|
15587
|
+
// --- Kimi (Moonshot AI) ---
|
|
15253
15588
|
{
|
|
15254
15589
|
cmd: "moonshotai/kimi-k2.6",
|
|
15255
15590
|
desc: "Multimodal"
|
|
15256
15591
|
},
|
|
15592
|
+
// --- DeepSeek Family ---
|
|
15257
15593
|
{
|
|
15258
|
-
cmd: "
|
|
15259
|
-
desc: ""
|
|
15594
|
+
cmd: "deepseek-ai/deepseek-v4-flash",
|
|
15595
|
+
desc: "Text Only"
|
|
15260
15596
|
},
|
|
15261
15597
|
{
|
|
15262
|
-
cmd: "
|
|
15263
|
-
desc: ""
|
|
15598
|
+
cmd: "deepseek-ai/deepseek-v4-pro",
|
|
15599
|
+
desc: "Text Only"
|
|
15264
15600
|
},
|
|
15601
|
+
// --- StepFun ---
|
|
15265
15602
|
{
|
|
15266
|
-
cmd: "
|
|
15267
|
-
desc: ""
|
|
15603
|
+
cmd: "stepfun-ai/step-3.7-flash",
|
|
15604
|
+
desc: "Multimodal"
|
|
15268
15605
|
},
|
|
15606
|
+
// --- Gemma Family (Google) ---
|
|
15269
15607
|
{
|
|
15270
|
-
cmd: "
|
|
15271
|
-
desc: ""
|
|
15608
|
+
cmd: "google/gemma-4-31b-it",
|
|
15609
|
+
desc: "Multimodal"
|
|
15272
15610
|
},
|
|
15273
15611
|
{
|
|
15274
|
-
cmd: "
|
|
15275
|
-
desc: ""
|
|
15612
|
+
cmd: "google/diffusiongemma-26b-a4b-it",
|
|
15613
|
+
desc: "Mega Fast [Experimental]"
|
|
15276
15614
|
},
|
|
15615
|
+
// --- Mistral ---
|
|
15277
15616
|
{
|
|
15278
15617
|
cmd: "mistralai/mistral-medium-3.5-128b",
|
|
15279
|
-
desc: ""
|
|
15618
|
+
desc: "Multimodal"
|
|
15619
|
+
},
|
|
15620
|
+
// --- GPT Open Source Series (OpenAI) ---
|
|
15621
|
+
{
|
|
15622
|
+
cmd: "openai/gpt-oss-20b",
|
|
15623
|
+
desc: "Text Only"
|
|
15624
|
+
},
|
|
15625
|
+
{
|
|
15626
|
+
cmd: "openai/gpt-oss-120b",
|
|
15627
|
+
desc: "Text Only"
|
|
15280
15628
|
},
|
|
15629
|
+
// --- GLM (Zhipu AI) ---
|
|
15281
15630
|
{
|
|
15282
15631
|
cmd: "z-ai/glm-5.1",
|
|
15283
|
-
desc: ""
|
|
15632
|
+
desc: "Text Only"
|
|
15284
15633
|
},
|
|
15634
|
+
// --- MiniMax Family ---
|
|
15285
15635
|
{
|
|
15286
|
-
cmd: "
|
|
15287
|
-
desc: "
|
|
15636
|
+
cmd: "minimaxai/minimax-m2.7",
|
|
15637
|
+
desc: "Text Only"
|
|
15288
15638
|
},
|
|
15289
15639
|
{
|
|
15290
15640
|
cmd: "minimaxai/minimax-m3",
|
|
15291
|
-
desc: ""
|
|
15641
|
+
desc: "Text Only"
|
|
15292
15642
|
}
|
|
15293
15643
|
] : apiTier === "Free" ? [
|
|
15294
15644
|
{
|
|
15295
15645
|
cmd: "gemma-4-26b-a4b-it",
|
|
15296
|
-
desc: "Standard & Faster"
|
|
15646
|
+
desc: "Standard & Faster (Multimodal)"
|
|
15297
15647
|
},
|
|
15298
15648
|
{
|
|
15299
15649
|
cmd: "gemma-4-31b-it",
|
|
15300
|
-
desc: "Standard Default"
|
|
15650
|
+
desc: "Standard Default (Multimodal)"
|
|
15301
15651
|
},
|
|
15302
15652
|
{
|
|
15303
15653
|
cmd: "gemini-2.5-flash-lite",
|
|
15304
|
-
desc: "Fast & Cheap (Limited Free Quota
|
|
15654
|
+
desc: "Fast & Cheap (Multimodal) [Limited Free Quota]"
|
|
15305
15655
|
},
|
|
15306
15656
|
{
|
|
15307
15657
|
cmd: "gemini-2.5-flash",
|
|
15308
|
-
desc: "Fast & Reliable (Limited Free Quota
|
|
15658
|
+
desc: "Fast & Reliable (Multimodal) [Limited Free Quota]"
|
|
15309
15659
|
},
|
|
15310
15660
|
{
|
|
15311
15661
|
cmd: "gemini-3-flash-preview",
|
|
15312
|
-
desc: "Fast & Lightweight (Limited Free Quota
|
|
15662
|
+
desc: "Fast & Lightweight (Multimodal) [Limited Free Quota]"
|
|
15313
15663
|
},
|
|
15314
15664
|
{
|
|
15315
15665
|
cmd: "gemini-3.5-flash",
|
|
15316
|
-
desc: "Flash Latest (Limited Free Quota
|
|
15666
|
+
desc: "Flash Latest (Multimodal) [Limited Free Quota] Instability Issues"
|
|
15317
15667
|
}
|
|
15318
15668
|
] : [
|
|
15319
15669
|
{
|
|
15320
15670
|
cmd: "gemini-2.5-flash-lite",
|
|
15321
|
-
desc: "Fast & Cheap"
|
|
15671
|
+
desc: "Fast & Cheap (Multimodal)"
|
|
15322
15672
|
},
|
|
15323
15673
|
{
|
|
15324
15674
|
cmd: "gemini-2.5-flash",
|
|
15325
|
-
desc: "Fast & Reliable"
|
|
15675
|
+
desc: "Fast & Reliable (Multimodal)"
|
|
15326
15676
|
},
|
|
15327
15677
|
{
|
|
15328
15678
|
cmd: "gemini-2.5-pro",
|
|
15329
|
-
desc: "Last gen Pro reasoning"
|
|
15679
|
+
desc: "Last gen Pro reasoning (Multimodal)"
|
|
15330
15680
|
},
|
|
15331
15681
|
{
|
|
15332
15682
|
cmd: "gemini-3.1-flash-lite",
|
|
15333
|
-
desc: "Ultra-Fast & Lite"
|
|
15683
|
+
desc: "Ultra-Fast & Lite (Multimodal)"
|
|
15334
15684
|
},
|
|
15335
15685
|
{
|
|
15336
15686
|
cmd: "gemini-3-flash-preview",
|
|
15337
|
-
desc: "Default, Fast & Lightweight"
|
|
15687
|
+
desc: "Default, Fast & Lightweight (Multimodal)"
|
|
15338
15688
|
},
|
|
15339
15689
|
{
|
|
15340
15690
|
cmd: "gemini-3.5-flash",
|
|
15341
|
-
desc: "Flash Latest
|
|
15691
|
+
desc: "Flash Latest (Multimodal) [Instability Issues]"
|
|
15342
15692
|
},
|
|
15343
15693
|
{
|
|
15344
15694
|
cmd: "gemini-3.1-pro-preview",
|
|
15345
|
-
desc: "Pro Reasoning"
|
|
15695
|
+
desc: "Pro Reasoning (Multimodal)"
|
|
15346
15696
|
}
|
|
15347
15697
|
]
|
|
15348
15698
|
},
|
|
@@ -15359,7 +15709,7 @@ function App({ args = [] }) {
|
|
|
15359
15709
|
cmd: "/fluxflow",
|
|
15360
15710
|
desc: "Project management",
|
|
15361
15711
|
subs: [
|
|
15362
|
-
{ cmd: "init", desc: "Create FluxFlow.md template" }
|
|
15712
|
+
{ cmd: "init", desc: "Create empty FluxFlow.md template" }
|
|
15363
15713
|
]
|
|
15364
15714
|
},
|
|
15365
15715
|
{
|
|
@@ -15374,8 +15724,8 @@ function App({ args = [] }) {
|
|
|
15374
15724
|
cmd: "/update",
|
|
15375
15725
|
desc: "Check/Install updates",
|
|
15376
15726
|
subs: [
|
|
15377
|
-
{ cmd: "
|
|
15378
|
-
{ cmd: "
|
|
15727
|
+
{ cmd: "latest", desc: "Install latest release" },
|
|
15728
|
+
{ cmd: "check", desc: "Check for new version" }
|
|
15379
15729
|
]
|
|
15380
15730
|
}
|
|
15381
15731
|
];
|
|
@@ -15455,6 +15805,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
15455
15805
|
const target = h[targetId] || Object.values(h).find((h2) => h2.name.toLowerCase() === targetId.toLowerCase());
|
|
15456
15806
|
if (target) {
|
|
15457
15807
|
stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
15808
|
+
clearBlocksCache();
|
|
15458
15809
|
setChatId(targetId);
|
|
15459
15810
|
const savedData = await loadChatContext(targetId);
|
|
15460
15811
|
chatTokenStartRef.current = sessionTotalTokens - savedData.total;
|
|
@@ -15538,6 +15889,7 @@ ${cleanText}`, color: "magenta" }];
|
|
|
15538
15889
|
]);
|
|
15539
15890
|
setCompletedIndex(1);
|
|
15540
15891
|
setClearKey((prev) => prev + 1);
|
|
15892
|
+
clearBlocksCache();
|
|
15541
15893
|
if (parsedArgs.playground) {
|
|
15542
15894
|
parsedArgs.playground = false;
|
|
15543
15895
|
deleteChat(PLAYGROUND_CHAT_ID).catch(() => {
|
|
@@ -15583,6 +15935,14 @@ ${cleanText}`, color: "magenta" }];
|
|
|
15583
15935
|
setIsExpanded(false);
|
|
15584
15936
|
setChatTokens(0);
|
|
15585
15937
|
chatTokenStartRef.current = sessionTotalTokens;
|
|
15938
|
+
setTimeout(() => {
|
|
15939
|
+
if (global.gc) {
|
|
15940
|
+
try {
|
|
15941
|
+
global.gc();
|
|
15942
|
+
} catch (e) {
|
|
15943
|
+
}
|
|
15944
|
+
}
|
|
15945
|
+
}, 500);
|
|
15586
15946
|
break;
|
|
15587
15947
|
}
|
|
15588
15948
|
case "/revert": {
|
|
@@ -15598,6 +15958,14 @@ ${cleanText}`, color: "magenta" }];
|
|
|
15598
15958
|
});
|
|
15599
15959
|
}
|
|
15600
15960
|
});
|
|
15961
|
+
setTimeout(() => {
|
|
15962
|
+
if (global.gc) {
|
|
15963
|
+
try {
|
|
15964
|
+
global.gc();
|
|
15965
|
+
} catch (e) {
|
|
15966
|
+
}
|
|
15967
|
+
}
|
|
15968
|
+
}, 500);
|
|
15601
15969
|
break;
|
|
15602
15970
|
}
|
|
15603
15971
|
case "/mode": {
|
|
@@ -16205,24 +16573,24 @@ ${timestamp}` };
|
|
|
16205
16573
|
});
|
|
16206
16574
|
const streamChat = async () => {
|
|
16207
16575
|
let didAppendCancel = false;
|
|
16208
|
-
const appendCancelMessage = (
|
|
16209
|
-
if (didAppendCancel)
|
|
16210
|
-
return prev;
|
|
16211
|
-
}
|
|
16212
|
-
const lastMsg = prev[prev.length - 1];
|
|
16213
|
-
if (lastMsg && lastMsg.text && lastMsg.text.includes("Request Cancelled")) {
|
|
16214
|
-
return prev;
|
|
16215
|
-
}
|
|
16576
|
+
const appendCancelMessage = () => {
|
|
16577
|
+
if (didAppendCancel) return;
|
|
16216
16578
|
didAppendCancel = true;
|
|
16217
|
-
|
|
16218
|
-
|
|
16219
|
-
|
|
16220
|
-
|
|
16221
|
-
|
|
16222
|
-
|
|
16223
|
-
|
|
16224
|
-
|
|
16225
|
-
|
|
16579
|
+
setMessages((prev) => {
|
|
16580
|
+
const lastMsg = prev[prev.length - 1];
|
|
16581
|
+
if (lastMsg && lastMsg.text && lastMsg.text.includes("Request Cancelled")) {
|
|
16582
|
+
return prev;
|
|
16583
|
+
}
|
|
16584
|
+
const updatedPrev = prev.map((m) => m.isStreaming ? { ...m, isStreaming: false } : m);
|
|
16585
|
+
const newMsgs = [...updatedPrev, {
|
|
16586
|
+
id: "cancel-" + Date.now(),
|
|
16587
|
+
role: "system",
|
|
16588
|
+
text: "\n\n\x1B[33m\u2139 Request Cancelled\x1B[0m",
|
|
16589
|
+
isMeta: true
|
|
16590
|
+
}];
|
|
16591
|
+
setCompletedIndex(newMsgs.length);
|
|
16592
|
+
return newMsgs;
|
|
16593
|
+
});
|
|
16226
16594
|
};
|
|
16227
16595
|
let hasFiredJanitor = false;
|
|
16228
16596
|
setIsProcessing(true);
|
|
@@ -16416,7 +16784,14 @@ Selection: ${val}`,
|
|
|
16416
16784
|
let toolCallBalance = 0;
|
|
16417
16785
|
let inToolCallString = null;
|
|
16418
16786
|
const signalRegex = /\[?\s*turn\s*:\s*.*?\s*\]?/gi;
|
|
16787
|
+
const bullyTheBug = path20.join(DATA_DIR, "padding");
|
|
16419
16788
|
for await (const packet of stream) {
|
|
16789
|
+
if (packet.type === "interactive_turn_finished") {
|
|
16790
|
+
fs22.writeFileSync(bullyTheBug, "pad_0xa\n");
|
|
16791
|
+
} else {
|
|
16792
|
+
fs22.appendFileSync(bullyTheBug, "\r");
|
|
16793
|
+
parsedBlocks.completed = [];
|
|
16794
|
+
}
|
|
16420
16795
|
if (isFirstPacket && packet.type === "text") {
|
|
16421
16796
|
apiStart = Date.now();
|
|
16422
16797
|
isFirstPacket = false;
|
|
@@ -16427,7 +16802,7 @@ Selection: ${val}`,
|
|
|
16427
16802
|
sendStatus(packet.content);
|
|
16428
16803
|
}
|
|
16429
16804
|
if (packet.content === "Request Cancelled") {
|
|
16430
|
-
|
|
16805
|
+
appendCancelMessage();
|
|
16431
16806
|
}
|
|
16432
16807
|
continue;
|
|
16433
16808
|
}
|
|
@@ -16466,6 +16841,14 @@ Selection: ${val}`,
|
|
|
16466
16841
|
setCompletedIndex(newMsgs.length);
|
|
16467
16842
|
return newMsgs;
|
|
16468
16843
|
});
|
|
16844
|
+
setTimeout(() => {
|
|
16845
|
+
if (global.gc) {
|
|
16846
|
+
try {
|
|
16847
|
+
global.gc();
|
|
16848
|
+
} catch (e) {
|
|
16849
|
+
}
|
|
16850
|
+
}
|
|
16851
|
+
}, 100);
|
|
16469
16852
|
continue;
|
|
16470
16853
|
}
|
|
16471
16854
|
if (packet.type === "interactive_turn_finished") {
|
|
@@ -16674,29 +17057,31 @@ Selection: ${val}`,
|
|
|
16674
17057
|
}
|
|
16675
17058
|
if (inThinkMode && currentThinkId) {
|
|
16676
17059
|
setMessages((prev) => {
|
|
17060
|
+
const next = [...prev];
|
|
16677
17061
|
let transitioning = false;
|
|
16678
17062
|
let transitionContent = "";
|
|
16679
|
-
|
|
16680
|
-
if (
|
|
16681
|
-
const newText =
|
|
17063
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
17064
|
+
if (next[i].id === currentThinkId) {
|
|
17065
|
+
const newText = next[i].text + chunkText;
|
|
16682
17066
|
if (newText.toLowerCase().includes("</think>")) {
|
|
16683
17067
|
transitioning = true;
|
|
16684
17068
|
const parts = newText.split(/<\/think>/gi);
|
|
16685
17069
|
transitionContent = parts.slice(1).join("</think>") || "";
|
|
16686
|
-
const startTime =
|
|
17070
|
+
const startTime = next[i].startTime || parseInt(String(next[i].id).split("-")[1]) || Date.now();
|
|
16687
17071
|
const duration = Date.now() - startTime;
|
|
16688
|
-
|
|
17072
|
+
next[i] = { ...next[i], text: parts[0], isStreaming: false, duration };
|
|
17073
|
+
} else {
|
|
17074
|
+
next[i] = { ...next[i], text: newText, isStreaming: true };
|
|
16689
17075
|
}
|
|
16690
|
-
|
|
17076
|
+
break;
|
|
16691
17077
|
}
|
|
16692
|
-
|
|
16693
|
-
});
|
|
17078
|
+
}
|
|
16694
17079
|
if (transitioning) {
|
|
16695
17080
|
inThinkMode = false;
|
|
16696
17081
|
currentAgentId = "agent-" + Date.now();
|
|
16697
|
-
|
|
17082
|
+
next.push({ id: currentAgentId, role: "agent", text: transitionContent.replace(/<\/?(think|thought)>/gi, ""), isStreaming: true });
|
|
16698
17083
|
}
|
|
16699
|
-
return
|
|
17084
|
+
return next;
|
|
16700
17085
|
});
|
|
16701
17086
|
} else if (!inThinkMode) {
|
|
16702
17087
|
const chunkLower2 = chunkText.toLowerCase();
|
|
@@ -16707,9 +17092,16 @@ Selection: ${val}`,
|
|
|
16707
17092
|
currentAgentId = "agent-" + Date.now();
|
|
16708
17093
|
setMessages((prev) => [...prev, { id: currentAgentId, role: "agent", text: chunkText, isStreaming: true }]);
|
|
16709
17094
|
} else {
|
|
16710
|
-
setMessages((prev) =>
|
|
16711
|
-
|
|
16712
|
-
|
|
17095
|
+
setMessages((prev) => {
|
|
17096
|
+
const next = [...prev];
|
|
17097
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
17098
|
+
if (next[i].id === currentAgentId) {
|
|
17099
|
+
next[i] = { ...next[i], text: next[i].text + chunkText, isStreaming: true };
|
|
17100
|
+
break;
|
|
17101
|
+
}
|
|
17102
|
+
}
|
|
17103
|
+
return next;
|
|
17104
|
+
});
|
|
16713
17105
|
}
|
|
16714
17106
|
}
|
|
16715
17107
|
}
|
|
@@ -16724,7 +17116,7 @@ Selection: ${val}`,
|
|
|
16724
17116
|
setIsProcessing(false);
|
|
16725
17117
|
setStatusText(null);
|
|
16726
17118
|
if (didSignalTerminationRef.current) {
|
|
16727
|
-
|
|
17119
|
+
appendCancelMessage();
|
|
16728
17120
|
}
|
|
16729
17121
|
if (!hasFiredJanitor) {
|
|
16730
17122
|
if (process.stdout.isTTY) {
|
|
@@ -16817,7 +17209,7 @@ Selection: ${val}`,
|
|
|
16817
17209
|
}
|
|
16818
17210
|
return [];
|
|
16819
17211
|
}, [input, isFilePickerDismissed]);
|
|
16820
|
-
|
|
17212
|
+
useEffect11(() => {
|
|
16821
17213
|
setSelectedIndex(0);
|
|
16822
17214
|
}, [suggestions]);
|
|
16823
17215
|
const CustomMenuItem = ({ label: label2, isSelected }) => {
|
|
@@ -17314,6 +17706,7 @@ Selection: ${val}`,
|
|
|
17314
17706
|
stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
17315
17707
|
}
|
|
17316
17708
|
setClearKey((prev) => prev + 1);
|
|
17709
|
+
clearBlocksCache();
|
|
17317
17710
|
const targetIdx = messages.findLastIndex(
|
|
17318
17711
|
(m) => m.role === "user" && m.text && (m.text.startsWith(targetPrompt) || m.text.includes(targetPrompt))
|
|
17319
17712
|
);
|
|
@@ -17366,6 +17759,7 @@ Selection: ${val}`,
|
|
|
17366
17759
|
const h = await loadHistory();
|
|
17367
17760
|
if (h[id]) {
|
|
17368
17761
|
stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
17762
|
+
clearBlocksCache();
|
|
17369
17763
|
setChatId(id);
|
|
17370
17764
|
const savedData = await loadChatContext(id);
|
|
17371
17765
|
chatTokenStartRef.current = sessionTotalTokens - savedData.total;
|
|
@@ -18007,9 +18401,22 @@ var init_app = __esm({
|
|
|
18007
18401
|
// src/cli.jsx
|
|
18008
18402
|
import { spawn as spawn3 } from "child_process";
|
|
18009
18403
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
18010
|
-
|
|
18404
|
+
import os5 from "os";
|
|
18405
|
+
var totalSystemRamBytes = os5.totalmem();
|
|
18406
|
+
var totalSystemRamMB = totalSystemRamBytes / (1024 * 1024);
|
|
18407
|
+
var SAFETY_MARGIN = 0.5;
|
|
18408
|
+
var calculatedLimit = Math.floor(totalSystemRamMB * SAFETY_MARGIN);
|
|
18409
|
+
var _rawArgs = process.argv.slice(2);
|
|
18410
|
+
var _allocIdx = _rawArgs.indexOf("--allocation");
|
|
18411
|
+
var _allocValue = _allocIdx !== -1 ? parseInt(_rawArgs[_allocIdx + 1], 10) : NaN;
|
|
18412
|
+
var _maxAllowed = Math.floor(totalSystemRamMB * 0.75);
|
|
18413
|
+
var HEAP_LIMIT = !isNaN(_allocValue) && _allocValue > 0 ? Math.min(_allocValue, _maxAllowed) : Math.max(1536, Math.min(32768, calculatedLimit));
|
|
18011
18414
|
var isBundled = fileURLToPath2(import.meta.url).endsWith(".js");
|
|
18012
18415
|
if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-size"))) {
|
|
18416
|
+
if (!Number.isNaN(_allocValue)) {
|
|
18417
|
+
console.log("\n[MEMORY] Using custom memory allocation: " + _allocValue + " MB" + (_allocValue > _maxAllowed ? " (Max allowed: " + _maxAllowed + "MB)" : ""));
|
|
18418
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
18419
|
+
}
|
|
18013
18420
|
const cp = spawn3(process.execPath, [
|
|
18014
18421
|
`--max-old-space-size=${HEAP_LIMIT}`,
|
|
18015
18422
|
fileURLToPath2(import.meta.url),
|
|
@@ -18042,6 +18449,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
|
|
|
18042
18449
|
--thinking <Fast|Low|Medium|High|xHigh> Set startup thinking level
|
|
18043
18450
|
--memory <on|off> Toggle memory system
|
|
18044
18451
|
--resume <session_id> Resume a previous session
|
|
18452
|
+
--allocation <mb> Override Node.js max-old-space-size in MB (default: auto)
|
|
18045
18453
|
--package <npm|pnpm|yarn|bun> Set package manager for updates
|
|
18046
18454
|
--auto-del <1d|7d|30d> Set history auto-deletion timeframe
|
|
18047
18455
|
--auto-exec <on|off> Toggle permission for autonomous command execution
|
|
@@ -18131,7 +18539,7 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
|
|
|
18131
18539
|
}
|
|
18132
18540
|
const promptPackageManager = async () => {
|
|
18133
18541
|
const React17 = (await import("react")).default;
|
|
18134
|
-
const { useState:
|
|
18542
|
+
const { useState: useState15 } = React17;
|
|
18135
18543
|
const { render: render2, Box: Box16, Text: Text17 } = await import("ink");
|
|
18136
18544
|
const SelectInput3 = (await import("ink-select-input")).default;
|
|
18137
18545
|
const TextInput5 = (await import("ink-text-input")).default;
|
|
@@ -18148,8 +18556,8 @@ if (isBundled && !process.execArgv.some((arg) => arg.includes("max-old-space-siz
|
|
|
18148
18556
|
};
|
|
18149
18557
|
let unmountFn;
|
|
18150
18558
|
const PromptComponent = () => {
|
|
18151
|
-
const [step, setStep] =
|
|
18152
|
-
const [customCommand2, setCustomCommand] =
|
|
18559
|
+
const [step, setStep] = useState15("select");
|
|
18560
|
+
const [customCommand2, setCustomCommand] = useState15("");
|
|
18153
18561
|
const handleSelect = (item) => {
|
|
18154
18562
|
if (item.value === "custom") {
|
|
18155
18563
|
setStep("custom");
|