03-memory-augmented-agent / memory_store.py
FlyingNunchucks's picture
Reset Agent 3 to sanitized public history
c63c390
Raw History Blame Contribute Delete
3.09 kB
import json
from datetime import datetime, timezone
from typing import Iterable, List, Optional
from uuid import uuid4
import numpy as np
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
from schemas import Memory, RetrievedMemory, MemoryWriteDecision
class MemoryStore:
def __init__(
self,
memories: Iterable[Memory],
model_name: str = "all-MiniLM-L6-v2",
embedding_model: Optional[SentenceTransformer] = None,
):
self.memories = list(memories)
self.embedding_model = embedding_model or SentenceTransformer(model_name)
self.refresh_embeddings()
def refresh_embeddings(self) -> None:
self.memory_texts = [memory.content for memory in self.memories]
if not self.memory_texts:
self.memory_embeddings = np.empty((0, 0))
return
self.memory_embeddings = self.embedding_model.encode(self.memory_texts)
def retrieve(self, query: str, top_k: int = 4) -> List[RetrievedMemory]:
if not self.memories or not query.strip():
return []
safe_top_k = max(1, min(int(top_k), len(self.memories)))
query_embedding = self.embedding_model.encode([query])
similarities = cosine_similarity(query_embedding, self.memory_embeddings)[0]
ranked_indices = similarities.argsort()[::-1][:safe_top_k]
return [
RetrievedMemory(
memory=self.memories[index],
similarity_score=float(similarities[index]),
rank=rank,
)
for rank, index in enumerate(ranked_indices, start=1)
]
def save_memory_from_decision(self, write_decision: MemoryWriteDecision) -> Optional[Memory]:
if write_decision.outcome != "save" or not write_decision.should_save:
return None
if not write_decision.proposed_memory:
return None
new_memory = Memory(
memory_id=f"session_{uuid4().hex[:10]}",
memory_type=write_decision.memory_type or "episodic",
content=write_decision.proposed_memory,
tags=["session_memory", "policy_approved"],
importance=write_decision.importance or 3,
created_at=datetime.now(timezone.utc).date().isoformat(),
source="session_write_policy",
)
self.memories.append(new_memory)
self.refresh_embeddings()
return new_memory
def to_dicts(self) -> List[dict]:
return [memory.model_dump() for memory in self.memories]
def export_to_json(self, filepath: str) -> None:
with open(filepath, "w", encoding="utf-8") as file:
json.dump(self.to_dicts(), file, indent=2)
def memories_from_dicts(memory_data: Iterable[dict]) -> List[Memory]:
return [Memory(**item) for item in memory_data]
def load_memories_from_json(filepath: str) -> List[Memory]:
with open(filepath, "r", encoding="utf-8") as file:
memory_data = json.load(file)
return memories_from_dicts(memory_data)