The chat's cost panel — a mockup
Chat info ▸ Cost, redrawn to the owner's layout: aligned columns,
no tokens, the admin console's group colours, and no row for a step that cost
nothing.
Status: BUILT 2026-08-21 (v941) — live on
main, not yet
on the box. Shipped with all four agreed suggestions, plus two decisions the owner made on
reading this page:
- The badge names the vendor, not the arithmetic — 「DeepSeek Peak Now」, and only
at peak. 「×2」 sat beside a total earned over days and read as 「this figure was doubled」,
which it never meant; and 「off-peak」 was a pill that only ever reported normal.
- The panel reads the LEDGER, by room. That fixes a real double-count: a full fork
inherits its parent's cost, so the same money showed in two chats and the sum of every panel
exceeded the real bill — while the console, counting by room, disagreed with both. What the
ledger cannot account for rides as one grey earlier row instead of vanishing.
The specimens below are the design record and still run on hand-written numbers.
1 · Now vs proposed
Today live
CostPEAK ×2$0.080
DeepSeek V4 Pro
63 calls · 1.24M · $0.041
DeepSeek V4 Flash
58 calls · 412k · $0.012
speech
21 calls · $0.042 · 53%
staging
21 calls · $0.019 · 24%
tool call
9 calls · $0.011 · 14%
memory
4 calls · $0.006 · 7%
Every figure floats: the name column
is content-width, so nothing lines up. Tokens sit between the reader and the money. One
coral bar for every step — the colour carries no information.
Proposed mockup
CostPEAK ×2
121 calls$0.080
V4 Pro
63 calls$0.041
V4 Flash
58 calls$0.012
speech
21 calls$0.042
FP
21 calls$0.019
tools
9 calls$0.011
persona.mem
4 calls$0.006
One grid, four rails: colour ·
name · calls · money. Models above the rule, steps below it — the same money cut two
ways. Colours are the console's groups, so a chat and the dashboard agree on sight.
2 · The other shapes it has to hold
A game room — every group lit
Costoff-peak
318 calls$0.412
V4 Pro
96 calls$0.291
V4 Flash
211 calls$0.098
Haiku 4.5
11 calls$0.023
speech78 calls$0.204
FP78 calls$0.071
games96 calls$0.058
tools44 calls$0.042
room14 calls$0.031
persona.mem8 calls$0.006
A fresh chat — one model, two steps
Costoff-peak
2 calls$0.0031
speech1 call$0.0026
FP1 call$0.0005
One model → the model rows and
the rule both vanish (today's rule, kept: 「one model, one row」says nothing). Under a
dollar the figures widen to four decimals so a cheap step is never 「$0.000」.
3 · What I'd change on top of your layout
Five suggestions — take any, none, or all.
- Keep a bar, but make it the share of the ROW, not a second colour. Your sketch
has「(bar)」 leading each step. I've drawn the swatch instead, because with the columns
aligned the $ column already ranks the rows — a 46px bar beside an aligned number is
redundant ink. If you want the proportion back, the cheapest honest version is a
hairline under the row, full-width at the top step. I'd try it without first.
- Group, not leaf — with the leaf on tap.「tools」is
tool.act +
tool.prop + tool.promised;「games」is five leaves. The panel is
~300px wide, so the group is the right grain — but the leaf split is already in the data,
and a tap on a row could expand it inline, exactly as the console's By-function table does.
- Name the rows as the console names them. Your sketch says「FP」and
「persona.mem」— machine-ish, and that is a virtue here: they are the SAME words the
dashboard uses, so a person who learns one screen can read the other. My one exception:
speech stays speech, not「persona msg」.
- Drop the tier badge to a footnote when off-peak. 「PEAK ×2」 earns its place —
it says the number in front of it is doubled. 「off-peak」 says nothing actionable and
wears the same weight. I'd hide it off-peak entirely (it is already hidden for non-tiered
vendors), and keep the peak badge loud.
- Cache stays, but under its own kicker. The cache bar lives directly beneath
this block and answers a different question (「what is in the prefix」, not「where did the
money go」). With the cost block now tabular, the two read as one confusing table unless
the cache keeps its own CURRENT CACHE kicker — it does today; I would not merge them.
4 · The decision, as taken
The ledger will not make these numbers more accurate — they are
already exact. Since v935 every provider call a room makes goes through one seam
(
Room._tally), which is what feeds this panel AND writes the ledger row, so the
panel is per-call exact today and already speaks the
group.leaf vocabulary.
What the ledger would add is a
different source, and it comes with a real trade:
- For it: one store shared with the console (they can never drift); it survives
the planned §9 state compaction; and it can be scoped by date (「this chat, last 7 days」).
- Against it: a network round trip per panel open, where today's numbers are
already in the room payload and update mid-turn; and it would change what a
full fork shows — a fork deliberately inherits its parent's spend today
(
run_room.py: 「the whole conversation」), while the ledger would show only
the calls the new room itself made, starting at $0.
I recommended keeping the in-memory tally; the owner chose the ledger — correctness and a single source first — and that is what shipped. The fork question was decided deliberately rather than as a side effect: a fork now shows what IT spent, with the inherited amount named as
earlier rather than passing as its own.
One real gap the ledger does close, if you want it. A room whose
state.json predates the per-kind split shows an empty step list — the panel has
nothing to show because nothing was recorded then. The ledger has rows for every call since
ledger_start, so those old rooms would gain a partial (honest, dated) split.
Rare, and it fixes itself as rooms age out.