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:
parent
dece0fa146
commit
f91034aa6b
@ -175,6 +175,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
- Tests/Telegram: add regression coverage for command-menu sync that asserts all `setMyCommands` entries are Telegram-safe and hyphen-normalized across native/custom/plugin command sources. (#19703) Thanks @obviyus.
|
||||
- Agents/Image: collapse resize diagnostics to one line per image and include visible pixel/byte size details in the log message for faster triage.
|
||||
- Auth/Cooldowns: clear all usage stats fields (`disabledUntil`, `disabledReason`, `failureCounts`) in `clearAuthProfileCooldown` so manual cooldown resets fully recover billing-disabled profiles without requiring direct file edits. (#19211) Thanks @nabbilkhan.
|
||||
- Agents/Subagents: preemptively guard accumulated tool-result context before model calls by truncating oversized outputs and compacting oldest tool-result messages to avoid context-window overflow crashes. Thanks @tyler6204.
|
||||
- Agents/Subagents/CLI: fail `sessions_spawn` when subagent model patching is rejected, allow subagent model patch defaults from `subagents.model`, and keep `sessions list`/`status` model reporting aligned to runtime model resolution. (#18660) Thanks @robbyczgw-cla.
|
||||
- Agents/Subagents: add explicit subagent guidance to recover from `[compacted: tool output removed to free context]` / `[truncated: output exceeded context limit]` markers by re-reading with smaller chunks instead of full-file `cat`. Thanks @tyler6204.
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user