(function () { 'use strict'; let selectedAgentId = null; let agents = []; const agentList = document.getElementById('agent-list'); const chatMessages = document.getElementById('chat-messages'); const chatInput = document.getElementById('chat-input'); const btnSend = document.getElementById('btn-send'); const chatAgentName = document.getElementById('chat-agent-name'); const chatInputArea = document.getElementById('chat-input-area'); const emptyState = document.getElementById('empty-state'); const btnOpenWindow = document.getElementById('btn-open-window'); const btnRunNow = document.getElementById('btn-run-now'); // ─── Bridge Events ─── document.addEventListener('bridge:agent_list_update', e => { const data = e.detail.extra; agents = Array.isArray(data) ? data : (data?.agents ?? []); renderSidebar(); }); document.addEventListener('bridge:agent_status', e => { const d = e.detail; const agent = agents.find(a => a.agentId === d.agentId); if (agent) { agent.status = d.status; renderSidebar(); } }); document.addEventListener('bridge:chat_history', e => { if (e.detail.agentId !== selectedAgentId) return; const history = e.detail.extra; chatMessages.innerHTML = ''; if (Array.isArray(history)) { history.forEach(entry => appendBubble(entry.role, entry.content, entry.timestamp)); } }); document.addEventListener('bridge:chat_message', e => { if (e.detail.agentId !== selectedAgentId) return; removeTypingIndicator(); const extra = e.detail.extra ?? {}; appendBubble(extra.role ?? 'assistant', e.detail.content, extra.timestamp); }); document.addEventListener('bridge:chat_typing', e => { if (e.detail.agentId !== selectedAgentId) return; showTypingIndicator(); }); document.addEventListener('bridge:run_started', e => { const agent = agents.find(a => a.agentId === e.detail.agentId); if (agent) { agent.status = 'running'; renderSidebar(); } }); document.addEventListener('bridge:run_finished', e => { const agent = agents.find(a => a.agentId === e.detail.agentId); if (agent) { agent.status = 'idle'; renderSidebar(); } removeTypingIndicator(); }); // ─── Sidebar ─── function renderSidebar() { agentList.innerHTML = ''; agents.forEach(agent => { const item = document.createElement('div'); item.className = 'agent-item' + (agent.agentId === selectedAgentId ? ' active' : ''); item.innerHTML = `
${escapeHtml(agent.displayName)}
${escapeHtml(agent.model || '')}
`; item.addEventListener('click', () => selectAgent(agent.agentId)); agentList.appendChild(item); }); } function selectAgent(agentId) { selectedAgentId = agentId; const agent = agents.find(a => a.agentId === agentId); chatAgentName.textContent = agent ? agent.displayName : agentId; chatInputArea.style.display = 'flex'; emptyState?.remove(); btnOpenWindow.style.display = 'inline-block'; btnRunNow.style.display = 'inline-block'; chatMessages.innerHTML = ''; renderSidebar(); window.__bridge.send({ type: 'select_agent', agentId: agentId }); } // ─── Chat Bubbles ─── function appendBubble(role, content, timestamp) { const bubble = document.createElement('div'); bubble.className = 'chat-bubble ' + (role === 'user' ? 'user' : 'assistant'); bubble.textContent = content || ''; if (timestamp) { const ts = document.createElement('span'); ts.className = 'timestamp'; ts.textContent = formatTime(timestamp); bubble.appendChild(ts); } chatMessages.appendChild(bubble); chatMessages.scrollTop = chatMessages.scrollHeight; } function showTypingIndicator() { removeTypingIndicator(); const indicator = document.createElement('div'); indicator.className = 'typing-indicator'; indicator.id = 'typing'; indicator.innerHTML = ''; chatMessages.appendChild(indicator); chatMessages.scrollTop = chatMessages.scrollHeight; } function removeTypingIndicator() { document.getElementById('typing')?.remove(); } // ─── Input Handling ─── btnSend.addEventListener('click', sendMessage); chatInput.addEventListener('keydown', e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); chatInput.addEventListener('input', () => { chatInput.style.height = 'auto'; chatInput.style.height = Math.min(chatInput.scrollHeight, 120) + 'px'; }); function sendMessage() { const text = chatInput.value.trim(); if (!text || !selectedAgentId) return; chatInput.value = ''; chatInput.style.height = 'auto'; window.__bridge.send({ type: 'user_message', agentId: selectedAgentId, content: text }); } // ─── Header Buttons ─── btnOpenWindow.addEventListener('click', () => { if (!selectedAgentId) return; window.__bridge.send({ type: 'open_agent_chat', agentId: selectedAgentId }); }); btnRunNow.addEventListener('click', () => { if (!selectedAgentId) return; window.__bridge.send({ type: 'run_now', agentId: selectedAgentId }); }); // ─── Helpers ─── function escapeHtml(str) { const div = document.createElement('div'); div.textContent = str; return div.innerHTML; } function formatTime(ts) { try { const d = new Date(ts); return d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }); } catch { return ''; } } })();