feat(FN-3959): add heartbeat timer registration repair sweep

Heartbeat timer repair sweep — adds a registration repair mechanism that detects and flags stale timers via agent updates, with tests covering the new sweep behavior. Documentation updated in agents.md to reflect the repair flow.

Fusion-Task-Id: FN-3959

Fusion-Task-Lineage: 40708b6b-01e1-4673-93e1-299678de2879
This commit is contained in:
Fusion
2026-05-11 15:18:40 -07:00
committed by gsxdsm
parent 1f47e137f7
commit 3f6c4c688a
6 changed files with 193 additions and 111 deletions

View File

@@ -13,6 +13,7 @@ import { createSSE, disconnectSSEClient, markSSEClientAlive } from "./sse.js";
import { rateLimit, RATE_LIMITS } from "./rate-limit.js";
import { ApiError, sendErrorResponse } from "./api-error.js";
import { getOrCreateProjectStore, evictAllProjectStores, setOnProjectFirstCreated } from "./project-store-resolver.js";
import { getOrCreateScopedChatStore } from "./chat-project-services.js";
import { getTerminalService, STALE_SESSION_THRESHOLD_MS } from "./terminal-service.js";
import { WebSocketServer, type WebSocket } from "ws";
import { terminalSessionManager } from "./terminal.js";
@@ -660,15 +661,18 @@ export function createServer(store: TaskStore, options?: ServerOptions): ReturnT
let agentStore;
let messageStore: MessageStore | undefined;
let automationStore: AutomationStore | undefined;
let scopedChatStore = chatStore;
if (engineManager) {
const engine = engineManager.getEngine(projectId);
scopedStore = engine?.getTaskStore() ?? await getOrCreateProjectStore(projectId);
scopedChatStore = getOrCreateScopedChatStore(scopedStore);
// Use the engine's stores if available
agentStore = engine?.getAgentStore();
messageStore = engine?.getMessageStore();
automationStore = engine?.getAutomationStore();
} else {
scopedStore = await getOrCreateProjectStore(projectId);
scopedChatStore = getOrCreateScopedChatStore(scopedStore);
}
// Fallback: create AgentStore if engine doesn't have one
if (!agentStore) {
@@ -689,7 +693,7 @@ export function createServer(store: TaskStore, options?: ServerOptions): ReturnT
},
agentStore,
messageStore,
chatStore,
scopedChatStore,
automationStore,
)(req, res);
} catch (err: unknown) {