pi-codex-dual
v0.2.3
Published
Two independently authorized ChatGPT/Codex accounts for Pi, with bounded failover and optional round-robin routing.
Readme
Pi Codex 双账号插件
让两个你自己的 ChatGPT Plus/Pro 账号分别保持 Codex OAuth 授权,在 Pi 中按请求切换。
不是合并订阅额度,也不是把 ChatGPT 网页版额度变成 OpenAI API 额度。 请求走 Pi 已支持的 Codex 订阅通道,每个账号仍受自己的额度、模型权限和服务条款约束。
安装 npm 包
发布到 npm 后,可在系统终端运行:
pi install npm:[email protected]然后在 Pi 执行 /reload 或重启。若已通过本地目录加载本插件,请先取消旧的本地安装登记,避免重复加载;这不会删除账号授权。本机正在测试最新版源码的用户无需再安装一份 npm 包。
此 npm 包只包含双账号路由插件,不包含 pi-cost-lens 的本地额度修复。 npm 当前的 [email protected] 尚未包含本次 B/自动路由联动修改;额度显示需使用更新后的本地 pi-cost-lens。只安装本包可使用短命令和账号路由,但不保证旧额度插件能显示 B 的额度。
日常操作(简化版)
安装或更新后,在 Pi 输入 /reload,然后:
| 命令 | 操作 |
|---|---|
| /dual | 打开菜单,方向键选择、Enter 确认、Esc 取消 |
| /dual a / /dual b | 固定账号 A/B,保留当前 Codex 模型 |
| /dual switch | 从当前账号切换到另一个账号 |
| /dual auto | 一步设置主账号优先并启用自动回退 |
| /dual round-robin | 一步设置并启用 A/B 轮询 |
| /dual threshold 10 / /dual threshold off | 设置提前换号阈值 / 关闭阈值(菜单也可设置) |
| /dual status | 查看登录、冷却、统计、阈值 |
原来的 /codex-dual use a|b、on、mode、prefer 等命令仍可使用;短命令也支持大写 A/B。
登录仍用 Pi 原生 /login openai-codex 和 /login openai-codex-b,无需重新登录已有账号。
低额度提前换号与重置倒计时
默认阈值为 10%,在 /dual auto 或 /dual round-robin 模式生效。任一可用的 5 小时/周窗口剩余 低于 阈值时,下一模型请求提前改用另一个已登录且未冷却的账号;不打断正在生成的回答。/dual a、/dual b 是手动固定模式,不会被覆盖。
/dual threshold 20
/dual auto上例将阈值设为 20% 并启用自动模式。/dual threshold off(或 0)仅关闭提前切换,不关闭服务端限流/授权失效后的自动回退。
- 数据来自正常响应头或配套 pi-cost-lens 的成功查询,不根据 Token 用量估算。
- 只采用 10 分钟内且未重置 的窗口报告;未知或过期额度不视为零。查询失败不产生新报告。
- 两账号都低时选择剩余较高者;只有一个可用账号时仍可尝试,服务端真实限流/授权冷却仍优先。
/cost quota手动刷新;默认后台刷新间隔由 pi-cost-lens 配置控制。- 配套 pi-cost-lens 0.1.3 在右下角分别显示 5h、周窗口距离下次额度重置的倒计时,不是最近查询时间。例如
5h剩余 80%(2h30m后重置)、周剩余 60%(3d12h后重置);d/h/m 表示天/小时/分钟。 - 倒计时只基于服务端的
resets_at/reset_after_seconds,每分钟本地重绘,不额外轮询 API。缺少重置时间显示重置 --,已到期显示已到期,待刷新,不擅自把额度改成满额。 - 宽度不足时两个窗口分行显示,保留各自百分比与倒计时;查询时间只留在
/cost quota诊断详情。首次从旧 footer 升级建议重启 Pi,避免旧包装器缓存。 - 未更新 pi-cost-lens 时不会显示倒计时,也不会发送查询额度报告;若模型传输提供使用率响应头,双账号插件仍可利用它提前路由。
额度跟随账号
右下角剩余额度由 pi-cost-lens 查询和显示,而非本插件。本次本地配套修复更新了 pi-cost-lens 的 src/index.ts 和 src/quota-service.ts,让它识别 B,并通过不含凭据的 codex-dual:account 事件获取自动路由的实际账号。以下效果需要该配套修复;它未随本 npm 包发布。
- 固定 A/B 时显示对应账号的
订阅 A/B · 5h剩余 … · 周剩余 …。 - 自动回退、轮询时显示当前会话最近实际使用的账号;尚未发出请求时显示预计路由账号。
- 切换立即清除旧账号显示,并展示新账号的查询中占位;网络返回后更新比例。慢到的旧响应不会覆盖新账号。
- 查询失败会标记“查询失败”:同账号有旧成功数据时保留旧数据,没有成功数据则显示
--。不会拿 A 的额度或重置时间冒充 B,也不根据 Token 用量推算订阅额度。 /cost quota可手动刷新。共享路由文件中的其他进程lastUsed不会改变本会话的额度账号。- 将插件复制到别的机器时,需要同时带上更新后的 pi-cost-lens;codex-dual 不接管或替换现有 footer,也不自行查询额度接口。
快速使用
当前优化版本 0.2.3。新增离线模拟测试覆盖菜单、短命令、旧命令兼容、轮询/回退账号通知、A/B 凭据隔离及快速切换竞态;没有使用真实账号或消耗订阅额度。
先临时加载,不修改你现有的全局配置:
pi -e /path/to/pi-codex-dual/src/index.ts这个命令保留其他已安装插件,包括你的 pi-web-access 和 pi-mcp-adapter。插件不注册或替换任何工具,也不改变工具的激活状态。
在 Pi 输入:
/login openai-codex-b
/dual auto
/dual status- A 直接复用已有
openai-codex登录,所以当前已登录 A 时不用再次授权,也不复制 refresh token。 - B 登录时,请把授权链接放到另一浏览器资料或无痕窗口,登录第二个账号。两个授权应分别进行,避免争用 OAuth 回调端口。
- 若 A 尚未登录,先执行
/login openai-codex。 - 如果 B 与 A 是同一账号,B 的登录会被拒绝,旧授权不会被覆盖。后来把 A 改成与 B 相同的账号,也会在路由前报错。
/codex-dual on保留当前 Codex 模型;当前模型不是 Codex 时,会让你选择。- 不要求提供密码、复制 Cookie 或在聊天中粘贴 token。
确认满意后,可以自行永久安装这个本地插件:
pi install /path/to/pi-codex-dual然后在当前 Pi 中 /reload,或者重启 Pi。卸载:
pi remove /path/to/pi-codex-dual卸载插件不会自动删除账号授权。需要时,趁插件仍加载,执行 /logout openai-codex-b;A 使用 Pi 原来的退出登录操作。
路由与手动切换
默认主账号优先:
/codex-dual mode failover
/codex-dual prefer a
/codex-dual on每个模型请求交替使用两个账号:
/codex-dual mode round-robin
/codex-dual on轮询按模型请求,不是按用户消息、token 数或剩余额度。 一条消息中的工具调用、后续回答、摘要等可能涉及多个请求。单个模型回答不会同时拼接两个账号的输出。
多个 Pi 进程使用相同 PI_CODING_AGENT_DIR、双账号 provider 时,会共享轮询指针和冷却状态。选择账号与记录尝试次数在同一个文件锁事务中完成,避免并发进程重复读取同一个旧指针。某账号冷却中时,另一个账号会承接更多请求。
固定某个账号,不自动切换:
/codex-dual use a
/codex-dual use b单独启动两个 Pi 进程,也可以分别使用两个账号:
pi -e /path/to/pi-codex-dual/src/index.ts --provider openai-codex --model gpt-6.1-sol
pi -e /path/to/pi-codex-dual/src/index.ts --provider openai-codex-b --model gpt-6.1-sol模型 ID 仅为本机已加载目录中的示例,请用 /model 选择账号实际有权限使用的模型。上述固定账号调用不经过双账号路由,不计入共享路由统计。
如果想让多个进程自动分流,两个进程都使用 --provider openai-codex-dual,并将模式设为 round-robin。它们按请求共享调度,不保证 token 消耗均等。
非交互调用
先在交互模式完成登录,然后:
pi -e /path/to/pi-codex-dual/src/index.ts --provider openai-codex-dual --model gpt-6.1-sol -p "你的任务"加载插件后也可以在 /model 中选择 openai-codex-dual 的模型。插件不会擅自改变默认模型;若希望后续会话默认路由,在模型选择器中选择该 provider 的模型,再按 Ctrl+S 保存默认设置。
切换规则与限制
- HTTP 429 或明确的额度/速率限制错误自动切换。
- 新增授权失效切换:401、
invalid_grant、明确的 refresh token 失效等错误,在尚未输出内容时可切换到另一个独立授权账号,并提示重新登录。默认开启,可用/codex-dual auth-failover off关闭。授权失败本地冷却 5 分钟,不表示服务端撤销会自动恢复。 - 403、一般网络/服务器失败、一般 OAuth 网络失败、上下文过长等不盲目切账号。
- 每个路由请求最多尝试 A、B 各一次,底层 SDK 重试设为 0。调用方传入
timeoutMs时,两次尝试共享总超时预算;取消/超时后不再切换。 - 任何文本、思考或工具事件开始向 Pi 输出后,不再切账号重放。 避免重复输出或重复执行有副作用的工具。
- 用户按 Esc 取消后不会触发账号切换。
- 综合服务端
Retry-After、retry-after-ms、错误恢复时间及已耗尽窗口的恢复时间,取较长的冷却;晚到的较短响应不会缩短已有冷却。非法、负数、空白的数字不会误当日期。 - 缺少恢复时间时,普通限流初始 60 秒、订阅额度错误初始 15 分钟;连续失败指数退避,分别最多 15 分钟/1 小时。成功后重置退避次数,但不抹掉其他并发请求确认的冷却。这些都是本地策略,不保证服务端额度已恢复。
- 响应暴露
x-codex-*使用率头时,记录服务端最近报告;报告窗口已用 100% 时跳过该账号的后续请求,当前成功回答不受影响。部分传输不提供这些头,因此可能没有报告;不额外请求私有额度接口。 - A、B 都不可用时停止,并尽量提示最早重试时间或重新登录方法。Pi 自己的顶层重试仍会跳过共享冷却中的账号。
- 冷却、请求尝试/成功/失败统计及轮询指针持久化,跨重启、
/reload和会话切换保留,并在同配置目录的进程间共享。 /codex-dual status可在回答过程中使用。它显示保存授权、共享统计及可选的服务端历史报告,不查询实时剩余额度。保存授权不保证未被撤销;尝试次数也不等于实际消耗次数。/codex-dual reset [a|b]清除共享冷却/退避,不清除统计,也不改变服务端额度。重新登录 B 只清除明确的授权失败冷却,不清除额度冷却;重新登录 A 后若仍有授权冷却,可手动reset a。- B 和双账号模型目录跟随当前原生 Codex provider。修改本地模型配置后可执行
/codex-dual refresh-models,不必重载整个插件,也不发起远程目录刷新。 /codex-dual doctor检查本地目录、文件权限和重复账号,不发模型请求、不刷新 OAuth。pi-web-access、MCP 服务自身的 API key、费用和限额不受此插件管理;只有经 Pi 当前双账号 provider 发出的模型请求会被路由。工具若自行直连其他模型服务,不会自动获得双账号能力。
授权与安全
使用 Pi 自带的 Codex OAuth 登录、刷新和凭据锁,不实现私有登录接口。
| 用途 | 位置 |
|---|---|
| A 的 OAuth | ~/.pi/agent/auth.json 的 openai-codex 条目 |
| B 的 OAuth | 同文件的 openai-codex-b 条目 |
| 非敏感模式配置 | ~/.pi/agent/codex-dual.json |
| 非敏感共享状态 | ~/.pi/agent/codex-dual-state.json |
PI_CODING_AGENT_DIR 可覆盖上述目录。配置/状态原子写入,权限为 0600,不包含 token、原始账号标识、原始错误内容。共享状态只保存 A/B 槽位、计数、冷却及使用率报告。配置修改也加锁,避免两个进程的不同设置互相覆盖。
状态锁仅在短暂的本地读写期间持有,不会覆盖 OAuth 或模型网络请求;等待锁可取消,进程异常退出后的过期锁可恢复。状态损坏、异常过大或指向符号链接时停止路由,不悄悄忘记冷却后重复请求。成功回答不会仅因事后的统计写入失败而丢弃,会提示检查存储。
OAuth 文件继续完全由 Pi 管理并加锁,不复制 refresh token。请不要手工把同一个 refresh token 放到多个 provider。
插件不另行上传凭据,不把凭据放进提示词;正常 OAuth 和模型请求仍需向对应服务携带授权。对插件负责的错误信息、流式消息中的错误字段及诊断数据新增凭据脱敏,防止上游回显 token 后进入 UI/模型上下文;不修改正常模型文本或工具内容。
模式配置示例:
{
"mode": "failover",
"preferred": "openai-codex",
"quotaThresholdPercent": 10
}原有配置无需迁移。quotaThresholdPercent 未设置时默认 10,范围 0–100,0 关闭提前切换。可选字段 "authFailover": false 关闭授权失效切换。配置在每次双账号请求和管理命令前重新读取,因此其他已运行的进程会在下一次请求时使用新设置,不需要常驻文件监听器。
开发与验证
cd /path/to/pi-codex-dual
npm test当前 test/*.test.mjs 使用临时配置目录和模拟 provider,覆盖短命令/菜单、旧命令兼容、轮询、回退账号通知、阈值边界/关闭、报告时效/重置、共享状态与当前显示隔离。pi-cost-lens 的配套测试覆盖 B 查询、A/B 授权隔离、自动路由反馈、快速切换、查询失败脱敏、独立窗口重置倒计时、空闲重绘及窄屏显示。本次两个源码目录共 71 项离线测试通过,不联系 OpenAI、不消耗额度。
开发依赖由本地 Pi 提供时,可设置 PI_TEST_HOST 为已安装 Pi 包的绝对路径(例如 D:\Program Files\nodejs\node_global\node_modules\@earendil-works\pi-coding-agent),然后执行 npm test;该环境变量仅供测试,不影响插件运行。
使用 [email protected] 管理共享状态锁,版本固定;它也是当前 Pi 核心已使用的依赖,本次复用了本机安装并检查其实现,没有另装第三方 Pi 插件。
本机 node_modules 使用开发链接。复制到别的机器后,先在插件目录执行 npm install --omit=dev --ignore-scripts --legacy-peer-deps 安装声明的运行依赖,再作为 Pi 本地包安装。核心模块由 Pi 加载器提供;开发测试需自行提供与安装版 Pi 一致的核心 peer dependencies。完整的跨电脑安装步骤见 INSTALL.md。
尚未验证第二个真实账号的 OAuth 和服务端双账号调用。 需要你在浏览器完成 B 的授权,然后实际使用验证。
