feat(tui): split each token-meter band into new and cache-read work - #1068
Merged
Conversation
A turn's prompt side is mostly context the provider already holds, so a column that reads as 90k of work can be 80k of re-sent conversation. The meter had no way to say which: cached input was deliberately excluded from the total to avoid double-counting, and then thrown away. Carry it instead. `TokenSample` gains a `cached` field — a subset of `tokens`, additive on the wire — fed by the live usage path and by the boot-time transcript scan, so a restarted client draws the same columns. Each model's band then splits in two: its new work at the base and the cache-served remainder directly above it, in the same hue pushed toward black. Bar height stays billed volume and the legend's rates are unchanged; only the shading is new. Hover names the exact cached figure per model. The recessed shade has to be a color rather than DIM: a single cell can hold a model's own new/cached boundary, where the two parts are the glyph's foreground and its background, and an attribute would dim both or neither. Also widen the legend's inter-column margin from one column to three. A rate sits against its cell's right edge and the next cell opens with a dot, so one space of separation read as one run of text rather than as columns.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A turn's prompt side is mostly context the provider already holds, so a meter column that reads as 90k of work can be 80k of re-sent conversation. The meter had no way to say which — cached input was deliberately excluded from the total to avoid double-counting, and then discarded.
Now it rides along.
TokenSamplegains acachedfield: a subset oftokens(sotokens - cachedis the new work),#[serde(default)]so records written before it existed load as 0. It's populated by both the live usage path and the boot-time transcript scan, so a restarted client draws the same columns it had before.Each model's band then splits in two — its new work at the base, the cache-served remainder directly above it, in the same hue pushed toward black (
blend_color(Black, base, 0.45)).opus 90.0k (80.0k cached)), which is the only place the shaded part gets a number.The recessed shade has to be a color, not
Modifier::DIM: one terminal cell can hold a model's own new/cached boundary, and there the two parts are the glyph's foreground and its background — an attribute would dim both or neither.ColumnCell/column_cells/stacked_eighthsare now generic over the band key so the same machinery draws a same-model boundary exactly like a cross-model one.Also: more margin between legend columns (1 → 3). A rate sits against its cell's right edge and the next cell opens with a dot, so a single space of separation read as one run of text rather than as columns. The gap is a named constant folded into the cell width, so the rate anchor, the column count, and the inter-column spacing stay consistent.
Spec
specs/0167-fleet-token-meter.mdgains "Cached input is a subset, and it shades a band rather than growing it" — the subset contract, why height stays billed volume, why same hue and why a color rather than an attribute, and what a harness reporting no cache figure looks like. The legend-grid section picks up the per-cell margin, and "The stack must survive the cell grid" is reworded from series boundary to band boundary to cover the same-model case.Tests
New unit coverage for: the split not changing column height, each model keeping its two parts adjacent, a zero part producing no band, over-reported cached being clamped, seeded history keeping its cached share, the cached color being darker on every channel while holding hue, and a same-model boundary encoding as fg-over-bg. Legend tests assert against the gap constant rather than a literal.
Binaries
Touches
crates/cli,crates/daemon,crates/protocol→ the user-visible change is inconstruct.