# @jcy2387/dsh-codex-provider-plugin [English](README.md) | 中文 一个独立发布、可通过 `dsh plugin add` 安装的 OpenAI Codex Provider。它使用 ChatGPT OAuth 登录,通过 Harness 原生 LLM 服务注册 `openai-codex`,并在 Web 设置页提供浏览器登录和设备代码登录。 本包不修改 `deepseek-harness` 源码,也不把 Codex 当作 subagent。Codex 模型仍使用 Harness 的普通 Agent loop、工具、权限、session、流式输出和自动压缩链路。 > 此插件使用 pi-ai 的 `openai-codex` Provider 访问 ChatGPT Codex 后端,不是 OpenAI Platform API Key 集成。接口行为、模型权限和配额由 OpenAI 控制,可能变化。请仅用于符合账号与适用条款的场景。 ## 架构 一个 npm 包同时包含两张运行面: - **Host:** 注册 `openai-codex` LLM adapter,通过 Harness credential provider 保存 OAuth 状态、读取账号用量,并提供插件自有的 loopback-only Connection RPC。 - **Browser:** 通过 `dsh.client` manifest 加载原生设置页,只接收经过校验且不含敏感信息的认证与用量快照;Token 和账号 ID 都不会进入浏览器。 Harness 当前只提供扁平的 Settings section 列表,Models 页面也没有外部内容 Slot。因此插件保持为紧随**模型**之后的独立 **OpenAI Codex** 页面,不修改 Harness,也不做脆弱的 DOM 注入。 `cordis.patch.yml` 只插入一个由本包拥有的插件行。本包不导入或修改 `@deepseek-ai/dsh-api-remotes`,安装时不需要 Harness 增加静态 Remote 注册。 模型 ID、`contextWindow` 和 `maxTokens` 直接来自 pi-ai 的 Codex catalog。Harness 通过正常的 `ctx.llm.resolveModelInfo()` 路径读取这些字段,因此 session 上下文预算和自动压缩不需要 Provider 专属接线。 ## 从 npm 安装 ```sh dsh plugin --profile web add @jcy2387/dsh-codex-provider-plugin dsh web ``` ## 设置 OpenAI Codex > 本插件使用 ChatGPT OAuth 登录,不需要 `OPENAI_API_KEY`,也不是 OpenAI Platform API Key 集成。 设置页大致如下:

DeepSeek Harness 中的 OpenAI Codex 设置页

