62 lines
2.2 KiB
Python
62 lines
2.2 KiB
Python
"""
|
|
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
|