""" Defines the abstract interface for Emma's memory systems. """ from abc import ABC, abstractmethod from typing import List, Dict, Any, Optional from contracts.common import EmmaConversation, MemoryRecord class MemoryStore(ABC): """Abstract Base Class for all memory store implementations.""" @abstractmethod async def get_conversation(self, conversation_id: str, owner_id: str) -> Optional[EmmaConversation]: pass @abstractmethod async def save_conversation(self, conversation: EmmaConversation) -> None: pass @abstractmethod async def store_memory(self, record: MemoryRecord) -> None: pass @abstractmethod async def recall_memory(self, embedding: List[float], owner_id: str, scope: List[str]) -> List[MemoryRecord]: pass class InMemoryMemoryStore(MemoryStore): """ A non-persistent, in-memory implementation of the MemoryStore for testing and local development. DO NOT USE IN PRODUCTION. """ def __init__(self): self._conversations: Dict[str, EmmaConversation] = {} self._memories: List[MemoryRecord] = [] print("WARNING: InMemoryMemoryStore is active. Data will not be persisted.") async def get_conversation(self, conversation_id: str, owner_id: str) -> Optional[EmmaConversation]: convo = self._conversations.get(conversation_id) # Enforce ownership check if convo and convo.owner_id == owner_id: return convo return None async def save_conversation(self, conversation: EmmaConversation) -> None: # Enforce ownership if conversation.owner_id: self._conversations[conversation.conversation_id] = conversation async def store_memory(self, record: MemoryRecord) -> None: # Enforce ownership if record.owner_id: self._memories.append(record) async def recall_memory(self, embedding: List[float], owner_id: str, scope: List[str]) -> List[MemoryRecord]: # Simple text match for testing, no real embedding search. # Also filters on ownership. recalled = [mem for mem in self._memories if mem.owner_id == owner_id] return recalled[:5] # Return top 5 for simplicity