fix(auth): make xAI OAuth pools multi-account resilient (salvage #62285) - #66123
Merged
kshitijk4poor merged 2 commits intoJul 17, 2026
Merged
Conversation
Keep each xAI OAuth auth-add login as an independent manual device-code pool entry and recognize xAI personal-team spending-limit 403 responses as billing exhaustion. Preserve the structured top-level error message so the failed credential is quarantined and the next healthy account is selected without attempting a pointless token refresh. Route direct xAI HTTP consumers through the credential pool as well. Proactive and 401-reactive refreshes update the exact issuing manual entry, preserve validated xAI base URL overrides, and serialize single-use refresh-token rotation across concurrent pool instances.
…folding The openai-codex and xai-oauth branches of _refresh_entry duplicated the lock-timeout computation and _auth_store_lock acquisition. Extract the shared scaffolding: a combined provider guard, a dispatch to the provider-specific sync helper, and a _single_use_refresh_lock_timeout() helper. Each provider's distinct post-sync decision logic (codex needs-refresh short-circuit vs xai token-equality adoption) is preserved verbatim. Behavior parity verified by the credential pool suite (98 passed) and a direct timeout-helper probe for both providers. Follow-up to salvaged PR NousResearch#62285.
kshitijk4poor
enabled auto-merge (rebase)
July 17, 2026 06:04
12 tasks
tonydwb
reviewed
Jul 17, 2026
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Comment
Small fix PR (59 additions / 14 deletions). The changes cover desktop/session.py with a title-based body drop that opens split view plus preserves session token. Looks well-scoped.
No security issues, no hardcoded secrets, no debug artifacts. Clean fix pattern.
Reviewed by Hermes Agent (cron batch 2026-07-17)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Salvage of #62285 onto current
main— makes xAI OAuth credential pools work end-to-end with multiple accounts. Cherry-picked with @cresslank's authorship preserved, plus one maintainer hardening commit.Four related failures prevented useful rotation across multiple xAI OAuth grants:
hermes auth add xai-oauthrouted through the singleton_save_xai_oauth_tokens, so every additional login overwrote the singleton-backeddevice_codeentry instead of appending an independent account.personal-team-blocked:spending-limit. Hermes classified it as auth/entitlement and returned beforemark_exhausted_and_rotate(), never trying the next account.current_id, billing recovery could quarantine the wrong entry. Now passes the active runtime key asapi_key_hintso the exact failed grant is quarantined.providers.xai-oauthwhile leaving the actual pool row stale. Now resolved/refreshed through the selected pool entry.Changes
hermes_cli/auth_commands.py: append each xAI OAuth login as an independentmanual:device_codepool entry; setactive_provideronly on first add (@cresslank)agent/credential_pool.py: force-refresh the entry matching the failed bearer; serialize xAI single-use token rotation across concurrent pool instances (@cresslank)agent/error_classifier.py: classify structured xAIpersonal-team-blocked:spending-limitas billing (@cresslank)tools/xai_http.py,plugins/web/xai/provider.py: pool-only credential detection +api_key_hint-targeted refresh (@cresslank)agent/agent_runtime_helpers.py: pass failed runtime key into billing rotation; preserve top-level stringerror(@cresslank)agent/credential_pool.py): consolidate the duplicated single-use-refresh lock scaffolding shared by the openai-codex and xai-oauth branches into a combined guard +_single_use_refresh_lock_timeout()helper, preserving each provider's distinct post-sync semantics (kshitijk4poor)Validation
30929eaea)Credit
Contributor commit
5d8834b91by @cresslank (cherry-picked, authorship preserved); maintainer hardening30929eaea. Closes #62285.