A premium, glassmorphic chat application built with React, Tailwind CSS v4, and Lucide React icons. Supports multiple LLM providers out of the box β Groq, OpenAI, Anthropic, and local Ollama models β with an optional cloud-based TTS backend.
- π§ Multi-Provider Support β Groq, OpenAI, Anthropic, and Local Ollama
- π¨ Premium Glassmorphic UI β Dark mode, gradient glows, smooth animations
- π Model Switcher Pill β Quick-switch between providers and models from the header
- π€ Voice Mode / TTS β Cloud-powered AI voices (8 voices) with automatic browser fallback
- π£οΈ Voice Picker β Choose between Nova, Orion, Aurora, Ember, and more from Settings
- ποΈ Voice Input / ASR β Record speech β transcribe with Qwen3-ASR-1.7B on GPU
- π¬ Conversation History β Auto-saved to localStorage with sidebar navigation
- π Sidebar β Slide-out panel listing all past chats with timestamps and delete
- π Quick Start Cards β Interactive onboarding cards (Analyze Code, Draft Content, Summarize, Brainstorm)
- βοΈ Multi-line Input β Expandable textarea with glassmorphism effect
- π± Fully Responsive β Works on desktop and mobile
The chat application now features a robust FastAPI backend to securely handle API keys, database storage, and LLM streaming.
cd chat_app/backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtStart the FastAPI server:
# Set your API keys in the environment or create a backend/.env file
export GROQ_API_KEY="your_key"
uvicorn app.main:app --host 0.0.0.0 --port 8080 --reloadThe backend will run on http://localhost:8080.
cd chat_app
cp .env.example .envEdit .env and set the frontend API URL (API keys are no longer needed in the frontend):
# Frontend Environment Variables (Vite)
VITE_API_URL=http://localhost:8080npm install
npm run devOpen http://localhost:5173 in your browser.
You can launch both the frontend (served via FastAPI static optionally or a separate container) and the backend easily via docker-compose:
docker-compose up -d --buildThis requires a created .env file in the root directory formatted like .env.example.
| Provider | URL |
|---|---|
| Groq | https://console.groq.com/keys |
| OpenAI | https://platform.openai.com/api-keys |
| Anthropic | https://console.anthropic.com/settings/keys |
If you have Ollama installed and running, the app auto-detects your local models on startup. Just select Local (Ollama) from the Model Switcher.
The app includes a high-fidelity TTS backend powered by the SVECTOR-CORPORATION/Continue-TTS model (~15 GB). This requires an Nvidia GPU, so the recommended method is to rent one on Vast.ai.
Without the backend, TTS falls back gracefully to your browser's built-in
speechSynthesisβ everything still works!
β οΈ Important: The originalcontinue-ttslibrary uses vLLM for inference, which crashes on many Vast.ai instances due to GPU memory/IPC issues. This project uses a custom PyTorch + SNAC decoder that bypasses vLLM entirely. The custom server lives inbackend/tts_server.py(based ontts_server_hf.py).
# 1. SSH into Vast.ai with port forwarding
ssh -p <PORT> root@<IP> -L 8080:localhost:8080
# 2. On the remote machine β start the TTS server (one-click)
bash /workspace/chat_app/backend/start_server.sh
# OR manually:
PORT=8080 /venv/main/bin/python3 /workspace/chat_app/backend/tts_server_hf.py
# 3. On your Mac β update .env and start Vite
echo "VITE_TTS_API_URL=http://localhost:8080" >> .env
npm run devThe first TTS request takes ~20-30s (model loads into GPU). Subsequent requests are fast (~5s).
cat ~/.ssh/id_rsa.pubPaste it into your Vast.ai Account Settings β SSH Keys.
- Go to the Create tab on Vast.ai
- Select the PyTorch template
- Choose a GPU with 16 GB+ VRAM (e.g., RTX 3090, 4090, A5000)
- Ensure 50 GB+ disk space (model weights are ~15 GB)
- Click Rent
# From your Mac
scp -P <PORT> -r backend root@<IP>:/workspace/chat_app/backend# SSH into Vast.ai
ssh -p <PORT> root@<IP>
# Install required packages
/venv/main/bin/pip install flask flask-cors numpy snac accelerate hf_transfer| Package | Why |
|---|---|
flask |
HTTP server |
flask-cors |
CORS headers for browser requests |
numpy |
Audio PCM array conversion |
snac |
SNAC 24kHz neural audio codec (decodes model tokens β WAV) |
accelerate |
HuggingFace device_map="auto" GPU placement |
hf_transfer |
Fast Rust-based model weight downloader |
HF_HUB_ENABLE_HF_TRANSFER=1 /venv/main/bin/python3 -c "
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
m = AutoModelForCausalLM.from_pretrained('SVECTOR-CORPORATION/Continue-TTS', device_map='auto', dtype=torch.float16, trust_remote_code=True)
print('β
Model downloaded and loaded successfully')
print('Devices:', m.hf_device_map)
"Weights are cached in
/workspace/.hf_home/hub/(~15 GB). Subsequent loads take ~2 seconds.
PORT=8080 /venv/main/bin/python3 /workspace/chat_app/backend/tts_server.pyYou should see:
* Serving Flask app 'tts_server'
* Running on http://127.0.0.1:8080
Open a separate terminal on your Mac:
ssh -p <PORT> root@<IP> -L 8080:localhost:8080This tunnels localhost:8080 on your Mac β port 8080 on the Vast.ai GPU.
# Set the TTS URL in .env
# (already done if you followed the quick start)
VITE_TTS_API_URL=http://localhost:8080
# Start Vite
npm run devOpen http://localhost:5173, send a message, and click the π€ Read button on any assistant response!
A test script is available in backend/generate/test_tts.sh:
cd backend/generate
bash test_tts.shThis generates test_orion.wav and test_nova.wav in the generate/ folder. Valid files are ~500-700 KB. If you see 44-93 byte files, the server has an error β check its terminal output.
# Play a test file on macOS
open backend/generate/test_orion.wav| Problem | Solution |
|---|---|
Port 8080 is in use |
Run on Vast.ai: fuser -k 8080/tcp then restart the server |
model_loaded: false in health check |
This is normal β model loads on first TTS request (~20s) |
Engine core initialization failed |
You're running the old vLLM-based server. Use tts_server_hf.py instead |
accelerate not found |
Run: /venv/main/bin/pip install accelerate |
| Model download stuck at 25% | Clear cache: rm -rf /workspace/.hf_home/hub/models--SVECTOR* and re-download with HF_HUB_ENABLE_HF_TRANSFER=1 |
| Browser uses robotic voice | Check browser console β if it says Continue-TTS service available: false, the SSH tunnel or server is down |
| SSH tunnel drops | Re-run: ssh -p <PORT> root@<IP> -L 8080:localhost:8080 |
The app includes a mic button ποΈ in the input area that records your voice and transcribes it using Qwen3-ASR-1.7B (~3.5 GB model, 52 languages supported).
- Click the ποΈ mic button (left of the send button) to start recording
- The button turns red and pulses while recording
- Click again to stop β audio is sent to the backend
/asr/transcribeendpoint - Transcribed text appears in the input box, ready to send
The ASR model runs alongside the TTS model on the same GPU. It's included in start_server.sh automatically:
# qwen-asr is installed by start_server.sh
# The model downloads (~3.5 GB) on first mic useTo test ASR from the command line:
curl -X POST http://localhost:8080/asr/transcribe \
-F "audio=@recording.wav"
# Returns: {"text": "Hello world", "language": "English"}Without the GPU backend, the mic button will show an error in the console. A future update could add browser-based
SpeechRecognitionas a fallback.
chat_app/
βββ src/
β βββ components/
β β βββ ChatBox.jsx # Main chat UI (messages, input, settings)
β β βββ Sidebar.jsx # Conversation history sidebar
β β βββ ChatBox.css # Legacy styles (Tailwind used inline)
β βββ hooks/
β β βββ useChatModel.js # Multi-provider SSE chat hook
β β βββ useConversations.js # Conversation CRUD (FastAPI/SQLite integration)
β β βββ useASR.js # Mic recording + backend transcription
β β βββ useTTS.js # TTS hook (cloud + browser fallback)
β βββ config/
β β βββ models.js # Provider & model definitions
β β βββ tts.js # General backend API config
β βββ App.jsx # Root layout (sidebar + chat)
β βββ index.css # Tailwind v4 import + base styles
βββ backend/
β βββ app/
β β βββ main.py # FastAPI Entrypoint
β β βββ config.py # Pydantic secure settings (API keys)
β β βββ database.py # aiosqlite connection setup
β β βββ models.py # SQLModel definitions (Conversation, Message)
β β βββ routers/ # Dedicated routers (/chat, /tts, /asr, /conversations)
β β βββ services/ # Business logic (`llm_service`, `tts_service`)
β βββ tests/ # Pytest suite
β βββ requirements.txt # Python dependencies
β βββ README.md # Backend-specific docs
βββ Dockerfile # Multi-stage Docker build
βββ docker-compose.yml # 1-click orchestration
βββ .env # Backend Secure Config (API keys) + VITE_API_URL
βββ package.json
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite 5, Tailwind CSS v4, Lucide React |
| Backend | Python FastAPI, WebSockets/SSE, Pydantic, SQLModel |
| Database | SQLite (aiosqlite asynchronous engine) |
| LLM APIs | Groq, OpenAI, Anthropic, Ollama (local) via server proxy |
| TTS | Continue-TTS (cloud GPU), Browser SpeechSynthesis (fallback) |
| ASR | Qwen3-ASR-1.7B (cloud GPU), 52 languages |
| DevOps | Docker, Docker Compose, Pre-commit hooks |