# Smart Memory

URL: https://cogitator.app/docs/channels/smart-memory

> Three-level memory system with knowledge graph, core facts, and compaction.

## Overview

The smart memory system provides three levels of persistent memory for your assistant, from key-value facts in the system prompt to a knowledge graph and the conversation history. `RuntimeBuilder` sets all three up from `cogitator.yml`.

## Level 1: Core Facts

Key-value pairs that are always included in the system prompt. Store the most important facts about the user here — name, timezone, preferences.

```typescript
import { CoreFactsStore } from '@cogitator-ai/memory';

const coreFacts = new CoreFactsStore({ path: './memory.db' });
await coreFacts.initialize();

await coreFacts.set('user_name', 'Alex');
await coreFacts.set('timezone', 'Europe/Berlin');

const prompt = await coreFacts.formatForPrompt();
// one "key: value" line per fact
```

Core facts are injected into the agent instructions automatically by `RuntimeBuilder` (under "What I know about the user") — re-read for every message, so facts saved during a conversation are visible immediately. The agent saves one with `remember({ fact, isCoreFact: true, coreFactKey })`. `CoreFactsStore` keeps a change history per key (`getHistory(key)`).

## Level 2: Knowledge Graph

Knowledge graph with nodes and relationships, stored in SQLite (or Postgres when `memory.adapter: postgres`). The agent uses `remember`, `recall`, and `forget` tools to interact with it.

```yaml title="cogitator.yml"
memory:
  knowledgeGraph: true
  autoExtract: true
```

### Memory Tools

When `knowledgeGraph` is enabled, three tools are added to the agent:

**remember** — Save a fact to the knowledge graph (optionally also as a core fact)

```
User: "My dog's name is Luna"
Agent calls: remember({ fact: "User's dog is named Luna", category: "pets" })

User: "Call me Alex"
Agent calls: remember({ fact: "Alex", isCoreFact: true, coreFactKey: "user_name" })
```

**recall** — Search memory by query

```
User: "What's my dog's name?"
Agent calls: recall({ query: "dog" })
→ Returns: { results: [{ fact: "User's dog is named Luna", ... }], coreFacts: { ... } }
```

`recall` matches the query against stored fact text (up to 10 results) and always returns all core facts. Pass `embeddingFn` to `createMemoryTools()` to switch it to semantic vector search — `RuntimeBuilder` does not.

**forget** — Delete every fact whose text matches the query

```
User: "Forget everything about my old address"
Agent calls: forget({ query: "address" })
```

### Auto-extraction

When `autoExtract` is enabled, the `AutoExtractMiddleware` runs in the background for each user message and automatically extracts entities and relationships into the knowledge graph (using the assistant's LLM) — without the agent needing to call `remember` explicitly. It needs `knowledgeGraph: true`.

```yaml
memory:
  autoExtract: true
```

## Level 3: Conversation History

Session-based message history stored in the memory adapter (SQLite or Postgres). Each user gets their own session per channel.

### Compaction

When the conversation history grows too long, automatic compaction summarizes older messages to stay within context limits:

```yaml title="cogitator.yml"
memory:
  compaction:
    threshold: 50
```

When a conversation holds at least `threshold` messages, the gateway triggers compaction:

1. Older messages are summarized into a single summary message by the assistant's LLM
2. The 10 most recent messages are kept intact
3. The summary replaces the old messages in the conversation history

Owners can also compact on demand with `/compact`.

## Full Configuration

```yaml title="cogitator.yml"
memory:
  adapter: sqlite # sqlite | postgres
  path: ~/.cogitator/memory.db # sqlite file (also holds core facts in postgres mode)
  connectionString: postgres://user:pass@host/db # postgres (or DATABASE_URL env), needs `pg`
  knowledgeGraph: true # enable knowledge graph + memory tools
  autoExtract: true # auto-extract entities from conversations
  compaction:
    threshold: 50 # messages before compaction triggers
```

## Programmatic Setup

If you're not using `RuntimeBuilder`, you can set up memory manually:

```typescript
import { SQLiteAdapter, SQLiteGraphAdapter, CoreFactsStore } from '@cogitator-ai/memory';
import { Agent, createMemoryTools } from '@cogitator-ai/core';

const memory = new SQLiteAdapter({ provider: 'sqlite', path: './memory.db' });
await memory.connect();

const graph = new SQLiteGraphAdapter({ path: './memory.db' });
await graph.initialize();

const coreFacts = new CoreFactsStore({ path: './memory.db' });
await coreFacts.initialize();

const memoryTools = createMemoryTools({
  graphAdapter: graph,
  coreFacts,
  agentId: 'jarvis',
});

const agent = new Agent({
  name: 'jarvis',
  model: 'google/gemini-3.8-flash',
  tools: [...memoryTools],
  instructions: 'You are a helpful assistant with persistent memory.',
});
```
