feat: 模型下拉框过滤嵌入模型,版本号升级至3.1.1

- loadModels 后台调用 /api/show 检测 capabilities
- 不支持 completion 的模型自动从下拉框移除
- 更新 README changelog
This commit is contained in:
Metona
2026-04-05 01:10:12 +08:00
parent f1a1c15a27
commit e519631bee
4 changed files with 43 additions and 3 deletions
+6 -1
View File
@@ -4,7 +4,7 @@
支持流式对话、多模态图片输入、文本/代码文件上传分析、Think 深度推理、RAG 本地知识库、历史记录管理,可安装为 PWA 离线使用。 支持流式对话、多模态图片输入、文本/代码文件上传分析、Think 深度推理、RAG 本地知识库、历史记录管理,可安装为 PWA 离线使用。
![版本](https://img.shields.io/badge/version-3.1.0-brightgreen) ![版本](https://img.shields.io/badge/version-3.1.1-brightgreen)
![平台](https://img.shields.io/badge/platform-Web-blue) ![平台](https://img.shields.io/badge/platform-Web-blue)
![协议](https://img.shields.io/badge/license-MIT-green) ![协议](https://img.shields.io/badge/license-MIT-green)
@@ -326,6 +326,11 @@ metona-ollama/
## 📋 更新日志 ## 📋 更新日志
### v3.1.1
- **模型选择下拉框过滤嵌入模型** — 后台检测模型 capabilities,自动移除不支持 completion 的嵌入模型(如 `nomic-embed-text`),仅保留可用于聊天的模型
- 版本号升级至 3.1.1
### v3.1.0 ### v3.1.0
- **修复 RAG 知识库问答时消息不显示的问题** — 开启 RAG 后 AI 回复内容无法渲染,页面一直显示"正在思考..." - **修复 RAG 知识库问答时消息不显示的问题** — 开启 RAG 后 AI 回复内容无法渲染,页面一直显示"正在思考..."
+1 -1
View File
@@ -20,7 +20,7 @@
<div class="header-left"> <div class="header-left">
<span class="logo">🦙</span> <span class="logo">🦙</span>
<span class="app-title">Metona Ollama</span> <span class="app-title">Metona Ollama</span>
<span class="app-version">v3.1.0</span> <span class="app-version">v3.1.1</span>
<button class="icon-btn help-btn" id="btnHelp" title="使用帮助"> <button class="icon-btn help-btn" id="btnHelp" title="使用帮助">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/> <circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/>
+1 -1
View File
@@ -33,7 +33,7 @@ function initHelpModal() {
}); });
} }
console.log('[Metona] 模块化版本 v3.1.0 ' + new Date().toISOString()); console.log('[Metona] 模块化版本 v3.1.1 ' + new Date().toISOString());
// ── 会话管理 ── // ── 会话管理 ──
+35
View File
@@ -82,6 +82,10 @@ export async function loadModels() {
if (modelSelectEl.value) { if (modelSelectEl.value) {
await checkModelCapability(modelSelectEl.value); await checkModelCapability(modelSelectEl.value);
} }
// 后台过滤:移除不支持 completion 的嵌入模型
filterEmbedModels(data.models);
} catch (err) { } catch (err) {
console.error('[ModelBar] 加载模型失败:', err); console.error('[ModelBar] 加载模型失败:', err);
modelSelectEl.innerHTML = '<option value="">加载失败 - 检查连接</option>'; modelSelectEl.innerHTML = '<option value="">加载失败 - 检查连接</option>';
@@ -90,6 +94,37 @@ export async function loadModels() {
} }
} }
/**
* 后台检测并过滤嵌入模型(不支持 completion 的模型)
*/
async function filterEmbedModels(models) {
for (const m of models) {
try {
const info = await api().showModel(m.name);
const caps = info.capabilities || [];
const isCompletion = caps.includes('completion');
// 缓存能力
modelCapabilityCache.set(m.name, {
think: caps.includes('thinking'),
vision: caps.includes('vision'),
completion: isCompletion,
});
// 从下拉框移除不支持 completion 的模型
if (!isCompletion) {
const opt = modelSelectEl.querySelector(`option[value="${CSS.escape(m.name)}"]`);
if (opt) opt.remove();
}
} catch { /* 忽略检测失败的模型 */ }
}
// 如果当前选中的模型被移除了,选中第一个可用模型
if (!modelSelectEl.value && modelSelectEl.options.length > 0) {
modelSelectEl.value = modelSelectEl.options[0].value;
state.set('_defaultModel', modelSelectEl.value);
if (db()) await db().saveSetting('selectedModel', modelSelectEl.value);
await checkModelCapability(modelSelectEl.value);
}
}
/** /**
* 调用 /api/show 检测模型能力 * 调用 /api/show 检测模型能力
* @param {string} modelName * @param {string} modelName