File size: 6,121 Bytes
a8df6b3 9f54287 a8df6b3 9f54287 a8df6b3 2254920 a8df6b3 2254920 a8df6b3 2254920 a8df6b3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
// ============================================================================
// 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, '<br>');
}
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, """)
.replace(/'/g, "'");
}
document.addEventListener('DOMContentLoaded', () => {
initTrajectory();
});
|