From 87c4111a09fc632cfe6e59de735f98618338f3fb Mon Sep 17 00:00:00 2001 From: Jarvis Date: Sat, 14 Mar 2026 13:06:51 +0800 Subject: [PATCH] fix(auth): honor disabled windows in cooldown checks --- src/agents/auth-profiles/usage.test.ts | 20 ++++++++++++++++++++ src/agents/auth-profiles/usage.ts | 3 +++ 2 files changed, 23 insertions(+) diff --git a/src/agents/auth-profiles/usage.test.ts b/src/agents/auth-profiles/usage.test.ts index 328b729d2e1..28309551a6e 100644 --- a/src/agents/auth-profiles/usage.test.ts +++ b/src/agents/auth-profiles/usage.test.ts @@ -123,6 +123,22 @@ describe("isProfileInCooldown", () => { ); }); + it("still blocks when a disabled window is active even if the stored rate-limit cooldown is for another model", () => { + const store = makeStore({ + "anthropic:default": { + cooldownUntil: Date.now() + 60_000, + cooldownReason: "rate_limit", + cooldownModel: "claude-opus-4-6", + disabledUntil: Date.now() + 5 * 60_000, + disabledReason: "billing", + }, + }); + + expect(isProfileInCooldown(store, "anthropic:default", undefined, "claude-sonnet-4-6")).toBe( + true, + ); + }); + it("returns false when cooldownUntil has passed", () => { const store = makeStore({ "anthropic:default": { cooldownUntil: Date.now() - 1_000 }, @@ -368,6 +384,8 @@ describe("clearExpiredCooldowns", () => { cooldownUntil: Date.now() - 1_000, disabledUntil: future, disabledReason: "billing", + cooldownReason: "rate_limit", + cooldownModel: "claude-opus-4-6", errorCount: 5, failureCounts: { rate_limit: 3, billing: 2 }, }, @@ -378,6 +396,8 @@ describe("clearExpiredCooldowns", () => { const stats = store.usageStats?.["anthropic:default"]; // cooldownUntil cleared expect(stats?.cooldownUntil).toBeUndefined(); + expect(stats?.cooldownReason).toBeUndefined(); + expect(stats?.cooldownModel).toBeUndefined(); // disabledUntil still active — not touched expect(stats?.disabledUntil).toBe(future); expect(stats?.disabledReason).toBe("billing"); diff --git a/src/agents/auth-profiles/usage.ts b/src/agents/auth-profiles/usage.ts index 57a667dbf00..a08ea5ecf8d 100644 --- a/src/agents/auth-profiles/usage.ts +++ b/src/agents/auth-profiles/usage.ts @@ -56,6 +56,7 @@ export function isProfileInCooldown( const unusableUntil = resolveProfileUnusableUntil(stats); const ts = now ?? Date.now(); if ( + !isActiveUnusableWindow(stats.disabledUntil, ts) && stats.cooldownReason === "rate_limit" && typeof forModel === "string" && forModel.trim().length > 0 && @@ -223,6 +224,8 @@ export function clearExpiredCooldowns(store: AuthProfileStore, now?: number): bo if (cooldownExpired) { stats.cooldownUntil = undefined; + stats.cooldownReason = undefined; + stats.cooldownModel = undefined; profileMutated = true; } if (disabledExpired) {