diff --git a/packages/api/src/agents/subagentThreads.spec.ts b/packages/api/src/agents/subagentThreads.spec.ts index 27fd1eb03a..cd78101cd3 100644 --- a/packages/api/src/agents/subagentThreads.spec.ts +++ b/packages/api/src/agents/subagentThreads.spec.ts @@ -1224,7 +1224,12 @@ describe('SubagentThreadTaskStore', () => { return methods.getMessages(...args); }), }; - const options = { leaseTtlMs: 500, leaseHeartbeatMs: 50 }; + /** The heartbeat fences itself when a renewal commits after the deadline it was + * issued against, so the TTL is this test's tolerance for runner jitter, not just + * its pace. Keep it well above the scheduling stalls a loaded shard produces: a + * half-second lease turns an ordinary pause into a lapse and the prepared run is + * refused instead of executed. */ + const options = { leaseTtlMs: 2_000, leaseHeartbeatMs: 50 }; const firstWorker = new SubagentThreadTaskStore(slowMethods, options); const secondWorker = new SubagentThreadTaskStore(methods, options); const config = buildSubagentThreadTaskConfig(firstWorker, { userId, parentConversationId }); @@ -1250,8 +1255,9 @@ describe('SubagentThreadTaskStore', () => { const heartbeatIndex = heartbeatCall == null ? -1 : intervalSpy.mock.calls.indexOf(heartbeatCall); const heartbeat = intervalSpy.mock.results[heartbeatIndex]?.value as NodeJS.Timeout | undefined; - const warningIndex = timeoutSpy.mock.calls.length - 1; - expect(timeoutSpy.mock.calls[warningIndex]?.[1]).toBe(5_000); + const warningCall = [...timeoutSpy.mock.calls].reverse().find(([, delay]) => delay === 5_000); + const warningIndex = warningCall == null ? -1 : timeoutSpy.mock.calls.lastIndexOf(warningCall); + expect(warningCall?.[1]).toBe(5_000); const warning = timeoutSpy.mock.results[warningIndex]?.value as NodeJS.Timeout | undefined; expect(heartbeat?.hasRef()).toBe(true); expect(warning?.hasRef()).toBe(true);