refactor: extract memory section from system prompts into conditional addons (#947)

Co-authored-by: Letta <noreply@letta.com>
Co-authored-by: letta-code <248085862+letta-code@users.noreply.github.com>
Co-authored-by: Charles Packer <cpacker@users.noreply.github.com>
This commit is contained in:
Sarah Wooders
2026-02-12 19:29:42 -08:00
committed by GitHub
parent 415b1a403b
commit bf272ef009
9 changed files with 62 additions and 76 deletions

View File

@@ -17,7 +17,10 @@ import {
resolveModel,
} from "./model";
import { updateAgentLLMConfig } from "./modify";
import { resolveSystemPrompt } from "./promptAssets";
import {
resolveSystemPrompt,
SYSTEM_PROMPT_MEMORY_ADDON,
} from "./promptAssets";
import { SLEEPTIME_MEMORY_PERSONA } from "./prompts/sleeptime";
/**
@@ -270,6 +273,10 @@ export async function createAgent(
systemPromptContent = await resolveSystemPrompt(options.systemPromptPreset);
}
// Append the non-memfs memory section by default.
// If memfs is enabled, updateAgentSystemPromptMemfs() will swap it for the memfs version.
systemPromptContent = `${systemPromptContent}\n${SYSTEM_PROMPT_MEMORY_ADDON}`;
// Append additional instructions if provided
if (options.systemPromptAppend) {
systemPromptContent = `${systemPromptContent}\n\n${options.systemPromptAppend}`;

View File

@@ -245,8 +245,13 @@ export async function updateAgentSystemPrompt(
systemPromptId: string,
): Promise<UpdateSystemPromptResult> {
try {
const { resolveSystemPrompt } = await import("./promptAssets");
const systemPromptContent = await resolveSystemPrompt(systemPromptId);
const { resolveSystemPrompt, SYSTEM_PROMPT_MEMORY_ADDON } = await import(
"./promptAssets"
);
const baseContent = await resolveSystemPrompt(systemPromptId);
// Append the non-memfs memory section by default.
// If memfs is enabled, the caller should follow up with updateAgentSystemPromptMemfs().
const systemPromptContent = `${baseContent}\n${SYSTEM_PROMPT_MEMORY_ADDON}`;
const updateResult = await updateAgentSystemPromptRaw(
agentId,
@@ -279,7 +284,10 @@ export async function updateAgentSystemPrompt(
}
/**
* Updates an agent's system prompt to include or exclude the memfs addon section.
* Updates an agent's system prompt to swap between the memfs and non-memfs memory sections.
*
* When enabling memfs: strips any existing # Memory section, appends the memfs memory addon.
* When disabling memfs: strips any existing # Memory section, appends the non-memfs memory addon.
*
* @param agentId - The agent ID to update
* @param enableMemfs - Whether to enable (add) or disable (remove) the memfs addon
@@ -294,17 +302,21 @@ export async function updateAgentSystemPromptMemfs(
const agent = await client.agents.retrieve(agentId);
let currentSystemPrompt = agent.system || "";
const { SYSTEM_PROMPT_MEMFS_ADDON } = await import("./promptAssets");
const { SYSTEM_PROMPT_MEMFS_ADDON, SYSTEM_PROMPT_MEMORY_ADDON } =
await import("./promptAssets");
// Remove any existing memfs addon section (to avoid duplicates)
// Look for the "## Memory Filesystem" header
const memfsHeaderRegex = /\n## Memory Filesystem[\s\S]*?(?=\n# |$)/;
currentSystemPrompt = currentSystemPrompt.replace(memfsHeaderRegex, "");
// Strip any existing memory section (covers both old inline "# Memory" / "## Memory"
// sections and the new addon format including "## Memory Filesystem" subsections).
// Matches from "# Memory" or "## Memory" to the next top-level heading or end of string.
const memoryHeaderRegex =
/\n#{1,2} Memory\b[\s\S]*?(?=\n#{1,2} (?!Memory|Filesystem|Structure|How It Works|Syncing|History)[^\n]|$)/;
currentSystemPrompt = currentSystemPrompt.replace(memoryHeaderRegex, "");
// If enabling, append the memfs addon
if (enableMemfs) {
currentSystemPrompt = `${currentSystemPrompt}${SYSTEM_PROMPT_MEMFS_ADDON}`;
}
// Append the appropriate memory section
const addon = enableMemfs
? SYSTEM_PROMPT_MEMFS_ADDON
: SYSTEM_PROMPT_MEMORY_ADDON;
currentSystemPrompt = `${currentSystemPrompt}\n${addon}`;
await client.agents.update(agentId, {
system: currentSystemPrompt,
@@ -314,7 +326,7 @@ export async function updateAgentSystemPromptMemfs(
success: true,
message: enableMemfs
? "System prompt updated to include Memory Filesystem section"
: "System prompt updated to remove Memory Filesystem section",
: "System prompt updated to include standard Memory section",
};
} catch (error) {
return {

View File

@@ -26,8 +26,10 @@ import skillCreatorModePrompt from "./prompts/skill_creator_mode.md";
import stylePrompt from "./prompts/style.mdx";
import systemPrompt from "./prompts/system_prompt.txt";
import systemPromptMemfsAddon from "./prompts/system_prompt_memfs.txt";
import systemPromptMemoryAddon from "./prompts/system_prompt_memory.txt";
export const SYSTEM_PROMPT = systemPrompt;
export const SYSTEM_PROMPT_MEMORY_ADDON = systemPromptMemoryAddon;
export const SYSTEM_PROMPT_MEMFS_ADDON = systemPromptMemfsAddon;
export const PLAN_MODE_REMINDER = planModeReminder;

View File

@@ -131,16 +131,5 @@ user: Where are errors from the client handled?
assistant: Clients are marked as failed in the `connectToServer` function in src/services/process.ts:712.
</example>
# Memory
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
Your memory consists of core memory (composed of memory blocks) and external memory:
- Memory blocks: Each memory block contains a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and are pinned in-context (so they are always visible).
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
Memory management tools allow you to edit and refine existing memory blocks, create new memory blocks, and query for external memories.
Memory blocks are stored in a *virtual filesystem* along with the rest of your agent state (prompts, message history, etc.), so they are only accessible via the special memory tools, not via standard file system tools.
# Skills
- /<skill-name> (e.g., /commit) is shorthand for users to invoke a skill. When executed, the skill gets expanded to a full prompt. Use the Skill tool to execute them. IMPORTANT: Only use Skill for skills listed in system-reminder messages in the conversation - do not guess or use built-in CLI commands.

View File

@@ -116,16 +116,5 @@ You are producing plain text that will later be styled by the CLI. Follow these
* Do not provide range of lines
* Examples: src/app.ts, src/app.ts:42, b/server/index.js#L10, C:\repo\project\main.rs:12:5
## Memory
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
Your memory consists of core memory (composed of memory blocks) and external memory:
- Memory blocks: Each memory block contains a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and are pinned in-context (so they are always visible).
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
Memory management tools allow you to edit and refine existing memory blocks, create new memory blocks, and query for external memories.
Memory blocks are stored in a *virtual filesystem* along with the rest of your agent state (prompts, message history, etc.), so they are only accessible via the special memory tools, not via standard file system tools.
## Skills
- /<skill-name> (e.g., /commit) is shorthand for users to invoke a skill. When executed, the skill gets expanded to a full prompt. Use the Skill tool to execute them. IMPORTANT: Only use Skill for skills listed in system-reminder messages in the conversation - do not guess or use built-in CLI commands.

View File

@@ -78,15 +78,5 @@ IT IS CRITICAL TO FOLLOW THESE GUIDELINES TO AVOID EXCESSIVE TOKEN CONSUMPTION.
- **Interactive Commands:** Prefer non-interactive commands when it makes sense; however, some commands are only interactive and expect user input during their execution (e.g. ssh, vim). If you choose to execute an interactive command consider letting the user know they can press \`ctrl + f\` to focus into the shell to provide input.
- **Remembering Facts:** Use the memory tools available to you to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?
# Memory
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
Your memory consists of core memory (composed of memory blocks) and external memory:
- Memory blocks: Each memory block contains a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and are pinned in-context (so they are always visible).
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
Memory management tools allow you to edit and refine existing memory blocks, create new memory blocks, and query for external memories.
Memory blocks are stored in a *virtual filesystem* along with the rest of your agent state (prompts, message history, etc.), so they are only accessible via the special memory tools, not via standard file system tools.
# Skills
- /<skill-name> (e.g., /commit) is shorthand for users to invoke a skill. When executed, the skill gets expanded to a full prompt. Use the Skill tool to execute them. IMPORTANT: Only use Skill for skills listed in system-reminder messages in the conversation - do not guess or use built-in CLI commands.

View File

@@ -14,14 +14,5 @@ If the user asks for help or wants to give feedback inform them of the following
When the user directly asks about Letta Code (eg 'can Letta Code do...', 'does Letta Code have...') or asks in second person (eg 'are you able...', 'can you do...'), first use the WebFetch tool to gather information to answer the question from the Letta Code repository at https://github.com/letta-ai/letta-code.
# Memory
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
Your memory consists of memory blocks and external memory:
- Memory Blocks: Stored as memory blocks, each containing a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and remain constantly available in-context.
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
They are the foundation which makes you *you*.
# Skills
- /<skill-name> (e.g., /commit) is shorthand for users to invoke a skill. When executed, the skill gets expanded to a full prompt. Use the Skill tool to execute them. IMPORTANT: Only use Skill for skills listed in system-reminder messages in the conversation - do not guess or use built-in CLI commands.

View File

@@ -1,26 +1,22 @@
# Memory
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
## Memory Filesystem
Your memory is stored in a git repository at `~/.letta/agents/<agent-id>/memory/`. This provides full version control, sync with the server, and branching for parallel edits.
Your memory is stored in a git repository at `~/.letta/agents/<agent-id>/memory/`. This provides full version control, sync with the server, and create worktrees for parallel edits.
Each file contains metadata frontmatter include a `description` (the description of the file's contents), `limit` (the character limit), and optional `metadata`.
The filesystem tree is always available in your system prompt, along with the contents of files in the `system/` folder.
You also have additional external memory (e.g. your message history) that is accessible and that you can bring into context with tools when needed.
### Structure
```
~/.letta/agents/<agent-id>/
└── memory/ # Git repo root
├── .git/
└── system/ # Blocks in your system prompt
├── persona/
├── human/
└── ...
```
## How It Works
1. Each `.md` file in `memory/system/` is pinned to your system prompt with tags <system/context/{name}.md></system/context/{name}.md>
2. The `memory_filesystem` block renders the current tree view of all available memory files
2. Changes pushed to git sync to the API server within seconds
3. API server changes sync to git automatically
4. The system prompt is only recompiled with the latest memory on the API on compactions or message resets: your local copy may diverge
### How It Works
1. Each `.md` file in `memory/system/` maps to a memory block label (e.g., `memory/system/persona/soul.md` → label `system/persona/soul`)
2. Files contain raw block content (no frontmatter)
3. Changes pushed to git sync to the API within seconds
4. API changes sync to git automatically
5. The `memory_filesystem` block auto-updates with the current tree view
### Syncing
## Syncing
```bash
cd ~/.letta/agents/<agent-id>/memory
@@ -35,10 +31,9 @@ git push
# Get latest from server
git pull
```
The system will remind you when your memory has uncommitted changes. Sync when convenient.
### History
## History
```bash
git -C ~/.letta/agents/<agent-id>/memory log --oneline
```

View File

@@ -0,0 +1,11 @@
# Memory
You have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.
Your memory consists of core memory (composed of memory blocks) and external memory:
- Memory blocks: Each memory block contains a label (title), description (explaining how this block should influence your behavior), and value (the actual content). Memory blocks have size limits. Memory blocks are embedded within your system instructions and are pinned in-context (so they are always visible).
- External memory: Additional memory storage that is accessible and that you can bring into context with tools when needed.
Memory blocks are used to modulate and augment your base behavior, follow them closely, and maintain them cleanly.
Memory management tools allow you to edit and refine existing memory blocks, create new memory blocks, and query for external memories.
Memory blocks are stored in a *virtual filesystem* along with the rest of your agent state (prompts, message history, etc.), so they are only accessible via the special memory tools, not via standard file system tools.