



























@@ -3,6 +3,7 @@ import {
33asDateTimestampMs,
44isFutureDateTimestampMs,
55positiveSecondsToSafeMilliseconds,
6+resolveExpiresAtMsFromDurationMs,
67resolveExpiresAtMsFromEpochSeconds,
78} from "@openclaw/normalization-core/number-coercion";
89import type { OpenClawConfig } from "../../config/types.openclaw.js";
@@ -127,6 +128,15 @@ function resolveActiveWindowUntil(value: unknown, now: number): number {
127128return timestampMs !== undefined && timestampMs > now ? timestampMs : 0;
128129}
129130131+function resolveUsageWindowUntil(now: number, durationMs: number): number {
132+if (!Number.isFinite(durationMs) || durationMs <= 0) {
133+return now;
134+}
135+return (
136+resolveExpiresAtMsFromDurationMs(Math.max(1, Math.floor(durationMs)), { nowMs: now }) ?? now
137+);
138+}
139+130140function resolveWhamResetMs(window: WhamUsageWindow | undefined, now: number): number | null {
131141if (!window) {
132142return null;
@@ -192,7 +202,10 @@ function applyWhamCooldownResult(params: {
192202}
193203return {
194204 ...params.computed,
195-cooldownUntil: Math.max(existingActiveCooldownUntil, params.now + params.whamResult.cooldownMs),
205+cooldownUntil: Math.max(
206+existingActiveCooldownUntil,
207+resolveUsageWindowUntil(params.now, params.whamResult.cooldownMs),
208+),
196209};
197210}
198211@@ -263,7 +276,7 @@ async function probeWhamForCooldown(
263276}
264277return {
265278cooldownMs: WHAM_BURST_COOLDOWN_MS,
266-blockedUntil: now + primaryResetMs,
279+blockedUntil: resolveUsageWindowUntil(now, primaryResetMs),
267280blockedSource: "wham",
268281reason: "wham_personal_rolling",
269282};
@@ -275,7 +288,7 @@ async function probeWhamForCooldown(
275288}
276289return {
277290cooldownMs: WHAM_BURST_COOLDOWN_MS,
278-blockedUntil: now + secondaryResetMs,
291+blockedUntil: resolveUsageWindowUntil(now, secondaryResetMs),
279292blockedSource: "wham",
280293reason: "wham_team_weekly",
281294};
@@ -287,7 +300,7 @@ async function probeWhamForCooldown(
287300}
288301return {
289302cooldownMs: WHAM_BURST_COOLDOWN_MS,
290-blockedUntil: now + primaryResetMs,
303+blockedUntil: resolveUsageWindowUntil(now, primaryResetMs),
291304blockedSource: "wham",
292305reason: "wham_team_rolling",
293306};
@@ -615,7 +628,7 @@ function computeNextProfileUsageStats(params: {
615628updatedStats.disabledUntil = keepActiveWindowOrRecompute({
616629existingUntil: params.existing.disabledUntil,
617630now: params.now,
618-recomputedUntil: params.now + backoffMs,
631+recomputedUntil: resolveUsageWindowUntil(params.now, backoffMs),
619632});
620633updatedStats.disabledReason = disabledFailureReason;
621634} else {
@@ -625,7 +638,7 @@ function computeNextProfileUsageStats(params: {
625638updatedStats.cooldownUntil = keepActiveWindowOrRecompute({
626639existingUntil: params.existing.cooldownUntil,
627640now: params.now,
628-recomputedUntil: params.now + backoffMs,
641+recomputedUntil: resolveUsageWindowUntil(params.now, backoffMs),
629642});
630643// Update cooldown metadata based on whether the window is still active
631644// and whether the same or a different model is failing.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。