
























@@ -27,6 +27,7 @@ const ISSUE_FILE_COUNTS = [
2727const ISSUE_MEMORY_FILE_COUNT = ISSUE_FILE_COUNTS.reduce((sum, [, count]) => sum + count, 0);
2828const DEFAULT_FILE_COUNT = 512;
2929const DEFAULT_MAX_WORKSPACE_REG_FDS = process.platform === "darwin" ? 8 : 64;
30+const MAX_TIMER_TIMEOUT_MS = 2_147_000_000;
3031/**
3132 * Maximum gateway-ready output tail retained while waiting for startup.
3233 */
@@ -134,6 +135,24 @@ function readPositiveNumberEnv(name, fallback) {
134135return raw == null || raw.trim() === "" ? fallback : readPositiveNumber(raw, name);
135136}
136137138+function clampTimerTimeoutMs(valueMs, minMs = 1) {
139+const min = Math.max(0, Math.floor(minMs));
140+const value = Number.isFinite(valueMs) ? valueMs : min;
141+return Math.min(Math.max(Math.floor(value), min), MAX_TIMER_TIMEOUT_MS);
142+}
143+144+function readTimerTimeoutNumber(value, label, minMs = 1) {
145+const parsed = minMs > 0 ? readPositiveNumber(value, label) : readNumber(value, label);
146+return clampTimerTimeoutMs(parsed, minMs);
147+}
148+149+function readTimerTimeoutNumberEnv(name, fallback, minMs = 1) {
150+const raw = process.env[name];
151+return raw == null || raw.trim() === ""
152+ ? clampTimerTimeoutMs(fallback, minMs)
153+ : readTimerTimeoutNumber(raw, name, minMs);
154+}
155+137156/**
138157 * Parses memory FD repro CLI arguments and environment fallbacks.
139158 */
@@ -192,13 +211,13 @@ export function parseArgs(argv) {
192211options.minLeakedFds = readPositiveNumber(readValue(), "--min-leaked-fds");
193212break;
194213case "--invoke-timeout-ms":
195-options.invokeTimeoutMs = readPositiveNumber(readValue(), "--invoke-timeout-ms");
214+options.invokeTimeoutMs = readTimerTimeoutNumber(readValue(), "--invoke-timeout-ms");
196215break;
197216case "--sample-delay-ms":
198-options.sampleDelayMs = readNumber(readValue(), "--sample-delay-ms");
217+options.sampleDelayMs = readTimerTimeoutNumber(readValue(), "--sample-delay-ms", 0);
199218break;
200219case "--settle-delay-ms":
201-options.settleDelayMs = readNumber(readValue(), "--settle-delay-ms");
220+options.settleDelayMs = readTimerTimeoutNumber(readValue(), "--settle-delay-ms", 0);
202221break;
203222case "--output-dir":
204223options.outputDir = path.resolve(readValue());
@@ -222,9 +241,17 @@ export function parseArgs(argv) {
222241"OPENCLAW_MEMORY_FD_REPRO_MAX_WORKSPACE_REG_FDS",
223242DEFAULT_MAX_WORKSPACE_REG_FDS,
224243);
225-options.invokeTimeoutMs ??= readPositiveNumberEnv("OPENCLAW_MEMORY_FD_REPRO_TIMEOUT_MS", 30_000);
226-options.sampleDelayMs ??= readNumberEnv("OPENCLAW_MEMORY_FD_REPRO_SAMPLE_DELAY_MS", 1_000);
227-options.settleDelayMs ??= readNumberEnv("OPENCLAW_MEMORY_FD_REPRO_SETTLE_DELAY_MS", 5_000);
244+options.invokeTimeoutMs ??= readTimerTimeoutNumberEnv("OPENCLAW_MEMORY_FD_REPRO_TIMEOUT_MS", 30_000);
245+options.sampleDelayMs ??= readTimerTimeoutNumberEnv(
246+"OPENCLAW_MEMORY_FD_REPRO_SAMPLE_DELAY_MS",
247+1_000,
248+0,
249+);
250+options.settleDelayMs ??= readTimerTimeoutNumberEnv(
251+"OPENCLAW_MEMORY_FD_REPRO_SETTLE_DELAY_MS",
252+5_000,
253+0,
254+);
228255if (!Number.isFinite(options.fileCount) || options.fileCount <= 0) {
229256throw new Error("file count must be greater than 0");
230257}
@@ -243,7 +270,7 @@ function logStep(message) {
243270244271function sleep(ms) {
245272return new Promise((resolve) => {
246-setTimeout(resolve, ms);
273+setTimeout(resolve, clampTimerTimeoutMs(ms, 0));
247274});
248275}
249276@@ -676,9 +703,10 @@ export function classifyMemorySearchInvokeResponse({ httpOk, status, bodyText })
676703};
677704}
678705679-async function invokeMemorySearch({ port, token, timeoutMs }) {
706+export async function invokeMemorySearch({ port, token, timeoutMs }) {
707+const resolvedTimeoutMs = clampTimerTimeoutMs(timeoutMs);
680708const controller = new AbortController();
681-const timer = setTimeout(() => controller.abort(), timeoutMs);
709+const timer = setTimeout(() => controller.abort(), resolvedTimeoutMs);
682710const startedAt = Date.now();
683711try {
684712const res = await fetch(`http://127.0.0.1:${port}/tools/invoke`, {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。