/** * dashboard-client/src/tabs/CacheTab.tsx -- Cache tab (B.3 + A3). * * Sections: * 1. Provider Prompt Cache -> ProviderCacheCard (/api/provider-cache) * 2. Cache Stripe Distribution -> StripeDistributionCard (/api/cache-stripes) * 3. Cache Hit-Rate Trend -> CacheHitRateTrendCard (/api/perf) * 4. Mega-Compact Dedup Cache -> CacheHitsCard + TimeSavedCard (/api/snapshot) * * Each section fetches independently; failures in one do not affect others. * 5s polling on provider cache and activity snapshot; 15s on stripes + trend. */ import { useState, useCallback } from "react"; import type { SnapshotResponse, ProviderCacheResponse, CacheStripesResponse, PerfResponse, PrefixStabilityResponse, SettingsResponse, } from "@contracts"; import { useApi } from "../hooks/useApi"; import { fetchSnapshot, fetchProviderCache, fetchCacheStripes, fetchPrefixStability, fetchPerf, fetchSettings, } from "../api/client"; import { CacheHitsCard } from "../components/CacheHitsCard"; import { TimeSavedCard } from "../components/TimeSavedCard"; import { ProviderCacheCard } from "../components/ProviderCacheCard"; import { StripeDistributionCard } from "../components/StripeDistributionCard"; import { CacheHitRateTrendCard } from "../components/CacheHitRateTrendCard"; import { PrefixStabilityCard } from "../components/PrefixStabilityCard"; import { Button } from "../components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card"; import { MetricsCards } from "./CacheTab/MetricsCards"; const DASH_0C_KEY = "MEGACOMPACT_DASH_0C"; /** Resolve the DASH-0c consolidation flag from the server settings state. * The dashboard client is a browser bundle with NO `process` global, so the * positive sprint flag is read from the server-authoritative /api/rag-settings * state (the server resolves MEGACOMPACT_DASH_0C into a SettingState boolean). * Absent/not-yet-loaded => false (flag-off posture), so flag-off users never * see the Performance section flash; it mounts only once settings confirm ON. */ function dash0cEnabled(settings: SettingsResponse | null): boolean { if (!settings) return false; for (const cat of settings.categories) { for (const s of cat.settings) { if (s.key === DASH_0C_KEY && s.type === "boolean") return s.value === true; } } return false; } export default function CacheTab(): React.ReactElement { const [infoExpanded, setInfoExpanded] = useState(false); /* --- Provider prompt cache (5s poll) --- */ const { data: providerCache, loading: pcLoading, error: pcError, } = useApi( useCallback(() => fetchProviderCache(), []), { pollInterval: 5000 }, ); /* --- Cache stripe distribution (15s poll) --- */ const { data: stripes, loading: stripesLoading, error: stripesError, } = useApi( useCallback(() => fetchCacheStripes(), []), { pollInterval: 15000 }, ); /* --- Cache hit-rate trend from perf samples (15s poll) --- */ const { data: perf, loading: perfLoading, error: perfError, } = useApi( useCallback(() => fetchPerf({ minutes: 30 }), []), { pollInterval: 15000 }, ); /* --- Per-turn stable-prefix ratio trend (PC-C, 15s poll) --- */ const { data: prefixStability, loading: psLoading, } = useApi( useCallback(() => fetchPrefixStability(50), []), { pollInterval: 15000 }, ); /* --- Dedup cache snapshot (5s poll) --- */ const { data: snapshot, loading: snapLoading, error: snapError, } = useApi( useCallback(() => fetchSnapshot(), []), { pollInterval: 5000 }, ); /* --- DASH-0c: server-resolved settings state for the flag gate --- */ const { data: settingsData } = useApi( useCallback(() => fetchSettings(), []), { pollInterval: 0, maxRetries: 0 }, ); const dash0cOn = dash0cEnabled(settingsData); return (
{infoExpanded && ( Cache-Friendly Prompt Ordering
  • Keep system prompts and stable context at the top of your conversation — the provider caches the leading prefix.
  • Tool results and volatile content are automatically moved to the tail by message separation (MEGACOMPACT_MESSAGE_SEPARATION) so they don't invalidate the cache prefix.
  • Cache striping (MEGACOMPACT_CACHE_STRIPING) further orders stable context by a stability score so the most durable chunks lead.
  • Avoid inserting new instructions mid-conversation — prepend them instead.
{snapshot && (
Status:{" "} {snapshot.config.auto ? "Auto-compaction Enabled" : "Auto-compaction Disabled"} |{" "} fast-gate {snapshot.config.fastGatePct}% / threshold{" "} {snapshot.config.thresholdTokens.toLocaleString()} tokens
)}
)}
{/* ============================================================== Section 1 -- Provider Prompt Cache ============================================================== */}

Provider Prompt Cache

{pcLoading ? (

Loading...

) : pcError ? (

Provider cache unavailable: {pcError.message}

) : providerCache ? ( ) : null} {/* ============================================================== Section 2 -- Cache Stripe Distribution ============================================================== */}

Cache Stripe Distribution

{stripesLoading ? (

Loading...

) : stripesError ? (

Cache stripe data unavailable: {stripesError.message}

) : stripes ? ( ) : null} {/* ============================================================== Section 3 -- Cache Hit-Rate Trend ============================================================== */}

Cache Hit-Rate Trend

{perfLoading ? (

Loading...

) : perfError ? (

Hit-rate trend unavailable: {perfError.message}

) : perf ? ( ) : null} {/* ============================================================== Section 3b -- Per-Turn Stable Prefix (PC-C) Omitted when flag-off: the endpoint 404s, so psError is set and this section stays empty. No sample/time-series data, only per-turn prefix ratios read from the local events log. ============================================================== */} {prefixStability && !psLoading ? (

Per-Turn Stable Prefix

) : null} {/* ============================================================== Section 4 -- Mega-Compact Dedup Cache ============================================================== */}

Mega-Compact Dedup Cache

{snapLoading ? (

Loading...

) : snapError ? (

Snapshot unavailable: {snapError.message}

) : ( snapshot && (() => { const { cacheHits, compacts, timeSaved } = snapshot; return (
); })() )} {/* ============================================================== Section 5 -- Performance (DASH-0c) The metrics body (ModelBadge + PerfChart + PerfCards + RagDashboard) absorbed from MetricsTab as a Performance section. Moved VERBATIM to ./CacheTab/MetricsCards.tsx. Omitted entirely when flag-off so the cache-only body is byte-identical to the predecessor. ============================================================== */} {dash0cOn && (

Performance

)}
); }