* feat(settings): run local VocaGateway from Speech Engine (podman-first) Add an optional Local VocaGateway panel next to Remote Server so Linux users can start the pinned v0.1.0 compose project with podman (docker fallback), watch Live/Pairable/Ready status, pair a phone without loopback QR URLs, and preset remote_api to the gateway transcriptions endpoint. Stop preserves volumes; Flatpak fails closed; tray offers Stop only when this session manages the gateway. Default on-device engine stays whisper.cpp. * fix(gateway-embed): drop nonexistent compose cpu profile VocaGateway v0.1.0 exposes default service gateway plus native/cuda/vulkan profiles, not cpu. Start and stop the default service without --profile, keep the latest image pin rejection, and prefer save_config for the remote_api preset. * fix(gateway-embed): keep compose --profile cpu per embed contract v0.1.0 has no cpu profile entry, but Compose still starts the unprofiled gateway service when --profile cpu is set, and keeps cuda/vulkan/native off. That matches the frozen desktop embed contract and stays forward-compatible. * fix(gateway-embed): harden embed path for settings and compose Keep podman/docker probing off the GTK thread, reject link-local and loopback public URLs for phone QR, sanitize compose .env image overrides, and cap bootstrap token reads so a hostile file cannot blow memory. * fix(gateway-embed): keep LAN toggle and phone QR in sync When Allow LAN flips while compose is already managed, rewrite publish host and PUBLIC_URL and recreate the gateway before Pairable comes back. Also reject default docker/podman bridge addresses for phone QR. * test(gateway-embed): pin bridge and LAN-gate pairing cases Cover 172.17.0.2 / link-local not becoming Pairable, and the mid-run LAN toggle path that must wait for compose republish before advertising a phone URL. * style(gateway-embed): black format embed modules * fix(gateway-embed): reject short-form loopback and localhost.* for QR Align Pairable/QR host checks with vocagateway desktop-embed policy so 127.1 / localhost.* never become phone-reachable display URLs. * fix(gateway-embed): detach Settings status listener on destroy Gateway poll callbacks were left registered after Settings closed, so idle_add could touch destroyed GTK widgets while compose stayed up. * fix(gateway-embed): pass host_env to bridge ip probe _bridge_iface_ips shells out to host ip; without host_env the AST gate fails and AppImage bundles can hand the wrong GLib to ip. * fix(packaging): ship gateway_embed in the AppImage The explicit setuptools packages list omitted the new package, so the bundle booted from source trees but died with ModuleNotFoundError on every distro boot test. * style(packaging): black the gateway_embed package guard * fix(settings): pack local VocaGateway into the Advanced island The rebase onto main auto-merged textually onto the simple Speech Model page. Keep the gateway card on advanced_box, next to Remote Server. * fix(gateway-embed): treat missing Compose as unavailable When podman or docker is present but Compose is not, stop advertising Run. Return empty compose_args, show an install-Compose hint, and cover it with a unit test. Also add module loggers on the new gateway_embed modules and annotate the gateway Settings/tray callbacks Greptile flagged. just lock found no lockfile drift. * fix(gateway-embed): keep Allow LAN bind matched to the switch Snapshot the LAN flag for start/republish, record what compose actually got, then republish again if the switch moved mid-flight so 0.0.0.0 never lingers while Allow LAN reads off. * fix(gateway-embed): detect leftover compose after Quit Quit does not stop compose, so a LAN-published gateway can keep running. Settings and the tray treated that as Stopped because managed_by_us is only process memory. Probe compose after runtime detection, show Stop when it is actually up, and let Stop work even if this session did not start it. * fix(gateway-embed): restore LAN switch from leftover compose Quit leaves compose running, so the next launch now reads VOCAGATEWAY_PUBLISH_HOST from the embed .env, adopts the project as managed, and keeps Allow LAN honest so republish can close 0.0.0.0. * fix(gateway-embed): restore .env if LAN republish fails compose recreate can fail after write_env_file already pointed VOCAGATEWAY_PUBLISH_HOST at loopback. Restore the previous .env so orphan adopt still sees a live 0.0.0.0 bind, and snap Allow LAN back to the running publish mode. * style(gateway-embed): type helper args and black MagicMock * refactor(types): move Readable protocol to common_types AGENTS.md keeps Protocol interfaces in common_types. Pairing now imports the shared Readable surface instead of a local _Readable helper. * fix(gateway-embed): satisfy mypy on rebased embed code * fix(audio): keep duck restore point when a set reports failure
3.7 KiB
Local VocaGateway from Vocalinux (optional)
Vocalinux can start a local VocaGateway container from Settings → Speech Model → Advanced, next to Remote Server. This is an optional power-user path. It is not on-device processing: microphone audio still leaves the desktop client and is transcribed by the gateway process on your machine (or LAN).
The default speech engine remains whisper.cpp on-device. Enabling a local
gateway never changes that default by itself. Use Use this Gateway only when
you want Vocalinux to talk to the gateway over the existing Remote API settings
(remote_api_*, endpoint /v1/audio/transcriptions). See HTTP_REMOTE.md.
Requirements (Linux MVP)
- podman (preferred) or docker, with a working
composeplugin (orpodman-compose/docker-compose). - Vocalinux does not bundle a container engine inside the AppImage.
- Flatpak: the sandbox cannot reach the host container socket. Run the native package or AppImage, or start VocaGateway on the host yourself and point Remote Server at it.
What Vocalinux does
- Pins upstream VocaGateway
v0.1.0(git tag) under your XDG cache and uses that checkout'scompose.yamlwith Compose project namevocagateway. - Writes a private bootstrap token under
~/.config/vocalinux/gateway_embed/(mode600) and a matching Compose.env. - Runs
compose -f compose.yaml --profile cpu up -dfor thegatewayservice. The v0.1.0 GitHub release has no published container image assets, so the first start builds the local imagevocagateway:v0.1.0from that tag (override withVOCAGATEWAY_IMAGE; neverlatest). Later starts reuse the image/volume. - Polls
GET /health/liveandGET /health/ready, and (when live) authenticatedGET /v1/admin/pairingfor phone pairing. - Stops with
compose downwithout-v, so the named data volume (models, config) is kept.
Status labels
| Status | Meaning |
|---|---|
| Stopped | Not running. |
| Starting | Compose up in progress, or live probe not green yet. |
| Live | Process answers /health/live. |
| Pairable | Live, plus a non-loopback phone URL and bearer token (QR-safe). |
| Ready | /health/ready is 200 (model selected in the gateway WebUI). |
| Error | Start/stop or probe failure (see the subtitle). |
Pairable can appear before Ready: you can pair a phone while a model is still downloading.
LAN / phone
By default the published host is 127.0.0.1 (desktop-only). Turn on Allow LAN
access for Phone to set VOCAGATEWAY_PUBLISH_HOST=0.0.0.0 and to advertise a
LAN URL in pairing. Open port 8765 in your firewall only on trusted networks.
Never put 127.0.0.1 / localhost in the phone QR. If a LAN toggle fails,
compose keeps the previous bind, Vocalinux restores the embed .env, and the
switch snaps back with an error (Stop and Run again, or retry).
Tray and Quit
The tray menu offers Stop local Gateway whenever compose is actually running (Starting, Live, Pairable, Ready, or Error), including a leftover from a previous Vocalinux session. Vocalinux does not auto-start the gateway on login in v1.
Quit does not stop compose. The pinned compose file uses restart: unless-stopped, so a LAN-published gateway on 0.0.0.0:8765 keeps running after
you quit Vocalinux. The next launch restores the Allow LAN switch from the running
compose publish host. Use Stop local Gateway in Settings or the tray when you
want it gone. Do not assume Quit tears it down.
Honesty
VocaGateway is optional self-hosted infrastructure for the Voca family. There is no Voca account and no hosted Voca cloud. Prefer a trusted LAN, Tailscale, or HTTPS. Do not expose port 8765 to the public internet.