iJetLi/dsh-providers-hub

dsh-providers-hub

登录并管理 16 个 AI 编程服务商的账号,另含一个跨渠道轮换渠道:多账号池、凭据自动续期、服务商支持时的积分领取,以及本地 OpenAI 兼容网关。

Uncategorized

dsh-providers-hub

本包原名 `dsh-codearts-auth`(0.2.0-rc.11 起改名)。老用户的 DSH profile 里
还锁着旧名时,插件会加载失败并被自动禁用(宿主报 N entry did not activate,
界面里也就看不到它)—— 升级前先看
⚠️ 从旧包名 dsh-codearts-auth 升级。
使用声明:本项目仅供学习研究使用,请遵守各服务提供方的服务条款。

deepseek-harness 插件:统一管理多个 AI 编程服务的账号,并把它们的模型接进 DSH 的模型选择器。支持多账号池(同一服务登录多个账号,按可用性自动选号)与 凭据静默续期(到期前自动刷新,无需再次打开浏览器)。

  • 17 个 provider 路由,外加 1 个聚合路由(见下)
  • 登录、状态、续期、积分领取全部在 Jet Hub 设置页完成,不注册任何斜杠命令
  • 附带一个本机 OpenAI 兼容网关,供其它客户端复用已登录账号
📌 本 README 只写「怎么用」。 各 provider 的协议、端点、登录流程、请求头
构造、实测数据与事故史等实现细节,统一记录在不入库的内部文档
docs/implementation-notes.md 中。需要改动实现或排查协议问题时读它。
⚠️ accio 的章节该文件里还没有(implementation-notes.md 目前零处 accio)——
读它时不要以为 accio 没有实现笔记。accio 的实测结论与坑点当前登记在
docs/agent-notes/providers-accio.md(含三条与参考实现相反的结论、两个真缺陷、
区域选择与接线陷阱),补写 implementation-notes.md 的 accio 章节是独立任务。

目录

  • 安装
  • 用法
  • 支持的渠道
  • 聚合路由
  • 本机 OpenAI 网关
  • 用量徽标与 Token 用量
  • 配置项
  • 开发

安装

该包尚未发布到 npm registry。提供两种安装方式。

⚠️ 从旧包名 dsh-codearts-auth 升级

本包在 0.2.0-rc.11 把包名从 dsh-codearts-auth 改成了 dsh-providers-hub。 仓库里改完了不代表你的机器上改完了 —— DSH 是在 profile 里按包名字符串 寻址 bundle 的,而老 profile 两处都还写着旧名:

// ~/.dsh/profiles/<name>/package.json
{
  "dependencies": { "dsh-codearts-auth": "link:…" },   // ← 旧键
  "dsh": { "profile": { "bundles": [ …, "dsh-codearts-auth" ] } }  // ← 旧项
}

两处必须一起改,缺一处就是静默失效 —— 而且「两处都不改」同样会坏, 只是坏的位置不同:

profile 里的状态 · 后果 两处都是旧名(老 profile 的现状) · bundle 目录解析得到(node_modules/dsh-codearts-auth 这个旧名别名还在),但包里 patch 的加载行写的是新包名,而宿主把加载行的解析基准设成 profile 目录 ⇒ 新名在那里解析不到(本机实测 MODULE_NOT_FOUND)⇒ 该加载行 import 失败 ⇒ 宿主报 N entry did not activate,桌面端落进恢复模式并把插件自动禁用(Jet Hub 界面自然也不出现,即 issue IKLUME 的症状) 只改 `dependencies` · dsh.profile.bundles[] 里的旧名在 profile 里解析不到 ⇒ resolveBundleDir() 抛错 ⇒ 该 bundle 进 skippedBundles ⇒ 整个插件(连宿主侧)都不加载,只在 stderr 留一行:无异常、无 UI 提示 只改 `dsh.profile.bundles` · 与上一格同因:node_modules/ 里只有旧名,bundles[] 里的新名解析不到 ⇒ 同样进 skippedBundles

实测(本机 ~/.dsh/profiles/web):require.resolve('dsh-codearts-auth/package.json')
成功解析到仓库根,而 require.resolve('dsh-providers-hub/package.json') 报
MODULE_NOT_FOUND。宿主把加载行的解析基准设成 profile 目录
(dsh-app-boot 对 patch 行调 prepareProfilePatches(…, pathToFileURL(dirname(absoluteConfigPath))…),
同一个值也是 boot() 里 ctx.baseUrl 的来源),所以「旧名能解析」与「新名解析不到」
会同时成立 —— 这正是第一格的判断依据是按名字解析、而不是「目录在不在」的原因。
⚠️ 第一格的落点不在客户端:宿主不会替用户把这种行摘掉 —— preflight()
只在「兼容性冲突」时 deny 一行,其余失败保留 cordis Loader 自己的诊断
(源码注释:*every other failure keeps the Loader's own diagnosis*),于是该行走进
Loader 并在宿主这一侧导入失败。所以排障的第一现场是宿主日志里的
N entry did not activate 与「插件已被禁用」,不是「宿主一切照常、只是客户端
entry 没建立」——后者会让排查方向整个偏到前端产物上去。

推荐做法是不要手改,直接用 dsh plugin --profile 的 remove / add 各走一遍,让工具自己写这两处:

dsh plugin --profile <name> remove dsh-codearts-auth
dsh plugin --profile <name> add "https://gitee.com/iJetLi/deepseek-harness-codearts.git"

⚠️ ` 要**逐个 profile 走一遍**:本机 ~/.dsh/profiles/ 下的 desktop / headless / tui / web 四个 profile 的 package.json **都**还锁着旧名,且 dsh.profile.bundles 里也都有它。只有既无依赖项也无 node_modules 的 profile (如 default / rescue`)可以跳过。

