Cogitator
Memory & RAG

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:

StrategyBehavior
recentFills context with the most recent entries that fit
relevantSelects entries by semantic similarity to current input
hybridReserves 30% for semantically relevant older entries, 70% recent

Choosing an Adapter

AdapterPersistenceSpeedEmbeddingsFactsBest For
InMemoryNoneFastestNoNoTesting, short-lived agents
RedisTTL-basedFastNoNoShort-term memory with auto-expiry
PostgresPermanentGoodpgvectorYesProduction with full features
SQLitePermanentFastNoNoSingle-process, local apps
MongoDBPermanentGoodNoNoDocument-oriented workloads
QdrantPermanentFastNativeNoDedicated 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/memory

Optional 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   # Qdrant

Redis uses the @cogitator-ai/redis package which is included automatically.

On this page