dsh-plugin-subscriptions [](https://awesome-dsh-plugin.com)
September 5, 2026 · View on GitHub
English | 中文
把你的 ChatGPT(Codex)、Claude、Grok(X Premium) 订阅当作 DeepSeek Harness 的 LLM provider 使用 —— 不需要 API key。Codex 和 Grok 通过 dsh web 界面 OAuth 登录(设置 → 订阅);Claude 在存在 Claude Code 会话时直接导入凭据(macOS Keychain 或 ~/.claude/.credentials.json),否则回退到同样的浏览器 OAuth 流程,因此不要求安装 Claude Code CLI。Token 保存在 ~/.dsh/plugins/subscriptions/auth.json(权限 0600),过期自动刷新。
演示
设置 → 订阅:每个 provider 的登录/退出,无需 API key。Claude 有 Claude Code 会话时导入凭据,否则和 Codex、Grok 一样走 OAuth(以下设置截图使用演示账号与目录数据):

模型显示、默认推理档和上下文已合并到 编辑模型列表,统一保存或取消:

按 provider 配置图片生成、视频生成和 X 搜索,工具开关仅影响保存后新建的会话:

已登录的 provider 会带着实时模型目录进入会话模型选择器:

声明了推理等级的模型会在同一菜单里多出推理等级选择 —— Codex 系列模型、Grok 4.6 / 4.5,以及 Copilot 的推理模型(档位和默认值来自各 provider 的实时目录,不是硬编码列表;Copilot 的 capabilities.supports.reasoning_effort 数组会按协议映射为 chat completions 的 reasoning_effort 或 Responses 的 reasoning.effort)。同时声明两个 Copilot 端点的模型(gpt-5.4、gpt-5-mini)默认走 chat completions,但请求同时携带函数工具和推理等级时会自动改走 /responses —— Copilot 在 chat 线路上拒绝这种组合:

目录声明了 fast tier(即 codex CLI 的 fast 模式)的 Codex 模型,会在输入框工具行(模型选择器旁)多出一个速度开关 —— 标准 / 快速(service_tier: priority),按会话生效。/fast 斜杠命令提供同样的弹窗选择;当前模型不支持快速档时会提示原因。

image_generate 工具生成的图片直接内联显示在对话里:

provider 参数可选择生图后端——同一条提示词分别走 GPT(gpt-image-2,上)和 Grok(grok-imagine-image-2.0,下):

video_generate 工具生成的视频直接内联播放:

Provider 一览
| 路由 | 订阅 | 模型 |
|---|---|---|
codex | ChatGPT Plus/Pro | 从 chatgpt.com/backend-api/codex/models 实时获取 |
claude | Claude Pro/Max | 订阅内所有可用模型(Opus、Sonnet、Haiku、Fable —— 静态目录,随插件更新) |
grok | X Premium (xAI) | 从 api.x.ai/v1/models 实时获取(仅对话模型);推理等级来自 Grok CLI 目录(cli-chat-proxy.grok.com/v1/models) |
copilot | GitHub Copilot | 从 api.githubcopilot.com/models 实时获取(两种 wire 的对话模型,含按模型的视觉标记与推理等级);登录使用 OAuth 设备码流程(在 github.com/login/device 输入页面显示的验证码) |
只有已登录的 provider 才会出现在会话模型选择器里;登录/退出后列表自动刷新。支持视觉的模型会声明 ['text', 'image'] 输入模态,图片内容会被翻译成各 provider 的 wire 格式。
已登录的卡片还会显示订阅用量——按限额窗口(5 小时会话窗、每周窗,以及计划包含的按模型每周窗)展示已用百分比、进度条和重置时间,并带刷新按钮。Codex 用量来自 chatgpt.com/backend-api/wham/usage(同时报告计划类型),Claude 用量来自 api.anthropic.com/api/oauth/usage,Grok 用量来自 Grok Build CLI 代理的 cli-chat-proxy.grok.com/v1/billing(即 CLI /usage 面板的数据源,报告共享每周额度和订阅档位)。Copilot 没有用量接口,其卡片不显示用量区块。
随 provider 启用自动注册的工具:
x_search(Grok)—— xAI 托管的 X 搜索,返回{ answer, citations }。image_generate(ChatGPT 或 Grok)—— 经 Codex 后端调用gpt-image-2,或经api.x.ai/v1/images/generations调用grok-imagine-image-2.0。provider参数指定首选提供方(gpt为默认值,可选grok);首选方未登录时自动回退到另一方。图片保存到~/.dsh/plugins/subscriptions/images/并返回路径。Grok 路径上size/quality参数会映射为 Grok 的aspect_ratio/quality。video_generate(Grok)—— 经api.x.ai/v1/videos调用grok-imagine-video-1.5(异步提交 + 轮询);MP4 保存到~/.dsh/plugins/subscriptions/videos/并返回路径,视频直接在对话里内联播放。支持时长(1–15 秒)、宽高比、分辨率,以及通过image_url做图生视频。
安装
刷新模型列表
在 设置 → 订阅 → 对应 provider → 编辑模型列表 中点击 刷新,可绕过五分钟目录缓存,并通知会话模型选择器重新读取。这与刷新订阅用量是两个独立操作。如果显式配置了非空的 models.<provider>,仍使用指定列表,不进行在线发现。
Codex 的目录可见性受请求中的 client_version 影响。默认自动读取 npm 官方 @openai/codex 包公开元数据中的稳定版本,不安装 CLI,也不向 npm 发送订阅登录凭据。查询成功后在内存缓存六小时;失败后五分钟再试,保留上次成功版本,首次失败则回退到已验证的 0.153.4。查询最多等待 1.5 秒,多账号共用查询,忽略预发布版和低于当前已知版本的结果。手动刷新模型列表也会重新检查版本。显式配置 codexClientVersion: '0.153.4' 时优先使用该值,并关闭自动查询;更改配置后需重启 DSH。模型仍以账号实际权限为准,详见验证记录。
安装命令
本机已有 dsh CLI 时,从 npm 安装(预构建产物,无需构建授权):
dsh plugin --profile web add dsh-plugin-subscriptions
也可以从 GitHub 安装源码:
dsh plugin --profile web add github:V1ki/dsh-plugin-subscriptions
首次安装 pnpm 会要求允许该包的构建脚本(git 安装拉取的是源码而非构建产物);把打印出的包名加进 profile 的 pnpm-workspace.yaml:
allowBuilds:
dsh-plugin-subscriptions: true
然后重新执行 add。该授权会在安装时执行包的代码,只授给你信任的来源。
本地检出安装:
git clone https://github.com/V1ki/dsh-plugin-subscriptions.git
cd dsh-plugin-subscriptions && pnpm install && pnpm build
dsh plugin --profile web add ./dsh-plugin-subscriptions
不装进 profile 的 headless 用法(先在 web 界面登录过 —— token 文件是共享的):
cp overlay.example.yml overlay.yml # 然后把 name: 改成本检出的 lib/index.js 绝对路径
dsh --profile headless --patch <检出目录>/overlay.yml "你的任务"
更新
npm 安装的:
dsh plugin --profile web update --latest dsh-plugin-subscriptions
GitHub 安装的:重新执行一遍 add github:V1ki/dsh-plugin-subscriptions —— 会重新拉取源码并构建。link 的本地检出只需在检出目录里 git pull && pnpm build。
无论哪种方式,更新后都要重启 dsh web 才会加载新版本。
使用
dsh web,打开打印的 URL。- 设置 → 订阅:点对应 provider 的「连接」。若先运行过
claude并登录,Claude 会即时导入凭据;没有凭据时,Claude 也和其他 provider 一样在浏览器里授权。Codex 和 Grok 在打开的标签页里授权;Copilot 会显示 GitHub 设备码,需在github.com/login/device输入;无浏览器环境下可展开手动兜底,粘贴回调 URL 或授权码。 - 在任意会话里打开模型选择器(
/model),选择 ChatGPT (Codex) / Claude (Subscription) / Grok (Subscription) / GitHub Copilot 下的模型。
未登录时:该 provider 不出现在选择器里;直接请求会报 MISSING_CREDENTIAL 并提示去设置页登录,不影响其他功能。
多账号
每个 provider 可以登录多个账号:连上第一个之后,卡片会出现「添加账号」按钮(Claude 拆分为「浏览器授权」和「导入 Claude Code」两种)。账号按身份(邮箱/用户名)归档——重复登录同一账号是覆盖更新,不同账号才是新增。浏览器授权以浏览器当前登录的账号为准,要添加不同账号请先在浏览器切换账号,或用无痕窗口走手动授权码。★ 默认账号服务直连路由;池路由会使用所有账号。从 Claude Code 导入的 Claude 账号会与 CLI 的凭据存储保持同步;OAuth 添加的 Claude 账号独立刷新,多个账号不会互相覆盖 Keychain。
编辑模型列表、上下文与工具
在 设置 → 订阅 → 对应 provider → 编辑模型列表 中搜索并勾选要显示的模型,再点击 保存更改。默认自动显示全部模型;手动勾选、全选或清空后会保存明确的显示列表,以后发现的新模型不会自动加入。重新勾选「自动显示全部模型」即可恢复。隐藏仅影响模型选择器和默认推理档列表,已有会话仍可使用隐藏模型;编辑器始终保留完整目录,可随时恢复显示。刷新目录不会覆盖选择,取消会丢弃尚未保存的编辑。
Codex 模型还可填写上下文 token 数,留空跟随服务商。插件读取每个账号的 context_window 与 max_context_window,实际使用 min(配置值, 账号最大值);未返回最大值时,保守地以上下文默认值为上限。账号池按实际成员分别解析并取最小窗口。这只调整 DSH 的本地上下文预算与压缩时机,不向 API 发送扩大容量的参数。更长的上下文可能增加响应延迟。
同一区块可开关 Codex 的图片生成,以及 Grok 的图片生成、视频生成和 X 搜索。工具策略只影响保存后新建的会话;已有会话及其重启后的恢复保留创建时的策略。图片生成是共享工具,只有 Codex 与 Grok 均关闭或未配置时才完全隐藏;调用时也不会回退到该会话已禁用的 provider。Claude 和 Copilot 当前没有本插件提供的独立工具开关。
设置和工具策略历史独立存于 ~/.dsh/plugins/subscriptions/provider-settings.json(权限 0600),不受五分钟模型发现缓存过期影响。原有非空 models.<provider> 配置仍决定基础目录;界面显示选择在该目录上生效。
编辑模型的默认推理档
默认推理档已合并进 编辑模型列表:每个支持推理档的模型在同一处配置显示、推理档和上下文,统一点击 保存更改 后生效。隐藏模型也可以设置推理档;没有推理档的模型不显示下拉框。选择「跟随服务商」清除覆盖,取消会恢复尚未保存的编辑。选项取自模型实时能力目录,账号池使用成员共同支持的档位;自定义池别名不提供无效的推理档覆盖。
原有推理档配置继续从 ~/.dsh/plugins/subscriptions/model-defaults.json(权限 0600)读取并保存。若保存中途失败,界面会保留未完成的草稿,明确提示已经保存的推理档,并可重试完成。
配置
- id: llm-subscriptions
name: dsh-plugin-subscriptions
config:
providers: [codex, claude] # 子集;默认四个全启用
streamIdleTimeoutMs: 300000
rateLimit:
wait: true # 等待限流窗口重开(默认开启)
maxWaitMs: 21600000 # 单次等待上限;6 小时,足够覆盖 5 小时会话窗口
models: # 覆盖实时发现/内置目录
codex:
- { id: gpt-5.6-sol, name: GPT-5.6 Sol, contextWindow: 272000, inputModalities: [text, image] }
copilot: # 手工条目会关闭 Copilot 目录发现
- { id: gpt-5.6-sol, wire: responses } # 仅 copilot:强制指定上游协议
wire(仅 copilot 条目)把模型固定到 chat-completions 或 responses。不加该字段手工条目照常
工作——它存在的原因是:实时目录不认识的手工模型否则会默认走 /chat/completions,而
responses-only 系列(gpt-5.5/5.6 等)会拒绝该端点。固定为 chat-completions 也会退出上文所述
tools+effort 的自动改道。
模型池
同一订阅下登录了两个及以上账号时,选择器显示该 provider 所有账号目录的并集(按模型 id 去重)。照常在 Claude 组选 claude-sonnet-5、在 ChatGPT 组选 gpt-5.4——不会多出一个池分组,也不会换 model id。
- 共有模型:至少两个账号的目录都列出的模型,在这些账号之间 failover(粘性、可按配额调度)。每个账号各自做一次目录发现,Plus 不会被拿去打 Pro 才有的模型。
- 单账号模型:只有一个账号目录里有的模型,请求就打到那个账号。即使它不是默认账号,选择器里也会出现。
- 显式账号列表(
families):覆盖某个目录模型的自动成员(仅同一 provider;跨 provider 的成员会被忽略)。可钉account,省略则用默认账号。 - 档位额外项(
tiers,可选):额外的选择器条目,failover 可以跨模型;出现在首个成员所在的 provider 分组。不会自动创建。
成员选择按会话粘性(prompt 缓存不失效),两种策略:priority(按顺序取第一个健康成员)和 quota_aware(默认——按"必需消耗速率 = 剩余配额 / 距重置时间"给成员打分,快重置且剩余多的窗口优先被用掉而不是浪费;粘性成员除非被挑战者以 switchMargin 倍分差击败否则不换)。任一用量窗口超过 95% 的成员会被硬门槛挡下;首个流式 chunk 之前的失败会记冷却并切换下一家(provider 给了 retry-after 就用它)——配额与认证类失败按整个账号冷却(配额是账号级的;Claude 的分模型窗口则只冷却出错成员),瞬时服务端失败只冷却出错成员。Copilot 没有用量接口,恒为 0 分,自然充当最后的保底。
- id: llm-subscriptions
name: dsh-plugin-subscriptions
config:
pool:
enabled: true # 默认开;需同一 provider ≥2 个账号
strategy: quota_aware # 或 priority
switchMargin: 2 # quota_aware 的滞后切换倍率
autoAccounts: true # 把该 provider 各账号自动池到每个目录模型
families: # 某个目录模型的显式账号列表(同一 provider)
claude-sonnet-5:
- { provider: claude, model: claude-sonnet-5 } # 默认账号
- { provider: claude, account: bob@example.com, model: claude-sonnet-5 }
tiers: # 可选的额外选择器条目
smart:
- { provider: claude, model: claude-sonnet-5 }
- { provider: codex, model: gpt-5.6-sol }
- { provider: grok, model: grok-4.6 }
等待限流窗口
订阅套餐天然是按限流窗口计费的 —— 5 小时会话窗口、周窗口,部分套餐还有按模型的周窗口 —— 所以 429 并不是终点:窗口会在 provider 自己告知的时刻重开。每条路由从自己的 429 里读出这个时刻,把它变成该账号在模型池里的冷却时长(见上文「模型池」),而不是固定猜测的 5 分钟。
只有能指明「是哪个窗口拒绝了这次请求」的信号才会被读取:Anthropic 的 anthropic-ratelimit-unified-reset、Codex 在 usage_limit_reached 上给出的秒数、xAI 在错误体里给出的延迟,或通用的 retry-after。各分桶的滚动快照(anthropic-ratelimit-{requests,tokens,…}-reset、x-codex-*-reset-after-seconds、x-ratelimit-reset-*)每个响应上都有,说不出是哪个桶拒绝的 —— 其中最早的那个往往正是还有余量的桶 —— 所以只带这些的 429 会通过插件的告警回调打印出相关 header 与响应体开头,而不是照着猜测把本轮(或池冷却)挂起。
读取只发生在 429 上。其他失败仍走各自的短本地退避:同样这些 header 也会出现在瞬时 500 上,在那里照办等于为一次一秒就恢复的过载把本轮挂满整个窗口。
有模型池时,真正在做等待这件事的其实是账号 failover:某个账号 429 了就按它自己披露的重开时刻冷却下来,请求立刻切到同 provider 的下一个账号 —— 不等待,也不丢本轮对话。只有整个池(所有账号)都在冷却时,adapter 才会上报一个 RATE_LIMIT,携带池里最早的重开时刻作为应等待的时长。单账号(没配池,或该 provider 只登了一个号)时,同样的披露时刻会被直接上报。
真正执行这段等待的是 @deepseek-ai/dsh-llm-retry,四条路由的重试策略都是为它写的:把它加进编排,否则不会有任何等待,关闭的窗口仍旧直接让本轮失败(如果池里还有别的健康账号,会先 failover 过去)。Copilot 当前使用通用的 retry-after 信号;GitHub 未识别的限流 header 会通过插件告警回调暴露出来,后续再添加 provider 专用解析器。
- name: '@deepseek-ai/dsh-llm-retry'
- name: dsh-plugin-subscriptions
config:
rateLimit:
wait: true # 默认;false 恢复此前秒级的行为
maxWaitMs: 21600000 # 6 小时 —— 留有余量地覆盖 5 小时会话窗口
重开时刻超过 maxWaitMs(比如几天后才重置的周窗口,或者整个池的冷却时间超过这个上限)会立即失败并带上重开时刻,而不是把会话挂上好几天。wait: false 则只保留本地退避。
四条路由共用 Claude Code 自己的重试形状:首次尝试之后重试 10 次,从 1 秒开始退避,带 20% 抖动,上限 60 秒。这些都是面向消费者的订阅端点,过载时按突发丢流量,而 dsh-llm 默认值(5 次重试,500 毫秒到 10 秒)约 15 秒就放弃,对这种场景偏短。没有给出重开时刻的 429 现在会本地重试约 17 分钟才让本轮失败 —— wait: false 下约 5 分钟,那时 60 秒上限才真正生效。
一个需要知道的取舍:延迟上限与这份本地退避共用,调高 maxWaitMs 同时也抬高了无关瞬时失败(TRANSPORT、SERVER、TIMEOUT)在有限重试预算耗尽前的退避时长 —— 第 10 次重试最长会从 60 秒上限变成 512 秒。
代理
DSH v0.1.3-alpha.1 新增宿主统一代理支持。建议在启动环境或 $DSH_HOME/.env 中配置 HTTP_PROXY / HTTPS_PROXY(或 ALL_PROXY)以及 NO_PROXY,重启 DSH,然后关闭插件代理。参见 DSH 网络代理指南。环境变量中的代理凭据会被子命令继承,与插件私有配置文件的凭据边界不同;不会自动删除或迁移已有设置。
插件代理作为可选覆盖设置保留,用于仍受支持的旧版 DSH 以及仅订阅请求使用独立代理的场景。所有订阅相关请求 —— token 交换、模型 API 流式调用、用量查询、模型目录发现,以及 x_search / image_generate / video_generate 工具 —— 都可以使用。在 设置 → 订阅 → 代理 → 配置… 中设置:勾选启用,填写代理地址(http://127.0.0.1:7890)、可选用户名/密码,以及可选的逗号分隔绕过列表(如 127.0.0.1、localhost、*.example.com)。关闭或绕过插件代理后使用 DSH 的全局 fetch 路由,不一定直连;要求直连时还应配置宿主的 NO_PROXY。密码保存在 ~/.dsh/plugins/subscriptions/proxy.json(权限 0600),不会回传给浏览器;「测试」按钮会用当前配置探测一次端点,显示 HTTP 状态码与耗时。
保存后立即对后续请求生效,无需重启。OAuth 授权页在浏览器中打开,走浏览器/系统自身的代理设置,不受此配置影响;不支持 socks 代理。
相关插件
本插件只提供模型路由,审批策略由其他插件负责:
dsh-plugin-auto-review—— 面向 DSH 工具审批的 provider 原生自动审查。它在本插件注册的codex/grok路由(或其他 DSH LLM adapter 的兼容路由)之上,通过ctx.llm.stream()复现 Codex Guardian 与 Grok 提权审查逻辑,不接触账号与凭据。安装:dsh plugin --profile web add dsh-plugin-auto-review。
开发
pnpm install # devDependencies 用 link: 指向本地 deepseek-harness 检出 —— 先改成你的路径
pnpm build # tsc(lib/)+ tsdown(lib/client.js 浏览器 bundle)
pnpm test # 编译后跑 node --test 单测
prepare(git 安装时触发)执行 tsdown.prepare.config.ts:自包含打包两个面,所有 @deepseek-ai/* 依赖外部化 —— 运行时从 dsh 安装解析,保证不会引入第二份 cordis。
改了代码后 pnpm build 并重启 dsh web 生效。
目录结构
src/index.ts—— 插件入口:配置 schema、adapter 注册、登录态变更通告、RPC 接线src/auth/—— PKCE/JWT 工具、token 存储、OAuth 流程引擎(临时本地回调服务)、Claude Code 凭据读取器(Keychain/文件)、/subscriptions-authRPC 通道src/providers/—— 各 provider 的 OAuth 常量/换发/刷新 +LlmAdapter实现,多账号 token 管理(accounts.ts),模型池(pool.ts+pool-health.ts/pool-usage.ts/pool-family.ts),以及rate-limit.ts(限流重开时刻解析 + 重试策略)src/translate/—— dshMessage[]与 OpenAI Responses / Anthropic Messages 格式互转,SSE →StreamChunksrc/tools/——x_search、image_generate与video_generatesrc/client/—— 设置 → 订阅页面(浏览器面,中英文,跟随明暗主题)