Files
openclaw/src/agents/subagent-run-timeout.test.ts
Masato Hoshino 153ee2abba fix(subagents): killed subagent runs stay running in the task list (#99806)
* fix(subagents): reconcile killed task outcomes

Co-authored-by: masatohoshino <g515hoshino@gmail.com>

* fix(subagents): retain reconciliation marker narrowing

* fix(subagents): honor generations in latest-run views

* test(subagents): align reconciliation fixtures

* fix(subagents): keep steer recovery best effort

* style(tasks): use type-only runtime contract import

* refactor(subagents): keep generation ordering leaf-only

* fix(subagents): sanitize persisted task owner ids

* fix(subagents): preserve failed replay lifecycle reason

* fix(agents): clear killed lifecycle timeout grace

* fix(tasks): preserve canonical subagent outcomes

* fix(agents): continue requester-wide cancellation

* fix(agents): fence yield revival races

* test(agents): mock detached task lookup

* fix: fence subagent cleanup deletion

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-05 02:17:10 -07:00

54 lines
1.9 KiB
TypeScript

// Subagent run timeout tests keep semantic deadlines separate from the maximum
// delay that Node timers can safely schedule.
import { describe, expect, it } from "vitest";
import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js";
import {
resolveSubagentRunDeadlineMs,
resolveSubagentRunDurationMs,
resolveSubagentRunEffectiveEndedAt,
resolveSubagentRunTimerDelayMs,
} from "./subagent-run-timeout.js";
describe("subagent run timeout helpers", () => {
it("preserves semantic deadlines longer than the timer cap", () => {
const thirtyDaysSeconds = 30 * 24 * 60 * 60;
expect(resolveSubagentRunDurationMs(thirtyDaysSeconds)).toBe(2_592_000_000);
expect(
resolveSubagentRunDeadlineMs({
createdAt: 1_000,
runTimeoutSeconds: thirtyDaysSeconds,
}),
).toBe(2_592_001_000);
});
it("caps actual timer delays without shortening semantic durations", () => {
// Long-lived subagent runs retain their requested deadline even though the
// watchdog timer must be scheduled in bounded chunks.
const thirtyDaysSeconds = 30 * 24 * 60 * 60;
expect(resolveSubagentRunTimerDelayMs(thirtyDaysSeconds)).toBe(MAX_TIMER_TIMEOUT_MS);
expect(resolveSubagentRunDurationMs(thirtyDaysSeconds)).toBeGreaterThan(MAX_TIMER_TIMEOUT_MS);
});
it("clamps delayed terminal observations to the explicit deadline", () => {
expect(
resolveSubagentRunEffectiveEndedAt(
{ createdAt: 1_000, startedAt: 2_000, runTimeoutSeconds: 3 },
6_000,
),
).toBe(5_000);
});
it("ignores invalid timeout seconds and invalid start timestamps", () => {
expect(resolveSubagentRunDurationMs(Number.NaN)).toBeUndefined();
expect(resolveSubagentRunDurationMs(0)).toBeUndefined();
expect(
resolveSubagentRunDeadlineMs({
createdAt: Number.POSITIVE_INFINITY,
runTimeoutSeconds: 60,
}),
).toBeUndefined();
});
});