Skip to main content
Glama
InterferenceBasedStrategy.ts9.14 kB
/** * Interference-Based Forgetting Strategy * * Implements forgetting based on memory interference patterns, * identifying conflicting memories and resolving them through forgetting. */ import { ForgettingContext, ForgettingFactor, ForgettingScore, InterferenceBasedStrategy, } from "../../interfaces/forgetting.js"; import { Concept, Episode } from "../../types/core.js"; export class InterferenceBasedStrategyImpl implements InterferenceBasedStrategy { name = "interference_based"; description = "Forgets memories that interfere with or conflict with newer memories"; similarity_threshold: number; conflict_resolution_mode: "keep_newer" | "keep_stronger" | "merge"; interference_weight: number; constructor(config?: { similarity_threshold?: number; conflict_resolution_mode?: "keep_newer" | "keep_stronger" | "merge"; interference_weight?: number; }) { this.similarity_threshold = config?.similarity_threshold ?? 0.8; this.conflict_resolution_mode = config?.conflict_resolution_mode ?? "keep_newer"; this.interference_weight = config?.interference_weight ?? 0.6; } async evaluateForForgetting( memory: Episode | Concept, context: ForgettingContext ): Promise<ForgettingScore> { const factors: ForgettingFactor[] = []; let totalScore = 0; let totalWeight = 0; // Content similarity interference const similarityFactor = await this.calculateSimilarityInterference( memory, context ); factors.push(similarityFactor); totalScore += similarityFactor.value * similarityFactor.weight; totalWeight += similarityFactor.weight; // Temporal interference - newer memories interfering with older ones const temporalFactor = this.calculateTemporalInterference(memory, context); factors.push(temporalFactor); totalScore += temporalFactor.value * temporalFactor.weight; totalWeight += temporalFactor.weight; // Context conflict interference const contextFactor = this.calculateContextInterference(memory, context); factors.push(contextFactor); totalScore += contextFactor.value * contextFactor.weight; totalWeight += contextFactor.weight; // Strength-based interference const strengthFactor = this.calculateStrengthInterference(memory, context); factors.push(strengthFactor); totalScore += strengthFactor.value * strengthFactor.weight; totalWeight += strengthFactor.weight; const finalScore = totalWeight > 0 ? totalScore / totalWeight : 0; const confidence = this.calculateConfidence(factors); return { strategy_name: this.name, score: Math.max(0, Math.min(1, finalScore)), confidence, reasoning: this.generateReasoning(factors, finalScore), factors, }; } private async calculateSimilarityInterference( _memory: Episode | Concept, _context: ForgettingContext ): Promise<ForgettingFactor> { // Simulate finding similar memories that might interfere // In a real implementation, this would search through the memory system const similarMemoryCount = Math.floor(Math.random() * 5); // Simulated const averageSimilarity = Math.random() * 0.4 + 0.6; // Simulated high similarity let interferenceScore = 0; if ( similarMemoryCount > 0 && averageSimilarity > this.similarity_threshold ) { // Higher interference when there are many similar memories interferenceScore = Math.min(similarMemoryCount / 3, 1) * averageSimilarity; } return { name: "content_similarity", value: interferenceScore, weight: 0.4, description: `Found ${similarMemoryCount} similar memories with avg similarity ${averageSimilarity.toFixed( 3 )}`, }; } private calculateTemporalInterference( memory: Episode | Concept, context: ForgettingContext ): ForgettingFactor { const memoryAge = this.getMemoryAge(memory, context.current_time); const ageInDays = memoryAge / (1000 * 60 * 60 * 24); // Older memories are more susceptible to interference from newer ones let interferenceScore = 0; if (ageInDays > 7) { // Memories older than a week interferenceScore = Math.min(ageInDays / 30, 1); // Normalize to 30 days // Apply conflict resolution mode switch (this.conflict_resolution_mode) { case "keep_newer": interferenceScore *= 1.2; // Bias towards forgetting older memories break; case "keep_stronger": const strength = this.getMemoryStrength(memory); interferenceScore *= 1 - strength; // Weaker memories more likely to be forgotten break; case "merge": interferenceScore *= 0.5; // Lower interference when merging is preferred break; } } return { name: "temporal_interference", value: Math.min(interferenceScore, 1), weight: 0.3, description: `Memory age: ${ageInDays.toFixed(1)} days, mode: ${ this.conflict_resolution_mode }`, }; } private calculateContextInterference( memory: Episode | Concept, context: ForgettingContext ): ForgettingFactor { // Check if memory context conflicts with current system goals let contextConflictScore = 0; if ("context" in memory && memory.context) { const memoryDomain = memory.context.domain; const currentGoals = context.system_goals; // Simple heuristic: if memory domain is not in current goals, it might interfere if ( memoryDomain && !currentGoals.some((goal) => goal.includes(memoryDomain)) ) { contextConflictScore = 0.6; } // Check for explicit conflicts in context if (memory.context.urgency === 0 && context.memory_pressure > 0.7) { // Low urgency contextConflictScore += 0.3; } } return { name: "context_conflict", value: Math.min(contextConflictScore, 1), weight: 0.2, description: `Context alignment with current goals and system state`, }; } private calculateStrengthInterference( memory: Episode | Concept, _context: ForgettingContext ): ForgettingFactor { const memoryStrength = this.getMemoryStrength(memory); // Weaker memories are more susceptible to interference const interferenceScore = 1 - memoryStrength; return { name: "strength_interference", value: interferenceScore, weight: this.interference_weight, description: `Memory strength: ${memoryStrength.toFixed( 3 )}, interference susceptibility: ${interferenceScore.toFixed(3)}`, }; } private calculateConfidence(factors: ForgettingFactor[]): number { // Confidence based on the strength of interference signals const interferenceFactors = factors.filter( (f) => f.name.includes("interference") ?? f.name.includes("similarity") ); if (interferenceFactors.length === 0) { return 0.3; // Low confidence without interference evidence } const avgInterference = interferenceFactors.reduce((sum, f) => sum + f.value, 0) / interferenceFactors.length; // Higher interference means higher confidence in forgetting decision return Math.max(0.4, avgInterference); } private generateReasoning( factors: ForgettingFactor[], finalScore: number ): string[] { const reasoning: string[] = []; reasoning.push( `Interference analysis resulted in forgetting score: ${finalScore.toFixed( 3 )}` ); // Analyze interference patterns const interferenceFactors = factors.filter((f) => f.value > 0.3); if (interferenceFactors.length > 0) { reasoning.push( `Detected interference from ${interferenceFactors.length} sources:` ); interferenceFactors.forEach((factor) => { reasoning.push(`- ${factor.name}: ${factor.description}`); }); } else { reasoning.push("No significant interference detected"); } // Resolution mode explanation reasoning.push( `Conflict resolution mode: ${this.conflict_resolution_mode}` ); if (finalScore > 0.6) { reasoning.push( "High interference detected - memory is likely causing conflicts" ); } else if (finalScore > 0.3) { reasoning.push( "Moderate interference - memory may benefit from consolidation or archiving" ); } else { reasoning.push( "Low interference - memory is not causing significant conflicts" ); } return reasoning; } private getMemoryAge(memory: Episode | Concept, currentTime: number): number { if ("timestamp" in memory) { return currentTime - memory.timestamp; } else if ("last_accessed" in memory) { return currentTime - memory.last_accessed; } return 0; } private getMemoryStrength(memory: Episode | Concept): number { if ("importance" in memory) { return memory.importance; } else if ("activation" in memory) { return memory.activation; } return 0.5; // Default moderate strength } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/keyurgolani/ThoughtMcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server