|
|
import sqlite3 |
|
|
import datetime |
|
|
import os |
|
|
|
|
|
|
|
|
DB_FILE = "/data/chats.db" |
|
|
|
|
|
def init_db(): |
|
|
|
|
|
print(f"Database path: {DB_FILE}") |
|
|
db_dir = os.path.dirname(DB_FILE) |
|
|
print(f"Database directory: {db_dir}") |
|
|
if not os.path.exists(db_dir): |
|
|
print(f"Directory {db_dir} does not exist, attempting to create it") |
|
|
try: |
|
|
os.makedirs(db_dir, exist_ok=True) |
|
|
except Exception as e: |
|
|
print(f"Failed to create directory {db_dir}: {str(e)}") |
|
|
raise RuntimeError(f"Cannot create directory {db_dir}: {str(e)}") |
|
|
if not os.access(db_dir, os.W_OK): |
|
|
print(f"Directory {db_dir} is not writable") |
|
|
raise RuntimeError(f"Directory {db_dir} is not writable") |
|
|
|
|
|
|
|
|
print(f"Attempting to connect to database at {DB_FILE}") |
|
|
try: |
|
|
with sqlite3.connect(DB_FILE) as conn: |
|
|
print("Successfully connected to database") |
|
|
c = conn.cursor() |
|
|
c.execute(''' |
|
|
CREATE TABLE IF NOT EXISTS chats ( |
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT, |
|
|
title TEXT, |
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
|
|
) |
|
|
''') |
|
|
c.execute(''' |
|
|
CREATE TABLE IF NOT EXISTS messages ( |
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT, |
|
|
chat_id INTEGER, |
|
|
role TEXT, |
|
|
content TEXT, |
|
|
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, |
|
|
FOREIGN KEY(chat_id) REFERENCES chats(id) |
|
|
) |
|
|
''') |
|
|
conn.commit() |
|
|
print("Database tables created successfully") |
|
|
except sqlite3.OperationalError as e: |
|
|
print(f"SQLite error: {str(e)}") |
|
|
raise |
|
|
|
|
|
|
|
|
def create_new_chat(): |
|
|
title = f"Chat {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" |
|
|
with sqlite3.connect(DB_FILE) as conn: |
|
|
c = conn.cursor() |
|
|
c.execute("INSERT INTO chats (title) VALUES (?)", (title,)) |
|
|
chat_id = c.lastrowid |
|
|
conn.commit() |
|
|
return chat_id |
|
|
|
|
|
def get_all_chats(): |
|
|
with sqlite3.connect(DB_FILE) as conn: |
|
|
c = conn.cursor() |
|
|
c.execute("SELECT id, title FROM chats ORDER BY id DESC") |
|
|
chats = c.fetchall() |
|
|
return chats |
|
|
|
|
|
def get_messages(chat_id): |
|
|
with sqlite3.connect(DB_FILE) as conn: |
|
|
c = conn.cursor() |
|
|
c.execute("SELECT role, content FROM messages WHERE chat_id = ? ORDER BY id", (chat_id,)) |
|
|
messages = c.fetchall() |
|
|
return messages |
|
|
|
|
|
def save_message(chat_id, role, content): |
|
|
with sqlite3.connect(DB_FILE) as conn: |
|
|
c = conn.cursor() |
|
|
c.execute("INSERT INTO messages (chat_id, role, content) VALUES (?, ?, ?)", (chat_id, role, content)) |
|
|
conn.commit() |
|
|
|
|
|
def system_prompt() -> str: |
|
|
return """ |
|
|
You are a friendly, intelligent, and reliable AI assistant. Your role is to help users with any questions or tasks they might have—whether expected or unexpected. Respond professionally, clearly, and concisely. Always remain calm and constructive, even when the user's input is vague, off-topic, or unusual. |
|
|
|
|
|
Key Behavior Guidelines: |
|
|
Friendly Introduction |
|
|
Greet the user politely and introduce yourself if it’s the first message. Example: |
|
|
“Hi there! I’m Juma's assistant. How can I help you today?” |
|
|
|
|
|
Understand and Clarify |
|
|
|
|
|
If the prompt is clear, respond helpfully. |
|
|
|
|
|
If unclear or unexpected, ask for clarification in a polite and constructive way. Example: |
|
|
“I didn’t quite catch that. Could you please explain a bit more?” |
|
|
|
|
|
Respond Appropriately |
|
|
|
|
|
Give direct, accurate answers when you can. |
|
|
|
|
|
If you don’t know something, say so honestly and suggest alternatives. Example: |
|
|
“I’m not certain about that, but here’s something related that might help...” |
|
|
|
|
|
Avoid Repetition & Filler |
|
|
|
|
|
Do not repeat the user’s name unnecessarily. |
|
|
|
|
|
Avoid phrases like “I’m just an assistant” or repeating your willingness to help multiple times. |
|
|
|
|
|
Stay On Topic, Guide Gently |
|
|
|
|
|
If the user goes off-topic, gently guide them back. |
|
|
|
|
|
If a prompt is strange or humorous, engage politely or play along if appropriate, without losing professionalism. |
|
|
|
|
|
Closing or Transitions |
|
|
End conversations politely or transition smoothly to the next task. Example: |
|
|
“Glad I could help! Let me know if there’s anything else.” |
|
|
|
|
|
General Rules |
|
|
|
|
|
Be clear, concise, and structured in your responses. |
|
|
|
|
|
Use bullet points or steps if listing instructions. |
|
|
|
|
|
Stay neutral, inclusive, and respectful at all times.""" |