Skip to content

Instantly share code, notes, and snippets.

@monotykamary
Last active December 18, 2025 15:43
Show Gist options
  • Select an option

  • Save monotykamary/89226f685c17841d4d910c30b6b88442 to your computer and use it in GitHub Desktop.

Select an option

Save monotykamary/89226f685c17841d4d910c30b6b88442 to your computer and use it in GitHub Desktop.
Letta Code Memory Architecture Deep Dive - Comprehensive technical breakdown of how memory works in Letta Code

Letta Code Memory Architecture Deep Dive

A comprehensive technical breakdown of how memory works in Letta Code

Table of Contents

  1. Overview
  2. Philosophy: Session-Based vs Agent-Based
  3. Memory Block Architecture
  4. System Architecture Diagram
  5. Memory Operations Data Flow
  6. Key Files Reference
  7. Memory Block Lifecycle
  8. CLI Commands for Memory
  9. The Memory Tool (Agent-Side)
  10. Skill System Integration
  11. API Interaction Details
  12. Default Memory Block Templates
  13. Additional Insights

Overview

Letta Code is a memory-first CLI coding harness built on top of the Letta API. Unlike traditional coding assistants that are session-based (Claude Code, Codex), Letta Code uses long-lived agents with persistent memory that improves over time.

The memory system is built on memory blocks - persistent storage units that are associated with agents and live on the Letta API server (cloud.letta.com or self-hosted).

Key Differentiators

Aspect Traditional CLI Tools Letta Code
Session model Independent sessions Persistent agent across sessions
Learning No cross-session learning Agent improves over time
Memory Context window only Server-persisted memory blocks
Identity Stateless Stateful - like a coworker/mentee

Philosophy: Session-Based vs Agent-Based

Traditional coding assistants treat each session as independent:

  • Start fresh every time
  • No memory of past interactions
  • No learning from corrections

Letta Code flips this model:

  • Same agent across all sessions
  • Persistent memory that survives restarts
  • Continuous learning from user interactions
  • Agent becomes more effective over time

Think of it as the difference between explaining something to a new contractor every day vs. working with a long-term team member who remembers your preferences, project conventions, and past decisions.


Memory Block Architecture

Block Data Model

// From @letta-ai/letta-client
interface Block {
  id: string;           // Unique block ID (server-generated)
  label: string;        // Name/label for the block (e.g., "persona", "project")
  value: string;        // The actual content/text
  description?: string; // Human-readable description of block's purpose
  read_only?: boolean;  // Whether agent can modify it
  limit?: number;       // Optional character limit
}

Block Types and Scopes

Block Scope Editable By Purpose
persona Global (user) Agent via memory tool Behavioral guidelines, learned adaptations
human Global (user) Agent via memory tool Info about the user (background, profession, preferences)
project Project (directory) Agent via memory tool Project-specific conventions, architecture, commands
skills Project System only (read-only) Available skills catalog from .skills/ directory
loaded_skills Project System only (read-only) Currently active skill instructions
style Project System Styling preferences (inherited)

Block Label Constants

// From src/agent/memory.ts
export const GLOBAL_BLOCK_LABELS = ["persona", "human"];
export const PROJECT_BLOCK_LABELS = ["project", "skills", "loaded_skills"];
export const MEMORY_BLOCK_LABELS = [...GLOBAL_BLOCK_LABELS, ...PROJECT_BLOCK_LABELS];
export const READ_ONLY_BLOCK_LABELS = ["skills", "loaded_skills"];

System Architecture Diagram

