Spaces:
Sleeping
Sleeping
| document.addEventListener('DOMContentLoaded', () => { | |
| const startBtn = document.getElementById('startBtn'); | |
| const topicInput = document.getElementById('topicInput'); | |
| const arena = document.getElementById('arena'); | |
| const globalStatus = document.getElementById('globalStatus'); | |
| const modelStatusList = document.getElementById('modelStatusList'); | |
| const MODELS = [ | |
| 'openai/gpt-oss-120b', | |
| 'llama-3.3-70b-versatile', | |
| 'qwen/qwen3-32b', | |
| 'gemini-2.5-flash', | |
| 'Gemma 4 (Architect)' | |
| ]; | |
| function initSidebar() { | |
| modelStatusList.innerHTML = ''; | |
| MODELS.forEach(m => { | |
| const li = document.createElement('li'); | |
| li.id = `status-${m.replace(/[^a-zA-Z0-9]/g, '')}`; | |
| li.innerHTML = ` | |
| <span class="model-name">${m}</span> | |
| <span class="model-status">Awaiting task</span> | |
| `; | |
| modelStatusList.appendChild(li); | |
| }); | |
| } | |
| initSidebar(); | |
| startBtn.addEventListener('click', async () => { | |
| const topic = topicInput.value.trim(); | |
| if (!topic) return; | |
| startBtn.disabled = true; | |
| arena.innerHTML = ''; | |
| initSidebar(); | |
| try { | |
| const response = await fetch('/api/debate', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ topic }) | |
| }); | |
| const reader = response.body.getReader(); | |
| const decoder = new TextDecoder("utf-8"); | |
| let buffer = ""; | |
| while (true) { | |
| const { done, value } = await reader.read(); | |
| if (done) break; | |
| buffer += decoder.decode(value, { stream: true }); | |
| const lines = buffer.split('\n\n'); | |
| buffer = lines.pop() || ""; | |
| for (const chunk of lines) { | |
| if (chunk.trim() === '') continue; | |
| const eventMatch = chunk.match(/event: (.*)\n/); | |
| const dataMatch = chunk.match(/data: (.*)/); | |
| if (eventMatch && dataMatch) { | |
| const event = eventMatch[1]; | |
| const data = JSON.parse(dataMatch[1]); | |
| handleEvent(event, data); | |
| } | |
| } | |
| } | |
| } catch (error) { | |
| console.error(error); | |
| globalStatus.innerText = "Error occurred."; | |
| } finally { | |
| startBtn.disabled = false; | |
| } | |
| }); | |
| function handleEvent(event, data) { | |
| if (event === 'status') { | |
| globalStatus.innerText = data.message; | |
| } | |
| else if (event === 'model_start') { | |
| const id = `status-${data.model.replace(/[^a-zA-Z0-9]/g, '')}`; | |
| const el = document.getElementById(id); | |
| if (el) { | |
| el.className = 'active'; | |
| el.querySelector('.model-status').innerHTML = `<span class="pulse-text">Thinking (Round ${data.round})...</span>`; | |
| } | |
| } | |
| else if (event === 'model_end') { | |
| const id = `status-${data.model.replace(/[^a-zA-Z0-9]/g, '')}`; | |
| const el = document.getElementById(id); | |
| if (el) { | |
| el.className = 'done'; | |
| el.querySelector('.model-status').innerText = `Finished Round ${data.round}`; | |
| } | |
| appendMessage(data.model, data.round, data.content); | |
| } | |
| else if (event === 'done') { | |
| globalStatus.innerText = "Debate Concluded. Final Verdict Delivered."; | |
| globalStatus.classList.remove('pulse-text'); | |
| MODELS.forEach(m => { | |
| const id = `status-${m.replace(/[^a-zA-Z0-9]/g, '')}`; | |
| const el = document.getElementById(id); | |
| if (el) { el.classList.remove('active'); el.classList.remove('done'); } | |
| }); | |
| } | |
| } | |
| function appendMessage(model, round, markdownContent) { | |
| const div = document.createElement('div'); | |
| div.className = `message-bubble ${model.includes('Architect') ? 'architect' : ''}`; | |
| div.style.animationDelay = `${0.1 * document.querySelectorAll('.message-bubble').length}s`; | |
| let roundLabel = round === 'Final' ? 'VERDICT' : `Round ${round}`; | |
| div.innerHTML = ` | |
| <div class="bubble-header"> | |
| <span>${model}</span> | |
| <span class="round">${roundLabel}</span> | |
| </div> | |
| <div class="bubble-content"> | |
| ${marked.parse(markdownContent)} | |
| </div> | |
| `; | |
| arena.appendChild(div); | |
| arena.scrollTop = arena.scrollHeight; | |
| } | |
| }); | |