File size: 4,880 Bytes
8aa3867
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# src/database/db_operations.py

import os
import sqlite3

class MindGuardDatabase:
    """
    This class handles the Long-Term Memory of MindGuard.
    It connects to a local SQLite database to save chat logs, track emotions, 
    and pull historical context for the LLM.
    """
    def __init__(self):
        print("💾 Initializing MindGuard SQLite Memory Bank...")
        
        # --- STRICT ARCHITECTURE PATHING ---
        self.script_dir = os.path.dirname(os.path.abspath(__file__))
        self.project_root = os.path.abspath(os.path.join(self.script_dir, "../../"))
        
        # 1. Define the exact path for the local SQLite file
        # We will save it right next to our ChromaDB in the artifacts folder
        self.db_dir = os.path.join(self.project_root, "artifacts", "database")
        os.makedirs(self.db_dir, exist_ok=True)
        self.db_path = os.path.join(self.db_dir, "mindguard_memory.sqlite3")
        
        try:
            # 2. Establish connection to the local SQLite file
            # check_same_thread=False allows Streamlit/FastAPI to talk to it later without crashing
            self.conn = sqlite3.connect(self.db_path, check_same_thread=False)
            
            # This forces SQLite to return rows as dictionaries, exactly like PostgreSQL did!
            self.conn.row_factory = sqlite3.Row 
            self.cursor = self.conn.cursor()
            print(f"✅ Successfully connected to SQLite at: {self.db_path}")
            
            # 3. Ensure our tables exist
            self._create_tables()
            
        except sqlite3.Error as e:
            print(f"❌ DATABASE ERROR: Could not connect to SQLite.")
            print(f"Details: {e}")

    def _create_tables(self):
        """Creates the database schema if it doesn't already exist."""
        # --- THE FIX: SQLite Syntax ---
        # PostgreSQL uses 'SERIAL' for auto-counting IDs. SQLite uses 'INTEGER PRIMARY KEY AUTOINCREMENT'
        create_table_query = """
        CREATE TABLE IF NOT EXISTS chat_history (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            session_id TEXT NOT NULL,
            user_message TEXT NOT NULL,
            bot_response TEXT NOT NULL,
            diagnosed_emotion TEXT,
            risk_level TEXT,
            timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
        );
        """
        self.cursor.execute(create_table_query)
        self.conn.commit() # SQLite requires us to manually commit structural changes
        print("✅ Database schema validated.")

    def save_interaction(self, session_id, user_message, bot_response, emotion, risk_level):
        """Saves a single conversation turn into the database."""
        # --- THE FIX: SQLite Parameters ---
        # PostgreSQL uses %s for security. SQLite uses ?
        insert_query = """
        INSERT INTO chat_history (session_id, user_message, bot_response, diagnosed_emotion, risk_level)
        VALUES (?, ?, ?, ?, ?);
        """
        self.cursor.execute(insert_query, (session_id, user_message, bot_response, emotion, risk_level))
        self.conn.commit() # SQLite requires us to manually commit inserted data
        print("💾 Interaction saved to Long-Term Memory.")

    def get_recent_history(self, session_id, limit=3):
        """
        Pulls the last few messages from a specific user session.
        We will feed this to the Groq LLM so it remembers what it just said.
        """
        select_query = """
        SELECT user_message, bot_response 
        FROM chat_history 
        WHERE session_id = ? 
        ORDER BY timestamp DESC 
        LIMIT ?;
        """
        self.cursor.execute(select_query, (session_id, limit))
        results = self.cursor.fetchall()
        
        # SQLite returns Row objects. We convert them to standard dicts and reverse them.
        return list(reversed([dict(row) for row in results]))

    def close(self):
        """Safely shuts down the database connection."""
        self.cursor.close()
        self.conn.close()
        print("🔌 Database connection closed.")

# --- EXECUTION BLOCK ---
if __name__ == "__main__":
    db = MindGuardDatabase()
    
    # Simulate a user session
    test_session = "user_mohit_001"
    
    print("\n--- Testing Database Save ---")
    db.save_interaction(
        session_id=test_session,
        user_message="I have a massive presentation tomorrow and my chest is tight.",
        bot_response="I can sense the tension... start humming a low note.",
        emotion="Nervousness",
        risk_level="Medium"
    )
    
    print("\n--- Testing Database Retrieval ---")
    history = db.get_recent_history(session_id=test_session)
    for row in history:
        print(f"User said: {row['user_message']}")
        print(f"Bot said: {row['bot_response'][:50]}...") # Truncated for readability
        
    db.close()