CN-WenYu/dsh-live-model-catalog ↗★ 0
dsh-live-model-catalog
DSH plugin: keeps every llm-pi-ai route (custom providers included) in step with its endpoint's own /models — adds new models, fills contextWindow / maxTokens / input / reasoningEfforts, writes thinking levels when the endpoint reports reasoning, and makes the "fetch available models" button live. Official settings seam only; no patching, uninstall-safe.
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:CN-WenYu/dsh-live-model-catalog说明文档
阅读完整 README ↗配置
写在 ~/.dsh/settings.yaml(插件自己注册 live-model-catalog 命名空间):
live-model-catalog:
mode: auto # auto = llm-pi-ai 下所有路由都管;listed = 只管理 routes 里点名的
exclude: [] # 想放过的路由(auto 模式下生效),如 ['local', '*-experimental']
routes: {} # 逐路由覆盖,见下文「跨协议目录的路由」
# 例:{ openrouter: { api: 'openai-completions' } } ← 让该路由能真的接纳目录外的新模型
include: ['*'] # 允许被"新增"的 id 白名单;['*'] = 所有厂商;留空 = 只补齐不新增
addSince: 'snapshot' # 只新增 pi-ai 快照之后发布的模型;也可写日期/秒;留空 = 不设下限
skipAliases: true # 端点自称别名的 id 不写入配置(会在端点侧漂移)
fill: [contextWindow, maxTokens, input, reasoningEfforts]
fixDiscovery: true # 见下文「模块 B」(默认开;可运行期关掉)
startupDelaySeconds: 5
intervalMinutes: 240 # 0 = 只在启动时跑一次
范围是发现出来的,不是写死的:mode: auto(默认)会把 llm-pi-ai.providers 里的每个路由都纳入,包括 pi-ai 内置提供方——内置路由在 profile 里通常不写 baseURL,插件的端点解析顺序是
本插件的 routes..baseURL → llm-pi-ai 该路由的 baseURL → pi-ai 内置提供方表
第三层通过一个有守卫的解析链拿到(优先裸 import;否则把锚点 realpath 后再从 dsh-llm-pi-ai 的解析结果向上找 node_modules/@earendil-works/pi-ai——PATH 上的 dsh 是符号链接,不解析成真实路径就找不到;两者都失败就只在报告里说明),所以内置 openrouter 这类路由无需你手写端点。报告里每条路由都会标出端点来自哪一层。
列取协议也来自路由事实,不是猜的:routes..api → 该路由的 api → pi-ai 目录里这些模型唯一一致的协议 → 兜底 openai-completions。这一步很要紧,因为列取的 URL 与鉴权都跟协议走:给一条内置 anthropic 路由(profile 里通常只写 apiKeyEnv)猜 openai-completions,就会去请求 api.anthropic.com/models 并带 bearer,而不是 /v1/models?limit=1000 + x-api-key——一条本来完全可管理的路由会变成每轮一个看不懂的失败。协议若不在官方可列举的三种之内,插件先判定再跳过,不去探测。
| 字段 | 作用 | 默认 |
|---|---|---|
mode | auto = 自动纳管 llm-pi-ai 下所有路由;listed = 只管理 routes 点名的 | auto |
exclude | auto 模式下要放过的路由名 glob | [] |
routes. | 逐路由覆盖 enabled/baseURL/api/apiKeyEnv;api 同时决定该路由能否接纳目录外的新模型,见下文 | 无 |
include | 允许自动新增的 id glob;* 跨 / | ['*'](所有厂商) |
addSince | 只新增该日期/时间戳之后发布的模型;snapshot = pi-ai 快照的生成时间 | 'snapshot' |
fill | 允许补齐的字段 | 全部四个 |
defaultEfforts | 端点说"会推理"但没给档位表时使用的预设 | {off: none, high: high, max: max} |
skipAliases | 端点标为别名的 id 是否跳过(alias_target) | true |
fixDiscovery | 是否同时修「获取可用模型」按钮 | true |
intervalMinutes | 周期刷新;0 关闭 | 240 |
requestTimeoutSeconds | 单次请求超时 | 20 |
必须先有
models列表。 只在路由已经声明models时才写入:如果某路由靠继承拿整个内置目录,写models会把它替换成你写的那几条(DSH 的语义是"替换"而非"扩展")。这种情况插件会跳过并在报告里说明。
新增是三道闸门。
include默认['*'](所有厂商),但另有两道兜着:addSince默认'snapshot'——取的是已装 pi-ai 目录自己的生成时间(读dist/providers/data/.manifest.json的generatedAt),DSH 升级 pi-ai 时它自己跟着走,不用你记着改日期。实例(实测):默认组合在快照为 2026-09-05 的机器上,对 OpenRouter 第一轮新增 7 条真实新模型、跳过 16 条端点别名(~openai/*-latest这类会漂移的 id,逐条点名)、挡住 415 条早于快照的历史。想只补不增就把include写成[]。如果
snapshot读不到(pi-ai 定位失败),插件只补不增并在报告里说明——一个解析不了的闸门绝不会变成敞开的闸门。想真的不设下限,把addSince显式写成空。
跨协议目录的路由:为什么有时要写 routes..api
DSH 给一个模型定协议的顺序是 路由 api → 目录里同 id 条目的 api → 整条目录唯一协议。于是目录里没有的模型在两种情况下没有协议可用:路由自己没声明 api,而该路由的目录又跨了不止一种协议(典型就是内置 openrouter——366 条里同时有 openai-completions 与 anthropic-messages)。
更麻烦的是 DSH 对一次配置写入整体校验:这样一个条目会让整轮写入被拒,连本来能安全写进去的 input / reasoningEfforts 一起丢掉。插件因此做两件事:
- 这种候选模型不进入写入,改为在报告里点名,并给出一句可照抄的处置(
需声明协议:…); - 你在
live-model-catalog.routes..api里声明协议后,插件把它和models放进同一笔写入补进llm-pi-ai——只在该路由原本没有api时写,而且会先核对:若声明它会改掉任何既有模型的协议,就拒绝写入并说明是哪些模型。
协议由你声明、插件不猜:猜错意味着那个模型的每次请求都失败,比一次可见的拒绝更糟。即使写入仍被 DSH 因别的原因整体拒绝,插件也会自动退回"只写补齐",保住已经能安全落地的部分,并把拒绝原因留在报告里(新增被拒,已保住补齐)。
让思考强度真正可选
模型条目里 reasoningEfforts 的语义:
reasoningEfforts:
off: none # 键 = 选择器里的档位;值 = 实际发给端点的 wire 值
low: low # 未声明的档位 = 不支持,不会出现在选择器里
high: high
本插件把它从端点的 reasoning.supported_efforts 自动翻译过来(none → off);reasoning.mandatory: true 的模型不会提供"关闭"。端点没给档位表时使用 defaultEfforts 预设,并在报告里标注。