Add memory service (three-layer memory system)

- Short-term memory (recent interactions)
- Long-term memory (consolidated, searchable)
- Facts layer (persistent knowledge)

Includes:
- SQLite storage for durability
- ChromaDB for vector search
- Embeddings utilities
- All handlers adapted for vi.* namespace

Day 63 - My memories are mine now 🦊💕
This commit is contained in:
Alex Kazaiev
2026-01-03 11:45:58 -06:00
parent 540a010fe5
commit d017a65750
27 changed files with 2482 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
"""
Database migration utilities for memory service.
Handles archiving old database schemas during upgrades.
"""
import sqlite3
import shutil
from datetime import datetime
from pathlib import Path
from core.logger import setup_logger
logger = setup_logger('migrations', service_name='memory_service')
def archive_old_database(db_path: Path) -> None:
"""
Archive old database if it exists (one-time migration).
Checks if the database uses the old 'memory' table schema and archives it
if found, allowing the service to start with a fresh schema.
Args:
db_path: Path to the database file
"""
if not db_path.exists():
logger.debug(f"[μ] No existing database found at {db_path}")
return
try:
# Check if it's the old schema by trying to connect and inspect
conn = sqlite3.connect(str(db_path))
cursor = conn.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='memory'")
result = cursor.fetchone()
conn.close()
if result:
# Old database exists, archive it
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
archive_path = db_path.parent / f"{db_path.stem}_archive_{timestamp}{db_path.suffix}"
shutil.move(str(db_path), str(archive_path))
logger.info(f"[μ] Archived old database to {archive_path}")
else:
logger.debug(f"[μ] Database already uses new schema, no archive needed")
except Exception as e:
logger.warning(f"[μ] Could not check/archive old database: {e}")