@hienlh/ppm 0.8.47 → 0.8.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.8.49] - 2026-03-25
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **Auth error backoff**: `onAuthError` now uses 5-minute base cooldown (exponential up to 30min) instead of 1s rate-limit backoff — prevents rapid retry loops on dead/rejected accounts
|
|
7
|
+
- **No permanent disable**: Auth errors never permanently disable accounts — cooldown allows recovery from transient issues (subscription lapse, org changes, API hiccups)
|
|
8
|
+
|
|
9
|
+
## [0.8.48] - 2026-03-25
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- **Account auth errors**: Use cooldown instead of permanent disable on `authentication_failed` / 401 — auth issues can be transient (subscription lapse, org changes, API hiccups)
|
|
13
|
+
- **SDK refresh safety**: Pass `disableOnFail=false` in SDK error handlers — prevents `refreshAccessToken` from disabling accounts as side effect during auto-retry
|
|
14
|
+
|
|
3
15
|
## [0.8.47] - 2026-03-25
|
|
4
16
|
|
|
5
17
|
### Fixed
|
package/package.json
CHANGED
|
@@ -611,7 +611,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
611
611
|
if (assistantError === "authentication_failed" && account && !authRetried) {
|
|
612
612
|
authRetried = true;
|
|
613
613
|
try {
|
|
614
|
-
await accountService.refreshAccessToken(account.id);
|
|
614
|
+
await accountService.refreshAccessToken(account.id, false);
|
|
615
615
|
console.log(`[sdk] session=${sessionId} OAuth token refreshed for ${account.id} — retrying`);
|
|
616
616
|
// Re-build env with refreshed token
|
|
617
617
|
const refreshedAccount = accountService.getWithTokens(account.id);
|
|
@@ -628,10 +628,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
628
628
|
}
|
|
629
629
|
} catch (refreshErr) {
|
|
630
630
|
console.error(`[sdk] session=${sessionId} OAuth refresh failed:`, refreshErr);
|
|
631
|
-
|
|
632
|
-
if (accountService.hasRefreshToken(account.id)) {
|
|
633
|
-
accountSelector.onAuthError(account.id);
|
|
634
|
-
}
|
|
631
|
+
accountSelector.onAuthError(account.id);
|
|
635
632
|
}
|
|
636
633
|
}
|
|
637
634
|
|
|
@@ -702,13 +699,10 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
702
699
|
} else if (errCode === 401) {
|
|
703
700
|
// Try refresh once
|
|
704
701
|
try {
|
|
705
|
-
await accountService.refreshAccessToken(account.id);
|
|
702
|
+
await accountService.refreshAccessToken(account.id, false);
|
|
706
703
|
console.log(`[sdk] 401 on account ${account.id} — token refreshed`);
|
|
707
704
|
} catch {
|
|
708
|
-
|
|
709
|
-
if (accountService.hasRefreshToken(account.id)) {
|
|
710
|
-
accountSelector.onAuthError(account.id);
|
|
711
|
-
}
|
|
705
|
+
accountSelector.onAuthError(account.id);
|
|
712
706
|
}
|
|
713
707
|
} else {
|
|
714
708
|
accountSelector.onSuccess(account.id);
|
|
@@ -8,6 +8,7 @@ const MAX_RETRY_CONFIG_KEY = "account_max_retry";
|
|
|
8
8
|
|
|
9
9
|
const BACKOFF_BASE_MS = 1_000;
|
|
10
10
|
const BACKOFF_MAX_MS = 30 * 60_000;
|
|
11
|
+
const AUTH_BACKOFF_BASE_MS = 5 * 60_000; // 5min base for auth errors (longer than rate limits)
|
|
11
12
|
|
|
12
13
|
class AccountSelectorService {
|
|
13
14
|
private cursor = 0;
|
|
@@ -125,11 +126,13 @@ class AccountSelectorService {
|
|
|
125
126
|
console.log(`[accounts] ${accountId} rate limited — cooldown ${Math.round(backoffMs / 1000)}s (retry #${retries})`);
|
|
126
127
|
}
|
|
127
128
|
|
|
128
|
-
/** Called when 401
|
|
129
|
+
/** Called when auth error (401 / authentication_failed) — cooldown with longer backoff */
|
|
129
130
|
onAuthError(accountId: string): void {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
const retries = (this.retryCounts.get(accountId) ?? 0) + 1;
|
|
132
|
+
this.retryCounts.set(accountId, retries);
|
|
133
|
+
const backoffMs = Math.min(AUTH_BACKOFF_BASE_MS * Math.pow(2, retries - 1), BACKOFF_MAX_MS);
|
|
134
|
+
accountService.setCooldown(accountId, Date.now() + backoffMs);
|
|
135
|
+
console.log(`[accounts] ${accountId} auth error — cooldown ${Math.round(backoffMs / 1000)}s (retry #${retries})`);
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
/** Called on successful request — reset retry count + track usage */
|