(function () { 'use strict'; const agentId = new URLSearchParams(location.search).get('agent'); 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 btnRunNow = document.getElementById('btn-run-now'); const btnAbort = document.getElementById('btn-abort'); // ─── Bridge Events ─── document.addEventListener('bridge:agent_list_update', e => { const data = e.detail.extra; const list = Array.isArray(data) ? data : (data?.agents ?? []); const agent = list.find(a => a.agentId === agentId); if (agent) chatAgentName.textContent = agent.displayName; }); document.addEventListener('bridge:chat_history', e => { if (e.detail.agentId !== agentId) return; chatMessages.innerHTML = ''; const history = e.detail.extra; if (Array.isArray(history)) { history.forEach(entry => appendBubble(entry.role, entry.content, entry.timestamp)); } }); document.addEventListener('bridge:chat_message', e => { if (e.detail.agentId !== agentId) 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 !== agentId) return; showTypingIndicator(); }); document.addEventListener('bridge:run_started', e => { if (e.detail.agentId !== agentId) return; btnAbort.style.display = 'inline-block'; }); document.addEventListener('bridge:run_finished', e => { if (e.detail.agentId !== agentId) return; btnAbort.style.display = 'none'; removeTypingIndicator(); }); // ─── 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 ─── 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 || !agentId) return; chatInput.value = ''; chatInput.style.height = 'auto'; window.__bridge.send({ type: 'user_message', agentId: agentId, content: text }); } // ─── Header Buttons ─── btnRunNow.addEventListener('click', () => { if (!agentId) return; window.__bridge.send({ type: 'run_now', agentId: agentId }); }); btnAbort.addEventListener('click', () => { if (!agentId) return; window.__bridge.send({ type: 'abort_run', agentId: agentId }); }); // ─── Helpers ─── function formatTime(ts) { try { const d = new Date(ts); return d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }); } catch { return ''; } } })();