fix(cache): fix trends chart data mismatch and remove redundant metrics card

- Align CacheTrends interface with API response (cachedRequests instead of hits/misses/hitRate)
- Update bar chart rendering to use cachedRequests field from getCacheTrend()
- Remove duplicate CacheStatsCard from cache overview (already in settings AI tab)
- Fix tooltip to use i18n translations instead of hardcoded English

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
oyi77
2026-04-02 23:50:48 +07:00
parent cc902db4ab
commit b5c84a91fb
2 changed files with 19 additions and 15 deletions

View File

@@ -5,9 +5,10 @@ import { useTranslations } from "next-intl";
export interface CacheTrendPoint {
timestamp: string;
requests: number;
hits: number;
misses: number;
hitRate: number;
cachedRequests: number;
inputTokens: number;
cachedTokens: number;
cacheCreationTokens: number;
}
interface CacheTrendsProps {
@@ -27,7 +28,8 @@ export default function CacheTrends({
const trendData: CacheTrendPoint[] = data ?? [];
const maxRequests = trendData.length > 0 ? Math.max(...trendData.map((p) => p.requests), 1) : 1;
const peakHitRate = trendData.length > 0 ? Math.max(...trendData.map((p) => p.hitRate)) : null;
const maxCachedRequests =
trendData.length > 0 ? Math.max(...trendData.map((p) => p.cachedRequests), 0) : 0;
return (
<div
@@ -69,17 +71,21 @@ export default function CacheTrends({
</div>
) : (
<>
{peakHitRate !== null && (
{maxCachedRequests > 0 && (
<div className="text-xs text-text-muted">
Peak hit rate:{" "}
<span className="font-medium text-foreground">{peakHitRate.toFixed(1)}</span>
Peak cached:{" "}
<span className="font-medium text-foreground">
{maxCachedRequests} / {maxRequests}
</span>
</div>
)}
<div className="flex items-end gap-1 h-32">
{trendData.map((point) => {
const height = Math.max(4, (point.requests / maxRequests) * 100);
const hitHeight =
point.requests > 0 ? Math.max(2, (point.hits / point.requests) * height) : 0;
const cachedHeight =
point.requests > 0
? Math.max(2, (point.cachedRequests / point.requests) * height)
: 0;
const hour = new Date(point.timestamp).toLocaleTimeString([], {
hour: "2-digit",
minute: "2-digit",
@@ -92,16 +98,17 @@ export default function CacheTrends({
className="flex-1 flex flex-col items-center gap-1 group relative"
>
<div className="absolute bottom-full mb-1 hidden group-hover:block bg-surface-raised border border-border rounded px-2 py-1 text-xs whitespace-nowrap z-10">
{hour}: {point.requests} requests, {point.hits} cached
{hour}: {point.requests} {t("requests").toLowerCase()}, {point.cachedRequests}{" "}
{t("cached").toLowerCase()}
</div>
<div className="w-full flex flex-col justify-end h-full gap-px">
<div
className="w-full bg-green-500/30 rounded-t"
style={{ height: `${hitHeight}%` }}
style={{ height: `${cachedHeight}%` }}
/>
<div
className="w-full bg-text-muted/20 rounded-t"
style={{ height: `${height - hitHeight}%` }}
style={{ height: `${height - cachedHeight}%` }}
/>
</div>
<span className="text-[10px] text-text-muted truncate w-full text-center">

View File

@@ -435,9 +435,6 @@ export default function CachePage() {
</Card>
)}
{/* Prompt Cache Metrics (cumulative with reset) */}
<CacheStatsCard />
{/* Cache Trend (24h) */}
{trend.length > 0 && (
<Card>