memory.tsā¢3.62 kB
import { MemoryEntry, AgentMemory } from '../agents/types';
export class WorksonaAgentMemory implements AgentMemory {
private memories: MemoryEntry[] = [];
private readonly maxMemories = 1000;
addMemory(entry: MemoryEntry): void {
// Add summary if not provided
if (!entry.summary && entry.response.length > 200) {
entry.summary = this.generateSummary(entry.response);
}
this.memories.push(entry);
// Cleanup old memories
if (this.memories.length > this.maxMemories) {
this.memories = this.memories.slice(-this.maxMemories);
}
}
getRelevantMemory(agentName: string, request: string, limit = 5): MemoryEntry[] {
const requestWords = this.extractKeywords(request);
const memories: Array<{ memory: MemoryEntry; relevanceScore: number }> = [];
for (const memory of this.memories) {
let score = 0;
// Same agent memories get higher relevance
if (memory.agentName === agentName) {
score += 10;
}
// Check keyword overlap in request and response
const memoryText = (memory.request + ' ' + memory.response).toLowerCase();
const memoryWords = this.extractKeywords(memoryText);
const overlap = requestWords.filter(word => memoryWords.includes(word));
score += overlap.length * 2;
// Time decay - recent memories are more relevant
const ageInDays = (Date.now() - memory.timestamp.getTime()) / (1000 * 60 * 60 * 24);
if (ageInDays < 1) score += 5;
else if (ageInDays < 7) score += 3;
else if (ageInDays < 30) score += 1;
if (score > 3) {
memories.push({ memory, relevanceScore: score });
}
}
return memories
.sort((a, b) => b.relevanceScore - a.relevanceScore)
.slice(0, limit)
.map(item => item.memory);
}
getConversationHistory(context: string, limit = 10): MemoryEntry[] {
return this.memories
.filter(memory => memory.context === context)
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())
.slice(0, limit);
}
clearMemory(olderThan?: Date): void {
if (olderThan) {
this.memories = this.memories.filter(memory => memory.timestamp > olderThan);
} else {
this.memories = [];
}
}
// Additional utility methods
getMemoryStats(): {
totalMemories: number;
agentCounts: Record<string, number>;
oldestMemory?: Date;
newestMemory?: Date;
} {
const agentCounts: Record<string, number> = {};
let oldestMemory: Date | undefined;
let newestMemory: Date | undefined;
for (const memory of this.memories) {
agentCounts[memory.agentName] = (agentCounts[memory.agentName] || 0) + 1;
if (!oldestMemory || memory.timestamp < oldestMemory) {
oldestMemory = memory.timestamp;
}
if (!newestMemory || memory.timestamp > newestMemory) {
newestMemory = memory.timestamp;
}
}
return {
totalMemories: this.memories.length,
agentCounts,
oldestMemory,
newestMemory
};
}
private generateSummary(text: string): string {
// Simple summary generation - take first 150 characters
const summary = text.substring(0, 150);
return summary.includes('.') ? summary.substring(0, summary.lastIndexOf('.') + 1) : summary + '...';
}
private extractKeywords(text: string): string[] {
return text
.toLowerCase()
.replace(/[^\w\s]/g, ' ')
.split(/\s+/)
.filter(word => word.length > 3)
.filter(word => !['this', 'that', 'with', 'from', 'they', 'have', 'will', 'been', 'were'].includes(word));
}
}