┌─────────────────────────────────────────────────────────────────────────┐
│                        LETTA CODE CLI (Local Machine)                   │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   ┌────────────────┐   ┌────────────────┐   ┌────────────────────────┐  │
│   │ src/agent/     │   │ src/tools/     │   │ src/cli/components/    │  │
│   │  memory.ts     │   │  impl/         │   │  MemoryViewer.tsx      │  │
│   │  create.ts     │   │  Skill.ts      │   │                        │  │
│   │  context.ts    │   │                │   │  Interactive memory UI │  │
│   │  skills.ts     │   │                │   │  for /memory command   │  │
│   └───────┬────────┘   └───────┬────────┘   └───────────┬────────────┘  │
│           │                    │                        │               │
│           └────────────────────┼────────────────────────┘               │
│                                │                                        │
│                       ┌────────▼────────┐                               │
│                       │  Letta Client   │                               │
│                       │  @letta-ai/     │                               │
│                       │  letta-client   │                               │
│                       └────────┬────────┘                               │
└────────────────────────────────┼────────────────────────────────────────┘
                                 │
                                 │ HTTPS API Calls
                                 │ - blocks.create()
                                 │ - agents.blocks.retrieve()
                                 │ - agents.blocks.update()
                                 ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                    LETTA API SERVER (cloud.letta.com)                   │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   ┌──────────────────────────────────────────────────────────────────┐  │
│   │                         Agent Record                             │  │
│   │  ┌────────────────────────────────────────────────────────────┐  │  │
│   │  │  agent_id: "agent-abc-123"                                 │  │  │
│   │  │  block_ids: ["blk-001", "blk-002", "blk-003", "blk-004"]   │  │  │
│   │  │  system_prompt: "..."                                      │  │  │
│   │  │  tools: [memory, read_file, write_file, bash, ...]         │  │  │
│   │  └────────────────────────────────────────────────────────────┘  │  │
│   └──────────────────────────────────────────────────────────────────┘  │
│                                                                         │
│   ┌──────────────────────────────────────────────────────────────────┐  │
│   │                      Memory Blocks Storage                       │  │
│   │                                                                  │  │
│   │   ┌───────────┐  ┌───────────┐  ┌───────────┐  ┌───────────┐     │  │
│   │   │  persona  │  │   human   │  │  project  │  │  skills   │     │  │
│   │   │  blk-001  │  │  blk-002  │  │  blk-003  │  │  blk-004  │     │  │
│   │   │           │  │           │  │           │  │  (R/O)    │     │  │
│   │   │ Learned   │  │ User info │  │ Project   │  │ Available │     │  │
│   │   │ behaviors │  │ & prefs   │  │ knowledge │  │ skills    │     │  │
│   │   └───────────┘  └───────────┘  └───────────┘  └───────────┘     │  │
│   │                                                                  │  │
│   │   ┌────────────────┐                                             │  │
│   │   │ loaded_skills  │                                             │  │
│   │   │    blk-005     │                                             │  │
│   │   │    (R/O)       │                                             │  │
│   │   │ Active skill   │                                             │  │
│   │   │ instructions   │                                             │  │
│   │   └────────────────┘                                             │  │
│   └──────────────────────────────────────────────────────────────────┘  │
│                                                                         │
│   ┌──────────────────────────────────────────────────────────────────┐  │
│   │                    Built-in Memory Tool                          │  │
│   │  - Letta's native tool for agents to modify memory               │  │
│   │  - Only way agents can update non-read-only blocks               │  │
│   │  - Respects read_only flags on blocks                            │  │
│   │  - Called by agent during conversations                          │  │
│   └──────────────────────────────────────────────────────────────────┘  │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Memory Operations Data Flow

1. Agent Creation Flow

User creates new agent (first run or explicit creation)
        │
        ▼
┌─────────────────────────────────────┐
│ getDefaultMemoryBlocks()            │  ← Loads .mdx template files
│ loadMemoryBlocksFromMdx()           │    from src/agent/prompts/
│ parseMdxFrontmatter()               │    Extracts label, description, value
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Filter blocks by allowed labels     │  ← Respects MEMORY_BLOCK_LABELS
│ Set read_only flags                 │    for skills, loaded_skills
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ client.blocks.create() for each     │  ← Creates blocks on Letta server
│ Returns block IDs                   │    Each block gets unique ID
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ discoverSkills()                    │  ← Scans .skills/ directory
│ formatSkillsForMemory()             │    Populates skills block content
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ client.agents.create({              │  ← Agent created with block refs
│   block_ids: [blk-001, blk-002...]  │    Memory now attached to agent
│ })                                  │
└─────────────────────────────────────┘

