OpenFang’s memory substrate provides a unified API over three specialized storage backends, all backed by a single SQLite database. Agents interact with a single Memory trait that abstracts over structured KV storage, semantic search, and knowledge graphs.
The entire memory system is synchronous at the storage layer (SQLite) but exposed via async APIs to the runtime. This allows non-blocking I/O while maintaining ACID guarantees.
The structured store is a simple key-value store scoped by agent ID:
// Writememory.set(agent_id, "last_report_date", json!("2025-03-06")).await?;// Readlet value = memory.get(agent_id, "last_report_date").await?;assert_eq!(value, Some(json!("2025-03-06")));// List all keys for an agentlet all_kv = memory.list_kv(agent_id).await?;// Deletememory.delete(agent_id, "last_report_date").await?;
Use Cases
Agent state: Counters, flags, timestamps
Hand metrics: Dashboard metrics (e.g., reports_count)
Configuration overrides: Per-agent settings
Cached results: Expensive computations that don’t need semantic recall
Schema
CREATE TABLE kv_store ( agent_id TEXT NOT NULL, key TEXT NOT NULL, value TEXT NOT NULL, -- JSON serialized updated_at TEXT NOT NULL, PRIMARY KEY (agent_id, key));
memory.store( agent_id, "The user prefers concise explanations without jargon.", MemorySource::UserPreference).await?;memory.store( agent_id, "Company XYZ launched a new product on 2025-03-01.", MemorySource::WebSearch).await?;
Memory sources tag where the information came from:
pub enum MemorySource { UserMessage, // Extracted from user input AgentResponse, // Generated by the agent ToolResult, // Returned by a tool call WebSearch, // Fetched from the web UserPreference, // Explicit user settings SystemNote, // Internal annotations}
This computes cosine similarity between the query vector and all stored fragment vectors, returning the top K matches.
Schema
CREATE TABLE memory_fragments ( id TEXT PRIMARY KEY, agent_id TEXT NOT NULL, content TEXT NOT NULL, embedding BLOB, -- Optional: serialized f32 vector source TEXT NOT NULL, -- MemorySource enum importance REAL DEFAULT 1.0, access_count INTEGER DEFAULT 0, created_at TEXT NOT NULL, last_accessed_at TEXT NOT NULL, FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE);CREATE VIRTUAL TABLE memory_fts USING fts5(content, agent_id);
Embedding generation is not required — OpenFang falls back to full-text search (SQLite FTS5) if no driver is configured. Embeddings improve recall quality but add latency and cost.
Returns all (Person) -[works_for]-> (OpenAI) matches.
Schema
CREATE TABLE entities ( id TEXT PRIMARY KEY, agent_id TEXT NOT NULL, entity_type TEXT NOT NULL, name TEXT NOT NULL, attributes TEXT, -- JSON created_at TEXT NOT NULL, FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE);CREATE TABLE relations ( id TEXT PRIMARY KEY, agent_id TEXT NOT NULL, from_entity_id TEXT NOT NULL, relation_type TEXT NOT NULL, to_entity_id TEXT NOT NULL, properties TEXT, -- JSON created_at TEXT NOT NULL, FOREIGN KEY (from_entity_id) REFERENCES entities(id) ON DELETE CASCADE, FOREIGN KEY (to_entity_id) REFERENCES entities(id) ON DELETE CASCADE);