dsh-codex-subs-plugin
August 14, 2026 · View on GitHub
中文 | English
实验性的 DeepSeek Harness 主模型适配器:通过 ChatGPT OAuth 使用账号的 Codex 订阅能力,而不是 OpenAI Platform API Key。
Warning
OpenAI 官方只公开承诺 Codex 可以“Sign in with ChatGPT”访问订阅。这个项目跟随 OpenAI Codex 客户端和 OpenCode 的开源实现,依赖 auth.openai.com 设备码接口、ChatGPT-Account-Id 与 chatgpt.com/backend-api/codex 等非公开稳定合约。服务端变化可能随时导致不兼容。订阅也不代表无限额度。
完整安装、登录、默认模型、代理、Headless 与 Web UI 操作见 USAGE 使用手册。
实现原理、上游源码证据与风险分析见 OpenCode 如何使用 Codex 订阅。
工作方式
ChatGPT OAuth(PKCE / device code)
→ access + refresh token + account id
→ DSH GenerateOptions 转为 Responses 请求
→ 固定发送到 chatgpt.com/backend-api/codex/responses
→ Responses SSE 转为 DSH StreamChunk
→ 保存 encrypted reasoning / tool replay state
它不会读取或复制 Codex CLI、OpenCode 的凭据,也不会把订阅“转换”为 API Key。凭据默认独立保存在:
$DSH_CODEX_SUBS_AUTH_FILE
或 $DSH_HOME/codex-subs/auth.json
或 ~/.dsh/codex-subs/auth.json
写入采用临时文件、fsync、原子 rename 和 0600 权限;刷新提前 60 秒并合并并发请求。传输层不提供自定义 endpoint,OAuth Bearer 只能发往代码中固定的 Codex 后端。
快速开始
需要 Node.js ^22.19.0 或 >=24.0.0、pnpm 和已安装的 dsh CLI。
1. 安装
pnpm install
pnpm run check
dsh plugin --profile headless add .
本包的 bundle 是非侵入式的:它只注册 codex-subscription provider,不会覆盖 DSH 现有默认模型。下面的命令可选,只能确认 Cordis 组合层已经插入 llm-codex-subscription:
dsh --profile headless --dump-config
--dump-config 不会加载 $DSH_HOME/settings.yaml 的运行时模型选择,因此不能证明请求会走本插件。
2. 登录
dsh plugin --profile headless exec dsh-codex-subs login
无桌面浏览器时使用有时限的设备码流程:
Device code 登录目前是 beta 功能:个人账户需先在 ChatGPT Settings → Security 启用,受管 workspace 则需管理员在 workspace permissions 中启用。详见 OpenAI authentication。
dsh plugin --profile headless exec dsh-codex-subs login --headless
3. 显式选择默认模型
编辑 $DSH_HOME/settings.yaml;未设置 DSH_HOME 时默认是 ~/.dsh/settings.yaml:
agent-default-model:
provider: codex-subscription
model: gpt-5.5
reasoningEffort: medium
默认 catalog 只是当前兼容快照;未列出的 model id 仍会原样发送,实际模型权限以服务端为准。
4. 检查本地状态
dsh plugin --profile headless exec dsh-codex-subs status
dsh plugin --profile headless exec dsh-codex-subs doctor
status 读取本地凭据元数据。doctor 不刷新 token、不发网络请求,只报告 auth 是否存在/到期、account id 是否存在、profile 安装状态、插件/provider、settings.yaml 中声明的默认 provider/model、代理变量是否存在、Node 环境代理开关和固定 endpoint;它不会输出 token、account id、代理 URL 或代理变量值。两者都不能验证远端 entitlement,也不能证明 DSH 已在真实运行时选中该 route。
5. 完成最小请求闭环
dsh --profile headless "只回复:codex-subscription-ok"
这是当前真正的运行时验证:新的 headless agent 会读取有效默认模型并通过所选 adapter 发出请求。成功响应同时验证运行时选路、OAuth、网络和服务端权限;它会消耗订阅用量。
不用本插件时可删除它自己的本地凭据:
dsh plugin --profile headless exec dsh-codex-subs logout
logout 不会远程 revoke token,也不会退出 ChatGPT、Codex CLI 或 OpenCode。
代理环境
OAuth、refresh、设备码和 Responses 请求共用隔离的 proxy-aware transport。它读取 HTTP_PROXY、HTTPS_PROXY、NO_PROXY 及其小写形式;同名大小写变量同时存在时,小写优先。示例:
export HTTPS_PROXY=http://proxy.example:8080
export HTTP_PROXY=http://proxy.example:8080
export NO_PROXY=localhost,127.0.0.1
ALL_PROXY既不被当前 transport 使用,也不计入doctor的 proxy presence;请按协议设置HTTPS_PROXY/HTTP_PROXY。- 未单独设置
HTTPS_PROXY时,Undici 会把HTTP_PROXY作为 HTTPS 请求的回退代理;明确设置两者更易诊断。 - 浏览器授权页由外部浏览器打开,使用浏览器/操作系统的网络路径;CLI 的 token 与模型请求使用本插件 transport,两者出口可能不同。
- Node 24 提供
NODE_USE_ENV_PROXY=1/--use-env-proxy作为全局 HTTP(S) 客户端能力。这只是诊断背景;本插件在支持的 Node 22/24 版本上都使用自己的统一 transport,不依赖该开关。 - transport 禁止自动跟随 redirect,并将网络错误脱敏。即使代理 URL 包含凭据,也不要把它或完整环境变量贴进日志、issue 或聊天。
unsupported_country_region_territory 排查
这类错误来自服务端;本插件会保留稳定错误码 UNSUPPORTED_COUNTRY_REGION_TERRITORY,但不能覆盖区域、账号或 workspace 策略:
- 先运行
status和doctor,确认 auth、默认 provider/model 与代理变量状态;它们不会测试远端。 - 对照 OpenAI 的受支持国家和地区。该页面描述 API 服务;私有 ChatGPT Codex 后端的最终资格仍由服务端判断。
- 让网络或企业管理员确认 CLI 进程的公网出口国家/地区。不要假设浏览器登录成功就代表 CLI 请求使用同一出口。
- 检查冲突或陈旧的大小写代理变量:本实现小写优先;确认
NO_PROXY没有意外绕过auth.openai.com或chatgpt.com;只设置ALL_PROXY对本 transport 无效。 - 在合规网络路径一致后重试最小请求;若失败阶段是 OAuth/device/refresh 或凭据已过期,再重新登录。若仍失败,保留错误阶段、HTTP 状态和 request id,删除 token、完整请求头与代理 URL 后联系 OpenAI 支持或 workspace 管理员。
不要通过伪造 client id/endpoint、复制他人凭据或规避区域限制来绕过服务端控制。
插件配置
在 profile 的 cordis.patch.yml 中覆盖 bundle 插入的行:
- id: llm-codex-subscription
config:
provider: codex-subscription
displayName: OpenAI Codex Subscription
reasoningEffort: medium
textVerbosity: low
streamIdleTimeoutMs: 300000
可选字段还有绝对路径 authFile 和 advisory models 列表。没有 baseURL 或 endpoint 配置,这是令牌边界的一部分。
已实现
- 浏览器 PKCE + state + 仅
127.0.0.1回调,5 分钟超时并保证清理。 - Headless device flow,15 分钟总超时。
- refresh token 旋转的原子持久化、提前刷新和 single-flight。
- OAuth、refresh、device 与 Responses 共用脱敏的环境代理 transport。
doctor安全报告本地 auth、安装、默认模型与代理 presence,不发网络请求。- 首次 401 后强制刷新并安全重放一次,绝不循环。
- Responses 的 text、reasoning summary、function call、usage、错误与 incomplete 映射。
store:false下 encrypted reasoning 和工具调用的无状态 replay。- DSH
usage → finish顺序、abort 与 stream idle timeout 契约。
如果只需要把 Codex 当作子代理,优先使用 DeepSeek Harness 自带的 @deepseek-ai/dsh-subagent-codex:它调用官方 codex app-server 并使用 Codex 原生认证。本项目适用于需要把 Codex 订阅接到 DSH 主 LLM route 的场景。
开发验证
pnpm run typecheck
pnpm run test
pnpm run build
pnpm pack --dry-run
测试全部使用 mock OAuth / Responses 数据,不会读取真实凭据,也不会访问 OpenAI。