Memory Storage
Memory Storage in Astreus is a hierarchical memory system that provides powerful conversation history management with adaptive context management. The enhanced system features intelligent AI-powered summarization, automatic context layer management, and smart frequency tracking across immediate, summarized, and persistent memory layers with intelligent token budgeting.
Hierarchical Memory Architecture
The Memory Storage system uses a three-layer architecture for optimal context management:
- Immediate Layer: Recent messages (40% of token budget)
- Summarized Layer: AI-powered conversation summaries (35% of token budget)
- Persistent Layer: Long-term important facts (25% of token budget)
- Intelligent Summarization: AI-powered summarization with simple fallback when provider unavailable
- Automatic Context Loading: Smart loading of context layers from database storage
- Adaptive Context: Automatic context window management with intelligent compression
- Session-Based Organization: Conversations organized by session ID
- Automatic Message Storage: Messages saved during
agent.chat()
andagent.chat({ stream: true })
- Direct Memory Access: Full memory operations through
agent.getMemory()
- Semantic Search: Optional vector embeddings for content search
- Priority-Based Retention: Important content stays longer based on multiple factors
Memory Through Agents
Access memory operations directly through your agent:
import { createAgent, createProvider, createMemory, createDatabase } from '@astreus-ai/astreus';
async function setupAgentWithMemory() {
const db = await createDatabase();
// Create memory with advanced features including adaptive context
const memory = await createMemory({
database: db,
tableName: "conversations",
maxEntries: 200,
enableEmbeddings: true, // Enable semantic search
enableAdaptiveContext: true, // Enable adaptive context management
tokenBudget: { // Custom token budget allocation
total: 4000,
immediate: 1600, // 40% for recent messages
summarized: 1400, // 35% for summaries
persistent: 1000 // 25% for persistent data
}
});
const provider = createProvider({
type: 'openai',
model: 'gpt-4o-mini'
});
// Create agent with memory
const agent = await createAgent({
name: 'MemoryAgent',
provider: provider,
memory: memory,
systemPrompt: "You are a helpful assistant with perfect memory."
});
return agent;
}
// Use agent memory operations
const agent = await setupAgentWithMemory();
// Automatic memory storage during chat
await agent.chat({
message: "Remember that I like coffee",
sessionId: "preferences",
metadata: { category: 'personal_preferences' },
stream: true,
onChunk: (chunk) => console.log(chunk)
});
// Direct memory access
const history = await agent.getHistory("preferences");
console.log(`Found ${history.length} messages`);
Session Management
Agents provide built-in session management for organizing conversations:
Session Operations
// List all sessions with metadata
const sessions = await agent.listSessions(20);
sessions.forEach(session => {
console.log(`Session: ${session.sessionId}`);
console.log(`Messages: ${session.messageCount}`);
console.log(`Last message: ${session.lastMessage}`);
console.log(`Last activity: ${session.lastActivity}`);
console.log(`Metadata:`, session.metadata);
});
// Get specific session history
const history = await agent.getHistory("session-123", 50);
history.forEach(msg => {
console.log(`${msg.role}: ${msg.content}`);
console.log(`Metadata:`, msg.metadata);
});
// Clear a session
await agent.clearHistory("old-session");
Manual Memory Management
Add custom entries to memory for context or system messages:
// Add system context
await agent.addToMemory({
sessionId: "user-preferences",
role: 'system',
content: "User prefers detailed technical explanations",
metadata: {
type: 'preference',
category: 'communication_style',
timestamp: new Date()
}
});
// Add user context
await agent.addToMemory({
sessionId: "project-discussion",
role: 'user',
content: "Working on a React application with TypeScript",
metadata: {
project: 'web_app',
technologies: ['react', 'typescript'],
context: 'project_setup'
}
});
// Add assistant notes
await agent.addToMemory({
sessionId: "troubleshooting",
role: 'assistant',
content: "Issue resolved by updating dependencies",
metadata: {
resolution: 'dependency_update',
issue_type: 'build_error',
resolved: true
}
});
Direct Memory Access
For advanced operations, access the memory instance directly:
// Get memory instance from agent
const memory = agent.getMemory();
// Advanced memory operations
const agentMemories = await memory.getByAgent(agent.id, 100);
console.log(`Agent has ${agentMemories.length} total memories`);
// Search by text content
const searchResults = await memory.searchByText("machine learning", 5);
searchResults.forEach(result => {
console.log(`Found: ${result.content}`);
console.log(`Session: ${result.sessionId}`);
});
// Search by embedding (if enabled)
if (memory.config.enableEmbeddings) {
const embedding = [0.1, 0.2, 0.3, 0.4, 0.5]; // 1536-dimensional vector for OpenAI
const similarResults = await memory.searchByEmbedding(embedding, 5, 0.8);
similarResults.forEach(result => {
console.log(`Similarity: ${result.similarity}`);
console.log(`Content: ${result.content}`);
});
}
// Get specific memory entry
const entry = await memory.getById("memory-id-123");
if (entry) {
console.log('Found entry:', entry.content);
}
// Delete specific entries
await memory.delete("memory-id-to-delete");
Memory Configuration
Configure memory when creating agents:
// Basic memory configuration
const basicMemory = await createMemory({
database: db,
tableName: "basic_conversations",
maxEntries: 100
});
// Advanced memory with embeddings
const advancedMemory = await createMemory({
database: db,
tableName: "advanced_conversations",
maxEntries: 500,
enableEmbeddings: true
});
// Create agents with different memory configurations
const basicAgent = await createAgent({
name: 'BasicAgent',
provider: provider,
memory: basicMemory
});
const advancedAgent = await createAgent({
name: 'AdvancedAgent',
provider: provider,
memory: advancedMemory
});
Memory Configuration Options
Option | Type | Description | Default |
---|---|---|---|
database | DatabaseInstance | Database for persistence | Required |
tableName | string | Table name for memory storage | "memories" |
maxEntries | number | Max entries per session | 100 |
enableEmbeddings | boolean | Enable semantic search | false |
enableAdaptiveContext | boolean | Enable adaptive context management with AI analysis | false |
tokenBudget | TokenBudgetConfig | Token allocation across layers | Default budget |
priorityWeights | PriorityWeights | Priority weights for content retention | Default weights |
defaultCompressionStrategy | CompressionStrategy | Default compression strategy | SUMMARIZE |
Adaptive Context Management
When enableAdaptiveContext
is true, the memory system automatically manages context across three hierarchical layers:
// Enable adaptive context with custom configuration
const adaptiveMemory = await createMemory({
database: db,
tableName: "adaptive_conversations",
maxEntries: 300,
enableAdaptiveContext: true,
tokenBudget: {
total: 6000,
immediate: 3000, // 50% for recent messages
summarized: 2000, // 33% for summaries
persistent: 1000 // 17% for persistent data
},
priorityWeights: {
recency: 0.4, // Prioritize recent messages
frequency: 0.1, // Less weight to frequency
importance: 0.4, // High importance weight
userInteraction: 0.1,
sentiment: 0.0 // Ignore sentiment
}
});
const agent = await createAgent({
name: 'AdaptiveAgent',
provider: provider,
memory: adaptiveMemory,
systemPrompt: "You are an intelligent assistant with advanced memory management."
});
// Context is automatically managed during conversations
const response = await agent.chat({
message: "Remember that I prefer concise answers",
sessionId: "preferences",
stream: true,
onChunk: (chunk) => console.log(chunk)
});
// Later conversations will remember preferences even with long context
const response2 = await agent.chat({
message: "What did I tell you about my communication preferences?",
sessionId: "preferences",
stream: true,
onChunk: (chunk) => console.log(chunk)
});
Adaptive Context Methods
Access adaptive context features directly:
// Get adaptive context layers for a session
const contextLayers = await memory.getAdaptiveContext("session-1", 4000);
console.log("Immediate messages:", contextLayers.immediate.messages.length);
console.log("Summary:", contextLayers.summarized.summary);
console.log("Important facts:", contextLayers.persistent.importantFacts.length);
// Update context with new information
await memory.updateContextLayers("session-1", {
role: "user",
content: "Important: I'm a software engineer",
timestamp: new Date()
});
// Compress context when needed
const compressionResult = await memory.compressContext("session-1", "SUMMARIZE");
console.log("Compression result:", compressionResult);
// Get formatted context for display (includes AI-generated summaries)
const formattedContext = await memory.getFormattedContext("session-1", 4000);
console.log("Formatted context:", formattedContext);
// Generate intelligent summary for session
const sessionSummary = await memory.generateSummary("session-1");
console.log("AI-powered session summary:", sessionSummary);
Semantic Search with Embeddings
When embeddings are enabled, perform semantic searches across conversations:
// Enable embeddings in memory
const vectorMemory = await createMemory({
database: db,
tableName: "vector_conversations",
maxEntries: 300,
enableEmbeddings: true
});
const agent = await createAgent({
name: 'VectorAgent',
provider: provider,
memory: vectorMemory
});
// Chat with automatic embedding storage
await agent.chat({
message: "I'm interested in machine learning algorithms",
sessionId: "ml-discussion",
stream: true,
onChunk: (chunk) => console.log(chunk)
});
await agent.chat({
message: "Tell me about neural networks",
sessionId: "ml-discussion",
stream: true,
onChunk: (chunk) => console.log(chunk)
});
// Search for semantically similar content
const memory = agent.config.memory;
const mlResults = await memory.searchByText("artificial intelligence", 5);
mlResults.forEach(result => {
console.log(`Related content: ${result.content}`);
console.log(`From session: ${result.sessionId}`);
});
Context-Aware Conversations
Use memory to build context-aware responses:
class ContextualAgent {
private agent: AgentInstance;
constructor(agent: AgentInstance) {
this.agent = agent;
}
async contextualChat(message: string, sessionId: string) {
// Get recent conversation context
const recentHistory = await this.agent.getHistory(sessionId, 5);
// Search for relevant past conversations
const memory = this.agent.getMemory();
const relevantMemories = await memory.searchByText(message, 3);
// Build context-aware system prompt
const context = [
...recentHistory.map(h => `${h.role}: ${h.content}`),
...relevantMemories.map(m => `Related: ${m.content}`)
].join('\n');
const contextPrompt = `Previous context:\n${context}\n\nCurrent message: ${message}`;
return await this.agent.chat({
message: contextPrompt,
sessionId,
systemPrompt: `You are a helpful assistant. Use the provided context to give more relevant and personalized responses.`,
stream: true,
onChunk: (chunk) => console.log(chunk)
});
}
async addUserPreference(sessionId: string, preference: string, category: string) {
await this.agent.addToMemory({
sessionId,
role: 'system',
content: `User preference: ${preference}`,
metadata: {
type: 'preference',
category,
timestamp: new Date()
}
});
}
async getUserPreferences(sessionId: string) {
const memory = this.agent.getMemory();
const preferences = await memory.searchByText("User preference", 10);
return preferences
.filter(p => p.sessionId === sessionId)
.map(p => ({
preference: p.content.replace('User preference: ', ''),
category: p.metadata?.category,
timestamp: p.metadata?.timestamp
}));
}
}
Multi-Session Memory Management
Manage memory across multiple sessions:
class MultiSessionMemoryManager {
private agent: AgentInstance;
constructor(agent: AgentInstance) {
this.agent = agent;
}
async getSessionSummary() {
const sessions = await this.agent.listSessions();
return sessions.map(session => ({
sessionId: session.sessionId,
messageCount: session.messageCount,
lastActivity: session.lastActivity,
lastMessage: session.lastMessage?.substring(0, 100) + '...',
metadata: session.metadata
}));
}
async findSessionsByTopic(topic: string) {
const memory = this.agent.getMemory();
const topicResults = await memory.searchByText(topic, 20);
// Group by session
const sessionMap = new Map();
topicResults.forEach(result => {
if (!sessionMap.has(result.sessionId)) {
sessionMap.set(result.sessionId, []);
}
sessionMap.get(result.sessionId).push(result);
});
return Array.from(sessionMap.entries()).map(([sessionId, messages]) => ({
sessionId,
relevantMessages: messages.length,
preview: messages[0]?.content.substring(0, 100) + '...'
}));
}
async cleanupOldSessions(daysOld: number = 30) {
const sessions = await this.agent.listSessions();
const cutoffDate = new Date(Date.now() - (daysOld * 24 * 60 * 60 * 1000));
const oldSessions = sessions.filter(s => s.lastActivity < cutoffDate);
for (const session of oldSessions) {
await this.agent.clearHistory(session.sessionId);
console.log(`Cleaned up session: ${session.sessionId}`);
}
return oldSessions.length;
}
async exportSessionData(sessionId: string) {
const history = await this.agent.getHistory(sessionId);
const sessions = await this.agent.listSessions();
const sessionInfo = sessions.find(s => s.sessionId === sessionId);
return {
sessionInfo,
messages: history,
exportDate: new Date(),
messageCount: history.length
};
}
}
Database Integration
Memory integrates seamlessly with the database system:
// Access database directly through agent
const database = agent.getDatabase();
// Custom queries on memory data
const customQuery = await database.knex('memories')
.where('agentId', agent.id)
.andWhere('role', 'user')
.andWhere('timestamp', '>', new Date(Date.now() - 7 * 24 * 60 * 60 * 1000))
.orderBy('timestamp', 'desc');
console.log(`User messages in last 7 days: ${customQuery.length}`);
// Memory statistics
const stats = await database.knex('memories')
.where('agentId', agent.id)
.groupBy('sessionId')
.select('sessionId')
.count('* as messageCount');
console.log('Session statistics:', stats);
Best Practices
- Session Organization: Use meaningful session IDs for better organization
- Metadata Usage: Store relevant metadata for filtering and search
- Memory Cleanup: Regularly clean old sessions to manage storage
- Context Building: Use memory search to build relevant context
- Embedding Strategy: Enable embeddings for semantic search capabilities
- Error Handling: Handle memory operations with proper error handling
- Performance: Limit history retrieval for better performance
The agent-centric memory system provides a more intuitive and powerful way to manage conversation history with built-in session management and advanced search capabilities.
How is this guide?