// All comments are in English. let conversationId = null; let conversations = []; async function login() { window.location = "/login"; } function toggleTheme() { document.body.classList.toggle("dark"); } async function loadConversations() { const r = await fetch("/api/conversations"); conversations = await r.json(); renderTabs(); } function renderTabs() { const tabs = document.getElementById("tabs"); tabs.innerHTML = ""; conversations.forEach(c => { const btn = document.createElement("button"); btn.textContent = c.title; btn.onclick = () => selectConversation(c.id); tabs.appendChild(btn); }); } async function newConversation() { const title = prompt("Conversation title:"); const r = await fetch("/api/new_conversation", { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({title}) }); const data = await r.json(); conversationId = data.conversation_id; await loadConversations(); await loadHistory(); } async function selectConversation(id) { conversationId = id; await loadHistory(); } async function loadHistory() { const r = await fetch(`/api/history/${conversationId}`); const msgs = await r.json(); const chat = document.getElementById("chat"); chat.innerHTML = ""; msgs.forEach(m => { const div = document.createElement("div"); div.className = "msg " + m.role; div.innerHTML = `
${m.role === "user" ? "🧑" : "🤖"}
${m.content}
`; chat.appendChild(div); }); // Load attachments const a = await fetch(`/api/attachments/${conversationId}`); const attachments = await a.json(); attachments.forEach(att => { const div = document.createElement("div"); div.className = "msg user"; div.innerHTML = `
🧑
Attachment: ${att.filename}
Download
`; chat.appendChild(div); }); } async function sendMessage() { const promptText = document.getElementById("prompt").value; const file = document.getElementById("attachment").files[0]; if (!conversationId) { await newConversation(); } if (file) { const form = new FormData(); form.append("file", file); await fetch(`/api/attachment/${conversationId}`, { method: "POST", body: form }); } const chat = document.getElementById("chat"); const userDiv = document.createElement("div"); userDiv.className = "msg user"; userDiv.innerHTML = `
🧑
${marked.parse(promptText)}
`; chat.appendChild(userDiv); const assistantDiv = document.createElement("div"); assistantDiv.className = "msg assistant streaming"; assistantDiv.innerHTML = `
🤖
▌
`; chat.appendChild(assistantDiv); const url = `/api/stream?conversation_id=${conversationId}&model=llama3.2&prompt=${encodeURIComponent(promptText)}`; const evtSource = new EventSource(url); let buffer = ""; const streamSpan = document.getElementById("stream-text"); evtSource.onmessage = (event) => { const data = JSON.parse(event.data); buffer += data.token; streamSpan.innerHTML = marked.parse(buffer); }; evtSource.onerror = () => { evtSource.close(); assistantDiv.classList.remove("streaming"); }; } window.onload = loadConversations;