diff --git a/.planning/phases/06-lab-advisor/06-03-SUMMARY.md b/.planning/phases/06-lab-advisor/06-03-SUMMARY.md new file mode 100644 index 0000000..81415c2 --- /dev/null +++ b/.planning/phases/06-lab-advisor/06-03-SUMMARY.md @@ -0,0 +1,96 @@ +--- +phase: 06-lab-advisor +plan: "03" +subsystem: frontend +tags: [advisor, chat, streaming, sse, react, tanstack-query] +dependency_graph: + requires: [06-02] + provides: [advisor-ui, streaming-chat-frontend] + affects: [web/src/router.tsx, web/src/components/layout/TopBar.tsx, web/src/components/layout/AppShell.tsx] +tech_stack: + added: [] + patterns: [ReadableStream SSE parsing, TanStack Query refetchInterval sidebar, optimistic user messages, streaming cursor animation] +key_files: + created: + - web/src/api/advisor.ts + - web/src/pages/AdvisorPage.tsx + modified: + - web/src/router.tsx + - web/src/components/layout/TopBar.tsx + - web/src/components/layout/AppShell.tsx +decisions: + - "Used fetch + ReadableStream instead of EventSource for SSE — POST body required for chat endpoint" + - "Used a ref (streamingContentRef) alongside state to capture latest streaming content inside async callbacks without stale closure issues" + - "Added noPadding prop to AppShell to support full-height two-panel layout without max-width constraint" + - "Model label in sidebar shows only the model slug (after /) to keep sidebar compact" +metrics: + duration: "~8 minutes" + completed: "2026-04-10T07:39:59Z" + tasks_completed: 2 + files_changed: 5 +--- + +# Phase 06 Plan 03: AdvisorPage Frontend Summary + +**One-liner:** Two-panel streaming chat UI at /advisor — sidebar conversation list, fetch+ReadableStream SSE token streaming, model dropdown, ClickHouse dark theme. + +## Tasks Completed + +| # | Task | Commit | Files | +|---|------|--------|-------| +| 1 | API wrappers for advisor endpoints | 811223d | web/src/api/advisor.ts | +| 2 | AdvisorPage component, route, and TopBar link | bcc3608 | web/src/pages/AdvisorPage.tsx, web/src/router.tsx, web/src/components/layout/TopBar.tsx, web/src/components/layout/AppShell.tsx | + +## What Was Built + +### web/src/api/advisor.ts +Typed API wrappers for all three advisor endpoints: +- `fetchConversations()` — GET /api/advisor/conversations, returns `[]` on 404 +- `fetchConversation(id)` — GET /api/advisor/conversations/:id +- `streamChat(params, onToken, onDone, onError)` — POST /api/advisor/chat, reads response.body via `getReader()` + `TextDecoder`, splits on `\n\n` SSE delimiters, parses `data:` lines, calls `onToken` per token and `onDone` on `[DONE]` + +### web/src/pages/AdvisorPage.tsx +Full two-panel AdvisorPage: +- Left sidebar (280px, hidden on mobile): "Lab Advisor" heading, "New Chat" button, conversation list with `refetchInterval: 5000`, selected state highlighted +- Main panel: messages area (scrolls to bottom on new content), optimistic user messages (right-aligned bg-[#1a1a1a]), assistant messages (left-aligned bg-[#111]), streaming assistant turn with animated cursor +- Input row: model `