File size: 4,194 Bytes
a5baa63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
718aa48
 
a84172d
 
718aa48
 
 
 
 
 
 
 
 
a5baa63
718aa48
 
 
 
 
 
 
 
 
 
 
 
a84172d
 
 
 
718aa48
 
 
 
 
a5baa63
 
 
a84172d
718aa48
 
 
 
 
 
 
 
 
 
 
 
a84172d
718aa48
 
 
 
 
a84172d
 
a5baa63
 
 
 
a84172d
 
718aa48
 
 
a5baa63
718aa48
 
 
 
 
 
 
 
a5baa63
718aa48
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// === Global Model List ===
const MODEL_LIST = [
  { id: "deepseek/deepseek-chat-v3-0324:free", name: "DeepSeek Chat v3" },
  { id: "google/gemini-2.0-flash-exp:free", name: "Gemini 2.0 Flash" },
  { id: "meta-llama/llama-4-maverick:free", name: "LLaMA 4 Maverick" },
  { id: "microsoft/mai-ds-r1:free", name: "MAI DS R1" },
  { id: "meta-llama/llama-4-scout:free", name: "LLaMA 4 Scout" },
  { id: "google/gemma-3-27b-it:free", name: "Gemma 3 27B" },
  { id: "qwen/qwq-32b:free", name: "Qwen QWQ 32B" },
  { id: "qwen/qwen2.5-vl-72b-instruct:free", name: "Qwen2.5 VL 72B" },
  { id: "qwen/qwen-2.5-72b-instruct:free", name: "Qwen 2.5 72B" },
  { id: "google/gemini-2.5-pro-exp-03-25:free", name: "Gemini 2.5 Pro" },
  { id: "deepseek/deepseek-r1:free", name: "DeepSeek R1" }
];

// === Populate Custom Dropdowns ===
function createDropdown(dropdownId) {
  const dropdown = document.getElementById(dropdownId);
  const selected = dropdown.querySelector(".selected");
  const options = dropdown.querySelector(".options");

  MODEL_LIST.forEach(model => {
    const option = document.createElement("div");
    option.className = "p-2 hover:bg-visual_green rounded cursor-pointer";
    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;
      options.classList.add("hidden");
    });
  });

  selected.addEventListener("click", (e) => {
    e.stopPropagation();
    options.classList.toggle("hidden");
  });

  // Close dropdowns if clicking outside
  document.addEventListener("click", () => {
    options.classList.add("hidden");
  });
}

// === Theme Toggle ===
const themeToggle = document.getElementById("themeToggle");
const toggleConfig = document.getElementById("toggleConfig");
const configPanel = document.getElementById("configPanel");
const html = document.documentElement;

function setInitialTheme() {
  const savedTheme = localStorage.getItem("theme");
  if (savedTheme === "dark") {
    html.classList.add("dark");
  } else if (savedTheme === "light") {
    html.classList.remove("dark");
  } else {
    const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
    if (prefersDark) html.classList.add("dark");
    else html.classList.remove("dark");
  }
}

setInitialTheme();

themeToggle.addEventListener("click", () => {
  const isDark = html.classList.toggle("dark");
  localStorage.setItem("theme", isDark ? "dark" : "light");
});

toggleConfig.addEventListener("click", () => {
  configPanel.classList.toggle("hidden");
});

// === Chat Handling ===
const chatForm = document.getElementById("chatForm");
const userInput = document.getElementById("userInput");
const chatContainer = document.getElementById("chatContainer");

createDropdown("modelA");
createDropdown("modelB");
createDropdown("modelC");

function appendMessage(role, text) {
  const div = document.createElement("div");
  div.className = `p-3 rounded shadow max-w-2xl ${role === "user" ? "bg-blue text-fg0 self-end" : "bg-green text-fg0 self-start"}`;
  div.innerText = text;
  chatContainer.appendChild(div);
  chatContainer.scrollTop = chatContainer.scrollHeight;
}

chatForm.addEventListener("submit", async (e) => {
  e.preventDefault();
  const prompt = userInput.value.trim();
  if (!prompt) return;

  appendMessage("user", prompt);
  userInput.value = "";

  appendMessage("bot", "Thinking...");

  const settings = {
    models: {
      "LLM-A": document.getElementById("modelA").dataset.value,
      "LLM-B": document.getElementById("modelB").dataset.value,
      "LLM-C": document.getElementById("modelC").dataset.value,
    }
  };

  const response = await fetch("/chat", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ prompt, settings })
  });

  chatContainer.lastChild.remove(); // remove 'Thinking...'

  if (response.ok) {
    const data = await response.json();
    appendMessage("bot", data.response);
  } else {
    appendMessage("bot", "An error occurred. Please check your model selections.");
  }
});