Store - ChatStore

abstract

Global Zustand store for chat session management and LLM model selection. Persists selectedProvider and selectedModel to localStorage so the user's model choice survives page refresh. Session list (sessions) is also persisted, giving the sidebar instant render without a network round-trip.


File

frontend/src/hooks/use-chat-store.ts


State Shape

interface ChatState {
  // Session management
  currentSessionId: string | null;
  sessions: ChatSession[];
  setCurrentSessionId: (id: string | null) => void;
  setSessions: (sessions: ChatSession[]) => void;
  addSession: (session: ChatSession) => void;
  removeSession: (id: string) => void;
  updateSessionTitle: (id: string, title: string) => void;
 
  // LLM model selection (persisted to localStorage)
  selectedProvider: string;
  selectedModel: string;
  setSelectedProvider: (provider: string) => void;
  setSelectedModel: (model: string) => void;
}

State Fields

FieldTypeInitialPersistedDescription
currentSessionIdstring | nullnullYesUUID of the active chat session
sessionsChatSession[][]YesOrdered list (newest first) from GET /api/v1/chat/sessions
selectedProviderstringYesActive LLM provider ("ollama", "openai", etc.)
selectedModelstringYesModel name sent in ask-stream query params

ChatSession type from frontend/src/types/chat.ts:

interface ChatSession {
  id: string;
  title: string;
  provider: string;
  model_name: string;
  created_at: string;
}

Actions

ActionSignatureSide Effects
setCurrentSessionId(id: string | null) => voidNavigates sidebar highlight
setSessions(sessions: ChatSession[]) => voidReplaces full session list
addSession(session: ChatSession) => voidPrepends + sets currentSessionId to new session
removeSession(id: string) => voidFilters list; nullifies currentSessionId if it matched
updateSessionTitle(id: string, title: string) => voidUpdates title in-place in sessions array
setSelectedProvider(provider: string) => voidPersisted immediately to localStorage
setSelectedModel(model: string) => voidPersisted immediately to localStorage

Persistence

Uses zustand/middleware persist. All state is serialized to localStorage. Key: default Zustand persist key derived from store definition order.

warning

sessions in localStorage can diverge from the server if sessions are created/deleted from another tab or device. app-sidebar.tsx re-fetches GET /api/v1/chat/sessions on mount and calls setSessions() to reconcile.


Data Flow


Consumers

ComponentWhat it readsWhat it calls
frontend/src/components/app-sidebar.tsxsessions, currentSessionIdaddSession, removeSession, setSessions, setCurrentSessionId
frontend/src/components/chat/chat-interface.tsxcurrentSessionId, selectedProvider, selectedModelsetCurrentSessionId
frontend/src/components/chat/model-selector.tsxselectedProvider, selectedModelsetSelectedProvider, setSelectedModel
frontend/src/components/nav-session.tsxsessions, currentSessionIdupdateSessionTitle, removeSession

RoleLink
Frontend page consuming this storePage - Home
Chat session APIAPI-GET-v1-chat-sessions
TypeScript typesfrontend/src/types/chat.ts