fix: restore trash icon, remove vestigial model dropdown, default preset to General Assistant
This commit is contained in:
+20
-15
@@ -4,6 +4,9 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>JarvisChat</title>
|
<title>JarvisChat</title>
|
||||||
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||||
|
<meta http-equiv="Pragma" content="no-cache">
|
||||||
|
<meta http-equiv="Expires" content="0">
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600&family=IBM+Plex+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600&family=IBM+Plex+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
@@ -228,7 +231,7 @@ body { font-family: var(--font-body); background: var(--bg-primary); color: var(
|
|||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<img class="logo" src="/static/logo.png" alt="JarvisChat Logo" onerror="this.style.display='none'">
|
<img class="logo" src="/static/logo.png" alt="JarvisChat Logo" onerror="this.style.display='none'">
|
||||||
<h1>⚡ JarvisChat {{ version }}</h1>
|
<h1>⚡ JarvisChat {{ version }}</h1>
|
||||||
<div class="subtitle">🦙 local coding companion</div>
|
<div class="subtitle">🦙 local coding companion <span id="tmplVer" style="font-size:9px;color:var(--danger)">v3</span></div>
|
||||||
<div class="btn-row">
|
<div class="btn-row">
|
||||||
<button class="new-chat-btn" onclick="newChat()">+ New Chat</button>
|
<button class="new-chat-btn" onclick="newChat()">+ New Chat</button>
|
||||||
<button class="settings-btn" onclick="openSettings()">⚙</button>
|
<button class="settings-btn" onclick="openSettings()">⚙</button>
|
||||||
@@ -318,10 +321,7 @@ body { font-family: var(--font-body); background: var(--bg-primary); color: var(
|
|||||||
|
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<div class="topbar">
|
<div class="topbar">
|
||||||
<div class="topbar-left">
|
<div class="topbar-left"></div>
|
||||||
<span class="topbar-label">Model</span>
|
|
||||||
<select id="modelSelect"></select>
|
|
||||||
</div>
|
|
||||||
<div class="topbar-right">
|
<div class="topbar-right">
|
||||||
<button class="memory-badge on" id="memoryBadge" onclick="toggleMemory()" title="Toggle memory injection">🧠 MEM ON</button>
|
<button class="memory-badge on" id="memoryBadge" onclick="toggleMemory()" title="Toggle memory injection">🧠 MEM ON</button>
|
||||||
<button class="search-badge on" id="searchBadge" onclick="toggleSearch()" title="Toggle auto web search">🔍 SEARCH ON</button>
|
<button class="search-badge on" id="searchBadge" onclick="toggleSearch()" title="Toggle auto web search">🔍 SEARCH ON</button>
|
||||||
@@ -364,6 +364,7 @@ let memoryEnabled = true;
|
|||||||
let skillsEnabled = true;
|
let skillsEnabled = true;
|
||||||
let presets = [];
|
let presets = [];
|
||||||
let skillsRegistry = [];
|
let skillsRegistry = [];
|
||||||
|
let currentModel = '';
|
||||||
let modelContextSize = 8192;
|
let modelContextSize = 8192;
|
||||||
let cachedProfile = '';
|
let cachedProfile = '';
|
||||||
let conversationHistory = [];
|
let conversationHistory = [];
|
||||||
@@ -664,21 +665,20 @@ async function loadModels() {
|
|||||||
try {
|
try {
|
||||||
const resp = await authFetch('/api/models');
|
const resp = await authFetch('/api/models');
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
const select = document.getElementById('modelSelect');
|
|
||||||
const settingSelect = document.getElementById('defaultModelSetting');
|
const settingSelect = document.getElementById('defaultModelSetting');
|
||||||
select.innerHTML = '';
|
|
||||||
settingSelect.innerHTML = '';
|
settingSelect.innerHTML = '';
|
||||||
(data.models || []).forEach(m => {
|
(data.models || []).forEach(m => {
|
||||||
const gb = (m.size / (1024*1024*1024)).toFixed(1);
|
|
||||||
select.add(new Option(m.name + ' (' + gb + 'GB)', m.name));
|
|
||||||
settingSelect.add(new Option(m.name, m.name));
|
settingSelect.add(new Option(m.name, m.name));
|
||||||
});
|
});
|
||||||
select.addEventListener('change', fetchModelContextSize);
|
if (!currentModel && data.models?.length) {
|
||||||
|
currentModel = data.models[0].name;
|
||||||
|
await fetchModelContextSize();
|
||||||
|
}
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchModelContextSize() {
|
async function fetchModelContextSize() {
|
||||||
const model = document.getElementById('modelSelect').value;
|
const model = currentModel;
|
||||||
if (!model) return;
|
if (!model) return;
|
||||||
try {
|
try {
|
||||||
const resp = await authFetch('/api/show', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ name: model }) });
|
const resp = await authFetch('/api/show', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ name: model }) });
|
||||||
@@ -702,7 +702,7 @@ async function loadSettings() {
|
|||||||
updateMemoryUI();
|
updateMemoryUI();
|
||||||
updateSkillsUI();
|
updateSkillsUI();
|
||||||
if (s.default_model) {
|
if (s.default_model) {
|
||||||
document.getElementById('modelSelect').value = s.default_model;
|
currentModel = s.default_model;
|
||||||
document.getElementById('defaultModelSetting').value = s.default_model;
|
document.getElementById('defaultModelSetting').value = s.default_model;
|
||||||
}
|
}
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
@@ -924,7 +924,12 @@ function renderPresetSelect() {
|
|||||||
const current = select.value;
|
const current = select.value;
|
||||||
select.innerHTML = '<option value="">None (profile only)</option>';
|
select.innerHTML = '<option value="">None (profile only)</option>';
|
||||||
presets.forEach(p => select.add(new Option(p.name, p.id)));
|
presets.forEach(p => select.add(new Option(p.name, p.id)));
|
||||||
|
if (current) {
|
||||||
select.value = current;
|
select.value = current;
|
||||||
|
} else {
|
||||||
|
const ga = presets.find(p => p.name === 'General Assistant');
|
||||||
|
if (ga) select.value = ga.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addPreset() {
|
async function addPreset() {
|
||||||
@@ -993,7 +998,7 @@ async function loadConversation(convId) {
|
|||||||
const resp = await authFetch(`/api/conversations/${convId}`);
|
const resp = await authFetch(`/api/conversations/${convId}`);
|
||||||
const data = await resp.json();
|
const data = await resp.json();
|
||||||
currentConvId = convId;
|
currentConvId = convId;
|
||||||
document.getElementById('modelSelect').value = data.conversation.model;
|
currentModel = data.conversation.model;
|
||||||
fetchModelContextSize();
|
fetchModelContextSize();
|
||||||
const container = document.getElementById('chatContainer');
|
const container = document.getElementById('chatContainer');
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
@@ -1040,7 +1045,7 @@ async function sendSearch() {
|
|||||||
const input = document.getElementById('userInput');
|
const input = document.getElementById('userInput');
|
||||||
const query = input.value.trim();
|
const query = input.value.trim();
|
||||||
if (!query || isStreaming) return;
|
if (!query || isStreaming) return;
|
||||||
const model = document.getElementById('modelSelect').value;
|
const model = currentModel;
|
||||||
const welcome = document.getElementById('welcomeScreen');
|
const welcome = document.getElementById('welcomeScreen');
|
||||||
if (welcome) welcome.remove();
|
if (welcome) welcome.remove();
|
||||||
appendMessage('user', '🔍 ' + query, true);
|
appendMessage('user', '🔍 ' + query, true);
|
||||||
@@ -1113,7 +1118,7 @@ async function sendMessage() {
|
|||||||
const input = document.getElementById('userInput');
|
const input = document.getElementById('userInput');
|
||||||
const message = input.value.trim();
|
const message = input.value.trim();
|
||||||
if (!message || isStreaming) return;
|
if (!message || isStreaming) return;
|
||||||
const model = document.getElementById('modelSelect').value;
|
const model = currentModel;
|
||||||
const presetPrompt = getSelectedPresetPrompt();
|
const presetPrompt = getSelectedPresetPrompt();
|
||||||
const welcome = document.getElementById('welcomeScreen');
|
const welcome = document.getElementById('welcomeScreen');
|
||||||
if (welcome) welcome.remove();
|
if (welcome) welcome.remove();
|
||||||
|
|||||||
Reference in New Issue
Block a user