Full-stack local voice agent:
- Frontend: React + Vite
- Backend: FastAPI (
faster-whisper+ Coqui TTS) - LLM: Ollama (
llama3.2:3bby default)
voice_agent/
backend/
main.py
run.sh
requirements.txt
.env.example
frontend/
src/
package.json
.env.example
- macOS/Linux shell
- Python
3.10or3.11 - Node.js
18+and npm - Ollama installed and running
ffmpeginstalled and inPATH
macOS install helpers:
brew install ffmpeg
brew install ollamacd backend
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .envNotes:
- If
python3.11is unavailable, use any Python3.10/3.11binary. - The backend converts uploaded audio via
ffmpeg, soffmpegmust be installed.
Start Ollama (if not already running):
ollama serveIn another terminal, pull the default model once:
ollama pull llama3.2:3bcd frontend
npm install
cp .env.example .envIf backend runs on the same machine, set:
VITE_JETSON_API=http://127.0.0.1:8000in frontend/.env.
Use 3 terminals.
Terminal A (Ollama):
ollama serveTerminal B (Backend):
cd backend
./run.shAlternative backend command:
cd backend
source .venv/bin/activate
uvicorn main:app --host 0.0.0.0 --port 8000Terminal C (Frontend):
cd frontend
npm run devOpen:
- Frontend:
http://127.0.0.1:5173 - Backend health:
http://127.0.0.1:8000/health
- Open frontend in browser.
- Click
Start Recording. - Speak a short sentence and click
Stop & Send. - Confirm transcript appears and reply audio plays.
Install ffmpeg:
brew install ffmpeg
ffmpeg -versionThen restart backend.
Use:
uvicorn main:app --host 0.0.0.0 --port 8000Do not use app.main:app for this repo layout.
Check frontend/.env:
VITE_JETSON_API=http://127.0.0.1:8000Then restart frontend (npm run dev).
- Use headphones to avoid speaker feedback into mic.
- Wait for reply audio playback to complete before re-recording.
- Keep
LANGUAGEinbackend/.envaligned with spoken language.
Backend (backend/.env):
OLLAMA_URLdefaulthttp://127.0.0.1:11434OLLAMA_MODELdefaultllama3.2:3bASR_MODELdefaultsmallLANGUAGEdefaultenTTS_MODEL,TTS_FALLBACK_MODELLOG_LEVEL
Frontend (frontend/.env):
VITE_JETSON_APIbackend base URL
- Keep
backend/.env.exampleandfrontend/.env.examplecommitted. - Keep real secrets/local values in
backend/.envandfrontend/.env(ignored by.gitignore).