@wrongstack/webui 0.273.0 → 0.273.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/assets/{index-CM62rXoC.js → index-D0dNaLPf.js} +54 -54
- package/dist/index.html +1 -1
- package/dist/index.js +108 -42
- package/dist/index.js.map +1 -1
- package/dist/server/entry.js +365 -287
- package/dist/server/entry.js.map +1 -1
- package/dist/server/index.js +366 -288
- package/dist/server/index.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/package.json +6 -6
package/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/wrongstack.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>WrongStack WebUI</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-D0dNaLPf.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-QTnfLwEv.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/vendor-P9eRrO6V.js">
|
|
11
11
|
<link rel="stylesheet" crossorigin href="/assets/vendor-Doh9e_v3.css">
|
package/dist/index.js
CHANGED
|
@@ -185,7 +185,7 @@ function httpOriginForAuth() {
|
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
// src/lib/ws-client.ts
|
|
188
|
-
var WrongStackWebSocketClient = class {
|
|
188
|
+
var WrongStackWebSocketClient = class _WrongStackWebSocketClient {
|
|
189
189
|
ws = null;
|
|
190
190
|
url;
|
|
191
191
|
handlers = /* @__PURE__ */ new Map();
|
|
@@ -195,6 +195,14 @@ var WrongStackWebSocketClient = class {
|
|
|
195
195
|
shouldReconnect = true;
|
|
196
196
|
reconnectTimer = null;
|
|
197
197
|
messageQueue = [];
|
|
198
|
+
// Cap on the offline-queue depth. Past this, send() drops the OLDEST
|
|
199
|
+
// queued message before appending the new one (FIFO drop). Bounds
|
|
200
|
+
// memory under long disconnects and prevents stale commands from
|
|
201
|
+
// flooding the server on reconnect -- a 50k-deep queue of stale
|
|
202
|
+
// user_messages re-firing on next open would just confuse the model
|
|
203
|
+
// and waste its context window. 1000 is a generous budget for a
|
|
204
|
+
// genuine reconnect window (typical reconnect <10s; <50 msg/s).
|
|
205
|
+
static MAX_QUEUED_MESSAGES = 1e3;
|
|
198
206
|
pendingConfirms = /* @__PURE__ */ new Map();
|
|
199
207
|
sessionId = null;
|
|
200
208
|
/** Stored last close reason / error message so the UI can show "what
|
|
@@ -440,6 +448,18 @@ var WrongStackWebSocketClient = class {
|
|
|
440
448
|
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
441
449
|
this.ws.send(JSON.stringify(message));
|
|
442
450
|
} else {
|
|
451
|
+
if (this.messageQueue.length >= _WrongStackWebSocketClient.MAX_QUEUED_MESSAGES) {
|
|
452
|
+
const dropped = this.messageQueue.shift();
|
|
453
|
+
if (dropped) {
|
|
454
|
+
console.warn(JSON.stringify({
|
|
455
|
+
level: "warn",
|
|
456
|
+
event: "ws_client.message_queue_full",
|
|
457
|
+
cap: _WrongStackWebSocketClient.MAX_QUEUED_MESSAGES,
|
|
458
|
+
droppedType: dropped.type,
|
|
459
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
460
|
+
}));
|
|
461
|
+
}
|
|
462
|
+
}
|
|
443
463
|
this.messageQueue.push(message);
|
|
444
464
|
}
|
|
445
465
|
}
|
|
@@ -742,6 +762,7 @@ var WrongStackWebSocketClient = class {
|
|
|
742
762
|
clearTimeout(this.reconnectTimer);
|
|
743
763
|
this.reconnectTimer = null;
|
|
744
764
|
}
|
|
765
|
+
this.messageQueue.length = 0;
|
|
745
766
|
this.ws?.close();
|
|
746
767
|
this.ws = null;
|
|
747
768
|
}
|
|
@@ -1536,6 +1557,10 @@ function pushTimeline(timeline, event) {
|
|
|
1536
1557
|
function bumpSparkline(bins) {
|
|
1537
1558
|
return [bins[0] + 1, ...bins.slice(0, SPARKLINE_BINS - 1)];
|
|
1538
1559
|
}
|
|
1560
|
+
function clampContextPct(pct) {
|
|
1561
|
+
if (!Number.isFinite(pct)) return 0;
|
|
1562
|
+
return Math.max(0, Math.min(100, pct));
|
|
1563
|
+
}
|
|
1539
1564
|
var useFleetStore = create10()((set, get) => ({
|
|
1540
1565
|
agents: /* @__PURE__ */ new Map(),
|
|
1541
1566
|
leaderId: void 0,
|
|
@@ -1703,7 +1728,7 @@ var useFleetStore = create10()((set, get) => ({
|
|
|
1703
1728
|
});
|
|
1704
1729
|
break;
|
|
1705
1730
|
case "ctx_pct":
|
|
1706
|
-
next.ctxPct = Math.round(Math.max(0, e.load ?? 0) * 100);
|
|
1731
|
+
next.ctxPct = clampContextPct(Math.round(Math.max(0, e.load ?? 0) * 100));
|
|
1707
1732
|
next.ctxTokens = e.tokens ?? next.ctxTokens;
|
|
1708
1733
|
next.maxContext = e.maxContext ?? next.maxContext;
|
|
1709
1734
|
if (next.ctxPct >= 80 && !next.budgetWarning) {
|
|
@@ -2033,6 +2058,10 @@ var useFileStore = create17()((set, get) => ({
|
|
|
2033
2058
|
|
|
2034
2059
|
// src/stores/viz-store.ts
|
|
2035
2060
|
import { create as create18 } from "zustand";
|
|
2061
|
+
function contextPctFromLoad(load) {
|
|
2062
|
+
const value = typeof load === "number" && Number.isFinite(load) ? load : 0;
|
|
2063
|
+
return Math.max(0, Math.min(100, Math.round(value * 100)));
|
|
2064
|
+
}
|
|
2036
2065
|
function inferKind(event, isTarget = false) {
|
|
2037
2066
|
if (isTarget && event.target) {
|
|
2038
2067
|
if (event.kind === "agent:tool") return "tool";
|
|
@@ -2472,7 +2501,7 @@ function wsToVizEvent(wsType, payload) {
|
|
|
2472
2501
|
timestamp: Date.now(),
|
|
2473
2502
|
source: agentId,
|
|
2474
2503
|
target: "session",
|
|
2475
|
-
label: `ctx ${
|
|
2504
|
+
label: `ctx ${contextPctFromLoad(payload.load)}%`,
|
|
2476
2505
|
magnitude: payload.tokens ?? 0,
|
|
2477
2506
|
data: payload,
|
|
2478
2507
|
color: NODE_COLORS.agent,
|
|
@@ -2570,7 +2599,6 @@ function wsToVizEvent(wsType, payload) {
|
|
|
2570
2599
|
};
|
|
2571
2600
|
}
|
|
2572
2601
|
case "ctx.pct": {
|
|
2573
|
-
const load = payload.load ?? 0;
|
|
2574
2602
|
const tokens = payload.tokens ?? 0;
|
|
2575
2603
|
return {
|
|
2576
2604
|
id: nextId(),
|
|
@@ -2578,7 +2606,7 @@ function wsToVizEvent(wsType, payload) {
|
|
|
2578
2606
|
timestamp: Date.now(),
|
|
2579
2607
|
source: "leader",
|
|
2580
2608
|
target: "session",
|
|
2581
|
-
label: `ctx ${
|
|
2609
|
+
label: `ctx ${contextPctFromLoad(payload.load)}%`,
|
|
2582
2610
|
magnitude: tokens,
|
|
2583
2611
|
data: payload,
|
|
2584
2612
|
color: NODE_COLORS.agent,
|
|
@@ -2710,6 +2738,20 @@ function deriveMonitorStats(sessions) {
|
|
|
2710
2738
|
}
|
|
2711
2739
|
return { clientCounts, totalAgents, activeAgents, aggregate };
|
|
2712
2740
|
}
|
|
2741
|
+
function clampCtxPct(pct) {
|
|
2742
|
+
if (pct === void 0) return void 0;
|
|
2743
|
+
if (!Number.isFinite(pct)) return 0;
|
|
2744
|
+
return Math.max(0, Math.min(100, Math.round(pct)));
|
|
2745
|
+
}
|
|
2746
|
+
function normalizeLiveSessions(sessions) {
|
|
2747
|
+
return sessions.map((session) => ({
|
|
2748
|
+
...session,
|
|
2749
|
+
agents: session.agents.map((agent) => ({
|
|
2750
|
+
...agent,
|
|
2751
|
+
ctxPct: clampCtxPct(agent.ctxPct)
|
|
2752
|
+
}))
|
|
2753
|
+
}));
|
|
2754
|
+
}
|
|
2713
2755
|
var mailActivitySeq = 0;
|
|
2714
2756
|
var useMonitorStore = create19()((set) => ({
|
|
2715
2757
|
clientCounts: { tui: 0, webui: 0, repl: 0 },
|
|
@@ -2724,11 +2766,14 @@ var useMonitorStore = create19()((set) => ({
|
|
|
2724
2766
|
aggregate: { toolCalls: 0, costUsd: 0, tokensIn: 0, tokensOut: 0 },
|
|
2725
2767
|
lastUpdated: Date.now(),
|
|
2726
2768
|
setClientCounts: (counts) => set({ clientCounts: counts, lastUpdated: Date.now() }),
|
|
2727
|
-
setLiveSessions: (sessions) =>
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2769
|
+
setLiveSessions: (sessions) => {
|
|
2770
|
+
const normalized = normalizeLiveSessions(sessions);
|
|
2771
|
+
set({
|
|
2772
|
+
liveSessions: normalized,
|
|
2773
|
+
...deriveMonitorStats(normalized),
|
|
2774
|
+
lastUpdated: Date.now()
|
|
2775
|
+
});
|
|
2776
|
+
},
|
|
2732
2777
|
addMailActivity: (activity) => set((state) => ({
|
|
2733
2778
|
mailActivity: [{ ...activity, seq: activity.seq ?? ++mailActivitySeq }, ...state.mailActivity].slice(0, 50),
|
|
2734
2779
|
lastUpdated: Date.now()
|
|
@@ -3661,10 +3706,18 @@ function handleContextCompacted(msg) {
|
|
|
3661
3706
|
function handleCompactionFailed(msg) {
|
|
3662
3707
|
pipeViz2(msg);
|
|
3663
3708
|
const payload = msg.payload;
|
|
3664
|
-
|
|
3709
|
+
let load;
|
|
3710
|
+
let label;
|
|
3711
|
+
if (payload.budget && payload.budget.availableInputTokens > 0) {
|
|
3712
|
+
load = Math.min(100, Math.max(0, Math.round(payload.budget.load * 100)));
|
|
3713
|
+
label = "input budget";
|
|
3714
|
+
} else {
|
|
3715
|
+
load = payload.maxContext > 0 ? Math.min(100, Math.max(0, Math.round(payload.tokens / payload.maxContext * 100))) : 0;
|
|
3716
|
+
label = "context";
|
|
3717
|
+
}
|
|
3665
3718
|
useChatStore.getState().addMessage({
|
|
3666
3719
|
role: "assistant",
|
|
3667
|
-
content: `Compaction failed at ${payload.level} (${load}%
|
|
3720
|
+
content: `Compaction failed at ${payload.level} (${load}% ${label}): ${payload.message}`,
|
|
3668
3721
|
isError: payload.fatal
|
|
3669
3722
|
});
|
|
3670
3723
|
toast.error(`Compaction failed: ${payload.message}`);
|
|
@@ -11545,6 +11598,10 @@ function getTextColor(pct) {
|
|
|
11545
11598
|
if (pct >= 60) return "text-[hsl(var(--warning))]";
|
|
11546
11599
|
return "text-[hsl(var(--success))]";
|
|
11547
11600
|
}
|
|
11601
|
+
function clampPct(pct) {
|
|
11602
|
+
if (!Number.isFinite(pct)) return 0;
|
|
11603
|
+
return Math.max(0, Math.min(100, pct));
|
|
11604
|
+
}
|
|
11548
11605
|
function ContextBar({
|
|
11549
11606
|
pct,
|
|
11550
11607
|
tokens,
|
|
@@ -11554,7 +11611,7 @@ function ContextBar({
|
|
|
11554
11611
|
className,
|
|
11555
11612
|
onClick
|
|
11556
11613
|
}) {
|
|
11557
|
-
const clamped =
|
|
11614
|
+
const clamped = clampPct(pct);
|
|
11558
11615
|
const eighths = Math.round(clamped / 100 * segments * 8);
|
|
11559
11616
|
const bars = [];
|
|
11560
11617
|
let remaining = eighths;
|
|
@@ -11563,7 +11620,7 @@ function ContextBar({
|
|
|
11563
11620
|
bars.push({ fill: segFill });
|
|
11564
11621
|
remaining -= segFill;
|
|
11565
11622
|
}
|
|
11566
|
-
const pctText =
|
|
11623
|
+
const pctText = `${Math.round(clamped)}%`;
|
|
11567
11624
|
const tokenText = showTokens && tokens !== void 0 && maxTokens !== void 0 && maxTokens > 0 ? ` ${fmtTok(tokens)}/${fmtTok(maxTokens)}` : "";
|
|
11568
11625
|
return /* @__PURE__ */ jsxs28(
|
|
11569
11626
|
"span",
|
|
@@ -11571,8 +11628,8 @@ function ContextBar({
|
|
|
11571
11628
|
className: cn(
|
|
11572
11629
|
"inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full text-[11px] font-mono font-medium shrink-0",
|
|
11573
11630
|
onClick && "cursor-pointer hover:ring-1 hover:ring-ring transition-shadow",
|
|
11574
|
-
getTextColor(
|
|
11575
|
-
|
|
11631
|
+
getTextColor(clamped),
|
|
11632
|
+
clamped >= 75 ? "bg-red-500/10" : clamped >= 60 ? "bg-amber-500/10" : "bg-emerald-500/10",
|
|
11576
11633
|
className
|
|
11577
11634
|
),
|
|
11578
11635
|
title: (tokens !== void 0 && maxTokens !== void 0 ? `Context window: ${tokens.toLocaleString()} / ${maxTokens.toLocaleString()} tokens (${pctText})` : `Context window: ${pctText}`) + (onClick ? " \u2014 click for breakdown" : ""),
|
|
@@ -11595,7 +11652,7 @@ function ContextBar({
|
|
|
11595
11652
|
{
|
|
11596
11653
|
className: cn(
|
|
11597
11654
|
"tabular-nums w-[0.55em] text-center",
|
|
11598
|
-
b.fill > 0 ? getTextColor(
|
|
11655
|
+
b.fill > 0 ? getTextColor(clamped) : "text-muted-foreground/30"
|
|
11599
11656
|
),
|
|
11600
11657
|
children: SEGMENT_FILL[b.fill] ?? " "
|
|
11601
11658
|
},
|
|
@@ -11615,8 +11672,8 @@ function ContextFillBar({
|
|
|
11615
11672
|
className,
|
|
11616
11673
|
onClick
|
|
11617
11674
|
}) {
|
|
11618
|
-
const clamped =
|
|
11619
|
-
const pctText =
|
|
11675
|
+
const clamped = clampPct(pct);
|
|
11676
|
+
const pctText = `${Math.round(clamped)}%`;
|
|
11620
11677
|
const tokenText = showTokens && tokens !== void 0 && maxTokens !== void 0 && maxTokens > 0 ? ` ${fmtTok(tokens)}/${fmtTok(maxTokens)}` : "";
|
|
11621
11678
|
return /* @__PURE__ */ jsxs28(
|
|
11622
11679
|
"span",
|
|
@@ -11644,14 +11701,14 @@ function ContextFillBar({
|
|
|
11644
11701
|
/* @__PURE__ */ jsx31("span", { className: "h-1.5 w-16 overflow-hidden rounded-full bg-muted shrink-0", children: /* @__PURE__ */ jsx31(
|
|
11645
11702
|
"span",
|
|
11646
11703
|
{
|
|
11647
|
-
className: cn("h-full rounded-full transition-all duration-300", getColor(
|
|
11704
|
+
className: cn("h-full rounded-full transition-all duration-300", getColor(clamped)),
|
|
11648
11705
|
style: { width: `${Math.max(2, clamped)}%` }
|
|
11649
11706
|
}
|
|
11650
11707
|
) }),
|
|
11651
11708
|
/* @__PURE__ */ jsx31(
|
|
11652
11709
|
"span",
|
|
11653
11710
|
{
|
|
11654
|
-
className: cn("text-[11px] font-mono tabular-nums font-medium", getTextColor(
|
|
11711
|
+
className: cn("text-[11px] font-mono tabular-nums font-medium", getTextColor(clamped)),
|
|
11655
11712
|
children: pctText
|
|
11656
11713
|
}
|
|
11657
11714
|
),
|
|
@@ -14156,7 +14213,7 @@ function ChatView() {
|
|
|
14156
14213
|
document.addEventListener("open:context-breakdown", handler);
|
|
14157
14214
|
return () => document.removeEventListener("open:context-breakdown", handler);
|
|
14158
14215
|
}, []);
|
|
14159
|
-
const ctxPct = maxContext > 0 && lastInputTokens > 0 ? Math.round(lastInputTokens / maxContext * 100) : 0;
|
|
14216
|
+
const ctxPct = maxContext > 0 && lastInputTokens > 0 ? Math.min(100, Math.round(lastInputTokens / maxContext * 100)) : 0;
|
|
14160
14217
|
const _ctxTone = ctxPct >= 85 ? "bg-red-500/15 text-red-600 dark:text-red-400" : ctxPct >= 70 ? "bg-amber-500/15 text-amber-600 dark:text-amber-400" : "bg-muted text-muted-foreground";
|
|
14161
14218
|
const [pinnedToBottom, setPinnedToBottom] = useState33(true);
|
|
14162
14219
|
const [unreadCount, setUnreadCount] = useState33(0);
|
|
@@ -20874,6 +20931,7 @@ function AgentDetail({
|
|
|
20874
20931
|
const [copied, setCopied] = useState47(false);
|
|
20875
20932
|
const leaderId = useFleetStore((s) => s.leaderId);
|
|
20876
20933
|
const isLeader = agent.id === leaderId;
|
|
20934
|
+
const ctxPct = Math.min(100, Math.max(0, agent.ctxPct));
|
|
20877
20935
|
const handleCopy = useCallback24(async (text) => {
|
|
20878
20936
|
try {
|
|
20879
20937
|
await navigator.clipboard.writeText(text);
|
|
@@ -20882,7 +20940,7 @@ function AgentDetail({
|
|
|
20882
20940
|
} catch {
|
|
20883
20941
|
}
|
|
20884
20942
|
}, []);
|
|
20885
|
-
const ctxTone =
|
|
20943
|
+
const ctxTone = ctxPct >= 85 ? "bg-red-500/15 text-red-600 dark:text-red-400" : ctxPct >= 70 ? "bg-amber-500/15 text-amber-600 dark:text-amber-400" : "bg-muted text-muted-foreground";
|
|
20886
20944
|
return /* @__PURE__ */ jsx76("div", { className: "fixed inset-0 z-50 flex items-start justify-center pt-[10vh] bg-black/40 backdrop-blur-sm", children: /* @__PURE__ */ jsxs69("div", { className: "w-full max-w-xl max-h-[80vh] overflow-y-auto rounded-xl border bg-card shadow-2xl", children: [
|
|
20887
20945
|
/* @__PURE__ */ jsxs69(
|
|
20888
20946
|
"div",
|
|
@@ -20972,7 +21030,7 @@ function AgentDetail({
|
|
|
20972
21030
|
/* @__PURE__ */ jsxs69("div", { className: "flex items-center justify-between text-[10px]", children: [
|
|
20973
21031
|
/* @__PURE__ */ jsx76("span", { className: "text-muted-foreground", children: "Context window" }),
|
|
20974
21032
|
/* @__PURE__ */ jsxs69("span", { className: cn("tabular font-medium", ctxTone.replace(/bg-\S+\s*/g, "")), children: [
|
|
20975
|
-
|
|
21033
|
+
ctxPct,
|
|
20976
21034
|
"%"
|
|
20977
21035
|
] })
|
|
20978
21036
|
] }),
|
|
@@ -20981,9 +21039,9 @@ function AgentDetail({
|
|
|
20981
21039
|
{
|
|
20982
21040
|
className: cn(
|
|
20983
21041
|
"h-full rounded-full transition-all",
|
|
20984
|
-
|
|
21042
|
+
ctxPct >= 85 ? "bg-destructive" : ctxPct >= 70 ? "bg-[hsl(var(--warning))]" : "bg-primary"
|
|
20985
21043
|
),
|
|
20986
|
-
style: { width: `${Math.
|
|
21044
|
+
style: { width: `${Math.max(2, ctxPct)}%` }
|
|
20987
21045
|
}
|
|
20988
21046
|
) }),
|
|
20989
21047
|
/* @__PURE__ */ jsxs69("div", { className: "text-[10px] text-muted-foreground tabular text-right", children: [
|
|
@@ -21094,6 +21152,7 @@ function AgentCard({
|
|
|
21094
21152
|
const meta2 = STATUS_META2[a.status];
|
|
21095
21153
|
const active = a.status === "running";
|
|
21096
21154
|
const tool = a.currentTool ?? a.lastTool;
|
|
21155
|
+
const ctxPct = Math.min(100, Math.max(0, a.ctxPct));
|
|
21097
21156
|
return /* @__PURE__ */ jsxs69(
|
|
21098
21157
|
"button",
|
|
21099
21158
|
{
|
|
@@ -21143,18 +21202,18 @@ function AgentCard({
|
|
|
21143
21202
|
]
|
|
21144
21203
|
}
|
|
21145
21204
|
),
|
|
21146
|
-
active && a.maxContext > 0 && /* @__PURE__ */ jsxs69("div", { className: "flex items-center gap-1", title: `Context ${
|
|
21205
|
+
active && a.maxContext > 0 && /* @__PURE__ */ jsxs69("div", { className: "flex items-center gap-1", title: `Context ${ctxPct}%`, children: [
|
|
21147
21206
|
/* @__PURE__ */ jsx76("div", { className: "h-1 flex-1 overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx76(
|
|
21148
21207
|
"div",
|
|
21149
21208
|
{
|
|
21150
21209
|
className: cn(
|
|
21151
21210
|
"h-full rounded-full transition-all",
|
|
21152
|
-
|
|
21211
|
+
ctxPct >= 85 ? "bg-destructive" : ctxPct >= 70 ? "bg-[hsl(var(--warning))]" : "bg-primary"
|
|
21153
21212
|
),
|
|
21154
|
-
style: { width: `${Math.
|
|
21213
|
+
style: { width: `${Math.max(2, ctxPct)}%` }
|
|
21155
21214
|
}
|
|
21156
21215
|
) }),
|
|
21157
|
-
/* @__PURE__ */ jsx76("span", { className: "tabular text-[9px] text-muted-foreground", children: a.maxContext > 0 ? `${
|
|
21216
|
+
/* @__PURE__ */ jsx76("span", { className: "tabular text-[9px] text-muted-foreground", children: a.maxContext > 0 ? `${ctxPct}%` : "\u2014" })
|
|
21158
21217
|
] }),
|
|
21159
21218
|
a.error && /* @__PURE__ */ jsx76(
|
|
21160
21219
|
"div",
|
|
@@ -21920,7 +21979,7 @@ function SessionPanel() {
|
|
|
21920
21979
|
() => Array.from(fleetAgents.values()).filter((a) => a.status === "running").length,
|
|
21921
21980
|
[fleetAgents]
|
|
21922
21981
|
);
|
|
21923
|
-
const ctxPct = maxContext > 0 && lastInputTokens > 0 ? Math.round(lastInputTokens / maxContext * 100) : 0;
|
|
21982
|
+
const ctxPct = maxContext > 0 && lastInputTokens > 0 ? Math.min(100, Math.round(lastInputTokens / maxContext * 100)) : 0;
|
|
21924
21983
|
const pinnedRows = pinnedIds.map((id) => messages.find((m) => m.id === id)).filter((m) => !!m && m.content.length > 0);
|
|
21925
21984
|
const send = (msg) => getWSClient(wsUrl)?.send?.(msg);
|
|
21926
21985
|
return /* @__PURE__ */ jsxs74("div", { className: "flex-1 overflow-y-auto", children: [
|
|
@@ -25037,6 +25096,7 @@ function FleetAgentDetailPanel({
|
|
|
25037
25096
|
const [showFullToolLog, setShowFullToolLog] = useState60(false);
|
|
25038
25097
|
const meta2 = STATUS_META6[agent.status];
|
|
25039
25098
|
const active = agent.status === "running";
|
|
25099
|
+
const ctxPct = Math.min(100, Math.max(0, agent.ctxPct));
|
|
25040
25100
|
const handleCopy = useCallback35(async (text) => {
|
|
25041
25101
|
try {
|
|
25042
25102
|
await navigator.clipboard.writeText(text);
|
|
@@ -25155,13 +25215,13 @@ function FleetAgentDetailPanel({
|
|
|
25155
25215
|
{
|
|
25156
25216
|
className: cn(
|
|
25157
25217
|
"h-full rounded-full transition-all",
|
|
25158
|
-
|
|
25218
|
+
ctxPct >= 85 ? "bg-destructive" : ctxPct >= 70 ? "bg-amber-500" : "bg-emerald-500"
|
|
25159
25219
|
),
|
|
25160
|
-
style: { width: `${
|
|
25220
|
+
style: { width: `${ctxPct}%` }
|
|
25161
25221
|
}
|
|
25162
25222
|
) }),
|
|
25163
25223
|
/* @__PURE__ */ jsxs89("span", { className: "text-[10px] text-muted-foreground tabular-nums font-mono", children: [
|
|
25164
|
-
|
|
25224
|
+
ctxPct,
|
|
25165
25225
|
"% used"
|
|
25166
25226
|
] })
|
|
25167
25227
|
] })
|
|
@@ -25295,6 +25355,7 @@ function FleetAgentRow({
|
|
|
25295
25355
|
}) {
|
|
25296
25356
|
const meta2 = STATUS_META6[agent.status];
|
|
25297
25357
|
const active = agent.status === "running";
|
|
25358
|
+
const ctxPct = Math.min(100, Math.max(0, agent.ctxPct));
|
|
25298
25359
|
return /* @__PURE__ */ jsxs89(
|
|
25299
25360
|
"button",
|
|
25300
25361
|
{
|
|
@@ -25331,12 +25392,12 @@ function FleetAgentRow({
|
|
|
25331
25392
|
{
|
|
25332
25393
|
className: cn(
|
|
25333
25394
|
"h-full rounded-full transition-all",
|
|
25334
|
-
|
|
25395
|
+
ctxPct >= 85 ? "bg-destructive" : ctxPct >= 70 ? "bg-amber-500" : "bg-emerald-500"
|
|
25335
25396
|
),
|
|
25336
|
-
style: { width: `${
|
|
25397
|
+
style: { width: `${ctxPct}%` }
|
|
25337
25398
|
}
|
|
25338
25399
|
) }),
|
|
25339
|
-
/* @__PURE__ */ jsx96("span", { className: "text-[9px] tabular-nums text-muted-foreground font-mono leading-none", children: agent.maxContext > 0 ? `${
|
|
25400
|
+
/* @__PURE__ */ jsx96("span", { className: "text-[9px] tabular-nums text-muted-foreground font-mono leading-none", children: agent.maxContext > 0 ? `${ctxPct}%` : "\u2014" })
|
|
25340
25401
|
] }),
|
|
25341
25402
|
/* @__PURE__ */ jsx96("span", { className: "tabular-nums text-[10px] text-muted-foreground", children: agent.extensions > 0 ? `\u26A1\xD7${agent.extensions}` : "\u2014" }),
|
|
25342
25403
|
/* @__PURE__ */ jsx96("span", { className: "text-[9px] text-destructive truncate", title: agent.failureReason, children: agent.failureReason ?? "" })
|
|
@@ -27758,6 +27819,9 @@ function feedColor(kind) {
|
|
|
27758
27819
|
|
|
27759
27820
|
// src/components/OfficeMapCanvas.tsx
|
|
27760
27821
|
import { Fragment as Fragment22, jsx as jsx104, jsxs as jsxs97 } from "react/jsx-runtime";
|
|
27822
|
+
function clampCtxPct2(value) {
|
|
27823
|
+
return Math.min(100, Math.max(0, value ?? 0));
|
|
27824
|
+
}
|
|
27761
27825
|
function StatusLED({ status, small, activity = 0 }) {
|
|
27762
27826
|
const size = small ? "w-2 h-2" : "w-3 h-3";
|
|
27763
27827
|
const glowRadius = small ? 4 + activity * 4 : 6 + activity * 6;
|
|
@@ -28061,6 +28125,7 @@ function AgentNode({ data }) {
|
|
|
28061
28125
|
const isError = data.status === "error";
|
|
28062
28126
|
const isCompleted = data.status === "completed";
|
|
28063
28127
|
const color = data.color || "#06b6d4";
|
|
28128
|
+
const ctxPct = clampCtxPct2(data.ctxPct);
|
|
28064
28129
|
return /* @__PURE__ */ jsxs97("div", { className: cn(
|
|
28065
28130
|
"rounded-lg border p-3 min-w-[150px] transition-all backdrop-blur-sm",
|
|
28066
28131
|
isActive && "border-cyan-500/50 bg-cyan-500/10 shadow-lg shadow-cyan-500/10",
|
|
@@ -28102,15 +28167,15 @@ function AgentNode({ data }) {
|
|
|
28102
28167
|
] })
|
|
28103
28168
|
] })
|
|
28104
28169
|
] }),
|
|
28105
|
-
|
|
28170
|
+
ctxPct > 0 && /* @__PURE__ */ jsxs97("div", { className: "mb-1", children: [
|
|
28106
28171
|
/* @__PURE__ */ jsxs97("div", { className: "flex justify-between text-[8px] text-gray-500 mb-0.5", children: [
|
|
28107
28172
|
/* @__PURE__ */ jsx104("span", { children: "ctx" }),
|
|
28108
|
-
/* @__PURE__ */ jsxs97("span", { className: cn("font-mono",
|
|
28109
|
-
|
|
28173
|
+
/* @__PURE__ */ jsxs97("span", { className: cn("font-mono", ctxPct >= 90 ? "text-red-400" : ctxPct >= 70 ? "text-amber-400" : "text-gray-400"), children: [
|
|
28174
|
+
ctxPct,
|
|
28110
28175
|
"%"
|
|
28111
28176
|
] })
|
|
28112
28177
|
] }),
|
|
28113
|
-
/* @__PURE__ */ jsx104("div", { className: "h-1 rounded-full bg-slate-700/60 overflow-hidden", children: /* @__PURE__ */ jsx104("div", { className: cn("h-full",
|
|
28178
|
+
/* @__PURE__ */ jsx104("div", { className: "h-1 rounded-full bg-slate-700/60 overflow-hidden", children: /* @__PURE__ */ jsx104("div", { className: cn("h-full", ctxPct >= 90 ? "bg-red-500" : ctxPct >= 70 ? "bg-amber-500" : "bg-cyan-500"), style: { width: `${ctxPct}%` } }) })
|
|
28114
28179
|
] }),
|
|
28115
28180
|
data.lastActivityAt && /* @__PURE__ */ jsxs97("div", { className: cn("flex items-center gap-1 text-[8px]", isActive ? "text-gray-600" : "text-gray-500"), children: [
|
|
28116
28181
|
isCompleted && /* @__PURE__ */ jsx104("span", { className: "text-emerald-500/70", children: "\u2713 done \xB7" }),
|
|
@@ -29067,6 +29132,7 @@ function OfficeMapCanvas() {
|
|
|
29067
29132
|
const isAgent = d.kind === "agent";
|
|
29068
29133
|
const isClient = d.kind === "webui" || d.kind === "tui" || d.kind === "repl";
|
|
29069
29134
|
const tokTotal = (d.tokensIn || 0) + (d.tokensOut || 0);
|
|
29135
|
+
const ctxPct = clampCtxPct2(d.ctxPct);
|
|
29070
29136
|
return /* @__PURE__ */ jsxs97("div", { className: "space-y-1.5 text-xs", children: [
|
|
29071
29137
|
/* @__PURE__ */ jsx104(
|
|
29072
29138
|
Row,
|
|
@@ -29090,7 +29156,7 @@ function OfficeMapCanvas() {
|
|
|
29090
29156
|
/* @__PURE__ */ jsx104(Row, { k: "Tokens in", v: fmtCompact(d.tokensIn) }),
|
|
29091
29157
|
/* @__PURE__ */ jsx104(Row, { k: "Tokens out", v: fmtCompact(d.tokensOut) }),
|
|
29092
29158
|
/* @__PURE__ */ jsx104(Row, { k: "Tokens total", v: fmtCompact(tokTotal) }),
|
|
29093
|
-
|
|
29159
|
+
ctxPct > 0 && /* @__PURE__ */ jsx104(Row, { k: "Context", v: `${ctxPct}%`, accent: ctxPct >= 90 ? "text-destructive" : ctxPct >= 70 ? "text-amber-600 dark:text-amber-400" : "text-foreground/70" }),
|
|
29094
29160
|
/* @__PURE__ */ jsx104(Row, { k: "Cost", v: `$${(d.costUsd || 0).toFixed(4)}`, accent: "text-emerald-600 dark:text-emerald-400" }),
|
|
29095
29161
|
d.lastActivityAt && /* @__PURE__ */ jsx104(Row, { k: "Last seen", v: fmtAgo2(d.lastActivityAt, now), accent: "text-muted-foreground" })
|
|
29096
29162
|
] }),
|