fix: heal profile Codex credential cooldowns from global pool - #41704
fix: heal profile Codex credential cooldowns from global pool#41704trevornk wants to merge 2 commits into
Conversation
|
Thanks for isolating the profile/global pool scenario. The underlying gap still exists on current main for a profile-local exhausted manual Codex entry: Problems
Suggested changes
Automated hermes-sweeper review. |
7fa1218 to
b2d730d
Compare
… parity, coverage Three real issues from the automated review, all confirmed against current code before fixing: 1. _sync_codex_entry_from_auth_store's broadened manual:device_code sync had no equivalent to hermes_cli/auth.py::_save_codex_tokens's previous-token match guard (regression protection for NousResearch#39236). Adopting singleton tokens unconditionally for manual entries can silently overwrite an independent account's live credentials when a re-auth targets a different account. Reverted the scope of this sync back to device_code only; profile-local manual:device_code healing already has a correct, ID-matched path via _merge_profile_entries_with_global_health in the same PR. 2. _credential_pool_entry_available's exhausted-cooldown fallback (blank reset_at -> available iff last_status_at is unset) didn't match the real pool runtime's actual fallback (last_status_at + _exhausted_ttl(error_code), a 401/429/default TTL). Now delegates to agent.credential_pool's own _exhausted_until via PooledCredential.from_dict, with a deferred import to avoid the existing credential_pool.py -> hermes_cli.auth circular dependency, keeping the two cooldown semantics from silently diverging. 3. Added test coverage for load_pool(...).select() (agent/credential_pool.py's CredentialPool), the actual production selection path -- previously only read_credential_pool()'s raw dict slice was tested, not the wrapped dataclass/select() path requests actually go through. All existing tests still pass (42/42 in the touched auth test files); verified the one pre-existing unrelated failure in test_anthropic_adapter.py::TestRunOauthSetupToken (MagicMock/json mismatch) reproduces identically on unmodified main, unrelated to this change.
|
Rebased onto current Reversed: the That reasoning describes a real sharp edge, but the conclusion was wrong in context: The healing feature itself is unaffected, and it never depended on that narrowing. Also dropped: the rebase wanted to restore Retained from commit 2: Tests: |
… parity, coverage Three real issues from the automated review, all confirmed against current code before fixing: 1. _sync_codex_entry_from_auth_store's broadened manual:device_code sync had no equivalent to hermes_cli/auth.py::_save_codex_tokens's previous-token match guard (regression protection for NousResearch#39236). Adopting singleton tokens unconditionally for manual entries can silently overwrite an independent account's live credentials when a re-auth targets a different account. Reverted the scope of this sync back to device_code only; profile-local manual:device_code healing already has a correct, ID-matched path via _merge_profile_entries_with_global_health in the same PR. 2. _credential_pool_entry_available's exhausted-cooldown fallback (blank reset_at -> available iff last_status_at is unset) didn't match the real pool runtime's actual fallback (last_status_at + _exhausted_ttl(error_code), a 401/429/default TTL). Now delegates to agent.credential_pool's own _exhausted_until via PooledCredential.from_dict, with a deferred import to avoid the existing credential_pool.py -> hermes_cli.auth circular dependency, keeping the two cooldown semantics from silently diverging. 3. Added test coverage for load_pool(...).select() (agent/credential_pool.py's CredentialPool), the actual production selection path -- previously only read_credential_pool()'s raw dict slice was tested, not the wrapped dataclass/select() path requests actually go through. All existing tests still pass (42/42 in the touched auth test files); verified the one pre-existing unrelated failure in test_anthropic_adapter.py::TestRunOauthSetupToken (MagicMock/json mismatch) reproduces identically on unmodified main, unrelated to this change.
b2d730d to
5d9730b
Compare
|
Rebased onto current One resolution worth calling out explicitly, because the naive rebase would have been a regression: Verified locally on Python 3.11.16: Mutation check: temporarily short-circuiting the healing path made the new tests fail, and restoring it returned them to green — so the coverage is load-bearing rather than decorative. Also scanned the diff for credential literals; none present. Broad-suite runs were skipped: this machine hit its memory ceiling and the OOM-killer was SIGKILLing pytest, so those numbers would have been noise. Note also that |
Summary
Why
A profile can materialize a local copy of globally inherited Codex OAuth credentials after runtime status updates. If that local copy remains exhausted while the same global OAuth entry has been reset or re-authed, the profile appears out of credentials even though a usable matching global credential exists.
Test Plan