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 = ` ${m} Awaiting task `; 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 = `Thinking (Round ${data.round})...`; } } 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 = `