From 84cbaf1832dd1024a1d102499a359a974583251a Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 13 Jun 2026 18:15:39 +0530 Subject: [PATCH] fix(usage): preserve partial footer counts --- .../agent-runner.misc.runreplyagent.test.ts | 22 +++++++++++++++++++ src/auto-reply/usage-bar/contract.ts | 7 ++++++ src/auto-reply/usage-bar/default-template.ts | 8 +++---- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/auto-reply/reply/agent-runner.misc.runreplyagent.test.ts b/src/auto-reply/reply/agent-runner.misc.runreplyagent.test.ts index 452f5d413438..7e01e863c2d8 100644 --- a/src/auto-reply/reply/agent-runner.misc.runreplyagent.test.ts +++ b/src/auto-reply/reply/agent-runner.misc.runreplyagent.test.ts @@ -2707,6 +2707,28 @@ describe("runReplyAgent response usage footer", () => { expect(text).not.toContain("ยท session "); }); + it("keeps partial token counts in the built-in full footer", async () => { + runEmbeddedAgentMock.mockResolvedValueOnce({ + payloads: [{ text: "ok" }], + meta: { + agentMeta: { + provider: "anthropic", + model: "claude", + usage: { output: 125 }, + }, + }, + }); + + const res = await createRun({ + responseUsage: "full", + sessionKey: "agent:main:whatsapp:dm:+1000", + }); + const payload = Array.isArray(res) ? res[0] : res; + const text = payload?.text ?? ""; + expect(text).toContain("โ†•๏ธ ?/125"); + expect(text).not.toContain("Usage:"); + }); + it("shows configured costs for aws-sdk providers when responseUsage=full", async () => { runEmbeddedAgentMock.mockResolvedValueOnce({ payloads: [{ text: "ok" }], diff --git a/src/auto-reply/usage-bar/contract.ts b/src/auto-reply/usage-bar/contract.ts index a391fa8092a8..2b3b4ebdf91e 100644 --- a/src/auto-reply/usage-bar/contract.ts +++ b/src/auto-reply/usage-bar/contract.ts @@ -11,6 +11,12 @@ export function buildUsageContract( const cacheRead = usage.cacheRead; const cacheWrite = usage.cacheWrite; const total = usage.total; + const hasTokens = + input !== undefined || + output !== undefined || + cacheRead !== undefined || + cacheWrite !== undefined || + total !== undefined; const promptTotal = (cacheRead ?? 0) + (cacheWrite ?? 0) + (input ?? 0); const cacheHitPct = @@ -70,6 +76,7 @@ export function buildUsageContract( cache_write_tokens: cacheWrite, total_tokens: total, cache_hit_pct: cacheHitPct, + has_tokens: hasTokens, last: last ? { input_tokens: last.input, diff --git a/src/auto-reply/usage-bar/default-template.ts b/src/auto-reply/usage-bar/default-template.ts index 4ffd8c8018d2..f18f43187f5e 100644 --- a/src/auto-reply/usage-bar/default-template.ts +++ b/src/auto-reply/usage-bar/default-template.ts @@ -35,8 +35,8 @@ export const DEFAULT_USAGE_BAR_TEMPLATE: UsageBarTemplate = { text: " | ๐Ÿ“š [{context.pct_used|meter:5:braille}]{context.max_tokens|num}", }, { - when: "usage.input_tokens", - text: " โ†•๏ธ {usage.input_tokens|num}/{usage.output_tokens|num}", + when: "usage.has_tokens", + text: " โ†•๏ธ {usage.input_tokens|num|?}/{usage.output_tokens|num|?}", }, { when: "usage.cache_hit_pct", text: " ๐Ÿ—„ {usage.cache_hit_pct|pct}" }, { when: "cost.turn_usd", text: " ๐Ÿ’ฐ{cost.turn_usd|fixed:4}" }, @@ -54,8 +54,8 @@ export const DEFAULT_USAGE_BAR_TEMPLATE: UsageBarTemplate = { text: " | ๐Ÿ“š [{context.pct_used|meter:5:braille}]{context.max_tokens|num}", }, { - when: "usage.input_tokens", - text: " โ†•๏ธ {usage.input_tokens|num}/{usage.output_tokens|num}", + when: "usage.has_tokens", + text: " โ†•๏ธ {usage.input_tokens|num|?}/{usage.output_tokens|num|?}", }, { when: "usage.cache_hit_pct", text: " ๐Ÿ—„ {usage.cache_hit_pct|pct}" }, { when: "cost.turn_usd", text: " ๐Ÿ’ฐ{cost.turn_usd|fixed:4}" },