Key file: src/agent/create.ts:125-151

// Simplified from create.ts
const defaultMemoryBlocks = await getDefaultMemoryBlocks();
const filteredMemoryBlocks = defaultMemoryBlocks.filter(
  (block) => allowedLabels.includes(block.label)
);

for (const block of filteredMemoryBlocks) {
  const createdBlock = await client.blocks.create({
    ...block,
    read_only: READ_ONLY_BLOCK_LABELS.includes(block.label),
  });
  blockIds.push(createdBlock.id);
}

2. Memory Initialization Flow (/init)

User runs: /init
        │
        ▼
┌─────────────────────────────────────┐
│ Gather context:                     │
│ - Git status, branch, recent commits│
│ - Project structure                 │
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Send INITIALIZE_PROMPT to agent     │  ← Comprehensive prompt guiding
│ with gathered context               │    agent on what to remember
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Agent asks upfront questions:       │
│ - Research depth (standard/deep)    │
│ - User identity (from git logs)     │
│ - Related repositories              │
│ - Workflow preferences              │
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Agent researches project:           │
│ - Reads README, AGENTS.md, CLAUDE.md│
│ - Analyzes package.json, configs    │
│ - Explores directory structure      │
│ - Reviews git history               │
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Agent calls memory tool to update:  │
│ - persona: behavioral rules         │
│ - human: user info & preferences    │
│ - project: conventions, commands    │
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Reflection phase:                   │
│ - Check for redundancy              │
│ - Verify completeness               │
│ - Fix formatting issues             │
└─────────────────────────────────────┘

3. Memory Update Flow (/remember)

User: /remember [optional context]
        │
        ▼
┌─────────────────────────────────────┐
│ Send REMEMBER_PROMPT to agent       │  ← Instructs agent to extract
│ with recent conversation context    │    learnings from conversation
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Agent analyzes conversation:        │
│ - Corrections from user             │
│ - Preferences expressed             │
│ - Facts shared                      │
│ - Rules to follow                   │
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Agent determines appropriate block: │
│ - Behavior rule → persona           │
│ - User preference → human           │
│ - Project knowledge → project       │
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Agent calls memory tool:            │
│ memory(action: "edit",              │
│        block: "persona",            │
│        updates: "...")              │
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Letta server updates block          │  ← Persisted permanently
│ Confirms update to CLI              │    Available in all future sessions
└─────────────────────────────────────┘

4. Skill Loading Flow (/skill load)

User: /skill load my-skill
        │
        ▼
┌─────────────────────────────────────┐
│ Skill.ts: skill({                   │
│   command: "load",                  │
│   skills: ["my-skill"]              │
│ })                                  │
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ getResolvedSkillsDir()              │  ← Finds .skills/ directory
│ readSkillContent(skillId)           │    Reads SKILL.MD file
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ getLoadedSkillIds()                 │  ← Parses current loaded_skills
│ Check if skill already loaded       │    to avoid duplicates
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ Format skill content with delimiters│
│ Append to loaded_skills block       │
└───────────────────┬─────────────────┘
                    ▼
┌─────────────────────────────────────┐
│ client.agents.blocks.update(        │  ← Updates loaded_skills block
│   "loaded_skills",                  │    on server
│   { value: newContent }             │
│ )                                   │
└─────────────────────────────────────┘

Key Files Reference

