| 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"); |
|
|
| |
| 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 = ` |
| <div class="dot"></div> |
| <div class="dot"></div> |
| <div class="dot"></div> |
| `; |
| } |
|
|
| 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(); |
|
|