Architecture Overview
System diagram
Section titled “System diagram”graph TB subgraph Client["Browser"] FE["SvelteKit Frontend"] end
subgraph Server["Server"] BE["Rust Axum Backend"] OL["Ollama"] end
subgraph Database["Supabase"] AUTH["Supabase Auth<br/>(Google OAuth)"] PG["PostgreSQL<br/>+ pgvector"] end
subgraph Cloud["Cloud Providers"] OPENAI["OpenAI API"] MISTRAL["Mistral API"] GEMINI["Gemini API"] HF["HuggingFace API"] end
FE -->|"REST API<br/>(HTTP)"| BE FE <-->|"WebSocket<br/>(streaming)"| BE FE -->|"OAuth flow"| AUTH AUTH -->|"JWT tokens"| FE
BE -->|"SQLx queries"| PG BE -->|"Chat + Embeddings"| OL BE -->|"Chat completions"| OPENAI BE -->|"Chat completions"| MISTRAL BE -->|"Chat completions"| GEMINI BE -->|"Inference"| HF
AUTH -->|"User management"| PGComponent overview
Section titled “Component overview”Frontend (SvelteKit)
Section titled “Frontend (SvelteKit)”The frontend is a SvelteKit application that handles:
- Authentication via Supabase Auth (Google OAuth), using
@supabase/ssrfor cookie-based sessions - Session and chat management through REST API calls to the backend
- Real-time streaming via a WebSocket connection per active session
- UI rendering with shadcn-svelte components (tabs, dialogs, inputs)
Key modules: lib/api.ts (REST client), lib/ws.ts (WebSocket client), lib/stores/ (Svelte stores for state).
Backend (Rust Axum)
Section titled “Backend (Rust Axum)”The backend is a Rust web server built on Axum that provides:
- REST API for CRUD operations on sessions, chats, context items, and models
- WebSocket endpoint for streaming chat completions token by token
- Plugin system (
LlmProvidertrait) for integrating multiple LLM providers - JWT authentication middleware that validates Supabase-issued tokens
- Embedding service that calls Ollama to generate vectors for context items
Key modules: routes/ (HTTP handlers), plugins/ (LLM providers), auth/ (JWT middleware), services/ (embeddings).
Database (Supabase PostgreSQL)
Section titled “Database (Supabase PostgreSQL)”A single PostgreSQL database with:
- Core tables:
profiles,sessions,chats,messages,session_prompts - Context tables:
context_items(withvector(768)column),query_items - Row Level Security on all tables, scoped to
auth.uid() - pgvector extension for cosine similarity search on embeddings
LLM Providers
Section titled “LLM Providers”The plugin registry (PluginRegistry) is a HashMap<String, Arc<dyn LlmProvider>> populated at startup:
- OpenAI — SSE streaming via
/v1/chat/completions - Mistral — SSE streaming via
/v1/chat/completions - Gemini — SSE streaming via Google’s generateContent API
- HuggingFace — Inference API (non-streaming)
- Ollama — NDJSON streaming via
/api/chat, models auto-discovered at startup
Data flow
Section titled “Data flow”Chat query (streaming)
Section titled “Chat query (streaming)”- User types a message in the frontend
- Frontend sends a
queryorquery_allmessage over the WebSocket - Backend validates JWT, verifies chat ownership, inserts user message into
messages - Backend loads full conversation history and sends it to the LLM provider
- Provider streams tokens back; backend forwards each as a
tokenWebSocket message - When the stream completes, backend inserts the assistant message and sends
done - Frontend accumulates tokens in a Svelte store and renders them progressively
Chat query (REST, non-streaming)
Section titled “Chat query (REST, non-streaming)”- Frontend calls
POST /api/chats/{chat_id}/querywith the user message - Backend inserts user message, calls
provider.send()(blocking), inserts assistant message - Returns the full
ChatWithMessagesobject
Authentication flow
Section titled “Authentication flow”- User clicks “Sign in with Google” on the login page
- Supabase Auth redirects to Google OAuth consent screen
- Google redirects back to Supabase with an auth code
- Supabase exchanges the code for tokens, creates a user in
auth.users - A database trigger creates a
profilesrow for the new user - Supabase returns a JWT to the frontend, stored in cookies via
@supabase/ssr - All backend API calls include the JWT in the
Authorization: Bearerheader