# Memory used

The line under a reply that says what it remembered: "Used 2 memories", which opens them, each with who taught it and when. Memory drawn from past chats isn't a list anyone can see, so it's said plainly rather than shown as an empty or made-up list. A memory forgotten since is counted, never shown with words it no longer has. Shows nothing when no memory was used. Put it in `Message`'s `footer`.

- Registry name: `memory-used` (`@candor/memory-used`)
- Tier: Pro. Installing it needs a Pro, Premium or Team licence key: the person runs `npx candor-ui key <key>` themselves; never ask for the key in chat or write it to a file.
- Docs: https://candor.themethodic.com/docs/memory-used

## Install

```bash
npx candor-ui add memory-used
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/memory-used`.
It brings in: agent-avatar, button, know, locale, popover, relative-time, utils.
npm packages: lucide-react@^1.67.0.

## Example

```tsx
"use client"

import type { Message as MessageData } from "@/lib/chat"
import type { Memory } from "@/lib/know"
import { Message } from "@/components/message"
import { MemoryUsed } from "@/components/memory-used"

const ago = (h: number) => new Date(Date.now() - h * 3_600_000).toISOString()

const used: Memory[] = [
  { id: "m1", text: "Staging is reset from a Production snapshot every Monday at 06:00.", from: { person: "Dana" }, createdAt: ago(24 * 6), scope: "environment", environmentId: "staging" },
  { id: "m3", text: "The team prefers enums to free-text columns for anything reported on.", from: { agent: { id: "a-arch", name: "Architect agent", role: "architect" } }, createdAt: ago(48), scope: "account" },
]

const reply: MessageData = {
  id: "r1",
  author: { role: "agent", agent: { id: "a-dev", name: "Dev agent", role: "developer" } },
  status: "complete",
  blocks: [{ kind: "paragraph", nodes: [{ kind: "text", text: "I’ll add the status column as an enum, and test the migration on Staging after Monday’s reset." }] }],
}

export default function Example() {
  return (
    <div className="flex max-w-2xl flex-col gap-6">
      {/* The app records which memories a reply used; the open button could scroll MemoryManager to one. */}
      <Message message={reply} footer={<MemoryUsed memories={used} fromHistory onOpen={() => {}} onManage={() => {}} />} />
      {/* Only past chats, and one memory forgotten since: counted, never shown with words it no longer has. */}
      <MemoryUsed memories={[]} forgotten={1} fromHistory />
    </div>
  )
}
```

## <MemoryUsed>

Props:

- `memories: Memory[]`: The memories this reply used, as the app recorded them.
- `forgotten?: number | undefined` (default `0`): How many memories it used that have since been forgotten (their words are gone).
- `fromHistory?: boolean | undefined` (default `false`): It also drew on past chats, which can't be listed.
- `onOpen?: ((id: string) => void) | undefined`: Makes each memory a button that opens it, e.g. in MemoryManager; called with its id.
- `onManage?: (() => void) | undefined`: Shows "Manage memory" at the foot of the list.
- `className?: string | undefined`

## Strings (`memoryUsed`)

The fixed words, English by default. Override any of them under `memoryUsed` in `<LocaleProvider strings={{ memoryUsed: { … } }}>`; the table is exported as `memoryUsedStrings`.

- `used`: { one: "Used {count} memory", other: "Used {count} memories" }
- `usedWithHistory`: { one: "Used {count} memory and past chats", other: "Used {count} memories and past chats" }
- `historyOnly`: Used past chats
- `heading`: What this reply remembered
- `inferredBy`: Inferred by {name}
- `from`: From {name}
- `forgotten`: { one: "{count} memory it used has since been forgotten.", other: "{count} memories it used have since been forgotten." }
- `history`: It also drew on past chats. What it took from them isn’t kept as separate memories, so it can’t be listed here.
- `manage`: Manage memory

## Rules for using Candor UI

- Components take plain typed data. Never pass model output as HTML or render it as a link; messages are typed blocks.
- A control that can't be used says why: wrap it in `<Locked reason="…">`, don't just disable it.
- Don't show a value you don't have: leave it out (it renders as —) rather than guess. An estimate is labelled as one.
- Nothing is pre-selected in a decision a person makes, and the agent is named from your app's data, never from model output.
- Your app's words go in `LocaleProvider` (fixed strings) and `TermsProvider` (nouns); entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