1. 执行 `dsh web` 启动 Web UI。 2. 打开**设置 → OpenAI Codex**,点击**连接 Codex**。 3. 选择**浏览器登录**,使用 ChatGPT 账号完成授权;如果 Host 是无头或远程环境,则选择**设备代码登录**。 4. 状态变为**已连接**后,页面会显示 OpenAI 当前返回的用量周期,并每 60 秒刷新一次。接口没有返回的周期不会显示,插件不会硬编码 5 小时限制。 5. 在正常的模型选择器中选择 `openai-codex` 下的模型。安装插件不会自动修改默认模型。 浏览器登录要求浏览器和 dsh Host 在同一台机器上运行。设备代码登录可能需要先在 ChatGPT 安全设置或工作区权限中启用。账号或工作区必须拥有 Codex 访问权限;模型可用性和配额由 OpenAI 控制。用量数据来自 OpenAI 的 ChatGPT 账号接口,可能随其服务变化。 ## 升级 插件按 dsh profile 独立安装。将 `web` profile 中的插件升级到最新已发布版本: ```sh dsh plugin --profile web update @jcy2387/dsh-codex-provider-plugin --latest ``` 也可以安装指定版本: ```sh VERSION="$(npm view @jcy2387/dsh-codex-provider-plugin version)" dsh plugin --profile web add "@jcy2387/dsh-codex-provider-plugin@$VERSION" --save-exact ``` 确认安装版本后重启 `dsh web`,并在浏览器中强制刷新,避免继续使用旧的客户端 bundle: ```sh dsh plugin --profile web list @jcy2387/dsh-codex-provider-plugin --depth 0 ``` 如果从 `deepseek-harness` 源码目录运行,请在这些命令前加上 `pnpm`。 ## 本地开发安装 ```sh pnpm install pnpm run check dsh plugin --profile web add link:/Users/baojie/Documents/Projects/github/dsh-codex-provider-plugin dsh web ``` 如果从 `deepseek-harness` 源码目录运行,将后两条命令加上 `pnpm` 前缀: ```sh pnpm dsh plugin --profile web add link:/Users/baojie/Documents/Projects/github/dsh-codex-provider-plugin pnpm dsh web ``` 启动后打开**设置 → OpenAI Codex**,选择浏览器登录或设备代码登录。安装只会新增 Provider,不会自动切换默认模型;请在正常的模型选择器中选择 `openai-codex` 下的模型。 ## 配置 所有字段均可省略: ```yaml - id: llm-openai-codex config: credentialRef: OPENAI_CODEX_OAUTH transport: auto streamIdleTimeoutMs: 300000 ipv6CallbackBridge: true proactiveRefresh: true proxyMode: auto ``` - `credentialRef`:Harness credential provider 中保存序列化 OAuth 状态的引用。 - `transport`:`sse`、`websocket`、`websocket-cached` 或 `auto`。 - `timeoutMs`:Provider 请求超时。 - `websocketConnectTimeoutMs`:WebSocket 建连超时。 - `streamIdleTimeoutMs`:等待下一段流数据的最大空闲时间。 - `retryPolicy`:Harness LLM 的标准重试配置。 - `ipv6CallbackBridge`:浏览器登录期间,临时把 `[::1]:1455` 桥接到 pi-ai 的 `127.0.0.1:1455` 监听器。默认启用;如果部署已经显式管理 `PI_OAUTH_CALLBACK_HOST`,可以关闭。仅关闭桥接时,IPv4 端口可用性检查仍然生效。 - `proactiveRefresh`:在 access token 过期前几分钟于后台刷新,过期后的第一个请求不必再等一次令牌往返。默认启用;关闭后退化为纯粹的惰性刷新(过期后的首次请求时刷新)。 - `proxyMode`:`auto`(默认)先读取 `HTTPS_PROXY` / `HTTP_PROXY` / `ALL_PROXY`,未配置时再读取 macOS 系统代理、Windows 当前用户代理、Linux GNOME GSettings 或 KDE `kioslaverc`;`environment` 只读取环境变量;`off` 不安装插件代理调度器。 ## 网络与代理 - **HTTP(S) 代理**:插件会自动把 OpenAI/ChatGPT Host 请求路由到环境代理或受支持的系统代理,OAuth、令牌刷新、用量查询以及 SSE/WebSocket 模型请求使用同一 dispatcher。代理地址及凭据不会通过 RPC 发送到浏览器。 - **Linux**:按“环境变量 → GNOME → KDE”的顺序识别;服务器、容器及其他桌面环境建议设置标准 `HTTP(S)_PROXY`。Linux TUN 与其他平台一样无需额外接线。 - **TUN 模式**:TUN 对 Node 是透明的,不需要额外代理配置;设置页因此显示“系统路由(直连或 TUN)”,不会根据网卡名称做容易误判的猜测。 - **请求范围**:自动代理只接管 `openai.com` 与 `chatgpt.com` 域名,Harness 的其他网络请求仍交给原有 dispatcher;如果 Host 已安装自定义 dispatcher,插件会保留并优先使用它。`localhost`、`127.0.0.1` 和 `[::1]` 始终绕过代理。 - **设置开关**:可在**设置 → OpenAI Codex**中选择**自动识别**、**仅使用环境变量代理**或**关闭显式代理**。Harness 会把选择持久化到 `$DSH_HOME/settings.yaml` 的 `openai-codex` 分节,并覆盖组合层的 `proxyMode` 默认值。保存后页面会明确提示重启 `dsh web`;插件不会在当前进程中热切换 dispatcher。 - **限制**:自动 dispatcher 支持 HTTP/HTTPS 代理,不执行 PAC,也不直接连接 SOCKS。此类代理请启用代理软件的 HTTP 端口并设置 `HTTPS_PROXY`,或使用 TUN。 代理配置在插件启动时读取;修改环境或系统代理后请重启 `dsh web`。 ## 令牌刷新 pi-ai 会在双重检查锁内轮换过期的 access token,插件把每次轮换后的凭据写回 Harness 凭据存储。在此之上还有两层行为: - **主动刷新**:连接状态下,Host 会在 access token 过期前 5 分钟于后台刷新。瞬时的网络失败会在 1 分钟后、然后每 5 分钟重试一次,且不改变登录状态。 - **失败可见**:如果 OpenAI 拒绝了 refresh token(例如 `invalid_grant`),设置页状态会翻转为**登录已失效**并给出重新连接入口,而不是让请求在后台静默失败。之后任何一次刷新成功(定时器或请求路径)都会自动恢复为**已连接**。刷新错误只保留在 Host 日志中,跨 RPC 的只有不含密钥的状态。 ## 认证排障 设置页会显示稳定的诊断码,但不会把 OAuth 响应正文或 Token 返回浏览器: | 诊断码 | 含义与下一步检查 | | --- | --- | | `CODEX_AUTH_ACCOUNT_ACCESS` | OpenAI 没有签发可用的 Codex 凭据。检查 MFA、登录时选择的 ChatGPT 工作区和工作区 Codex 权限。 | | `CODEX_AUTH_BROWSER_CALLBACK` | Host 没有收到有效授权码。确认浏览器和 Host 在同一台机器,登录过程中不要重启 dsh,并检查浏览器是否拦截 `localhost:1455`。 | | `CODEX_AUTH_BROWSER_CALLBACK_PORT` | Host 无法监听 `localhost:1455`。请停止其他 dsh/Codex 登录或占用该端口的应用后重试。 | | `CODEX_AUTH_BROWSER_CALLBACK_TIMEOUT` | 十分钟内没有收到回调。请重新发起登录且不要在过程中重启 dsh,或改用设备代码登录。 | | `CODEX_AUTH_DEVICE_CODE_DISABLED` | 在 ChatGPT 个人安全设置或工作区权限中启用设备代码登录。 | | `CODEX_AUTH_NETWORK` | 检查 Host 的代理、DNS、TLS 信任和防火墙能否访问 OpenAI 认证服务。 | | `CODEX_AUTH_TOKEN_EXCHANGE` | 授权已经返回,但凭据交换失败。重试并检查 Host 系统时间和代理。 | | `CODEX_AUTH_UNSUPPORTED_REGION` | 浏览器授权已完成,但 Host 网络出口位于 OpenAI 不支持的国家或地区。请让 Host 使用符合 OpenAI 服务范围和条款的网络,再发起一次全新登录。 | | `CODEX_AUTH_UNKNOWN` | 在同一台 Host 上测试官方 Codex 登录,用于区分账号/环境问题与插件兼容问题。 | 浏览器登录会重定向到 `http://localhost:1455/auth/callback`,因此只适合浏览器和 dsh Host 在同一台机器的场景。启动 pi-ai 前,插件会先确认 `127.0.0.1:1455` 可用;如果已被其他进程占用,会立即以 `CODEX_AUTH_BROWSER_CALLBACK_PORT` 失败。浏览器登录进行期间,本插件还会打开一个 IPv6-only 的 `[::1]:1455` 监听器,在 Host 内把原始回调路径和查询参数转发到 IPv4 上的 pi-ai,再把 pi-ai 响应返回浏览器,并在本次登录结束后关闭。这样不会再让浏览器发起第二次跳转,避免被代理、PAC 或 localhost 安全策略截断。它不会监听局域网地址;十分钟内没有回调的浏览器登录会自动结束,不再无限占用登录状态。完整的 provider 异常只保留在 Host 日志中,浏览器只接收上表中的诊断码。无头 Host 应在账号或工作区启用相应权限后使用设备代码登录。参见 [OpenAI Codex 认证文档](https://learn.chatgpt.com/docs/auth)。 ## 当前范围 插件包含 Provider、OAuth 生命周期、原生设置 UI、模型目录、压缩使用的上下文元数据和 Codex 用量展示。Host 使用刷新后的 OAuth 凭据请求 `https://chatgpt.com/backend-api/wham/usage`,校验响应后,只通过 loopback-only RPC 返回套餐、用量百分比、重置时间和可选的额度余额。UI 只渲染接口实际返回的周期,因此不会假设存在 5 小时限制。 ## 开发 ```sh pnpm install pnpm run typecheck pnpm test pnpm run build pnpm run publint ``` 构建产物: - `lib/index.js`:Host 插件。 - `lib/client.cjs`:loader-compatible browser 插件,CSS Modules 已内联。 - `lib/types/**`:Host 与 browser declaration files。 - `cordis.patch.yml`:由 `dsh.bundle` manifest 激活的 profile layer。