gpui-ai

Progress

Context meter

Context-window usage as a ring, bar, or text with severity tones and a breakdown.

Context meter — gpui-ai

Starts when it scrolls into view

Pop out

NORD FROST · DARK · RADIUS 6/10 · BASE 16PX · SHADOW

Running the real component, compiled to WebAssembly. The frame is 120 px tall, which is what this story measures at the demo width in the default type size — a narrower column or a theme that changes that size will wrap it differently.
Story
context-meter
Demo height
120 px
Events
None

Code

Cut from the gallery story this page runs, so it stays true.

crates/gallery/src/gallery.rsOpen in the galleryImplementation
let tokens = cx.theme().semantic_tokens();
let comfortable = ContextUsage::new(84_300, 200_000)
    .input(61_000)
    .output(19_800)
    .cached(3_500)
    .cost("$0.42");
let elevated = ContextUsage::new(148_000, 200_000)
    .input(120_000)
    .output(22_000)
    .reasoning(6_000)
    .cost("$0.91");
let critical = ContextUsage::new(186_500, 200_000)
    .input(150_000)
    .output(30_000)
    .reasoning(6_500)
    .cost("$1.28");
let row = |label: &'static str, variant: ContextMeterVariant| {
    h_flex()
        .items_center()
        .flex_wrap()
        .gap(tokens.spacing.lg)
        .child(
            div()
                .w(tokens.spacing.xxl * 2.0)
                .text_xs()
                .text_color(cx.theme().muted_foreground)
                .child(label),
        )
        .child(
            ContextMeter::new(format!("ctx-{label}-comfortable"), &comfortable)
                .variant(variant),
        )
        .child(
            ContextMeter::new(format!("ctx-{label}-elevated"), &elevated)
                .variant(variant),
        )
        .child(
            ContextMeter::new(format!("ctx-{label}-critical"), &critical)
                .variant(variant),
        )
};
v_flex()
    .gap(tokens.spacing.md)
    .child(row("Ring", ContextMeterVariant::Ring))
    .child(row("Bar", ContextMeterVariant::Bar))
    .child(row("Text", ContextMeterVariant::Text))

Events and ownership

Who owns the state
ContextMeter renders state supplied by the application; it does not own durable work.
What it emits
This presentation surface adds no component-specific interaction event.
What it means
Context-window usage as a ring, bar, or text with severity tones and a breakdown.
Overflow and motion
Wide content retains context in a bounded surface; reduced motion preserves a useful state.

What the demo does and does not show

The demo above is the same Rust as the native component, compiled to WebAssembly and drawn on a WebGPU canvas — not a mock-up, a recording, or a re-implementation. What it paints is what the component paints: layout, colour from the live theme, and motion.

The live browser specimen requires WebGPU; the native component remains the authoritative runtime.

A canvas cannot stand in for the platform, so treat everything that goes through the operating system as unproven here: keyboard handling and shortcuts, screen reader semantics, text input and IME, the clipboard, file drops, and the frame rate you would get on your own GPU. Judge those in a native build. If your browser has no WebGPU, the frame says so rather than showing an empty box.