Elements

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>
  );
}