Cron: route reminders by session namespace

This commit is contained in:
Vignesh Natarajan
2026-02-16 14:29:21 -08:00
committed by Peter Steinberger
parent f452a7a60b
commit f988abf202
19 changed files with 530 additions and 32 deletions

View File

@@ -1,6 +1,7 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import { startHeartbeatRunner } from "./heartbeat-runner.js";
import { requestHeartbeatNow, resetHeartbeatWakeStateForTests } from "./heartbeat-wake.js";
describe("startHeartbeatRunner", () => {
function startDefaultRunner(runOnce: (typeof startHeartbeatRunner)[0]["runOnce"]) {
@@ -13,6 +14,7 @@ describe("startHeartbeatRunner", () => {
}
afterEach(() => {
resetHeartbeatWakeStateForTests();
vi.useRealTimers();
vi.restoreAllMocks();
});
@@ -162,4 +164,42 @@ describe("startHeartbeatRunner", () => {
runner.stop();
});
it("routes targeted wake requests to the requested agent/session", async () => {
vi.useFakeTimers();
vi.setSystemTime(new Date(0));
const runSpy = vi.fn().mockResolvedValue({ status: "ran", durationMs: 1 });
const runner = startHeartbeatRunner({
cfg: {
agents: {
defaults: { heartbeat: { every: "30m" } },
list: [
{ id: "main", heartbeat: { every: "30m" } },
{ id: "ops", heartbeat: { every: "15m" } },
],
},
} as OpenClawConfig,
runOnce: runSpy,
});
requestHeartbeatNow({
reason: "cron:job-123",
agentId: "ops",
sessionKey: "agent:ops:discord:channel:alerts",
coalesceMs: 0,
});
await vi.advanceTimersByTimeAsync(1);
expect(runSpy).toHaveBeenCalledTimes(1);
expect(runSpy).toHaveBeenCalledWith(
expect.objectContaining({
agentId: "ops",
reason: "cron:job-123",
sessionKey: "agent:ops:discord:channel:alerts",
}),
);
runner.stop();
});
});