SupaC's picture
Upload folder using huggingface_hub
db5fc17 verified
Raw History Blame Contribute Delete
6.04 kB
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 = `
<div class="avatar">👤</div>
<div class="message-content">${marked.parse(text)}</div>
`;
messagesContainer.appendChild(userMsgEl);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
// Prepare assistant placeholder
const assistantMsgEl = document.createElement("div");
assistantMsgEl.className = "message assistant-message";
assistantMsgEl.innerHTML = `
<div class="avatar">🧠</div>
<div class="message-content typing-indicator">Thinking...</div>
`;
messagesContainer.appendChild(assistantMsgEl);
messagesContainer.scrollTop = messagesContainer.scrollHeight;
const contentEl = assistantMsgEl.querySelector(".message-content");
// Format system + history + new prompt
const messages = [
{ role: "system", content: "You are a helpful coding assistant. Provide clean, correct, and well-structured code when asked." },
...chatHistory,
{ role: "user", content: text }
];
const token = tokenInput.value.trim();
const headers = {
"Content-Type": "application/json"
};
if (token) {
headers["Authorization"] = `Bearer ${token}`;
}
try {
const response = await fetch("https://api-inference.huggingface.co/models/Qwen/Qwen2.5-Coder-7B-Instruct/v1/chat/completions", {
method: "POST",
headers: headers,
body: JSON.stringify({
model: "Qwen/Qwen2.5-Coder-7B-Instruct",
messages: messages,
max_tokens: 2048,
temperature: 0.7,
top_p: 0.9,
stream: true
})
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
const errMsg = errorData.error?.message || response.statusText;
contentEl.innerHTML = `<span style="color: #ef4444;">API Error: ${errMsg}</span>`;
return;
}
contentEl.innerHTML = "";
contentEl.classList.remove("typing-indicator");
const fullText = await handleStreamingResponse(response, assistantMsgEl, contentEl);
// Save to history
chatHistory.push({ role: "user", content: text });
chatHistory.push({ role: "assistant", content: fullText });
} catch (err) {
contentEl.innerHTML = `<span style="color: #ef4444;">Connection Error: ${err.message}</span>`;
}
});
});