V8 / memory /manager.py
Drizzy0101's picture
Initial upload
f7e32a5
Raw
History Blame Contribute Delete
5.35 kB
"""Memory manager — orchestrates short-term, long-term, and vector memory."""
import json
from datetime import datetime
from typing import Optional
from config import config
from database.repositories import MemoryRepo, UserFactRepo
class MemoryManager:
"""Central memory system for Synapse V8."""
def __init__(self, user_id: str = "guest"):
self.user_id = user_id
self.short_term: list[dict] = []
self._short_term_limit = config.memory.short_term_limit
async def add_short_term(self, role: str, content: str,
metadata: dict = None) -> dict:
entry = {
"role": role,
"content": content,
"timestamp": datetime.utcnow().isoformat(),
"metadata": metadata or {},
}
self.short_term.append(entry)
if len(self.short_term) > self._short_term_limit:
await self._consolidate_oldest()
return entry
async def _consolidate_oldest(self):
if not self.short_term:
return
oldest = self.short_term.pop(0)
importance = self._calculate_importance(oldest["content"])
if importance >= config.memory.long_term_threshold:
await MemoryRepo.create(
user_id=self.user_id,
content=oldest["content"],
memory_type="consolidated",
importance=importance,
metadata=oldest.get("metadata"),
)
def _calculate_importance(self, content: str) -> float:
score = 0.3
important_markers = [
"remember", "important", "never forget", "always",
"my name", "i prefer", "i like", "i don't like",
"my birthday", "my email", "password", "secret",
"goal", "project", "deadline", "meeting",
]
lower = content.lower()
for marker in important_markers:
if marker in lower:
score += 0.15
if len(content) > 200:
score += 0.1
if "?" in content:
score += 0.05
return min(score, 1.0)
def get_short_term_context(self, max_messages: int = 20) -> list[dict]:
return self.short_term[-max_messages:]
async def search_long_term(self, query: str, limit: int = 5) -> list[dict]:
results = await MemoryRepo.search(self.user_id, query)
return results[:limit]
async def get_pinned_memories(self) -> list[dict]:
return await MemoryRepo.get_pinned(self.user_id)
async def add_memory(self, content: str, memory_type: str = "long_term",
importance: float = 0.5, tags: list = None,
conversation_id: str = None) -> dict:
return await MemoryRepo.create(
user_id=self.user_id,
content=content,
memory_type=memory_type,
importance=importance,
tags=tags,
conversation_id=conversation_id,
)
async def add_user_fact(self, fact: str, category: str = "general",
source: str = None) -> dict:
return await UserFactRepo.create(
user_id=self.user_id,
fact=fact,
category=category,
source=source,
)
async def get_user_facts(self, category: str = None) -> list[dict]:
return await UserFactRepo.get_user_facts(self.user_id, category)
async def get_all_memories(self, memory_type: str = None,
limit: int = 50) -> list[dict]:
return await MemoryRepo.get_user_memories(
self.user_id, memory_type=memory_type, limit=limit
)
async def toggle_pin_memory(self, memory_id: str) -> None:
await MemoryRepo.toggle_pin(memory_id)
async def delete_memory(self, memory_id: str) -> bool:
return await MemoryRepo.delete(memory_id)
async def build_memory_context(self) -> str:
parts = []
pinned = await self.get_pinned_memories()
if pinned:
parts.append("Pinned memories:")
for m in pinned[:10]:
parts.append(f"- {m['content']}")
facts = await self.get_user_facts()
if facts:
parts.append("\nKnown facts about user:")
for f in facts[:10]:
parts.append(f"- {f['fact']} ({f['category']})")
recent_memories = await self.get_all_memories(limit=5)
if recent_memories:
parts.append("\nRecent memories:")
for m in recent_memories:
parts.append(f"- {m['content']}")
return "\n".join(parts) if parts else ""
async def consolidate(self, conversation_messages: list[dict]) -> None:
if len(conversation_messages) < config.memory.consolidation_interval:
return
summary_parts = []
for msg in conversation_messages[-config.memory.consolidation_interval:]:
summary_parts.append(f"{msg['role']}: {msg['content'][:200]}")
summary = "\n".join(summary_parts)
importance = self._calculate_importance(summary)
if importance >= 0.4:
await self.add_memory(
content=f"Conversation summary: {summary[:500]}",
memory_type="summary",
importance=importance,
)