From bc63ba9611e09aa0d820088930aa76b492575b60 Mon Sep 17 00:00:00 2001 From: thzxx Date: Sun, 5 Apr 2026 19:55:45 +0800 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20Agent=20=E9=A2=84=E8=AE=BE=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=20-=20=E4=B8=80=E9=94=AE=E5=88=87=E6=8D=A2=E8=A7=92?= =?UTF-8?q?=E8=89=B2/=E5=B7=A5=E4=BD=9C=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 内置 6 个预设:默认、翻译官、代码审查、写作助手、数据分析师、学习导师 - 每个预设包含:系统提示词、温度、上下文长度、Think 开关 - 预设栏胶囊按钮,点击即切换,自动应用全部配置 - 支持创建/编辑/删除自定义预设,IndexedDB 持久化 - 切换预设时同步设置面板 UI + toast 提示 - 温度参数集成到聊天 API 调用 --- css/style.css | 160 ++++++++++++++++++ index.html | 53 ++++++ js/app.js | 10 ++ js/components/input-area.js | 4 +- js/components/preset-bar.js | 212 ++++++++++++++++++++++++ js/preset-manager.js | 314 ++++++++++++++++++++++++++++++++++++ 6 files changed, 752 insertions(+), 1 deletion(-) create mode 100644 js/components/preset-bar.js create mode 100644 js/preset-manager.js diff --git a/css/style.css b/css/style.css index d3c3352..9790192 100644 --- a/css/style.css +++ b/css/style.css @@ -372,6 +372,166 @@ body::before { border: 1px solid rgba(0, 245, 212, 0.2); } +/* ── 预设栏 ── */ +.preset-bar { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 16px; + background: var(--bg-secondary); + border-bottom: 1px solid var(--border-glass); + flex-shrink: 0; + overflow: hidden; +} + +.preset-list { + display: flex; + gap: 6px; + flex: 1; + overflow-x: auto; + overflow-y: hidden; + scrollbar-width: none; + -ms-overflow-style: none; + padding: 2px 0; +} + +.preset-list::-webkit-scrollbar { display: none; } + +.preset-chip { + display: flex; + align-items: center; + gap: 5px; + padding: 5px 12px; + border-radius: 20px; + border: 1px solid var(--border-glass); + background: var(--bg-glass-light); + color: var(--text-secondary); + font-size: 12px; + font-weight: 500; + font-family: var(--font-sans); + white-space: nowrap; + cursor: pointer; + transition: var(--transition); + flex-shrink: 0; + user-select: none; +} + +.preset-chip:hover { + background: var(--bg-glass-hover); + border-color: rgba(0, 245, 212, 0.3); + color: var(--text-primary); + transform: translateY(-1px); +} + +.preset-chip.active { + background: var(--gradient-main); + border-color: transparent; + color: #fff; + font-weight: 600; + box-shadow: 0 2px 10px rgba(0, 245, 212, 0.25); +} + +.preset-chip.active:hover { + box-shadow: 0 4px 16px rgba(0, 245, 212, 0.35); + transform: translateY(-1px); +} + +.preset-chip-icon { + font-size: 14px; + line-height: 1; +} + +.preset-chip-name { + line-height: 1; +} + +.preset-add-btn { + width: 30px; + height: 30px; + border-radius: 50%; + border: 1px dashed var(--border-glass); + background: transparent; + color: var(--text-muted); + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: var(--transition); + flex-shrink: 0; +} + +.preset-add-btn:hover { + border-color: var(--accent-cyan); + color: var(--accent-cyan); + background: rgba(0, 245, 212, 0.06); + transform: scale(1.1); +} + +.preset-add-btn svg { + width: 16px; + height: 16px; +} + +/* ── 预设模态框 ── */ +.preset-name-row { + display: flex; + gap: 8px; + align-items: center; +} + +.preset-icon-input { + width: 56px !important; + text-align: center; + font-size: 18px; + flex-shrink: 0; + padding: 8px 4px !important; +} + +.preset-temp-slider { + width: 100%; + -webkit-appearance: none; + appearance: none; + height: 6px; + border-radius: 3px; + background: var(--bg-glass-light); + outline: none; + margin: 8px 0; +} + +.preset-temp-slider::-webkit-slider-thumb { + -webkit-appearance: none; + width: 20px; + height: 20px; + border-radius: 50%; + background: var(--gradient-main); + cursor: pointer; + box-shadow: 0 2px 8px rgba(0, 245, 212, 0.3); + transition: transform 0.15s ease; +} + +.preset-temp-slider::-webkit-slider-thumb:hover { + transform: scale(1.2); +} + +.preset-temp-slider::-moz-range-thumb { + width: 20px; + height: 20px; + border-radius: 50%; + background: var(--gradient-main); + cursor: pointer; + border: none; + box-shadow: 0 2px 8px rgba(0, 245, 212, 0.3); +} + +.preset-modal-actions { + display: flex; + gap: 8px; + align-items: center; + margin-top: 16px; + padding-top: 12px; + border-top: 1px solid var(--border-glass); +} + /* ── Think 按钮(输入栏内) ── */ .think-toggle { display: flex; diff --git a/index.html b/index.html index a100612..a81decb 100644 --- a/index.html +++ b/index.html @@ -366,6 +366,59 @@ + + +
diff --git a/js/app.js b/js/app.js index d945f72..afd7236 100644 --- a/js/app.js +++ b/js/app.js @@ -142,19 +142,23 @@ async function init() { await db.saveSetting('selectedModel', savedModel); } - // 8. 恢复系统提示词和上下文长度 + // 8. 恢复系统提示词、上下文长度、温度 const systemPromptEnabled = await db.getSetting('systemPromptEnabled', false); const systemPrompt = await db.getSetting('systemPrompt', ''); const numCtx = await db.getSetting('numCtx', 24576); + const temperature = await db.getSetting('temperature', 0.7); state.set(KEYS.SYSTEM_PROMPT_ENABLED, systemPromptEnabled); state.set(KEYS.SYSTEM_PROMPT, systemPrompt); state.set(KEYS.NUM_CTX, numCtx); + state.set('temperature', temperature); document.querySelector('#toggleSystemPrompt').checked = systemPromptEnabled; document.querySelector('#inputSystemPrompt').disabled = !systemPromptEnabled; document.querySelector('#inputSystemPrompt').value = systemPrompt; document.querySelector('#inputNumCtx').value = numCtx; + document.querySelector('#inputTemperature').value = temperature; + document.querySelector('#tempValue').textContent = parseFloat(temperature).toFixed(1); // 9. 聚焦输入框 document.querySelector('#chatInput')?.focus(); diff --git a/js/components/settings-modal.js b/js/components/settings-modal.js index 2850296..d1a9a37 100644 --- a/js/components/settings-modal.js +++ b/js/components/settings-modal.js @@ -62,6 +62,21 @@ export function initSettingsModal() { }, 500); document.querySelector('#inputNumCtx').addEventListener('input', saveNumCtx); + // 温度滑块 + const tempSlider = document.querySelector('#inputTemperature'); + const tempDisplay = document.querySelector('#tempValue'); + tempSlider.addEventListener('input', () => { + const val = parseFloat(tempSlider.value); + tempDisplay.textContent = val.toFixed(1); + }); + const saveTemperature = debounce(async () => { + const db = state.get(KEYS.DB); + const val = parseFloat(tempSlider.value); + state.set('temperature', val); + if (db) await db.saveSetting('temperature', val); + }, 300); + tempSlider.addEventListener('change', saveTemperature); + // 释放显存 document.querySelector('#btnReleaseVRAM').addEventListener('click', async () => { const api = state.get(KEYS.API); diff --git a/js/preset-manager.js b/js/preset-manager.js index d3f09e6..dc409c8 100644 --- a/js/preset-manager.js +++ b/js/preset-manager.js @@ -227,6 +227,12 @@ function syncPresetToUI(preset) { const inputCtx = document.querySelector('#inputNumCtx'); if (inputCtx) inputCtx.value = preset.numCtx || 24576; + // Temperature + const tempSlider = document.querySelector('#inputTemperature'); + const tempDisplay = document.querySelector('#tempValue'); + if (tempSlider) tempSlider.value = preset.temperature ?? 0.7; + if (tempDisplay) tempDisplay.textContent = (preset.temperature ?? 0.7).toFixed(1); + // Think toggle const thinkCheckbox = document.querySelector('#toggleThink'); if (thinkCheckbox) { From 039afa5f0ba454cc34c02cabad38bea3b6368d9f Mon Sep 17 00:00:00 2001 From: thzxx Date: Sun, 5 Apr 2026 20:08:51 +0800 Subject: [PATCH 4/7] =?UTF-8?q?chore:=20=E7=89=88=E6=9C=AC=E5=8F=B7?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=E8=87=B3=20v4.0.1=EF=BC=8C=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 ++++++++- index.html | 2 +- js/app.js | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c385612..cc23db9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 支持流式对话、多模态图片输入、文本/代码文件上传分析、Think 深度推理、RAG 本地知识库、历史记录管理,可安装为 PWA 离线使用。 -![版本](https://img.shields.io/badge/version-4.0.0-brightgreen) +![版本](https://img.shields.io/badge/version-4.0.1-brightgreen) ![平台](https://img.shields.io/badge/platform-Web-blue) ![协议](https://img.shields.io/badge/license-MIT-green) @@ -329,6 +329,13 @@ metona-ollama/ ## 📋 更新日志 +### v4.0.1 + +- **设置面板新增温度滑块** — 在上下文长度下方新增 Temperature 滑块控制 (0~2, 步长0.1),实时显示当前值,保存到 IndexedDB 持久化 +- 切换预设时自动同步温度滑块 UI +- 应用启动时从 DB 恢复温度设置 +- 版本号升级至 4.0.1 + ### v4.0.0 - **Agent 预设系统** — 用户可创建、保存多个角色预设,每个预设包含系统提示词、温度、上下文长度、Think 开关。一键切换预设 = 切换人格/工作模式 diff --git a/index.html b/index.html index 09ea17a..38ac426 100644 --- a/index.html +++ b/index.html @@ -20,7 +20,7 @@
Metona Ollama - v4.0.0 + v4.0.1