Skip to main content

@agentlib/memory

Memory providers for AgentLIB — manage conversation history and context across agent runs.

Installation

npm install @agentlib/memory

Overview

The @agentlib/memory package provides several memory implementations for managing agent conversation history:
  • BufferMemory: Simple in-memory buffer with message limit
  • SlidingWindowMemory: Token-aware sliding window
  • SummarizingMemory: Automatic summarization of old context
  • CompositeMemory: Combine multiple memory strategies
All memory providers implement the MemoryProvider interface from @agentlib/core.

Memory Providers

BufferMemory

Simplest in-process memory that stores messages in a Map keyed by sessionId.
import { BufferMemory } from '@agentlib/memory'
import { createAgent } from '@agentlib/core'

const memory = new BufferMemory({
  maxMessages: 40,  // Keep last 40 messages
  maxTokens: 8000   // Optional token budget
})

const agent = createAgent({
  name: 'assistant',
  memory
})

// Same sessionId → conversation continues
await agent.run({ input: 'Hello', sessionId: 'user-123' })
await agent.run({ input: 'What did I just say?', sessionId: 'user-123' })
Configuration:
interface BufferMemoryConfig {
  /** Maximum number of messages to retain per session (default: 20) */
  maxMessages?: number
  
  /** If set, trim history to fit within this token budget */
  maxTokens?: number
  
  /** Optional pre-populated store for testing */
  defaultStore?: Map<string, ModelMessage[]>
}
Best for:
  • Single-process applications
  • Development and testing
  • Short conversations
  • When you need simple message count limits

SlidingWindowMemory

Token-aware memory that tracks conversation turns (user+assistant pairs) and enforces a token budget.
import { SlidingWindowMemory } from '@agentlib/memory'

const memory = new SlidingWindowMemory({
  maxTokens: 8000,  // Token budget for context window
  maxTurns: 30      // Maximum conversation turns to keep
})

agent.memory(memory)
Configuration:
interface SlidingWindowMemoryConfig {
  /** Maximum token budget for retrieved history (default: 4000) */
  maxTokens?: number
  
  /** Maximum conversation turns to keep (default: 50) */
  maxTurns?: number
}
Features:
  • Automatically groups messages into conversation turns
  • Trims old turns when exceeding maxTurns
  • Applies token budget when reading history
  • Tracks estimated token counts
Usage:
// Check memory statistics
const stats = memory.stats('user-123')
console.log(stats)
// { turns: 15, estimatedTokens: 6420 }
Best for:
  • Production applications with token limits
  • Long conversations
  • When you need precise context window control

SummarizingMemory

Automatically summarizes old conversation context to reduce token usage while preserving key information.
import { SummarizingMemory } from '@agentlib/memory'
import { openai } from '@agentlib/openai'

const memory = new SummarizingMemory({
  model: openai({ apiKey: process.env.OPENAI_API_KEY! }),
  maxTokens: 4000,
  summarizeAfter: 20,  // Summarize when > 20 messages
  keepRecent: 10       // Keep last 10 messages as-is
})

agent.memory(memory)
Configuration:
interface SummarizingMemoryConfig {
  /** Model provider for generating summaries */
  model: ModelProvider
  
  /** Maximum tokens for full history + summary */
  maxTokens?: number
  
  /** Trigger summarization after this many messages */
  summarizeAfter?: number
  
  /** Keep this many recent messages unsummarized */
  keepRecent?: number
  
  /** Custom summarization prompt */
  summaryPrompt?: string
}
How it works:
  1. When message count exceeds summarizeAfter, old messages are summarized
  2. Recent messages (last keepRecent) are kept in full
  3. Summary is injected as a system message
  4. Total tokens stay within maxTokens budget
Best for:
  • Very long conversations
  • When you need to preserve context but minimize tokens
  • Customer support, therapy bots, long-running assistants

CompositeMemory

Combines multiple memory providers with custom merge strategies.
import { CompositeMemory, BufferMemory, SlidingWindowMemory } from '@agentlib/memory'

