feat(auth): support multiple OpenAI/Codex subscriptions - #68520
feat(auth): support multiple OpenAI/Codex subscriptions#68520mehmetkr-31 wants to merge 1 commit into
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for addressing the remaining auth.json-import gap after multi-account device-code login shipped.
Problems
hermes_cli/auth.py:3747scans and imports everyauth*.jsonwithout deduplication. In the documented workflow, the final directory containsauth.jsonfor Account B andauth.account-b.jsonwith the same account, so Account B is added twice.CredentialPool.add_entry()appends entries unconditionally (agent/credential_pool.py:2091-2096), while Codex refresh tokens are explicitly single-use (agent/credential_pool.py:1132-1140).
Suggested changes
- Deduplicate the directory results by stable credential/account material before adding pool entries, and add a test with
auth.json,auth.account-a.json, andauth.account-b.jsonasserting two resulting entries. - Document the new flags in the CLI reference.
Automated hermes-sweeper review.
| """ | ||
| dir_path = Path(directory).expanduser() | ||
| if not dir_path.is_dir(): | ||
| return [] |
There was a problem hiding this comment.
The documented workflow leaves the latest Account B in both auth.json and auth.account-b.json, so this glob imports B twice. Please deduplicate directory results by stable credential/account material before adding pool entries, and cover that three-file/two-account case. Duplicate Codex entries can independently spend the same single-use refresh token.
Currently only a single OpenAI ChatGPT Codex subscription is supported. When rate limit hits, users cannot switch to another active subscription. This adds multi-account import support for openai-codex: - `hermes auth add openai-codex --auth-file <path>` Import a single Codex account from a specific auth.json file (e.g. ~/.codex/auth.account-b.json). No device-code flow needed. - `hermes auth add openai-codex --codex-dir <dir>` Import all valid Codex accounts from a directory of auth*.json files (e.g. ~/.codex). Supports the "log in A → copy auth.json → log in B" workflow. Each imported account becomes a distinct, self-contained ``manual:device_code`` pool entry — the same pattern already used by xai-oauth, qwen-oauth, and minimax-oauth. The credential pool's round-robin / fill-first / least-used rotation strategies then handle rate-limit failover automatically. Expired tokens are rejected at import time (they cannot be refreshed). Imports are de-duplicated by account identity. The copy-then-relogin workflow routinely leaves one account in two files (the live auth.json plus the labelled copy of it), and re-running the import would append a second entry for an already-pooled account. Since Codex refresh tokens are single-use, two entries sharing a pair strand each other the first time one rotates. codex_credential_identity() keys on the JWT's chatgpt_account_id so the same account collapses even when the two files hold different token pairs, falling back to the refresh token when the claim is absent. The account-id extraction reuses the existing _decode_jwt_claims() helper and replaces the inline copy of the same claim lookup in the Codex usage probe. Fixes NousResearch#65735 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fc9b3c5 to
095b7a0
Compare
|
Reworked per the sweeper review — the duplicate-import defect is fixed and the branch is rebuilt on current The double-add is real and now closed. Confirmed the mechanics the review described:
Tests — including the exact case the review asked for:
All three fail with the de-dup reverted and pass with it in place. Suite: Two notes from the salvage:
|
SummaryOf the three surfaced PRs, #68520 directly addresses the remaining Codex auth.json import gap with single-file and directory import plus account deduplication; #58146 addresses stale cooldown state across profiles, while #49079 adds bulk credential removal and does not address multi-subscription import or rotation. Related pull requests
Suggested consolidationKeep #68520 open with a salvage path: retain its Codex file/directory import, stable-account deduplication, tests, and documentation, and obtain contributor re-review of the addressed single-use-refresh-token objection before further disposition. #49079 and #58146 are not duplicates of #68520 and should remain on their separate keep-open tracks for bulk removal and cross-profile cooldown reset, respectively; no merge recommendation is supported here. Complex graphflowchart LR
classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
classDef best stroke-width:3px,stroke:#b45309
classDef target stroke-width:3px,stroke:#4338ca
I65735(["issue #65735 (closed)"])
P68520["PR #68520 (open)"]
P68520 -->|best fix| I65735
class I65735 closed
class P68520 open
class P68520 best
class P68520 target
click I65735 "https://github.com/NousResearch/hermes-agent/issues/65735"
click P68520 "https://github.com/NousResearch/hermes-agent/pull/68520"
Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed (state tag in the node label). Cross-PR triage: Reviewed 3 pull requests and 1 issue in this complex. Each diff was read against this issue; Assessment working set: 56 kB of PR diffs, 5 kB of issue/PR text, 6 kB of discussion (8 comments), 3 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch. |
|
Is this going to receive any attention soon? |
Problem
Currently only a single OpenAI ChatGPT Codex subscription is supported. When rate limit hits, users cannot switch to another active subscription.
Each Codex CLI has a
~/.codex/auth.json, which one can import (functionality already exists). But importing multiple accounts requires running the device-code OAuth flow for each account — even when the user already has valid auth.json files.Solution
Multi-account import support for
openai-codex:hermes auth add openai-codexhermes auth add openai-codex --auth-file <path>hermes auth add openai-codex --codex-dir <dir>auth*.jsonfilesMulti-account workflow
Each imported account becomes a distinct, self-contained
manual:device_codepool entry — the same pattern already used by xai-oauth, qwen-oauth, and minimax-oauth. The credential pool's round-robin / fill-first / least-used rotation strategies then handle rate-limit failover automatically.Safety
_import_codex_cli_tokensnow accepts an optionalauth_pathparameter for reading from non-default locations_import_codex_cli_tokens_from_directoryscans a directory forauth*.jsonfilesTests
Added 5 new tests in
tests/hermes_cli/test_auth_commands.py:--auth-file)--codex-dir)--auth-filevs--codex-dirprecedenceAll 58 tests pass.
Fixes #65735