let MODEL_LIST = []; async function fetchModelList() { try { const response = await fetch("/models"); if (response.ok) { MODEL_LIST = await response.json(); initializeDropdowns(); } else { console.error("Failed to fetch model list"); } } catch (error) { console.error("Error fetching models:", error); } } function createDropdown(dropdownId) { const dropdown = document.getElementById(dropdownId); const selected = dropdown.querySelector(".selected"); const options = dropdown.querySelector(".options"); const modelZone = dropdown.closest(".model-zone"); const nameDisplay = modelZone.querySelector(".model-name"); MODEL_LIST.forEach(model => { const option = document.createElement("div"); option.textContent = model.name; option.dataset.value = model.id; options.appendChild(option); option.addEventListener("click", (e) => { e.stopPropagation(); selected.textContent = model.name; dropdown.dataset.value = model.id; if (nameDisplay) nameDisplay.textContent = model.name; options.classList.remove("show"); }); }); selected.addEventListener("click", (e) => { e.stopPropagation(); options.classList.toggle("show"); }); document.addEventListener("click", (e) => { if (!dropdown.contains(e.target)) { options.classList.remove("show"); } }); } function initializeDropdowns() { createDropdown("modelA"); createDropdown("modelB"); createDropdown("modelC"); createDropdown("aggregator"); } const themeToggle = document.getElementById("themeToggle"); const toggleConfig = document.getElementById("toggleConfig"); const docsButton = document.getElementById("docsButton"); const configPanel = document.getElementById("configPanel"); const html = document.documentElement; function setInitialTheme() { const savedTheme = localStorage.getItem("theme"); if (savedTheme === "dark") { html.classList.add("dark"); themeToggle.textContent = "🌙"; } else if (savedTheme === "light") { html.classList.remove("dark"); themeToggle.textContent = "☀️"; } else { const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; if (prefersDark) { html.classList.add("dark"); themeToggle.textContent = "🌙"; } else { html.classList.remove("dark"); themeToggle.textContent = "☀️"; } } } setInitialTheme(); themeToggle.addEventListener("click", () => { const isDark = html.classList.toggle("dark"); localStorage.setItem("theme", isDark ? "dark" : "light"); themeToggle.textContent = isDark ? "🌙" : "☀️"; }); toggleConfig.addEventListener("click", () => { if (configPanel.classList.contains("minimal")) { configPanel.classList.remove("minimal"); configPanel.classList.add("expanded"); } else if (configPanel.classList.contains("expanded")) { configPanel.classList.remove("expanded"); configPanel.classList.add("minimal"); // Force close any dropdowns document.querySelectorAll(".options").forEach(opt => opt.classList.remove("show")); } else { configPanel.classList.add("expanded"); configPanel.classList.remove("hidden"); } }); docsButton.addEventListener("click", () => { window.location.href = "/docs"; }); function showLoader(id) { const loader = document.getElementById(`loader${id}`); const modelZone = loader.closest(".model-zone"); loader.classList.remove("hidden"); modelZone.classList.add("loading"); loader.innerHTML = `
`; } function hideLoader(id) { const loader = document.getElementById(`loader${id}`); const modelZone = loader.closest(".model-zone"); loader.classList.add("hidden"); modelZone.classList.remove("loading"); loader.innerHTML = ""; } const chatForm = document.getElementById("chatForm"); const userInput = document.getElementById("userInput"); const chatContainer = document.getElementById("chatContainer"); function appendMessage(role, text) { const wrapper = document.createElement("div"); wrapper.className = `flex ${role === "user" ? "justify-end" : "justify-start"}`; const div = document.createElement("div"); div.className = `p-3 rounded shadow max-w-2xl whitespace-pre-wrap break-words ${ role === "user" ? "bg-blue text-fg0" : "bg-green text-fg0" }`; div.textContent = text; wrapper.appendChild(div); chatContainer.appendChild(wrapper); chatContainer.scrollTop = chatContainer.scrollHeight; } chatForm.addEventListener("submit", async (e) => { e.preventDefault(); const prompt = userInput.value.trim(); if (!prompt) return; appendMessage("user", prompt); userInput.value = ""; configPanel.classList.remove("expanded"); configPanel.classList.add("minimal"); const selections = { "LLM-A": document.getElementById("modelA").dataset.value, "LLM-B": document.getElementById("modelB").dataset.value, "LLM-C": document.getElementById("modelC").dataset.value, "LLM-D": document.getElementById("aggregator").dataset.value }; ["A", "B", "C"].forEach(id => showLoader(id)); const settings = { models: { "LLM-A": selections["LLM-A"], "LLM-B": selections["LLM-B"], "LLM-C": selections["LLM-C"] }, aggregator: selections["LLM-D"] }; try { const response = await fetch("/chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ prompt, settings }) }); if (response.ok) { const data = await response.json(); appendMessage("bot", data.response); } else { appendMessage("bot", "An error occurred. Please check your model selections."); } } catch (error) { appendMessage("bot", "An unexpected error occurred."); } finally { ["A", "B", "C", "D"].forEach(id => hideLoader(id)); } }); fetchModelList();