v1.2.0
  1. ds
  2. Agent
  3. Context meter

Context meter

A segmented context bar with normal, near and over thresholds, and a token breakdown.

Context 63%126k of 200k
  • System prompt8k
  • Tools24k
  • Thread62k
  • Files32k
  • Free74k

Compacts at 160k tokens.

Show code
<div class="ctx" data-state="normal" role="group" aria-labelledby="ctx-n">
  <div class="ctx-head">
    <span class="ctx-label" id="ctx-n"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><line x1="10" x2="14" y1="2" y2="2"/><line x1="12" x2="15" y1="14" y2="11"/><circle cx="12" cy="14" r="8"/></svg>Context</span>
    <span class="ctx-value"><b>63%</b><small>126k of 200k</small></span>
  </div>
  <div class="ctx-track" role="meter" aria-label="Context window use" aria-valuemin="0" aria-valuemax="100" aria-valuenow="63" aria-valuetext="63 percent used, 74k tokens free">
    <span class="ctx-seg" data-k="system" style="--v:4"></span>
    <span class="ctx-seg" data-k="tools" style="--v:12"></span>
    <span class="ctx-seg" data-k="thread" style="--v:31"></span>
    <span class="ctx-seg" data-k="files" style="--v:16"></span>
    <span class="ctx-seg free" style="--v:37"></span>
    <span class="ctx-mark" style="--at:.8" aria-hidden="true"></span>
  </div>
  <ul class="ctx-list">
    <li><span class="ctx-key"><i class="ctx-dot" data-k="system"></i>System prompt</span><span class="ctx-num">8k</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="tools"></i>Tools</span><span class="ctx-num">24k</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="thread"></i>Thread</span><span class="ctx-num">62k</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="files"></i>Files</span><span class="ctx-num">32k</span></li>
    <li class="free"><span class="ctx-key"><i class="ctx-dot"></i>Free</span><span class="ctx-num">74k</span></li>
  </ul>
  <p class="ctx-note"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>Compacts at 160k tokens.</p>
</div>

The context meter answers how full the window is and what filled it. The bar is one track split into named segments, so a reader can see the thread growing without opening a panel. The value line gives the percentage and the raw count; the list gives each part.

Meter is the single-track primitive. .ctx uses the same --v fill idea and the same warn and down vocabulary, then adds segments, a threshold and the breakdown. The status bar's .sb-meter stays the one-number version for the bottom rail.

Thresholds

Context 79%158k of 200k
  • System prompt8k
  • Tools24k
  • Thread94k
  • Files32k
  • Free42k

Near the limit. 2k until compaction.

Show code
<div class="ctx" data-state="near" role="group" aria-labelledby="ctx-near">
  <div class="ctx-head">
    <span class="ctx-label" id="ctx-near"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><line x1="10" x2="14" y1="2" y2="2"/><line x1="12" x2="15" y1="14" y2="11"/><circle cx="12" cy="14" r="8"/></svg>Context</span>
    <span class="ctx-value"><b>79%</b><small>158k of 200k</small></span>
  </div>
  <div class="ctx-track" role="meter" aria-label="Context window use" aria-valuemin="0" aria-valuemax="100" aria-valuenow="79" aria-valuetext="79 percent used, 42k tokens free">
    <span class="ctx-seg" data-k="system" style="--v:4"></span>
    <span class="ctx-seg" data-k="tools" style="--v:12"></span>
    <span class="ctx-seg" data-k="thread" style="--v:47"></span>
    <span class="ctx-seg" data-k="files" style="--v:16"></span>
    <span class="ctx-seg free" style="--v:21"></span>
    <span class="ctx-mark" style="--at:.8" aria-hidden="true"></span>
  </div>
  <ul class="ctx-list">
    <li><span class="ctx-key"><i class="ctx-dot" data-k="system"></i>System prompt</span><span class="ctx-num">8k</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="tools"></i>Tools</span><span class="ctx-num">24k</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="thread"></i>Thread</span><span class="ctx-num">94k</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="files"></i>Files</span><span class="ctx-num">32k</span></li>
    <li class="free"><span class="ctx-key"><i class="ctx-dot"></i>Free</span><span class="ctx-num">42k</span></li>
  </ul>
  <p class="ctx-note"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>Near the limit. 2k until compaction.</p>
</div>

data-state carries the threshold: normal, near and over. Near turns the value and the threshold mark amber; over turns them red and adds the error rule. The words in .ctx-note say what happens next, so the state is never colour alone.

Context 94%188k of 200k
  • System prompt8k
  • Tools24k
  • Thread104k
  • Files52k
  • Free12k

Over the limit. The next turn trims older tool output.

