
3D Extruded Buildings & Urban Footprints
Real-world 3D building extrusions with dynamic sunlight shadows, terrain DEM elevations, and pitch/bearing camera controls.
LlamaIndex and LangChain style Retrieval-Augmented Generation (RAG) pipeline debugger and chunk retrieval inspector. Features 5-stage interactive DAG flow, HyDE expansion preview, hybrid dense/sparse search telemetry, cross-encoder reranking, and grounded response synthesis.
Also available for Vue ->$pnpm dlx shadcn@latest add https://uipkge.dev/r/react/rag-pipeline-visualizer.json$npx shadcn@latest add https://uipkge.dev/r/react/rag-pipeline-visualizer.json$yarn dlx shadcn@latest add https://uipkge.dev/r/react/rag-pipeline-visualizer.json$bunx shadcn@latest add https://uipkge.dev/r/react/rag-pipeline-visualizer.jsonnpx shadcn@latest add @uipkge-react/rag-pipeline-visualizerInstalls to:components/blocks/| Name | Type / Values | Default | Required |
|---|---|---|---|
className | string | — | optional |
Type aliases exported from this item's source. Use these to shape the data you pass in.
PipelineStageinterface PipelineStage {
id: number
name: string
subtitle: string
latency: string
durationMs: number
status: 'completed' | 'active' | 'queued' | 'bypassed'
icon: React.ElementType
tag: string
details: {
description: string
metrics: { label: string; value: string }[]
codeOrData?: { title: string; content: string }
}
}RetrievedChunkinterface RetrievedChunk {
id: string
citationIndex: number
relevanceScore: number
rerankBoost: number
cosineScore: number
bm25Score: number
documentPath: string
namespace: string
chunkOffset: string
tokenCount: number
updatedAgo: string
title: string
snippetPrefix: string
highlightedText: string
snippetSuffix: string
fullSnippet: string
}'use client'
import * as React from 'react'
import {
BookOpen,
Bot,
Check,
ChevronRight,
Code2,
Copy,
Cpu,
Database,
FileCode,
Filter,
Layers,
Play,
RefreshCw,
Search,
ShieldCheck,
SlidersHorizontal,
Sparkles,
Terminal,
ThumbsDown,
ThumbsUp,
Workflow,
Zap,
} from 'lucide-react'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Progress } from '@/components/ui/progress'
import { Separator } from '@/components/ui/separator'
import { Slider } from '@/components/ui/slider'
import { Switch } from '@/components/ui/switch'
import { cn } from '@/lib/utils'
export interface RagPipelineVisualizerProps {
className?: string
}
interface PipelineStage {
id: number
name: string
subtitle: string
latency: string
durationMs: number
status: 'completed' | 'active' | 'queued' | 'bypassed'
icon: React.ElementType
tag: string
details: {
description: string
metrics: { label: string; value: string }[]
codeOrData?: { title: string; content: string }
}
}
interface RetrievedChunk {
id: string
citationIndex: number
relevanceScore: number
rerankBoost: number
cosineScore: number
bm25Score: number
documentPath: string
namespace: string
chunkOffset: string
tokenCount: number
updatedAgo: string
title: string
snippetPrefix: string
highlightedText: string
snippetSuffix: string
fullSnippet: string
}
const presetQueries = [
'How do I configure OKLCH color palettes in Tailwind v4 with UIPKGE?',
'Cross-Encoder vs Bi-Encoder reranker score calibration',
'HyDE prompt expansion for zero-shot semantic retrieval',
'Pinecone HNSW index tuning: efSearch & M parameter tradeoffs',
]
const allChunks: RetrievedChunk[] = [
{
id: 'chunk-1',
citationIndex: 1,
relevanceScore: 0.942,
rerankBoost: 0.142,
cosineScore: 0.8,
bm25Score: 0.785,
documentPath: 'docs/styling/tailwind-v4-oklch.md',
namespace: 'docs',
chunkOffset: 'Chunk #3 · Lines 42–78',
tokenCount: 384,
updatedAgo: '2 hours ago',
title: 'Tailwind v4 OKLCH Architecture & @theme Configuration',
snippetPrefix: 'Tailwind CSS v4 introduces native CSS-first token configuration with ',
highlightedText:
'@theme inline and OKLCH color spaces. In contrast to RGB/HSL, OKLCH ensures perceptually uniform lightness across hues',
snippetSuffix:
', preventing contrast degradation in dark mode variants while preserving single-source token truth.',
fullSnippet:
'Tailwind CSS v4 introduces native CSS-first token configuration with `@theme inline` and OKLCH color spaces. In contrast to RGB/HSL, OKLCH ensures perceptually uniform lightness across hues, preventing contrast degradation in dark mode variants while preserving single-source token truth.',
},
{
id: 'chunk-2',
citationIndex: 2,
relevanceScore: 0.887,
rerankBoost: 0.095,
cosineScore: 0.792,
bm25Score: 0.71,
documentPath: 'docs/tokens/color-derivation.md',
namespace: 'docs',
chunkOffset: 'Chunk #1 · Lines 1–36',
tokenCount: 412,
updatedAgo: '1 day ago',
title: 'Color Tokens Derivation & Contrast Calibration',
snippetPrefix: 'Deriving consistent dark-mode contrasts requires ',
highlightedText:
'anchoring chroma and shifting lightness along the OKLCH L-axis. Use --color-primary: oklch(0.65 0.22 260) for vibrant interactive states',
snippetSuffix:
' and calibrate border contrast with `--color-border: oklch(0.28 0.01 260)` for WCAG AA compliance across both frameworks.',
fullSnippet:
'Deriving consistent dark-mode contrasts requires anchoring chroma and shifting lightness along the OKLCH L-axis. Use `--color-primary: oklch(0.65 0.22 260)` for vibrant interactive states and calibrate border contrast with `--color-border: oklch(0.28 0.01 260)` for WCAG AA compliance across both frameworks.',
},
{
id: 'chunk-3',
citationIndex: 3,
relevanceScore: 0.824,
rerankBoost: 0.048,
cosineScore: 0.776,
bm25Score: 0.65,
documentPath: 'blog/2026/design-systems-monorepo.md',
namespace: 'blog',
chunkOffset: 'Chunk #5 · Lines 112–164',
tokenCount: 526,
updatedAgo: '3 days ago',
title: 'Dual-Framework Component Registry Architecture',
snippetPrefix: 'When architecting a dual-framework registry (Vue + React), ',
highlightedText:
'shared design tokens must compile cleanly without runtime overhead. We leverage CSS custom properties to mirror CVA component variants',
snippetSuffix: ' across both frameworks with zero extra runtime.',
fullSnippet:
'When architecting a dual-framework registry (Vue + React), shared design tokens must compile cleanly without runtime overhead. We leverage modern CSS custom properties and PostCSS pipelines to mirror CVA component variants across both frameworks with zero extra runtime.',
},
]
export function RagPipelineVisualizer({ className }: RagPipelineVisualizerProps) {
const [currentQuery, setCurrentQuery] = React.useState(
'How do I configure OKLCH color palettes in Tailwind v4 with UIPKGE?',
)
const [topK, setTopK] = React.useState(3)
const [rerankerEnabled, setRerankerEnabled] = React.useState(true)
const [selectedStageId, setSelectedStageId] = React.useState<number>(3)
const [isExecuting, setIsExecuting] = React.useState(false)
const [copiedChunkId, setCopiedChunkId] = React.useState<string | null>(null)
const [copiedResponse, setCopiedResponse] = React.useState(false)
const [copiedTrace, setCopiedTrace] = React.useState(false)
const [activeCitationHover, setActiveCitationHover] = React.useState<number | null>(null)
const [showTraceJson, setShowTraceJson] = React.useState(false)
const [userFeedback, setUserFeedback] = React.useState<'up' | 'down' | null>(null)
const stages = React.useMemo<PipelineStage[]>(
() => [
{
id: 1,
name: '1. User Query & HyDE Expansion',
subtitle: 'Query rewritten with hypothetical document embedding · 42ms',
latency: '42ms',
durationMs: 42,
status: 'completed',
icon: Sparkles,
tag: 'Prompt Rewriting',
details: {
description:
'Generates a synthetic hypothetical answer using Claude 3.5 Haiku to bridge vocabulary mismatch between conversational queries and technical documentation.',
metrics: [
{ label: 'Expansion Model', value: 'Claude 3.5 Haiku' },
{ label: 'Latency', value: '42ms' },
{ label: 'Prompt Tokens', value: '48 tokens' },
{ label: 'Hypothesis Length', value: '112 tokens' },
],
codeOrData: {
title: 'Generated Hypothetical Document (HyDE)',
content:
'Tailwind CSS v4 defines color tokens using CSS variables inside `@theme inline` with `oklch(L C H)` functions. In dual-framework component registries like UIPKGE, OKLCH ensures uniform perceptual lightness across hue shifts in light and dark variants without breaking WCAG AA contrast.',
},
},
},
{
id: 2,
name: '2. Hybrid Dense + Sparse Search',
subtitle: 'Dense Cosine + BM25 Lexical search across 480k chunks · 64ms',
latency: '64ms',
durationMs: 64,
status: 'completed',
icon: Database,
tag: 'Reciprocal Rank Fusion',
details: {
description:
'Performs vector similarity search on 1536-dim embeddings combined with sparse BM25 keyword matching across 482,910 document chunks.',
metrics: [
{ label: 'Vector Index', value: 'Pinecone Serverless (HNSW)' },
{ label: 'Dimension', value: '1536-dim (text-embedding-3-small)' },
{ label: 'Fusion Weight', value: 'α = 0.70 Dense + 0.30 Sparse' },
{ label: 'Candidate Pool', value: '20 Candidate Chunks' },
],
codeOrData: {
title: 'Dense Vector Projection (32-float slice)',
content:
'[-0.048, 0.135, 0.092, -0.018, 0.245, -0.110, 0.049, 0.174, -0.082, 0.001, 0.325, -0.059, 0.097, 0.191, -0.149, 0.068, -0.024, 0.212, 0.082, -0.094, 0.121, -0.037, 0.156, 0.031, -0.172, 0.099, 0.056, -0.078, 0.195, -0.013, 0.072, 0.141]',
},
},
},
{
id: 3,
name: '3. Cross-Encoder Reranker',
subtitle: rerankerEnabled
? 'Cohere Rerank v3: re-scores Top 20 -> Top 3 · 28ms'
: 'Bypassed (Using raw hybrid search ranking) · 0ms',
latency: rerankerEnabled ? '28ms' : '0ms',
durationMs: rerankerEnabled ? 28 : 0,
status: rerankerEnabled ? 'completed' : 'bypassed',
icon: Filter,
tag: rerankerEnabled ? 'Cross-Attention Re-Scoring' : 'Bypassed',
details: {
description: rerankerEnabled
? 'Applies deep transformer cross-attention to score query-document pairs simultaneously, eliminating false-positive semantic matches.'
: 'Reranker is currently bypassed. Chunks are ordered purely by initial hybrid reciprocal rank scores.',
metrics: [
{ label: 'Model', value: 'cohere-rerank-v3.0-multilingual' },
{ label: 'Top-K Retained', value: `Top ${topK} of 20` },
{ label: 'Relevance Cutoff', value: '≥ 0.800 score' },
{ label: 'Max Rank Shift', value: '+3 positions (Chunk #3)' },
],
codeOrData: {
title: 'Reranker Score Calibration Delta',
content:
'Chunk #1: 0.800 (Cosine) -> 0.942 (Rerank) [+0.142 boost]\nChunk #2: 0.792 (Cosine) -> 0.887 (Rerank) [+0.095 boost]\nChunk #3: 0.776 (Cosine) -> 0.824 (Rerank) [+0.048 boost]\n17 candidates pruned below 0.800 relevance threshold',
},
},
},
{
id: 4,
name: '4. Context Window Assembly',
subtitle: '1,248 tokens packed, 98% prompt density · 8ms',
latency: '8ms',
durationMs: 8,
status: 'completed',
icon: Layers,
tag: 'Token Packaging',
details: {
description:
'Deduplicates overlapping chunk boundaries, injects citation boundary anchors `[1]`, `[2]`, `[3]`, and formats system directives for zero-hallucination grounding.',
metrics: [
{ label: 'Window Budget', value: '1,248 / 8,192 tokens (15.2%)' },
{ label: 'Prompt Density', value: '98.4% relevance tokens' },
{ label: 'Chunks Packaged', value: `${Math.min(topK, 3)} chunks` },
{ label: 'Delimiter Format', value: '<context_document_id>' },
],
codeOrData: {
title: 'Assembled Prompt Context Envelope',
content:
'<system>\nYou are a Lead Design Systems Architect. Synthesize answers strictly from provided context chunks.\nAlways ground every technical claim with an inline citation key [1], [2], or [3].\n</system>\n\n<context>\n[1] doc: docs/styling/tailwind-v4-oklch.md (score: 0.942)\n[2] doc: docs/tokens/color-derivation.md (score: 0.887)\n[3] doc: blog/2026/design-systems-monorepo.md (score: 0.824)\n</context>',
},
},
},
{
id: 5,
name: '5. LLM Synthesis & Grounding',
subtitle: 'Claude 3.5 Sonnet streaming generation · 820ms',
latency: '820ms',
durationMs: 820,
status: 'completed',
icon: Bot,
tag: 'Streaming Synthesis',
details: {
description:
'Generates final structured markdown answer with streaming tokens, verifies every claim against citation sources, and produces grounded output.',
metrics: [
{ label: 'Model', value: 'claude-3-5-sonnet-20241022' },
{ label: 'Time to First Token', value: '180ms' },
{ label: 'Generation Speed', value: '68.2 tokens/sec' },
{ label: 'Grounding Verification', value: '100% (3/3 facts grounded)' },
],
codeOrData: {
title: 'Telemetry & Cost Summary',
content:
'Prompt Tokens: 1,248 ($0.00374)\nCompletion Tokens: 214 ($0.00064)\nTotal Cost: $0.00438\nHallucination Detection: 0 violations detected',
},
},
},
],
[rerankerEnabled, topK],
)
const displayedChunks = React.useMemo(() => {
const count = Math.min(Math.max(1, topK), allChunks.length)
return allChunks.slice(0, count)
}, [topK])
const currentStage = stages.find((s) => s.id === selectedStageId) ?? stages[0]
const totalPipelineLatency = React.useMemo(() => {
const sum = stages.reduce((acc, s) => acc + s.durationMs, 0)
return `${sum}ms`
}, [stages])
const traceJson = React.useMemo(() => {
return JSON.stringify(
{
traceId: 'trc_rag_948201a4',
pipeline: 'enterprise_knowledge_rag_v3',
timestamp: new Date().toISOString(),
query: currentQuery,
config: {
embeddingModel: 'text-embedding-3-small',
dimensions: 1536,
vectorDb: 'Pinecone Serverless',
topK: topK,
reranker: rerankerEnabled ? 'cohere-rerank-v3' : 'none',
alphaFusion: 0.7,
},
stages: stages.map((s) => ({
id: s.id,
name: s.name,
durationMs: s.durationMs,
status: s.status,
})),
retrievedChunks: displayedChunks.map((c) => ({
citation: c.citationIndex,
docPath: c.documentPath,
relevance: rerankerEnabled ? c.relevanceScore : c.cosineScore,
rerankBoost: rerankerEnabled ? c.rerankBoost : 0,
tokenCount: c.tokenCount,
})),
synthesis: {
model: 'claude-3-5-sonnet-20241022',
promptTokens: 1248,
completionTokens: 214,
groundedFactRatio: 1.0,
latencyMs: 820,
},
},
null,
2,
)
}, [currentQuery, topK, rerankerEnabled, stages, displayedChunks])
const handleRunPipeline = () => {
if (isExecuting) return
setIsExecuting(true)
setSelectedStageId(1)
setTimeout(() => {
setSelectedStageId(2)
}, 200)
setTimeout(() => {
setSelectedStageId(3)
}, 450)
setTimeout(() => {
setSelectedStageId(4)
}, 700)
setTimeout(() => {
setSelectedStageId(5)
setIsExecuting(false)
}, 950)
}
const handleSelectPreset = (preset: string) => {
setCurrentQuery(preset)
handleRunPipeline()
}
const handleCopyChunk = (id: string, text: string) => {
navigator.clipboard.writeText(text)
setCopiedChunkId(id)
setTimeout(() => {
setCopiedChunkId(null)
}, 2000)
}
const handleCopyResponse = (text: string) => {
navigator.clipboard.writeText(text)
setCopiedResponse(true)
setTimeout(() => {
setCopiedResponse(false)
}, 2000)
}
const handleCopyTrace = () => {
navigator.clipboard.writeText(traceJson)
setCopiedTrace(true)
setTimeout(() => {
setCopiedTrace(false)
}, 2000)
}
return (
<div className={cn('w-full space-y-6 font-sans', className)}>
{/* 1. Pipeline Header */}
<Card className="border-border bg-card shadow-xs">
<CardHeader className="pb-4">
<div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
<div className="space-y-1.5">
<div className="flex flex-wrap items-center gap-2">
<div className="bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg">
<Workflow className="size-4.5" />
</div>
<h2 className="text-foreground text-lg font-semibold tracking-tight sm:text-xl">
enterprise_knowledge_rag_v3
</h2>
<Badge variant="outline" className="border-success/30 bg-success/10 text-success">
<span className="bg-success mr-1.5 size-1.5 rounded-full motion-safe:animate-pulse" />
Pipeline Active
</Badge>
<Badge variant="secondary" className="font-mono text-xs">
p99 {totalPipelineLatency}
</Badge>
</div>
<p className="text-muted-foreground text-sm">
Production Retrieval-Augmented Generation pipeline with HyDE query rewriting, hybrid reciprocal rank
fusion, and cross-encoder validation.
</p>
</div>
<div className="flex flex-wrap items-center gap-2">
<Button
variant="outline"
size="sm"
className="gap-1.5 shadow-xs"
onClick={() => setShowTraceJson(!showTraceJson)}
>
<FileCode className="size-4" />
<span>{showTraceJson ? 'Hide Trace' : 'Export Trace JSON'}</span>
</Button>
<Button size="sm" className="gap-1.5 shadow-xs" disabled={isExecuting} onClick={handleRunPipeline}>
{isExecuting ? (
<RefreshCw className="size-4 motion-safe:animate-spin" />
) : (
<Play className="size-4 fill-current" />
)}
<span>{isExecuting ? 'Executing Pipeline...' : 'Test Query Pipeline'}</span>
</Button>
</div>
</div>
{/* Pipeline Metadata Specs Bar */}
<div className="border-border mt-4 grid grid-cols-2 gap-2 border-t pt-4 text-xs sm:grid-cols-4">
<div className="text-muted-foreground flex items-center gap-2">
<Cpu className="text-primary size-3.5 shrink-0" />
<span className="truncate">
<strong className="text-foreground font-medium">Embedding:</strong> OpenAI text-embedding-3-small ·
1536-dim
</span>
</div>
<div className="text-muted-foreground flex items-center gap-2">
<Database className="text-primary size-3.5 shrink-0" />
<span className="truncate">
<strong className="text-foreground font-medium">Vector DB:</strong> Pinecone Serverless · HNSW
</span>
</div>
<div className="text-muted-foreground flex items-center gap-2">
<Layers className="text-primary size-3.5 shrink-0" />
<span className="truncate">
<strong className="text-foreground font-medium">Index Space:</strong> 482,910 chunks · 4 namespaces
</span>
</div>
<div className="text-muted-foreground flex items-center gap-2">
<ShieldCheck className="text-success size-3.5 shrink-0" />
<span className="truncate">
<strong className="text-foreground font-medium">Grounding:</strong> 100% strict context citation
</span>
</div>
</div>
</CardHeader>
</Card>
{/* Optional Trace JSON Drawer */}
{showTraceJson && (
<Card className="border-border bg-card/95 shadow-xs">
<CardHeader className="pb-2">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Terminal className="text-primary size-4" />
<CardTitle className="text-sm font-medium">OpenTelemetry Pipeline Execution Trace</CardTitle>
</div>
<Button variant="ghost" size="xs" className="gap-1" onClick={handleCopyTrace}>
{copiedTrace ? <Check className="text-success size-3.5" /> : <Copy className="size-3.5" />}
<span>{copiedTrace ? 'Copied JSON' : 'Copy Trace'}</span>
</Button>
</div>
</CardHeader>
<CardContent>
<pre className="bg-muted/70 text-foreground max-h-64 overflow-x-auto rounded-md p-3 font-mono text-xs">
{traceJson}
</pre>
</CardContent>
</Card>
)}
{/* 2. Query Input & Runtime Controls Bar */}
<Card className="border-border bg-card shadow-xs">
<CardContent className="space-y-4 p-4 sm:p-6">
<div className="space-y-2">
<div className="flex items-center justify-between">
<label
htmlFor="rag-query-input-react"
className="text-muted-foreground text-xs font-semibold tracking-wider uppercase"
>
Interactive Test Query
</label>
<span className="text-muted-foreground text-xs">Press Enter or click Test Query to simulate</span>
</div>
<div className="relative flex items-center">
<Input
id="rag-query-input-react"
value={currentQuery}
onChange={(e) => setCurrentQuery(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') handleRunPipeline()
}}
className="pr-20 text-sm font-medium shadow-xs"
placeholder="Enter search prompt or technical query..."
prefixIcon={<Search className="text-muted-foreground size-4" />}
/>
<Button size="xs" className="absolute right-1.5 gap-1" disabled={isExecuting} onClick={handleRunPipeline}>
<Zap className="size-3" />
<span>Run</span>
</Button>
</div>
</div>
{/* Query Presets Chips */}
<div className="flex flex-wrap items-center gap-1.5">
<span className="text-muted-foreground text-xs font-medium">Presets:</span>
{presetQueries.map((preset) => (
<button
key={preset}
type="button"
className={cn(
'focus-visible:ring-ring min-h-6 cursor-pointer rounded-full border px-2.5 py-0.5 text-xs transition-colors focus-visible:ring-2 focus-visible:outline-hidden',
currentQuery === preset
? 'border-primary bg-primary/10 text-primary font-medium'
: 'border-border bg-muted/40 text-muted-foreground hover:bg-muted hover:text-foreground',
)}
onClick={() => handleSelectPreset(preset)}
>
{preset}
</button>
))}
</div>
<Separator />
{/* Controls Toolbar: Top-K Slider + Reranker Switch + Metrics */}
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{/* Top-K Slider */}
<div className="space-y-2">
<div className="flex items-center justify-between">
<div className="flex items-center gap-1.5">
<SlidersHorizontal className="text-primary size-3.5" />
<span className="text-foreground text-xs font-medium">Top-K Chunks</span>
</div>
<Badge variant="secondary" className="font-mono text-xs">
Top {topK} Chunks
</Badge>
</div>
<Slider
value={[topK]}
min={1}
max={3}
step={1}
tooltip={false}
className="w-full"
onValueChange={(val) => setTopK(val[0])}
/>
<div className="text-muted-foreground flex justify-between font-mono text-xs">
<span>k=1</span>
<span>k=2</span>
<span>k=3</span>
</div>
</div>
{/* Reranker Toggle */}
<div className="border-border/80 bg-muted/20 flex flex-col justify-between space-y-2 rounded-lg border p-3">
<div className="flex items-center justify-between">
<div className="space-y-0.5">
<div className="flex items-center gap-1.5">
<Filter className="text-primary size-3.5" />
<span className="text-foreground text-xs font-semibold">Cohere Rerank v3</span>
</div>
<p className="text-muted-foreground text-xs">Cross-encoder contextual re-scoring</p>
</div>
<Switch checked={rerankerEnabled} onCheckedChange={setRerankerEnabled} />
</div>
<div className="flex items-center gap-2">
<Badge
variant={rerankerEnabled ? 'outline' : 'secondary'}
className={cn(
'font-mono text-xs',
rerankerEnabled ? 'border-success/30 bg-success/10 text-success' : 'text-muted-foreground',
)}
>
{rerankerEnabled ? 'Active (+0.142 boost)' : 'Bypassed (Cosine only)'}
</Badge>
</div>
</div>
{/* Pipeline Telemetry Overview */}
<div className="border-border/80 bg-muted/20 flex flex-col justify-between space-y-1.5 rounded-lg border p-3 sm:col-span-2 lg:col-span-1">
<div className="flex items-center justify-between">
<span className="text-foreground text-xs font-semibold">Execution Latency</span>
<span className="text-primary font-mono text-xs font-medium">{totalPipelineLatency} total</span>
</div>
<div className="space-y-1">
<div className="text-muted-foreground flex justify-between text-xs">
<span>Dense + BM25</span>
<span className="font-mono">106ms</span>
</div>
<Progress value={15} className="h-1.5" />
</div>
<div className="space-y-1">
<div className="text-muted-foreground flex justify-between text-xs">
<span>LLM Synthesis</span>
<span className="font-mono">820ms (85%)</span>
</div>
<Progress value={85} className="h-1.5" />
</div>
</div>
</div>
</CardContent>
</Card>
{/* 3. Interactive RAG 5-Stage Architecture Flow */}
<div className="space-y-3">
<div className="flex items-center justify-between">
<div>
<h3 className="text-foreground text-xs font-semibold tracking-wider uppercase">
RAG Pipeline Execution Graph
</h3>
<p className="text-muted-foreground text-xs">
Click any stage node to inspect low-level telemetry, prompt variables, and intermediate embeddings.
</p>
</div>
<Badge variant="outline" className="font-mono text-xs">
5 Connected Stages
</Badge>
</div>
{/* 5-Stage Connected Cards */}
<div className="grid grid-cols-1 gap-2.5 sm:grid-cols-2 lg:grid-cols-5">
{stages.map((stage) => {
const Icon = stage.icon
const isSelected = selectedStageId === stage.id
return (
<div
key={stage.id}
className={cn(
'group focus-visible:ring-ring relative flex cursor-pointer flex-col justify-between rounded-lg border p-3.5 transition-colors focus-visible:ring-2 focus-visible:outline-hidden',
isSelected
? 'border-primary bg-primary/5 ring-primary/40 shadow-xs ring-1'
: 'border-border bg-card hover:border-primary/40 hover:bg-muted/30',
)}
tabIndex={0}
role="button"
aria-pressed={isSelected}
onClick={() => setSelectedStageId(stage.id)}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
setSelectedStageId(stage.id)
}
}}
>
<div className="space-y-2">
<div className="flex items-center justify-between">
<div
className={cn(
'flex size-7 items-center justify-center rounded-md text-xs font-semibold',
isSelected
? 'bg-primary text-primary-foreground'
: 'bg-muted text-foreground group-hover:bg-primary/20 group-hover:text-primary',
)}
>
<Icon className="size-3.5" />
</div>
<Badge
variant="secondary"
className={cn(
'font-mono text-xs',
stage.status === 'bypassed' && 'text-muted-foreground line-through opacity-70',
)}
>
{stage.latency}
</Badge>
</div>
<div>
<p className="text-foreground text-xs leading-tight font-semibold">{stage.name}</p>
<p className="text-muted-foreground mt-1 line-clamp-2 text-xs leading-relaxed">{stage.subtitle}</p>
</div>
</div>
<div className="border-border/60 text-muted-foreground mt-3 flex items-center justify-between border-t pt-2 text-xs">
<span className="truncate font-medium">{stage.tag}</span>
<ChevronRight
className={cn(
'size-3.5 transition-transform',
isSelected ? 'text-primary translate-x-0.5' : 'text-muted-foreground',
)}
/>
</div>
</div>
)
})}
</div>
{/* Stage Detail Drill-down Panel */}
<Card className="border-border bg-card/60 shadow-xs">
<CardHeader className="pb-3">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<div className="flex items-center gap-2">
<div className="bg-primary/10 text-primary flex size-7 items-center justify-center rounded-md">
{React.createElement(currentStage.icon, { className: 'size-4' })}
</div>
<div>
<CardTitle className="text-foreground text-sm font-semibold">
{currentStage.name} — Inspector
</CardTitle>
<CardDescription className="text-xs">{currentStage.details.description}</CardDescription>
</div>
</div>
<Badge variant="outline" className="w-fit font-mono text-xs">
Stage {currentStage.id} of 5 · {currentStage.latency}
</Badge>
</div>
</CardHeader>
<CardContent className="space-y-4 pt-0">
{/* Metrics Grid for Stage */}
<div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
{currentStage.details.metrics.map((metric) => (
<div key={metric.label} className="border-border/80 bg-muted/40 rounded-md border p-2.5">
<p className="text-muted-foreground text-xs">{metric.label}</p>
<p className="text-foreground mt-0.5 truncate font-mono text-xs font-semibold">{metric.value}</p>
</div>
))}
</div>
{/* Code or Data Artifact Preview */}
{currentStage.details.codeOrData && (
<div className="space-y-1.5">
<div className="text-muted-foreground flex items-center justify-between text-xs font-medium">
<span className="flex items-center gap-1.5">
<Code2 className="text-primary size-3.5" />
{currentStage.details.codeOrData.title}
</span>
<span className="font-mono text-xs">read-only buffer</span>
</div>
<pre className="bg-muted/80 text-foreground max-h-40 overflow-x-auto rounded-md p-3 font-mono text-xs leading-relaxed whitespace-pre-wrap">
{currentStage.details.codeOrData.content}
</pre>
</div>
)}
</CardContent>
</Card>
</div>
{/* 4. Retrieved Context Chunks Inspector */}
<div className="space-y-3">
<div className="flex items-center justify-between">
<div>
<h3 className="text-foreground text-xs font-semibold tracking-wider uppercase">
Retrieved Context Chunks ({displayedChunks.length} Active Chunks)
</h3>
<p className="text-muted-foreground text-xs">
Ranked by cross-encoder relevance score. Keyword spans matching user intent are highlighted.
</p>
</div>
<div className="flex items-center gap-2">
<Badge variant="secondary" className="font-mono text-xs">
Fusion: Dense (70%) + Sparse (30%)
</Badge>
</div>
</div>
<div className="space-y-3">
{displayedChunks.map((chunk) => (
<Card
key={chunk.id}
className={cn(
'border-border bg-card shadow-xs transition-colors',
activeCitationHover === chunk.citationIndex && 'border-primary/80 ring-primary/20 bg-primary/5 ring-2',
)}
>
<CardHeader className="p-4 pb-2">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<div className="flex flex-wrap items-center gap-2">
{/* Citation Badge Pill */}
<span
className={cn(
'flex size-6 items-center justify-center rounded-md font-mono text-xs font-bold transition-colors',
activeCitationHover === chunk.citationIndex
? 'bg-primary text-primary-foreground'
: 'bg-muted text-foreground',
)}
>
[{chunk.citationIndex}]
</span>
{/* Relevancy Score Badge */}
<Badge
variant="outline"
className={cn(
'font-mono text-xs font-semibold',
chunk.relevanceScore >= 0.9
? 'border-success/30 bg-success/10 text-success'
: chunk.relevanceScore >= 0.85
? 'border-success/30 bg-success/10 text-success'
: 'border-info/30 bg-info/10 text-info',
)}
>
Score: {rerankerEnabled ? chunk.relevanceScore.toFixed(3) : chunk.cosineScore.toFixed(3)}
</Badge>
{/* Rerank Delta Badge */}
{rerankerEnabled && (
<Badge variant="secondary" className="text-muted-foreground font-mono text-xs">
+{chunk.rerankBoost.toFixed(3)} boost (Rank #{chunk.citationIndex})
</Badge>
)}
{/* Document Path */}
<span className="text-foreground font-mono text-xs font-medium">{chunk.documentPath}</span>
</div>
{/* Metadata & Copy Action */}
<div className="flex items-center gap-2">
<span className="text-muted-foreground hidden font-mono text-xs sm:inline">
{chunk.chunkOffset} · {chunk.tokenCount} tok
</span>
<Button
variant="ghost"
size="xs"
className="text-muted-foreground hover:text-foreground gap-1"
onClick={() => handleCopyChunk(chunk.id, chunk.fullSnippet)}
>
{copiedChunkId === chunk.id ? (
<Check className="text-success size-3" />
) : (
<Copy className="size-3" />
)}
<span className="text-xs">{copiedChunkId === chunk.id ? 'Copied' : 'Copy'}</span>
</Button>
</div>
</div>
</CardHeader>
<CardContent className="p-4 pt-2">
{/* Chunk Text with Highlighted Spans */}
<div className="border-border/70 bg-muted/40 text-foreground rounded-md border p-3 font-mono text-xs leading-relaxed">
<span>{chunk.snippetPrefix}</span>
<mark className="bg-primary/20 text-primary dark:bg-primary/30 rounded px-1 py-0.5 font-semibold">
{chunk.highlightedText}
</mark>
<span>{chunk.snippetSuffix}</span>
</div>
{/* Scoring Breakdown Sub-bar */}
<div className="text-muted-foreground mt-2.5 flex flex-wrap items-center justify-between gap-2 text-xs">
<div className="flex flex-wrap items-center gap-3 font-mono">
<span>
Dense Cosine:{' '}
<strong className="text-foreground font-semibold">{chunk.cosineScore.toFixed(3)}</strong>
</span>
<span>
Sparse BM25:{' '}
<strong className="text-foreground font-semibold">{chunk.bm25Score.toFixed(3)}</strong>
</span>
{rerankerEnabled && (
<span>
Cross-Encoder:{' '}
<strong className="text-success font-semibold">{chunk.relevanceScore.toFixed(3)}</strong>
</span>
)}
</div>
<span className="text-muted-foreground text-xs">Updated {chunk.updatedAgo}</span>
</div>
</CardContent>
</Card>
))}
</div>
</div>
{/* 5. Final Synthesized Output Card with Citations */}
<Card className="border-border bg-card shadow-xs">
<CardHeader className="pb-3">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<div className="flex items-center gap-2">
<div className="bg-primary text-primary-foreground flex size-7 items-center justify-center rounded-md">
<Sparkles className="size-4" />
</div>
<div>
<CardTitle className="text-foreground text-base font-semibold">Synthesized Grounded Response</CardTitle>
<CardDescription className="text-xs">
Generated via Claude 3.5 Sonnet streaming with verified inline citations.
</CardDescription>
</div>
</div>
<div className="flex flex-wrap items-center gap-2">
<Badge variant="outline" className="border-success/30 bg-success/10 text-success font-mono text-xs">
<ShieldCheck className="mr-1 size-3" />
100% Grounded · 0 Hallucinations
</Badge>
<Badge variant="secondary" className="font-mono text-xs">
820ms (TTFT 180ms)
</Badge>
</div>
</div>
</CardHeader>
<CardContent className="space-y-4">
{/* Markdown Formatted Synthesized Body */}
<div className="border-border/80 bg-muted/20 text-foreground space-y-3 rounded-lg border p-4 text-sm leading-relaxed sm:p-5">
<p className="text-foreground font-medium">
To configure OKLCH color palettes in Tailwind CSS v4 with UIPKGE:
</p>
<ol className="text-foreground/90 list-decimal space-y-2.5 pl-5 text-sm">
<li className="leading-relaxed">
<strong>Define Theme Tokens in CSS:</strong> Use{' '}
<code className="bg-muted text-foreground rounded px-1.5 py-0.5 font-mono text-xs">@theme inline</code>{' '}
in your root stylesheet to declare single-source-of-truth OKLCH variables
<button
type="button"
className="bg-primary/10 py-0.2 text-primary hover:bg-primary hover:text-primary-foreground mx-1 inline-flex min-h-6 cursor-pointer items-center rounded px-1 font-mono text-xs font-bold transition-colors"
onMouseEnter={() => setActiveCitationHover(1)}
onMouseLeave={() => setActiveCitationHover(null)}
>
[1]
</button>
. Unlike legacy RGB/HSL, OKLCH ensures perceptually uniform lightness across hue shifts
<button
type="button"
className="bg-primary/10 py-0.2 text-primary hover:bg-primary hover:text-primary-foreground mx-1 inline-flex min-h-6 cursor-pointer items-center rounded px-1 font-mono text-xs font-bold transition-colors"
onMouseEnter={() => setActiveCitationHover(1)}
onMouseLeave={() => setActiveCitationHover(null)}
>
[1]
</button>
.
</li>
<li className="leading-relaxed">
<strong>Calibrate Dark Mode Contrasts:</strong> Anchor chroma and shift lightness along the OKLCH L-axis
(e.g.,{' '}
<code className="bg-muted rounded px-1.5 py-0.5 font-mono text-xs">
--color-primary: oklch(0.65 0.22 260)
</code>{' '}
and{' '}
<code className="bg-muted rounded px-1.5 py-0.5 font-mono text-xs">
--color-border: oklch(0.28 0.01 260)
</code>
) to maintain WCAG AA compliance across both light and dark modes
<button
type="button"
className="bg-primary/10 py-0.2 text-primary hover:bg-primary hover:text-primary-foreground mx-1 inline-flex min-h-6 cursor-pointer items-center rounded px-1 font-mono text-xs font-bold transition-colors"
onMouseEnter={() => setActiveCitationHover(2)}
onMouseLeave={() => setActiveCitationHover(null)}
>
[2]
</button>
.
</li>
<li className="leading-relaxed">
<strong>Maintain Dual-Framework CVA Parity:</strong> Wire CSS tokens directly through Class Variance
Authority (<code className="bg-muted rounded px-1.5 py-0.5 font-mono text-xs">cva()</code>) variants so
that both Vue and React registry components share identical token namespaces with zero runtime bundle
overhead
<button
type="button"
className="bg-primary/10 py-0.2 text-primary hover:bg-primary hover:text-primary-foreground mx-1 inline-flex min-h-6 cursor-pointer items-center rounded px-1 font-mono text-xs font-bold transition-colors"
onMouseEnter={() => setActiveCitationHover(3)}
onMouseLeave={() => setActiveCitationHover(null)}
>
[3]
</button>
.
</li>
</ol>
{/* Streaming cursor pulse */}
<div className="text-muted-foreground flex items-center gap-1.5 pt-1 font-mono text-xs">
<span className="bg-success size-2 rounded-full motion-safe:animate-ping" />
<span>Generation Complete · 214 tokens streamed</span>
</div>
</div>
{/* Citation Footnotes Bar */}
<div className="border-border/70 bg-muted/40 space-y-1.5 rounded-md border p-3 text-xs">
<span className="text-foreground flex items-center gap-1.5 font-semibold">
<BookOpen className="text-primary size-3.5" />
Referenced Citations (Hover citation to locate chunk):
</span>
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-3">
{displayedChunks.map((chunk) => (
<div
key={chunk.id}
className={cn(
'flex cursor-pointer items-center justify-between rounded border p-1.5 font-mono text-xs transition-colors',
activeCitationHover === chunk.citationIndex
? 'border-primary bg-primary/10 text-primary'
: 'border-border/60 bg-card text-muted-foreground hover:bg-muted',
)}
onMouseEnter={() => setActiveCitationHover(chunk.citationIndex)}
onMouseLeave={() => setActiveCitationHover(null)}
>
<span className="truncate">
[{chunk.citationIndex}] {chunk.documentPath.split('/').pop()}
</span>
<span className="font-semibold">{chunk.relevanceScore.toFixed(3)}</span>
</div>
))}
</div>
</div>
{/* Telemetry Footer & Action Buttons */}
<div className="border-border text-muted-foreground flex flex-col gap-3 border-t pt-2 text-xs sm:flex-row sm:items-center sm:justify-between">
<div className="flex flex-wrap items-center gap-3 font-mono">
<span>
Input: <strong className="text-foreground">1,248 tok</strong>
</span>
<span>
Output: <strong className="text-foreground">214 tok</strong>
</span>
<span>
Cost: <strong className="text-foreground">$0.00438</strong>
</span>
<span>
Grounding: <strong className="text-success">99.4%</strong>
</span>
</div>
<div className="flex items-center gap-2">
<div className="border-border bg-card flex items-center rounded-md border p-0.5">
<Button
aria-label="Thumbs up"
variant="ghost"
size="xs"
className={cn('px-2', userFeedback === 'up' && 'text-success')}
onClick={() => setUserFeedback(userFeedback === 'up' ? null : 'up')}
>
<ThumbsUp className="size-3.5" />
</Button>
<Separator orientation="vertical" className="h-4" />
<Button
aria-label="Thumbs down"
variant="ghost"
size="xs"
className={cn('px-2', userFeedback === 'down' && 'text-destructive')}
onClick={() => setUserFeedback(userFeedback === 'down' ? null : 'down')}
>
<ThumbsDown className="size-3.5" />
</Button>
</div>
<Button variant="outline" size="xs" className="gap-1" onClick={handleRunPipeline}>
<RefreshCw className="size-3" />
<span>Regenerate</span>
</Button>
<Button
size="xs"
className="gap-1"
onClick={() =>
handleCopyResponse(
'To configure OKLCH color palettes in Tailwind CSS v4 with UIPKGE: 1. Define Theme Tokens in CSS (@theme inline)... 2. Calibrate Dark Mode Contrasts... 3. Maintain Dual-Framework CVA Parity...',
)
}
>
{copiedResponse ? <Check className="size-3" /> : <Copy className="size-3" />}
<span>{copiedResponse ? 'Copied' : 'Copy Answer'}</span>
</Button>
</div>
</div>
</CardContent>
</Card>
</div>
)
}
export default RagPipelineVisualizer
Raw manifest:https://uipkge.dev/r/react/rag-pipeline-visualizer.json