NLP-Hub / static /js /task3_chat.js
Manas
Recommit files with PNGs tracked by LFS
6124cbc
document.addEventListener("DOMContentLoaded", () => {
const chatLog = document.getElementById("task3ChatLog");
const userInput = document.getElementById("task3UserInput");
const sendBtn = document.getElementById("task3SendBtn");
const WELCOME = "Send a message and compare what each variety-tuned LoRA adapter predicts. (First call per dialect lazy-loads the adapter, so expect a short delay.)";
let loadingCounter = 0;
const varietyOrder = ["en-AU", "en-IN", "en-UK"];
const models = Object.entries(TASK3_MODELS)
.map(([key, model]) => ({ key, ...model }))
.sort((a, b) => varietyOrder.indexOf(a.trained_on) - varietyOrder.indexOf(b.trained_on));
userInput.addEventListener("input", () => {
userInput.style.height = "auto";
userInput.style.height = Math.min(userInput.scrollHeight, 140) + "px";
});
userInput.addEventListener("keydown", event => {
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
sendMessage();
}
});
sendBtn.addEventListener("click", sendMessage);
async function sendMessage() {
const text = userInput.value.trim();
if (!text) return;
if (models.length === 0) {
appendMsg("bot", "No models are registered for Task 3.");
return;
}
appendMsg("user", text);
userInput.value = "";
userInput.style.height = "auto";
sendBtn.disabled = true;
const requests = models.map(model => runModel(model, text));
await Promise.allSettled(requests);
sendBtn.disabled = false;
userInput.focus();
}
async function runModel(model, text) {
const loadingId = appendLoading(model);
try {
const response = await fetch("/api/task3/infer", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text, task: "sarcasm", model_key: model.key }),
});
const data = await response.json();
removeLoading(loadingId);
if (data.error) {
appendMsg("bot", `Warning: ${escapeHTML(data.error)}`, model);
} else {
appendMsg("bot", formatResult(data, model), model);
}
} catch (error) {
removeLoading(loadingId);
appendMsg("bot", `Warning: Network error: ${escapeHTML(error.message)}`, model);
}
}
function appendMsg(role, content, model = null) {
const wrapper = document.createElement("div");
wrapper.className = `msg ${role}`;
const avatar = document.createElement("div");
avatar.className = "msg-avatar";
avatar.innerHTML = role === "bot"
? '<i class="fa-solid fa-microchip"></i>'
: '<i class="fa-solid fa-user"></i>';
const bubble = document.createElement("div");
bubble.className = "msg-bubble";
bubble.innerHTML = role === "bot" ? content : escapeHTML(content);
wrapper.appendChild(avatar);
wrapper.appendChild(bubble);
chatLog.appendChild(wrapper);
chatLog.scrollTop = chatLog.scrollHeight;
}
function appendLoading(model) {
const id = `task3-loading-${++loadingCounter}`;
const wrapper = document.createElement("div");
wrapper.className = "msg bot";
wrapper.id = id;
wrapper.innerHTML = `
<div class="msg-avatar"><i class="fa-solid fa-microchip"></i></div>
<div class="msg-bubble">
<div class="model-badge">${escapeHTML(model.name)} <span>Trained on ${escapeHTML(model.trained_on)}</span></div>
<div class="loading-dots"><span></span><span></span><span></span></div>
</div>
`;
chatLog.appendChild(wrapper);
chatLog.scrollTop = chatLog.scrollHeight;
return id;
}
function removeLoading(id) {
const element = document.getElementById(id);
if (element) element.remove();
}
function formatResult(data, model) {
const raw = String(data.label || "").toUpperCase();
let display = data.label || "Unknown";
if (raw === "SARCASTIC" || raw === "LABEL_1" || raw === "1") display = "Sarcastic";
if (raw === "NOT_SARCASTIC" || raw === "LABEL_0" || raw === "0") display = "Not Sarcastic";
const score = data.score !== undefined ? `<span class="rs">Score: ${data.score}</span>` : "";
const trainedOn = data.trained_on || model.trained_on || "";
return `
<div class="model-badge">${escapeHTML(model.name)} <span>Trained on ${escapeHTML(trainedOn)}</span></div>
<div class="result-block">
<span class="rl">Result:</span> <span class="rv">${escapeHTML(display)}</span>
${score}
</div>
`;
}
function escapeHTML(str) {
return String(str).replace(/[&<>"']/g, tag => ({
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#39;",
}[tag]));
}
});