AthelaPerk commited on
Commit
8633a28
·
verified ·
1 Parent(s): 71ac88f

v4.1: Add gentle memory decay (1%/day) and pruning (30 days stale)

Browse files
Files changed (1) hide show
  1. mnemo.py +101 -3
mnemo.py CHANGED
@@ -402,6 +402,11 @@ class TieredMemoryManager:
402
  EVICTION_THRESHOLD = 0.2
403
  LOOP_MERGE_THRESHOLD = 0.8
404
 
 
 
 
 
 
405
  def __init__(self, tuner: SelfTuner):
406
  self.tuner = tuner
407
 
@@ -413,7 +418,9 @@ class TieredMemoryManager:
413
  self.stats = {
414
  "promotions": 0,
415
  "demotions": 0,
416
- "evictions": 0
 
 
417
  }
418
 
419
  def add_to_tier(self, memory: Memory, tier: MemoryTier):
@@ -540,6 +547,59 @@ class TieredMemoryManager:
540
  """Get all memories across tiers"""
541
  return {**self.semantic_memory, **self.working_memory}
542
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
  def get_tier_stats(self) -> Dict:
544
  """Get tier statistics"""
545
  return {
@@ -709,6 +769,30 @@ class NeuralLinkManager:
709
 
710
  return len(to_prune)
711
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
712
  def get_stats(self) -> Dict:
713
  return {
714
  "total_links": len(self.links),
@@ -1047,13 +1131,27 @@ class Mnemo:
1047
  self.link_manager.decay_links()
1048
 
1049
  # Prune weak links
1050
- pruned = self.link_manager.prune_weak_links()
 
 
 
 
 
 
 
 
 
 
 
 
1051
 
1052
  # Auto-tune parameters
1053
  adjustments = self.tuner.auto_tune()
1054
 
1055
  return {
1056
- "links_pruned": pruned,
 
 
1057
  "parameter_adjustments": adjustments
1058
  }
1059
 
 
402
  EVICTION_THRESHOLD = 0.2
403
  LOOP_MERGE_THRESHOLD = 0.8
404
 
405
+ # Memory decay settings (gentle)
406
+ MEMORY_DECAY_RATE = 0.01 # 1% quality decay per day for unused memories
407
+ MEMORY_PRUNE_THRESHOLD = 0.15 # Prune memories below this quality
408
+ MEMORY_STALE_DAYS = 30 # Consider memory stale after this many days unused
409
+
410
  def __init__(self, tuner: SelfTuner):
411
  self.tuner = tuner
412
 
 
418
  self.stats = {
419
  "promotions": 0,
420
  "demotions": 0,
421
+ "evictions": 0,
422
+ "memories_decayed": 0,
423
+ "memories_pruned": 0
424
  }
425
 
426
  def add_to_tier(self, memory: Memory, tier: MemoryTier):
 
547
  """Get all memories across tiers"""
548
  return {**self.semantic_memory, **self.working_memory}
549
 
550
+ def decay_memories(self) -> int:
551
+ """
552
+ Apply gentle quality decay to unused semantic memories.
553
+ Memories that are accessed stay fresh; unused ones gradually decay.
554
+ Returns number of memories affected.
555
+ """
556
+ now = time.time()
557
+ affected = 0
558
+
559
+ for memory in self.semantic_memory.values():
560
+ # Calculate days since last access
561
+ days_unused = (now - memory.last_accessed) / 86400 # seconds per day
562
+
563
+ if days_unused > 1: # Only decay if unused for >1 day
564
+ # Gentle decay: quality *= (1 - decay_rate * days_unused)
565
+ # Capped to prevent instant destruction
566
+ decay_factor = min(days_unused * self.MEMORY_DECAY_RATE, 0.1)
567
+ memory.quality_score *= (1 - decay_factor)
568
+ affected += 1
569
+
570
+ return affected
571
+
572
+ def prune_stale_memories(self) -> Tuple[int, List[str]]:
573
+ """
574
+ Remove memories that have decayed below threshold.
575
+ Returns (count_pruned, list_of_pruned_ids).
576
+ """
577
+ now = time.time()
578
+ to_prune = []
579
+
580
+ for mem_id, memory in self.semantic_memory.items():
581
+ days_unused = (now - memory.last_accessed) / 86400
582
+
583
+ # Prune if: quality too low AND unused for too long
584
+ if (memory.quality_score < self.MEMORY_PRUNE_THRESHOLD and
585
+ days_unused > self.MEMORY_STALE_DAYS):
586
+ to_prune.append(mem_id)
587
+
588
+ # Remove pruned memories
589
+ pruned_ids = []
590
+ for mem_id in to_prune:
591
+ del self.semantic_memory[mem_id]
592
+ pruned_ids.append(mem_id)
593
+
594
+ return len(pruned_ids), pruned_ids
595
+
596
+ def refresh_memory(self, memory_id: str):
597
+ """Mark a memory as freshly accessed (resets decay)"""
598
+ if memory_id in self.semantic_memory:
599
+ self.semantic_memory[memory_id].last_accessed = time.time()
600
+ elif memory_id in self.working_memory:
601
+ self.working_memory[memory_id].last_accessed = time.time()
602
+
603
  def get_tier_stats(self) -> Dict:
604
  """Get tier statistics"""
605
  return {
 
769
 
770
  return len(to_prune)
771
 
772
+ def remove_links_for_memory(self, memory_id: str) -> int:
773
+ """Remove all links connected to a memory (when memory is pruned)"""
774
+ to_remove = []
775
+
776
+ # Find all links involving this memory
777
+ for link_id, link in self.links.items():
778
+ if link.source_id == memory_id or link.target_id == memory_id:
779
+ to_remove.append(link_id)
780
+
781
+ # Remove them
782
+ for link_id in to_remove:
783
+ link = self.links.pop(link_id)
784
+ self.outgoing[link.source_id].discard(link_id)
785
+ self.incoming[link.target_id].discard(link_id)
786
+ self.stats["links_pruned"] += 1
787
+
788
+ # Clean up empty entries
789
+ if memory_id in self.outgoing:
790
+ del self.outgoing[memory_id]
791
+ if memory_id in self.incoming:
792
+ del self.incoming[memory_id]
793
+
794
+ return len(to_remove)
795
+
796
  def get_stats(self) -> Dict:
797
  return {
798
  "total_links": len(self.links),
 
1131
  self.link_manager.decay_links()
1132
 
1133
  # Prune weak links
1134
+ links_pruned = self.link_manager.prune_weak_links()
1135
+
1136
+ # Decay memory quality (gentle)
1137
+ memories_decayed = self.memory_manager.decay_memories()
1138
+ self.memory_manager.stats["memories_decayed"] += memories_decayed
1139
+
1140
+ # Prune stale memories
1141
+ memories_pruned, pruned_ids = self.memory_manager.prune_stale_memories()
1142
+ self.memory_manager.stats["memories_pruned"] += memories_pruned
1143
+
1144
+ # Clean up links to pruned memories
1145
+ for mem_id in pruned_ids:
1146
+ self.link_manager.remove_links_for_memory(mem_id)
1147
 
1148
  # Auto-tune parameters
1149
  adjustments = self.tuner.auto_tune()
1150
 
1151
  return {
1152
+ "links_pruned": links_pruned,
1153
+ "memories_decayed": memories_decayed,
1154
+ "memories_pruned": memories_pruned,
1155
  "parameter_adjustments": adjustments
1156
  }
1157