dsh-free-model

August 27, 2026 · View on GitHub

dsh-free-model logo

dsh-free-model 是一个 DeepSeek Harness(DSH)插件: 浏览 OpenRouter 的免费模型,一键把其中任何一个添加到 DSH 模型列表。

  • 平台 tab:设置入口内按平台分 tab(当前内置 OpenRouter;PLATFORMS 注册表让后续平台 接入只需一行)。拉取/过滤/排序都在宿主侧完成,tab 是唯一入口。
  • 免费模型目录:由宿主拉取 https://openrouter.ai/api/v1/models,只保留价格为 0 (prompt 与 completion 同时为 0)或带 :free 标记的模型,并按 OpenRouter 的 created 时间倒序排列——最新上线的模型永远在最上面。结果缓存到 $DSH_HOME/dsh-free-model.json (6 小时新鲜窗口;网络重试全部失败时降级展示旧缓存并提示)。
  • 卡片展示完整信息:名称、id(点击复制)、上架时间、上下文长度、最大输出、输入/输出 模态、分词器、价格、支持的请求参数、内容审核 / 强制推理标记、可展开的完整描述——并支持 二次本地搜索(id / 名称 / 描述 / 厂商)。排版适配窄面板与移动端(卡片纵向堆叠、 网格退化单列、弹框转为全屏页签)。
  • 「添加到模型列表」→ 一键创建模型配置:仅当该平台还没有已存凭据时才要求输入 OpenRouter API Token(可现场「校验」,调 GET /api/v1/key)。确定后:
    1. Token 经宿主 credentials 服务落 .credentials.yamlOPENROUTER_API_KEY);
    2. 把模型并入 settings.yaml 里的 OpenRouter 路由llm-pi-ai 命名空间——已有 openrouter / openrouter-free / baseURL 指向 openrouter.ai 的路由时并入,原样保留其 apiKeyEnv 与已有模型条目;否则新建 openrouter-free 路由,openai-completions 协议 + https://openrouter.ai/api/v1);
    3. 可选勾选设为新会话的默认模型agent-default-model 命名空间)。 完成后模型立即出现在对话框底部的模型选择器中,无需重启宿主
  • 稳健拉取:所有 OpenRouter 请求失败自动重试,最多 10 次(指数退避 + 抖动)。
  • 中英双语界面,无硬编码路径。

English

命令

脚本作用
npm run checktsc -b 类型检查(host + client 两个 program)
npm run build清理 lib/tsc -b,tsdown 打包 lib/index.js(宿主,ESM)+ lib/client.js(浏览器,__ModuleLoader__ 工厂)
npm run watchtsdown watch 模式
npm run verify模拟宿主模块加载器校验 lib/client.js(工厂形状 + seed 外部依赖)
npm run test:ops宿主逻辑离线单测(免费判定、排序、路由识别、配置写入编排、数据文件往返)
npm run smoke直连真实 OpenRouter /models 的冒烟测试
npm run releasecheck + build + verify,然后 npm version patchgit push --follow-tags
npm run publish:npmcheck + build + verify,然后 npm publish --access public

安装

# 本地开发(link 工作区;lib/ 重新构建后自动生效)
dsh plugin --profile web add ./dsh-free-model

# 已发布:npm / tarball / GitHub
dsh plugin --profile web add dsh-free-model
dsh plugin --profile web add github:you/dsh-free-model#<sha>

dsh --profile web --dump-config   # 确认分层
dsh --profile web                 # 启动(宿主半边需要重启后加载)

本地开发依赖:宿主经原生 Node ESM 加载 lib/index.js,因此插件目录必须能解析 @deepseek-ai/schemastery@deepseek-ai/dsh-settings。在插件目录里执行一次 pnpm install,或直接使用仓库内已提交的 lib/ 构建产物(本仓库提交 lib/,与 dsh-jenkins 一致)。

使用

  1. 打开 设置 → 免费模型,选择平台 tab(OpenRouter)。
  2. 列表按上架时间倒序出现(缓存新鲜时秒出;点刷新强制回源)。
  3. 在搜索框输入关键词本地过滤。
  4. 点某个模型的添加到模型列表
    • 仅当平台还没有已存凭据时才出现 Token 输入框(已配置时直接沿用 OPENROUTER_API_KEY,弹框中有提示),
    • 需要的话勾选设为新会话的默认模型
    • 确定——配置写入完成,弹框会显示该去哪里选这个模型。

新增一个平台

  1. src/client/components/FreeModelsSection.tsx:在 PLATFORMS 追加 { id, labelKey }, 并在下方按 id 挂载面板组件。
  2. 复制 src/client/components/OpenRouterPanel.tsx 作为起点;ops 请求带上 platform: '<id>'
  3. src/host/ops.ts:扩展 runOp 的平台分发(按平台 API 实现拉取/过滤,映射到 RouteModelProfile,并在 model-config.ts 里补该平台的凭据引用与路由命名)。

结构

├── src/host/*.ts      # 宿主半边:/dsh-free-model/api 路由(按平台分发 op)、
│                      # OpenRouter 拉取过滤排序(10 次重试)、缓存存储、
│                      # 模型配置写入(settings + credentials 服务)
├── src/client/*.tsx   # 浏览器半边:settings.section 平台 tab 外壳、
│                      # 各平台面板(本地搜索、模型卡片)、添加到模型列表弹框
├── lib/index.js       # 宿主半边构建产物(tsdown,ESM),已提交
├── lib/client.js      # 浏览器半边构建产物(tsdown → __ModuleLoader__ 工厂),已提交
├── scripts/           # verify-client.mjs、test-ops.mts(离线单测)、smoke-openrouter.mts(真实冒烟)
├── tsdown.config.ts   # node 半边 + client bundle 包装
├── cordis.patch.yml   # 组合包 patch:按包名引用的插件行
└── package.json       # dsh.bundle + dsh.client(web) 清单 + peerDependencies

说明

  • OpenRouter 免费模型同样需要账号 Token(有每日限额),弹框里有提示。
  • 写入走的是官方通道:settings.update('llm-pi-ai', …) 会经过 llm-pi-ai 的 schema 校验(不合法的配置在写入处被拒绝),适配器实时重注册路由——添加模型 后无需重启宿主
  • 对已有 OpenRouter 路由的手工修改(自定义 apiKeyEnv、额外字段)会被保留: 添加模型只重写该路由的 models 数组(按 id 合并,同 id 覆盖)。
  • 插件从不直接改写 settings / credentials 文件——一切经宿主服务完成;插件自己写的 唯一文件是模型缓存(dsh-free-model.json)。