v3/implementation/adrs/ADR-006-UNIFIED-MEMORY.md
Status: Implemented Date: 2026-01-03
v2 has 6 memory implementations: MemoryManager, DistributedMemory, SwarmMemory, AdvancedMemoryManager, SQLiteBackend, MarkdownBackend.
Single MemoryService with pluggable backends.
class MemoryService {
constructor(
private backend: IMemoryBackend, // SQLite, AgentDB, or Hybrid
private cache: MemoryCache,
private indexer: MemoryIndexer
) {}
}
// Backend selection via config
{
memory: {
backend: 'hybrid', // 'sqlite' | 'agentdb' | 'hybrid'
cacheSize: 100,
indexing: true
}
}
| Backend | Use Case | Pros | Cons |
|---|---|---|---|
| SQLite | Structured queries, ACID | Fast, reliable | No vector search |
| AgentDB | Semantic search, RAG | Vector similarity | Requires setup |
| Hybrid | General purpose | Best of both | Higher memory |
Memory Service Interface:
interface IMemoryService {
// Core operations
store(entry: MemoryEntry): Promise<string>;
retrieve(id: string): Promise<MemoryEntry | null>;
delete(id: string): Promise<boolean>;
// Query operations
search(query: MemoryQuery): Promise<MemoryEntry[]>;
searchSemantic(text: string, k: number): Promise<MemoryEntry[]>;
// Namespace operations
listNamespaces(): Promise<string[]>;
clearNamespace(namespace: string): Promise<void>;
}
// Memory entry with embedding support
interface MemoryEntry {
id: string;
namespace: string;
content: string;
type: 'episodic' | 'semantic' | 'procedural' | 'working';
metadata?: Record<string, unknown>;
embedding?: Float32Array;
createdAt: Date;
ttl?: number;
}
AgentDB Integration:
class AgentDBBackend implements IMemoryBackend {
private db: AgentDB;
constructor(config: AgentDBConfig) {
this.db = new AgentDB({
dimensions: config.dimensions,
indexType: 'HNSW',
hnswM: 16,
hnswEfConstruction: 200,
});
}
async searchSemantic(embedding: Float32Array, k: number): Promise<MemoryEntry[]> {
// Uses HNSW for 150x-12,500x faster search
return this.db.search(embedding, k);
}
}
Added optimized bulk operations to AgentDBAdapter for 2-3x faster batch processing:
// 4-phase optimized bulk insert
async bulkInsert(entries: MemoryEntry[], options?: { batchSize?: number }): Promise<void> {
// Phase 1: Parallel embedding generation in batches
// Phase 2: Store all entries (skip individual cache updates)
// Phase 3: Batch index embeddings
// Phase 4: Batch cache update (only populate hot entries)
}
// Parallel bulk retrieval
async bulkGet(ids: string[]): Promise<Map<string, MemoryEntry | null>>;
// Batch updates with parallel processing
async bulkUpdate(updates: Array<{ id: string; update: MemoryEntryUpdate }>): Promise<Map<string, MemoryEntry | null>>;
// Parallel deletion
async bulkDelete(ids: string[]): Promise<Map<string, boolean>>;
Performance Improvements:
Promise.all()@claude-flow/[email protected] (published 2026-01-07)Added memory init command to CLI (@claude-flow/[email protected]) using sql.js (WASM SQLite) for cross-platform compatibility without native compilation.
# Initialize memory database
npx @claude-flow/cli@latest memory init
# Options
npx @claude-flow/cli@latest memory init --backend sqlite # Default
npx @claude-flow/cli@latest memory init --path ./data/custom.db
npx @claude-flow/cli@latest memory init --force # Overwrite existing
Schema (6 tables):
| Table | Schema |
|---|---|
memory_entries | id, namespace, key, value, metadata, created_at, updated_at, ttl |
vectors | id, entry_id, embedding (768-dim), norm |
patterns | id, name, pattern_data, confidence, created_at, updated_at |
sessions | id, session_data, started_at, ended_at, status |
trajectories | id, session_id, step, state, action, reward, next_state, created_at |
metadata | key, value, updated_at |
Why sql.js:
better-sqlite3 native binding issuesLocations:
.swarm/memory.db - Primary database.claude/memory.db - Sync location for Claude Code hooksImplementation Date: 2026-01-04 Last Updated: 2026-01-08 Status: ✅ Complete (with CLI init)