# Context meter

What fills the model's context budget, as a ring in the composer that opens to a breakdown: system, instructions, Know, the thread, tools, files. Counts are the service's own token counts; the ring warns past 80%. When a new count arrives the ring sweeps to it and changes colour at the warning line; it draws its first value in place, with no sweep from zero.

- Registry name: `context-meter` (`@candor/context-meter`)
- Tier: Free (MIT). No licence key needed.
- Docs: https://candor.themethodic.com/docs/context-meter

## Install

```bash
npx candor-ui add context-meter
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/context-meter`.
It brings in: know, locale, popover, utils.

## Example

```tsx
"use client"

import { ContextMeter } from "@/components/context-meter"

export default function Example() {
  return (
    <ContextMeter
      className="max-w-md"
      limit={200_000}
      segments={[
        { label: "System prompt", tokens: 3_200, kind: "system" },
        { label: "Help-centre articles", tokens: 21_000, kind: "knowledge" },
        { label: "This conversation", tokens: 46_500, kind: "thread" },
        { label: "Tool results", tokens: 12_800, kind: "tools" },
      ]}
    />
  )
}
```

## <ContextMeter>

Props:

- `segments: ContextSegment[]`: What fills the context window, by kind, in tokens.
- `limit: number`: The model's context window, in tokens.
- `className?: string | undefined`

## Strings (`contextMeter`)

The fixed words, English by default. Override any of them under `contextMeter` in `<LocaleProvider strings={{ contextMeter: { … } }}>`; the table is exported as `contextMeterStrings`.

- `thousands`: {n}k
- `label`: Context: {used} of {limit} tokens used
- `context`: Context
- `usage`: {used} / {limit} tokens
- `nearlyFull`: Nearly full. Older thread turns will be summarised to make room.

## Rules for using Candor UI

- Components take plain typed data. Never pass model output as HTML or render it as a link; messages are typed blocks.
- A control that can't be used says why: wrap it in `<Locked reason="…">`, don't just disable it.
- Don't show a value you don't have: leave it out (it renders as —) rather than guess. An estimate is labelled as one.
- Nothing is pre-selected in a decision a person makes, and the agent is named from your app's data, never from model output.
- Your app's words go in `LocaleProvider` (fixed strings) and `TermsProvider` (nouns); entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
