Fix: Add Hermes introduction and ensure modal dropdown is populated
- Add dynamic Hermes introduction generation when modal opens - Fetch models directly in modal instead of copying from existing dropdown - Fix empty dropdown issue by ensuring models are loaded before display - Add page-specific intro caching and fallback handling
This commit is contained in:
parent
f455f17fa3
commit
ebb316fcf1
1 changed files with 118 additions and 22 deletions
140
src/ui.js
140
src/ui.js
|
|
@ -613,17 +613,14 @@ export async function openHermesModal() {
|
|||
`;
|
||||
}
|
||||
|
||||
// Copy options from existing model dropdown
|
||||
const existingDropdown = document.getElementById('model-selection');
|
||||
if (existingDropdown) {
|
||||
Array.from(existingDropdown.options).forEach(option => {
|
||||
const newOption = document.createElement('option');
|
||||
newOption.value = option.value;
|
||||
newOption.textContent = option.textContent;
|
||||
newOption.selected = option.selected;
|
||||
modelSelect.appendChild(newOption);
|
||||
});
|
||||
}
|
||||
// Populate model dropdown dynamically
|
||||
const models = await fetchModelsFromEndpoints();
|
||||
models.forEach(model => {
|
||||
const option = document.createElement('option');
|
||||
option.value = model.uniqueId;
|
||||
option.textContent = `${model.endpointId} | ${model.modelName}`;
|
||||
modelSelect.appendChild(option);
|
||||
});
|
||||
|
||||
// Restore saved model selection
|
||||
const savedModel = localStorage.getItem('hermes-selected-model');
|
||||
|
|
@ -719,18 +716,26 @@ export async function openHermesModal() {
|
|||
localStorage.removeItem('vllmEndpointsHash');
|
||||
const models = await fetchModelsFromEndpoints();
|
||||
|
||||
// Update both dropdowns
|
||||
[modelSelect, document.getElementById('model-selection')].forEach(dropdown => {
|
||||
if (dropdown) {
|
||||
dropdown.innerHTML = '';
|
||||
models.forEach(model => {
|
||||
const option = document.createElement('option');
|
||||
option.value = model.uniqueId;
|
||||
option.textContent = `${model.endpointId} | ${model.modelName}`;
|
||||
dropdown.appendChild(option);
|
||||
});
|
||||
}
|
||||
// Update modal dropdown
|
||||
modelSelect.innerHTML = '';
|
||||
models.forEach(model => {
|
||||
const option = document.createElement('option');
|
||||
option.value = model.uniqueId;
|
||||
option.textContent = `${model.endpointId} | ${model.modelName}`;
|
||||
modelSelect.appendChild(option);
|
||||
});
|
||||
|
||||
// Update main page dropdown if it exists
|
||||
const mainDropdown = document.getElementById('model-selection');
|
||||
if (mainDropdown) {
|
||||
mainDropdown.innerHTML = '';
|
||||
models.forEach(model => {
|
||||
const option = document.createElement('option');
|
||||
option.value = model.uniqueId;
|
||||
option.textContent = `${model.endpointId} | ${model.modelName}`;
|
||||
mainDropdown.appendChild(option);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const clearBtn = document.createElement('button');
|
||||
|
|
@ -847,6 +852,97 @@ export async function openHermesModal() {
|
|||
}
|
||||
restoreConversationHistory();
|
||||
|
||||
// Generate dynamic Hermes introduction using LLM
|
||||
async function addHermesIntroduction() {
|
||||
const history = loadConversationHistory();
|
||||
if (history.length === 0) {
|
||||
const pageContent = extractWebpageContent();
|
||||
const pageTitle = document.title;
|
||||
const pageUrl = window.location.href;
|
||||
|
||||
// Create cache key based on page content hash (handle Unicode safely)
|
||||
const contentForHash = pageContent.substring(0, 1000);
|
||||
let contentHash;
|
||||
try {
|
||||
contentHash = btoa(unescape(encodeURIComponent(contentForHash))).replace(/[^a-zA-Z0-9]/g, '').substring(0, 32);
|
||||
} catch (e) {
|
||||
// Fallback: use simple string hash if btoa fails
|
||||
let hash = 0;
|
||||
for (let i = 0; i < contentForHash.length; i++) {
|
||||
const char = contentForHash.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + char;
|
||||
hash = hash & hash; // Convert to 32bit integer
|
||||
}
|
||||
contentHash = Math.abs(hash).toString(36).substring(0, 32);
|
||||
}
|
||||
const cacheKey = `hermes-intro-${contentHash}`;
|
||||
|
||||
// Check if we have a cached introduction for this page content
|
||||
const cachedIntro = localStorage.getItem(cacheKey);
|
||||
if (cachedIntro) {
|
||||
displayIntroduction(cachedIntro);
|
||||
// Add cached intro to chat history
|
||||
chatHistory.push({ role: "assistant", content: cachedIntro });
|
||||
saveConversationHistory(chatHistory);
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate new introduction using LLM
|
||||
const introDiv = document.createElement('div');
|
||||
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> <em>✨ Analyzing this page and crafting a personalized introduction... This may take a moment.</em></p>';
|
||||
chatBox.appendChild(introDiv);
|
||||
chatBox.scrollTop = chatBox.scrollHeight;
|
||||
|
||||
try {
|
||||
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. Write 3 full paragraphs that showcase your capabilities and how you can help with THIS specific page.`;
|
||||
|
||||
let generatedIntro = '';
|
||||
for await (const chunk of sendMessage(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
|
||||
chatHistory.push({ role: "assistant", content: generatedIntro });
|
||||
saveConversationHistory(chatHistory);
|
||||
|
||||
// Cache the generated introduction
|
||||
localStorage.setItem(cacheKey, generatedIntro);
|
||||
|
||||
chatBox.scrollTop = chatBox.scrollHeight;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error generating introduction:', error);
|
||||
const fallbackIntro = 'Greetings! I\'m Hermes, a large language model from Nous Research. I\'m here to help you understand this page and assist with any questions, coding, or creative tasks you might have. Feel free to ask me anything!';
|
||||
introDiv.innerHTML = `<p><strong>🤖 Hermes:</strong> ${fallbackIntro}</p>`;
|
||||
// Add fallback to chat history too
|
||||
chatHistory.push({ role: "assistant", content: fallbackIntro });
|
||||
saveConversationHistory(chatHistory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function displayIntroduction(introText) {
|
||||
const introDiv = document.createElement('div');
|
||||
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);
|
||||
chatBox.scrollTop = chatBox.scrollHeight;
|
||||
}
|
||||
|
||||
// Call addHermesIntroduction after restoring history
|
||||
await addHermesIntroduction();
|
||||
|
||||
// Create input area
|
||||
const inputArea = document.createElement('div');
|
||||
if (USE_CUSTOM_STYLING) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue