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 2 commits into
Conversation
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
|
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. |
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.
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. |
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