// ============================================================================ // AGENT TRAJECTORY - Chat Interface // ============================================================================ const SCENARIO_DESCRIPTIONS = { 'mimic': 'Exploring clinical patterns and patient outcomes in a large-scale electronic health record (EHR) database.', '10k': 'Extracting deep insights from SEC 10-K annual reports for longitudinal financial performance analysis.', 'globem': 'Analyzing multi-modal longitudinal behavioral and sensor data for detecting mental health trends.' }; let currentTrajScenario = 'mimic'; function initTrajectory() { if (typeof TRAJECTORY_DATA === 'undefined') { setTimeout(initTrajectory, 500); // Wait for data load return; } // Configure marked with highlight.js if (typeof marked !== 'undefined') { marked.setOptions({ highlight: function (code, lang) { // Auto Format SQL if (lang === 'sql' && typeof sqlFormatter !== 'undefined') { try { code = sqlFormatter.format(code, { language: 'sql', indent: ' ' }); } catch (e) { console.warn('SQL Formatting failed:', e); } } // Highlight if (lang && hljs.getLanguage(lang)) { return hljs.highlight(code, { language: lang }).value; } return hljs.highlightAuto(code).value; }, breaks: true, langPrefix: 'hljs language-' // Ensure .hljs class is added for themes }); } // Setup toggle buttons document.querySelectorAll('[data-traj-scenario]').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('[data-traj-scenario]').forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentTrajScenario = btn.dataset.trajScenario; // Update description const descEl = document.getElementById('trajectory-scenario-description'); if (descEl && SCENARIO_DESCRIPTIONS[currentTrajScenario]) { descEl.textContent = SCENARIO_DESCRIPTIONS[currentTrajScenario]; } renderTrajectory(currentTrajScenario); }); }); // Initial Render renderTrajectory('mimic'); } function renderTrajectory(scenario) { const container = document.getElementById('chat-window'); const messages = TRAJECTORY_DATA[scenario]; if (!container || !messages) return; container.innerHTML = ''; messages.forEach((msg, index) => { const msgDiv = document.createElement('div'); msgDiv.className = `chat-message role-${msg.role}`; // Role Label const roleLabel = document.createElement('div'); roleLabel.className = 'message-role-label'; // Capitalize roleLabel.textContent = msg.role.charAt(0).toUpperCase() + msg.role.slice(1); if (msg.role === 'user') roleLabel.textContent = 'User Prompt'; msgDiv.appendChild(roleLabel); // Bubble const bubble = document.createElement('div'); bubble.className = 'message-bubble'; // Parse Markdown let htmlContent = ''; if (typeof marked !== 'undefined') { htmlContent = marked.parse(msg.content); } else { // Fallback htmlContent = escapeHtml(msg.content).replace(/\n/g, '
'); } const contentDiv = document.createElement('div'); contentDiv.innerHTML = htmlContent; bubble.appendChild(contentDiv); msgDiv.appendChild(bubble); container.appendChild(msgDiv); // Append to DOM to calculate height // Height Check (Post-render) // 3 lines is approx 80-100px. const COLLAPSE_HEIGHT = 200; const isLastMessage = (index === messages.length - 1); // Only apply collapse logic if NOT the last message if (!isLastMessage && contentDiv.scrollHeight > COLLAPSE_HEIGHT + 20) { contentDiv.style.cssText = `max-height: ${COLLAPSE_HEIGHT}px; overflow: hidden; position: relative; mask-image: linear-gradient(to bottom, black 60%, transparent 100%); -webkit-mask-image: linear-gradient(to bottom, black 60%, transparent 100%);`; const btn = document.createElement('button'); btn.textContent = 'Show More'; btn.style.cssText = 'display:block; margin: 8px auto 0; border:none; background: rgba(0,0,0,0.05); color: #0071e3; border-radius: 12px; padding: 4px 12px; cursor:pointer; font-size:12px; font-weight:500; transition: all 0.2s;'; if (msg.role === 'agent') { btn.style.background = 'rgba(255,255,255,0.2)'; btn.style.color = 'white'; } btn.onclick = () => { if (contentDiv.style.maxHeight !== 'none') { // Expand contentDiv.style.maxHeight = 'none'; contentDiv.style.maskImage = 'none'; contentDiv.style.webkitMaskImage = 'none'; btn.textContent = 'Show Less'; } else { // Collapse contentDiv.style.maxHeight = `${COLLAPSE_HEIGHT}px`; contentDiv.style.maskImage = 'linear-gradient(to bottom, black 60%, transparent 100%)'; contentDiv.style.webkitMaskImage = 'linear-gradient(to bottom, black 60%, transparent 100%)'; btn.textContent = 'Show More'; } }; bubble.appendChild(btn); } }); container.scrollTop = 0; } function escapeHtml(text) { if (!text) return ''; return text .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } document.addEventListener('DOMContentLoaded', () => { initTrajectory(); });