#3909: fix(auth): refresh all OAuth profiles per provider
commands
agents
Cluster:
Auth Improvements and Fixes
## Summary
Fixes #3803 - OAuth tokens for google-gemini-cli and google-antigravity providers now refresh all accounts, not just the first one per provider.
### Root Cause
Previously, `resolveOAuthToken()` in `src/infra/provider-usage.auth.ts` would return immediately after finding the first valid profile for a provider. This left other profiles with expired tokens until they were specifically accessed.
Additionally, the status display showed stale expiry times because it read credentials before the usage fetch triggered token refreshes.
### Changes
1. **Refresh all profiles per provider** (`src/infra/provider-usage.auth.ts`):
- Renamed `resolveOAuthToken()` to `resolveOAuthTokens()`
- Changed from returning early to collecting all valid profiles in an array
- Updated `resolveProviderAuths()` to spread all resolved tokens
2. **Display refreshed state** (`src/commands/models/list.status-command.ts`):
- Added store re-read after usage fetch completes
- Rebuilt auth health summary with fresh credential data
- Status display now shows post-refresh state immediately
### Test Plan
- [x] Verified all 6 Google OAuth accounts refresh on single `moltbot models status` run
- [x] Confirmed status display shows refreshed expiry times (no stale "expired" entries)
- [x] Existing OAuth refresh tests pass
- [x] Multi-account test scenario validates all profiles get new tokens
### Before
```
$ moltbot models status
# Only 2 out of 6 expired accounts refreshed
# Status showed "expired expires in 0m" for 4 accounts
```
### After
```
$ moltbot models status
# All 6 accounts refresh
# All show "expiring expires in Xm" with valid times
```
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR fixes multi-account OAuth refresh by changing provider usage auth resolution to collect tokens for *all* OAuth/token profiles per provider (instead of returning after the first match), and updates the `models status` command to rebuild the displayed OAuth health after the usage snapshot fetch triggers refresh.
Key flow changes:
- `src/infra/provider-usage.auth.ts` now returns a `ProviderAuth[]` from `resolveOAuthTokens()` and spreads all resolved tokens into `resolveProviderAuths()`, which is used by provider usage snapshots.
- `src/commands/models/list.status-command.ts` re-reads the auth store and rebuilds the auth health summary after `loadProviderUsageSummary()` completes so the status output reflects refreshed expiry times.
- Adds a Vitest suite covering OAuth refresh behavior for the Google OAuth providers via the pi-ai API wrapper.
<h3>Confidence Score: 3/5</h3>
- Mostly safe to merge, but there is a likely agent-scope bug in the refreshed status display path.
- The auth refresh logic change is localized and aligned with the PR goal (returning all OAuth tokens per provider). However, the new post-usage refresh re-read in `models status` appears to ignore `agentDir`, which can show incorrect refreshed state for `--agent` usage, and the new test suite has a potentially flaky module-reset/mocking pattern.
- src/commands/models/list.status-command.ts; src/agents/auth-profiles/oauth-refresh.test.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#5027: fix(auth): use correct OAuth credentials for google-gemini-cli refresh
by shayan919293 · 2026-01-30
83.7%
#4550: fix: sync google-gemini-cli-auth tokens from external CLI (#3803)
by SalimBinYousuf1 · 2026-01-30
80.7%
#2123: fix(auth): sync from Claude CLI keychain before OAuth refresh
by jorge123255 · 2026-01-26
80.5%
#8225: feat(auth): add forceRefresh option and invalidateOAuthToken for 40...
by arodundef · 2026-02-03
78.7%
#14824: fix: do not trigger provider cooldown on LLM request timeouts
by CyberSinister · 2026-02-12
78.6%
#14574: fix: gentler rate-limit cooldown backoff + clear stale cooldowns on...
by JamesEBall · 2026-02-12
78.0%
#3196: docs: clarify auth-profiles.json format for Claude Max setup-tokens
by aadeina · 2026-01-28
77.8%
#2657: fix: use TLS 1.2 for gemini-cli and google-antigravity OAuth reques...
by PrentissLiu · 2026-01-27
76.7%
#21884: feat(models): auth improvements — status command, heuristics, multi...
by kckylechen1 · 2026-02-20
76.3%
#8805: [Bug Fix][AI-assisted] Refresh Copilot token before expiry and retr...
by Arthur742Ramos · 2026-02-04
76.3%