tui.js:/manage 改为只显示已连接 provider(读 opencode.json provider 字段),不再拉全量 232 个

This commit is contained in:
youpaishidifu
2026-10-19 10:48:58 +08:00
parent fd8cfa8887
commit 90eb09b2a4
+34 -18
View File
@@ -470,45 +470,61 @@ function mmReadCatalog() {
async function openModelManager(context) {
try {
const cat = await mmReadCatalog()
if (!cat || !cat.body) {
context.ui.toast.show({
message: "模型目录读取失败(DB 路径或 catalog 行缺失)",
variant: "error",
})
return
// 从 opencode.json 读「已连接 provider」(用户配了 API key 的),不是 catalog 全量
let connectedProviders = []
try {
const cfgPath = join(homedir(), ".config", "opencode", "opencode.json")
if (existsSync(cfgPath)) {
const cfg = JSON.parse(readFileSync(cfgPath, "utf-8"))
const prov = (cfg && cfg.provider) || {}
// 每个 provider 的 models 字典,合并成 {providerName: modelList}
for (const pid of Object.keys(prov)) {
const pv = prov[pid] || {}
// provider 名称优先取 name,其次 id
const name = pv.name || pid
const models = Object.keys((pv.models && pv.models) || {})
connectedProviders.push({ id: pid, name, models })
}
}
} catch (e) {
log("[oc-session-all] /manage 读 config provider 失败: " + e.message)
}
const providers = Object.keys(JSON.parse(cat.body))
if (providers.length === 0) {
context.ui.toast.show({ message: "模型目录为空", variant: "warning" })
if (connectedProviders.length === 0) {
context.ui.toast.show({
message: "没有已连接 provider(opencode.json 的 provider 字段为空),先 /connect 一个再 /manage",
variant: "warning",
})
return
}
// 第一层:选 provider(顶置「恢复出厂」全局操作)
// 注意:OC dialog.select 的 options 字段是 title/value(不是 label/value,label 会 undefined→崩溃)
const providerOptions = [
{
title: "🏭 恢复出厂(全部 provider)",
title: "🏭 恢复出厂(全部已连接 provider)",
value: "__reset_all__",
},
...providers.map((p) => ({ title: p, value: p })),
...connectedProviders.map((p) => ({
title: p.name + "(" + p.models.length + " 个模型)",
value: p.name,
})),
]
const pickProvider = await context.ui.dialog.select({
title: "模型管理 · 选 provider",
placeholder: "选一个 provider 管理其模型…",
title: "模型管理 · 选已连接 provider",
placeholder: "选一个已连接 provider 管理其模型…",
options: providerOptions,
})
if (!pickProvider) return
if (pickProvider === "__reset_all__") {
for (const p of providers) mmEnqueue("reset", { provider: p })
for (const p of connectedProviders) mmEnqueue("reset", { provider: p.name })
context.ui.toast.show({
message: "恢复出厂已入队(" + providers.length + " 个 provider),等 daemon 消费后 /models 生效",
message: "恢复出厂已入队(" + connectedProviders.length + " 个 provider),等 daemon 消费后 /models 生效",
variant: "info",
})
return
}
// 该 provider 的当前 models
const pbody = JSON.parse(cat.body)[pickProvider] || {}
const models = Object.keys(pbody.models || {})
const target = connectedProviders.find((p) => p.name === pickProvider)
const models = (target && target.models) || []
if (models.length === 0) {
context.ui.toast.show({ message: pickProvider + " 下没有模型", variant: "warning" })
return