Session UI
Main chat container with resizable panels and responsive layout.
ChatSessionUI is the top-level container for an active chat conversation. It orchestrates messages, the map panel, the document viewer, and the settings sheet.
Props
interface ChatSessionUIProps {
chatSession: ChatSession;
enableDocumentStatusPolling?: boolean;
}State Management
The component manages several pieces of state:
// Map visibility (synced with URL query params)
const [isMapVisible, setIsMapVisible] = useQueryParam("map");
// Document viewer tabs
const [openDocuments, setOpenDocuments] = useState<DocumentTab[]>([]);
const [activeDocumentId, setActiveDocumentId] = useState<string | null>(null);
// Mobile document sheet
const [isMobileDocumentSheetOpen, setIsMobileDocumentSheetOpen] = useState(false);
// Document processing status
const [documentStatuses, setDocumentStatuses] = useState<DocumentStatus[]>([]);Desktop Layout (Resizable Panels)
On desktop, the chat uses ResizablePanelGroup for a flexible multi-panel layout:
┌─────────────────┬──────────────┬──────────────────┐
│ │ │ │
│ Message List │ Google Map │ Document Viewer │
│ + Input Form │ (optional) │ (optional) │
│ │ │ │
└─────────────────┴──────────────┴──────────────────┘- Panel 1 (Messages): Always visible, min 30% width
- Panel 2 (Map): Toggled via header button, shows Google Maps with location markers
- Panel 3 (Documents): Opens when clicking a citation source, tabbed document viewer
Users can drag panel borders to resize.
Mobile Layout
On mobile, the layout stacks vertically:
┌──────────────────┐
│ Chat Header │
├──────────────────┤
│ │
│ Message List │
│ │
├──────────────────┤
│ Input Form │
└──────────────────┘
+ Sheet modals for Map & DocumentsDocuments and map open in Sheet components (slide-up panels).
Document Status Polling
When enableDocumentStatusPolling is true, the component polls document processing status every 5 seconds:
useEffect(() => {
if (!enableDocumentStatusPolling) return;
const interval = setInterval(async () => {
const statuses = await fetchDocumentStatuses(chatSession.id);
setDocumentStatuses(statuses);
}, 5000);
return () => clearInterval(interval);
}, []);This keeps the UI updated when documents are being ingested in the background.
Citation Click Flow
When a user clicks a citation source in a message:
onCitationClick(documentId, chunkId)is called- If document not already open, add to
openDocumentstabs - Set
activeDocumentIdto the clicked document - Pass
highlightChunkIdto the document viewer - On mobile, open the document sheet
Settings Sheet
The ChatSessionSettingsForm opens as a side sheet. It shows only the settings the chat's model takes, from the backend's model catalog (GET /api/workspaces/{id}/ai-models/):
| Setting | For | Stored as |
|---|---|---|
| Name | Every chat | name |
| Model | Every chat; models outside the plan are locked | ai_model |
| Instructions | Every chat | system_prompt |
| Response style: Precise (default), Balanced, Creative | Models that take temperature | temperature (0.2, 0.7, 1.0) |
| Reasoning effort | GPT-5, o3, o4-mini | model_parameters.reasoning_effort |
| Extended thinking, with a budget | Claude | model_parameters.thinking |
| Reply length, up to the model's limit | Every chat | max_tokens |
| Advanced: temperature, Top P, Top K, penalties, seed, stop sequences | Each where the model takes it | the chat's fields, or model_parameters |
- An empty setting shows its default, never a blank box, and each one can be reset to it.
- Claude takes temperature or Top P, not both, so setting one clears the other; with extended thinking on, neither applies and they're hidden.
- Switching model drops the settings the new one can't take.
- Save sends only what changed, by
PATCH, and shows the backend's reason if it refuses ("The Free plan doesn't include …"). Reset goes back to what's saved.
Below the settings, knowledge bases can be attached and detached.
Location Sheet
When a location tag is clicked in a message:
onLocationClick(location)is called- A floating sheet opens with
LocationDetailView - Shows location name, address, and details
- Map panel centers on the location marker