feat(FN-1975): stream chat session updates through SSE

- Emit chat:session:updated from ChatStore when message deletion mutates a session and cover deleteMessage false returns
- Pass ChatStore into SSE setup and forward chat session update events to connected clients
- Update useChat to consume SSE updates in real time with safer EnrichedChatSession typing
- Add core and dashboard tests for chat-store emissions, SSE forwarding, route wiring, and hook behavior
This commit is contained in:
Fusion
2026-04-18 00:44:27 -07:00
committed by gsxdsm
parent 03f4e7fe44
commit 430f7cf39d
12 changed files with 692 additions and 7 deletions

View File

@@ -413,6 +413,9 @@ export function createServer(store: TaskStore, options?: ServerOptions): ReturnT
app.use(express.static(clientDir));
}
// Create ChatStore for chat session management (available for SSE event forwarding)
const chatStore = options?.chatStore ?? new ChatStore(store.getFusionDir(), store.getDatabase());
// Rate limiting — stricter limit on SSE connections
app.get("/api/events", rateLimit(RATE_LIMITS.sse), async (req, res) => {
const projectId = typeof req.query.projectId === "string" ? req.query.projectId : undefined;
@@ -432,6 +435,7 @@ export function createServer(store: TaskStore, options?: ServerOptions): ReturnT
undefined,
defaultAgentStore,
defaultMessageStore,
chatStore,
)(req, res);
return;
}
@@ -468,6 +472,7 @@ export function createServer(store: TaskStore, options?: ServerOptions): ReturnT
},
agentStore,
messageStore,
chatStore,
)(req, res);
} catch (err: unknown) {
sendErrorResponse(res, 500, err instanceof Error ? err.message : "Failed to open project event stream");
@@ -655,9 +660,6 @@ export function createServer(store: TaskStore, options?: ServerOptions): ReturnT
);
}
// Create ChatStore for chat session management
const chatStore = options?.chatStore ?? new ChatStore(store.getFusionDir(), store.getDatabase());
// Create AgentStore for chat prompt enrichment (initialized lazily by ChatManager)
const chatAgentStore = new AgentStore({ rootDir: store.getFusionDir() });