feat(FN-2113): merge fusion/fn-2113

This commit is contained in:
gsxdsm
2026-04-19 05:07:00 -07:00
parent a956ce5a4f
commit 59fbdc8dab
4 changed files with 22 additions and 22 deletions

View File

@@ -1132,7 +1132,7 @@ describe("HeartbeatMonitor", () => {
const config = monitor.getAgentHeartbeatConfig("agent-001");
expect(config.heartbeatTimeoutMs).toBe(5000);
expect(config.pollIntervalMs).toBe(30000); // default
expect(config.pollIntervalMs).toBe(3_600_000); // default
expect(config.maxConcurrentRuns).toBe(1); // default
});
@@ -3834,45 +3834,45 @@ describe("HeartbeatTriggerScheduler", () => {
expect(scheduler.getRegisteredAgents()).not.toContain("agent-001");
});
it("applies default 30-second interval when intervalMs is undefined", async () => {
it("applies default 3600-second interval when intervalMs is undefined", async () => {
vi.useFakeTimers();
scheduler.registerAgent("agent-001", {});
expect(scheduler.getRegisteredAgents()).toContain("agent-001");
// Verify the default 30-second interval fires
// Verify the default 3600-second interval fires
expect(callback).not.toHaveBeenCalled();
await vi.advanceTimersByTimeAsync(30_000);
await vi.advanceTimersByTimeAsync(3_600_000);
expect(callback).toHaveBeenCalledOnce();
vi.useRealTimers();
});
it("applies default 30-second interval when intervalMs is 0", async () => {
it("applies default 3600-second interval when intervalMs is 0", async () => {
vi.useFakeTimers();
scheduler.registerAgent("agent-001", { heartbeatIntervalMs: 0 });
expect(scheduler.getRegisteredAgents()).toContain("agent-001");
// Verify the default 30-second interval fires
// Verify the default 3600-second interval fires
expect(callback).not.toHaveBeenCalled();
await vi.advanceTimersByTimeAsync(30_000);
await vi.advanceTimersByTimeAsync(3_600_000);
expect(callback).toHaveBeenCalledOnce();
vi.useRealTimers();
});
it("applies default 30-second interval when heartbeatIntervalMs is not set", async () => {
it("applies default 3600-second interval when heartbeatIntervalMs is not set", async () => {
vi.useFakeTimers();
scheduler.registerAgent("agent-001", { enabled: true });
expect(scheduler.getRegisteredAgents()).toContain("agent-001");
// Should fire at exactly 30 seconds (default interval)
await vi.advanceTimersByTimeAsync(29_999);
// Should fire at exactly 3600 seconds (default interval)
await vi.advanceTimersByTimeAsync(3_599_999);
expect(callback).not.toHaveBeenCalled();
await vi.advanceTimersByTimeAsync(1); // Now at exactly 30 seconds
await vi.advanceTimersByTimeAsync(1); // Now at exactly 3600 seconds
expect(callback).toHaveBeenCalledOnce();
expect(callback).toHaveBeenCalledWith("agent-001", "timer", {
wakeReason: "timer",
triggerDetail: "scheduled",
intervalMs: 30_000,
intervalMs: 3_600_000,
});
vi.useRealTimers();
});
@@ -3882,7 +3882,7 @@ describe("HeartbeatTriggerScheduler", () => {
scheduler.registerAgent("agent-001", { heartbeatIntervalMs: 15_000, enabled: true });
expect(scheduler.getRegisteredAgents()).toContain("agent-001");
// Should fire at 15 seconds (explicit), not 30
// Should fire at 15 seconds (explicit), not 3600
await vi.advanceTimersByTimeAsync(14_999);
expect(callback).not.toHaveBeenCalled();

View File

@@ -46,7 +46,7 @@ export interface HeartbeatMonitorOptions {
agentStore?: AgentStore;
/** Optional MessageStore for wake-on-message behavior */
messageStore?: MessageStore;
/** Polling interval in milliseconds (default: 30000) */
/** Polling interval in milliseconds (default: 3600000) */
pollIntervalMs?: number;
/** Heartbeat timeout in milliseconds (default: 60000) */
heartbeatTimeoutMs?: number;
@@ -247,7 +247,7 @@ export class HeartbeatMonitor {
constructor(options: HeartbeatMonitorOptions) {
this.store = options.store;
this.configStore = options.agentStore ?? options.store;
this.pollIntervalMs = options.pollIntervalMs ?? 30000;
this.pollIntervalMs = options.pollIntervalMs ?? 3_600_000;
this.heartbeatTimeoutMs = options.heartbeatTimeoutMs ?? 60000;
this.maxConcurrentRuns = options.maxConcurrentRuns ?? 1;
this.onMissed = options.onMissed;
@@ -1641,7 +1641,7 @@ interface AgentTimer {
* const scheduler = new HeartbeatTriggerScheduler(agentStore, async (agentId, source, ctx) => {
* await heartbeatMonitor.startRun(agentId, { source, triggerDetail: ctx.triggerDetail, contextSnapshot: { ...ctx } });
* });
* scheduler.registerAgent("agent-123", { heartbeatIntervalMs: 30000, enabled: true });
* scheduler.registerAgent("agent-123", { heartbeatIntervalMs: 3600000, enabled: true });
* scheduler.start();
* ```
*/
@@ -1701,8 +1701,8 @@ export class HeartbeatTriggerScheduler {
return this.running;
}
/** Default heartbeat interval when not explicitly configured (30 seconds) */
private static readonly DEFAULT_HEARTBEAT_INTERVAL_MS = 30_000;
/** Default heartbeat interval when not explicitly configured (3600 seconds / 1 hour) */
private static readonly DEFAULT_HEARTBEAT_INTERVAL_MS = 3_600_000;
/**
* Register an agent for timer-based heartbeat triggers.

View File

@@ -789,14 +789,14 @@ describe("InProcessRuntime", () => {
expect(scheduler!.getRegisteredAgents()).toContain(agent.id);
});
it("registers agent without explicit heartbeatIntervalMs using default 30s interval", async () => {
it("registers agent without explicit heartbeatIntervalMs using default 3600s interval", async () => {
// Create a new agent with only enabled: true (no heartbeatIntervalMs)
// This tests that the default 30-second interval is applied
// This tests that the default 3600-second interval (1 hour) is applied
const store = getAgentStore(runtime);
const agent = await store.createAgent({
name: "test-agent-default-interval",
role: "executor",
runtimeConfig: { enabled: true }, // No heartbeatIntervalMs - should use default 30s
runtimeConfig: { enabled: true }, // No heartbeatIntervalMs - should use default 3600s (1 hour)
});
// Verify the agent was registered with the trigger scheduler

View File

@@ -497,7 +497,7 @@ export class InProcessRuntime
this.agentStore.on("agent:updated", this.agentUpdatedListener);
// Register existing agents with heartbeat monitoring not explicitly disabled
// Agents without explicit heartbeat config will use the default 30-second interval
// Agents without explicit heartbeat config will use the default 3600-second interval (1 hour)
try {
const agents = await this.agentStore.listAgents();
let registeredCount = 0;