fix(FN-7786): show partial Command Center costs

Fusion-Task-Id: FN-7786
This commit is contained in:
gsxdsm
2026-07-10 23:24:00 -07:00
parent 122e404494
commit fbea66d0f2
9 changed files with 72 additions and 20 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Show partial estimated costs across all Command Center cost views when some model pricing is unavailable.
category: fix
dev: Priced subtotals use a trailing plus sign; entirely unpriced usage remains unavailable.

View File

@@ -715,6 +715,18 @@ describe("CommandCenter shell", () => {
expect(liveMetricValue("command-center-live-tokens")).toBe("1,234,567,890");
});
it("shows the priced subtotal in Overview when some usage has unknown pricing", async () => {
mockOverviewApi({
tokens: {
...tokenFixture(1_500),
cost: { usd: 911.39004125, unavailable: true, stale: false },
},
});
render(<CommandCenter />);
expect(await screen.findByTestId("command-center-stat-tokens")).toHaveTextContent("$911.39+");
});
it("live-polls token totals for the Overview card, live strip, and model charts", async () => {
vi.useFakeTimers();
let resolvePoll: ((value: ReturnType<typeof tokenFixture>) => void) | null = null;

View File

@@ -54,7 +54,7 @@ type OrgChartDragState = {
};
function costSortValue(cost: CostResult): number {
return cost.unavailable || cost.usd === null ? -1 : cost.usd;
return cost.usd ?? -1;
}
function agentLabel(agent: TeamAgentSummary, unknownLabel: string): string {

View File

@@ -38,7 +38,7 @@ The Tokens detail area is the full-fidelity by-model source of truth: every grou
*/
function costSortValue(cost: CostResult): number {
return cost.unavailable || cost.usd === null ? -1 : cost.usd;
return cost.usd ?? -1;
}
function modelGroupIdentity(group: TokenGroupSummary): string {
@@ -287,16 +287,12 @@ export function TokensArea({ range, projectId }: { range: DateRange; projectId?:
<td>{formatCount(g.cachedTokens)}</td>
<td>{formatCount(g.totalTokens)}</td>
<td>
{g.cost.unavailable || g.cost.usd === null ? (
<span
className="cc-unavailable"
title={t("commandCenter.tokens.costUnavailable", "No pricing for this model")}
>
—
</span>
) : (
formatCost(g.cost.usd, g.cost.unavailable)
)}
<span
className={g.cost.usd === null ? "cc-unavailable" : undefined}
title={g.cost.unavailable ? t("commandCenter.tokens.costUnavailable", "No pricing for some or all usage") : undefined}
>
{formatCost(g.cost.usd, g.cost.unavailable)}
</span>
</td>
</tr>
))}

View File

@@ -14,7 +14,7 @@ import { WorkflowIcon } from "../../WorkflowIcon";
type SortKey = "workflow" | "tokens" | "cost" | "filesChanged" | "tasksCompleted" | "tasksInProgress" | "tasksInReview";
function costSortValue(cost: CostResult): number {
return cost.unavailable || cost.usd === null ? -1 : cost.usd;
return cost.usd ?? -1;
}
function workflowLabel(workflow: WorkflowSummary, unknownLabel: string): string {

View File

@@ -180,6 +180,24 @@ afterEach(() => {
});
describe("TokensArea provider model icons", () => {
it("renders a priced subtotal when the aggregate also contains unpriced usage", async () => {
apiMock.mockResolvedValue({
...tokenFixture(),
cost: { usd: 11.25, unavailable: true, stale: false },
groups: [
{
...tokenFixture().groups[0],
cost: { usd: 3.5, unavailable: true, stale: false },
},
],
});
render(<TokensArea range={range7d} />);
expect(await screen.findByTestId("cc-tokens-cost")).toHaveTextContent("$11.25+");
expect(screen.getByTestId("cc-tokens-row-claude-sonnet-4-5")).toHaveTextContent("$3.50+");
});
it("renders current OpenAI Codex priced costs as dollars instead of the unavailable sentinel", async () => {
const usage = { inputTokens: 1_000_000, outputTokens: 200_000, cachedTokens: 500_000, cacheWriteTokens: 100_000 };
const cost = costFor(usage, { provider: "openai-codex", model: "gpt-5.5" });

View File

@@ -112,8 +112,7 @@ describe("WorkflowArea", () => {
await screen.findByTestId("cc-area-workflows");
expect(mocks.api).toHaveBeenCalledWith("/command-center/workflows?from=2026-06-08", undefined);
expect(screen.getByTestId("cc-workflows-total-tokens").textContent).toContain("1,650");
expect(screen.getByTestId("cc-workflows-total-cost").textContent).toContain("—");
expect(screen.getByTestId("cc-workflows-total-cost").textContent).not.toContain("$0");
expect(screen.getByTestId("cc-workflows-total-cost").textContent).toContain("$4.25+");
expect(screen.getByTestId("cc-workflows-tokens-chart").textContent).toContain("Coding");
const table = screen.getByTestId("cc-workflows-table");

View File

@@ -59,7 +59,7 @@ import { ActivityArea } from "../ActivityArea";
import { EcosystemArea } from "../EcosystemArea";
import { useAnalyticsArea } from "../useAnalyticsArea";
import { ConfirmDialogProvider } from "../../../../hooks/useConfirm";
import { rangeQuery } from "../areaShared";
import { formatCost, rangeQuery } from "../areaShared";
import { defaultPresets, rangeFromPreset } from "../../DateRangePicker";
import {
activityFixture,
@@ -80,6 +80,15 @@ import {
tokenFixture,
} from "./areas.test-harness";
describe("Command Center cost formatting", () => {
it("shows priced subtotals when only part of the usage has known pricing", () => {
expect(formatCost(911.39004125, true)).toBe("$911.39+");
expect(formatCost(12.5, false)).toBe("$12.50");
expect(formatCost(0, false)).toBe("$0.00");
expect(formatCost(null, true)).toBe("—");
});
});
beforeEach(() => {
apiMock.mockReset();
backfillGithubSourceIssueClosedAtMock.mockReset();
@@ -1394,11 +1403,16 @@ describe("TeamArea", () => {
});
it("renders a large comma-grouped total unchanged in the team total tokens stat", async () => {
apiMock.mockResolvedValue(populatedTeamFixture(1_234_567_890));
const fixture = populatedTeamFixture(1_234_567_890);
apiMock.mockResolvedValue({
...fixture,
totals: { ...fixture.totals, cost: { usd: 4.25, unavailable: true, stale: false } },
});
render(<TeamArea range={range7d} />);
await screen.findByTestId("cc-area-team");
expect(screen.getByTestId("cc-team-total-tokens").textContent).toContain("1,234,567,890");
expect(screen.getByTestId("cc-team-total-cost")).toHaveTextContent("$4.25+");
});
it("keeps the team pie safe for single-item and non-finite data", async () => {

View File

@@ -45,12 +45,18 @@ export function formatDurationMs(ms: number | null): string {
return `${seconds}s`;
}
/** Format a USD cost result, returning the unavailable sentinel "—" when unknown. */
/**
* Format a USD cost result for every Command Center cost surface.
*
* FNXC:CommandCenterCost 2026-07-10-23:20:
* Cost aggregation deliberately preserves the priced subtotal when some usage has unknown pricing. Overview, Tokens, Team, and Workflows must display that subtotal with a trailing `+`; show `—` only when no usage can be priced, and keep an exact priced zero distinct from unavailable data.
*/
export function formatCost(usd: number | null, unavailable: boolean): string {
if (unavailable || usd === null || !Number.isFinite(usd)) {
if (usd === null || !Number.isFinite(usd)) {
return "—";
}
return `$${usd.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
const formatted = `$${usd.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
return unavailable ? `${formatted}+` : formatted;
}
/** True when the picker's custom range is invalid (from after to). */