41 / 122 · Knowledge
Retrieval chunks
The passages a retrieval answer stands on, scored, before the answer itself arrives.
how does draft restore work
Retrieving
Installation
npx shadcn@latest add "@assistant-ui/elements-retrieval-chunks"
Usage
import { RetrievalChunks } from "@/components/elements/retrieval-chunks";
<RetrievalChunks
query="how does draft restore work"
chunks={chunks}
visibleCount={3}
searching={false}
/>Props
RetrievalChunks
query*stringThe text that was embedded and searched.
chunks*RetrievalChunk[]Passages returned above the threshold, already sorted by score.
visibleCount*numberHow many passages have landed so far.
searching*booleanShimmers the status line while the index is still being queried.
classNamestringExtra classes merged onto the root.
RetrievalChunk
id*stringStable identity for the list key.
source*stringWhere the passage came from: a file, a document, a record.
text*stringThe passage itself, clamped to two lines.
locator*stringWhere inside the source the passage sits: a section, a line range, a page.
score*numberSimilarity from 0 to 1. Drives both the printed value and the bar, and turns green at 0.8.
Source
retrieval-chunks.tsx"use client";
import { DatabaseIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { field, mono, paper } from "./surfaces";
export interface RetrievalChunk {
id: string;
source: string;
locator: string;
score: number;
text: string;
}
export function RetrievalChunks({
query,
chunks,
visibleCount,
searching,
className,
}: {
query: string;
chunks: readonly RetrievalChunk[];
visibleCount: number;
searching: boolean;
className?: string;
}) {
return (
<div className={cn("flex w-full max-w-sm flex-col gap-2.5", className)}>
<span
className={cn(
field,
"text-foreground/70 inline-flex w-fit items-center gap-1.5 rounded-full px-3.5 py-2 text-xs",
)}
>
<DatabaseIcon className="text-foreground/40 size-3" />
{query}
</span>
<div className="text-foreground/45 text-xs">
{searching ? (
<span className="relative inline-block leading-none">
<span>Retrieving</span>
<span
aria-hidden
className="shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none"
>
Retrieving
</span>
</span>
) : (
<span className="fade-in animate-in duration-300">
{chunks.length} passages above threshold
</span>
)}
</div>
<div className="flex min-h-[7rem] flex-col gap-1.5">
{chunks.slice(0, visibleCount).map((chunk) => (
<div
key={chunk.id}
className={cn(
paper,
"fade-in slide-in-from-bottom-1 animate-in fill-mode-both flex flex-col gap-1.5 rounded-2xl px-3.5 py-2.5 duration-300",
)}
>
<div className="flex items-baseline gap-2">
<span className="text-foreground/90 min-w-0 flex-1 truncate text-[13px] font-medium">
{chunk.source}
</span>
<span className={cn(mono, "text-foreground/30 shrink-0")}>
{chunk.locator}
</span>
<span
className={cn(
mono,
"shrink-0 tabular-nums",
chunk.score >= 0.8
? "text-emerald-600 dark:text-emerald-400"
: "text-foreground/35",
)}
>
{chunk.score.toFixed(2)}
</span>
</div>
<p className="text-foreground/55 line-clamp-2 text-xs leading-relaxed">
{chunk.text}
</p>
<span className="bg-foreground/[0.06] h-[2px] w-full overflow-hidden rounded-full">
<span
className="block h-full rounded-full bg-blue-500/70 transition-[width] duration-500 dark:bg-blue-400/70"
style={{ width: `${chunk.score * 100}%` }}
/>
</span>
</div>
))}
</div>
</div>
);
}