diff --git a/src/app/(dashboard)/dashboard/usage/components/UsageTable.js b/src/app/(dashboard)/dashboard/usage/components/UsageTable.js index 9da3c3e6..f249d41e 100644 --- a/src/app/(dashboard)/dashboard/usage/components/UsageTable.js +++ b/src/app/(dashboard)/dashboard/usage/components/UsageTable.js @@ -105,6 +105,7 @@ export default function UsageTable({ renderDetailCells, renderSummaryCells, emptyMessage, + providerLabel, }) { const [expanded, setExpanded] = useState(new Set()); @@ -198,8 +199,13 @@ export default function UsageTable({ chevron_right - 0 ? "text-primary" : ""}`}> - {group.groupKey} + 0 ? "text-primary" : ""}`} + title={group.groupKey} + > + {tableType === "provider" && providerLabel + ? providerLabel(group.groupKey) + : group.groupKey} diff --git a/src/shared/components/UsageStats.js b/src/shared/components/UsageStats.js index ff5286a3..b5b75062 100644 --- a/src/shared/components/UsageStats.js +++ b/src/shared/components/UsageStats.js @@ -2,7 +2,7 @@ import { useState, useEffect, useMemo, useCallback, useRef } from "react"; import { useSearchParams, useRouter } from "next/navigation"; -import { FREE_PROVIDERS, AI_PROVIDERS } from "@/shared/constants/providers"; +import { FREE_PROVIDERS, AI_PROVIDERS, getProviderByAlias } from "@/shared/constants/providers"; // Keep providers without serviceKinds (default LLM) or with "llm" in serviceKinds function isLLMProvider(id) { @@ -104,7 +104,7 @@ function RecentRequests({ requests = [] }) { className="py-1.5 font-mono truncate max-w-[80px] text-text-muted" title={r.provider} > - {r.provider || "—"} + {getProviderLabel(r.provider) || "—"} @@ -310,6 +310,17 @@ export default function UsageStats({ const [tableView, setTableView] = useState("provider"); const [viewMode, setViewMode] = useState("costs"); const [providers, setProviders] = useState([]); + + // Resolve a provider key (built-in id, alias, or custom node id like + // "openai-compatible-chat-096baf9a-...") to a human-friendly name. + const getProviderLabel = useCallback((providerId) => { + if (!providerId) return "Unknown Provider"; + const match = providers.find((p) => p.provider === providerId || p.id === providerId); + if (match) return match.nodeName || match.name || providerId; + // Fallback: known built-in provider (by id, alias, or display prefix) + const known = getProviderByAlias(providerId) || AI_PROVIDERS[providerId] || FREE_PROVIDERS[providerId]; + return known?.name || known?.uiAlias || known?.alias || providerId; + }, [providers]); const [periodLocal, setPeriodLocal] = useState("today"); const isInitialLoad = useRef(true); const hasLoadedStats = useRef(false); @@ -458,7 +469,7 @@ export default function UsageStats({ variant={item.pending > 0 ? "primary" : "neutral"} size="sm" > - {item.provider} + {getProviderLabel(item.provider)} {fmt(item.requests)} @@ -522,7 +533,7 @@ export default function UsageStats({ variant={item.pending > 0 ? "primary" : "neutral"} size="sm" > - {item.provider} + {getProviderLabel(item.provider)} {fmt(item.requests)} @@ -560,7 +571,7 @@ export default function UsageStats({ {item.rawModel} - {item.provider} + {getProviderLabel(item.provider)} {fmt(item.requests)} @@ -593,7 +604,7 @@ export default function UsageStats({ renderDetailCells: (item) => ( <> - {item.provider || item.key} + {getProviderLabel(item.provider || item.key)} {fmt(item.requests)} @@ -633,7 +644,7 @@ export default function UsageStats({ {item.rawModel} - {item.provider} + {getProviderLabel(item.provider)} {fmt(item.requests)} @@ -645,7 +656,7 @@ export default function UsageStats({ }; } } - }, [stats, tableView, sortBy, sortOrder]); + }, [stats, tableView, sortBy, sortOrder, getProviderLabel]); if (!stats && !loading) return ( @@ -752,6 +763,7 @@ export default function UsageStats({ renderSummaryCells={activeTableConfig.renderSummaryCells} renderDetailCells={activeTableConfig.renderDetailCells} emptyMessage={activeTableConfig.emptyMessage} + providerLabel={getProviderLabel} /> )}