fix(sessions): reuse canonical token count formatting

This commit is contained in:
Peter Steinberger
2026-08-01 09:38:51 -07:00
parent 1296ab3b41
commit 52b24e781a
2 changed files with 93 additions and 5 deletions

View File

@@ -56,6 +56,95 @@ describe("sessionsCommand", () => {
);
});
it.each([
{ totalTokens: 0, contextTokens: 420, expected: "0/420 (0%)" },
{ totalTokens: 1, contextTokens: 999, expected: "1/999 (0%)" },
{ totalTokens: 420, contextTokens: 999, expected: "420/999 (42%)" },
{ totalTokens: 999, contextTokens: 1_000, expected: "999/1.0k (100%)" },
{ totalTokens: 1_000, contextTokens: 200_000, expected: "1.0k/200k (1%)" },
{ totalTokens: 999_499, contextTokens: 1_000_000, expected: "999k/1.0m (100%)" },
{ totalTokens: 999_500, contextTokens: 1_000_000, expected: "1.0m/1.0m (100%)" },
{ totalTokens: 1_000_000, contextTokens: 2_500_000, expected: "1.0m/2.5m (40%)" },
])(
"formats actual session-table token boundaries ($totalTokens/$contextTokens)",
async ({ totalTokens, contextTokens, expected }) => {
const store = await writeStore({
"agent:main:boundary": {
sessionId: "boundary-session",
updatedAt: Date.now() - 60_000,
totalTokens,
totalTokensFresh: true,
contextTokens,
model: "test:opus",
},
});
const { runtime, logs } = makeRuntime();
await sessionsCommand({ store }, runtime);
cleanupStore(store);
const row = logs.find((line) => line.includes("id:boundary-session")) ?? "";
expect(row).toContain(expected);
},
);
it("formats unknown totals with the actual session context-token boundary", async () => {
const store = await writeStore({
"agent:main:unknown-boundary": {
sessionId: "unknown-boundary-session",
updatedAt: Date.now() - 60_000,
contextTokens: 999,
model: "test:opus",
},
});
const { runtime, logs } = makeRuntime();
await sessionsCommand({ store }, runtime);
cleanupStore(store);
const row = logs.find((line) => line.includes("id:unknown-boundary-session")) ?? "";
expect(row).toContain("unknown/999 (?%)");
});
it("keeps exact numeric token counts unchanged in JSON output", async () => {
const store = await writeStore({
"agent:main:small": {
sessionId: "small-boundary-session",
updatedAt: Date.now() - 60_000,
totalTokens: 420,
totalTokensFresh: true,
contextTokens: 999,
model: "test:opus",
},
"agent:main:large": {
sessionId: "large-boundary-session",
updatedAt: Date.now() - 120_000,
totalTokens: 1_000_000,
totalTokensFresh: true,
contextTokens: 2_500_000,
model: "test:opus",
},
});
const payload = await runSessionsJson<{
sessions?: Array<{ key: string; totalTokens: number; contextTokens: number }>;
}>(sessionsCommand, store);
expect(payload.sessions).toEqual(
expect.arrayContaining([
expect.objectContaining({
key: "agent:main:small",
totalTokens: 420,
contextTokens: 999,
}),
expect.objectContaining({
key: "agent:main:large",
totalTokens: 1_000_000,
contextTokens: 2_500_000,
}),
]),
);
});
it("renders the agent runtime in the tabular view", async () => {
setMockSessionsConfig(() => ({
agents: {

View File

@@ -33,6 +33,7 @@ import {
deliveryContextFromSession,
sessionDeliveryOrigin,
} from "../utils/delivery-context.shared.js";
import { formatTokenCount } from "../utils/token-format.js";
import { resolveSessionStoreTargetsOrExit } from "./session-store-targets.js";
import {
resolveSessionDisplayModelRef,
@@ -72,8 +73,6 @@ const DEFAULT_SESSIONS_LIMIT = 100;
const TOP_N_SELECTION_LIMIT = 200;
const contextLookupRuntimeLoader = createLazyImportLoader(() => import("../agents/context.js"));
const formatKTokens = (value: number) => `${(value / 1000).toFixed(value >= 10_000 ? 0 : 1)}k`;
/**
* Inline ACP model overlay — catalog #20.
*
@@ -176,12 +175,12 @@ const formatTokensCell = (
rich: boolean,
) => {
if (total === undefined) {
const ctxLabel = contextTokens ? formatKTokens(contextTokens) : "?";
const ctxLabel = contextTokens ? formatTokenCount(contextTokens) : "?";
const label = `unknown/${ctxLabel} (?%)`;
return rich ? theme.muted(label.padEnd(TOKENS_PAD)) : label.padEnd(TOKENS_PAD);
}
const totalLabel = formatKTokens(total);
const ctxLabel = contextTokens ? formatKTokens(contextTokens) : "?";
const totalLabel = formatTokenCount(total);
const ctxLabel = contextTokens ? formatTokenCount(contextTokens) : "?";
const pct = contextTokens ? Math.min(999, Math.round((total / contextTokens) * 100)) : null;
const label = `${totalLabel}/${ctxLabel} (${pct ?? "?"}%)`;
const padded = label.padEnd(TOKENS_PAD);