feat(FN-3432): document chat streaming recovery guarantees in architecture

Added documentation for chat streaming recovery guarantees to the architecture docs.

Fusion-Task-Id: FN-3432
This commit is contained in:
Fusion
2026-05-05 00:06:56 -07:00
committed by gsxdsm
parent 4b10ac0ba6
commit cd1d44abab
5 changed files with 180 additions and 11 deletions

View File

@@ -1465,6 +1465,7 @@ export function ChatView({ projectId, addToast }: ChatViewProps) {
};
const activeModelTag = formatModelTag(activeSession?.modelProvider, activeSession?.modelId);
const hasThreadInView = Boolean(activeSession || isStreaming || messages.length > 0);
const threadHeaderTitle = activeSession?.agentId === FN_AGENT_ID
? (activeModelTag ?? "Fusion")
@@ -1666,9 +1667,9 @@ export function ChatView({ projectId, addToast }: ChatViewProps) {
{/* Thread */}
<div className="chat-thread" style={threadKeyboardStyle}>
{/* Header - always rendered in desktop/tablet, only rendered in mobile when viewing a thread */}
{(activeSession || !isMobile) && (
{(hasThreadInView || !isMobile) && (
<div className="chat-thread-header">
{isMobile && activeSession && (
{isMobile && hasThreadInView && (
<button className="btn-icon" onClick={handleBack} data-testid="chat-back-btn">
<ChevronLeft size={16} />
</button>

View File

@@ -1512,6 +1512,42 @@ describe("ChatView", () => {
});
describe("streaming states", () => {
it("keeps mobile thread visible when active session metadata refreshes during streaming", () => {
const mediaQuerySpy = mockViewportMode("mobile");
const streamingState: UseChatReturn = {
...defaultChatState,
sessions: [{ ...activeSessionFixture }],
filteredSessions: [{ ...activeSessionFixture }],
activeSession: { ...activeSessionFixture },
messages: [],
isStreaming: true,
streamingText: "",
streamingThinking: "",
};
const refreshedStreamingState: UseChatReturn = {
...streamingState,
sessions: [{ ...activeSessionFixture, updatedAt: "2026-04-08T00:05:00.000Z" }],
filteredSessions: [{ ...activeSessionFixture, updatedAt: "2026-04-08T00:05:00.000Z" }],
activeSession: null,
};
mockUseChat
.mockReturnValueOnce(streamingState)
.mockReturnValue(refreshedStreamingState);
const { rerender } = render(<ChatView projectId="proj-123" addToast={vi.fn()} />);
expect(document.querySelector(".chat-message--streaming")?.textContent).toContain("Connecting");
rerender(<ChatView projectId="proj-123" addToast={vi.fn()} />);
expect(document.querySelector(".chat-message--streaming")?.textContent).toContain("Connecting");
expect(screen.queryByText("Start a new conversation")).not.toBeInTheDocument();
expect(screen.queryByText("No messages yet. Start the conversation!")).not.toBeInTheDocument();
expect(screen.getByTestId("chat-back-btn")).toBeInTheDocument();
void mediaQuerySpy;
});
it("keeps the streaming indicator visible while message history is still loading", () => {
setupMockChat({
activeSession: { id: "session-001", agentId: "agent-001", status: "active", title: "Test Chat", createdAt: "2026-04-08T00:00:00.000Z", updatedAt: "2026-04-08T00:00:00.000Z" },