Letta + Fable 5: Persistent Memory for Multi-Week Projects
Give Fable 5 a memory that survives restarts via Letta's structured memory blocks, so a project runs for weeks, not one session.
Run this workflow
CI-verified, 5/5 fixtures passing.
Build this with your agent
One copy-paste hands Claude Code, Codex, or Cursor the full recipe, steps included, nothing to fetch.
Intended Use
A multi-week build where the agent should keep notes across sessions: Letta gives Fable structured memory blocks it reads and rewrites over time. CI verifies the deterministic spine: the agent config dict is valid, model equals anthropic/claude-fable-5, and the human and persona memory blocks are present and non-empty. No key. The agent's recall and self-editing are the fenced model step.
Not for
- Skipping a running Letta server (self-hosted or Letta Cloud, hence the LETTA_API_KEY)
- Assuming Anthropic provider support without checking your Letta version (model strings follow Letta's provider/model convention)
- Letting memory blocks drift; prune them over time
The Stack
Tested Against
letta-client@latestclaude-fable-5Side effects & data flow
- Network
- none, local only
- Writes
- ./letta-agent.json, ./checkletta.mjs
- Credentials
- none required
Prerequisites
- Python (pip install letta-client)
- A running Letta server (self-hosted or Letta Cloud) and LETTA_API_KEY
- An Anthropic API key for anthropic/claude-fable-5
Steps
- 1
Create a Letta agent on Fable with memory blocks
pip install letta-client. Then client.agents.create(model='anthropic/claude-fable-5', memory_blocks=[{label:'human', value:'...'}, {label:'persona', value:'...'}]). The agent reads and rewrites those blocks over time, so it remembers across restarts.
- 2
What CI checks: the agent config is valid and names Fable
CI confirms the agent config dict is valid, model equals anthropic/claude-fable-5, and the required human and persona memory blocks are present and non-empty. Deterministic, no key. The recall and self-editing are fenced.
cat > letta-agent.json <<'EOF' { "model": "anthropic/claude-fable-5", "memory_blocks": [ { "label": "human", "value": "Lead engineer migrating a monolith to services." }, { "label": "persona", "value": "I am a long-horizon coding agent. I keep notes and update them." } ] } EOF cat > checkletta.mjs <<'EOF' import { readFileSync } from 'node:fs'; const cfg = JSON.parse(readFileSync('letta-agent.json', 'utf8')); let ok = true; function check(label, cond){ console.log(label + ': ' + (cond ? 'yes' : 'NO')); if(!cond) ok=false; } check('agent config parses', true); check('model is anthropic/claude-fable-5', cfg.model === 'anthropic/claude-fable-5'); const blocks = cfg.memory_blocks || []; const by = Object.fromEntries(blocks.map(b => [b.label, (b.value || '').trim()])); check('human memory block present and non-empty', !!by.human && by.human.length > 0); check('persona memory block present and non-empty', !!by.persona && by.persona.length > 0); if(!ok){ console.log('letta agent config check FAILED'); process.exit(1); } console.log('letta agent config check OK: anthropic/claude-fable-5 + human/persona blocks'); EOF node checkletta.mjs - 3
Run it across sessions (the model step, not checked by CI)
Send messages over days or weeks; Fable recalls and updates its memory blocks. That runs the model and is non-deterministic, so CI never claims it. The badge covers the agent config, not the recall.
Eval, 5 fixtures
Last passed: verified todaynames-fablecontainstimeout 30s · max $0Expected:
model is anthropic/claude-fable-5: yeshuman-blockcontainstimeout 30s · max $0Expected:
human memory block present and non-empty: yespersona-blockcontainstimeout 30s · max $0Expected:
persona memory block present and non-empty: yescheck-okcontainstimeout 30s · max $0Expected:
letta agent config check OK: anthropic/claude-fable-5 + human/persona blocksclean-exitexit_codetimeout 30s · max $0Expected:
0
Results
~23.2k stars; persistent file-based memory improved Fable's Slay-the-Spire result 3x more than it did for Opus 4.8.
Did this work for you?
Our CI checks the setup runs. You tell us if the whole thing worked. Tell us straight.
Liked this workflow?
Get new verified workflows in WebAfterAI, three issues a week (Tue, Thu, Sat).