ChatGPT/Claude-style conversational interface for querying documents with grounded, cited responses.
apps/web/src/
app/chat/page.tsx — Chat page (full height)
components/chat/
chat-container.tsx — Main orchestrator (messages, streaming, citations)
chat-input.tsx — Textarea with auto-resize, Enter to send
message-bubble.tsx — User/assistant bubbles with inline [N] citation links
citation-panel.tsx — Side panel listing all sources with excerpts + download links
- User navigates to
/chatvia sidebar - Empty state shows "Ask your documents" prompt
- User types question, presses Enter or clicks Send
- Streaming begins:
- "Searching documents..." indicator while retrieval runs
- Tokens stream in as the LLM generates the answer
- Citation panel slides open if sources were used
- User clicks
[1],[2]etc. in the response → citation highlighted in panel - Panel shows: doc title, section path, page number, text excerpt, "View source" download link
Frontend connects via POST /chat/stream. Events arrive in order:
metadata— conversation_id, retrieval metricscitations— array of Citation objectstoken(repeated) — text chunks as they arrivedone— signals stream completeerror— emitted on failure (detail field describes the issue)
- Auto-scroll: Messages area scrolls to bottom on new content
- Multi-turn: Conversation ID maintained for follow-up questions
- Abort: AbortController cancels in-flight requests if user navigates away
- Error handling: Toast notification on failure, empty assistant messages removed
- Retrieval badges: Shows "N sources used", "N queries", "Nms" after each response
- Keyboard: Enter sends, Shift+Enter for newlines
streamChatMessage()— SSE streaming via fetch ReadableStream (used by chat UI)sendChatMessage()— non-streaming POST /chat (exported for programmatic use)getChatHistory()— retrieve past conversationsearchDocuments()— direct semantic searchgetDocumentStats()— vector store stats
Chat is the second item in the sidebar (after Dashboard), using the MessageSquare lucide icon.