DeepSeek TUI User Memory Custom Context System Prompt: How Persistent Notes Work
DeepSeek TUI's user memory system is an opt-in feature that stores persistent notes in ~/.deepseek/memory.md and automatically injects them into the LLM's system prompt as a <user_memory> XML block on every turn.
DeepSeek TUI implements a persistent user-memory system that allows both users and the model itself to store arbitrary notes which survive across chat sessions. This custom context mechanism, found in the Hmbown/DeepSeek-TUI repository, prepends stored memories to the system prompt, giving the LLM durable context about user preferences and previously noted facts. Unlike ephemeral conversation history, this memory remains constant until explicitly edited or cleared.
Enabling the User Memory System
The feature is disabled by default to minimize token usage. Activation requires either setting [memory] enabled = true in ~/.deepseek/config.toml or exporting the environment variable DEEPSEEK_MEMORY=on. When the engine initializes, it consults these flags in crates/tui/src/core/engine/tool_setup.rs to determine whether to register the remember tool and load the memory file.
You can also customize the storage location via the memory_path configuration key or the DEEPSEEK_MEMORY_PATH environment variable. The default path is ~/.deepseek/memory.md.
How the Memory Block is Constructed
When enabled, the engine calls memory::compose_block(enabled, path) from crates/tui/src/memory.rs to prepare the context segment. This function performs three critical operations:
- File reading: It attempts to read the markdown file at the configured path. If the file is missing or empty, it returns
Noneand no memory block is injected. - Size enforcement: The content is truncated to 100 KiB (
MAX_MEMORY_SIZE) with a "(truncated)" marker appended if the file exceeds this limit. - XML wrapping: Valid content is wrapped in a
<user_memory source="...">...</user_memory>block, creating a machine-readable delimiter that the model can reference.
// From crates/tui/src/memory.rs
let mem_block = memory::compose_block(
config.memory_enabled(),
&config.memory_path(),
);
// Returns Option<String> - None if disabled or file empty
Injecting Memory into the System Prompt
The generated block is prepended to the system prompt alongside the existing <project_instructions> block. This placement ensures the model receives persistent context at the start of every conversation turn. According to the source code in crates/tui/src/core/engine/tool_setup.rs, this injection happens during tool setup, meaning the memory context is present before any user messages are processed.
The 100 KiB size limit protects against token overflow while allowing substantial reference material. When the limit is exceeded, only the most recent content (up to the truncation point) is visible to the model.
Adding and Managing Entries
DeepSeek TUI provides three interfaces for manipulating the memory file without manually editing configuration files.
Quick-Add from the Composer
Typing a line that starts with # in the composer interface automatically appends a timestamped bullet to the memory file. The UI strips the leading # before storage, converting important preference into a dated entry. This logic resides in crates/tui/src/tui/app.rs and executes without creating a new conversation turn.
// Simplified from crates/tui/src/tui/app.rs
fn handle_composer_input(input: &str) {
if let Some(stripped) = input.strip_prefix('#') {
let _ = memory::append_entry(&memory_path, stripped);
}
}
The Remember Tool
The model can autonomously store notes via the remember tool, implemented in crates/tui/src/tools/remember.rs. When the LLM invokes this tool, it passes a note argument which the implementation writes to disk via memory::append_entry.
// From crates/tui/src/tools/remember.rs
pub async fn run(&self, args: RememberArgs) -> ToolResult {
memory::append_entry(&self.memory_path, &args.note)?;
Ok(ToolResult::Message(format!("remembered: {}", args.note)))
}
Slash Commands
The /memory slash command family in crates/tui/src/commands/memory.rs provides direct file manipulation:
/memorydisplays the resolved file path and current contents./memory editprints a command to open the file in$EDITORor$VISUAL./memory clearwipes the file contents without deleting the file itself.
# CLI interaction examples
$ deepseek /memory # Show path and contents
$ deepseek /memory edit # Open in $EDITOR
$ echo "# API key expires 2025-06" >> ~/.deepseek/memory.md
Implementation Architecture
The system is intentionally modular to maintain zero overhead when disabled. The core API in crates/tui/src/memory.rs handles all file I/O, while crates/tui/src/commands/memory.rs manages the user interface layer. The remember tool is conditionally compiled and registered only when the memory feature is enabled, ensuring that builds without the feature flag contain no dead code.
Key constants and defaults:
- Default path:
~/.deepseek/memory.md - Max size: 100 KiB (
MAX_MEMORY_SIZE) - XML tag:
<user_memory source="...">
Summary
- Opt-in activation: Enable via
config.toml[memory]section orDEEPSEEK_MEMORY=onenvironment variable. - Automatic injection: The
memory::compose_blockfunction incrates/tui/src/memory.rsloads and formats notes as XML prepended to the system prompt. - Size limits: Content truncates at 100 KiB to prevent token exhaustion.
- Multiple input methods: Use
#prefix in composer, theremembertool, or/memoryslash commands to update stored context. - Persistent storage: Notes survive application restarts and are readable by the model as
<user_memory>blocks in everyturn.
Frequently Asked Questions
How do I enable the DeepSeek TUI user memory system?
Set [memory] enabled = true in your ~/.deepseek/config.toml file or launch the application with DEEPSEEK_MEMORY=on exported in your environment. The engine checks these settings in crates/tui/src/core/engine/tool_setup.rs before registering the memory tools.
What happens if my memory file exceeds the size limit?
The memory::compose_block function truncates content to 100 KiB (MAX_MEMORY_SIZE) and appends a "(truncated)" marker. This prevents the system prompt from consuming excessive tokens while preserving the most recent entries.
Can the model add to its own memory?
Yes. The remember tool, implemented in crates/tui/src/tools/remember.rs, exposes a run method that the LLM can invoke to append timestamped bullets to ~/.deepseek/memory.md without user intervention.
Where are memory commands handled in the source code?
Slash commands like /memory, /memory edit, and /memory clear are implemented in crates/tui/src/commands/memory.rs, while the quick-add composer functionality (using the # prefix) is handled in crates/tui/src/tui/app.rs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →