Getting started
Installation & setup
The web application and the generation worker are separate processes with separate requirements. You can run the interface without any credentials.
Requirements
- Node.js 22.13 or newer
- Python 3.12
uv- FFmpeg and FFprobe
Node version
The build fails on Node 18 with node:fs/promises does not provide an export named 'glob'. Check with node -v before anything else.
The web application
npm install
The app works in stored-snapshot mode with no credentials at all. The topbar will read Snapshot instead of Live B2, and media served through the proxy will show its unavailable state — everything else renders.
Connecting Backblaze B2
Copy the example environment file and provide a bucket-scoped key.
cp .env.example .env.local
Never commit .env.local
Credentials stay server-side. No B2 key ever reaches browser code, and the media proxies accept fixed kinds or exact opaque job handles — never arbitrary B2 keys.
Use a least-privilege application key scoped to the single bucket. The application reads records through a server-only bridge.
The pipeline
UV_CACHE_DIR=.uv-cache uv sync --project services/pipeline
services/pipeline/.venv/bin/python -m pytest services/pipeline
Ordinary automated tests mock external providers. Successful checkpoints are reused from B2, and page loads never regenerate media.
See services/pipeline/README.md
for pipeline commands.
The worker
The generation worker runs as a single replica, isolated from the web
application. Its deployment contract lives in
deploy/vps/.
One replica, deliberately
A second replica could claim the same job and double-bill the speech provider. Admission slots and the job claim are what make spend predictable, so the replica count is part of the contract rather than a scaling knob.
Environment flags
| Flag | Effect |
|---|---|
TOLUVA_ENABLE_LIVE_INTAKE | Opens or closes public job creation |
TOLUVA_PUBLIC_DAILY_JOB_LIMIT | Admission slots per UTC day, 1–25 |
Enable live intake only after you have explicitly authorized provider spend.