* feat(speech): move the speech catalog to transcribe-cpp models
Parakeet v2/v3, Whisper tiny and SenseVoice now download their GGUF
builds, which run on transcribe-cpp everywhere, Intel Macs included (on
the CPU). A model still holding its old sherpa-onnx download shows
"Update to the faster version (<size>)"; updating replaces the old
files, and dictating before then says the model needs that update.
The five models with no GGUF build are retired and their users moved
over: the Japanese Parakeet, the Chinese-English Zipformer and the
Paraformer to SenseVoice, and the Korean and Chinese streaming
Zipformers to the new Nemotron 3.5 (28 languages). Nemotron's locale
codes (ko-KR) are matched from the ISO language setting.
* feat(speech): offer the speech model update once after the engine change
A card in the notification corner tells people whose selected on-device
model needs the new download, or whose retired model was replaced, and
starts the same download as Settings > Voice. After a replacement it
offers to delete the retired model's files.
* feat(speech): move retired Korean and Chinese models to SenseVoice and offer Whisper Large v3 Turbo
On transcribe-cpp 0.4.1 with Metal, SenseVoice beat Nemotron 3.5 on Korean
and Chinese FLEURS clips, so the retired Korean and Chinese streaming
Zipformers now move to SenseVoice. Whisper Large v3 Turbo (Q8_0, 886 MB)
joins the catalog as the most accurate choice for Japanese, Korean and
Chinese. Nemotron 3.5 stays, described by the languages it does best.
* feat(speech): run GGUF models on transcribe-cpp, falling back to the CPU
The speech host child can now load a second engine. A model whose files
are GGUF runs on transcribe-cpp (Metal on Apple silicon, Vulkan on
Windows and Linux, CPU otherwise); everything else stays on sherpa-onnx,
which remains the only engine on Intel Macs.
A GPU that fails to load, errors, stalls for 25 s or crashes the process
moves the dictation to a CPU-only process (TRANSCRIBE_BACKENDS=cpu) that
replays the audio the GPU had not decoded yet, so no words are lost or
repeated. A GPU that crashed or would not load is remembered per
transcribe-cpp version and OS release, and voice.speechGpu = 'off' keeps
it on the CPU.
Packaging copies transcribe-cpp, koffi and the target's native package
into resources/node_modules outside asar, fails when a target's package
is missing, and ships the MSVC runtime beside transcribe.dll on Windows.
No catalog model is GGUF yet, so nothing runs on transcribe-cpp until
the catalog change that follows.
* fix(speech): keep the speech queue running after a failed task, and drop audio frames after a discard
* fix(speech): keep the engine's file reads off the main thread's hot paths
The engine lookup and the GPU failure marker are read once per process
instead of on every dictation start and mobile catalog request, the marker
is written asynchronously, and the child reads the hotwords file with
fs/promises. The baseline moves the existing engine presence checks from
stt-worker-paths to the shared package table and adds the once-per-process
marker reads.