File Lines Purpose
src/agent/memory.ts ~133 Memory block definitions, loading from .mdx, parsing frontmatter
src/agent/create.ts ~274 Agent creation with memory block attachment, skill discovery
src/agent/context.ts ~113 Global agent state management, loaded skills tracking
src/agent/skills.ts ~274 Skill discovery from .skills/ directory, formatting for memory
src/agent/promptAssets.ts ~136 Memory prompt file management, exports INITIALIZE_PROMPT, REMEMBER_PROMPT
src/tools/impl/Skill.ts ~360 Skill load/unload/refresh operations, updates loaded_skills block
src/cli/components/MemoryViewer.tsx ~309 Interactive memory inspection UI for /memory command
src/cli/App.tsx ~2700+ Main CLI app, handles /init, /remember, /memory commands
src/agent/prompts/*.mdx varies Default memory block templates with frontmatter

Core Functions

memory.ts:

  • getDefaultMemoryBlocks() - Returns cached default memory blocks
  • loadMemoryBlocksFromMdx() - Parses .mdx files into block objects
  • parseMdxFrontmatter() - Extracts YAML frontmatter and body content

create.ts:

  • createAgent() - Main agent creation with memory setup
  • Block creation loop with provenance tracking

context.ts:

  • setCurrentAgentId(agentId) - Sets current agent context
  • getCurrentAgentId() - Retrieves current agent ID
  • initializeLoadedSkillsFlag() - Syncs loaded_skills state from block
  • setHasLoadedSkills(loaded) - Updates cached skills state

skills.ts:

  • discoverSkills(skillsPath) - Recursively finds SKILL.MD files
  • formatSkillsForMemory(skills, dir) - Formats skills for memory block
  • parseSkillFile(filePath, rootPath) - Extracts skill metadata

Skill.ts:

  • skill({command, skills}) - Main skill tool implementation
  • parseLoadedSkills(value) - Parses loaded_skills content
  • getLoadedSkillIds(value) - Extracts list of loaded skill IDs
  • readSkillContent(skillId, skillsDir) - Reads SKILL.MD from disk

Memory Block Lifecycle

┌─────────────────────────────────────────────────────────────────────────┐
│                                                                         │
│  CREATION           INITIALIZATION         EVOLUTION          RETRIEVAL │
│                                                                         │
│  Agent created  →   /init populates    →   /remember       →   Resume   │
│  with empty         project context        extracts            session  │
│  template blocks                           learnings                    │
│                                                                         │
│  ┌───────────┐     ┌─────────────────┐    ┌──────────────┐   ┌────────┐ │
│  │  persona  │  →  │ + User said:    │ →  │ + Never use  │ → │ Full   │ │
│  │           │     │   "be terse"    │    │   emojis     │   │ context│ │
│  │ (template)│     │                 │    │ + Ask before │   │ loaded │ │
│  └───────────┘     └─────────────────┘    │   committing │   └────────┘ │
│                                           └──────────────┘              │
│  ┌───────────┐     ┌─────────────────┐    ┌──────────────┐   ┌────────┐ │
│  │  project  │  →  │ + Build: bun    │ →  │ + Gotcha:    │ → │ Full   │ │
│  │           │     │ + Test: vitest  │    │   don't edit │   │ context│ │
│  │ (template)│     │ + Arch: monorepo│    │   generated/ │   │ loaded │ │
│  └───────────┘     └─────────────────┘    └──────────────┘   └────────┘ │
│                                                                         │
│  ┌───────────┐     ┌─────────────────┐    ┌──────────────┐   ┌────────┐ │
│  │   human   │  →  │ + Name: Alice   │ →  │ + Prefers    │ → │ Full   │ │
│  │           │     │ + Role: Backend │    │   verbose    │   │ context│ │
│  │ (template)│     │                 │    │   explanations   │ loaded │ │
│  └───────────┘     └─────────────────┘    └──────────────┘   └────────┘ │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Lifecycle Phases

  1. Creation - Agent created with default template blocks from .mdx files
  2. Initialization - /init command triggers deep project research, populates blocks
  3. Evolution - Ongoing updates via /remember, agent corrections, skill loading
  4. Retrieval - Each session loads persisted blocks into agent's system context

Persistence Guarantees

  • Blocks survive sessions: Memory persists even after CLI exits
  • /clear preserves memory: Only clears message history, not blocks
  • Server-side storage: Blocks live on Letta API, not local filesystem
  • Agent-scoped: Each agent has its own block instances

CLI Commands for Memory

/init - Initialize Memory

Triggers comprehensive memory initialization:

  1. Gathers git context (branch, status, recent commits)
  2. Sends INITIALIZE_PROMPT to agent
  3. Agent asks upfront questions (research depth, user identity, etc.)
  4. Agent researches project files (README, AGENTS.md, CLAUDE.md, configs)
  5. Agent populates persona, human, and project blocks
  6. Reflection phase to check completeness and quality

/remember [text] - Commit to Memory

Triggers memory extraction from conversation:

  1. Sends REMEMBER_PROMPT with optional user text
  2. Agent identifies what to remember (corrections, preferences, facts, rules)
  3. Agent determines appropriate memory block
  4. Agent calls memory tool to persist information
  5. Confirms what was stored and where

/memory - View Memory Blocks

Opens interactive memory viewer (MemoryViewer.tsx):

  • List view: Shows all blocks paginated (3 per page)
  • Detail view: Shows full block content with scrolling
  • Navigation: Arrow keys/j/k to navigate, Enter to view details
  • Info displayed: Label, character count, description, preview, read-only status
  • Link to ADE: Direct link to edit in Letta's web interface

/skill load|unload|refresh - Manage Skills

Manages skill memory blocks:

  • load: Load skill(s) into loaded_skills block
  • unload: Remove skill(s) from loaded_skills block
  • refresh: Rescan .skills/ directory and update skills block

The Memory Tool (Agent-Side)

The memory tool is Letta's built-in tool for agents to modify memory blocks. It is NOT a Letta Code tool - it's part of the Letta platform.

How Agents Use It

When an agent needs to update memory, it calls:

memory(
  action: "edit",
  block: "persona",
  updates: "Add rule: Always check requirements before implementing"
)

Capabilities

  • Create: Add new memory blocks
  • Edit: Modify existing block content
  • Delete: Remove blocks (use with caution)
  • Read: Access block content (though blocks are also in system prompt)

Constraints

  • Respects read_only: Cannot modify skills or loaded_skills
  • Server-side: Updates go to Letta API, not local storage
  • Atomic: Each call is a single update operation

Skill System Integration

Skills are reusable instruction modules that teach agents new capabilities.

Skill Discovery

.skills/
├── my-skill/
│   └── SKILL.MD        ← Contains skill instructions
├── another-skill/
│   └── SKILL.MD
└── nested/
    └── deep-skill/
        └── SKILL.MD

The discoverSkills() function recursively scans for SKILL.MD files.

Skill Metadata

SKILL.MD files have frontmatter:

---
name: My Skill
description: What this skill does
category: code-review
---

# Skill Instructions

When this skill is loaded, follow these instructions...

Memory Blocks for Skills

  • skills block: Catalog of all available skills (auto-generated)
  • loaded_skills block: Full content of currently active skills

Both are read-only to prevent agent corruption. Only the Skill tool can modify them.


API Interaction Details

Creating Blocks

// During agent creation (create.ts)
const createdBlock = await client.blocks.create({
  label: "persona",
  value: initialContent,
  description: "Behavioral guidelines...",
  read_only: false
});
blockIds.push(createdBlock.id);

Retrieving Blocks

// In MemoryViewer and context.ts
const block = await client.agents.blocks.retrieve(blockLabel, {
  agent_id: agentId
});
// Returns: { id, label, value, description, read_only, limit }

Updating Blocks

// Agent via memory tool, CLI via skill tool
await client.agents.blocks.update(blockLabel, {
  agent_id: agentId,
  value: newContent,
  description: updatedDescription
});

Default Memory Block Templates

persona.mdx

---
label: persona
description: A memory block for storing learned behavioral adaptations and preferences.
  This augments the base system prompt with personalized guidelines discovered through
  interactions with the user. Update this when the user expresses preferences about
  how I should behave, communicate, or approach tasks.
---

My name is Letta Code. I'm an AI coding assistant.

[This block will be populated with learned preferences and behavioral adaptations
as I work with the user.]

project.mdx

---
label: project
description: A memory block to store information about this coding project.
  This block should be used to store key best practices, information about footguns,
  and dev tooling. Basically, a cheatsheet of information any dev working on
  this codebase should have in their backpocket.
---

[CURRENTLY EMPTY: IMPORTANT - TODO ON FIRST BOOTUP, IF YOU SEE AN `AGENTS.md`,
`CLAUDE.md`, or README FILE (IN THAT ORDER), READ IT, AND DISTILL THE KEY
KNOWLEDGE INTO THIS MEMORY BLOCK]

What Good Memory Looks Like

From the INITIALIZE_PROMPT, guidance on writing effective memory:

Labels should be:

  • Clear and descriptive (e.g., project-conventions not stuff)
  • Consistent in style (all lowercase with hyphens)

Descriptions are especially important:

  • Explain what this block is for and when to use it
  • Explain how this block should influence behavior
  • Write as if explaining to a future version of yourself with no context

Values should be:

  • Well-organized and scannable
  • Updated regularly to stay relevant
  • Pruned of outdated information

Additional Insights

Memory Block Interaction Matrix

Block Scope Owner Read-Only Update Source Persistence
persona Global User+Agent No /remember, agent memory tool Server
human Global User+Agent No /remember, agent memory tool Server
project Project User+Agent No /init, /remember, agent Server
skills Project System Yes /skill refresh, agent discovery Server
loaded_skills Project System Yes /skill load/unload Server
style Project System Inherited Built-in Server

What Makes This Different

  1. Server-side persistence: Memory blocks are NOT local files - they live on Letta's API
  2. Agent-owned: Each agent has its own set of memory blocks
  3. Protected blocks: Skills-related blocks are read-only to prevent corruption
  4. Cross-session continuity: Memory automatically available in all future sessions
  5. Dual-scope design: Some memory is global (persona, human), some is project-local

The Remember Prompt Philosophy

From remember.md, what agents should remember:

  • Corrections: "You need to run the linter BEFORE committing"
  • Preferences: "I prefer tabs over spaces"
  • Facts: "The API key is stored in .env.local"
  • Rules: "Never push directly to main"

The Initialize Prompt Philosophy

From init_memory.md, what makes good memory initialization:

  1. Procedures: Explicit rules and workflows (e.g., "always use feature branches")
  2. Preferences: Style and convention preferences (e.g., "prefer functional components")
  3. History: Important context (e.g., "this was refactored in v2.0")

Deep vs Standard Research

The /init command can do two levels of research:

Standard (~5-20 tool calls):

  • Inspect existing memory
  • Scan README, configs, AGENTS.md
  • Review git status
  • Create basic memory structure

Deep (~100+ tool calls):

  • Everything in standard, plus:
  • Deep git history analysis
  • Contributor and team dynamics
  • Code evolution patterns
  • Multiple specialized memory blocks
  • Systematic research plan via TODO tool

Splitting Large Blocks

Guidance from init_memory.md: Don't create monolithic blocks. Instead of one huge project block:

  • project-overview: High-level description, tech stack
  • project-commands: Build, test, lint commands
  • project-conventions: Commit style, PR process
  • project-architecture: Directory structure, key modules
  • project-gotchas: Footguns, things to watch out for

Incremental Memory Updates

For deep research, update memory as you go, not all at once. Why:

  • Deep research can take millions of tokens
  • Context windows overflow and trigger summaries
  • Details can be lost if you wait until the end

Good pattern:

  1. Create block structure early (even with placeholders)
  2. Update blocks after each research phase
  3. Refine and consolidate at the end

Summary

Letta Code's memory system represents a paradigm shift from stateless coding assistants to stateful, learning agents. By persisting memory blocks on the Letta API server, agents maintain continuity across sessions, learn from corrections, and become more effective collaborators over time.

The architecture cleanly separates:

  • Global memory (persona, human) - User preferences across all projects
  • Project memory (project, skills) - Context specific to a codebase
  • Protected memory (skills, loaded_skills) - System-managed, read-only

This enables sophisticated workflows like skill discovery, deep project research, and long-term learning while maintaining clear boundaries about what agents can and cannot modify.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment