Skip to main content

Fact Integration

Info

Last Updated: 2026-01-13

Facts Throughout the System

Facts are automatically integrated into recall(), search results, and memory enrichment. This page covers advanced patterns for working with extracted facts.

Tip

v0.30.0: Facts now support semantic search via embeddings. When an embedding is available in recall(), facts are searched by semantic similarity, not just keywords.

How Embeddings Work in Batteries-Included Mode​

v0.30.0+: Configure embedding once at SDK initialization for batteries-included semantic search:

import { Cortex } from '@cortexmemory/sdk';

const cortex = new Cortex({
convexUrl: process.env.CONVEX_URL!,
// Configure embedding provider - batteries included!
embedding: {
provider: 'openai',
apiKey: process.env.OPENAI_API_KEY,
model: 'text-embedding-3-small', // optional, this is the default
},
});

// Now every recall() automatically:
// 1. Generates an embedding for the query
// 2. Uses semantic search for both memories AND facts
// No manual embedding code needed!
const result = await cortex.memory.recall({
memorySpaceId: 'user-space',
query: "What are the user's preferences?",
// Embedding is auto-generated from the query!
});

// remember() also auto-generates embeddings for facts
await cortex.memory.remember({
memorySpaceId: 'user-space',
userMessage: "I prefer dark mode",
agentResponse: "Got it!",
// Facts extracted are automatically given embeddings
});

You can also use environment variables for zero-config setup:

# Set these env vars
export CORTEX_EMBEDDING=true
export OPENAI_API_KEY=sk-...
// SDK auto-configures embedding from env vars!
const cortex = await Cortex.create({
convexUrl: process.env.CONVEX_URL!,
});
Looking for Extraction?

See Fact Extraction for how to configure automatic or custom fact extraction from conversations.


Using Facts in Retrieval​

recall() Includes Facts Automatically

recall() searches facts as a primary source, not just enrichment. No extra configuration needed.

// With embedding - uses semantic search for facts (recommended)
const result = await cortex.memory.recall({
memorySpaceId: 'user-space',
query: "What are the user's preferences?",
embedding: await embed("What are the user's preferences?"), // Enables semantic fact search
});

// Facts included automatically in sources
console.log(`Found ${result.sources.facts?.items.length || 0} facts`);

result.sources.facts?.items.forEach(fact => {
console.log(`- ${fact.fact} (${fact.confidence}% confidence)`);
});

// LLM-ready context includes facts
console.log(result.context);
// "## Known Facts
// - User prefers dark mode (95% confidence)
// - User likes TypeScript (88% confidence)
//
// ## Recent Memories
// ..."
Info

v0.30.0+: When embedding is provided, facts are searched semantically—meaning "What colors does the user like?" can find "User prefers purple" even without the word "color" in the fact.

Filter Facts in recall()​

// Get only high-confidence facts
const result = await cortex.memory.recall({
memorySpaceId: 'user-space',
query: 'user preferences',
sources: {
facts: {
minConfidence: 80,
factType: 'preference',
isSuperseded: false, // Current beliefs only
},
},
});

Direct Fact Operations​

await cortex.facts.store({
memorySpaceId: 'user-space',
userId: 'user-123',
fact: 'User prefers TypeScript over JavaScript',
factType: 'preference',
subject: 'user-123',
predicate: 'language_preference',
object: 'TypeScript',
confidence: 90,
sourceType: 'conversation',
tags: ['coding', 'preferences'],
});

Fact Types​

ParameterTypeRequiredDefaultDescription
preferenceFactTypeNo—User likes/dislikes something (e.g., 'User prefers dark mode')
identityFactTypeNo—Who someone is (e.g., 'User is a software engineer')
knowledgeFactTypeNo—Something the user knows (e.g., 'User knows Python')
relationshipFactTypeNo—Connection between entities (e.g., 'User works_at Google')
eventFactTypeNo—Something that happened (e.g., 'User joined on 2025-01-15')
observationFactTypeNo—System-observed behavior (e.g., 'User logs in daily')

Fact Versioning​

Facts are Versioned

When a fact is updated or superseded via belief revision, previous versions are preserved for audit trails.

// Get complete version history
const history = await cortex.facts.getHistory('user-space', factId);

history.forEach(version => {
console.log(`v${version.version}: ${version.fact}`);
console.log(` Confidence: ${version.confidence}%`);
console.log(` Updated: ${new Date(version.updatedAt).toISOString()}`);
});

// Get supersession chain (evolution of belief)
const chain = await cortex.facts.getSupersessionChain(factId);
// Returns: [oldest] -> [older] -> [current]

chain.forEach((entry, i) => {
console.log(`${i + 1}. ${entry.fact}`);
if (entry.supersededBy) {
console.log(` Superseded by: ${entry.supersededBy}`);
}
});

Best Practices​

Extract Atomic Facts
// Bad: Compound fact
{ fact: 'User is 25 years old from California and likes hiking' }

// Good: Atomic facts
[
{ fact: 'User is 25 years old', factType: 'identity' },
{ fact: 'User is from California', factType: 'identity' },
{ fact: 'User likes hiking', factType: 'preference' },
]
Use Consistent Subject IDs
// Always use same format for subject
extractFacts: async (userMsg, agentResp) => [{
fact: 'User prefers email notifications',
subject: userId, // Consistent ID
confidence: 90,
}],
Tag for Organization
{
fact: 'User speaks English and Spanish',
factType: 'knowledge',
tags: ['language', 'communication', 'multilingual'],
}

Next Steps​