Appearance
Memory
The Lota SDK includes a durable memory system backed by SurrealDB with HNSW vector search and BM25 full-text search. Memory stores extracted facts from conversations and makes them available for future agent turns.
Architecture
User Message -> Agent Turn -> Fact Extraction -> Memory Store
|
v
Vector Embeddings
|
v
Future Turn <- Retrieval Pipeline <- HNSW Search + BM25 + RerankingMemory records are stored in the memory table in SurrealDB. Each record contains:
content-- the fact textembedding-- 1536-dimensional vector (text-embedding-3-small by default)hash-- content hash for deduplication (unique index)scopeId-- namespace for organization or agent-scoped memoriesmemoryType-- classification of the memorydurability-- decay tierimportance-- 0-1 relevance score
Memory Types
| Type | Description |
|---|---|
fact | Concrete business facts, decisions, confirmed truths |
preference | User preferences and formatting choices |
interaction | Conversational patterns |
summary | Condensed summaries |
user_request | Explicit user requests |
entity | Named entities (people, products, companies) |
interest | User interests and topics |
Durability Tiers
| Tier | Description | Use Case |
|---|---|---|
core | No decay. Permanent storage. | Business decisions, architecture, confirmed requirements |
standard | Moderate decay rate. | General facts, inferences |
ephemeral | High decay rate. | Preferences, one-off interactions |
Scopes
Memories are namespaced by scope ID. Two scope patterns exist:
- Organization scope:
org:{orgId}-- shared facts about the organization. - Agent scope:
org:{orgId}:agent:{agentName}-- agent-specific memories visible only to that agent.
When extracting facts from conversation, the SDK writes to both the organization scope and any relevant agent scopes simultaneously.
Fact Extraction
After each chat turn, the memory pipeline:
- Builds a normalized conversation payload from the turn's messages.
- Assesses the conversation's memory importance using a helper model.
- If classified as
transientwithephemeraldurability, the turn is skipped. - Extracts structured facts with confidence scores and durability classifications.
- Classifies each fact against existing memories (new, supersedes, contradicts, enriches, duplicate).
- Writes new facts, updates superseded facts, and creates
memoryRelationedges.
Extraction happens asynchronously via the post-chat-memory queue for onboarding turns and the regular-chat-memory-digest queue for post-onboarding turns.
Search and Retrieval
The retrieval pipeline combines vector search and optional LLM-based reranking:
ts
const { memoryService } = runtime.services
// Search organization memories
const results = await memoryService.searchOrganizationMemories(orgId, query)
// Search agent-scoped memories
const results = await memoryService.searchAgentMemories(orgId, agentName, query)
// Batched multi-scope search with reranking
const results = await memoryService.searchAllMemoriesBatched({
orgId,
agentName: 'cto',
query: 'technical architecture decisions',
fastMode: false,
})The search flow:
- HNSW vector search retrieves candidate memories (default: 12 candidates for 6 results).
- If candidates exceed the result limit, an LLM reranker selects the most relevant items.
- Results are formatted as sectioned text for injection into agent context.
Pre-seeded Memories
High-importance core memories are pre-loaded into agent context at the start of each turn without a query. These are fetched via getTopMemories() and formatted as a <pre-seeded-memories> section.
Memory Blocks
In addition to the global memory system, each workstream has a local memory block -- a structured list of short-term notes accumulated during conversation. See Workstreams for details on memory block compaction.
Memory blocks are:
- Per-workstream, not global
- Role-labeled (e.g.,
chief: ...,cto: ...) - Compacted when entries exceed 15 items
- Injected into agent context alongside the global memory retrieval
Consolidation
A recurring memory-consolidation job runs every 24 hours to maintain memory health:
- Archives stale memories
- Resolves contradictions
- Updates importance scores based on access patterns
Memory Relations
The memoryRelation table stores semantic edges between memories:
| Relation | Description |
|---|---|
contradicts | New fact conflicts with existing memory |
supports | New fact corroborates existing memory |
supersedes | New fact replaces outdated memory |
caused_by | Causal relationship |
depends_on | Dependency relationship |
part_of | Compositional relationship |
implements | Implementation relationship |
Relations are created during fact extraction and used during retrieval to expand context with related memories.