Files
Luna/Documentation/References/OpenClaw/Memory SDK.md
T
darman 9929941748 Add project documentation and reference materials
Include Luna AI Assistant design docs covering channels, configuration,
core architecture, memory, scheduler, and skills. Add reference docs
from OpenClaw and ZeroClaw projects, plus Mistral and OpenAI API specs.
2026-04-04 04:14:06 +02:00

9.0 KiB

Memory SDK

OpenClaw's memory system lives in a standalone package (packages/memory-host-sdk) that exposes composable engines for storage, embeddings, query processing, and foundation utilities. The SDK defines a clear host-engine boundary: the host application consumes the SDK surface, while the SDK encapsulates all storage, indexing, and retrieval logic behind exported contracts.


Package Structure

The SDK entry point (engine.ts) re-exports four focused engine modules:

export * from "./engine-foundation.js";
export * from "./engine-storage.js";
export * from "./engine-embeddings.js";
export * from "./engine-qmd.js";

Each engine is a self-contained barrel export covering one concern. New code is directed to the focused subpaths rather than the aggregate surface.


Engine Storage

The storage engine (engine-storage.ts) provides the persistence and retrieval primitives built on SQLite with the sqlite-vec vector extension.

Key Exports

  • MemoryChunk and MemoryFileEntry — the core data types. A chunk is an indexed segment of content with metadata; a file entry represents a source document on disk.
  • buildFileEntry / buildMultimodalChunkForIndexing — constructors for creating index-ready records.
  • chunkMarkdown — splits markdown content into semantically coherent chunks for embedding.
  • cosineSimilarity — vector distance computation for retrieval ranking.
  • parseEmbedding — deserializes stored embedding vectors.
  • ensureMemoryIndexSchema — creates or migrates the SQLite schema (tables, FTS indexes, vector columns).
  • loadSqliteVecExtension — loads the sqlite-vec native extension into the SQLite connection.
  • requireNodeSqlite — resolves the Node.js SQLite driver.
  • readMemoryFile — reads a memory file from disk with safety checks.
  • resolveMemoryBackendConfig — resolves backend-specific configuration (SQLite paths, vector dimensions, etc.).

Storage Architecture

The storage layer uses SQLite as a single-file database with the sqlite-vec extension providing vector column support. Memory chunks are stored alongside their embeddings in the same database, enabling hybrid queries that combine full-text search with cosine vector similarity in a single SQL statement. This mirrors the approach used by ZeroClaw's SQLite backend (see ZeroClaw/Memory).

// Types exported for consumers
type MemoryChunk = { /* chunk content, metadata, embedding vector */ };
type MemoryFileEntry = { /* source file path, hash, modification time */ };
type MemorySearchResult = { /* ranked results with scores and source info */ };

Engine Embeddings

The embeddings engine (engine-embeddings.ts) provides a pluggable embedding provider system with six built-in backends and batch processing utilities.

Embedding Providers

Provider Default Model Module
Local DEFAULT_LOCAL_MODEL embeddings.js
Gemini DEFAULT_GEMINI_EMBEDDING_MODEL embeddings-gemini.js
Mistral DEFAULT_MISTRAL_EMBEDDING_MODEL embeddings-mistral.js
Ollama DEFAULT_OLLAMA_EMBEDDING_MODEL embeddings-ollama.js
OpenAI DEFAULT_OPENAI_EMBEDDING_MODEL embeddings-openai.js
Voyage DEFAULT_VOYAGE_EMBEDDING_MODEL embeddings-voyage.js

Provider Interface

// Core provider contract
type MemoryEmbeddingProvider = {
  name: string;
  // ... embedding computation methods
};

type MemoryEmbeddingProviderAdapter = {
  // Adapts raw provider to the SDK contract
};

// Factory and registry
function getMemoryEmbeddingProvider(name: string): MemoryEmbeddingProvider;
function listMemoryEmbeddingProviders(): string[];

Batch Processing

Three batch helpers handle high-throughput embedding jobs for initial indexing or re-indexing:

  • runGeminiEmbeddingBatches — Gemini-specific batching with rate limit handling.
  • runOpenAiEmbeddingBatches — OpenAI batch API integration (OPENAI_BATCH_ENDPOINT).
  • runVoyageEmbeddingBatches — Voyage AI batch processing.

