feat(desktop): display cache-read/write/fresh-input breakdown in agent-usage focused view

The plumbing already returned cacheReadTokens/cacheWriteTokens/freshInputTokens
at every scope of AgentUsageSeries, but the focused view rendered only the four
top-level stats and never surfaced them. Add an Input-breakdown subsection to the
totals card (Cache read / Cache write / Fresh input) gated on any known cache
value, and a compact per-model breakdown line. Fields follow the existing
unknown-not-zero semantics: absent subsets are omitted, a known-but-incomplete
value shows its lower bound with a Partial marker, and a scope with no cache data
renders no subsection at all.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This commit is contained in:
Duncan
2026-08-12 18:09:16 -04:00
co-authored by Will Pfleger
parent 3d723a7954
commit b01a381a46
5 changed files with 393 additions and 34 deletions
@@ -13,8 +13,10 @@ import {
formatCoverageDate,
formatEstimatedCostUsd,
formatLocalDate,
formatModelCacheBreakdown,
formatTokenCountCompact,
formatTokenCountExact,
hasKnownCacheData,
isPartialField,
isUnknownField,
MAX_RANGE_DAYS,
@@ -443,6 +445,85 @@ test("isPartialField and isUnknownField classify usage fields correctly", () =>
assert.equal(isUnknownField(usageField({ value: "0" })), false);
});
// ── formatModelCacheBreakdown / hasKnownCacheData ────────────────────────────
test("hasKnownCacheData is true iff any cache subset carries a known value", () => {
assert.equal(hasKnownCacheData(reportedUsage()), false, "all absent → false");
for (const field of [
"cacheReadTokens",
"cacheWriteTokens",
"freshInputTokens",
]) {
assert.equal(
hasKnownCacheData(reportedUsage({ [field]: usageField({ value: "0" }) })),
true,
`a known ${field} (even zero) → true`,
);
}
// A field that is incomplete but has no value is still unknown, not known.
assert.equal(
hasKnownCacheData(
reportedUsage({
cacheReadTokens: usageField({ value: null, incomplete: true }),
}),
),
false,
"incomplete with null value is unknown, not known",
);
});
test("formatModelCacheBreakdown omits absent subsets, never renders them as zero, and marks a known lower bound Partial", () => {
const build = (overrides) =>
modelUsage("m", null, { usage: reportedUsage(overrides) });
// No cache data at all → null, so the caller omits the line entirely.
assert.equal(formatModelCacheBreakdown(build({})), null);
// Each known subset appears compact-formatted; absent ones are omitted
// rather than shown as "0".
assert.equal(
formatModelCacheBreakdown(
build({
cacheReadTokens: usageField({ value: "1500" }),
cacheWriteTokens: usageField({ value: "300" }),
freshInputTokens: usageField({ value: "1200000" }),
}),
),
"Cache read 1.5K · Cache write 300 · Fresh 1.2M",
);
// Only cache-read known — the other two are unknown and omitted, not zero.
assert.equal(
formatModelCacheBreakdown(
build({ cacheReadTokens: usageField({ value: "800" }) }),
),
"Cache read 800",
);
// An incomplete known field appends a single trailing Partial marker.
assert.equal(
formatModelCacheBreakdown(
build({
cacheReadTokens: usageField({ value: "800", incomplete: true }),
cacheWriteTokens: usageField({ value: "200" }),
}),
),
"Cache read 800 · Cache write 200 · Partial",
);
// An incomplete field with NO value carries no known lower bound: it is
// omitted and does not trigger Partial on its own.
assert.equal(
formatModelCacheBreakdown(
build({
cacheReadTokens: usageField({ value: "800" }),
cacheWriteTokens: usageField({ value: null, incomplete: true }),
}),
),
"Cache read 800",
);
});
// ── sumKnownBucketTotals ──────────────────────────────────────────────────────
function bucket(overrides = {}) {
@@ -534,6 +534,57 @@ export function isUnknownField(field: UsageField | CostField): boolean {
return field.value === null;
}
/**
* Compact per-model input breakdown for the focused view: the cache-read,
* cache-write, and fresh-input subsets of input, each shown only when known
* (`value !== null`) and never as zero. Returns `null` when no subset is
* known at all, so the caller omits the line entirely rather than printing
* three unknowns. A trailing ` · Partial` marks that at least one shown field
* is a known-but-incomplete lower bound — matching the row's Partial badge and
* {@link deriveUsageIngressTrailing}'s text convention. Absent (`null`) fields
* are simply omitted, never marked Partial (they carry no known lower bound).
*/
export function formatModelCacheBreakdown(
model: AgentUsageModel,
): string | null {
const { cacheReadTokens, cacheWriteTokens, freshInputTokens } = model.usage;
const parts: string[] = [];
const push = (label: string, field: UsageField) => {
const parsed = parseTokenCount(field.value);
if (parsed !== null) {
parts.push(`${label} ${formatTokenCountCompact(parsed)}`);
}
};
push("Cache read", cacheReadTokens);
push("Cache write", cacheWriteTokens);
push("Fresh", freshInputTokens);
if (parts.length === 0) return null;
const partial =
isPartialField(cacheReadTokens) ||
isPartialField(cacheWriteTokens) ||
isPartialField(freshInputTokens);
return partial ? `${parts.join(" · ")} · Partial` : parts.join(" · ");
}
/**
* True when a usage scope has any known cache-read, cache-write, or
* fresh-input value — the gate for showing the focused view's input-breakdown
* subsection. When every cache subset is unknown (old-harness data that never
* reported cache tokens), the subsection is omitted rather than rendering a
* row of "—", which keeps absence honest without visual noise.
*/
export function hasKnownCacheData(usage: {
cacheReadTokens: UsageField;
cacheWriteTokens: UsageField;
freshInputTokens: UsageField;
}): boolean {
return (
!isUnknownField(usage.cacheReadTokens) ||
!isUnknownField(usage.cacheWriteTokens) ||
!isUnknownField(usage.freshInputTokens)
);
}
/**
* Truthful trailing summary for the profile Info-tab Usage ingress row
* (plan:328): the viewer's own agent's 7-day known total, `Partial` when
@@ -18,8 +18,10 @@ import {
describeRange,
formatCoverageDate,
formatEstimatedCostUsd,
formatModelCacheBreakdown,
formatTokenCountCompact,
formatTokenCountExact,
hasKnownCacheData,
isPartialField,
isUnknownField,
parseTokenCount,
@@ -218,6 +220,8 @@ function AgentUsageFocusedTotals({
// Display total for the Total tokens stat.
const displayTotal = deriveDisplayTotal(agent.usage);
const { cacheReadTokens, cacheWriteTokens, freshInputTokens } = agent.usage;
const showCacheBreakdown = hasKnownCacheData(agent.usage);
return (
<Card className="space-y-4 p-6" data-testid="agent-usage-focused-totals">
@@ -236,6 +240,34 @@ function AgentUsageFocusedTotals({
/>
</div>
{showCacheBreakdown ? (
<div
className="space-y-2 border-t border-border pt-4"
data-testid="agent-usage-focused-cache"
>
<h3 className="text-sm font-medium text-foreground">
Input breakdown
</h3>
<div className="grid grid-cols-2 gap-4 sm:grid-cols-3">
<TokenStat
field={cacheReadTokens}
label="Cache read"
testId="agent-usage-focused-cache-read-value"
/>
<TokenStat
field={cacheWriteTokens}
label="Cache write"
testId="agent-usage-focused-cache-write-value"
/>
<TokenStat
field={freshInputTokens}
label="Fresh input"
testId="agent-usage-focused-fresh-input-value"
/>
</div>
</div>
) : null}
{agent.buckets.length > 0 ? (
<div
className="space-y-2 border-t border-border pt-4"
@@ -253,35 +285,10 @@ function AgentUsageFocusedTotals({
>
<h3 className="text-sm font-medium text-foreground">By model</h3>
{models.map((model) => (
<div
className="flex items-center justify-between gap-3 text-sm"
<FocusedModelRow
key={`${model.harness ?? ""}:${model.model ?? "unknown"}`}
>
<span className="min-w-0 truncate text-muted-foreground">
{model.model ?? "Unknown model"}
{model.harness !== null ? (
<span
className="ml-1.5 text-xs text-muted-foreground/70"
data-testid="agent-usage-model-harness-label"
>
{model.harness}
</span>
) : null}
</span>
<span className="shrink-0 font-medium text-foreground">
{isUnknownField(model.usage.totalTokens)
? formatModelIndependentFields(model)
: formatTokenCountExact(
parseTokenCount(model.usage.totalTokens.value) ?? 0n,
)}
{isPartialField(model.usage.totalTokens) ||
isModelIoPartial(model) ? (
<Badge className="ml-2" variant="outline">
Partial
</Badge>
) : null}
</span>
</div>
model={model}
/>
))}
</div>
) : null}
@@ -318,9 +325,11 @@ function AgentUsageFocusedTotals({
function TokenStat({
field,
label,
testId,
}: {
field: { value: string | null; incomplete: boolean };
label: string;
testId?: string;
}) {
const parsed = parseTokenCount(field.value);
return (
@@ -328,6 +337,7 @@ function TokenStat({
display={parsed !== null ? formatTokenCountExact(parsed) : null}
isPartial={isPartialField(field)}
label={label}
testId={testId}
/>
);
}
@@ -400,6 +410,55 @@ function formatCoverageRange(coverage: AgentUsageSeries["coverage"]): string {
return `${formatCoverageDate(firstReportedAt)} ${formatCoverageDate(lastReportedAt)}`;
}
/**
* One "By model" row: the model/harness label with its display total and
* Partial badge, plus a muted cache/fresh-input breakdown line beneath it
* when any cache subset is known. The breakdown is computed once and omitted
* entirely when no subset was reported, so old-harness models read no
* differently than before.
*/
function FocusedModelRow({ model }: { model: AgentUsageModel }) {
const cacheBreakdown = formatModelCacheBreakdown(model);
return (
<div className="space-y-0.5">
<div className="flex items-center justify-between gap-3 text-sm">
<span className="min-w-0 truncate text-muted-foreground">
{model.model ?? "Unknown model"}
{model.harness !== null ? (
<span
className="ml-1.5 text-xs text-muted-foreground/70"
data-testid="agent-usage-model-harness-label"
>
{model.harness}
</span>
) : null}
</span>
<span className="shrink-0 font-medium text-foreground">
{isUnknownField(model.usage.totalTokens)
? formatModelIndependentFields(model)
: formatTokenCountExact(
parseTokenCount(model.usage.totalTokens.value) ?? 0n,
)}
{isPartialField(model.usage.totalTokens) ||
isModelIoPartial(model) ? (
<Badge className="ml-2" variant="outline">
Partial
</Badge>
) : null}
</span>
</div>
{cacheBreakdown !== null ? (
<p
className="text-xs text-muted-foreground/70"
data-testid="agent-usage-model-cache-breakdown"
>
{cacheBreakdown}
</p>
) : null}
</div>
);
}
/**
* Render known model I/O fields when the model total is unknown — never
* collapses to "No usage reported" when input or output is actually known
@@ -24,6 +24,9 @@ function reportedUsage(
outputTokens: string | null;
totalTokens: string | null;
estimatedCostUsd: number | null;
cacheReadTokens: string | null;
cacheWriteTokens: string | null;
freshInputTokens: string | null;
}> = {},
) {
return {
@@ -31,9 +34,9 @@ function reportedUsage(
inputTokens: usageField(overrides.inputTokens ?? null),
outputTokens: usageField(overrides.outputTokens ?? null),
totalTokens: usageField(overrides.totalTokens ?? null),
cacheReadTokens: usageField(null),
cacheWriteTokens: usageField(null),
freshInputTokens: usageField(null),
cacheReadTokens: usageField(overrides.cacheReadTokens ?? null),
cacheWriteTokens: usageField(overrides.cacheWriteTokens ?? null),
freshInputTokens: usageField(overrides.freshInputTokens ?? null),
};
}
@@ -296,6 +299,9 @@ test.describe("agent usage screenshots", () => {
inputTokens: "2100",
outputTokens: "700",
estimatedCostUsd: 0.35,
cacheReadTokens: "1400",
cacheWriteTokens: "300",
freshInputTokens: "400",
}),
},
{
@@ -308,6 +314,9 @@ test.describe("agent usage screenshots", () => {
inputTokens: "600",
outputTokens: "200",
estimatedCostUsd: 0.04,
cacheReadTokens: "350",
cacheWriteTokens: "50",
freshInputTokens: "200",
}),
},
],
@@ -316,6 +325,9 @@ test.describe("agent usage screenshots", () => {
inputTokens: "2700",
outputTokens: "900",
totalTokens: "3600",
cacheReadTokens: "1750",
cacheWriteTokens: "350",
freshInputTokens: "600",
}),
}),
],
+159 -3
View File
@@ -55,6 +55,9 @@ function reportedUsage(
outputTokens: string | null;
totalTokens: string | null;
estimatedCostUsd: number | null;
cacheReadTokens: string | null;
cacheWriteTokens: string | null;
freshInputTokens: string | null;
}> = {},
) {
return {
@@ -62,9 +65,9 @@ function reportedUsage(
inputTokens: usageField(overrides.inputTokens ?? null),
outputTokens: usageField(overrides.outputTokens ?? null),
totalTokens: usageField(overrides.totalTokens ?? null),
cacheReadTokens: usageField(null),
cacheWriteTokens: usageField(null),
freshInputTokens: usageField(null),
cacheReadTokens: usageField(overrides.cacheReadTokens ?? null),
cacheWriteTokens: usageField(overrides.cacheWriteTokens ?? null),
freshInputTokens: usageField(overrides.freshInputTokens ?? null),
};
}
@@ -994,6 +997,159 @@ test("focused view renders the unknown-intervals and invalid-reports caveats und
});
});
test("the focused view shows the cache/fresh-input breakdown with exact totals and a per-model line when cache data is present", async ({
page,
}) => {
await installMockBridge(page);
await openAgentsView(page);
const agentPubkey = await addGenericAgent(page, "general", "Cache Bot");
await seedSeries(
page,
mockUsageSeries({
agents: [
mockAgentUsage(agentPubkey, {
models: [
{
harness: "claude-code",
hasUnknownUsage: false,
model: "claude-opus",
reportCount: 1,
usage: reportedUsage({
totalTokens: "12000",
inputTokens: "10000",
outputTokens: "2000",
cacheReadTokens: "6000",
cacheWriteTokens: "1500",
freshInputTokens: "2500",
}),
},
],
usage: reportedUsage({
inputTokens: "10000",
outputTokens: "2000",
totalTokens: "12000",
cacheReadTokens: "6000",
cacheWriteTokens: "1500",
freshInputTokens: "2500",
}),
}),
],
}),
);
await page.getByTestId(`agent-usage-row-${agentPubkey}`).click();
await expect(page.getByTestId("agent-usage-focused-view")).toBeVisible();
// Input-breakdown subsection: three exact stats, none rendered as zero.
const cache = page.getByTestId("agent-usage-focused-cache");
await expect(cache).toBeVisible();
await expect(cache).toContainText("Cache read");
await expect(
page.getByTestId("agent-usage-focused-cache-read-value"),
).toHaveText("6,000");
await expect(
page.getByTestId("agent-usage-focused-cache-write-value"),
).toHaveText("1,500");
await expect(
page.getByTestId("agent-usage-focused-fresh-input-value"),
).toHaveText("2,500");
// No Partial badge when every shown cache field is a complete value.
await expect(cache.getByText("Partial", { exact: true })).toHaveCount(0);
// Per-model breakdown line carries the same subsets, compact-formatted.
const modelCache = page.getByTestId("agent-usage-model-cache-breakdown");
await expect(modelCache).toContainText("Cache read 6K");
await expect(modelCache).toContainText("Cache write 1.5K");
await expect(modelCache).toContainText("Fresh 2.5K");
});
test("the focused view marks a known-but-incomplete cache field Partial, omits absent subsets, and hides the breakdown entirely when no cache data exists", async ({
page,
}) => {
await installMockBridge(page);
await openAgentsView(page);
const agentPubkey = await addGenericAgent(
page,
"general",
"Partial Cache Bot",
);
await test.step("mixed cache completeness → Partial on the lower bound, absent fresh-input shows em-dash", async () => {
await seedSeries(
page,
mockUsageSeries({
agents: [
mockAgentUsage(agentPubkey, {
usage: {
estimatedCostUsd: costField(null),
inputTokens: usageField("10000"),
outputTokens: usageField("2000"),
totalTokens: usageField("12000"),
// Known but incomplete (Will's mixed-window shape) → Partial.
cacheReadTokens: usageField("6000", true),
// Absent → must render "—", never 0.
cacheWriteTokens: usageField(null),
// Fail-closed: fresh input cannot be derived → unknown → "—".
freshInputTokens: usageField(null, true),
},
}),
],
}),
);
await page.getByTestId(`agent-usage-row-${agentPubkey}`).click();
const cache = page.getByTestId("agent-usage-focused-cache");
await expect(cache).toBeVisible();
// Cache read: known lower bound → value plus Partial badge.
await expect(
page.getByTestId("agent-usage-focused-cache-read-value"),
).toHaveText("6,000");
await expect(cache.getByText("Partial", { exact: true })).toBeVisible();
// Cache write + fresh input are unknown → em-dash, never zero.
await expect(
page.getByTestId("agent-usage-focused-cache-write-value"),
).toHaveText("—");
await expect(
page.getByTestId("agent-usage-focused-fresh-input-value"),
).toHaveText("—");
});
await test.step("no cache data at all → the breakdown subsection is absent", async () => {
await seedSeries(
page,
mockUsageSeries({
agents: [
mockAgentUsage(agentPubkey, {
// Old-harness shape: i/o known, every cache subset absent.
usage: reportedUsage({
inputTokens: "10000",
outputTokens: "2000",
totalTokens: "12000",
}),
}),
],
}),
);
await page.evaluate(() =>
(
window as Window & {
__BUZZ_E2E_QUERY_CLIENT__?: {
invalidateQueries: () => Promise<void>;
};
}
).__BUZZ_E2E_QUERY_CLIENT__?.invalidateQueries(),
);
await page.getByTestId(`agent-usage-row-${agentPubkey}`).click();
await expect(page.getByTestId("agent-usage-focused-totals")).toBeVisible();
await expect(page.getByTestId("agent-usage-focused-cache")).toHaveCount(0);
await expect(
page.getByTestId("agent-usage-model-cache-breakdown"),
).toHaveCount(0);
});
});
test("overview and focused view distinguish an invalid-only window from ordinary empty windows", async ({
page,
}) => {