























@@ -11,45 +11,11 @@ describe("resolveLlmIdleTimeoutMs", () => {
1111expect(resolveLlmIdleTimeoutMs()).toBe(DEFAULT_LLM_IDLE_TIMEOUT_MS);
1212});
131314-it("returns default when llm config is missing", () => {
14+it("returns default when agent defaults are missing", () => {
1515const cfg = { agents: {} } as OpenClawConfig;
1616expect(resolveLlmIdleTimeoutMs({ cfg })).toBe(DEFAULT_LLM_IDLE_TIMEOUT_MS);
1717});
181819-it("returns default when idleTimeoutSeconds is not set", () => {
20-const cfg = { agents: { defaults: { llm: {} } } } as OpenClawConfig;
21-expect(resolveLlmIdleTimeoutMs({ cfg })).toBe(DEFAULT_LLM_IDLE_TIMEOUT_MS);
22-});
23-24-it("returns 0 when idleTimeoutSeconds is 0 (disabled)", () => {
25-const cfg = { agents: { defaults: { llm: { idleTimeoutSeconds: 0 } } } } as OpenClawConfig;
26-expect(resolveLlmIdleTimeoutMs({ cfg })).toBe(0);
27-});
28-29-it("returns configured value in milliseconds", () => {
30-const cfg = { agents: { defaults: { llm: { idleTimeoutSeconds: 30 } } } } as OpenClawConfig;
31-expect(resolveLlmIdleTimeoutMs({ cfg })).toBe(30_000);
32-});
33-34-it("caps at max safe timeout", () => {
35-const cfg = {
36-agents: { defaults: { llm: { idleTimeoutSeconds: 10_000_000 } } },
37-} as OpenClawConfig;
38-expect(resolveLlmIdleTimeoutMs({ cfg })).toBe(2_147_000_000);
39-});
40-41-it("ignores negative values", () => {
42-const cfg = { agents: { defaults: { llm: { idleTimeoutSeconds: -10 } } } } as OpenClawConfig;
43-expect(resolveLlmIdleTimeoutMs({ cfg })).toBe(DEFAULT_LLM_IDLE_TIMEOUT_MS);
44-});
45-46-it("ignores non-finite values", () => {
47-const cfg = {
48-agents: { defaults: { llm: { idleTimeoutSeconds: Infinity } } },
49-} as OpenClawConfig;
50-expect(resolveLlmIdleTimeoutMs({ cfg })).toBe(DEFAULT_LLM_IDLE_TIMEOUT_MS);
51-});
52-5319it("caps agents.defaults.timeoutSeconds fallback at the default idle watchdog", () => {
5420const cfg = { agents: { defaults: { timeoutSeconds: 300 } } } as OpenClawConfig;
5521expect(resolveLlmIdleTimeoutMs({ cfg })).toBe(DEFAULT_LLM_IDLE_TIMEOUT_MS);
@@ -72,43 +38,53 @@ describe("resolveLlmIdleTimeoutMs", () => {
7238expect(resolveLlmIdleTimeoutMs({ runTimeoutMs: 2_147_000_000 })).toBe(0);
7339});
744075-it("prefers llm.idleTimeoutSeconds over agents.defaults.timeoutSeconds", () => {
76-const cfg = {
77-agents: { defaults: { timeoutSeconds: 300, llm: { idleTimeoutSeconds: 120 } } },
78-} as OpenClawConfig;
79-expect(resolveLlmIdleTimeoutMs({ cfg })).toBe(120_000);
41+it("uses the provider request timeout as the model idle watchdog", () => {
42+expect(resolveLlmIdleTimeoutMs({ modelRequestTimeoutMs: 300_000 })).toBe(300_000);
8043});
814482-it("prefers llm.idleTimeoutSeconds over an explicit run timeout override", () => {
83-const cfg = {
84-agents: { defaults: { llm: { idleTimeoutSeconds: 120 } } },
85-} as OpenClawConfig;
86-expect(resolveLlmIdleTimeoutMs({ cfg, runTimeoutMs: 900_000 })).toBe(120_000);
45+it("caps provider request timeout at the max safe timeout", () => {
46+expect(resolveLlmIdleTimeoutMs({ modelRequestTimeoutMs: 10_000_000_000 })).toBe(2_147_000_000);
8747});
884889-it("keeps idleTimeoutSeconds=0 disabled even when timeoutSeconds is set", () => {
49+it("ignores invalid provider request timeout values", () => {
50+expect(resolveLlmIdleTimeoutMs({ modelRequestTimeoutMs: -1 })).toBe(
51+DEFAULT_LLM_IDLE_TIMEOUT_MS,
52+);
53+expect(resolveLlmIdleTimeoutMs({ modelRequestTimeoutMs: Infinity })).toBe(
54+DEFAULT_LLM_IDLE_TIMEOUT_MS,
55+);
56+});
57+58+it("bounds provider request timeout by agents.defaults.timeoutSeconds when shorter", () => {
9059const cfg = {
91-agents: { defaults: { timeoutSeconds: 300, llm: { idleTimeoutSeconds: 0 } } },
60+agents: { defaults: { timeoutSeconds: 45 } },
9261} as OpenClawConfig;
93-expect(resolveLlmIdleTimeoutMs({ cfg })).toBe(0);
62+expect(resolveLlmIdleTimeoutMs({ cfg, modelRequestTimeoutMs: 300_000 })).toBe(45_000);
63+});
64+65+it("bounds provider request timeout by explicit run timeout when shorter", () => {
66+expect(resolveLlmIdleTimeoutMs({ modelRequestTimeoutMs: 300_000, runTimeoutMs: 45_000 })).toBe(
67+45_000,
68+);
69+});
70+71+it("uses provider request timeout for cron model calls", () => {
72+expect(resolveLlmIdleTimeoutMs({ trigger: "cron", modelRequestTimeoutMs: 300_000 })).toBe(
73+300_000,
74+);
9475});
95769677it("disables the default idle timeout for cron when no timeout is configured", () => {
9778expect(resolveLlmIdleTimeoutMs({ trigger: "cron" })).toBe(0);
987999-const cfg = { agents: { defaults: { llm: {} } } } as OpenClawConfig;
80+const cfg = { agents: { defaults: {} } } as OpenClawConfig;
10081expect(resolveLlmIdleTimeoutMs({ cfg, trigger: "cron" })).toBe(0);
10182});
1028310384it("caps agents.defaults.timeoutSeconds for cron before disabling the default idle timeout", () => {
10485const cfg = { agents: { defaults: { timeoutSeconds: 300 } } } as OpenClawConfig;
10586expect(resolveLlmIdleTimeoutMs({ cfg, trigger: "cron" })).toBe(DEFAULT_LLM_IDLE_TIMEOUT_MS);
10687});
107-108-it("keeps an explicit cron idle timeout when configured", () => {
109-const cfg = { agents: { defaults: { llm: { idleTimeoutSeconds: 45 } } } } as OpenClawConfig;
110-expect(resolveLlmIdleTimeoutMs({ cfg, trigger: "cron" })).toBe(45_000);
111-});
11288});
1138911490describe("streamWithIdleTimeout", () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。