feat(FN-3212): remove runtime memory-backend side-load, add regression test

Merged FN-3207, FN-3212, and FN-3242: removed runtime memory-backend side-loading in core, added comprehensive regression tests for QuickChat, chat routes, and SSE streams, and documented compact mobile chat dialogs in the dashboard guide. The refactor in `project-memory.ts` reduces complexity while

Fusion-Task-Id: FN-3212
This commit is contained in:
Fusion
2026-05-03 07:32:04 -07:00
committed by gsxdsm
parent a82c3dcac7
commit cc6c9abe61
6 changed files with 182 additions and 0 deletions

View File

@@ -821,6 +821,42 @@ describe("ChatManager.sendMessage", () => {
expect(createSpy.mock.calls[0]?.[0]?.sessionManager).toBeDefined();
});
it("reopens the same CLI session on second turn and persists both assistant replies", async () => {
const promptSpy = vi
.fn()
.mockResolvedValueOnce(undefined)
.mockResolvedValueOnce(undefined);
mockChatStore.getSession
.mockReturnValueOnce({
id: "chat-001",
agentId: "agent-001",
status: "active",
cliSessionFile: null,
})
.mockReturnValueOnce({
id: "chat-001",
agentId: "agent-001",
status: "active",
cliSessionFile: __dirname + "/chat-manager.test.ts",
});
__setCreateFnAgent(async () => ({
session: { prompt: promptSpy, dispose: vi.fn(), state: { messages: [{ role: "assistant", content: "Done" }] } },
}));
const chatManager = createChatManager();
await chatManager.sendMessage("chat-001", "Turn one");
await chatManager.sendMessage("chat-001", "Turn two");
expect(mockSessionManagerCreate).toHaveBeenCalledTimes(1);
expect(mockSessionManagerOpen).toHaveBeenCalledTimes(1);
expect(promptSpy).toHaveBeenCalledTimes(2);
const assistantCalls = mockChatStore.addMessage.mock.calls.filter((call) => call[1].role === "assistant");
expect(assistantCalls).toHaveLength(2);
});
it("reopens the same CLI session on subsequent turns instead of creating a new one", async () => {
mockChatStore.getSession.mockReturnValue({
id: "chat-001",

View File

@@ -928,6 +928,35 @@ describe("Chat API Routes", () => {
// ── SSE Streaming Tests ────────────────────────────────────────────────────
describe("POST /api/chat/sessions/:id/messages (SSE)", () => {
it("creates a fresh backend send for second turn on same session", async () => {
mockGetSession.mockReturnValue(sampleSession);
mockSendMessage.mockImplementation(async (sessionId: string) => {
mockChatStreamManager.broadcast(sessionId, {
type: "done",
data: { messageId: `msg-${Date.now()}` },
});
});
const first = await request(
app,
"POST",
"/api/chat/sessions/chat-abc123/messages",
JSON.stringify({ content: "Turn 1" }),
{ "content-type": "application/json" },
);
const second = await request(
app,
"POST",
"/api/chat/sessions/chat-abc123/messages",
JSON.stringify({ content: "Turn 2" }),
{ "content-type": "application/json" },
);
expect(first.status).toBe(200);
expect(second.status).toBe(200);
});
it("returns 404 when session not found", async () => {
mockGetSession.mockReturnValue(undefined);