fix(auth): reject unsafe wham reset windows · openclaw/openclaw@4305fb7
steipete
·
2026-05-30
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -957,6 +957,27 @@ describe("markAuthProfileFailure — WHAM-aware Codex cooldowns", () => {
|
957 | 957 | expect(store.usageStats?.["openai-codex:default"]?.cooldownUntil).toBe(now + 30_000); |
958 | 958 | }); |
959 | 959 | |
| 960 | +it.each([ |
| 961 | +["reset_after_seconds", { reset_after_seconds: Number.MAX_SAFE_INTEGER }], |
| 962 | +["reset_at", { reset_at: Number.MAX_SAFE_INTEGER }], |
| 963 | +])("does not pin profiles from unsafe WHAM %s values", async (_label, resetFields) => { |
| 964 | +const now = 1_700_000_000_000; |
| 965 | +const store = makeStore({}); |
| 966 | +mockWhamResponse(200, { |
| 967 | +rate_limit: { |
| 968 | +limit_reached: true, |
| 969 | +primary_window: { used_percent: 100, ...resetFields }, |
| 970 | +}, |
| 971 | +}); |
| 972 | + |
| 973 | +await markCodexFailureAt({ store, now }); |
| 974 | + |
| 975 | +const stats = store.usageStats?.["openai-codex:default"]; |
| 976 | +expect(stats?.blockedUntil).toBeUndefined(); |
| 977 | +expect(stats?.cooldownUntil).toBe(now + 30_000); |
| 978 | +expect(stats?.cooldownReason).toBe("rate_limit"); |
| 979 | +}); |
| 980 | + |
960 | 981 | it("leaves non-codex providers on the normal stepped backoff path", async () => { |
961 | 982 | const now = 1_700_000_000_000; |
962 | 983 | const store = makeStore({}); |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
1 | 1 | import type { OpenClawConfig } from "../../config/types.openclaw.js"; |
2 | 2 | import { createSubsystemLogger } from "../../logging/subsystem.js"; |
| 3 | +import { |
| 4 | +positiveSecondsToSafeMilliseconds, |
| 5 | +resolveExpiresAtMsFromEpochSeconds, |
| 6 | +} from "../../shared/number-coercion.js"; |
3 | 7 | import { normalizeProviderId } from "../provider-id.js"; |
4 | 8 | import { resolveProviderRequestHeaders } from "../provider-request-config.js"; |
5 | 9 | import { logAuthProfileFailureStateChange } from "./state-observation.js"; |
@@ -124,14 +128,15 @@ function resolveWhamResetMs(window: WhamUsageWindow | undefined, now: number): n
|
124 | 128 | Number.isFinite(window.reset_after_seconds) && |
125 | 129 | window.reset_after_seconds > 0 |
126 | 130 | ) { |
127 | | -return window.reset_after_seconds * 1000; |
| 131 | +return positiveSecondsToSafeMilliseconds(window.reset_after_seconds) ?? null; |
128 | 132 | } |
129 | 133 | if ( |
130 | 134 | typeof window.reset_at === "number" && |
131 | 135 | Number.isFinite(window.reset_at) && |
132 | 136 | window.reset_at > 0 |
133 | 137 | ) { |
134 | | -return Math.max(0, window.reset_at * 1000 - now); |
| 138 | +const resetAtMs = resolveExpiresAtMsFromEpochSeconds(window.reset_at); |
| 139 | +return resetAtMs === undefined ? null : Math.max(0, resetAtMs - now); |
135 | 140 | } |
136 | 141 | return null; |
137 | 142 | } |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。