Files
openclaw/src/agents/auth-profiles.ts
T
nabbilkhan 03cadc4b7a fix(auth): auto-expire stale auth profile cooldowns and reset error count
When an auth profile hits a rate limit, `errorCount` is incremented and
`cooldownUntil` is set with exponential backoff. After the cooldown
expires, the time-based check correctly returns false — but `errorCount`
persists. The next transient failure immediately escalates to a much
longer cooldown because the backoff formula uses the stale count:

  60s × 5^(errorCount-1), max 1h

This creates a positive feedback loop where profiles appear permanently
stuck after rate limits, requiring manual JSON editing to recover.

Add `clearExpiredCooldowns()` which sweeps all profiles on every call to
`resolveAuthProfileOrder()` and clears expired `cooldownUntil` /
`disabledUntil` values along with resetting `errorCount` and
`failureCounts` — giving the profile a fair retry window (circuit-breaker
half-open → closed transition).

Key design decisions:
- `cooldownUntil` and `disabledUntil` handled independently (a profile
  can have both; only the expired one is cleared)
- `errorCount` reset only when ALL unusable windows have expired
- `lastFailureAt` preserved for the existing failureWindowMs decay logic
- In-memory mutation; disk persistence happens lazily on the next store
  write, matching the existing save pattern

Fixes #3604
Related: #13623, #15851, #11972, #8434
2026-02-16 12:53:45 -06:00

44 lines
1.3 KiB
TypeScript

export { CLAUDE_CLI_PROFILE_ID, CODEX_CLI_PROFILE_ID } from "./auth-profiles/constants.js";
export { resolveAuthProfileDisplayLabel } from "./auth-profiles/display.js";
export { formatAuthDoctorHint } from "./auth-profiles/doctor.js";
export { resolveApiKeyForProfile } from "./auth-profiles/oauth.js";
export { resolveAuthProfileOrder } from "./auth-profiles/order.js";
export { resolveAuthStorePathForDisplay } from "./auth-profiles/paths.js";
export {
listProfilesForProvider,
markAuthProfileGood,
setAuthProfileOrder,
upsertAuthProfile,
upsertAuthProfileWithLock,
} from "./auth-profiles/profiles.js";
export {
repairOAuthProfileIdMismatch,
suggestOAuthProfileIdForLegacyDefault,
} from "./auth-profiles/repair.js";
export {
ensureAuthProfileStore,
loadAuthProfileStore,
saveAuthProfileStore,
} from "./auth-profiles/store.js";
export type {
ApiKeyCredential,
AuthProfileCredential,
AuthProfileFailureReason,
AuthProfileIdRepairResult,
AuthProfileStore,
OAuthCredential,
ProfileUsageStats,
TokenCredential,
} from "./auth-profiles/types.js";
export {
calculateAuthProfileCooldownMs,
clearAuthProfileCooldown,
clearExpiredCooldowns,
getSoonestCooldownExpiry,
isProfileInCooldown,
markAuthProfileCooldown,
markAuthProfileFailure,
markAuthProfileUsed,
resolveProfileUnusableUntilForDisplay,
} from "./auth-profiles/usage.js";