← Back to all documents

cai-exos-systems/daveadmin-exos-demo:assets/js/demo.js.bak

gitea 3,663 words Source ↗
assets/js/demo.js.bak ```text /** * Exos Agentic BSS — Demo Chat UI * VS Code–style 4-panel layout */ const AGENT_PROMPTS = { billing: [ "Show me the latest invoice and break down the main charges", "How does this month's invoice compare to last month — what's driving the change?", "Which line items on the latest invoice are unusually high, and why?", "Based on this account's usage profile, what products would you recommend?", ], product: [ "Show the full product catalogue with current pricing", "Which products in the catalogue are end-of-life or being phased out?", "List all enterprise connectivity products and their pricing tiers", "Add a new SD-WAN Enterprise product to the catalogue at $4,500/month", ], order: [ "Show all failed orders — what went wrong with each one?", "Which orders are currently blocked and what needs to happen to unblock them?", "What is the combined revenue impact of all failed and stalled orders?", "Place a new order for SD-WAN Enterprise service for this account", ], care: [ "Show the full customer profile for this account", "List all open support tickets — highlight any P1 or P2 incidents", "Who is the account manager and what is the escalation path for urgent issues?", "Create a P2 support ticket for a connectivity issue on the primary circuit", ], }; const AGENT_META = { billing: { icon: '💶', label: 'Billing Expert', welcome: 'Ask about invoices, bill comparisons, or charge anomalies.' }, product: { icon: '📦', label: 'Product Expert', welcome: 'Ask about the product catalogue, pricing, or add new offerings.' }, order: { icon: '📋', label: 'Order Expert', welcome: 'Ask about order status, failures, or place new orders.' }, care: { icon: '🤝', label: 'Care Agent', welcome: 'Look up customer profiles, support tickets, or account managers.' }, }; const ACCOUNT_META = { '1': 'Sure Telecom', '2': 'Telesur Suriname', '3': 'CW Seychelles', '4': 'Digicel Pacific', '5': 'Vodacom Mozambique', };
assets/js/demo.js.bak renderSidebar() { const el = document.getElementById('account-context'); if (!el) return; const acct = ACCOUNT_DATA[currentAccount]; if (!acct) return; const section = acct[currentAgent]; if (!section) return; const healthLabel = { green: 'Healthy', amber: 'Attention', red: 'Critical' }[acct.health] ?? acct.health; const metricsHtml = section.metrics.map(m => ` <div class="metric-row"> <span class="metric-icon">${m.icon}</span> <span class="metric-label">${escHtml(m.label)}</span> <span class="metric-value">${escHtml(m.value)}</span> </div>`).join(''); const alertsHtml = section.alerts.map(a => ` <div class="alert-chip ${a.level === 'critical' ? 'alert-critical' : 'alert-warn'}"> ${a.level === 'critical' ? '🔴' : '⚠️'} ${escHtml(a.text)} </div>`).join(''); el.innerHTML = ` <div class="sidebar-section"> <div class="account-card"> <div class="account-card-name"> <span class="account-flag">${acct.flag}</span> <span>${escHtml(acct.name)}</span> </div> <span class="health-badge health-${acct.health}">${healthLabel}</span> </div> <div class="metric-list">${metricsHtml}</div> ${alertsHtml ? `<div class="alert-list">${alertsHtml}</div>` : ''} </div>`; } // ── Welcome screen ───────────────────────────────────────── function renderWelcome() { if (messagesEl.querySelector('.msg')) return; messagesEl.innerHTML = ` <div class="chat-welcome" id="chat-welcome"> <div class="chat-welcome-icon">${AGENT_META[currentAgent]?.icon ?? '🤖'}</div> <h3>${AGENT_META[currentAgent]?.label ?? 'Agent'}</h3> <p>${AGENT_META[currentAgent]?.welcome ?? ''}</p> <p style="color:var(--text-dim);font-size:0.78rem;margin-top:0.5rem"> Account: <strong style="color:var(--cyan)">${ACCOUNT_META[currentAccount]}</strong> </p> </div>`; } function clearChat() { messagesEl.innerHTML = ''; } // ── Send message ─────────────────────────────────────────── async function sendMessage(text) { const msg = (text ?? inputEl.value).trim(); if (!msg || isStreaming) return; document.getElementById('chat-welcome')?.remove(); inputEl.value = ''; autoResize(inputEl); appendUserMsg(msg); const typingId = 'typing-' + Date.now(); appendTyping(typingId); isStreaming = true; sendBtn.disabled = true; // Prepare panels clearToolResults(); clearThinkingPanel(); showThinkingPanel(); setStreamingStatus(true); // Switch left panel to tool trace tab switchLeftTab('tools'); try { const res = await fetch('/api/chat.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ agent: currentAgent, message: msg, conversation_id: conversationId ?? '', account: currentAccount, ...getModelParams(), }), }); if (!res.ok) { removeTyping(typingId); appendError(`Server error: ${res.status}`); return; } const reader = res.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; let aiMsgEl = null; let fullText = ''; let toolCalls = []; let firstChunk = true; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop() ?? ''; for (const line of lines) { if (!line.startsWith('data: ')) continue; const raw = line.slice(6).trim(); if (raw === '[DONE]') continue; let evt; try { evt = JSON.parse(raw); } catch { continue; } const etype = evt.event; if (etype === 'message' || etype === 'agent_message') { if (firstChunk) { removeTyping(typingId); aiMsgEl = appendAiMsg(''); firstChunk = false; } fullText += evt.answer ?? ''; if (aiMsgEl) updateAiMsg(aiMsgEl, fullText, toolCalls); } if (etype === 'agent_thought') { const toolName = (evt.tool ?? '').trim(); const thought = (evt.thought ?? evt.observation ?? '').trim(); const toolInput = evt.tool_input ?? ''; const observation = evt.observation ?? ''; // Feed both panels appendThought(toolName, thought); appendToolResult(toolName, toolInput, observation); if (toolName) { const label = TOOL_LABELS[toolName] ?? toolName.replace(/-/g, ' '); if (firstChunk) updateTypingStatus(typingId, `${label}…`); if (!toolCalls.includes(toolName)) { toolCalls.push(toolName); if (aiMsgEl) updateAiMsg(aiMsgEl, fullText, toolCalls); } } else if (thought && firstChunk) { const brief = thought.length > 72 ? thought.slice(0, 72) + '…' : thought; updateTypingStatus(typingId, `Reasoning: ${brief}`); } } if (etype === 'message_replace') { fullText = evt.answer ?? fullText; if (aiMsgEl) updateAiMsg(aiMsgEl, fullText, toolCalls); } if (etype === 'message_end') { conversationId = evt.conversation_id ?? conversationId; finishThinkingPanel(); setStreamingStatus(false); } if (etype === 'error') { removeTyping(typingId); appendError(evt.message ?? 'Agent error'); } } } removeTyping(typingId); if (!aiMsgEl && fullText) appendAiMsg(fullText, toolCalls); } catch (err) { removeTyping(typingId); appendError(err.message ?? 'Network error'); } finally { isStreaming = false; sendBtn.disabled = false; setStreamingStatus(false); inputEl.focus(); scrollBottom(); } }