Skip to content

Commit 8cef28e

Browse files
kevin-dpclaude
andcommitted
feat(agents-server-ui): circular ring gauge for the context usage indicator
Replace the flat dot before the "X%" label with a small SVG donut whose arc fills proportionally to the context-window usage. Track + progress arc both use currentColor, so the existing normal/warning/critical level colour tints the ring without extra wiring. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent aa3fbbb commit 8cef28e

3 files changed

Lines changed: 73 additions & 7 deletions

File tree

packages/agents-server-ui/src/components/ContextUsageIndicator.module.css

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,20 @@
1515
color: inherit;
1616
}
1717

18-
.dot {
19-
width: 6px;
20-
height: 6px;
21-
border-radius: 50%;
22-
background: currentColor;
23-
opacity: 0.6;
18+
.ring {
19+
display: block;
2420
flex-shrink: 0;
21+
overflow: visible;
22+
}
23+
24+
.ringTrack {
25+
stroke: currentColor;
26+
opacity: 0.22;
27+
}
28+
29+
.ringProgress {
30+
stroke: currentColor;
31+
transition: stroke-dasharray 0.3s ease;
2532
}
2633

2734
/* Levels mirror the compaction thresholds: warning once background

packages/agents-server-ui/src/components/ContextUsageIndicator.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from '@electric-ax/agents-runtime/client'
99
import type { EntityStreamDBWithActions } from '@electric-ax/agents-runtime/client'
1010
import { Tooltip } from '../ui/Tooltip'
11+
import { ContextUsageRing } from './ContextUsageRing'
1112
import styles from './ContextUsageIndicator.module.css'
1213

1314
/**
@@ -86,7 +87,7 @@ export function ContextUsageIndicator({
8687
className={[styles.indicator, styles[level]].filter(Boolean).join(` `)}
8788
aria-label={`Context used: ${percent} (${tooltip})`}
8889
>
89-
<span className={styles.dot} aria-hidden="true" />
90+
<ContextUsageRing ratio={usage.ratio} />
9091
<span className={styles.percent}>{percent}</span>
9192
</span>
9293
</Tooltip>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import styles from './ContextUsageIndicator.module.css'
2+
3+
interface ContextUsageRingProps {
4+
/** Fraction of the context window used, 0–1. */
5+
ratio: number
6+
/** Outer diameter in px. */
7+
size?: number
8+
/** Ring thickness in px. */
9+
strokeWidth?: number
10+
}
11+
12+
/**
13+
* A tiny circular gauge ("donut") whose arc fills proportionally to `ratio`.
14+
* Both the track and the progress arc use `currentColor`, so the surrounding
15+
* indicator's level colour (normal/warning/critical) tints it for free.
16+
*/
17+
export function ContextUsageRing({
18+
ratio,
19+
size = 14,
20+
strokeWidth = 2.5,
21+
}: ContextUsageRingProps): React.ReactElement {
22+
const clamped = Math.min(1, Math.max(0, ratio))
23+
const radius = (size - strokeWidth) / 2
24+
const circumference = 2 * Math.PI * radius
25+
const filled = circumference * clamped
26+
const center = size / 2
27+
28+
return (
29+
<svg
30+
className={styles.ring}
31+
width={size}
32+
height={size}
33+
viewBox={`0 0 ${size} ${size}`}
34+
aria-hidden="true"
35+
>
36+
<circle
37+
className={styles.ringTrack}
38+
cx={center}
39+
cy={center}
40+
r={radius}
41+
fill="none"
42+
strokeWidth={strokeWidth}
43+
/>
44+
<circle
45+
className={styles.ringProgress}
46+
cx={center}
47+
cy={center}
48+
r={radius}
49+
fill="none"
50+
strokeWidth={strokeWidth}
51+
strokeLinecap="round"
52+
strokeDasharray={`${filled} ${circumference - filled}`}
53+
// Start the arc at 12 o'clock and sweep clockwise.
54+
transform={`rotate(-90 ${center} ${center})`}
55+
/>
56+
</svg>
57+
)
58+
}

0 commit comments

Comments
 (0)