Usage popover: 'Uncached input' when a cache split exists

Input rows then read as components: uncached + cache reads + cache
writes = Total input; plain 'Input' stays for cacheless backends.
This commit is contained in:
Rohit C Prasad
2026-07-28 11:48:21 -07:00
parent d1524b3376
commit 27311cd97f
2 changed files with 16 additions and 9 deletions
+2 -1
View File
@@ -32,7 +32,8 @@ test("usage chip appears after a turn and opens the breakdown popover", async ({
await expect(pop).toContainText("9.8k of 200k · 5%"); await expect(pop).toContainText("9.8k of 200k · 5%");
await expect(pop).toContainText("Session totals"); await expect(pop).toContainText("Session totals");
await expect(pop).toContainText("Claude Opus 4.8 · Anthropic"); await expect(pop).toContainText("Claude Opus 4.8 · Anthropic");
await expect(pop).toContainText("Input"); // Cache split present → the input rows read as components of Total input.
await expect(pop).toContainText("Uncached input");
await expect(pop).toContainText("Cache reads"); await expect(pop).toContainText("Cache reads");
await expect(pop).toContainText("Cache writes"); await expect(pop).toContainText("Cache writes");
// Total input = fresh 1k + cache_read 8k + cache_write 800 (cumulative billed input). // Total input = fresh 1k + cache_read 8k + cache_write 800 (cumulative billed input).
+14 -8
View File
@@ -658,15 +658,21 @@ function UsageChip({
<div className="text-[12px] text-ink font-medium truncate" title={id}> <div className="text-[12px] text-ink font-medium truncate" title={id}>
{labelFor(id)} {labelFor(id)}
</div> </div>
{/* Every row is a session sum. With a cache split, the input rows are
the three BILLING CLASSES of input (each priced differently) and
read as components: uncached + cache reads + cache writes = total.
Without one (Ollama, compat vendors), plain "Input" says it all. */}
<div className="mt-0.5 flex flex-col gap-0.5"> <div className="mt-0.5 flex flex-col gap-0.5">
{stat("Input", t.input)} {t.cache_read + t.cache_write > 0 ? (
{t.cache_read > 0 && stat("Cache reads", t.cache_read)} <>
{t.cache_write > 0 && stat("Cache writes", t.cache_write)} {stat("Uncached input", t.input)}
{/* Cumulative billed input volume = fresh + cache reads + cache {stat("Cache reads", t.cache_read)}
writes (each class bills at its own rate). Shown only when a {stat("Cache writes", t.cache_write)}
cache split exists — otherwise it would duplicate Input. */} {stat("Total input", t.input + t.cache_read + t.cache_write)}
{t.cache_read + t.cache_write > 0 && </>
stat("Total input", t.input + t.cache_read + t.cache_write)} ) : (
stat("Input", t.input)
)}
{stat("Output", t.output)} {stat("Output", t.output)}
</div> </div>
</div> </div>