refactor: combine backend and model selectors into one dropdown
Co-authored-by: aider (openai//models/qwen2.5-coder-32b-instruct-q4_k_m.gguf) <aider@aider.chat>
This commit is contained in:
88
chatv2.js
88
chatv2.js
@@ -19,6 +19,19 @@ const IS_PRODUCTION = window.location.hostname === 'jarvis-lan.appmodel.nl'
|
|||||||
const API_KEY = 'not-needed'
|
const API_KEY = 'not-needed'
|
||||||
const MAX_CHAT_HISTORY = 50
|
const MAX_CHAT_HISTORY = 50
|
||||||
|
|
||||||
|
let currentBackendModel = null
|
||||||
|
let availableBackendModels = []
|
||||||
|
let currentStreamController = null
|
||||||
|
let isStreaming = false
|
||||||
|
let chatHistory = JSON.parse(localStorage.getItem('chatHistory')) || []
|
||||||
|
|
||||||
|
chatHistory = chatHistory.map(message => ({
|
||||||
|
role : message.role || 'user',
|
||||||
|
content : message.content || '',
|
||||||
|
markdown : message.markdown || false,
|
||||||
|
messageId: message.messageId || `msg-${ Date.now() }`
|
||||||
|
}))
|
||||||
|
|
||||||
const welcomeMessage = `# Welcome to LM Studio Chat!
|
const welcomeMessage = `# Welcome to LM Studio Chat!
|
||||||
|
|
||||||
I now support **full conversation history**, **real-time streaming responses** and **dark, readable text formatting**.
|
I now support **full conversation history**, **real-time streaming responses** and **dark, readable text formatting**.
|
||||||
@@ -38,68 +51,60 @@ I now support **full conversation history**, **real-time streaming responses** a
|
|||||||
|
|
||||||
> *Tip: You can toggle streaming and markdown using the checkboxes below.*`
|
> *Tip: You can toggle streaming and markdown using the checkboxes below.*`
|
||||||
|
|
||||||
let currentBackend = 'plato'
|
|
||||||
let currentModel = null
|
|
||||||
let availableModels = []
|
|
||||||
let currentStreamController = null
|
|
||||||
let isStreaming = false
|
|
||||||
let chatHistory = JSON.parse(localStorage.getItem('chatHistory')) || []
|
|
||||||
|
|
||||||
chatHistory = chatHistory.map(message => ({
|
|
||||||
role : message.role || 'user',
|
|
||||||
content : message.content || '',
|
|
||||||
markdown : message.markdown || false,
|
|
||||||
messageId: message.messageId || `msg-${ Date.now() }`
|
|
||||||
}))
|
|
||||||
|
|
||||||
function getApiUrl() {
|
function getApiUrl() {
|
||||||
const backend = BACKENDS[currentBackend]
|
const [backendKey, model] = currentBackendModel.split(':')
|
||||||
|
const backend = BACKENDS[backendKey]
|
||||||
return IS_PRODUCTION ? backend.prod : backend.dev
|
return IS_PRODUCTION ? backend.prod : backend.dev
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateBackendDisplay() {
|
function updateBackendModelDisplay() {
|
||||||
const backend = BACKENDS[currentBackend]
|
const [backendKey, model] = currentBackendModel.split(':')
|
||||||
|
const backend = BACKENDS[backendKey]
|
||||||
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
|
document.getElementById('backendDisplay').textContent = `${ displayText } - Model: ${ model }`
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchModels() {
|
async function fetchBackendModels() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${ getApiUrl() }/models`)
|
const response = await fetch(`${ getApiUrl() }/models`)
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
availableModels = data.data || []
|
availableBackendModels = data.data.map(model => ({
|
||||||
populateModelSelector()
|
backend: currentBackendModel.split(':')[0],
|
||||||
|
model: model.id
|
||||||
|
}))
|
||||||
|
populateBackendModelSelector()
|
||||||
|
|
||||||
if (!currentModel && availableModels.length > 0) {
|
if (!currentBackendModel && availableBackendModels.length > 0) {
|
||||||
currentModel = availableModels[0].id
|
currentBackendModel = `${ availableBackendModels[0].backend }:${ availableBackendModels[0].model }`
|
||||||
document.getElementById('modelSelector').value = currentModel
|
document.getElementById('backendModelSelector').value = currentBackendModel
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('Failed to fetch models:', response.statusText)
|
console.error('Failed to fetch models:', response.statusText)
|
||||||
document.getElementById('modelSelector').innerHTML = '<option value="">Error loading models</option>'
|
document.getElementById('backendModelSelector').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('modelSelector').innerHTML = '<option value="">Error loading models</option>'
|
document.getElementById('backendModelSelector').innerHTML = '<option value="">Error loading models</option>'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateModelSelector() {
|
function populateBackendModelSelector() {
|
||||||
const selector = document.getElementById('modelSelector')
|
const selector = document.getElementById('backendModelSelector')
|
||||||
if (availableModels.length === 0) {
|
if (availableBackendModels.length === 0) {
|
||||||
selector.innerHTML = '<option value="">No models available</option>'
|
selector.innerHTML = '<option value="">No models available</option>'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
selector.innerHTML = availableModels.map(model =>
|
selector.innerHTML = availableBackendModels.map(backendModel =>
|
||||||
`<option value="${ model.id }">${ model.id }</option>`
|
`<option value="${ backendModel.backend }:${ backendModel.model }">${ BACKENDS[backendModel.backend].name } - ${ backendModel.model }</option>`
|
||||||
).join('')
|
).join('')
|
||||||
|
|
||||||
if (currentModel) {
|
if (currentBackendModel) {
|
||||||
selector.value = currentModel
|
selector.value = currentBackendModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,22 +123,15 @@ function trimChatHistory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const backendSelector = document.getElementById('backendSelector')
|
const backendModelSelector = document.getElementById('backendModelSelector')
|
||||||
const modelSelector = document.getElementById('modelSelector')
|
|
||||||
|
|
||||||
backendSelector.value = currentBackend
|
backendModelSelector.addEventListener('change', (e) => {
|
||||||
updateBackendDisplay()
|
currentBackendModel = e.target.value
|
||||||
fetchModels()
|
updateBackendModelDisplay()
|
||||||
|
fetchBackendModels()
|
||||||
backendSelector.addEventListener('change', (e) => {
|
|
||||||
currentBackend = e.target.value
|
|
||||||
updateBackendDisplay()
|
|
||||||
fetchModels()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
modelSelector.addEventListener('change', (e) => {
|
fetchBackendModels()
|
||||||
currentModel = e.target.value
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const chatLog = document.getElementById('chatLog')
|
const chatLog = document.getElementById('chatLog')
|
||||||
|
|||||||
14
index.html
14
index.html
@@ -15,17 +15,9 @@
|
|||||||
<div>Chat with Streaming</div>
|
<div>Chat with Streaming</div>
|
||||||
<div style="font-size: 0.9em; opacity: 0.9; display: flex; align-items: center; gap: 15px; flex-wrap: wrap;">
|
<div style="font-size: 0.9em; opacity: 0.9; display: flex; align-items: center; gap: 15px; flex-wrap: wrap;">
|
||||||
<div style="display: flex; align-items: center; gap: 8px;">
|
<div style="display: flex; align-items: center; gap: 8px;">
|
||||||
<span>Backend:</span>
|
<span>Backend & Model:</span>
|
||||||
<select id="backendSelector" style="padding: 4px 8px; border-radius: 4px; border: 1px solid #444; background: #2a2a2a; color: #e0e0e0;">
|
<select id="backendModelSelector" style="padding: 4px 8px; border-radius: 4px; border: 1px solid #444; background: #2a2a2a; color: #e0e0e0; min-width: 200px;">
|
||||||
<option value="ollama">Ollama (192.168.1.159:8081)</option>
|
<option value="">Loading backends and models...</option>
|
||||||
<option value="plato">Plato (192.168.1.74)</option>
|
|
||||||
<option value="stoic">Stoic (192.168.1.159)</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div style="display: flex; align-items: center; gap: 8px;">
|
|
||||||
<span>Model:</span>
|
|
||||||
<select id="modelSelector" style="padding: 4px 8px; border-radius: 4px; border: 1px solid #444; background: #2a2a2a; color: #e0e0e0; min-width: 200px;">
|
|
||||||
<option value="">Loading models...</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<code id="backendDisplay" style="font-size: 0.85em;"></code>
|
<code id="backendDisplay" style="font-size: 0.85em;"></code>
|
||||||
|
|||||||
Reference in New Issue
Block a user