import { IconChartTreemap, IconChevronDown, IconChevronRight, IconLock, IconListDetails, } from "@tabler/icons-react"; import { useMemo, useState } from "react"; import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip.js"; import { cn } from "../utils.js"; import { ContextSegmentRowView } from "./ContextSegmentRow.js"; import { ContextTreemapView } from "./ContextTreemap.js"; import { contextGroupColor, formatContextTokens } from "./format.js"; import type { ContextManifestViewData, ContextSegmentStatus, ContextSegmentViewData, ContextSystemSectionViewData, } from "./types.js"; interface Group { name: string; tokens: number; segments: ContextSegmentViewData[]; } function applyOptimisticStatus( segments: ContextSegmentViewData[], optimistic: Map, ) { if (optimistic.size === 0) return segments; return segments.map((segment) => optimistic.has(segment.segmentId) ? { ...segment, status: optimistic.get(segment.segmentId)! } : segment, ); } function groupedSegments(segments: ContextSegmentViewData[]): Group[] { const map = new Map(); for (const segment of segments) { const name = segment.status === "pinned" ? "Pinned" : segment.status === "evicted" ? "Evicted" : segment.group; const group = map.get(name) ?? { name, tokens: 0, segments: [] }; group.tokens += segment.tokenCount; group.segments.push(segment); map.set(name, group); } const order = [ "Pinned", "Tool results", "Files read", "Conversation", "Thinking", "Evicted", ]; return [...map.values()].sort((a, b) => { const ai = order.indexOf(a.name); const bi = order.indexOf(b.name); return ai >= 0 || bi >= 0 ? (ai < 0 ? 99 : ai) - (bi < 0 ? 99 : bi) : b.tokens - a.tokens; }); } function sourceLabel(section: ContextSystemSectionViewData) { return ( section.sourceRef?.path ?? section.sourceRef?.resourceId ?? section.sourceRef?.scope ?? "framework" ); } function SystemSectionRow({ section, totalTokens, }: { section: ContextSystemSectionViewData; totalTokens: number; }) { const share = totalTokens > 0 ? Math.round((section.tokenCount / totalTokens) * 100) : 0; return (
{section.label}
{sourceLabel(section)} · {formatContextTokens(section.tokenCount)}{" "} tokens · {share}% {section.tokenMethod === "estimate" ? " · estimated" : ""}
{section.preview ? (
{section.preview}
) : null}
); } export function ContextXRayPanelView({ manifest, contextWindow, optimistic, onPin, onEvict, onRestore, governanceLabels = {}, systemOrderedLabel = "System · ordered, not evictable", titleLabel = "Context X-Ray", }: { manifest: ContextManifestViewData; contextWindow: number; optimistic: Map; onPin: (segmentId: string) => void; onEvict: (segmentId: string) => void; onRestore: (segmentId: string) => void; governanceLabels?: Partial>; systemOrderedLabel?: string; titleLabel?: string; }) { const [mode, setMode] = useState<"list" | "map">("list"); const [collapsed, setCollapsed] = useState>(new Set()); const segments = useMemo( () => applyOptimisticStatus(manifest.segments, optimistic), [manifest.segments, optimistic], ); const groups = useMemo(() => groupedSegments(segments), [segments]); const sections = manifest.systemSections ?? []; const systemGroups = useMemo( () => (["required", "inherited", "user"] as const).flatMap((governance) => { const items = sections.filter( (section) => section.governance === governance, ); return items.length ? [ { governance, sections: items, tokens: items.reduce( (sum, section) => sum + section.tokenCount, 0, ), }, ] : []; }), [sections], ); const pct = Math.min( 100, Math.round((manifest.totalTokens / contextWindow) * 100), ); const headroom = Math.max(0, contextWindow - manifest.totalTokens); const { conversationTokens: conversation, systemTokens: system } = manifest; const pinned = segments.filter( (segment) => segment.status === "pinned", ).length; const evicted = segments.filter( (segment) => segment.status === "evicted", ).length; const details = [ `${formatContextTokens(headroom)} free`, system > 0 ? `${formatContextTokens(system)} system` : null, `${formatContextTokens(conversation)} conversation`, pinned > 0 ? `${pinned} pinned` : null, evicted > 0 ? `${evicted} evicted` : null, manifest.tokenCountMethod === "estimate" ? "estimated" : null, !manifest.enforceable ? "advisory" : null, ].filter((item): item is string => Boolean(item)); const toggle = (key: string) => setCollapsed((current) => { const next = new Set(current); if (next.has(key)) next.delete(key); else next.add(key); return next; }); return (

{titleLabel}

{formatContextTokens(manifest.totalTokens)} · {pct}%
{details.map((detail) => ( {detail} ))} {manifest.reclaimedTokens > 0 ? ( -{formatContextTokens(manifest.reclaimedTokens)} ) : null}
List Map
{mode === "map" ? ( { if (segments.some((segment) => segment.segmentId === id)) setCollapsed(new Set()); }} /> ) : (
{systemGroups.length ? (
{systemOrderedLabel}
{systemGroups.map((group) => { const key = `system:${group.governance}`; const isCollapsed = collapsed.has(key); return (
{!isCollapsed ? (
{group.sections .slice() .sort((a, b) => b.tokenCount - a.tokenCount) .map((section) => ( ))}
) : null}
); })}
) : null} {groups.map((group) => { const isCollapsed = collapsed.has(group.name); return (
{!isCollapsed ? (
{group.segments .slice() .sort((a, b) => b.tokenCount - a.tokenCount) .map((segment) => ( onPin(segment.segmentId)} onEvict={() => onEvict(segment.segmentId)} onRestore={() => onRestore(segment.segmentId)} /> ))}
) : null}
); })}
)}
); }