persist perplexity per assistant message; display on loaded convos
This commit is contained in:
@@ -123,6 +123,7 @@ def init_db():
|
|||||||
CREATE TABLE IF NOT EXISTS messages (
|
CREATE TABLE IF NOT EXISTS messages (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT, conversation_id TEXT NOT NULL,
|
id INTEGER PRIMARY KEY AUTOINCREMENT, conversation_id TEXT NOT NULL,
|
||||||
role TEXT NOT NULL, content TEXT NOT NULL, created_at TEXT NOT NULL,
|
role TEXT NOT NULL, content TEXT NOT NULL, created_at TEXT NOT NULL,
|
||||||
|
perplexity REAL,
|
||||||
FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE
|
FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
@@ -164,6 +165,11 @@ def init_db():
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn.execute("ALTER TABLE messages ADD COLUMN perplexity REAL")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
if not conn.execute("SELECT id FROM profile WHERE id = 1").fetchone():
|
if not conn.execute("SELECT id FROM profile WHERE id = 1").fetchone():
|
||||||
now = datetime.now(timezone.utc).isoformat()
|
now = datetime.now(timezone.utc).isoformat()
|
||||||
conn.execute("INSERT INTO profile (id, content, updated_at) VALUES (1, ?, ?)", (DEFAULT_PROFILE, now))
|
conn.execute("INSERT INTO profile (id, content, updated_at) VALUES (1, ?, ?)", (DEFAULT_PROFILE, now))
|
||||||
|
|||||||
+6
-6
@@ -114,8 +114,8 @@ async def chat(request: Request):
|
|||||||
else:
|
else:
|
||||||
db.execute("UPDATE conversations SET updated_at = ? WHERE id = ?", (now, conv_id))
|
db.execute("UPDATE conversations SET updated_at = ? WHERE id = ?", (now, conv_id))
|
||||||
|
|
||||||
db.execute("INSERT INTO messages (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)",
|
db.execute("INSERT INTO messages (conversation_id, role, content, created_at, perplexity) VALUES (?, ?, ?, ?, ?)",
|
||||||
(conv_id, "user", encrypt_text(user_message), now))
|
(conv_id, "user", encrypt_text(user_message), now, None))
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
raw_rows = db.execute(
|
raw_rows = db.execute(
|
||||||
@@ -218,8 +218,8 @@ async def chat(request: Request):
|
|||||||
saved_msg = remember_response + "\n\n" + saved_msg
|
saved_msg = remember_response + "\n\n" + saved_msg
|
||||||
|
|
||||||
db2 = get_db()
|
db2 = get_db()
|
||||||
db2.execute("INSERT INTO messages (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)",
|
db2.execute("INSERT INTO messages (conversation_id, role, content, created_at, perplexity) VALUES (?, ?, ?, ?, ?)",
|
||||||
(conv_id, "assistant", encrypt_text(saved_msg), datetime.now(timezone.utc).isoformat()))
|
(conv_id, "assistant", encrypt_text(saved_msg), datetime.now(timezone.utc).isoformat(), round(perplexity, 2)))
|
||||||
db2.commit()
|
db2.commit()
|
||||||
db2.close()
|
db2.close()
|
||||||
|
|
||||||
@@ -240,8 +240,8 @@ async def chat(request: Request):
|
|||||||
saved_msg = remember_response + "\n\n" + saved_msg
|
saved_msg = remember_response + "\n\n" + saved_msg
|
||||||
|
|
||||||
db2 = get_db()
|
db2 = get_db()
|
||||||
db2.execute("INSERT INTO messages (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)",
|
db2.execute("INSERT INTO messages (conversation_id, role, content, created_at, perplexity) VALUES (?, ?, ?, ?, ?)",
|
||||||
(conv_id, "assistant", encrypt_text(saved_msg), datetime.now(timezone.utc).isoformat()))
|
(conv_id, "assistant", encrypt_text(saved_msg), datetime.now(timezone.utc).isoformat(), round(perplexity, 2)))
|
||||||
db2.commit()
|
db2.commit()
|
||||||
db2.close()
|
db2.close()
|
||||||
|
|
||||||
|
|||||||
@@ -132,8 +132,8 @@ async def chat_completions(request: Request):
|
|||||||
content = msg.get("content", "")
|
content = msg.get("content", "")
|
||||||
if role in ("user", "assistant"):
|
if role in ("user", "assistant"):
|
||||||
db.execute(
|
db.execute(
|
||||||
"INSERT INTO messages (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)",
|
"INSERT INTO messages (conversation_id, role, content, created_at, perplexity) VALUES (?, ?, ?, ?, ?)",
|
||||||
(conv_id, role, encrypt_text(content), now),
|
(conv_id, role, encrypt_text(content), now, None),
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
@@ -195,8 +195,8 @@ async def _stream_chat(payload: dict, model: str, conv_id: str, request: Request
|
|||||||
if assistant_msg:
|
if assistant_msg:
|
||||||
db = get_db()
|
db = get_db()
|
||||||
db.execute(
|
db.execute(
|
||||||
"INSERT INTO messages (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)",
|
"INSERT INTO messages (conversation_id, role, content, created_at, perplexity) VALUES (?, ?, ?, ?, ?)",
|
||||||
(conv_id, "assistant", encrypt_text(assistant_msg), datetime.now(timezone.utc).isoformat()),
|
(conv_id, "assistant", encrypt_text(assistant_msg), datetime.now(timezone.utc).isoformat(), None),
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.close()
|
db.close()
|
||||||
@@ -240,8 +240,8 @@ async def _blocking_chat(payload: dict, model: str, conv_id: str, request: Reque
|
|||||||
if assistant_msg:
|
if assistant_msg:
|
||||||
db = get_db()
|
db = get_db()
|
||||||
db.execute(
|
db.execute(
|
||||||
"INSERT INTO messages (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)",
|
"INSERT INTO messages (conversation_id, role, content, created_at, perplexity) VALUES (?, ?, ?, ?, ?)",
|
||||||
(conv_id, "assistant", encrypt_text(assistant_msg), datetime.now(timezone.utc).isoformat()),
|
(conv_id, "assistant", encrypt_text(assistant_msg), datetime.now(timezone.utc).isoformat(), None),
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.close()
|
db.close()
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ async def explicit_search(request: Request):
|
|||||||
else:
|
else:
|
||||||
db.execute("UPDATE conversations SET updated_at = ? WHERE id = ?", (now, conv_id))
|
db.execute("UPDATE conversations SET updated_at = ? WHERE id = ?", (now, conv_id))
|
||||||
|
|
||||||
db.execute("INSERT INTO messages (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)",
|
db.execute("INSERT INTO messages (conversation_id, role, content, created_at, perplexity) VALUES (?, ?, ?, ?, ?)",
|
||||||
(conv_id, "user", encrypt_text(query), now))
|
(conv_id, "user", encrypt_text(query), now, None))
|
||||||
db.commit()
|
db.commit()
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
@@ -60,8 +60,8 @@ async def explicit_search(request: Request):
|
|||||||
error_msg = "No search results found."
|
error_msg = "No search results found."
|
||||||
yield f"data: {json.dumps({'token': error_msg, 'conversation_id': conv_id})}\n\n"
|
yield f"data: {json.dumps({'token': error_msg, 'conversation_id': conv_id})}\n\n"
|
||||||
db2 = get_db()
|
db2 = get_db()
|
||||||
db2.execute("INSERT INTO messages (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)",
|
db2.execute("INSERT INTO messages (conversation_id, role, content, created_at, perplexity) VALUES (?, ?, ?, ?, ?)",
|
||||||
(conv_id, "assistant", encrypt_text(error_msg), datetime.now(timezone.utc).isoformat()))
|
(conv_id, "assistant", encrypt_text(error_msg), datetime.now(timezone.utc).isoformat(), None))
|
||||||
db2.commit()
|
db2.commit()
|
||||||
db2.close()
|
db2.close()
|
||||||
yield f"data: {json.dumps({'done': True, 'conversation_id': conv_id})}\n\n"
|
yield f"data: {json.dumps({'done': True, 'conversation_id': conv_id})}\n\n"
|
||||||
@@ -102,8 +102,8 @@ async def explicit_search(request: Request):
|
|||||||
saved_msg = f"{summary}\n\n---\n*🔍 Web search results*"
|
saved_msg = f"{summary}\n\n---\n*🔍 Web search results*"
|
||||||
|
|
||||||
db2 = get_db()
|
db2 = get_db()
|
||||||
db2.execute("INSERT INTO messages (conversation_id, role, content, created_at) VALUES (?, ?, ?, ?)",
|
db2.execute("INSERT INTO messages (conversation_id, role, content, created_at, perplexity) VALUES (?, ?, ?, ?, ?)",
|
||||||
(conv_id, "assistant", encrypt_text(saved_msg), datetime.now(timezone.utc).isoformat()))
|
(conv_id, "assistant", encrypt_text(saved_msg), datetime.now(timezone.utc).isoformat(), None))
|
||||||
db2.commit()
|
db2.commit()
|
||||||
db2.close()
|
db2.close()
|
||||||
|
|
||||||
|
|||||||
+13
-3
@@ -1154,7 +1154,7 @@ async function loadConversation(convId) {
|
|||||||
const container = document.getElementById('chatContainer');
|
const container = document.getElementById('chatContainer');
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
conversationHistory = [];
|
conversationHistory = [];
|
||||||
data.messages.forEach(msg => { appendMessage(msg.role, msg.content, false); conversationHistory.push({ role: msg.role, content: msg.content }); });
|
data.messages.forEach(msg => { appendMessage(msg.role, msg.content, false, false, null, msg.perplexity); conversationHistory.push({ role: msg.role, content: msg.content }); });
|
||||||
scrollToLatest();
|
scrollToLatest();
|
||||||
await loadConversations();
|
await loadConversations();
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
@@ -1500,7 +1500,7 @@ function setStreamingState(streaming) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendMessage(role, content, animate, isSearch = false, afterEl = null) {
|
function appendMessage(role, content, animate, isSearch = false, afterEl = null, perplexity = null) {
|
||||||
const container = document.getElementById('chatContainer');
|
const container = document.getElementById('chatContainer');
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.className = 'message ' + role + (isSearch && role === 'assistant' ? ' search-result' : '');
|
div.className = 'message ' + role + (isSearch && role === 'assistant' ? ' search-result' : '');
|
||||||
@@ -1511,7 +1511,17 @@ function appendMessage(role, content, animate, isSearch = false, afterEl = null)
|
|||||||
const timeStr = months[now.getMonth()] + ' ' + String(now.getDate()).padStart(2,'0') + ', ' + now.getFullYear() + ' ' + String(now.getHours()).padStart(2,'0') + ':' + String(now.getMinutes()).padStart(2,'0') + ':' + String(now.getSeconds()).padStart(2,'0') + '.' + String(Math.floor(ms / 10)).padStart(2,'0');
|
const timeStr = months[now.getMonth()] + ' ' + String(now.getDate()).padStart(2,'0') + ', ' + now.getFullYear() + ' ' + String(now.getHours()).padStart(2,'0') + ':' + String(now.getMinutes()).padStart(2,'0') + ':' + String(now.getSeconds()).padStart(2,'0') + '.' + String(Math.floor(ms / 10)).padStart(2,'0');
|
||||||
const textHtml = content ? renderMarkdown(content) : '';
|
const textHtml = content ? renderMarkdown(content) : '';
|
||||||
const copyIcon = role === 'user' && content ? `<span class="user-copy-btn" data-content="${escapeHtml(content).replace(/"/g,'"')}" onclick="var el=this;event.stopPropagation();var t=el.getAttribute('data-content');function d(){el.textContent='✓';setTimeout(function(){el.innerHTML='📋'},1500);showToast('Copied')}if(navigator.clipboard){navigator.clipboard.writeText(t).then(d).catch(function(){execCopy(t);d()})}else{execCopy(t);d()}">📋</span>` : '';
|
const copyIcon = role === 'user' && content ? `<span class="user-copy-btn" data-content="${escapeHtml(content).replace(/"/g,'"')}" onclick="var el=this;event.stopPropagation();var t=el.getAttribute('data-content');function d(){el.textContent='✓';setTimeout(function(){el.innerHTML='📋'},1500);showToast('Copied')}if(navigator.clipboard){navigator.clipboard.writeText(t).then(d).catch(function(){execCopy(t);d()})}else{execCopy(t);d()}">📋</span>` : '';
|
||||||
div.innerHTML = `<div class="avatar">${role === 'user' ? 'YOU' : 'cAIc'}</div><div class="content"><div class="role-label">${role === 'assistant' ? modelLabel() : role}${role === 'user' ? ' <span class="msg-time">' + timeStr + '</span>' : ''}</div><div class="text">${textHtml}${copyIcon}</div>${role === 'assistant' ? '<div class="msg-toolbar"></div>' : ''}</div>`;
|
let roleLabelHtml = role === 'assistant' ? modelLabel() : role;
|
||||||
|
roleLabelHtml += role === 'user' ? ' <span class="msg-time">' + timeStr + '</span>' : '';
|
||||||
|
if (role === 'assistant' && perplexity != null) {
|
||||||
|
const ppl = parseFloat(perplexity);
|
||||||
|
if (!isNaN(ppl)) {
|
||||||
|
const conf = Math.round(Math.max(0, Math.min(100, (1 - (ppl - 1) / 10) * 100)));
|
||||||
|
const cls = conf >= 80 ? 'high' : conf >= 15 ? 'medium' : 'low';
|
||||||
|
roleLabelHtml += `<span class="conf-badge ${cls}">${conf}%</span>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div.innerHTML = `<div class="avatar">${role === 'user' ? 'YOU' : 'cAIc'}</div><div class="content"><div class="role-label">${roleLabelHtml}</div><div class="text">${textHtml}${copyIcon}</div>${role === 'assistant' ? '<div class="msg-toolbar"></div>' : ''}</div>`;
|
||||||
if (role === 'user') {
|
if (role === 'user') {
|
||||||
const pair = document.createElement('div');
|
const pair = document.createElement('div');
|
||||||
pair.className = 'msg-pair' + (isSearch ? ' search-pair' : '');
|
pair.className = 'msg-pair' + (isSearch ? ' search-pair' : '');
|
||||||
|
|||||||
Reference in New Issue
Block a user