dsh-pi-ai-sync:从 pi.dev 同步模型目录,免去手改 node_modules

前言

在 DeepSeek Harness(DSH)里通过 llm-pi-ai 走 pi.dev 网关时,新模型往往要过两道关:一是 @earendil-works/pi-ai 安装包里的 catalog(DSH 是否认识该模型、走哪种协议),二是配置里的 llm-pi-ai.providers.<route>.models(模型选择器是否列出它)。只改 settings、不改 catalog,在 混合协议 路由(例如 opencode 同时有 anthropic-messages、openai-completions 等)上,缺 catalog 记录的模型会被直接拒绝;手改 node_modules 里的 JSON 既难维护,升级依赖也容易丢。

下面介绍社区插件 dsh-pi-ai-sync(维护者 jiaruihuang),它从 pi.dev 拉取与 catalog 同形的列表,补齐本地 catalog 并按需 reconcile settings,使新 provider 模型可在不手编 node_modules 的情况下变为可选。插件归类为 联网工具;仓库在 SkillHub 目录页 与 GitHub 可查(截至资料抓取时 GitHub 星标为 0)。

这是什么

dsh-pi-ai-sync 是 DSH 的 Cordis 插件:按路由向 https://pi.dev/api/models/providers/<route> 请求数据,在一轮同步里依次处理 catalog 层(写入 @earendil-works/pi-ai/dist/providers/data/<route>.json 中缺失的记录,原子写入并备份首次修改)和 settings 层(按 settingsMode 处理 llm-pi-ai.providers.<route>.models)。设计上融合了 dsh-model-sync(settings 接缝)与 dsh-opencode-go-models(pi-ai catalog 文件),不维护手写协议/家族表,因为 pi.dev 列表本身已是 pi-ai catalog 形状。

DSH 解析模型协议时为 route.api ?? catalog[id].api ?? sharedCatalogApi(route)。在 dsh 0.1.x 线路上,settings 里的模型 schema 没有 单模型 api 字段:单协议路由可用 route 级 api 兜底;混合协议路由则必须依赖完整 catalog,否则缺项即失败。该插件针对的是这一根因,而非仅在 settings 里 workaround。

核心功能

每一轮、每个受管路由的流程(README 原文):

one round, per managed route
  1. GET https://pi.dev/api/models/providers/<route>     (catalog-shaped records)
  2. catalog layer  → copy records the installed catalog is missing into
                       dist/providers/data/<route>.json
                       (atomic write + first-modification backup)
                       ⇒ the model becomes base-matching; restart needed
  3. settings layer → reconcile llm-pi-ai.providers.<route>.models
                       (unset by default; mirror/keep optional)

要点:

  1. catalog 层:缺什么补什么;catalog 在进程启动时载入内存,本轮若新增了模型,会报告 restartNeeded,需重启 DSH 后生效。
  2. settings 层:默认 settingsMode: unset,去掉路由上的 models 覆盖,让补齐后的 catalog 成为列表来源;也可选 mirror(整表重写)或 keep(只动 catalog)。
  3. 定时刷新:可通过 intervalMinutes 等配置自动轮询;0 表示仅启动时执行。
  4. 可选行为:catalogSync、updateExistingModels、keepCatalogOnly 等控制是否维护 catalog、是否刷新已有记录、mirror 模式下是否保留仅存在于 catalog 的 id。

插件无额外 HTTP 代理依赖,使用 Node 全局 fetch 访问 pi.dev。

安装与启用

尚未发布到 npm,需从 GitHub 或本地路径安装(README 原文):

# newest `main` (what you want while the plugin is still young)
dsh plugin --profile web add github:jiaruihuang/dsh-pi-ai-sync

# a pinned release
dsh plugin --profile web add github:jiaruihuang/dsh-pi-ai-sync#v0.1.0

# or from a local checkout:
dsh plugin --profile web add /path/to/dsh-pi-ai-sync

安装后需 重启 dsh(涉及 bundle 层变更)。

从 GitHub 安装会执行包内的 prepare 脚本以编译 TypeScript(lib/ 在仓库中被 gitignore)。pnpm 默认阻止安装期脚本,需在 profile 的 pnpm-workspace.yaml 中按安装报错提示加入 allowBuilds,例如:

