Require actionable work for timer heartbeats

This commit is contained in:
Dotta committed 2026-07-01 19:12:59 +00:00
1 parent 2e16d218b1
commit 4b9f8165c5
4 files changed
+22 -3

No files matched your search

@@ -393,7 +393,7 @@ describeEmbeddedPostgres("heartbeat stale queued-run invalidation", () => {
expect(countExecuteCallsForRun(run!.id)).toBe(1);
});
it("runs generic timer wakes by default for proactive agents without assigned issue work", async () => {
it("skips generic timer wakes by default when there is no assigned issue work", async () => {
const { agentId } = await seedCompanyAndAgent({
heartbeatConfig: {
enabled: true,
@@ -405,9 +405,25 @@ describeEmbeddedPostgres("heartbeat stale queued-run invalidation", () => {
triggerDetail: "schedule",
});
expect(run).toBeNull();
expect(mockAdapterExecute).not.toHaveBeenCalled();
});
it("allows explicit proactive generic timer wakes without assigned issue work", async () => {
const { agentId } = await seedCompanyAndAgent({
heartbeatConfig: {
enabled: true,
skipTimerWhenNoActionableWork: false,
},
});
const run = await heartbeat.wakeup(agentId, {
source: "timer",
triggerDetail: "schedule",
});
expect(run).not.toBeNull();
await waitForCondition(async () => countExecuteCallsForRun(run!.id) > 0);
expect(countExecuteCallsForRun(run!.id)).toBe(1);
});
+1 -1
View File
@@ -7996,7 +7996,7 @@ export function heartbeatService(db: Db, options: HeartbeatServiceOptions = {})
heartbeat.skipTimerWhenNoActionableWork ??
heartbeat.requireActionableTimerWork ??
heartbeat.issueOnlyTimer,
false,
true,
),
maxDailyRuns: normalizeOptionalNonNegativeInteger(
heartbeat.maxDailyRuns ?? heartbeat.dailyRunLimit ?? heartbeat.dailyRunCap ?? heartbeat.maxRunsPerDay,
@@ -10,6 +10,7 @@ describe("buildNewAgentRuntimeConfig", () => {
enabled: false,
intervalSec: 300,
wakeOnDemand: true,
skipTimerWhenNoActionableWork: true,
cooldownSec: 10,
maxConcurrentRuns: AGENT_DEFAULT_MAX_CONCURRENT_RUNS,
},
@@ -27,6 +28,7 @@ describe("buildNewAgentRuntimeConfig", () => {
enabled: true,
intervalSec: 3600,
wakeOnDemand: true,
skipTimerWhenNoActionableWork: true,
cooldownSec: 10,
maxConcurrentRuns: AGENT_DEFAULT_MAX_CONCURRENT_RUNS,
},
+1
View File
@@ -12,6 +12,7 @@ export function buildNewAgentRuntimeConfig(input?: {
enabled: input?.heartbeatEnabled ?? defaultCreateValues.heartbeatEnabled,
intervalSec: input?.intervalSec ?? defaultCreateValues.intervalSec,
wakeOnDemand: true,
skipTimerWhenNoActionableWork: true,
cooldownSec: 10,
maxConcurrentRuns: AGENT_DEFAULT_MAX_CONCURRENT_RUNS,
},