← Back to PRs

#3909: fix(auth): refresh all OAuth profiles per provider

by Daviey open 2026-01-29 10:12 View on GitHub →
commands agents
## 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