chore: update 1 file(s)
This commit is contained in:
113
chatv2.js
113
chatv2.js
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user