Voice-enabled, offline laptop recommender that runs a swappable Small Language Model locally on a Raspberry Pi 5 (or any Linux box). FAISS-backed RAG over a 25-laptop INR catalogue, rule-based clarification, optional Whisper/Piper voice I/O, browser UI on LAN.
See edge-slm-smart-store.md (full design doc) and
PROGRESS.md (implementation status).
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt # or: pyyaml numpy fastapi uvicorn pydantic sentence-transformers faiss-cpu python-multipart
python scripts/build_index.py # builds FAISS index from catalogue
uvicorn edgeslm.main:app --app-dir src --host 0.0.0.0 --port 8080Open http://localhost:8080/ (user) or http://localhost:8080/admin (admin).
If no GGUF is present the backend falls back to a deterministic template response — the app is fully usable for retrieval + dialogue without any downloaded models. To enable the SLM and voice:
bash scripts/download_models.sh # Qwen2.5-1.5B + Whisper tiny.en + Piperpytest -q # 37 tests, <1sbash scripts/install_pi.sh # on the Pi
sudo cp systemd/edgeslm.service /etc/systemd/system/
sudo systemctl enable --now edgeslmconfigs/ app.yaml + models.yaml (single source of truth)
data/catalogue/ laptops.json (25 items)
data/index/ persisted FAISS index + embeddings
src/edgeslm/
catalogue/ Laptop dataclass + JSON/CSV loader
retrieval/ MiniLM + FAISS, pre-filter, pool-restricted search
dialogue/ regex parser, rule clarifier, session store
generation/ llama.cpp wrapper, grounded RAG prompt, guard, fallback
voice/ whisper.cpp STT, Piper TTS, Bhashini stub
api/ FastAPI routes (chat / voice / admin) + pydantic schemas
orchestrator.py single boundary: handle_turn(session_id, text)
main.py FastAPI app + WebSocket token streaming + SPA hosting
scripts/ build_index, download_models, bench, install_pi, start
tests/ pytest suite (catalogue, retrieval, parser, clarifier, prompt, e2e)
web/dist/ minimal SPA (index.html = user, admin.html = admin)