allowBuilds:
  "dsh-pi-ai-sync@git+https://github.com/jiaruihuang/dsh-pi-ai-sync.git": true

需使用上述 git+https 形式,而非裸包名或易过期的 tar.gz commit 键。需要可复现环境时,安装命令可钉在 #vX.Y.Z 标签上。

package.json 要求 Node >=22.19.0,许可证 MIT。插件在 当前 dsh 进程权限 下运行,会改写已安装 pi-ai 包内文件并请求外网;安装前请自行审阅源码与许可证。

配置示例

在 dsh 0.1.x 线路下,编辑 ~/.dsh/settings.yaml 中的 pi-ai-sync 段(README 示例):

pi-ai-sync:
  managedRoutes:
    - opencode
    - opencode-go
  settingsMode: unset
  intervalMinutes: 240
Key Default 说明(摘自 README)
managedRoutes [] 要同步的路由;空则等价于 opencode、opencode-go
settingsMode unset unset 移除 models 覆盖;mirror 按 pi.dev 重写列表;keep 不动 settings
catalogSync true 是否维护已安装的 pi-ai catalog 文件
updateExistingModels false 是否用 pi.dev 当日字段刷新 catalog 中已有记录
intervalMinutes 240 自动刷新间隔;0 仅启动时
startupDelaySeconds 5 首次自动轮询前延迟
refreshTimeoutMs 120000 单轮请求超时
fetchAttempts 3 每路由 fetch 次数(指数退避);1 不重试

选择 settingsMode 时:非空的 models 会 替换 对外提供的 catalog 列表(configured.length > 0 ? configured : catalog)。默认 unset 与插件设计一致:catalog 为单一事实来源。若要在不维护 models 的前提下微调某模型,可使用 modelOverrides(不能与非空 models 并存);mirror 每轮整表重写,手改 models 内字段不会保留。

典型用法与网络注意

  1. 安装插件并配置 managedRoutes,保持默认 settingsMode: unset 与 catalogSync: true。
  2. 重启 dsh,等待首轮同步(或查看日志中 syncNotify 相关报告)。
  3. 若本轮 catalog 有新增,按提示再次重启 dsh,再在 Web 或配置里选择新模型。

在不走 models 列表、仅依赖 catalog + 覆盖时,settings 形态示例(README):

llm-pi-ai:
  providers:
    opencode:
      apiKeyEnv: OPENCODE_API_KEY
      baseURL: https://opencode.ai/zen/v1
      modelOverrides:
        step-5-preview-free:
          maxTokens: 65536

仅能通过代理访问 pi.dev 时,Node 的 fetch 默认不读 http_proxy / https_proxy,可能出现 TypeError: fetch failed。需在启动 dsh 时启用环境代理(Node >= 24,README 示例):

NODE_USE_ENV_PROXY=1 dsh web

NO_PROXY 仍会被尊重;这是宿主机侧设置,插件刻意不在包内读取代理环境以避免额外依赖。

适用场景与注意

适合:使用 pi.dev 网关、受管路由(如 opencode、opencode-go)需要与线上模型列表对齐;希望新模型进入选择器且混合协议路由不因缺 catalog 而失败;愿意接受「改 catalog 文件 + 可能重启 dsh」的运维方式。

注意:

  • 改写的是已安装依赖树中的 pi-ai catalog JSON,升级 @earendil-works/pi-ai 后需重新同步或核对备份。
  • mirror 与手写 models / modelOverrides 的组合受 DSH 规则约束(例如 mirror 拒绝与非空 modelOverrides 同路由)。
  • 社区插件目录(SkillHub)与 DeepSeek / 幻方无官方从属关系;DSH 生态强调「一切皆插件」,选用前请自行评估信任边界。

结尾

dsh-pi-ai-sync 把 pi.dev 的 provider 列表同步到 pi-ai catalog 与可选的 llm-pi-ai 模型列表两层,解决混合协议路由下「只改 settings 不够」的问题,减少手改 node_modules。进一步了解可访问 SkillHub 插件页 与 GitHub 仓库 中的完整 README。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye