跳到主要内容

dsh-catalog-refresh

已验证

dsh-catalog-refresh · v0.5.0 · MIT

Rebuild DSH's pi-ai model catalogues at runtime: fetches the live model lists from OpenRouter, OpenCode Zen, Fireworks, Groq, Together and DeepSeek and patches the harness's installed pi-ai MODELS registry, so the model picker and discovery show fresh mod

安装

dsh plugin add dsh-catalog-refresh

用 dsh --profile default --dump-config 确认 layer 已生效 —— 参见安装指南。

源码

发布到 npm 但没有公开仓库。安装前请检查包内容。

标签

说明文档

dsh-catalog-refresh

在运行时重建 DSH 提供的模型目录,让 OpenRouter、OpenCode、Fireworks 等 服务显示最新的模型列表,而不是 DSH 所固定的 @earendil-works/pi-ai 版本里内置的过期快照。

为什么需要它

DSH 的所有 LLM 提供方的模型列表都来自它所捆绑的 @earendil-works/pi-ai 包:dsh-llm-pi-ai 读取 pi-ai 内置的静态 MODELS 注册表 (dist/providers/data/*.json,在 pi-ai 发布时生成)。模型选择器、 Models 页面的发现探测以及请求路由都使用这份内置列表——所以当 OpenRouter 在 pi-ai 发布之后新增模型时,在 DSH 升级 pi-ai 之前,用户只能手工添加 自定义模型。

这个插件在启动时(以及之后按固定节奏)抓取各提供方自己的实时模型端点, 把它们转换成 pi-ai 的 Model 条目,并原地修补 harness 的 pi-ai MODELS 注册表——也就是 dsh-llm-pi-ai 读取的同一个模块实例。仅仅修补 MODELS 还不足以刷新模型选择器:dsh-llm-pi-ai 只在设置分区变化时才会 重新物化每条路由的模型列表,所以插件还会往 llm-pi-ai 设置分区中已声明 提供方的 headers 里写入一个每次刷新都不同的时间戳(深度合并,不触碰 任何已配置字段)。这会让 dsh-llm-pi-ai 针对修补后的注册表重新解析路由, 选择器无需重启即可实时更新。

数据源

provider endpoint auth detail
openrouter https://openrouter.ai/api/v1/models public 完整(定价、上下文、最大 token、推理、模态)
opencode https://opencode.ai/zen/v1/models public 仅 id 列表;已安装元数据保留,新 id 按前缀路由
fireworks https://api.fireworks.ai/inference/v1/models API key id + 上下文、视觉、对话标记
groq https://api.groq.com/openai/v1/models API key id + 上下文、最大 token、模态
together https://api.together.ai/v1/models API key 仅 id 列表;已安装元数据保留
deepseek https://api.deepseek.com/models API key 仅 id 列表;已安装元数据保留

需要密钥的数据源使用常规环境变量 (FIREWORKS_API_KEY、GROQ_API_KEY、TOGETHER_API_KEY、DEEPSEEK_API_KEY) 或 DSH Models 页面保存的凭据记录(llm-pi-ai/<provider>)。没有密钥时该 数据源会被跳过,已安装的目录保持不变。

如何修补

  1. 定位运行中的 harness 所导入的 pi-ai 包,以启动进程的 dsh CLI 入口为 锚点(process.argv[1] → @deepseek-ai/dsh-llm-pi-ai → @earendil-works/pi-ai)。
  2. 通过文件 URL 导入该包的 dist/models.generated.js——Node 以 URL 为键 的模块缓存会保证它与 dsh-llm-pi-ai 通过 @earendil-works/pi-ai/providers/all 读取的是同一个实例。
  3. 用重建后的映射替换 MODELS[provider]。发现调用实时读取注册表,因此 Models 页面的探测立即返回新列表。
  4. 推动选择器重新解析。 dsh-llm-pi-ai 只在设置分区变化时才会重新 物化路由的模型列表,而选择器(llm.models / session.models)服务 的正是这些物化后的列表。因此每次修补后,插件都会向 llm-pi-ai 设置 分区中已声明的每个提供方的 headers 写入一个新时间戳 (settings.yaml 中会出现 x-catalog-refresh: <时间戳> 条目——无实际 作用,深度合并不会改动其他字段)。分区变化会让 dsh-llm-pi-ai 针对 修补后的注册表重新解析路由,选择器立即显示重建后的目录。

启动时先执行缓存轮(不联网,尽早让选择器解析到最新数据),再执行实时轮; 两轮都会触发推动。时间戳按指纹门控:只有当某提供方的模型集合确实变化时 (或每次启动首次)才会推动,因此 settings.yaml 不会在每次重启时被重写。

合并规则:对于 OpenRouter,实时条目优先(定价、上下文、最大 token、推理、 模态),而已安装条目中的精选字段(compat、thinkingLevelMap)在存在时 会保留。对于仅 id 列表的数据源,已安装条目在精选字段(compat、 thinkingLevelMap、推理、成本、线上协议)上保持权威,而实时列表会刷新 端点报告的结构事实(上下文窗口、最大 token、输入模态、名称)—— Fireworks 和 Groq 都会发布这些数据——未知 id 以结构默认值加入。端点报告为 非对话模型的条目(语音/音频输出,如 Groq 的 whisper/orpheus)会被剔除。

抓取的列表缓存在 $DSH_HOME/catalog-refresh/ 下;在没有网络的情况下重启 仍会应用最后一次成功的刷新。

推理档位支持

dsh-llm-pi-ai 只为声明了档位元数据的模型显示 Composer 的推理档位选择器。 pi-ai 内置目录没有任何档位元数据,而 dsh-thinking-effort 插件只处理 手工声明的设置模型——所以目录重建后,目录托管的模型失去了档位选择器。 本插件会为每个重建后的推理模型写入默认 thinkingLevelMap,与 dsh-thinking-effort 的官方预设一致:

  • 推理模型提供 Off / High / Max(OpenRouter 的 openai-completions 线上请求会收到 reasoning: { effort: "high" | "max" }),
  • 非推理模型不提供档位控制(与之前一致)。

可提供的档位由 CATALOG_REFRESH_EFFORTS 控制(逗号分隔的档位 id;off 始终支持)。例如 CATALOG_REFRESH_EFFORTS=off,low,medium,high 会提供 Off/Low/Medium/High。自定义线上值(例如 High 发送 ultra)仍需要在 llm-pi-ai 设置文档里按模型写 reasoningEfforts——本插件只提供目录默认值。

仅 id 列表的数据源(opencode、fireworks、groq、together、deepseek)只返回 模型 id,不返回能力元数据。已知 id 沿用已安装目录的标记;未知 id 默认 按推理模型处理(聊天模型绝大多数都是),因此 Fireworks 的 glm-5p3 等 新模型会立即获得档位选择器。明确非推理的模型家族(Fireworks 的 *-embedding-* / *-reranker-*)会被排除,绝不展示档位。

配置(环境变量)

变量 含义 默认值
CATALOG_REFRESH_DISABLE 设为 1 完全禁用该插件 关闭
CATALOG_REFRESH_INTERVAL_HOURS 重新抓取的节奏(小时) 12
CATALOG_REFRESH_HOME 缓存目录覆盖 $DSH_HOME 或 ~/.dsh
CATALOG_REFRESH_EFFORTS 重建模型提供的推理档位 off,high,max

安装

dsh plugin --profile <profile> add dsh-catalog-refresh

启动输出中每个数据源一行:

[dsh-catalog-refresh] openrouter: patched 396 models (live)
[dsh-catalog-refresh] opencode: patched 67 models (live)
[dsh-catalog-refresh] fireworks: skipped (… answered 401)

运维说明

  • pnpm 安装时会把包复制进 profile。 修改插件源码后需要在 profile 中 再次运行 pnpm install(profile 的 node_modules/dsh-catalog-refresh 是快照而不是符号链接),然后重启 dsh web。
  • 需要密钥的数据源(fireworks、groq、together、deepseek 等)使用常规 环境变量,或 DSH Models 页面保存的凭据记录(llm-pi-ai/<provider>)。
  • 修补只对运行中的进程生效;重启应用会重新执行刷新(网络不可用时优先 应用缓存列表)。
  • settings.yaml 中每个已声明提供方会多出一个 x-catalog-refresh header——这是触发重新解析的机制,不是配置变更。可以安全删除;下次 刷新会自动重写。

开发

npm run check   # 语法检查各模块
npm test        # 单元测试(转换、合并、缓存优先修补、nudge)——无需网络,无机器相关路径