add auto-scroll to bottom for all chat messages and streaming responses

This commit is contained in:
Russell Ballestrini 2025-06-30 15:26:01 -04:00
parent 6e84ee58b1
commit b2a63f44f4

View file

@ -1466,19 +1466,21 @@ function openHermesModal() {
chatBox.scrollTop = chatBox.scrollHeight;
try {
const prompt = `You are Hermes, a large language model from Nous Research. Write a friendly 2-paragraph introduction for yourself when embedded on this webpage. Be specific about this page's content and identify 2-3 key takeaways. Keep it conversational and helpful.
const prompt = `You are Hermes, a large language model from Nous Research. Write a friendly 3-paragraph introduction for yourself when embedded on this webpage. Be specific about this page's content and identify 2-3 key takeaways. Keep it conversational and helpful.
Page Title: ${pageTitle}
Page URL: ${pageUrl}
Page Content: ${pageContent.substring(0, 2000)}
Format: Start with "Greetings! I'm Hermes..." and make it sound natural and engaging. Focus on what YOU can help with regarding THIS specific page.`;
Format: Start with "Greetings! I'm Hermes..." and make it sound natural and engaging. Write 3 full paragraphs that showcase your capabilities and how you can help with THIS specific page.`;
let generatedIntro = '';
for await (const chunk of sendMessageDirect(prompt)) {
generatedIntro += chunk;
// Update display in real-time
introDiv.innerHTML = `<p><strong>🤖 Hermes:</strong> ${generatedIntro}</p>`;
// Scroll to bottom as content updates
chatBox.scrollTop = chatBox.scrollHeight;
}
// Add to chat history and save
@ -1488,6 +1490,9 @@ Format: Start with "Greetings! I'm Hermes..." and make it sound natural and enga
// Cache the generated introduction
localStorage.setItem(cacheKey, generatedIntro);
// Add TTS button for introduction
addTTSButtonToIntro(introDiv, generatedIntro);
chatBox.scrollTop = chatBox.scrollHeight;
} catch (error) {
@ -1506,9 +1511,67 @@ Format: Start with "Greetings! I'm Hermes..." and make it sound natural and enga
introDiv.style.cssText = 'position: relative; margin-bottom: 10px; padding: 10px; border-radius: 5px; background: rgba(0,100,200,0.1); border-left: 4px solid #0066cc;';
introDiv.innerHTML = `<p><strong>🤖 Hermes:</strong> ${introText}</p>`;
chatBox.appendChild(introDiv);
// Add TTS button for cached introduction
addTTSButtonToIntro(introDiv, introText);
chatBox.scrollTop = chatBox.scrollHeight;
}
// Add TTS button to introduction message
function addTTSButtonToIntro(introDiv, introText) {
const ttsIntroBtn = document.createElement('button');
ttsIntroBtn.textContent = '🔊 Play Response';
if (USE_CUSTOM_STYLING) {
ttsIntroBtn.style.cssText = 'margin: 5px 0; padding: 6px 12px; border: 1px solid #0066cc; border-radius: 4px; background: #f0f8ff; cursor: pointer; color: #0066cc;';
} else {
ttsIntroBtn.style.cssText = 'margin: 5px 0; padding: 6px 12px; border-radius: 4px; cursor: pointer;';
}
let introAudio = null;
let introBlob = null;
ttsIntroBtn.onclick = async () => {
if (!introAudio) {
ttsIntroBtn.textContent = 'Processing...';
ttsIntroBtn.disabled = true;
const selectedVoice = voiceSelect.value;
const result = await speakText(introText, selectedVoice, 0.9);
introAudio = result.audio;
introBlob = result.blob;
ttsIntroBtn.textContent = 'Pause';
ttsIntroBtn.disabled = false;
introAudio.play();
// Add download button for intro
const downloadIntroBtn = document.createElement('button');
downloadIntroBtn.textContent = '💾 Download';
if (USE_CUSTOM_STYLING) {
downloadIntroBtn.style.cssText = 'margin: 5px; padding: 6px 12px; border: 1px solid #0066cc; border-radius: 4px; background: #f0f8ff; cursor: pointer; color: #0066cc;';
} else {
downloadIntroBtn.style.cssText = 'margin: 5px; padding: 6px 12px; border-radius: 4px; cursor: pointer;';
}
downloadIntroBtn.onclick = () => {
const a = document.createElement('a');
a.href = URL.createObjectURL(introBlob);
a.download = `hermes-introduction-${Date.now()}.mp3`;
a.click();
};
introDiv.appendChild(downloadIntroBtn);
} else {
if (introAudio.paused) {
introAudio.play();
ttsIntroBtn.textContent = 'Pause';
} else {
introAudio.pause();
ttsIntroBtn.textContent = 'Play';
}
}
};
introDiv.appendChild(ttsIntroBtn);
}
// Direct LLM call for introduction generation (doesn't add to chat history)
async function* sendMessageDirect(message) {
const selectedModel = modelSelect.value || MODEL;
@ -1656,6 +1719,9 @@ Format: Start with "Greetings! I'm Hermes..." and make it sound natural and enga
userMessageDiv.innerHTML = `<p><strong>You:</strong> ${userInput}</p>`;
chatBox.appendChild(userMessageDiv);
// Scroll to bottom when user message is added
chatBox.scrollTop = chatBox.scrollHeight;
// Create AI response container
const aiMessageDiv = document.createElement('div');
aiMessageDiv.style.cssText = 'position: relative; margin-bottom: 10px; padding: 5px; border-radius: 5px; background: rgba(0,0,0,0.05);';
@ -1675,6 +1741,9 @@ Format: Start with "Greetings! I'm Hermes..." and make it sound natural and enga
responseContent.querySelectorAll('pre code').forEach((block) => {
hljs.highlightElement(block);
});
// Auto-scroll to bottom as response streams in
chatBox.scrollTop = chatBox.scrollHeight;
}
// Add assistant response to chat history and save