Context Meter
How much of the model's context window a conversation has used. A 16px ring and a percentage on the toolbar; hover or click it and it opens onto what the total is made of and what it has cost.
Installation#
Usage#
import {
ContextMeter,
ContextMeterTrigger,
ContextMeterContent,
ContextMeterRows,
ContextMeterRow,
ContextMeterFooter,
} from "@/components/ui/context-meter"
export function Usage({ usage, model }) {
return (
<ContextMeter used={usage.totalTokens} max={model.contextWindow}>
<ContextMeterTrigger />
<ContextMeterContent>
<ContextMeterRows>
<ContextMeterRow label="Input" tokens={usage.inputTokens} />
<ContextMeterRow label="Output" tokens={usage.outputTokens} />
</ContextMeterRows>
</ContextMeterContent>
</ContextMeter>
)
}Anatomy#
import {
ContextMeter,
ContextMeterTrigger,
ContextMeterContent,
ContextMeterRows,
ContextMeterRow,
ContextMeterFooter,
} from "@/components/ui/context-meter"
<ContextMeter>
<ContextMeterTrigger />
<ContextMeterContent>
<ContextMeterRows>
<ContextMeterRow />
</ContextMeterRows>
<ContextMeterFooter />
</ContextMeterContent>
</ContextMeter>Levels#
Three levels by the fraction of the window used: normal, then warning from warnAt (70%), then critical from criticalAt (90%). The level tints the ring and the bar and nothing else: a window filling up is information, not an error, until it is nearly full. Drag the slider to watch the ring sweep.
Ring only#
showValue={false} drops the percentage for a crowded toolbar. The trigger keeps the whole reading as its accessible name, and the number is one hover away.
An action in the footer#
The footer is a muted well, so it can carry the way out of a full window as well as the cost: a ghost button to compact or summarise the conversation.
In a composer#
On PromptInput's toolbar it sits beside the send button, with the Model Selector at the other end. Pass the selected model's window as max and the reading re-scales when you switch: the same chat is 42% of a 200K window and 8% of a 1M one.
API reference#
ContextMeter
The root: the reading every part shares, and a Popover that opens on hover and on click.
| Prop | Type | Default | Description |
|---|---|---|---|
| used* | number | - | Tokens the conversation uses now. |
| max* | number | - | The model's context window, in tokens. |
| warnAt | number | 0.7 | Fraction from which the reading turns warning. |
| criticalAt | number | 0.9 | Fraction from which the reading turns critical. |
| format | (tokens: number) => string | compact, en-US | How a token count is written (84.2K). Fixed locale by default, so server and client agree. |
| open | boolean | - | The panel's open state, controlled. |
| defaultOpen | boolean | - | The panel's initial open state. |
| onOpenChange | (open: boolean) => void | - | Called when the panel opens or closes. |
ContextMeterTrigger
A ghost Button with the ring and the percentage. Its accessible name is the whole reading. Forwards Button props.
| Prop | Type | Default | Description |
|---|---|---|---|
| showValue | boolean | true | Show the percentage beside the ring. |
| size | ButtonProps["size"] | "sm" | Match the bar it sits on. |
| Data attribute | Description |
|---|---|
| data-level | normal, warning or critical. |
ContextMeterContent
The breakdown panel: the total over a Meter bar in the level's tone, then your rows. Forwards PopoverContent props.
| Prop | Type | Default | Description |
|---|---|---|---|
| title | React.ReactNode | "Context window" | The panel's heading. |
ContextMeterRows
The rows under the bar, a <dl>.
ContextMeterRow
One part of the total, a <dt>/<dd> pair.
| Prop | Type | Default | Description |
|---|---|---|---|
| label* | React.ReactNode | - | What the part is: Input, Cached. |
| tokens | number | - | Formatted the way the root formats. |
| value | React.ReactNode | - | Anything else in the value column (a price). |
| swatch | string | - | A text colour class for a leading dot, to key the row to a chart. |
ContextMeterFooter
The muted well that closes the panel: the cost, or an action. Forwards native <div> props.