Memory Overview
Understand how Cogitator agents persist context across conversations using pluggable memory adapters, embeddings, and knowledge graphs.
Why Memory Matters
LLMs are stateless. Every request starts from scratch unless you explicitly pass conversation history. As conversations grow, they exceed context window limits. Memory solves this by persisting, indexing, and intelligently retrieving past interactions.
Cogitator's memory system gives agents:
- Conversation persistence across sessions via threads and entries
- Semantic search over past messages using vector embeddings
- Fact storage for long-term knowledge (user preferences, learned info)
- Knowledge graphs for structured entity and relationship tracking
- Token-aware context building that fits the most relevant history into the model's context window
Architecture
┌─────────────────────────────────────────────────────┐
│ ContextBuilder │
│ Assembles messages, facts, and semantic context │
│ within a token budget │
├──────────┬──────────────┬───────────────┬────────────┤
│ MemoryAdapter │ FactAdapter │ EmbeddingAdapter │ GraphAdapter │
│ (threads + │ (long-term │ (vector search) │ (entities + │
│ entries) │ facts) │ │ relations) │
├──────────┴──────────────┴───────────────┴────────────┤
│ InMemory │ Redis │ Postgres │ SQLite │
│ MongoDB │ Qdrant │
└─────────────────────────────────────────────────────┘Every adapter implements the same MemoryAdapter interface. You can swap backends without changing application code.
Core Concepts
Threads
A Thread represents a conversation session. Each thread belongs to an agent and holds an ordered list of memory entries.
import { InMemoryAdapter } from '@cogitator-ai/memory';
const memory = new InMemoryAdapter();
await memory.connect();
const { data: thread } = await memory.createThread('agent-1', {
topic: 'onboarding',
});Memory Entries
A MemoryEntry stores a single message along with token count and optional tool call data.
await memory.addEntry({
threadId: thread.id,
message: { role: 'user', content: 'Hello!' },
tokenCount: 3,
});
await memory.addEntry({
threadId: thread.id,
message: { role: 'assistant', content: 'Hi there! How can I help?' },
tokenCount: 8,
});
const { data: entries } = await memory.getEntries({
threadId: thread.id,
limit: 50,
});Facts
Facts are long-term memories that persist across threads. They represent user preferences, learned information, or system-level knowledge. Only PostgresAdapter implements FactAdapter.
const postgres = new PostgresAdapter({
provider: 'postgres',
connectionString: process.env.DATABASE_URL!,
});
await postgres.connect();
await postgres.addFact({
agentId: 'agent-1',
content: 'User prefers dark mode',
category: 'preference',
confidence: 0.95,
source: 'user',
});Context Building
The ContextBuilder assembles the final message list sent to the LLM. It respects token limits by selecting the most relevant entries from memory.
import { ContextBuilder } from '@cogitator-ai/memory';
const builder = new ContextBuilder(
{
maxTokens: 8192,
strategy: 'recent',
includeSystemPrompt: true,
includeFacts: true,
includeSemanticContext: true,
},
{
memoryAdapter: memory,
factAdapter: postgres,
embeddingAdapter: postgres,
embeddingService: embeddings,
}
);
const context = await builder.build({
threadId: thread.id,
agentId: 'agent-1',
systemPrompt: 'You are a helpful assistant.',
currentInput: 'What were we discussing yesterday?',
});Three context strategies are available:
| Strategy | Behavior |
|---|---|
recent | Fills context with the most recent entries that fit |
relevant | Selects entries by semantic similarity to current input |
hybrid | Reserves 30% for semantically relevant older entries, 70% recent |
Choosing an Adapter
| Adapter | Persistence | Speed | Embeddings | Facts | Best For |
|---|---|---|---|---|---|
| InMemory | None | Fastest | No | No | Testing, short-lived agents |
| Redis | TTL-based | Fast | No | No | Short-term memory with auto-expiry |
| Postgres | Permanent | Good | pgvector | Yes | Production with full features |
| SQLite | Permanent | Fast | No | No | Single-process, local apps |
| MongoDB | Permanent | Good | No | No | Document-oriented workloads |
| Qdrant | Permanent | Fast | Native | No | Dedicated vector search |
For most production deployments, Postgres is the recommended adapter since it supports threads, facts, embeddings, and keyword search in a single backend.
Installation
pnpm add @cogitator-ai/memoryOptional peer dependencies based on your adapter choice:
pnpm add pg # Postgres
pnpm add better-sqlite3 # SQLite
pnpm add mongodb # MongoDB
pnpm add @qdrant/js-client-rest # QdrantRedis uses the @cogitator-ai/redis package which is included automatically.