fix(oauth+errors): OAuth silent refresh, quota STOP patterns, compaction loop cap

Bug fixes:
1. OAuth token refresh (#3149): buildHttpRequestInit() now attempts silent refresh
   via refresh_token before triggering full browser re-auth. Added refresh() method
   to McpOAuthProvider. Includes test isolation fix for discovery mock.

2. Quota error STOP (#3126): Added STOP_MESSAGE_PATTERNS in model-error-classifier
   that take precedence over RETRYABLE_MESSAGE_PATTERNS. Message-only quota errors
   now non-retryable. Runtime-fallback: quota_exceeded with 'retrying in' signal
   still triggers fallback (provider-managed auto-retry). Restored removed patterns.

3. Compaction loop (#3127): MAX_RECOVERY_ATTEMPTS=3 cap + additional suppression
   guard from opencode session in degradation monitor.

Also: refactored extractAutoRetrySignal to auto-retry-signal.ts, new regression
tests for quota classifier and compaction degradation monitor.
This commit is contained in:
YeonGyu-Kim
2026-04-06 17:38:37 +09:00
parent 6c4e0b69a5
commit 61083d499d
15 changed files with 611 additions and 531 deletions
@@ -44,7 +44,7 @@ export async function buildHttpRequestInit(
const provider = getOrCreateAuthProvider(authProviders, config.url, config.oauth, createOAuthProvider)
let tokenData = provider.tokens()
if (!tokenData || isTokenExpired(tokenData)) {
if (!tokenData) {
try {
tokenData = await provider.login()
} catch {
@@ -52,6 +52,20 @@ export async function buildHttpRequestInit(
}
}
if (tokenData && isTokenExpired(tokenData)) {
try {
tokenData = tokenData.refreshToken
? await provider.refresh(tokenData.refreshToken)
: await provider.login()
} catch {
try {
tokenData = await provider.login()
} catch {
tokenData = null
}
}
}
if (tokenData) {
headers.Authorization = `Bearer ${tokenData.accessToken}`
}