Spaces:
Running on Zero
Running on Zero
| """Database migrations — schema versioning.""" | |
| SCHEMA_VERSION = 1 | |
| MIGRATIONS = { | |
| 1: """ | |
| CREATE TABLE IF NOT EXISTS users ( | |
| id TEXT PRIMARY KEY, | |
| username TEXT UNIQUE NOT NULL, | |
| display_name TEXT, | |
| email TEXT, | |
| avatar_url TEXT, | |
| preferences TEXT DEFAULT '{}', | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| CREATE TABLE IF NOT EXISTS conversations ( | |
| id TEXT PRIMARY KEY, | |
| user_id TEXT, | |
| title TEXT DEFAULT 'New Chat', | |
| folder_id TEXT, | |
| personality_id TEXT DEFAULT 'synapse', | |
| mode TEXT DEFAULT 'agent', | |
| is_pinned INTEGER DEFAULT 0, | |
| is_bookmarked INTEGER DEFAULT 0, | |
| summary TEXT, | |
| metadata TEXT DEFAULT '{}', | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE | |
| ); | |
| CREATE TABLE IF NOT EXISTS messages ( | |
| id TEXT PRIMARY KEY, | |
| conversation_id TEXT NOT NULL, | |
| role TEXT NOT NULL CHECK(role IN ('user','assistant','system','tool')), | |
| content TEXT NOT NULL, | |
| reasoning TEXT, | |
| tool_calls TEXT, | |
| tool_results TEXT, | |
| model TEXT, | |
| tokens_used INTEGER DEFAULT 0, | |
| metadata TEXT DEFAULT '{}', | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE | |
| ); | |
| CREATE TABLE IF NOT EXISTS folders ( | |
| id TEXT PRIMARY KEY, | |
| user_id TEXT, | |
| name TEXT NOT NULL, | |
| parent_id TEXT, | |
| color TEXT DEFAULT '#6366f1', | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE | |
| ); | |
| CREATE TABLE IF NOT EXISTS memories ( | |
| id TEXT PRIMARY KEY, | |
| user_id TEXT, | |
| conversation_id TEXT, | |
| content TEXT NOT NULL, | |
| memory_type TEXT DEFAULT 'long_term', | |
| importance REAL DEFAULT 0.5, | |
| embedding BLOB, | |
| is_pinned INTEGER DEFAULT 0, | |
| tags TEXT DEFAULT '[]', | |
| metadata TEXT DEFAULT '{}', | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| accessed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE | |
| ); | |
| CREATE TABLE IF NOT EXISTS user_facts ( | |
| id TEXT PRIMARY KEY, | |
| user_id TEXT NOT NULL, | |
| fact TEXT NOT NULL, | |
| category TEXT DEFAULT 'general', | |
| confidence REAL DEFAULT 1.0, | |
| source TEXT, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE | |
| ); | |
| CREATE TABLE IF NOT EXISTS personalities ( | |
| id TEXT PRIMARY KEY, | |
| name TEXT NOT NULL, | |
| system_prompt TEXT NOT NULL, | |
| description TEXT, | |
| mood TEXT DEFAULT 'neutral', | |
| humor_level REAL DEFAULT 0.5, | |
| creativity_level REAL DEFAULT 0.7, | |
| is_default INTEGER DEFAULT 0, | |
| avatar_url TEXT, | |
| metadata TEXT DEFAULT '{}', | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| CREATE TABLE IF NOT EXISTS chat_history ( | |
| id TEXT PRIMARY KEY, | |
| user_id TEXT, | |
| conversation_id TEXT NOT NULL, | |
| action TEXT NOT NULL, | |
| old_value TEXT, | |
| new_value TEXT, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE | |
| ); | |
| CREATE TABLE IF NOT EXISTS plugins ( | |
| id TEXT PRIMARY KEY, | |
| name TEXT NOT NULL UNIQUE, | |
| description TEXT, | |
| version TEXT DEFAULT '1.0.0', | |
| author TEXT, | |
| enabled INTEGER DEFAULT 1, | |
| config TEXT DEFAULT '{}', | |
| tools TEXT DEFAULT '[]', | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| CREATE TABLE IF NOT EXISTS generated_files ( | |
| id TEXT PRIMARY KEY, | |
| user_id TEXT, | |
| file_type TEXT NOT NULL, | |
| file_path TEXT NOT NULL, | |
| original_prompt TEXT, | |
| metadata TEXT DEFAULT '{}', | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE | |
| ); | |
| CREATE TABLE IF NOT EXISTS sessions ( | |
| id TEXT PRIMARY KEY, | |
| user_id TEXT, | |
| token TEXT UNIQUE NOT NULL, | |
| ip_address TEXT, | |
| user_agent TEXT, | |
| expires_at TIMESTAMP, | |
| created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE | |
| ); | |
| CREATE TABLE IF NOT EXISTS settings ( | |
| user_id TEXT, | |
| key TEXT NOT NULL, | |
| value TEXT, | |
| PRIMARY KEY (user_id, key), | |
| FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE | |
| ); | |
| CREATE TABLE IF NOT EXISTS migrations ( | |
| version INTEGER PRIMARY KEY, | |
| applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ); | |
| CREATE INDEX IF NOT EXISTS idx_messages_conversation ON messages(conversation_id); | |
| CREATE INDEX IF NOT EXISTS idx_messages_role ON messages(role); | |
| CREATE INDEX IF NOT EXISTS idx_conversations_user ON conversations(user_id); | |
| CREATE INDEX IF NOT EXISTS idx_memories_user ON memories(user_id); | |
| CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type); | |
| CREATE INDEX IF NOT EXISTS idx_generated_files_user ON generated_files(user_id); | |
| CREATE INDEX IF NOT EXISTS idx_chat_history_conversation ON chat_history(conversation_id); | |
| """, | |
| } | |
| async def run_migrations(db): | |
| await db.execute(""" | |
| CREATE TABLE IF NOT EXISTS migrations ( | |
| version INTEGER PRIMARY KEY, | |
| applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP | |
| ) | |
| """) | |
| await db.commit() | |
| cursor = await db.execute( | |
| "SELECT version FROM migrations ORDER BY version DESC LIMIT 1" | |
| ) | |
| row = await cursor.fetchone() | |
| current_version = row[0] if row else 0 | |
| for version, sql in sorted(MIGRATIONS.items()): | |
| if version > current_version: | |
| await db.executescript(sql) | |
| await db.execute( | |
| "INSERT INTO migrations (version) VALUES (?)", (version,) | |
| ) | |
| await db.commit() | |