fix: usage API rate-limit guard and cleanup debug logging
This commit is contained in:
@@ -58,13 +58,17 @@ function loadUsageDiskCache(): void {
|
||||
if (fs.existsSync(USAGE_CACHE_FILE)) {
|
||||
usageDiskCache = JSON.parse(fs.readFileSync(USAGE_CACHE_FILE, 'utf-8'));
|
||||
}
|
||||
} catch { /* start fresh */ }
|
||||
} catch {
|
||||
/* start fresh */
|
||||
}
|
||||
}
|
||||
|
||||
function saveUsageDiskCache(): void {
|
||||
try {
|
||||
fs.writeFileSync(USAGE_CACHE_FILE, JSON.stringify(usageDiskCache));
|
||||
} catch { /* best effort */ }
|
||||
} catch {
|
||||
/* best effort */
|
||||
}
|
||||
}
|
||||
|
||||
function cacheKey(token: string): string {
|
||||
@@ -104,7 +108,9 @@ async function fetchUsageForToken(
|
||||
return null;
|
||||
}
|
||||
if (res.status === 429) {
|
||||
logger.warn('Claude usage API: rate limited (429), returning cached data');
|
||||
logger.warn(
|
||||
'Claude usage API: rate limited (429), returning cached data',
|
||||
);
|
||||
return usageDiskCache[cacheKey(token)]?.usage ?? null;
|
||||
}
|
||||
if (!res.ok) {
|
||||
|
||||
@@ -48,15 +48,13 @@ interface FallbackConfig {
|
||||
// ── State ────────────────────────────────────────────────────────
|
||||
|
||||
let cooldown: CooldownState | null = null;
|
||||
let lastUsageAvailabilityCheck:
|
||||
| {
|
||||
checkedAt: number;
|
||||
result: 'available' | 'exhausted' | 'unknown';
|
||||
}
|
||||
| null = null;
|
||||
let usageAvailabilityCheckPromise:
|
||||
| Promise<'available' | 'exhausted' | 'unknown'>
|
||||
| null = null;
|
||||
let lastUsageAvailabilityCheck: {
|
||||
checkedAt: number;
|
||||
result: 'available' | 'exhausted' | 'unknown';
|
||||
} | null = null;
|
||||
let usageAvailabilityCheckPromise: Promise<
|
||||
'available' | 'exhausted' | 'unknown'
|
||||
> | null = null;
|
||||
|
||||
const USAGE_RECOVERY_RECHECK_MS = 30_000;
|
||||
|
||||
@@ -213,7 +211,10 @@ export async function getActiveProvider(): Promise<string> {
|
||||
}
|
||||
if (usageAvailability === 'exhausted') {
|
||||
// Current token exhausted — try rotating to another token (ignore cooldowns)
|
||||
if (getTokenCount() > 1 && rotateToken(undefined, { ignoreRateLimits: true })) {
|
||||
if (
|
||||
getTokenCount() > 1 &&
|
||||
rotateToken(undefined, { ignoreRateLimits: true })
|
||||
) {
|
||||
logger.info(
|
||||
'Claude current token exhausted, rotated to next token — retrying',
|
||||
);
|
||||
|
||||
@@ -307,14 +307,14 @@ Check the run.
|
||||
phase: 'intermediate',
|
||||
result: "You're out of extra usage · resets 4am (Asia/Seoul)",
|
||||
});
|
||||
await onOutput?.({
|
||||
status: 'success',
|
||||
result: "You're out of extra usage · resets 4am (Asia/Seoul)",
|
||||
});
|
||||
return {
|
||||
status: 'success',
|
||||
result: null,
|
||||
};
|
||||
await onOutput?.({
|
||||
status: 'success',
|
||||
result: "You're out of extra usage · resets 4am (Asia/Seoul)",
|
||||
});
|
||||
return {
|
||||
status: 'success',
|
||||
result: null,
|
||||
};
|
||||
},
|
||||
)
|
||||
.mockImplementationOnce(
|
||||
@@ -324,14 +324,14 @@ Check the run.
|
||||
_onProcess: unknown,
|
||||
onOutput?: (output: Record<string, unknown>) => Promise<void>,
|
||||
) => {
|
||||
await onOutput?.({
|
||||
status: 'success',
|
||||
result: 'rotated scheduled task response',
|
||||
});
|
||||
return {
|
||||
status: 'success',
|
||||
result: null,
|
||||
};
|
||||
await onOutput?.({
|
||||
status: 'success',
|
||||
result: 'rotated scheduled task response',
|
||||
});
|
||||
return {
|
||||
status: 'success',
|
||||
result: null,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -156,11 +156,7 @@ export function rotateToken(
|
||||
for (let i = 1; i < tokens.length; i++) {
|
||||
const idx = (currentIndex + i) % tokens.length;
|
||||
const state = tokens[idx];
|
||||
if (
|
||||
ignoreRL ||
|
||||
!state.rateLimitedUntil ||
|
||||
state.rateLimitedUntil <= now
|
||||
) {
|
||||
if (ignoreRL || !state.rateLimitedUntil || state.rateLimitedUntil <= now) {
|
||||
state.rateLimitedUntil = null;
|
||||
currentIndex = idx;
|
||||
logger.info(
|
||||
|
||||
Reference in New Issue
Block a user