Quickstart — run the desktop app
README.md is the non-technical guide for end users — see the launcher at launch.bat / launch.sh.)Prefer watching? npm run dev does everything: it starts the Python backend (auto-creating the venv), the Vite dev server, and the Electron window. The only manual step is installing Node dependencies.
1. Prerequisites
| Tool | Why | Version |
|---|---|---|
| Python | Backend + models (Electron creates the .venv for you, but Python 3 must be on PATH) | 3.11+ |
| Node.js | Vite, React build, Electron | 18+ (npm 9+) |
| Git | Clone the repo | any |
| GPU (optional) | GPU-accelerated embedding (falls back to CPU) | NVIDIA + CUDA |
For LLM-powered answers you also need Ollama running locally (http://localhost:11434) with a model pulled (the launcher's default is lfm2.5:8b). If Ollama isn't running, retrieval still works; answers report the model as "unavailable".
2. Clone & install
bashgit clone https://github.com/haal-lab/Lawyer-Assistant.git
cd Lawyer-Assistant
# Install Node dependencies (three workspaces)
npm install # root — provides `npm run dev` (start alias)
cd frontend && npm install
cd frontend/electron && npm install
cd ..
Python is handled automatically. On first npm run dev, the Electron main process (frontend/electron/src/main/venv-manager.ts) checks for .venv; if missing it creates it with system Python and installs requirements.txt. It falls back to system Python if venv creation fails.
3. Run the app
From the repo root, one command starts the whole desktop app:
bashnpm run dev # or: npm start
dev launches Electron only — and Electron boots everything else itself:
| Process | Who starts it | Port |
|---|---|---|
| Backend | Electron's Python bridge (frontend/electron/src/main/python-bridge.ts) — uses .venv via the venv manager, runs backend/main.py | 8765 |
| Frontend | Electron's Vite launcher (frontend/electron/src/main/vite-dev-server.ts) | 5173 |
| Electron | npm run dev (the single process you start) | — (loads the Vite URL) |
Why only Electron? The Electron main process already spawns the backend and Vite itself (seefrontend/electron/src/main/index.ts). Aconcurrentlytriple-start would launch duplicates that fight over ports 8765/5173. Need just the backend or frontend for browser-only dev? Use the piecemeal scripts instead:npm run dev:backend,npm run dev:frontend, ornpm run dev:web(backend + frontend, no Electron window).
- Electron kills any stale processes on ports 8765/5173.
- It spawns the Python backend and polls
/api/healthuntil ready (30s timeout, 500ms interval). - It starts Vite and opens the Electron window.
- The app's BootLoader runs its own health check; the UI appears when the backend responds
{status: "ok"}.
First launch is slower: creating the venv + installing Python deps happens once. The backend also warms up models (BGE-M3 embedder, BGE-Reranker, Ollama, classifier references) in a background thread at startup, so the first query is fast after that.
4. Add documents (ingestion)
Two ways:
A. In the app (per-file, easy)
- Click the + (attach) button in the chat input bar — or drag & drop a file (PDF, image, TXT, etc.) onto the input area.
- Pick a project folder first (the "Work in a folder" button) — chat, upload and scan all require an active workspace; there is no default
data/folder anymore. - Send a message. The file is uploaded to
/api/upload(saved into the project folder itself), ingested into ChromaDB, and indexed for BM25. - Attach files without typing and it runs a default batch-scan prompt ("Scan these documents for compliance issues: …").
Up to 5 files per message (or a whole folder — up to 50 supported docs — via the folder picker in the input bar).
B. Bulk initial ingest (CLI, one-time corpus)
With the app's venv active (or your own):
bash.venv\Scripts\activate # Windows
# .venv/bin/activate # macOS/Linux
# Ingest everything in data/raw/ (PDFs, images, Dataset_BA.json)
cd backend && python scripts/ingest_all.py
# Useful flags:
cd backend && python scripts/ingest_all.py --reset # wipe ChromaDB first
cd backend && python scripts/ingest_all.py --device cpu # force CPU
cd backend && python scripts/ingest_all.py --skip-json # skip Dataset_BA.json
cd backend && python scripts/ingest_all.py --batch-size 32 # lower GPU memory
Pipeline: collect chunks (Docling parse + structure-aware chunking) → embed with BGE-M3 → save to ChromaDB → build the BM25 index (backend/scripts/ingest_all.py does all four phases).
5. Ask your first question
Type a legal question in the input bar, e.g.:
What is rescission under the civil code?
What happens (visible live in the UI):
- The intent router classifies the message and writes a plan.
- The agent calls
search_documents(dense + sparse + rerank) andverify_relevance. - Retrieved chunks are cited inline; the answer streams in with chain-of-thought, tool cards, and statuses in the message.
- The Sources panel lists cited documents (file, page, section, score); click one to open the source viewer. The Pipeline Editor (Pipeline button in the Sources header) lights up the active node live.
6. Compliance scan (playbook)
Open the scan panel, pick a document + playbook, and run a scan. Chunks are classified by clause type and checked against the playbook rules; findings (flags) appear with severity and can be resolved / dismissed / escalated. See BACKEND.md §6.
7. Verify it works
bash# Backend health (while the app is running)
curl http://localhost:8765/api/health
# → {"status":"ok","service":"lawyer-assistant"}
# Frontend typecheck
cd frontend && npm run typecheck
8. Troubleshooting (quick)
| Symptom | Fix |
|---|---|
| Boot screen stuck on "loading" | Backend didn't start — check the Electron console; ensure Python 3 is on PATH |
| "Could not reach the backend server" | Port 8765 blocked/stale process — restart npm run dev (it kills stale 8765/5173 listeners) |
| Answers say model "unavailable" | Ollama isn't running or has no model — start Ollama, ollama pull lfm2.5:8b |
| Empty results | Corpus not ingested — run cd backend && python scripts/ingest_all.py or attach files in the app |
| GPU out of memory | cd backend && python scripts/ingest_all.py --batch-size 32 |
Stuck on something else? The full guide — TROUBLESHOOTING.md — covers 12 failure scenarios with diagnostics commands (netstat/lsof, curl health checks, Ollama checks).
9. Next steps
- Troubleshooting →
TROUBLESHOOTING.md - Architecture →
ARCHITECTURE.md - Backend/API/agents →
BACKEND.md - Frontend/UI/stores →
FRONTEND.md - Pipeline editor →
PIPELINE_EDITOR.md - Terminology →
GLOSSARY.md - Agent Q&A →
AGENT_KNOWLEDGE_BASE.md