fix: context overflow compaction and subagent announce improvements (#11664) (thanks @tyler6204)

* initial commit

* feat: implement deriveSessionTotalTokens function and update usage tests

* Added deriveSessionTotalTokens function to calculate total tokens based on usage and context tokens.
* Updated usage tests to include cases for derived session total tokens.
* Refactored session usage calculations in multiple files to utilize the new function for improved accuracy.

* fix: restore overflow truncation fallback + changelog/test hardening (#11551) (thanks @tyler6204)
This commit is contained in:
Tyler Yust
2026-02-07 20:02:32 -08:00
committed by GitHub
parent 8fae55e8e0
commit 191da1feb5
31 changed files with 889 additions and 178 deletions

View File

@@ -1,6 +1,7 @@
import type { OpenClawConfig } from "../config/config.js";
const DEFAULT_AGENT_TIMEOUT_SECONDS = 600;
const MAX_SAFE_TIMEOUT_MS = 2_147_000_000;
const normalizeNumber = (value: unknown): number | undefined =>
typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : undefined;
@@ -18,10 +19,11 @@ export function resolveAgentTimeoutMs(opts: {
minMs?: number;
}): number {
const minMs = Math.max(normalizeNumber(opts.minMs) ?? 1, 1);
const defaultMs = resolveAgentTimeoutSeconds(opts.cfg) * 1000;
// Use a very large timeout value (30 days) to represent "no timeout"
// when explicitly set to 0. This avoids setTimeout issues with Infinity.
const NO_TIMEOUT_MS = 30 * 24 * 60 * 60 * 1000;
const clampTimeoutMs = (valueMs: number) =>
Math.min(Math.max(valueMs, minMs), MAX_SAFE_TIMEOUT_MS);
const defaultMs = clampTimeoutMs(resolveAgentTimeoutSeconds(opts.cfg) * 1000);
// Use the maximum timer-safe timeout to represent "no timeout" when explicitly set to 0.
const NO_TIMEOUT_MS = MAX_SAFE_TIMEOUT_MS;
const overrideMs = normalizeNumber(opts.overrideMs);
if (overrideMs !== undefined) {
if (overrideMs === 0) {
@@ -30,7 +32,7 @@ export function resolveAgentTimeoutMs(opts: {
if (overrideMs < 0) {
return defaultMs;
}
return Math.max(overrideMs, minMs);
return clampTimeoutMs(overrideMs);
}
const overrideSeconds = normalizeNumber(opts.overrideSeconds);
if (overrideSeconds !== undefined) {
@@ -40,7 +42,7 @@ export function resolveAgentTimeoutMs(opts: {
if (overrideSeconds < 0) {
return defaultMs;
}
return Math.max(overrideSeconds * 1000, minMs);
return clampTimeoutMs(overrideSeconds * 1000);
}
return Math.max(defaultMs, minMs);
return defaultMs;
}