fix(acp): recover stale OAuth on long-lived ACP sessions (all hosts) - #70465
fix(acp): recover stale OAuth on long-lived ACP sessions (all hosts)#70465joelbrilliant wants to merge 3 commits into
Conversation
|
Reframed for maintainers: this is not Buzz-specific. Any long-lived Buzz dogfood was the discovery path only. |
Related to #70293: both repair ACP credential-pool handoff, while this patch also changes generic 403 auth classification and the Codex/xAI refresh retry path. The mechanisms overlap but are not redundant. |
Relationship to #70293Thanks for the triage note. Fully agree these overlap but are not redundant.
Suggested landing order (happy either way):
Dogfood: same No conflict intended with @stefanpieter — happy to reshape this PR however maintainers prefer. |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the ACP runtime handoff; current main still drops credential_pool between acp_adapter/session.py:636-645, and recovery exits when that field is absent (agent/agent_runtime_helpers.py:930-932).
Problems
- The new 403 condition is too broad. xAI subscription 403s classify as
auth(agent/error_classifier.py:797-824), while pool recovery deliberately declines them as entitlement (agent/agent_runtime_helpers.py:1123-1179). After that decline, the proposedconversation_loop.pycondition would force-refresh the singleton and retry the entitlement request once. - The new classifier
should_rotate_credentialvalue is not currently consumed for recovery; the loop logs it atagent/conversation_loop.py:3677-3682but makes the proposed retry decision fromclassified.reason. - The added test covers ACP construction only. The modified 403 behavior needs stale-token and entitlement regression cases.
Suggested changes
- Narrow the 403 singleton retry to the existing stale-token discriminator, while preserving current 401 handling.
- Add tests proving WKE/OAuth-validation 403 refreshes, while the known subscription 403 does not refresh.
This is an automated hermes-sweeper review.
ACP sessions omitted credential_pool from resolve_runtime_provider while gateway/CLI pass it through. After idle, xAI returns HTTP 403 bad-credentials for a stale access token; without the pool the turn aborted as non-retryable while Telegram/Desktop on the same home kept working. - Forward credential_pool into AIAgent from ACP session construction - Treat generic 403 auth like 401 for should_rotate_credential - Singleton xAI/Codex refresh also on 403 when classified as auth
Generic OpenRouter 403 auth must keep should_rotate_credential=False (historical behaviour). Enable rotation for xAI/Codex/Nous and explicit bad-credentials / OAuth2-validation bodies only.
68fca44 to
00b9cf2
Compare
SummaryThree PRs address #70292: #70293 and #77029 contain the same minimal ACP credential-pool handoff and regression assertion, while #70465 includes that handoff plus stale-token-specific 403 classification, refresh logic, and entitlement regressions. Related pull requests
Duplicates#70293 and #77029 are substantively identical; #70293 is the closed source implementation superseded by #77029. #70465 overlaps on that handoff but is not a full duplicate because it also implements discriminator-gated 403 OAuth recovery and entitlement regressions. Suggested consolidationKeep #77029 open as the active minimal handoff replacement and leave #70293 closed as superseded by #77029. For #70465, author action: rebase onto main once the handoff is present there, or split out the salvageable stale-token-specific 403 recovery and entitlement regression coverage; this preserves the keep_open review's requested path without duplicating #77029. Cross-PR triage: Reviewed 3 pull requests and 1 issue in this complex. Each diff was read against this issue; Assessment working set: 15 kB of PR diffs, 11 kB of issue/PR text, 5 kB of discussion (8 comments), 4 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch. |
Summary
General ACP reliability fix. Any long-lived ACP host can abort turns after idle with a stale OAuth access token, while Telegram / Discord / gateway / CLI on the same
HERMES_HOMEkeep working.Typical error:
Who is affected
hermes acpstdio hosts)credential_poolintoAIAgentBuzz Desktop dogfood is how we found it (owner-only Rocky after ~3h idle). The bug is in Hermes ACP construction and OAuth recovery, not in Buzz.
Root cause
resolve_runtime_providerbut did not passcredential_poolintoAIAgent. Gateway/CLI do. Without the pool,_recover_with_credential_poolis a no-op on the ACP path.should_rotate_credential.Result: idle ACP → first multimodal or text turn after hours → non-retryable 403 → user thinks they must reauth, even though gateway still works on the same profile.
Fix
credential_poolfromresolve_runtime_providerin ACP_make_agent(match gateway/CLI)should_rotate_credential=True(billing/spend-limit 403s unchanged)auth, not only 401No config migration. Default editor behaviour unchanged when credentials are fresh.
Test plan
scripts/run_tests.sh tests/acp/test_session.py tests/run_agent/test_codex_xai_oauth_recovery.py -q(97 passed)credential_poolfrom runtimeRelated
acp.tool_policy: profile): feat(acp): opt-in profile tool policy for full-capability hosts #70326