Safety Utilities

  • enforceEmbeddingMaxInputTokens — truncates input to provider-specific token limits.
  • estimateStructuredEmbeddingInputBytes / estimateUtf8Bytes — byte estimation for payload sizing.
  • hasNonTextEmbeddingParts — detects multimodal content that requires special handling.

Engine Foundation

The foundation engine (engine-foundation.ts) re-exports core utilities from the main OpenClaw application that the memory system depends on. Rather than duplicating logic, the SDK imports these through relative paths to the monorepo src/ directory.

Key Capabilities

  • Agent Scope Resolution: resolveAgentDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveSessionAgentId — determines which agent's memory space to operate on.
  • Memory Search Configuration: resolveMemorySearchConfig with ResolvedMemorySearchConfig type — controls search behavior (result limits, relevance thresholds).
  • Configuration Loading: loadConfig, resolveStateDir — reads OpenClaw configuration and state directories.
  • Session Integration: resolveSessionTranscriptsDirForAgent, onSessionTranscriptUpdate — watches for new conversation transcripts to index into memory.
  • File Safety: writeFileWithinRoot — prevents path traversal when writing memory files.
  • Secrets: hasConfiguredSecretInput, normalizeResolvedSecretInputString — resolves API keys for embedding providers.

Engine QMD (Query Processing)

The QMD engine (engine-qmd.ts) handles query decomposition, keyword extraction, and scope filtering before executing memory searches.

Query Pipeline

  • extractKeywords — pulls meaningful terms from a natural language query, filtering stop words via isQueryStopWordToken.
  • parseQmdQueryJson — parses structured query results (type QmdQueryResult) from the QMD binary.
  • Scope Filtering: deriveQmdScopeChannel, deriveQmdScopeChatType, isQmdScopeAllowed — restricts search results to the appropriate channel and conversation type.
  • Session Files: buildSessionEntry, listSessionFilesForAgent, sessionPathForFile — manages the session transcript files that feed into memory indexing.
  • CLI Integration: checkQmdBinaryAvailability, resolveCliSpawnInvocation, runCliCommand — interfaces with an external QMD binary for query processing.

Integration Pattern

The SDK is consumed by the host application through the aggregate engine.ts export. The boundary is clear:

  • Host responsibility: Decides when to index, when to search, which agent scope to use, and how to present results.
  • SDK responsibility: Handles all storage I/O, embedding computation, vector indexing, query processing, and schema management.

The typical flow:

  1. Initialization: Host calls resolveMemoryBackendConfig to set up the storage backend.
  2. Indexing: Host uses engine-embeddings to generate vectors and engine-storage to persist chunks.
  3. Retrieval: Host uses engine-qmd to process the query, then performs a similarity search via engine-storage.

This separation means the memory engine can be tested independently, and the host can swap backends (e.g., different SQLite configurations, different embedding providers) without changing application logic.


Relevance to Luna

Luna's Memory module defines an IMemoryStore interface but the current file-based implementation only supports writing — there is no recall or search capability.

Patterns to Adopt

  • Composable Engine Architecture: Separating storage, embeddings, and query processing into distinct layers is a clean pattern for Luna. Rather than building a monolithic memory service, Luna could define IMemoryStorage, IEmbeddingProvider, and IQueryProcessor interfaces that compose into a full memory system.
  • SQLite + Vector Extension: Both OpenClaw and ZeroClaw use SQLite with vector extensions for hybrid search. Luna already references SQLite packages — finishing SqliteMemoryStore with this architecture is the natural path.
  • Pluggable Embedding Providers: Luna should support multiple embedding backends from the start. The factory pattern (getMemoryEmbeddingProvider(name)) maps to C# service registration.
  • Batch Processing: For initial indexing or re-indexing of conversation history, batch embedding helpers prevent rate-limiting issues.
  • Query Preprocessing: Keyword extraction and scope filtering before search improves relevance. Luna should implement query expansion as a pipeline step before hitting the vector store.

Key Difference

OpenClaw's SDK is a package boundary within a monorepo — it re-exports from the main src/ tree through barrel files. Luna, as a single compiled application, would implement this as a set of interfaces within a Memory namespace rather than a separate package. The architectural principle (composable engines with clear contracts) translates directly to C# DI registration.