43 / 122 · Knowledge
Memory
What it now remembers about you, written during the turn and removable.
memory
Prefers TypeScriptWorks in a pnpm monorepo
Installation
npx shadcn@latest add "@assistant-ui/elements-memory-chips"
Usage
import { MemoryChips } from "@/components/elements/memory-chips";
<MemoryChips chips={chips} onForget={forget} />Props
MemoryChips
chips*MemoryChip[]What is remembered. Anything not marked existing is counted as new this turn and tinted.
onForget(id: string) => voidCalled to drop a fact. Every chip is removable, including ones it just learned.
classNamestringExtra classes merged onto the root.
MemoryChip
id*stringStable identity, reported back by onForget.
text*stringThe remembered fact, in the assistant's words.
change*"added" | "updated" | "existing"existing is neutral; added and updated are tinted and counted in the header.
Source
memory-chips.tsx"use client";
import { BrainIcon, XIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { field, ghostButton, mono } from "./surfaces";
export type MemoryChange = "added" | "updated" | "existing";
export interface MemoryChip {
id: string;
text: string;
change: MemoryChange;
}
export function MemoryChips({
chips,
onForget,
className,
}: {
chips: readonly MemoryChip[];
onForget?: (id: string) => void;
className?: string;
}) {
const fresh = chips.filter((chip) => chip.change !== "existing").length;
return (
<div className={cn("flex w-full max-w-sm flex-col gap-2", className)}>
<div className="flex items-center gap-1.5">
<BrainIcon className="text-foreground/30 size-3.5" />
<span className={cn(mono, "text-foreground/35")}>
{fresh > 0 ? `remembered ${fresh}` : "memory"}
</span>
</div>
<div className="flex flex-wrap gap-1.5">
{chips.map((chip) => (
<span
key={chip.id}
className={cn(
"fade-in zoom-in-95 animate-in fill-mode-both group flex items-center gap-1 rounded-full py-1 pr-1 pl-2.5 text-xs duration-300",
chip.change === "existing"
? cn(field, "text-foreground/55")
: "bg-blue-500/12 text-blue-700 dark:bg-blue-400/15 dark:text-blue-300",
)}
>
{chip.text}
<button
type="button"
aria-label={`Forget "${chip.text}"`}
onClick={() => onForget?.(chip.id)}
className={cn(ghostButton, "size-4")}
>
<XIcon className="size-2.5" />
</button>
</span>
))}
</div>
</div>
);
}