# Memory mode

Whether agents use memory: on, paused or off, with what each does to the memories already kept. Paused never reads as deleted: it says the memories stay. What off does depends on the app, so it says what you tell it (`whenOff`), and an off that deletes asks first and offers pausing instead. The mode shown is the one the app last reported; while a change is on its way it says so.

- Registry name: `memory-mode` (`@candor/memory-mode`)
- 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-mode

## Install

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

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/memory-mode`.
It brings in: button, know, locale, locked, utils.

## Example

```tsx
"use client"

import * as React from "react"
import type { MemoryModeValue } from "@/lib/know"
import { MemoryMode } from "@/components/memory-mode"

export default function Example() {
  // The mode shown is the one the app reports; here the "app" reports the change after a moment.
  const [mode, setMode] = React.useState<MemoryModeValue>("on")
  const [count, setCount] = React.useState(12)
  const [pending, setPending] = React.useState(false)
  const change = (next: MemoryModeValue) => {
    setPending(true)
    setTimeout(() => {
      setMode(next)
      if (next === "off") setCount(0)
      setPending(false)
    }, 600)
  }
  return (
    <div className="flex max-w-md flex-col gap-8">
      {/* In this app, turning memory off deletes it, so Off asks first and offers pausing instead. */}
      <MemoryMode mode={mode} whenOff="deleted" count={count} pending={pending} onChange={change} />
      <MemoryMode mode="paused" whenOff="kept" count={12} locked="Your workspace’s policy sets memory for everyone." />
    </div>
  )
}
```

## <MemoryMode>

Props:

- `mode?: MemoryModeValue | undefined`: The mode the app last reported. Undefined while it hasn't said.
- `whenOff: "kept" | "deleted"`: What turning memory off does to existing memories in your app: they're "kept", or "deleted" (asks first).
- `count?: number | undefined`: How many memories are kept now, if known. Shown on paused and off, and in the delete question.
- `onChange?: ((mode: MemoryModeValue) => void) | undefined`: Asks for a change. Show the new mode once the app reports it (`mode`).
- `pending?: boolean | undefined` (default `false`): A change is on its way.
- `error?: string | undefined`: Why the last change failed, if it did. Pass "" for no reason.
- `locked?: string | undefined`: Why memory can't be changed here: a policy, a role.
- `className?: string | undefined`

## Strings (`memoryMode`)

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

- `label`: Memory
- `on`: On
- `onDetail`: Agents use what’s remembered and can save new memories.
- `paused`: Paused
- `pausedDetail`: Agents don’t use or save memories for now. Existing memories are kept as they are, and used again when memory is back on.
- `off`: Off
- `offKeptDetail`: Agents don’t use or save memories. Existing memories are kept until you forget them.
- `offDeletedDetail`: Agents don’t use or save memories, and existing memories are deleted. This can’t be undone.
- `kept`: { one: "{count} memory kept", other: "{count} memories kept" }
- `confirmTitle`: Turn memory off and delete what’s remembered?
- `confirmCount`: { one: "This deletes {count} memory, and it can’t be undone. Pausing keeps it instead.", other: "This deletes {count} memories, and it can’t be undone. Pausing keeps them instead." }
- `confirmNoCount`: This deletes every memory, and it can’t be undone. Pausing keeps them instead.
- `confirm`: Turn off and delete
- `pauseInstead`: Pause instead
- `cancel`: Keep “{mode}”
- `changing`: Changing…
- `failed`: Memory didn’t change: {reason}
- `failedNoReason`: Memory didn’t change.
- `unknown`: Not reported

## 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`.
