Skip to main content
The Memory trait defines the interface for all persistence backends in ZeroClaw. Implement this trait to integrate new storage systems like databases, vector stores, or custom memory solutions.

Trait Definition

Required Methods

name

Return the backend name.
&str
Stable lowercase identifier (e.g., “sqlite”, “markdown”, “qdrant”)

store

Store a memory entry.
&str
required
Unique identifier for this memory entry
&str
required
Memory content (text, JSON, or any string data)
MemoryCategory
required
Memory category for organization:
  • MemoryCategory::Core - Long-term facts, preferences, decisions
  • MemoryCategory::Daily - Daily session logs
  • MemoryCategory::Conversation - Conversation context
  • MemoryCategory::Custom(String) - User-defined category
Option<&str>
Optional session identifier to scope the memory
anyhow::Result<()>
Success or error

recall

Recall memories matching a query (keyword or semantic search).
&str
required
Search query string
usize
required
Maximum number of results to return
Option<&str>
Optional session filter
Vec<MemoryEntry>
Array of matching memory entries, ranked by relevance

get

Get a specific memory by key.
&str
required
Memory key to retrieve
anyhow::Result<Option<MemoryEntry>>
Memory entry if found, or None

list

List all memory entries with optional filters.
Option<&MemoryCategory>
Filter by category (all categories if None)
Option<&str>
Filter by session (all sessions if None)
anyhow::Result<Vec<MemoryEntry>>
Array of matching memory entries

forget

Remove a memory by key.
&str
required
Memory key to remove
anyhow::Result<bool>
true if memory was deleted, false if not found

count

Count total memories.
anyhow::Result<usize>
Total number of memory entries

health_check

Check if the memory backend is healthy.
bool
true if backend is operational

Optional Methods

reindex

Rebuild embeddings for all memories using the current embedding provider.
Option<Box<dyn Fn(usize, usize) + Send + Sync>>
Optional callback for progress updates: (current, total)
anyhow::Result<usize>
Number of memories reindexed
Default: Returns error “Reindex not supported”. Use case: Call after changing embedding model to ensure vector search works correctly.

Types

MemoryEntry

MemoryCategory

Display format:
  • Core"core"
  • Daily"daily"
  • Conversation"conversation"
  • Custom("notes")"notes"
Serialization: Uses snake_case (e.g., "core", "daily", "conversation").

Implementation Example

Here’s a simplified in-memory backend:

Vector Search Example

For vector-based semantic search (SQLite with embeddings, Qdrant, etc.):

Factory Registration

Register your memory backend in the factory:

Best Practices

Concurrent Access: Use proper locking (RwLock, Mutex) for in-memory backends or rely on database transaction isolation for persistence.
Search Quality: For keyword search, implement fuzzy matching and stemming. For semantic search, use embeddings with cosine similarity.
Session Isolation: Always respect session_id filters to prevent data leakage between sessions.
Performance: Index frequently queried fields (key, category, session_id, timestamp) for faster lookups.
Vector Reindexing: Implement reindex() for vector-based backends to support model migration.

Testing