feat(memoro): voice recording → mana-stt transcription pipeline

Adds end-to-end browser voice capture for the Memoro module, mirroring the
existing dreams pattern: MediaRecorder → SvelteKit server proxy → mana-stt
on the Windows GPU box via Cloudflare tunnel.

Recording UI lives in /memoro page header (mic button + live timer + cancel +
sticky-permission retry). Server proxy at /api/v1/memoro/transcribe forwards
the blob with the server-held X-API-Key. memosStore.createFromVoice creates a
placeholder memo with processingStatus='processing' and fires transcribeBlob
in the background, which writes the transcript and flips status on completion
(or 'failed' with error in metadata).

Also corrects the mana-stt hostname across the repo: stt-api.mana.how (which
never existed in DNS) → gpu-stt.mana.how (the actual Cloudflare tunnel route
to the Windows GPU box). Adds an ENVIRONMENT_VARIABLES.md section explaining
how to obtain MANA_STT_API_KEY and where the tunnel terminates. Adds tunnel
health probes to the mac-mini health-check script so we catch tunnel-side
breakage in addition to LAN-side.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-07 18:48:41 +02:00
parent 4d9bf78f41
commit c5aeaf5e7f
9 changed files with 568 additions and 8 deletions

View file

@ -111,6 +111,34 @@ The generator reads `.env.development` and creates app-specific `.env` files wit
| `CARDS_SUPABASE_URL` | Supabase project URL | - |
| `CARDS_SUPABASE_ANON_KEY` | Supabase anonymous key | - |
### Speech-to-Text (mana-stt)
Used by the unified Mana web app's voice features (Memoro recording, Dreams voice capture, etc).
The browser never talks to mana-stt directly — requests go through the SvelteKit server-side proxy
(`/api/v1/memoro/transcribe`, `/api/v1/dreams/transcribe`) which attaches the API key from
`MANA_STT_API_KEY`. Keep that key out of the browser bundle.
| Variable | Description | Default |
|----------|-------------|---------|
| `STT_URL` | Public mana-stt URL — generates `MANA_STT_URL` for the web app | `https://gpu-stt.mana.how` |
| `MANA_STT_API_KEY` | API key for mana-stt. **Never commit a real value.** | _(empty)_ |
**Where to obtain a key:**
- Production deploy: set `MANA_STT_API_KEY` in the Mac Mini's `.env` (sourced by
`docker-compose.macmini.yml`, line ~1076). The key lives on the Windows GPU box in
`services/mana-stt/.env` under `API_KEYS=<key>:<name>` and is the source of truth.
- Local dev: paste the dev key into your local `apps/mana/apps/web/.env` after running
`pnpm setup:env` (the generator only writes an empty placeholder). Ask in `#mana-dev` or
pull from the team's password manager under `mana-stt → web-key`.
- New dev key: SSH to the Windows GPU box (`ssh mana-gpu`), append a new entry to
`C:\mana\services\mana-stt\.env` `API_KEYS` (format: `<random>:<name>`), restart the
`ManaSTT` scheduled task. Use a fresh key per consumer (`mana-web`, `chat-server`, etc.)
so we can revoke individually.
**Endpoint:** `https://gpu-stt.mana.how` — Cloudflare Tunnel `mana-gpu-server`
Windows GPU box (`192.168.178.11:3020`). Health: `curl https://gpu-stt.mana.how/health`.
## Adding New Variables
### Step 1: Add to `.env.development`