From 90eb09b2a4495114244ed2e4f7dea5521278e47a Mon Sep 17 00:00:00 2001 From: youpaishidifu Date: Mon, 19 Oct 2026 10:48:58 +0800 Subject: [PATCH] =?UTF-8?q?tui.js=EF=BC=9A/manage=20=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=8F=AA=E6=98=BE=E7=A4=BA=E5=B7=B2=E8=BF=9E=E6=8E=A5=20provid?= =?UTF-8?q?er=EF=BC=88=E8=AF=BB=20opencode.json=20provider=20=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=EF=BC=89=EF=BC=8C=E4=B8=8D=E5=86=8D=E6=8B=89=E5=85=A8?= =?UTF-8?q?=E9=87=8F=20232=20=E4=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tui-plugins/oc-session-all.js | 52 +++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/tui-plugins/oc-session-all.js b/tui-plugins/oc-session-all.js index b03de82..26560ea 100644 --- a/tui-plugins/oc-session-all.js +++ b/tui-plugins/oc-session-all.js @@ -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