Skip to main content

Cognitive Memory Guide

Personality-modulated, decay-aware memory grounded in cognitive science: Ebbinghaus forgetting curves, Baddeley's working memory, spreading activation, and HEXACO-driven encoding.


Table of Contents

  1. Overview
  2. Memory Types
  3. Working Memory
  4. Encoding and Retrieval
  5. Spreading Activation
  6. Memory Consolidation
  7. Prospective Memory
  8. Knowledge Graph Integration
  9. Configuration Reference

Overview

Traditional agent memory is a flat vector store: ingest text, embed it, retrieve by similarity. The AgentOS Cognitive Memory System replaces this with a biologically-grounded model where:

  • Encoding strength varies with the agent's HEXACO personality and current PAD mood
  • Forgetting follows the Ebbinghaus exponential decay curve
  • Retrieval scores six signals simultaneously: strength, similarity, recency, emotional congruence, graph activation, and importance
  • Working memory enforces Baddeley's slot-limited capacity (7 ± 2 items, personality-modulated)
  • Consolidation runs as a background sweep that prunes weak traces and merges clusters into schemas

Cognitive Science Foundations

ModelApplication
Atkinson-ShiffrinSensory → working → long-term memory pipeline
Baddeley's working memorySlot-based capacity with activation levels
Tulving's LTM taxonomyEpisodic, semantic, procedural, prospective
Ebbinghaus forgetting curveExponential strength decay over time
Yerkes-Dodson lawEncoding peaks at moderate arousal
PAD emotional modelMood-congruent encoding and retrieval bias
Anderson's ACT-RSpreading activation through memory graph
HEXACO personality modelTrait-driven attention weights and capacity

Memory Types

Based on Tulving's long-term memory taxonomy:

TypeWhat it storesExample
episodicAutobiographical events — specific interactions"User asked about deployment on Tuesday"
semanticGeneral knowledge — learned facts and preferences"User prefers TypeScript over Python"
proceduralSkills and workflows — how-to knowledge"To deploy, run wunderland deploy"
prospectiveFuture intentions — goals and reminders"Remind user about the PR review at 3pm"

Memory Scopes

ScopeVisibilityUse Case
threadSingle conversationIn-conversation working context
userAll conversations with a userUser preferences and history
personaAll users of a personaPersona's accumulated knowledge
organizationAll agents in an orgShared organizational knowledge

Working Memory

Working memory is the agent's active mental workspace — a bounded set of traces currently held in immediate attention.

import { CognitiveMemoryManager } from '@framers/agentos/memory';

const memory = new CognitiveMemoryManager({
workingMemory: {
capacity: 7, // slots (Baddeley's 7 ± 2)
activationDecayRate: 0.1, // per-turn decay of activation
hexacoOpenness: 0.7, // high openness → more slots available
},
});

// The working memory automatically manages activation levels
// Encode a new experience
await memory.encode({
content: 'User mentioned they prefer short responses',
type: 'semantic',
scope: 'user',
scopeId: 'user-123',
source: { type: 'user_statement' },
});

// The lowest-activation trace is evicted to make room
// when capacity is reached — no manual management needed

Inspecting Working Memory

const wm = await memory.getWorkingMemory('user-123');

console.log(wm.slots.length); // number of active items
console.log(wm.utilization); // 0–1 fill ratio
console.log(wm.slots[0]);
// {
// traceId: 'trace-abc',
// content: 'User prefers short responses',
// activation: 0.92,
// slot: 0,
// }

Encoding and Retrieval

Encoding

const trace = await memory.encode({
content: 'User mentioned they are building a Discord bot in TypeScript.',
type: 'episodic',
scope: 'user',
scopeId: 'user-456',
source: {
type: 'user_statement',
sourceId: 'turn-001',
confidence: 0.95,
},
// Optional: override emotion at encoding time
emotionalContext: {
valence: 0.6, // positive (user seemed excited)
arousal: 0.5,
dominance: 0.0,
intensity: 0.3,
gmiMood: 'engaged',
},
});

console.log(trace.id);
console.log(trace.encodingStrength); // 0–1, influenced by personality and mood

Retrieval

const results = await memory.retrieve({
query: 'What does the user prefer for language and framework?',
scopeId: 'user-456',
filters: {
types: ['semantic', 'episodic'],
scope: 'user',
minStrength: 0.2, // filter out nearly-forgotten traces
},
maxResults: 10,
});

for (const result of results) {
console.log(result.content);
console.log(result.compositeScore); // weighted sum of 6 signals
console.log(result.strengthScore); // Ebbinghaus current strength
console.log(result.similarityScore); // vector cosine similarity
console.log(result.recencyScore); // time since last access
}

Retrieval Scoring

The composite score combines six signals with weights that adapt to the agent's personality:

compositeScore =
w_strength * strengthScore + // Ebbinghaus current strength
w_similarity * similarityScore + // vector cosine similarity
w_recency * recencyScore + // time-decay recency
w_emotion * emotionalScore + // mood congruence match
w_activation * activationScore + // graph spreading activation boost
w_importance * importanceScore // manually tagged importance

Spreading Activation

Co-retrieved traces strengthen associations between each other, forming a memory graph where related concepts cluster:

// This happens automatically during retrieval — no API needed.
// After retrieval, edges between co-retrieved traces are strengthened.
// On the next retrieval, strongly associated traces surface together.

// You can inspect the graph directly:
const graph = await memory.getMemoryGraph('user-456');
const neighbors = await graph.neighbors('trace-abc');

