""" MemoryDecay Handles memory archiving, deprioritization, and restoration. """ from datetime import UTC, datetime from typing import TYPE_CHECKING if TYPE_CHECKING: from app.models.memory import UserMemory class MemoryDecay: """Handle memory archiving and deprioritization decisions.""" ARCHIVE_THRESHOLD = 0.2 DEPRIORITIZE_THRESHOLD = 0.5 def evaluate(self, memory: "UserMemory") -> dict: """Evaluate memory and return action recommendation. Returns: dict with keys: decay_score, should_archive, should_deprioritize, action """ from app.services.memory.forgetting_curve import ForgettingCurve curve = ForgettingCurve() decay_score = curve.calculate_decay(memory) archive = decay_score < self.ARCHIVE_THRESHOLD deprioritize = decay_score < self.DEPRIORITIZE_THRESHOLD if archive: action = "archive" elif deprioritize: action = "deprioritize" else: action = "keep_active" return { "decay_score": decay_score, "should_archive": archive, "should_deprioritize": deprioritize, "action": action, } def archive_memory(self, memory: "UserMemory") -> "UserMemory": """Archive a memory (set is_archived=True, reset decay_score to low value). Archived memories are moved to cold storage and not included in active reminders or context injection. """ memory.is_archived = True memory.decay_score = 0.1 # Very low, will be restored on access memory.archive_at = datetime.now(UTC) return memory def deprioritize_memory(self, memory: "UserMemory") -> "UserMemory": """Mark a memory as deprioritized (excluded from active reminders). Unlike archival, the memory is still accessible and included in context injection if relevant. """ # Just update decay_score, the importance_level already encodes priority from app.services.memory.forgetting_curve import ForgettingCurve curve = ForgettingCurve() memory.decay_score = curve.calculate_decay(memory) return memory def restore_from_archive(self, memory: "UserMemory") -> "UserMemory": """Restore a memory from archive. Resets is_archived=False and decay_score=0.8 (strong retention). The memory is moved back to hot storage. """ memory.is_archived = False memory.decay_score = 0.8 # Strong retention after restore memory.last_accessed_at = datetime.now(UTC) memory.archive_at = None return memory