chore: update 1 file(s)

This commit is contained in:
mike
2025-12-28 05:11:34 +01:00
parent 267e155ad1
commit 7b9947da7e

113
chatv2.js
View File

@@ -89,7 +89,10 @@ function updateBackendModelDisplay() {
const displayText = IS_PRODUCTION const displayText = IS_PRODUCTION
? `${backend.prod} - ${backend.name}` ? `${backend.prod} - ${backend.name}`
: backend.dev; : backend.dev;
document.getElementById('backendDisplay').textContent = `${displayText} - Model: ${model || 'None'}`; const displayElement = document.getElementById('backendDisplay');
if (displayElement) {
displayElement.textContent = `${displayText} - Model: ${model || 'None'}`;
}
} }
async function fetchBackendModels() { async function fetchBackendModels() {
@@ -103,6 +106,7 @@ async function fetchBackendModels() {
console.log(`Fetching models from: ${apiUrl}`); console.log(`Fetching models from: ${apiUrl}`);
const response = await fetch(`${apiUrl}/models`); const response = await fetch(`${apiUrl}/models`);
const selector = document.getElementById('backendModelSelector');
if (response.ok) { if (response.ok) {
const data = await response.json(); const data = await response.json();
@@ -119,24 +123,31 @@ async function fetchBackendModels() {
// ✅ FIX: Only auto-select if no model is set // ✅ FIX: Only auto-select if no model is set
const hasModel = currentBackendModel && currentBackendModel.includes(':') && currentBackendModel.split(':')[1]; const hasModel = currentBackendModel && currentBackendModel.includes(':') && currentBackendModel.split(':')[1];
if (!hasModel && availableBackendModels.length > 0) { if (!hasModel && availableBackendModels.length > 0 && selector) {
currentBackendModel = `${availableBackendModels[0].backend}:${availableBackendModels[0].model}`; currentBackendModel = `${availableBackendModels[0].backend}:${availableBackendModels[0].model}`;
document.getElementById('backendModelSelector').value = currentBackendModel; selector.value = currentBackendModel;
} }
updateBackendModelDisplay(); updateBackendModelDisplay();
} else { } else {
console.error('Failed to fetch models:', response.statusText); console.error('Failed to fetch models:', response.statusText);
document.getElementById('backendModelSelector').innerHTML = '<option value="">Error loading models</option>'; if (selector) {
selector.innerHTML = '<option value="">Error loading models</option>';
}
} }
} catch (error) { } catch (error) {
console.error('Error fetching models:', error); console.error('Error fetching models:', error);
document.getElementById('backendModelSelector').innerHTML = '<option value="">Error loading models</option>'; const selector = document.getElementById('backendModelSelector');
if (selector) {
selector.innerHTML = '<option value="">Error loading models</option>';
}
} }
} }
function populateBackendModelSelector() { function populateBackendModelSelector() {
const selector = document.getElementById('backendModelSelector'); const selector = document.getElementById('backendModelSelector');
if (!selector) return;
if (availableBackendModels.length === 0) { if (availableBackendModels.length === 0) {
selector.innerHTML = '<option value="">No models available</option>'; selector.innerHTML = '<option value="">No models available</option>';
return; return;
@@ -168,13 +179,13 @@ function trimChatHistory() {
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const backendModelSelector = document.getElementById('backendModelSelector'); const backendModelSelector = document.getElementById('backendModelSelector');
backendModelSelector.addEventListener('change', (e) => { if (backendModelSelector) {
currentBackendModel = e.target.value; backendModelSelector.addEventListener('change', (e) => {
updateBackendModelDisplay(); currentBackendModel = e.target.value;
fetchBackendModels(); updateBackendModelDisplay();
}); fetchBackendModels();
});
fetchBackendModels(); }
}); });
const chatLog = document.getElementById('chatLog'); const chatLog = document.getElementById('chatLog');
@@ -201,7 +212,7 @@ function autoResize(textarea) {
textarea.style.height = Math.min(textarea.scrollHeight, 300) + 'px'; textarea.style.height = Math.min(textarea.scrollHeight, 300) + 'px';
} }
function addMessage(role, content, markdown = false, messageId = null) { function addMessage(role, content, markdown = false, messageId = null, saveToHistory = true) {
const messageDiv = document.createElement('div'); const messageDiv = document.createElement('div');
messageDiv.className = `message message-${role}`; messageDiv.className = `message message-${role}`;
if (messageId) { if (messageId) {
@@ -213,7 +224,7 @@ function addMessage(role, content, markdown = false, messageId = null) {
const avatar = document.createElement('div'); const avatar = document.createElement('div');
avatar.className = `avatar ${role}-avatar`; avatar.className = `avatar ${role}-avatar`;
avatar.textContent = role === 'user' ? '?' : '?'; avatar.textContent = role === 'user' ? '👤' : '🤖';
const name = document.createElement('span'); const name = document.createElement('span');
name.textContent = role === 'user' ? 'You' : 'Assistant'; name.textContent = role === 'user' ? 'You' : 'Assistant';
@@ -239,17 +250,21 @@ function addMessage(role, content, markdown = false, messageId = null) {
contentDiv.innerHTML = processedContent; contentDiv.innerHTML = processedContent;
contentDiv.style.whiteSpace = 'pre-wrap'; contentDiv.style.whiteSpace = 'pre-wrap';
contentDiv.style.padding = '8px 0'; contentDiv.style.padding = '8px 0';
contentDiv.style.color = '#2d3339'; contentDiv.style.color = '#e0e0e0';
} }
messageDiv.appendChild(headerDiv); messageDiv.appendChild(headerDiv);
messageDiv.appendChild(contentDiv); messageDiv.appendChild(contentDiv);
chatLog.appendChild(messageDiv); if (chatLog) {
chatLog.scrollTop = chatLog.scrollHeight; chatLog.appendChild(messageDiv);
chatLog.scrollTop = chatLog.scrollHeight;
}
chatHistory.push({ role, content, markdown, messageId }); if (saveToHistory) {
trimChatHistory(); chatHistory.push({ role, content, markdown, messageId });
localStorage.setItem('chatHistory', JSON.stringify(chatHistory)); trimChatHistory();
localStorage.setItem('chatHistory', JSON.stringify(chatHistory));
}
return contentDiv; return contentDiv;
} }
@@ -300,7 +315,7 @@ window.toggleThinking = function(id) {
function updateMessageContent(contentDiv, newContent, markdown = false, role) { function updateMessageContent(contentDiv, newContent, markdown = false, role) {
const processedContent = parseThinkingTags(newContent); const processedContent = parseThinkingTags(newContent);
if (markdown && role === 'assistant' && markdownToggle.checked) { if (markdown && role === 'assistant' && markdownToggle && markdownToggle.checked) {
contentDiv.innerHTML = marked.parse(processedContent); contentDiv.innerHTML = marked.parse(processedContent);
if (window.hljs) { if (window.hljs) {
setTimeout(() => { setTimeout(() => {
@@ -311,6 +326,12 @@ function updateMessageContent(contentDiv, newContent, markdown = false, role) {
} }
} else { } else {
contentDiv.innerHTML = processedContent; contentDiv.innerHTML = processedContent;
contentDiv.style.whiteSpace = 'pre-wrap';
contentDiv.style.padding = '8px 0';
contentDiv.style.color = '#e0e0e0';
}
if (chatLog) {
chatLog.scrollTop = chatLog.scrollHeight;
} }
} }
@@ -324,12 +345,12 @@ function showTypingIndicator() {
const avatar = document.createElement('div'); const avatar = document.createElement('div');
avatar.className = 'avatar assistant-avatar'; avatar.className = 'avatar assistant-avatar';
avatar.textContent = '?'; avatar.textContent = '🤖';
const name = document.createElement('span'); const name = document.createElement('span');
name.textContent = 'Assistant'; name.textContent = 'Assistant';
headerDiv.appendChild(avatar); // ✅ FIX: Typo "abatar" headerDiv.appendChild(avatar);
headerDiv.appendChild(name); headerDiv.appendChild(name);
const dotsDiv = document.createElement('div'); const dotsDiv = document.createElement('div');
@@ -343,8 +364,10 @@ function showTypingIndicator() {
typingDiv.appendChild(headerDiv); typingDiv.appendChild(headerDiv);
typingDiv.appendChild(dotsDiv); typingDiv.appendChild(dotsDiv);
chatLog.appendChild(typingDiv); if (chatLog) {
chatLog.scrollTop = chatLog.scrollHeight; chatLog.appendChild(typingDiv);
chatLog.scrollTop = chatLog.scrollHeight;
}
return typingDiv; return typingDiv;
} }
@@ -369,7 +392,7 @@ async function handleStreamingResponse(userMessage) {
const avatar = document.createElement('div'); const avatar = document.createElement('div');
avatar.className = 'avatar assistant-avatar'; avatar.className = 'avatar assistant-avatar';
avatar.textContent = '?'; avatar.textContent = '🤖';
const name = document.createElement('span'); const name = document.createElement('span');
name.textContent = 'Assistant'; name.textContent = 'Assistant';
@@ -382,7 +405,9 @@ async function handleStreamingResponse(userMessage) {
messageDiv.appendChild(headerDiv); messageDiv.appendChild(headerDiv);
messageDiv.appendChild(contentDiv); messageDiv.appendChild(contentDiv);
chatLog.appendChild(messageDiv); if (chatLog) {
chatLog.appendChild(messageDiv);
}
const cursorSpan = document.createElement('span'); const cursorSpan = document.createElement('span');
cursorSpan.className = 'streaming-cursor'; cursorSpan.className = 'streaming-cursor';
@@ -433,24 +458,28 @@ async function handleStreamingResponse(userMessage) {
if (timeSinceLastUpdate >= MIN_UPDATE_INTERVAL) { if (timeSinceLastUpdate >= MIN_UPDATE_INTERVAL) {
updateScheduled = true; updateScheduled = true;
requestAnimationFrame(() => { requestAnimationFrame(() => {
updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked, 'assistant'); updateMessageContent(contentDiv, accumulatedContent, markdownToggle && markdownToggle.checked, 'assistant');
if (cursorSpan.parentNode) { if (cursorSpan.parentNode) {
contentDiv.appendChild(cursorSpan); contentDiv.appendChild(cursorSpan);
} }
chatLog.scrollTop = chatLog.scrollHeight; if (chatLog) {
lastUpdate = Date.now(); chatLog.scrollTop = chatLog.scrollHeight;
updateScheduled = false; }
}); lastUpdate = Date.now();
updateScheduled = false;
});
} else { } else {
updateScheduled = true; updateScheduled = true;
setTimeout(() => { setTimeout(() => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked, 'assistant'); updateMessageContent(contentDiv, accumulatedContent, markdownToggle && markdownToggle.checked, 'assistant');
if (cursorSpan.parentNode) { if (cursorSpan.parentNode) {
contentDiv.appendChild(cursorSpan); contentDiv.appendChild(cursorSpan);
} }
chatLog.scrollTop = chatLog.scrollHeight; if (chatLog) {
chatLog.scrollTop = chatLog.scrollHeight;
}
lastUpdate = Date.now(); lastUpdate = Date.now();
updateScheduled = false; updateScheduled = false;
}); });
@@ -618,7 +647,7 @@ userInput.addEventListener('keydown', (e) => {
// ✅ Updated window.onload with better initialization // ✅ Updated window.onload with better initialization
window.onload = () => { window.onload = () => {
userInput.focus(); if (userInput) userInput.focus();
// Set default backend BEFORE fetching // Set default backend BEFORE fetching
if (!currentBackendModel) { if (!currentBackendModel) {
@@ -629,11 +658,11 @@ window.onload = () => {
// Load chat history after models are fetched // Load chat history after models are fetched
if (chatLog) { if (chatLog) {
if (chatHistory.length === 0) { if (chatHistory.length === 0) {
//addMessage('assistant', welcomeMessage, true); //addMessage('assistant', welcomeMessage, true, null, false);
} else { } else {
chatHistory.forEach(msg => { chatHistory.forEach(msg => {
if (typeof msg.content === 'string' && msg.content.trim()) { if (typeof msg.content === 'string' && msg.content.trim()) {
addMessage(msg.role, msg.content, msg.markdown, msg.messageId); addMessage(msg.role, msg.content, msg.markdown, msg.messageId, false);
} }
}); });
} }
@@ -649,6 +678,6 @@ function resetChat() {
if (chatLog) { if (chatLog) {
chatLog.innerHTML = ''; chatLog.innerHTML = '';
addMessage('assistant', welcomeMessage, true); addMessage('assistant', welcomeMessage, true, null, false);
} }
} }