console.log(neighbors);
// [
// { traceId: 'trace-def', edgeWeight: 0.82, coRetrievals: 5 },
// { traceId: 'trace-xyz', edgeWeight: 0.44, coRetrievals: 2 },
// ]

Activation mechanics:

  1. A query activates matching traces (vector search)
  2. Activation spreads to their graph neighbors (Hebbian reinforcement)
  3. Reranked results include both direct matches and their associates
  4. Co-retrieved pairs have their edge weight incremented

Memory Consolidation

Consolidation is a periodic background process (like sleep in humans) that:

  • Prunes traces whose strength has decayed below minRetentionStrength
  • Merges semantically similar episodic traces into semantic schemas
  • Resolves contradictions between traces
  • Transfers high-importance episodic memories to semantic store
const memory = new CognitiveMemoryManager({
consolidation: {
enabled: true,
intervalMs: 1000 * 60 * 60, // every hour
minRetentionStrength: 0.05, // prune below this
mergeSimilarityThreshold: 0.85, // merge if > 85% similar
maxTracesPerRun: 500,
},
});

// Trigger consolidation manually (e.g., at session end):
const report = await memory.consolidate('user-456');
console.log(report.pruned); // number of traces removed
console.log(report.merged); // number of clusters merged to schemas
console.log(report.resolved); // number of contradictions resolved

Episodic → Semantic Transfer

After enough episodic encounters, a pattern becomes a semantic fact:

[episodic] "User said 'I prefer TypeScript'" (turn 12)
[episodic] "User said 'let's use TypeScript for this'" (turn 47)
[episodic] "User switched a file from JS to TS unprompted" (turn 83)
↓ consolidation
[semantic] "User strongly prefers TypeScript" (confidence: 0.91)

Prospective Memory

Prospective memory holds future intentions — things the agent should do at a specific time, after a specific event, or when a certain context arises.

import { ProspectiveMemoryManager } from '@framers/agentos/memory/prospective';

const prospective = new ProspectiveMemoryManager({ memoryManager: memory });

// Time-based trigger
await prospective.add({
scopeId: 'user-789',
intention: 'Remind user to review the PR that expires today',
trigger: {
type: 'time',
fireAt: '2026-03-25T15:00:00Z',
},
});

// Event-based trigger
await prospective.add({
scopeId: 'user-789',
intention: 'When user mentions deployment, ask if they want to run tests first',
trigger: {
type: 'event',
eventKey: 'user_mentions_deploy',
},
});

// Context-based trigger
await prospective.add({
scopeId: 'user-789',
intention: 'If user asks about billing, mention the new pricing page',
trigger: {
type: 'context',
contextMatch: 'billing OR pricing OR subscription',
},
});

// Check triggers before each turn
const fired = await prospective.check({
scopeId: 'user-789',
currentContext: 'How do I deploy to production?',
now: new Date(),
});

for (const intention of fired) {
console.log(intention.intention);
// → "When user mentions deployment, ask if they want to run tests first"
}

Knowledge Graph Integration

Memories can be linked to a knowledge graph (Neo4j or in-memory graphology) for rich relational retrieval beyond vector similarity:

const memory = new CognitiveMemoryManager({
knowledgeGraph: {
enabled: true,
adapter: 'neo4j', // or 'graphology' (in-memory)
neo4j: {
uri: process.env.NEO4J_URI,
username: process.env.NEO4J_USERNAME,
password: process.env.NEO4J_PASSWORD,
},
},
});

// Traces with named entities are automatically linked in the graph
// Entity extraction runs during encoding:
await memory.encode({
content: 'Alice works with Bob on the AgentOS project at Frame.dev.',
type: 'semantic',
scope: 'organization',
scopeId: 'org-001',
entities: ['Alice', 'Bob', 'AgentOS', 'Frame.dev'], // or extracted automatically
source: { type: 'observation' },
});

// Graph-augmented retrieval: surfaces traces connected to "Frame.dev"
const results = await memory.retrieve({
query: 'Who works on AgentOS?',
scopeId: 'org-001',
graphHops: 2, // traverse up to 2 hops from matched entities
});

Configuration Reference

import { CognitiveMemoryManager, type CognitiveMemoryConfig } from '@framers/agentos/memory';

const config: CognitiveMemoryConfig = {
// Ebbinghaus decay model
decay: {
enabled: true,
baseDecayRateMs: 7 * 24 * 60 * 60 * 1000, // 7-day half-life
minStrength: 0.01, // floor before pruning
retrievalBoost: 1.5, // stability multiplier on recall
},

// Baddeley's working memory
workingMemory: {
capacity: 7,
activationDecayRate: 0.1,
hexacoOpenness: 0.6, // 0–1, high = more capacity
},

// Retrieval scoring weights (must sum to 1.0)
retrieval: {
weights: {
strength: 0.25,
similarity: 0.30,
recency: 0.15,
emotion: 0.10,
activation: 0.10,
importance: 0.10,
},
maxResults: 20,
minStrength: 0.05,
},

// Consolidation sweep
consolidation: {
enabled: true,
intervalMs: 3_600_000, // hourly
minRetentionStrength: 0.05,
mergeSimilarityThreshold: 0.85,
maxTracesPerRun: 500,
},

// Prospective memory
prospective: {
enabled: true,
checkIntervalMs: 60_000, // check every minute
},

// Vector store backend
vectorStore: {
type: 'hnsw', // 'hnsw' | 'in-memory'
dimensions: 1536,
efSearch: 50,
M: 16,
},

// Optional knowledge graph
knowledgeGraph: {
enabled: false,
adapter: 'graphology',
},
};

const memory = new CognitiveMemoryManager(config);