Show code
<div class="ctx" data-state="over" role="group" aria-labelledby="ctx-over">
  <div class="ctx-head">
    <span class="ctx-label" id="ctx-over"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><line x1="10" x2="14" y1="2" y2="2"/><line x1="12" x2="15" y1="14" y2="11"/><circle cx="12" cy="14" r="8"/></svg>Context</span>
    <span class="ctx-value"><b>94%</b><small>188k of 200k</small></span>
  </div>
  <div class="ctx-track" role="meter" aria-label="Context window use" aria-valuemin="0" aria-valuemax="100" aria-valuenow="94" aria-valuetext="94 percent used, 12k tokens free">
    <span class="ctx-seg" data-k="system" style="--v:4"></span>
    <span class="ctx-seg" data-k="tools" style="--v:12"></span>
    <span class="ctx-seg" data-k="thread" style="--v:52"></span>
    <span class="ctx-seg" data-k="files" style="--v:26"></span>
    <span class="ctx-seg free" style="--v:6"></span>
    <span class="ctx-mark" style="--at:.8" aria-hidden="true"></span>
  </div>
  <ul class="ctx-list">
    <li><span class="ctx-key"><i class="ctx-dot" data-k="system"></i>System prompt</span><span class="ctx-num">8k</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="tools"></i>Tools</span><span class="ctx-num">24k</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="thread"></i>Thread</span><span class="ctx-num">104k</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="files"></i>Files</span><span class="ctx-num">52k</span></li>
    <li class="free"><span class="ctx-key"><i class="ctx-dot"></i>Free</span><span class="ctx-num">12k</span></li>
  </ul>
  <p class="ctx-note"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>Over the limit. The next turn trims older tool output.</p>
</div>

Over is the error state of this component. Say what the agent will do about it. A silent trim is worse than a stated one.

Loading

Context Measuring
  • System prompt…
  • Tools…
  • Thread…
  • Files…
  • Free…

Counting tokens after the model switch.

Show code
<div class="ctx" data-state="loading" role="group" aria-labelledby="ctx-load" aria-busy="true">
  <div class="ctx-head">
    <span class="ctx-label" id="ctx-load"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><line x1="10" x2="14" y1="2" y2="2"/><line x1="12" x2="15" y1="14" y2="11"/><circle cx="12" cy="14" r="8"/></svg>Context</span>
    <span class="ctx-value"><b>Measuring</b></span>
  </div>
  <div class="ctx-track" aria-hidden="true">
    <span class="ctx-seg" data-k="system" style="--v:4"></span>
    <span class="ctx-seg" data-k="tools" style="--v:12"></span>
    <span class="ctx-seg" data-k="thread" style="--v:31"></span>
    <span class="ctx-seg" data-k="files" style="--v:16"></span>
    <span class="ctx-seg free" style="--v:37"></span>
    <span class="ctx-mark" style="--at:.8"></span>
  </div>
  <ul class="ctx-list">
    <li><span class="ctx-key"><i class="ctx-dot" data-k="system"></i>System prompt</span><span class="ctx-num">…</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="tools"></i>Tools</span><span class="ctx-num">…</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="thread"></i>Thread</span><span class="ctx-num">…</span></li>
    <li><span class="ctx-key"><i class="ctx-dot" data-k="files"></i>Files</span><span class="ctx-num">…</span></li>
    <li class="free"><span class="ctx-key"><i class="ctx-dot"></i>Free</span><span class="ctx-num">…</span></li>
  </ul>
  <p class="ctx-note"><svg class="i" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>Counting tokens after the model switch.</p>
</div>

Token counts arrive after the model and the tools are known. While they are being counted, the track holds its last shape at low opacity and the value says "Measuring". Give the group aria-busy="true" and leave the meter role off until there is a real number.

API

ClassOnWhat it does
.ctxdivThe panel. data-state: normal (default), near, over, loading.
.ctx-headdivThe label on the left, the value on the right.
.ctx-labelspanThe uppercase mono label with the timer icon.
.ctx-valuespanThe percentage and the raw count. b carries the threshold colour.
.ctx-trackdivThe segmented bar. Use role="meter" with aria-valuenow and a label.
.ctx-segspanOne segment. --v weights it against the others.
data-k.ctx-segsystem, tools, thread or files. Sets the series colour.
.ctx-seg.free.ctx-segThe free space, hatched. Keep it in the track.
.ctx-markspanThe compaction threshold. Set --at from 0 to 1.
.ctx-listulThe breakdown. One row per segment plus free.
.ctx-keyspanA dot and the part name.
.ctx-dotiThe colour key. Same data-k values as the segment.
.ctx-numspanThe token count, in mono.
.ctx-notepWhat happens at this level. Uses the threshold colour at near and over.
aria-selected="true".ctxFor a context meter inside a selected session or tab.
aria-disabled="true".ctxDims a readout that cannot be trusted.
Do
  • Keep the free segment visible. It is the headroom.
  • Name each segment and give its count in the list.
  • Show the threshold mark at the compaction point the agent actually uses.
Don't
  • One unlabelled bar with a percentage and nothing else.
  • A red bar with no sentence about what happens next.
  • Animating every segment while tokens stream. Update on a tick.

Accessibility

  • The track is a role="meter" with aria-valuemin, aria-valuemax, aria-valuenow and a label. aria-valuetext adds what is free, which the percentage alone does not say.
  • The breakdown is text and stays in reading order. A screen reader gets the same parts and counts as the eye.
  • Threshold state is written in the note. Near and over change colour and wording together.
  • While loading, the group is aria-busy="true" and the track has no meter role. Do not announce a number before it is real.
  • At 390px the head wraps and the list stays one column. No segment or count is hidden.
  • The loading pulse stops under prefers-reduced-motion; the "Measuring" value remains.