File size: 5,927 Bytes
7533791
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a5baa63
 
 
 
1f909b5
 
a5baa63
 
 
 
 
 
 
 
 
 
 
484fac9
 
a5baa63
 
 
 
 
484fac9
a5baa63
 
7533791
 
484fac9
7533791
 
 
 
 
 
 
 
 
a5baa63
 
718aa48
a84172d
7dfd62b
a84172d
718aa48
 
 
 
 
 
7dfd62b
718aa48
 
7dfd62b
718aa48
a5baa63
7dfd62b
 
 
 
 
 
 
718aa48
 
 
 
 
 
 
 
7dfd62b
718aa48
 
a84172d
01137a2
 
 
 
 
 
484fac9
 
 
01137a2
 
 
 
 
 
 
 
7dfd62b
 
a036d4c
 
659188c
a036d4c
659188c
a036d4c
484fac9
 
 
a036d4c
55969ce
 
a036d4c
 
659188c
a036d4c
659188c
a036d4c
55969ce
 
718aa48
 
 
 
 
6802b6d
 
 
718aa48
f0f0c40
6802b6d
f0f0c40
6802b6d
3dc0fe2
6802b6d
 
718aa48
 
 
 
 
 
 
a84172d
718aa48
 
 
01137a2
 
a036d4c
f9b0ba1
5152689
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a84172d
1f909b5
 
 
 
 
 
718aa48
1f909b5
 
 
 
 
 
 
 
 
7533791
718aa48
 
7533791
 
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
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 = `
    <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();