mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-28 00:35:32 +08:00
feat(usage): filter-driven Hero with cache-normalized totals
- Normalize OpenAI/Gemini input_tokens semantics in SQL via the new fresh_input_sql helper (cache_read subtracted at query time, no data migration). Recovers correct cache hit rates for Codex/Gemini. - Add get_usage_summary_by_app endpoint for per-app split (single UNION ALL + GROUP BY, avoids N+1). - Replace UsageSummaryCards + AppBreakdownRail with a single filter-driven UsageHero card; clicking a filter button now truly changes the displayed numbers and the title accent color. - Tighten KNOWN_APP_TYPES to the 3 app_types whose token data is reliably collected (claude/codex/gemini); hide claude-desktop, hermes, opencode, openclaw filter buttons and i18n keys. - Flag cache_creation as N/A for OpenAI-style protocols (Codex, Gemini); show a "partial" tooltip when the All view mixes both protocol families.
This commit is contained in:
@@ -18,7 +18,12 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { useRequestLogs } from "@/lib/query/usage";
|
||||
import type { LogFilters, UsageRangeSelection } from "@/types/usage";
|
||||
import {
|
||||
KNOWN_APP_TYPES,
|
||||
getFreshInputTokens,
|
||||
type LogFilters,
|
||||
type UsageRangeSelection,
|
||||
} from "@/types/usage";
|
||||
import { ChevronLeft, ChevronRight, Search, X } from "lucide-react";
|
||||
import { UsageDateRangePicker } from "./UsageDateRangePicker";
|
||||
import {
|
||||
@@ -138,9 +143,11 @@ export function RequestLogTable({
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">{t("usage.allApps")}</SelectItem>
|
||||
<SelectItem value="claude">Claude</SelectItem>
|
||||
<SelectItem value="codex">Codex</SelectItem>
|
||||
<SelectItem value="gemini">Gemini</SelectItem>
|
||||
{KNOWN_APP_TYPES.map((at) => (
|
||||
<SelectItem key={at} value={at}>
|
||||
{t(`usage.appFilter.${at}`, { defaultValue: at })}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
@@ -323,9 +330,23 @@ export function RequestLogTable({
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell className="text-center px-1.5">
|
||||
<div className="tabular-nums">
|
||||
{fmtInt(log.inputTokens, locale)}
|
||||
</div>
|
||||
{(() => {
|
||||
const freshInput = getFreshInputTokens(log);
|
||||
const isCacheInclusive =
|
||||
log.inputTokens !== freshInput;
|
||||
return (
|
||||
<div
|
||||
className="tabular-nums"
|
||||
title={
|
||||
isCacheInclusive
|
||||
? `Raw: ${log.inputTokens.toLocaleString()}`
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{fmtInt(freshInput, locale)}
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
{(log.cacheReadTokens > 0 ||
|
||||
log.cacheCreationTokens > 0) && (
|
||||
<div className="text-[10px] text-muted-foreground whitespace-nowrap">
|
||||
|
||||
Reference in New Issue
Block a user