fluxflow-cli 3.0.11 → 3.0.12
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 +130 -45
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -4829,36 +4829,78 @@ var init_ChatLayout = __esm({
|
|
|
4829
4829
|
// src/components/StatusBar.jsx
|
|
4830
4830
|
import React5 from "react";
|
|
4831
4831
|
import { Box as Box4, Text as Text5 } from "ink";
|
|
4832
|
-
import { useState as useState5, useEffect as useEffect4 } from "react";
|
|
4832
|
+
import { useState as useState5, useEffect as useEffect4, useRef as useRef3 } from "react";
|
|
4833
4833
|
function getMemoryInfo() {
|
|
4834
4834
|
if (activeGetMemoryInfo) {
|
|
4835
4835
|
activeGetMemoryInfo();
|
|
4836
4836
|
}
|
|
4837
4837
|
}
|
|
4838
|
-
var activeGetMemoryInfo, StatusBar, StatusBar_default;
|
|
4838
|
+
var activeGetMemoryInfo, getLatencyColor, StatusBar, StatusBar_default;
|
|
4839
4839
|
var init_StatusBar = __esm({
|
|
4840
4840
|
"src/components/StatusBar.jsx"() {
|
|
4841
4841
|
init_text();
|
|
4842
4842
|
activeGetMemoryInfo = null;
|
|
4843
|
+
getLatencyColor = (delay) => {
|
|
4844
|
+
if (delay <= 400) return "#00a564";
|
|
4845
|
+
if (delay >= 5e3) return "#ff0000";
|
|
4846
|
+
const points = [
|
|
4847
|
+
{ t: 400, r: 0, g: 165, b: 100 },
|
|
4848
|
+
{ t: 800, r: 120, g: 220, b: 80 },
|
|
4849
|
+
{ t: 1500, r: 250, g: 210, b: 40 },
|
|
4850
|
+
{ t: 3e3, r: 255, g: 120, b: 0 },
|
|
4851
|
+
{ t: 5e3, r: 255, g: 0, b: 0 }
|
|
4852
|
+
];
|
|
4853
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
4854
|
+
const p1 = points[i];
|
|
4855
|
+
const p2 = points[i + 1];
|
|
4856
|
+
if (delay >= p1.t && delay <= p2.t) {
|
|
4857
|
+
const ratio = (delay - p1.t) / (p2.t - p1.t);
|
|
4858
|
+
const r = Math.round(p1.r + (p2.r - p1.r) * ratio);
|
|
4859
|
+
const g = Math.round(p1.g + (p2.g - p1.g) * ratio);
|
|
4860
|
+
const b = Math.round(p1.b + (p2.b - p1.b) * ratio);
|
|
4861
|
+
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
|
|
4862
|
+
}
|
|
4863
|
+
}
|
|
4864
|
+
return "#ff0000";
|
|
4865
|
+
};
|
|
4843
4866
|
StatusBar = React5.memo(({ mode, thinkingLevel, tokens = "0.0k", tokensTotal = "0.0k", chatId = "NEW-SESSION", isMemoryEnabled = true, apiTier = "Free", aiProvider = "Google", activeModel = "", isProcessing = false, lastChunkTime = 0 }) => {
|
|
4844
4867
|
const modeIcon = mode === "Flux" ? "" : "";
|
|
4845
4868
|
const [memoryUsage, setMemoryUsage] = useState5(0);
|
|
4846
4869
|
const [memoryLimit, setMemoryLimit] = useState5(0);
|
|
4847
4870
|
const [memoryUnit, setMemoryUnit] = useState5("MB");
|
|
4848
4871
|
const [dotColor, setDotColor] = useState5("green");
|
|
4872
|
+
const chunkTimesRef = useRef3([]);
|
|
4849
4873
|
useEffect4(() => {
|
|
4850
|
-
if (!isProcessing)
|
|
4874
|
+
if (!isProcessing) {
|
|
4875
|
+
chunkTimesRef.current = [];
|
|
4876
|
+
return;
|
|
4877
|
+
}
|
|
4878
|
+
if (lastChunkTime > 0) {
|
|
4879
|
+
const times = chunkTimesRef.current;
|
|
4880
|
+
if (times.length === 0 || times[times.length - 1] !== lastChunkTime) {
|
|
4881
|
+
times.push(lastChunkTime);
|
|
4882
|
+
if (times.length > 5) {
|
|
4883
|
+
times.shift();
|
|
4884
|
+
}
|
|
4885
|
+
}
|
|
4886
|
+
}
|
|
4851
4887
|
const checkLatency = () => {
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
}
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4888
|
+
if (!lastChunkTime) {
|
|
4889
|
+
setDotColor("#00a564");
|
|
4890
|
+
return;
|
|
4891
|
+
}
|
|
4892
|
+
const times = chunkTimesRef.current;
|
|
4893
|
+
let averageInterval = 0;
|
|
4894
|
+
if (times.length > 1) {
|
|
4895
|
+
let sum = 0;
|
|
4896
|
+
for (let i = 1; i < times.length; i++) {
|
|
4897
|
+
sum += times[i] - times[i - 1];
|
|
4898
|
+
}
|
|
4899
|
+
averageInterval = sum / (times.length - 1);
|
|
4861
4900
|
}
|
|
4901
|
+
const timeSinceLast = Date.now() - lastChunkTime;
|
|
4902
|
+
const delay = Math.max(averageInterval, timeSinceLast);
|
|
4903
|
+
setDotColor(getLatencyColor(delay));
|
|
4862
4904
|
};
|
|
4863
4905
|
checkLatency();
|
|
4864
4906
|
const timer = setInterval(checkLatency, 100);
|
|
@@ -15001,7 +15043,7 @@ __export(app_exports, {
|
|
|
15001
15043
|
default: () => App
|
|
15002
15044
|
});
|
|
15003
15045
|
import os4 from "os";
|
|
15004
|
-
import React15, { useState as useState14, useEffect as useEffect11, useRef as
|
|
15046
|
+
import React15, { useState as useState14, useEffect as useEffect11, useRef as useRef4, useMemo as useMemo2 } from "react";
|
|
15005
15047
|
import { Box as Box14, Text as Text15, useInput as useInput9, useStdout as useStdout2, Static } from "ink";
|
|
15006
15048
|
import fs22 from "fs-extra";
|
|
15007
15049
|
import path20 from "path";
|
|
@@ -15027,8 +15069,8 @@ function App({ args = [] }) {
|
|
|
15027
15069
|
const [isFilePickerDismissed, setIsFilePickerDismissed] = useState14(false);
|
|
15028
15070
|
const [showBridgePromo, setShowBridgePromo] = useState14(false);
|
|
15029
15071
|
const [promoSelectedIndex, setPromoSelectedIndex] = useState14(0);
|
|
15030
|
-
const suggestionOffsetRef =
|
|
15031
|
-
const persistedModelRef =
|
|
15072
|
+
const suggestionOffsetRef = useRef4(0);
|
|
15073
|
+
const persistedModelRef = useRef4(null);
|
|
15032
15074
|
useEffect11(() => {
|
|
15033
15075
|
const ideName = getIDEName();
|
|
15034
15076
|
const isIDE = !["Terminal", "Windows Terminal"].includes(ideName) || !!process.env.VSC_TERMINAL_URL;
|
|
@@ -15242,7 +15284,7 @@ function App({ args = [] }) {
|
|
|
15242
15284
|
const [janitorModel, setJanitorModel] = useState14("gemma-4-26b-a4b-it");
|
|
15243
15285
|
const [isInitializing, setIsInitializing] = useState14(true);
|
|
15244
15286
|
const [isAppFocused, setIsAppFocused] = useState14(true);
|
|
15245
|
-
const lastFocusEventTime =
|
|
15287
|
+
const lastFocusEventTime = useRef4(0);
|
|
15246
15288
|
const [apiKey, setApiKey] = useState14(null);
|
|
15247
15289
|
const [tempKey, setTempKey] = useState14("");
|
|
15248
15290
|
const addShiftEnterBinding = async (ideName) => {
|
|
@@ -15313,7 +15355,7 @@ function App({ args = [] }) {
|
|
|
15313
15355
|
const [sessionBackgroundCalls, setSessionBackgroundCalls] = useState14(0);
|
|
15314
15356
|
const [sessionTotalTokens, setSessionTotalTokens] = useState14(0);
|
|
15315
15357
|
const [chatTokens, setChatTokens] = useState14(0);
|
|
15316
|
-
const chatTokenStartRef =
|
|
15358
|
+
const chatTokenStartRef = useRef4(0);
|
|
15317
15359
|
const [sessionTotalCachedTokens, setSessionTotalCachedTokens] = useState14(0);
|
|
15318
15360
|
const [sessionTotalCandidateTokens, setSessionTotalCandidateTokens] = useState14(0);
|
|
15319
15361
|
const [sessionToolSuccess, setSessionToolSuccess] = useState14(0);
|
|
@@ -15356,12 +15398,12 @@ function App({ args = [] }) {
|
|
|
15356
15398
|
const [isTerminalFocused, setIsTerminalFocused] = useState14(false);
|
|
15357
15399
|
const [activeSubagents, setActiveSubagents] = useState14([]);
|
|
15358
15400
|
const [tick, setTick] = useState14(0);
|
|
15359
|
-
const isFirstRender =
|
|
15360
|
-
const isSecondRender =
|
|
15361
|
-
const isThirdRender =
|
|
15362
|
-
const prevProviderRef =
|
|
15363
|
-
const originalAllowExternalAccessRef =
|
|
15364
|
-
const originalMemoryRef =
|
|
15401
|
+
const isFirstRender = useRef4(true);
|
|
15402
|
+
const isSecondRender = useRef4(true);
|
|
15403
|
+
const isThirdRender = useRef4(true);
|
|
15404
|
+
const prevProviderRef = useRef4(aiProvider);
|
|
15405
|
+
const originalAllowExternalAccessRef = useRef4(false);
|
|
15406
|
+
const originalMemoryRef = useRef4(true);
|
|
15365
15407
|
useEffect11(() => {
|
|
15366
15408
|
if (prevProviderRef.current !== aiProvider) {
|
|
15367
15409
|
prevProviderRef.current = aiProvider;
|
|
@@ -15447,8 +15489,8 @@ function App({ args = [] }) {
|
|
|
15447
15489
|
}
|
|
15448
15490
|
};
|
|
15449
15491
|
}, []);
|
|
15450
|
-
const activeCommandRef =
|
|
15451
|
-
const execOutputRef =
|
|
15492
|
+
const activeCommandRef = useRef4(null);
|
|
15493
|
+
const execOutputRef = useRef4("");
|
|
15452
15494
|
useEffect11(() => {
|
|
15453
15495
|
activeCommandRef.current = activeCommand;
|
|
15454
15496
|
}, [activeCommand]);
|
|
@@ -15504,8 +15546,8 @@ function App({ args = [] }) {
|
|
|
15504
15546
|
const [escTimer, setEscTimer] = useState14(null);
|
|
15505
15547
|
const [escPressCount, setEscPressCount] = useState14(0);
|
|
15506
15548
|
const [recentPrompts, setRecentPrompts] = useState14([]);
|
|
15507
|
-
const escDoubleTimerRef =
|
|
15508
|
-
const chatLoadingRef =
|
|
15549
|
+
const escDoubleTimerRef = useRef4(null);
|
|
15550
|
+
const chatLoadingRef = useRef4(false);
|
|
15509
15551
|
useEffect11(() => {
|
|
15510
15552
|
return () => {
|
|
15511
15553
|
if (escDoubleTimerRef.current) {
|
|
@@ -15513,7 +15555,7 @@ function App({ args = [] }) {
|
|
|
15513
15555
|
}
|
|
15514
15556
|
};
|
|
15515
15557
|
}, []);
|
|
15516
|
-
const didSignalTerminationRef =
|
|
15558
|
+
const didSignalTerminationRef = useRef4(false);
|
|
15517
15559
|
const [queuedPrompt, setQueuedPrompt] = useState14(null);
|
|
15518
15560
|
const [resolutionData, setResolutionData] = useState14(null);
|
|
15519
15561
|
const [tempModelOverride, setTempModelOverride] = useState14(null);
|
|
@@ -15566,11 +15608,11 @@ function App({ args = [] }) {
|
|
|
15566
15608
|
return next;
|
|
15567
15609
|
});
|
|
15568
15610
|
};
|
|
15569
|
-
const queuedPromptRef =
|
|
15611
|
+
const queuedPromptRef = useRef4(null);
|
|
15570
15612
|
const [btwResponse, setBtwResponse] = useState14("");
|
|
15571
15613
|
const [showBtwBox, setShowBtwBox] = useState14(false);
|
|
15572
|
-
const btwResponseRef =
|
|
15573
|
-
const btwClosedRef =
|
|
15614
|
+
const btwResponseRef = useRef4("");
|
|
15615
|
+
const btwClosedRef = useRef4(null);
|
|
15574
15616
|
useEffect11(() => {
|
|
15575
15617
|
if (messages.length === 0) return;
|
|
15576
15618
|
const lastMsg = messages[messages.length - 1];
|
|
@@ -15591,8 +15633,8 @@ function App({ args = [] }) {
|
|
|
15591
15633
|
}, [messages]);
|
|
15592
15634
|
const [completedIndex, setCompletedIndex] = useState14(messages.length);
|
|
15593
15635
|
const [clearKey, setClearKey] = useState14(0);
|
|
15594
|
-
const lastCompletedBlocksRef =
|
|
15595
|
-
const cachedHistoryRef =
|
|
15636
|
+
const lastCompletedBlocksRef = useRef4([]);
|
|
15637
|
+
const cachedHistoryRef = useRef4({
|
|
15596
15638
|
completedIndex: 0,
|
|
15597
15639
|
columns: 0,
|
|
15598
15640
|
historicalBlocks: [],
|
|
@@ -16234,7 +16276,7 @@ function App({ args = [] }) {
|
|
|
16234
16276
|
setTempKey("");
|
|
16235
16277
|
}
|
|
16236
16278
|
};
|
|
16237
|
-
const lastSavedTimeRef =
|
|
16279
|
+
const lastSavedTimeRef = useRef4(SESSION_START_TIME);
|
|
16238
16280
|
useEffect11(() => {
|
|
16239
16281
|
if (activeView === "exit") {
|
|
16240
16282
|
const flush = async () => {
|
|
@@ -19243,7 +19285,7 @@ Selection: ${val}`,
|
|
|
19243
19285
|
return /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", borderStyle: "round", paddingX: 3, paddingY: 1, borderColor: "grey", width: Math.min(100, (stdout?.columns || 100) - 2), marginTop: 0, marginBottom: 0 }, /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text15, { bold: true }, gradient2(["blue", "purple"])("Agent powering down. Goodbye!"))), /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Text15, { color: "white", bold: true, underline: true }, "Interaction Summary"), /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Session ID:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, chatId)), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Tool Calls:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, sessionToolSuccess + sessionToolFailure + sessionToolDenied, " ( ", /* @__PURE__ */ React15.createElement(Text15, { color: "green" }, "\u2713 ", sessionToolSuccess), " ", /* @__PURE__ */ React15.createElement(Text15, { color: "yellow" }, "\u2298 ", sessionToolDenied), " ", /* @__PURE__ */ React15.createElement(Text15, { color: "red" }, "\u2715 ", sessionToolFailure), " )")), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Success Rate:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, successRate, "%")), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Code Changes:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, /* @__PURE__ */ React15.createElement(Text15, { color: "green" }, "+", linesAdded), " ", /* @__PURE__ */ React15.createElement(Text15, { color: "red" }, "-", linesRemoved))), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Tokens Consumed:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatTokens(sessionTotalTokens))), sessionTotalTokens > 0 && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React15.createElement(Box14, { width: 18 }, /* @__PURE__ */ React15.createElement(Text15, { color: "grey" }, "\xBB Input Tokens:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatTokens(sessionTotalTokens - sessionTotalCandidateTokens))), sessionTotalCachedTokens > 0 && /* @__PURE__ */ React15.createElement(Box14, { marginLeft: 4 }, /* @__PURE__ */ React15.createElement(Box14, { width: 16 }, /* @__PURE__ */ React15.createElement(Text15, { color: "grey" }, "\xBB Cached:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatTokens(sessionTotalCachedTokens))), sessionTotalCandidateTokens > 0 && /* @__PURE__ */ React15.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React15.createElement(Box14, { width: 18 }, /* @__PURE__ */ React15.createElement(Text15, { color: "grey" }, "\xBB Output Tokens:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatTokens(sessionTotalCandidateTokens)))), sessionImageCount > 0 && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Images Made:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, sessionImageCount)), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Image Credits:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, Number(((sessionImageCredits || 0) * 1e3).toFixed(0)), " credits")))), /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text15, { color: "white", bold: true, underline: true }, "Performance"), /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Wall Time:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatMsDuration(wallTimeMs))), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Box14, { width: 20 }, /* @__PURE__ */ React15.createElement(Text15, { color: "blue" }, "Agent Active:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatMsDuration(agentActiveMs))), /* @__PURE__ */ React15.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React15.createElement(Box14, { width: 18 }, /* @__PURE__ */ React15.createElement(Text15, { color: "grey" }, "\xBB API Time:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatMsDuration(sessionApiTime), " (", apiPercent, "%)")), /* @__PURE__ */ React15.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React15.createElement(Box14, { width: 18 }, /* @__PURE__ */ React15.createElement(Text15, { color: "grey" }, "\xBB Tool Time:")), /* @__PURE__ */ React15.createElement(Text15, { color: "white" }, formatMsDuration(sessionToolTime), " (", toolPercent, "%)"))));
|
|
19244
19286
|
})())));
|
|
19245
19287
|
}
|
|
19246
|
-
var shouldClearValue, getPrefilledValue, getIDEName, getIDEDirName, getKeybindingsPath, parseJsonc, hasShiftEnterBinding, getPromoOptions, BridgePromo, SESSION_START_TIME, CHANGELOG_URL, DOCS_URL, linesAdded, linesRemoved, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, parseAgentText, getProjectFiles, cachedShortcut, SubagentRow;
|
|
19288
|
+
var shouldClearValue, getPrefilledValue, getIDEName, getIDEDirName, getKeybindingsPath, parseJsonc, hasShiftEnterBinding, getPromoOptions, BridgePromo, SESSION_START_TIME, CHANGELOG_URL, DOCS_URL, linesAdded, linesRemoved, packageJsonPath, packageJson, versionFluxflow, updatedOn, ResolutionModal, parseAgentText, getProjectFiles, cachedShortcut, getLatencyColor2, SubagentRow;
|
|
19247
19289
|
var init_app = __esm({
|
|
19248
19290
|
async "src/app.jsx"() {
|
|
19249
19291
|
init_build();
|
|
@@ -19499,21 +19541,64 @@ var init_app = __esm({
|
|
|
19499
19541
|
};
|
|
19500
19542
|
})();
|
|
19501
19543
|
cachedShortcut = "\\ + Enter";
|
|
19544
|
+
getLatencyColor2 = (delay) => {
|
|
19545
|
+
if (delay <= 400) return "#00a564";
|
|
19546
|
+
if (delay >= 5e3) return "#ff0000";
|
|
19547
|
+
const points = [
|
|
19548
|
+
{ t: 400, r: 0, g: 165, b: 100 },
|
|
19549
|
+
{ t: 800, r: 120, g: 220, b: 80 },
|
|
19550
|
+
{ t: 1500, r: 250, g: 210, b: 40 },
|
|
19551
|
+
{ t: 3e3, r: 255, g: 120, b: 0 },
|
|
19552
|
+
{ t: 5e3, r: 255, g: 0, b: 0 }
|
|
19553
|
+
];
|
|
19554
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
19555
|
+
const p1 = points[i];
|
|
19556
|
+
const p2 = points[i + 1];
|
|
19557
|
+
if (delay >= p1.t && delay <= p2.t) {
|
|
19558
|
+
const ratio = (delay - p1.t) / (p2.t - p1.t);
|
|
19559
|
+
const r = Math.round(p1.r + (p2.r - p1.r) * ratio);
|
|
19560
|
+
const g = Math.round(p1.g + (p2.g - p1.g) * ratio);
|
|
19561
|
+
const b = Math.round(p1.b + (p2.b - p1.b) * ratio);
|
|
19562
|
+
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
|
|
19563
|
+
}
|
|
19564
|
+
}
|
|
19565
|
+
return "#ff0000";
|
|
19566
|
+
};
|
|
19502
19567
|
SubagentRow = React15.memo(({ sa }) => {
|
|
19503
19568
|
const [dotColor, setDotColor] = useState14("green");
|
|
19569
|
+
const chunkTimesRef = useRef4([]);
|
|
19504
19570
|
useEffect11(() => {
|
|
19505
|
-
if (sa.status !== "running")
|
|
19571
|
+
if (sa.status !== "running") {
|
|
19572
|
+
chunkTimesRef.current = [];
|
|
19573
|
+
return;
|
|
19574
|
+
}
|
|
19575
|
+
const lastChunkTime = sa.lastChunkTime;
|
|
19576
|
+
if (lastChunkTime > 0) {
|
|
19577
|
+
const times = chunkTimesRef.current;
|
|
19578
|
+
if (times.length === 0 || times[times.length - 1] !== lastChunkTime) {
|
|
19579
|
+
times.push(lastChunkTime);
|
|
19580
|
+
if (times.length > 5) {
|
|
19581
|
+
times.shift();
|
|
19582
|
+
}
|
|
19583
|
+
}
|
|
19584
|
+
}
|
|
19506
19585
|
const checkLatency = () => {
|
|
19507
|
-
|
|
19508
|
-
|
|
19509
|
-
|
|
19510
|
-
}
|
|
19511
|
-
|
|
19512
|
-
|
|
19513
|
-
|
|
19514
|
-
|
|
19515
|
-
|
|
19586
|
+
if (!lastChunkTime) {
|
|
19587
|
+
setDotColor("#00a564");
|
|
19588
|
+
return;
|
|
19589
|
+
}
|
|
19590
|
+
const times = chunkTimesRef.current;
|
|
19591
|
+
let averageInterval = 0;
|
|
19592
|
+
if (times.length > 1) {
|
|
19593
|
+
let sum = 0;
|
|
19594
|
+
for (let i = 1; i < times.length; i++) {
|
|
19595
|
+
sum += times[i] - times[i - 1];
|
|
19596
|
+
}
|
|
19597
|
+
averageInterval = sum / (times.length - 1);
|
|
19516
19598
|
}
|
|
19599
|
+
const timeSinceLast = Date.now() - lastChunkTime;
|
|
19600
|
+
const delay = Math.max(averageInterval, timeSinceLast);
|
|
19601
|
+
setDotColor(getLatencyColor2(delay));
|
|
19517
19602
|
};
|
|
19518
19603
|
checkLatency();
|
|
19519
19604
|
const timer = setInterval(checkLatency, 100);
|