feat(FN-2113): merge fusion/fn-2113
This commit is contained in:
@@ -1132,7 +1132,7 @@ describe("HeartbeatMonitor", () => {
|
|||||||
|
|
||||||
const config = monitor.getAgentHeartbeatConfig("agent-001");
|
const config = monitor.getAgentHeartbeatConfig("agent-001");
|
||||||
expect(config.heartbeatTimeoutMs).toBe(5000);
|
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
|
expect(config.maxConcurrentRuns).toBe(1); // default
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -3834,45 +3834,45 @@ describe("HeartbeatTriggerScheduler", () => {
|
|||||||
expect(scheduler.getRegisteredAgents()).not.toContain("agent-001");
|
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();
|
vi.useFakeTimers();
|
||||||
scheduler.registerAgent("agent-001", {});
|
scheduler.registerAgent("agent-001", {});
|
||||||
expect(scheduler.getRegisteredAgents()).toContain("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();
|
expect(callback).not.toHaveBeenCalled();
|
||||||
await vi.advanceTimersByTimeAsync(30_000);
|
await vi.advanceTimersByTimeAsync(3_600_000);
|
||||||
expect(callback).toHaveBeenCalledOnce();
|
expect(callback).toHaveBeenCalledOnce();
|
||||||
vi.useRealTimers();
|
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();
|
vi.useFakeTimers();
|
||||||
scheduler.registerAgent("agent-001", { heartbeatIntervalMs: 0 });
|
scheduler.registerAgent("agent-001", { heartbeatIntervalMs: 0 });
|
||||||
expect(scheduler.getRegisteredAgents()).toContain("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();
|
expect(callback).not.toHaveBeenCalled();
|
||||||
await vi.advanceTimersByTimeAsync(30_000);
|
await vi.advanceTimersByTimeAsync(3_600_000);
|
||||||
expect(callback).toHaveBeenCalledOnce();
|
expect(callback).toHaveBeenCalledOnce();
|
||||||
vi.useRealTimers();
|
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();
|
vi.useFakeTimers();
|
||||||
scheduler.registerAgent("agent-001", { enabled: true });
|
scheduler.registerAgent("agent-001", { enabled: true });
|
||||||
expect(scheduler.getRegisteredAgents()).toContain("agent-001");
|
expect(scheduler.getRegisteredAgents()).toContain("agent-001");
|
||||||
|
|
||||||
// Should fire at exactly 30 seconds (default interval)
|
// Should fire at exactly 3600 seconds (default interval)
|
||||||
await vi.advanceTimersByTimeAsync(29_999);
|
await vi.advanceTimersByTimeAsync(3_599_999);
|
||||||
expect(callback).not.toHaveBeenCalled();
|
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).toHaveBeenCalledOnce();
|
||||||
expect(callback).toHaveBeenCalledWith("agent-001", "timer", {
|
expect(callback).toHaveBeenCalledWith("agent-001", "timer", {
|
||||||
wakeReason: "timer",
|
wakeReason: "timer",
|
||||||
triggerDetail: "scheduled",
|
triggerDetail: "scheduled",
|
||||||
intervalMs: 30_000,
|
intervalMs: 3_600_000,
|
||||||
});
|
});
|
||||||
vi.useRealTimers();
|
vi.useRealTimers();
|
||||||
});
|
});
|
||||||
@@ -3882,7 +3882,7 @@ describe("HeartbeatTriggerScheduler", () => {
|
|||||||
scheduler.registerAgent("agent-001", { heartbeatIntervalMs: 15_000, enabled: true });
|
scheduler.registerAgent("agent-001", { heartbeatIntervalMs: 15_000, enabled: true });
|
||||||
expect(scheduler.getRegisteredAgents()).toContain("agent-001");
|
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);
|
await vi.advanceTimersByTimeAsync(14_999);
|
||||||
expect(callback).not.toHaveBeenCalled();
|
expect(callback).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export interface HeartbeatMonitorOptions {
|
|||||||
agentStore?: AgentStore;
|
agentStore?: AgentStore;
|
||||||
/** Optional MessageStore for wake-on-message behavior */
|
/** Optional MessageStore for wake-on-message behavior */
|
||||||
messageStore?: MessageStore;
|
messageStore?: MessageStore;
|
||||||
/** Polling interval in milliseconds (default: 30000) */
|
/** Polling interval in milliseconds (default: 3600000) */
|
||||||
pollIntervalMs?: number;
|
pollIntervalMs?: number;
|
||||||
/** Heartbeat timeout in milliseconds (default: 60000) */
|
/** Heartbeat timeout in milliseconds (default: 60000) */
|
||||||
heartbeatTimeoutMs?: number;
|
heartbeatTimeoutMs?: number;
|
||||||
@@ -247,7 +247,7 @@ export class HeartbeatMonitor {
|
|||||||
constructor(options: HeartbeatMonitorOptions) {
|
constructor(options: HeartbeatMonitorOptions) {
|
||||||
this.store = options.store;
|
this.store = options.store;
|
||||||
this.configStore = options.agentStore ?? 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.heartbeatTimeoutMs = options.heartbeatTimeoutMs ?? 60000;
|
||||||
this.maxConcurrentRuns = options.maxConcurrentRuns ?? 1;
|
this.maxConcurrentRuns = options.maxConcurrentRuns ?? 1;
|
||||||
this.onMissed = options.onMissed;
|
this.onMissed = options.onMissed;
|
||||||
@@ -1641,7 +1641,7 @@ interface AgentTimer {
|
|||||||
* const scheduler = new HeartbeatTriggerScheduler(agentStore, async (agentId, source, ctx) => {
|
* const scheduler = new HeartbeatTriggerScheduler(agentStore, async (agentId, source, ctx) => {
|
||||||
* await heartbeatMonitor.startRun(agentId, { source, triggerDetail: ctx.triggerDetail, contextSnapshot: { ...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();
|
* scheduler.start();
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
@@ -1701,8 +1701,8 @@ export class HeartbeatTriggerScheduler {
|
|||||||
return this.running;
|
return this.running;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Default heartbeat interval when not explicitly configured (30 seconds) */
|
/** Default heartbeat interval when not explicitly configured (3600 seconds / 1 hour) */
|
||||||
private static readonly DEFAULT_HEARTBEAT_INTERVAL_MS = 30_000;
|
private static readonly DEFAULT_HEARTBEAT_INTERVAL_MS = 3_600_000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register an agent for timer-based heartbeat triggers.
|
* Register an agent for timer-based heartbeat triggers.
|
||||||
|
|||||||
@@ -789,14 +789,14 @@ describe("InProcessRuntime", () => {
|
|||||||
expect(scheduler!.getRegisteredAgents()).toContain(agent.id);
|
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)
|
// 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 store = getAgentStore(runtime);
|
||||||
const agent = await store.createAgent({
|
const agent = await store.createAgent({
|
||||||
name: "test-agent-default-interval",
|
name: "test-agent-default-interval",
|
||||||
role: "executor",
|
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
|
// Verify the agent was registered with the trigger scheduler
|
||||||
|
|||||||
@@ -497,7 +497,7 @@ export class InProcessRuntime
|
|||||||
this.agentStore.on("agent:updated", this.agentUpdatedListener);
|
this.agentStore.on("agent:updated", this.agentUpdatedListener);
|
||||||
|
|
||||||
// Register existing agents with heartbeat monitoring not explicitly disabled
|
// 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 {
|
try {
|
||||||
const agents = await this.agentStore.listAgents();
|
const agents = await this.agentStore.listAgents();
|
||||||
let registeredCount = 0;
|
let registeredCount = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user