omp packages

pi-codex-dual0.2.3

Two independently authorized ChatGPT/Codex accounts for Pi, with bounded failover and optional round-robin routing.

shuo-wang Published 12 days ago MIT ~348 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

Pi Codex 双账号插件

让两个你自己的 ChatGPT Plus/Pro 账号分别保持 Codex OAuth 授权,在 Pi 中按请求切换。

不是合并订阅额度,也不是把 ChatGPT 网页版额度变成 OpenAI API 额度。 请求走 Pi 已支持的 Codex 订阅通道,每个账号仍受自己的额度、模型权限和服务条款约束。

安装 npm 包

发布到 npm 后,可在系统终端运行:

pi install npm:pi-codex-dual@0.2.3

然后在 Pi 执行 /reload 或重启。若已通过本地目录加载本插件,请先取消旧的本地安装登记,避免重复加载;这不会删除账号授权。本机正在测试最新版源码的用户无需再安装一份 npm 包。

此 npm 包只包含双账号路由插件,不包含 pi-cost-lens 的本地额度修复。 npm 当前的 pi-cost-lens@0.1.1 尚未包含本次 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;该环境变量仅供测试,不影响插件运行。

使用 proper-lockfile@4.1.2 管理共享状态锁,版本固定;它也是当前 Pi 核心已使用的依赖,本次复用了本机安装并检查其实现,没有另装第三方 Pi 插件。

本机 node_modules 使用开发链接。复制到别的机器后,先在插件目录执行 npm install --omit=dev --ignore-scripts --legacy-peer-deps 安装声明的运行依赖,再作为 Pi 本地包安装。核心模块由 Pi 加载器提供;开发测试需自行提供与安装版 Pi 一致的核心 peer dependencies。完整的跨电脑安装步骤见 INSTALL.md。

尚未验证第二个真实账号的 OAuth 和服务端双账号调用。 需要你在浏览器完成 B 的授权,然后实际使用验证。