diff --git a/scripts/lib/ci-node-test-plan.mjs b/scripts/lib/ci-node-test-plan.mjs index 5a789c85610e..926f515170d5 100644 --- a/scripts/lib/ci-node-test-plan.mjs +++ b/scripts/lib/ci-node-test-plan.mjs @@ -30,6 +30,11 @@ const GATEWAY_STARTUP_CORE_RUNNER = DEFAULT_NODE_TEST_RUNNER; const GATEWAY_STARTUP_HEALTH_RUNTIME_ENV = { OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "60000", }; +// The first embedded-agent file owns 157 serial tests and can stay quiet for +// more than five minutes on a cold GitHub-hosted 4-vCPU fork runner. +const AGENTS_EMBEDDED_AGENT_ENV = { + OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "420000", +}; const MAX_BUNDLED_NODE_TEST_PATTERNS = 64; // PR-only bundles trade a little serial work for fewer ephemeral runner registrations. // Keep runner classes and subprocess isolation intact while bounding each combined job. @@ -71,7 +76,9 @@ const COMPACT_GROUP_SECONDS_HINTS = new Map([ ["agentic-agents-core-runtime", 79], ["agentic-agents-core-subagents", 32], ["agentic-agents-core-tools", 52], - ["agentic-agents-embedded", 57], + // A cold fork run is about 430s and emits no file result for most of its + // first five minutes. Keep this whole-config whale in its own compact job. + ["agentic-agents-embedded", 430], ["agentic-agents-support", 105], ["agentic-agents-tools", 42], ["agentic-cli", 72], @@ -1183,6 +1190,7 @@ const SPLIT_NODE_SHARDS = new Map([ { shardName: "agentic-agents-embedded", configs: ["test/vitest/vitest.agents-embedded-agent.config.ts"], + env: AGENTS_EMBEDDED_AGENT_ENV, requiresDist: false, }, { diff --git a/src/agents/embedded-agent-runner/run.incomplete-turn.test.ts b/src/agents/embedded-agent-runner/run.incomplete-turn.test.ts index 949046af360f..b6897a3a3774 100644 --- a/src/agents/embedded-agent-runner/run.incomplete-turn.test.ts +++ b/src/agents/embedded-agent-runner/run.incomplete-turn.test.ts @@ -50,6 +50,10 @@ const SETTLED_TOOL_TERMINAL_CONTINUATION_INSTRUCTION = let runEmbeddedAgent: typeof import("./run.js").runEmbeddedAgent; +// Cold GitHub-hosted fork runners can spend more than five minutes loading and +// warming this broad harness before the first test reports progress. +const COLD_FORK_RUNNER_HOOK_TIMEOUT_MS = 420_000; + function resolveIncompleteTurnPayloadText( params: Omit[0], "externalAbort"> & { externalAbort?: boolean; @@ -64,7 +68,7 @@ describe("runEmbeddedAgent incomplete-turn safety", () => { beforeAll(async () => { ({ runEmbeddedAgent } = await loadRunOverflowCompactionHarness()); await warmRunOverflowCompactionHarness(runEmbeddedAgent); - }, 300_000); + }, COLD_FORK_RUNNER_HOOK_TIMEOUT_MS); beforeEach(() => { resetRunOverflowCompactionHarnessMocks(); diff --git a/test/scripts/ci-node-test-plan.test.ts b/test/scripts/ci-node-test-plan.test.ts index d83e7820b799..354c5df2613a 100644 --- a/test/scripts/ci-node-test-plan.test.ts +++ b/test/scripts/ci-node-test-plan.test.ts @@ -299,6 +299,13 @@ describe("scripts/lib/ci-node-test-plan.mjs", () => { .flatMap((shard) => shard.groups) .find((group) => group.shard_name === "agentic-control-plane-startup-health-runtime")?.env, ).toEqual({ OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "60000" }); + const embeddedAgentJob = compact.find((shard) => + shard.groups.some((group) => group.shard_name === "agentic-agents-embedded"), + ); + expect(embeddedAgentJob?.groups).toHaveLength(1); + expect(embeddedAgentJob?.groups[0]?.env).toEqual({ + OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "420000", + }); expect( compact .filter((shard) => shard.groups.some((group) => !group.includePatterns)) @@ -997,6 +1004,7 @@ describe("scripts/lib/ci-node-test-plan.mjs", () => { { checkName: "checks-node-agentic-agents-embedded", configs: ["test/vitest/vitest.agents-embedded-agent.config.ts"], + env: { OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "420000" }, requiresDist: false, runner: DEFAULT_NODE_TEST_RUNNER, shardName: "agentic-agents-embedded",