import { Box, Paper, Text } from "@mantine/core"; import type { Task } from "../types"; import { formatCompactTokens, formatEstimatedCost, formatFullTokens, taskReportedWorkView, usageView, } from "../presentation"; import { ShimmerText } from "./ShimmerText"; export function UsagePanel({ task }: { task: Task }) { const usage = usageView(task); const reportedWork = taskReportedWorkView(task); const ready = usage.kind === "ready" ? usage : null; const models = Object.keys(ready?.usage.models ?? {}).join(", "); const estimatedCost = ready?.usage.estimatedCostUsd; const hasEstimatedCost = typeof estimatedCost === "number" && Number.isFinite(estimatedCost); const stateValue = usage.kind === "pending" ? "Pending" : usage.kind === "calculating" ? "Calculating" : "n/a"; const accessibleState = usage.kind === "unavailable" ? "unavailable" : stateValue.toLowerCase(); const values: Array<{ accessibleValue?: string; animated?: boolean; label: string; title?: string; value: string; }> = [ { accessibleValue: ready ? `${formatFullTokens(ready.usage.totalTokens)} tokens` : usage.label, animated: usage.kind === "pending" || usage.kind === "calculating" || ready?.knownSoFar, label: "Tokens", title: ready ? `${formatFullTokens(ready.usage.totalTokens)} tokens` : usage.label, value: ready ? formatCompactTokens(ready.usage.totalTokens) : stateValue, }, { accessibleValue: ready ? ready.usage.estimatedCostUsd == null ? "Estimated cost unavailable" : `Estimated cost ${formatEstimatedCost(ready.usage.estimatedCostUsd)}` : `Estimated cost ${accessibleState}${ usage.kind === "unavailable" ? `: ${usage.label}` : "" }`, animated: usage.kind === "pending" || usage.kind === "calculating" || (ready?.knownSoFar && hasEstimatedCost), label: "Estimated cost", title: ready?.usage.estimatedCostUsd == null ? "Estimated cost unavailable" : `Unrounded estimate: $${ready.usage.estimatedCostUsd}`, value: ready ? ready.usage.estimatedCostUsd == null ? "n/a" : formatEstimatedCost(ready.usage.estimatedCostUsd) : stateValue, }, { accessibleValue: reportedWork.accessibleLabel, label: "Duration", title: reportedWork.title, value: reportedWork.value, }, { accessibleValue: models || "Models unavailable", label: "Models", title: models || "Models unavailable", value: models || "n/a", }, ]; return ( {values.map(({ accessibleValue, animated, label, title, value }) => ( {label} {animated ? {value} : value} ))} {usage.kind === "unavailable" && usage.label !== "Token usage unavailable" && ( {usage.label} )} ); }