mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 09:31:25 +00:00
fix(auth): clear all usage stats fields in clearAuthProfileCooldown (openclaw#19211) thanks @nabbilkhan
Verified: - pnpm install --frozen-lockfile - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: nabbilkhan <203121263+nabbilkhan@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -1,11 +1,21 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { AuthProfileStore } from "./types.js";
|
||||
import {
|
||||
clearAuthProfileCooldown,
|
||||
clearExpiredCooldowns,
|
||||
isProfileInCooldown,
|
||||
resolveProfileUnusableUntil,
|
||||
} from "./usage.js";
|
||||
|
||||
vi.mock("./store.js", async (importOriginal) => {
|
||||
const original = await importOriginal<typeof import("./store.js")>();
|
||||
return {
|
||||
...original,
|
||||
updateAuthProfileStoreWithLock: vi.fn().mockResolvedValue(null),
|
||||
saveAuthProfileStore: vi.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
function makeStore(usageStats: AuthProfileStore["usageStats"]): AuthProfileStore {
|
||||
return {
|
||||
version: 1,
|
||||
@@ -283,3 +293,55 @@ describe("clearExpiredCooldowns", () => {
|
||||
expect(clearExpiredCooldowns(store)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// clearAuthProfileCooldown
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe("clearAuthProfileCooldown", () => {
|
||||
it("clears all error state fields including disabledUntil and failureCounts", async () => {
|
||||
const store = makeStore({
|
||||
"anthropic:default": {
|
||||
cooldownUntil: Date.now() + 60_000,
|
||||
disabledUntil: Date.now() + 3_600_000,
|
||||
disabledReason: "billing",
|
||||
errorCount: 5,
|
||||
failureCounts: { billing: 3, rate_limit: 2 },
|
||||
},
|
||||
});
|
||||
|
||||
await clearAuthProfileCooldown({ store, profileId: "anthropic:default" });
|
||||
|
||||
const stats = store.usageStats?.["anthropic:default"];
|
||||
expect(stats?.cooldownUntil).toBeUndefined();
|
||||
expect(stats?.disabledUntil).toBeUndefined();
|
||||
expect(stats?.disabledReason).toBeUndefined();
|
||||
expect(stats?.errorCount).toBe(0);
|
||||
expect(stats?.failureCounts).toBeUndefined();
|
||||
});
|
||||
|
||||
it("preserves lastUsed and lastFailureAt timestamps", async () => {
|
||||
const lastUsed = Date.now() - 10_000;
|
||||
const lastFailureAt = Date.now() - 5_000;
|
||||
const store = makeStore({
|
||||
"anthropic:default": {
|
||||
cooldownUntil: Date.now() + 60_000,
|
||||
errorCount: 3,
|
||||
lastUsed,
|
||||
lastFailureAt,
|
||||
},
|
||||
});
|
||||
|
||||
await clearAuthProfileCooldown({ store, profileId: "anthropic:default" });
|
||||
|
||||
const stats = store.usageStats?.["anthropic:default"];
|
||||
expect(stats?.lastUsed).toBe(lastUsed);
|
||||
expect(stats?.lastFailureAt).toBe(lastFailureAt);
|
||||
});
|
||||
|
||||
it("no-ops for unknown profile id", async () => {
|
||||
const store = makeStore(undefined);
|
||||
await clearAuthProfileCooldown({ store, profileId: "nonexistent" });
|
||||
expect(store.usageStats).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -400,6 +400,9 @@ export async function clearAuthProfileCooldown(params: {
|
||||
...freshStore.usageStats[profileId],
|
||||
errorCount: 0,
|
||||
cooldownUntil: undefined,
|
||||
disabledUntil: undefined,
|
||||
disabledReason: undefined,
|
||||
failureCounts: undefined,
|
||||
};
|
||||
return true;
|
||||
},
|
||||
@@ -416,6 +419,9 @@ export async function clearAuthProfileCooldown(params: {
|
||||
...store.usageStats[profileId],
|
||||
errorCount: 0,
|
||||
cooldownUntil: undefined,
|
||||
disabledUntil: undefined,
|
||||
disabledReason: undefined,
|
||||
failureCounts: undefined,
|
||||
};
|
||||
saveAuthProfileStore(store, agentDir);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user