Conversation Memory Viz
An interactive visualisation of the sliding-window memory failure mode. Production LLMs that keep "the last N messages" don't forget gracefully — they drop facts the second their source message scrolls off. As 25 turns accumulate, six tracked entities (name, company, project, framework, database, auth provider) get extracted, then silently lost when their introducing message leaves the window.
Three modes:
- Explore — step through one message at a time and watch the entity tracker degrade.
- Predict — answer five "you are the model" questions where you can only see the window.
- Challenge — four multiple-choice diagnostics on the window's failure modes.
A conversation begins. The model's context window holds the last 10 messages.
Conversation Timeline
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Press Step to begin the conversation
Entity Tracker
User name
Company
Project
Framework
Database
Auth provider
A conversation begins. The model's context window holds the last 10 messages.
Customize
Window
10
Installation
npx shadcn@latest add https://craftbits.dev/r/conversation-memory-viz.jsonUsage
import { ConversationMemoryViz } from "@craft-bits/viz/conversation-memory-viz";
<ConversationMemoryViz />Bring your own transcript and entities:
<ConversationMemoryViz
messages={[
{ id: 1, role: "user", text: "I'm Vijay from Acme", entities: [{ key: "name", value: "Vijay" }] },
{ id: 2, role: "user", text: "Working on Project Aurora", entities: [{ key: "project", value: "Project Aurora" }] },
/* … */
]}
entities={[
{ key: "name", label: "User name", sourceMsg: 1, value: "Vijay" },
{ key: "project", label: "Project", sourceMsg: 2, value: "Project Aurora" },
]}
/>Subscribe to score events:
<ConversationMemoryViz
onModeComplete={({ mode, correct, total }) => {
/* lift the new totals into an external chart */
}}
/>Understanding the component
- The timeline. A scrollable strip of 25 numbered bubbles. Squares are user turns, circles are bot turns. A translucent rectangle marks the model's current sliding window; the label
windowsits below it. The current step glows with a focus ring. - The entity tracker. Six rows beneath the timeline track facts the model would extract: name, company, project, framework, database, auth provider. Each row shows a status dot — neutral before discovery, green while the source message is still in the window, red (with a strike-through value and shake animation) the moment that message slides out.
- Predict mode. You see only the window for one specific round and answer a question that requires resolving a fact stated earlier in the conversation. After checking your answer, the viz reveals the message that was lost (with a body-shake animation) and explains why the sliding window failed.
- Challenge mode. Pure multiple-choice diagnostics: "At message 15 with window 10, can the model greet the user by name? How would entity extraction fix this? In a 500-message conversation with window 20, how many of the first 100 messages survive?"
- Reduced motion. Under
prefers-reduced-motion: reduce, every entrance, the window-shift spring, the entity shake on loss, and the mode crossfade collapse to instant transitions.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
messages | readonly ConversationMemoryVizMessage[] | 25-turn project-onboarding transcript | The conversation. Each entry needs id, role, text, optional entities. |
entities | readonly ConversationMemoryVizEntityDef[] | 6 entities | Facts to track. Each needs key, label, sourceMsg, value. |
windowSize | number | 10 | Number of messages the sliding window can hold. |
predictRounds | readonly ConversationMemoryVizPredictRound[] | 5 rounds | "You are the model" rounds for predict mode. |
challengeRounds | readonly ConversationMemoryVizChallengeRound[] | 4 rounds | Multiple-choice rounds for challenge mode. |
defaultMode | "explore" | "predict" | "challenge" | "explore" | Mode visible on first render. |
transition | Transition | SPRINGS.snap | Override the spring for bubble entrances. |
onStepChange | (step: number) => void | — | Fires when the explore-mode step changes. |
onModeChange | (mode) => void | — | Fires when the user switches modes. |
onModeComplete | (score) => void | — | Fires when a predict / challenge run finishes with { mode, correct, total, results }. |
className | string | — | Merged onto the root via cn(). |
Accessibility
- The three mode buttons are a
role="group"witharia-label="Visualization mode"andaria-pressedon the active one. - The conversation timeline is a scrollable
role="region"withtabIndex={0}and anaria-labeldescribing the window range. Every bubble carries anaria-labelthat includes the body text and whether the message is "in window" or "lost from window". - A polite live region (
aria-live="polite") announces the current narration string on every step / mode change. - Mode switches focus the mode-content wrapper so screen readers re-read the new pane.
- Each option button in predict / challenge has
aria-pressed, a visible focus ring, and meets the 40×40 minimum hit area. - Colour is never the only signal — visible/lost counts are also spelled out in text, and lost entities use a strike-through plus a
(msg N)label. - Motion respects
prefers-reduced-motion: reduce— every entrance, the entity shake-on-loss, the lost-message shake reveal, and the mode crossfade collapse to instant transitions.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/systems/ConversationMemoryViz.tsx). The source was a lesson component wired toWidget/useWidgetHistory/ModeStrip/ChallengeBtn/FeedbackBadge/ScoreDotsprimitives in@/lessons/primitives/chrome/*and used per-track palette tokens (--color-accent-400,--color-fail-400,--color-success-400,--color-ink-*) plus CA-specific spring aliases (SPRINGS.snappy,SPRINGS.dramatic,STAGGER.tight,TIMING.wrong.shakeSpring). The craft-bits extract drops the lesson chrome (no widget shell, no undo/redo history — pureuseState), re-keys every colour to the semantic--cb-*palette so consumer themes repaint freely, and routes every transition through the canonicalSPRINGS.snap/SPRINGS.smooth/SPRINGS.bouncy/SPRINGS.slowfrom@craft-bits/core/motion. The mode strip, primary / secondary buttons, feedback badge, score dots, and option list are inlined as private sub-components that consumecb-*tokens. The hard-coded transcript, entities, predict rounds, and challenge rounds are now props with the original 25-turn project-onboarding scenario as the default.forwardRef+cn()+ spread...propswere added to match the library's interactive-component API.