DDR_Bench / trajectory.js
thinkwee
update links
9f54287
// ============================================================================
// 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, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
document.addEventListener('DOMContentLoaded', () => {
initTrajectory();
});