document.addEventListener("DOMContentLoaded", () => { const chatForm = document.getElementById("chat-form"); const userInput = document.getElementById("user-input"); const messagesContainer = document.getElementById("messages-container"); const tokenInput = document.getElementById("hf-token"); // Load saved HF Token from localStorage if present if (localStorage.getItem("hf_token")) { tokenInput.value = localStorage.getItem("hf_token"); } // Auto-resize textarea userInput.addEventListener("input", () => { userInput.style.height = "auto"; userInput.style.height = userInput.scrollHeight + "px"; }); // Handle shift+enter to submit userInput.addEventListener("keydown", (e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); chatForm.dispatchEvent(new Event("submit")); } }); // Save token changes tokenInput.addEventListener("change", () => { localStorage.setItem("hf_token", tokenInput.value.trim()); }); // Chat history state let chatHistory = []; // Parse streaming response async function handleStreamingResponse(response, messageEl, contentEl) { const reader = response.body.getReader(); const decoder = new TextDecoder("utf-8"); let buffer = ""; let fullText = ""; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split("\n"); buffer = lines.pop(); for (const line of lines) { const cleanLine = line.trim(); if (!cleanLine) continue; if (cleanLine.startsWith("data:")) { const dataStr = cleanLine.substring(5).trim(); if (dataStr === "[DONE]") break; try { const dataObj = JSON.parse(dataStr); const token = dataObj.choices[0].delta.content; if (token) { fullText += token; // Render Markdown contentEl.innerHTML = marked.parse(fullText); // Run Prism syntax highlighting Prism.highlightAllUnder(contentEl); // Auto scroll messagesContainer.scrollTop = messagesContainer.scrollHeight; } } catch (err) { // Suppress JSON parse errors on partial streams } } } } return fullText; } // Submit form handler chatForm.submit = async (e) => { // Fallback for form submit }; chatForm.addEventListener("submit", async (e) => { e.preventDefault(); const text = userInput.value.trim(); if (!text) return; // Reset input area userInput.value = ""; userInput.style.height = "auto"; // Append user message const userMsgEl = document.createElement("div"); userMsgEl.className = "message user-message"; userMsgEl.innerHTML = `