affectUI › Screens › App screens

Agent / Memory

What your agent knows about you and your work – grouped by where it applies, each with where it came from and where it was used; a memory it recalls lights up while it works, and what it picks up on its own waits for your OK.

Part of affectUI Pro. Install: npx shadcn@latest add https://www.affectui.com/r/agent-memory.json · Import from @/components/ui/agent-memory

When to use

  • Showing what an agent remembers about a person and their work – and letting them correct it, move it to a project or forget it
  • Making memory visible while the agent works: which memory it just used, how often, and for what
  • Asking for consent before the agent keeps something it picked up on its own

When not to use

  • Instructions that apply to every chat (a system prompt) – use Settings / Preferences
  • Files and sources the agent can read – use Folders
  • What waits on a decision – use Agent / Inbox

Usage

import { AgentMemoryScreen } from "@/components/ui/agent-memory";

export default function Page() {
  const [memories, setMemories] = useState(initialMemories);
  return (
    <AgentMemoryScreen
      memories={memories} // a newer usedAt plays the recall sheen on that row
      projects={["Northwind", "Platform", "Evalkit"]}
      onChange={(m) => api.updateMemory(m)}
      onForget={(id) => api.forget(id)}
      onRestore={(m, at) => api.restore(m)}
      onKeep={(id) => api.keep(id)}
      onCreate={(m) => api.remember(m.text, m.project)}
      onOpenSource={(m) => router.push(sourceUrl(m))}
      onNavigate={(label) => router.push(routes[label])}
    />
  );
}

Props

NameTypeDefaultDescription
memories{ id; text; project?; source: { kind: "thread" | "decision" | "told" | "file"; at; quote?; question?; file? }; uses?; usedAt?; usedIn?: { task; how; at }[]; review? }[]Every memory. Without a project it lists under About you and applies everywhere; source is where it came from – your words go in quote, a decision's question in question, a file's name in file; usedIn is where it was used, newest first; review lists it under To review until Keep. Pass a stable array (state): the screen follows it, and when a memory's usedAt moves on, its row lights up
projectsstring[]in the order they appearThe projects, in the order their groups show – and the choices for Applies to
defaultTab"saved" | "review""saved"The list the screen opens with
defaultSelectedstring | null"friday"The memory open on the right when the screen starts
inboxCountnumber5The Inbox count in the sidebar
onSelect(id: string) => voidCalled when a memory is opened
onCreate(memory: AgentMemory) => voidCalled with a memory you added with Remember – source told, at the top of its group
onChange(memory: AgentMemory) => voidCalled with the whole memory when you edit its words or where it applies – and when Undo takes a Keep back (review: true)
onForget(id: string) => voidCalled once a forgotten (or not kept) memory's row has folded away
onRestore(memory: AgentMemory, index: number) => voidCalled when Undo brings it back – index is where it was in the list
onKeep(id: string) => voidCalled with Keep on a memory under To review
onOpenSource(memory: AgentMemory) => voidCalled with Open next to where it came from – without it the screen calls onNavigate("Thread") or onNavigate("Agent Inbox") for a decision
onNavigate(label: string) => voidCalled with the label of a sidebar item
workspacestring"Fieldwork"The workspace in the sidebar
labels{ memory?; saved?; review?; reviewShort?; aboutYou?; everywhere?; remember?; keep?; dontKeep?; forget?; undo?; … }Labels, e.g. for a translation
user{ name: string; avatar?: string }{ name: "Alex Morgan" }Account at the bottom of the sidebar
classNamestringExtra class on the root

Keyboard

  • J / K: Next and previous row – anywhere in the screen, as long as you're not typing
  • ↑ / ↓ / Home / End: In the list: move through the group heads and rows (one Tab stop)
  • Enter / Space: On a row: open the memory on the right. On a group's head: fold or unfold it
  • ← / →: On a group's head: fold, unfold (→ on an open one steps into it). On a row, ← goes to its group's head
  • Delete / Backspace: On a row: forget it – or, under To review, don't keep it; Undo brings it back for five seconds
  • /: Search – Esc clears it, ↓ steps into the results
  • N: Remember something new – Enter saves it and clears the line for the next one, Esc closes it
  • Enter / Esc: In the panel's text: Enter saves your edit, Esc puts the old words back

Accessibility

  • The list is a role="tree": group heads are level-1 items with aria-expanded and their count, rows level-2 items; one Tab stop, the arrow keys move it
  • Every row is named in full – what it knows, where it came from, how often and when it was last used – while the faint columns stay hidden from screen readers
  • Keep and Don't keep on a row are a pointer's shortcuts; the keyboard reaches the same through Enter, then the panel's buttons, or Delete
  • A polite live region says what happened: "Forgotten: …", "Kept – it uses this from now on"
  • Text fields never get a ring – the caret and a firmer edge say it; rings show for the keyboard only and sit inset in the list and the panel
  • Applies to is the App Shell's menu – every item with an icon, the chosen one checked
  • Long text ends in '…' with the full text in a tooltip; right-to-left text reads in its own direction and still starts at the row's glyph

Responsive

  • Fills its container – give it the full viewport height in your app
  • Rows have one fixed height; source, uses and time sit in fixed columns so they line up; below 720px the source column makes room
  • Below 560px each row takes two lines of text and a row opens its memory in the App Shell's sheet from the right
  • Below 400px the search folds to its icon and takes the tabs' place while you type; below 340px To review says Review (labels.reviewShort)
  • Counts stay in their column at any size – 12.5K× in the row, the whole number in the panel; dates from another year carry the year
  • Long lists stay quick: rows are memoized, so moving through a thousand memories only re-renders the two rows that change
  • Touch targets grow to 36px and shortcut hints hide on touch screens
  • Dark mode built in: switches when an ancestor (usually <html>) has the class dark or data-theme="dark"

Requirements

  • React 19
  • @hugeicons/react
  • @hugeicons/core-free-icons
  • App Shell (installed with it)

Related

  • Agent / Tasks – Your work as tasks, not agents – a calm list grouped by project, each row a ring, where it is in words and a small Needs you, and a click opens what happened so far and what it made
  • Agent / Inbox – What your orchestrator needs from you, one question at a time – pick an option, a variant or approve, send it in a keystroke and the next one glides in
  • Agent / Thread – One conversation with your orchestrator – it answers in plain text with small task and decision cards, folds its parallel tools into one line, and keeps working through a dropped connection, a slow upload or a long time away