const shortTerm = new BufferMemory({ maxMessages: 10 })
const longTerm = new SlidingWindowMemory({ maxTokens: 16000 })

const memory = new CompositeMemory({
  providers: [shortTerm, longTerm],
  merge: 'concat',  // or 'dedupe'
  readStrategy: 'parallel'  // or 'sequential'
})

agent.memory(memory)
Configuration:
interface CompositeMemoryConfig {
  /** Array of memory providers to combine */
  providers: MemoryProvider[]
  
  /** How to merge results from multiple providers */
  merge?: 'concat' | 'dedupe'
  
  /** Read providers in parallel or sequential order */
  readStrategy?: 'parallel' | 'sequential'
  
  /** Write to all providers or just the first */
  writeStrategy?: 'all' | 'first'
}
Best for:
  • Hybrid memory strategies
  • Short-term + long-term memory separation
  • Combining in-memory with persistent storage
  • Advanced memory architectures

Common Operations

Session Management

// Different sessions maintain separate histories
await agent.run({ input: 'Hello', sessionId: 'user-1' })
await agent.run({ input: 'Hello', sessionId: 'user-2' })

// No sessionId → uses 'default'
await agent.run({ input: 'Hello' })

Clearing Memory

// Clear specific session
await memory.clear('user-123')

// Clear all sessions
await memory.clear()

Inspecting Memory

// Get raw memory entries
const entries = await memory.entries('user-123')
console.log(entries)
// [{ id: '...', sessionId: 'user-123', messages: [...], metadata: {...} }]

// Get all entries
const allEntries = await memory.entries()

Manual Read/Write

// Read history
const messages = await memory.read({ sessionId: 'user-123' })

// Write messages
await memory.write(
  [{ role: 'user', content: 'Hello' }],
  { sessionId: 'user-123', agentName: 'assistant' }
)

Memory Metadata

All memory entries include metadata:
interface MemoryMetadata {
  createdAt: Date
  accessedAt?: Date
  agentName?: string
  tags?: Record<string, string>
  tokenCount?: number
}

Tagging

// Write with tags
await memory.write(messages, {
  sessionId: 'user-123',
  tags: { category: 'support', priority: 'high' }
})

// Read with tag filter (if provider supports it)
const messages = await memory.read({
  sessionId: 'user-123',
  tags: { category: 'support' }
})

Token Management

Memory providers use utilities from @agentlib/core for token estimation:
import { estimateMessagesTokens, trimToTokenBudget } from '@agentlib/core'

// Estimate tokens
const tokens = estimateMessagesTokens(messages)

// Trim to budget
const trimmed = trimToTokenBudget(messages, 4000)

Best Practices

  1. Choose the right provider:
    • BufferMemory: Simple use cases, development
    • SlidingWindowMemory: Production apps with token limits
    • SummarizingMemory: Very long conversations
    • CompositeMemory: Advanced architectures
  2. Set appropriate limits:
    // For GPT-4o (128k context)
    const memory = new SlidingWindowMemory({ maxTokens: 100000 })
    
    // For GPT-3.5 (16k context)
    const memory = new SlidingWindowMemory({ maxTokens: 12000 })
    
  3. Use session IDs:
    // Per-user sessions
    await agent.run({ input, sessionId: `user-${userId}` })
    
  4. Clear stale sessions:
    // Periodic cleanup
    setInterval(async () => {
      await memory.clear('old-session-id')
    }, 3600000) // Every hour
    

Requirements

  • Node.js: >= 18.0.0
  • Dependencies: @agentlib/core (workspace)

Exports

Classes

  • BufferMemory
  • SlidingWindowMemory
  • SummarizingMemory
  • CompositeMemory

Types

  • BufferMemoryConfig
  • SlidingWindowMemoryConfig
  • SummarizingMemoryConfig
  • CompositeMemoryConfig

Build docs developers (and LLMs) love