diff --git a/packages/ui/src/components/layout/ContextSidebarTab.tsx b/packages/ui/src/components/layout/ContextSidebarTab.tsx index f8e43545..f15e8467 100644 --- a/packages/ui/src/components/layout/ContextSidebarTab.tsx +++ b/packages/ui/src/components/layout/ContextSidebarTab.tsx @@ -8,6 +8,7 @@ import { useThemeSystem } from '@/contexts/useThemeSystem'; import { generateSyntaxTheme } from '@/lib/theme/syntaxThemeGenerator'; import { useConfigStore } from '@/stores/useConfigStore'; import { useSessionUIStore } from '@/sync/session-ui-store'; +import { computeCacheHitRate } from '@/stores/utils/tokenUtils'; import { useSessions, useSessionMessageRecords } from '@/sync/sync-context'; import { copyTextToClipboard } from '@/lib/clipboard'; import { getCurrentIntlLocale, useI18n } from '@/lib/i18n'; @@ -340,6 +341,14 @@ export const ContextPanelContent: React.FC = () => { const tokenBreakdown = contextMessage ? extractTokenBreakdown(contextMessage) : EMPTY_BREAKDOWN; + // Cache hit rate for the last assistant message. `input` is the non-cached portion + // (total input - cache.read - cache.write per SDK's session.ts:getUsage), + // so hit rate = cache.read / (input + cache.read + cache.write). + const cacheHitRate = computeCacheHitRate({ + input: tokenBreakdown.input, + cache: { read: tokenBreakdown.cacheRead, write: tokenBreakdown.cacheWrite }, + }); + const totalAssistantCost = assistantMessages.reduce((sum, message) => { const cost = toNonNegativeNumber((message.info as { cost?: unknown }).cost); return sum + cost; @@ -384,6 +393,7 @@ export const ContextPanelContent: React.FC = () => { providerModel, tokenBreakdown, usagePercent, + cacheHitRate, totalAssistantCost, contextLimit, breakdown: { @@ -471,18 +481,29 @@ export const ContextPanelContent: React.FC = () => { {/* ── Last turn tokens ── */}