⚠️ 老版本可能残留 node_modules/dsh-codearts-auth 与 pnpm-lock.yaml 里的同名 依赖项;add 之后确认 profile 里不再有旧名的依赖键。

方式一:从 git 仓库安装(推荐)

add 以 git 仓库方式安装(pnpm 内部走 git+https: 协议),会运行本包的 prepare 脚本自动构建 lib/,无需手动 pnpm build。

⚠️ prepare 不依赖任何包管理器(它直接内联 tsc / node):pnpm 在 clone 目录里跑 prepare 时,pnpm 10 / 11 不会把 npm 注入 PATH(只有 pnpm ≥ 12 会) ⇒ 若 prepare 里写 npm run …,那两代上安装会直接失败。

⚠️ pnpm 10 起会拦截依赖的构建脚本,必须先在 profile 的 pnpm-workspace.yaml (路径形如 ~/.dsh/profiles//pnpm-workspace.yaml)里放行;而放行键的写法 在 pnpm 10 与 pnpm 11 之间互不兼容,写错就装不上。

1. 先跑一次安装(这一次必然失败,为的是让 pnpm 打印它期望的键):

dsh plugin --profile <name> add "https://gitee.com/iJetLi/deepseek-harness-codearts.git"

2. 按第 1 步的报错选一种写法,写进 profile 的 `pnpm-workspace.yaml`。

报 `ERR_PNPM_INVALID_VERSION_UNION` 的(pnpm 10.x)—— 只认纯包名键:

allowBuilds:
  dsh-providers-hub: true

报 `ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED` 的(pnpm 11.x)—— git 托管包 不认纯包名键,必须用第 1 步 pnpm 打印的完整键(含 `#`):

allowBuilds:
  dsh-providers-hub@git+https://gitee.com/iJetLi/deepseek-harness-codearts.git#<第 1 步打印的 commit>: true

两代通用(省事,但放宽了权限):

dangerouslyAllowAllBuilds: true

它会放行该 profile 里所有依赖的构建脚本(不止本插件)。

3. 重跑第 1 步的命令:这次会拉取、构建并安装成功。之后每次升级重新 add 即可。

⚠️ 不要写 dsh-providers-hub@git+https://gitee.com/…(不带 #)—— 这个"看起来最自然"的键在两代 pnpm 上都不工作。

⚠️ pnpm 11.x 的精确键里带 commit,因此升级(重新 `add` 拉到新 commit)后该键 失效,按新报错里的键替换即可;用 dangerouslyAllowAllBuilds 则不必改。

方式二:从源码目录安装(本地开发)

先在本仓库中构建 lib/,再安装为 pnpm link: 依赖:

pnpm build:all
dsh plugin --profile <name> install <path-to-this-repo>
dsh plugin install 以 link: 方式安装,pnpm 不会为 link: 依赖运行
prepare 脚本,因此必须先手动执行 pnpm build:all 生成 lib/。
注意必须用 build:all 而非 build:后者只编译宿主侧,不产出
lib/client/jet-hub.js。

每次修改 src/ 或 plugin-src/ 后都需要重新执行 pnpm build:all —— dsh 启动时 不会自动重建。

通用说明

该包声明了 dsh.bundle 补丁(cordis.patch.yml),因此 profile 的 layer 栈会 自动拾取 codearts-auth 行。插件注入由 dsh base 提供的 credentials、 commands 和 llm 服务。

用法

登录入口:Jet Hub 设置页的对应 provider 面板。

⚠️ 不注册任何斜杠命令 —— 登录、状态查看、续期与积分领取统一在 Jet Hub 完成。

基本流程:

  1. 打开 Jet Hub(点主导航里的 Jet Hub 一行;也可从「设置 → 插件 → Jet Hub」

进入 —— 两条路径渲染的是同一个页面);

  1. 点「+ 新建账号」→ 浏览器打开授权页 → 完成登录;
  2. 需要多个账号时重复第 2 步(账号池会自动选号);
  3. 回到 dsh 的模型选择器,选中该渠道的模型即可开始对话。

页头的「侧栏」开关可以随时把那一行从主导航里收起来(设置页入口照旧);偏好 存在宿主侧而不是浏览器存储,重启后保持 —— 理由见 docs/agent-notes/client-ui.md。

「+ 新建账号」是两步式的:先返回 loginUrl 由前端弹窗打开,后台再轮询换取 令牌 —— 这样不会阻塞浏览器手势窗口,弹窗不会被拦截。

账号卡片支持:测试 / 重测 / 重置 / 停用 / 代理 / 指纹 / 删除,以及拖拽排序 (顺序即选号优先级)。停用只影响自动选号,不影响凭据续期与积分领取。

⚠️ 「代理」按钮目前只对 opencode 与 gemini 渲染(两者语义不同,见 「出不去墙外服务」一节);其余渠道的账号卡片上没有这个按钮。

支持的渠道

17 个 provider 路由,互不覆盖,可同时使用。