Problem
All chat UI logic is currently embedded directly in WikiLive (lib/pearl_web/live/wiki_live.ex). The chat panel markup, message rendering, streaming state management, and event handling are tightly coupled to the wiki RAG Q&A use case.
We want to support future chat views that aren't restricted to a single repo wiki (e.g. cross-repo chat, general-purpose LLM chat, multi-agent conversations), so the chat components need to be extracted and made reusable.
Current State
Tightly coupled to WikiLive:
- Chat panel markup (slide-in panel, message list, input form) — inline HEEx in
wiki_live.ex
- Chat assigns:
ask_messages, ask_open, ask_current_input, ask_loading
- Event handlers:
toggle_ask, ask, handle_info({:answer_chunk, ...}), handle_info(:answer_complete), handle_info({:answer_error, ...})
- Streaming task supervision for chunked LLM responses
Already generic / reusable:
MarkdownComponent — renders markdown with syntax highlighting + Mermaid
- JS hooks —
ScrollToBottom, AutoFocus, Highlight, Mermaid
- CSS animations for slide-in panel
- Layout "Ask" button (just toggles a flag)
Proposed Approach
- Extract chat function components — message bubble, message list, chat input, chat panel container into a new
ChatComponents module
- Extract chat state + event handling — into a reusable module (e.g.
ChatState or a LiveComponent) that any LiveView can mount and delegate to
- Make the data source pluggable — the chat module should accept a callback/function for generating responses, rather than hard-coding
Rag.ask/3
- Keep WikiLive as a thin consumer — WikiLive wires up the reusable chat with its RAG-specific response function
Acceptance Criteria
Problem
All chat UI logic is currently embedded directly in
WikiLive(lib/pearl_web/live/wiki_live.ex). The chat panel markup, message rendering, streaming state management, and event handling are tightly coupled to the wiki RAG Q&A use case.We want to support future chat views that aren't restricted to a single repo wiki (e.g. cross-repo chat, general-purpose LLM chat, multi-agent conversations), so the chat components need to be extracted and made reusable.
Current State
Tightly coupled to WikiLive:
wiki_live.exask_messages,ask_open,ask_current_input,ask_loadingtoggle_ask,ask,handle_info({:answer_chunk, ...}),handle_info(:answer_complete),handle_info({:answer_error, ...})Already generic / reusable:
MarkdownComponent— renders markdown with syntax highlighting + MermaidScrollToBottom,AutoFocus,Highlight,MermaidProposed Approach
ChatComponentsmoduleChatStateor a LiveComponent) that any LiveView can mount and delegate toRag.ask/3Acceptance Criteria