""" Memory manager - high-level interface for memory operations. """ import logging from typing import Optional, List from datetime import datetime from uuid import uuid4 from memory.schema import MemoryEntry, MemoryCategory, MemorySource from memory.storage import MemoryStorage logger = logging.getLogger(__name__) class MemoryManager: """High-level memory management.""" def __init__(self, storage: Optional[MemoryStorage] = None): """ Initialize memory manager. Args: storage: Memory storage instance. If None, creates default. """ self.storage = storage or MemoryStorage() def store_fact(self, category: MemoryCategory, key: str, value: str, confidence: float = 1.0, source: MemorySource = MemorySource.EXPLICIT, context: Optional[str] = None, tags: Optional[List[str]] = None) -> MemoryEntry: """ Store a fact in memory. Args: category: Memory category key: Fact key value: Fact value confidence: Confidence level (0.0-1.0) source: Source of the fact context: Additional context tags: Tags for categorization Returns: Created memory entry """ entry = MemoryEntry( id=str(uuid4()), category=category, key=key, value=value, confidence=confidence, source=source, timestamp=datetime.now(), tags=tags or [] ) if context: entry.context = context self.storage.store(entry) return entry def get_fact(self, category: MemoryCategory, key: str) -> Optional[MemoryEntry]: """ Get a fact from memory. Args: category: Memory category key: Fact key Returns: Memory entry or None """ return self.storage.get(category, key) def get_category_facts(self, category: MemoryCategory, limit: Optional[int] = None) -> List[MemoryEntry]: """ Get all facts in a category. Args: category: Memory category limit: Maximum number of facts Returns: List of memory entries """ return self.storage.get_by_category(category, limit) def search_facts(self, query: str, category: Optional[MemoryCategory] = None, limit: int = 10) -> List[MemoryEntry]: """ Search facts by query. Args: query: Search query category: Optional category filter limit: Maximum results Returns: List of matching memory entries """ return self.storage.search(query, category, limit) def format_for_prompt(self, category: Optional[MemoryCategory] = None, limit: int = 20) -> str: """ Format memory entries for inclusion in LLM prompt. Args: category: Optional category filter limit: Maximum entries per category Returns: Formatted string for prompt """ if category: entries = self.get_category_facts(category, limit) return self._format_entries(entries, category.value) else: # Get entries from all categories sections = [] for cat in MemoryCategory: entries = self.get_category_facts(cat, limit) if entries: sections.append(self._format_entries(entries, cat.value)) return "\n\n".join(sections) if sections else "No memory entries." def _format_entries(self, entries: List[MemoryEntry], category_name: str) -> str: """Format entries for a category.""" lines = [f"## {category_name.title()} Facts"] for entry in entries[:20]: # Limit per category confidence_str = f" (confidence: {entry.confidence:.1f})" if entry.confidence < 1.0 else "" source_str = f" [{entry.source.value}]" if entry.source != MemorySource.EXPLICIT else "" lines.append(f"- {entry.key}: {entry.value}{confidence_str}{source_str}") return "\n".join(lines) def delete_fact(self, entry_id: str) -> bool: """ Delete a fact. Args: entry_id: Entry ID to delete Returns: True if deleted successfully """ return self.storage.delete(entry_id) def update_confidence(self, entry_id: str, confidence: float) -> bool: """ Update confidence of a fact. Args: entry_id: Entry ID confidence: New confidence (0.0-1.0) Returns: True if updated successfully """ return self.storage.update_confidence(entry_id, confidence) # Global memory manager instance _manager = MemoryManager() def get_memory_manager() -> MemoryManager: """Get the global memory manager instance.""" return _manager