Files
VoiceStudio/bin
5bd8968aea feat(engines): real synthesis "Self-test" + copy-paste setup snippet for opt-in engines (#930)
* feat(engines): real synthesis "Self-test" + copy-paste setup snippet for opt-in engines

Builds on #905's Engines-settings fixes (verified still green: license dialog
mounts, matrix reloads on select, cpu_fallback routing toast, cpu-native →
cpu_only). Two enhancements, no #905 behavior touched.

Real "Self-test" for in-process TTS engines
-------------------------------------------
The existing /engines/{id}/health probe only imports the package and reports
"deps OK" for in-process engines — it never proves the engine can emit audio.
New POST /engines/{id}/selftest runs a *tiny real synthesis* from a fixed short
ASCII phrase and reports ok + duration + sample-rate + sample count, proving the
engine actually produces audio. Guardrails keep it cross-platform-identical and
CPU-cheap: TTS + available + in-process only, bounded wall-clock timeout
(OMNIVOICE_SELFTEST_TIMEOUT_S, default 90s) that returns ok=false/timed_out
instead of hanging the panel, a process-wide lock so a click-storm can't stack
model loads, loopback-gated, and only ever on user click (never on load). The
Compat Matrix gains a "Self-test" button (with cooldown) that renders
"0.82s @ 24 kHz in 820 ms". HF tokens in a synth error are redacted like the
health route. Verified end-to-end: kittentts synthesized 89,200 samples @ 24 kHz.

Copy-paste setup snippet for path-gated opt-in engines
------------------------------------------------------
IndexTTS / MOSS-v1.5 / dots.tts / Confucius4 gate on an OMNIVOICE_*_DIR env var.
list_backends() now emits a single-sourced `setup_snippet` (the exact
`export VAR=/path/...` line) surfaced with a Copy button inside the matrix's
"Why unavailable?" disclosure, so users don't reconstruct it from the docs.

Also tightened the incomplete SelectEngineResponse TS type to include the
routing echo (routing_status/effective_device/routing_reason) the post-select
toast already reads at runtime.

Tests: backend selftest success/subprocess-reject/unavailable/unknown/loopback/
exception-capture/timeout/HF-redaction + setup_snippet shape; frontend self-test
render, timeout marker, subprocess+ASR gating, setup-snippet render. New route
added to the API route snapshot. Full vitest (808) + backend engine/routing/asr/
route-inventory/no-CJK green; lint 0 errors; format + typecheck:ci clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(test): allow setup_snippet key in list_backends shape assertion

The engine self-test PR added setup_snippet to each backend entry but only
updated the route-shape test; test_list_backends_shape strict-asserts the key
set. Add setup_snippet there too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: mergetest <test@local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 17:02:08 +05:30
..

Bundled binaries

This directory holds platform-specific binaries that ship inside the OmniVoice Studio installer. Today:

File Built from Purpose
omnivoice-tts-darwin-arm64 ServeurpersoCom/omnivoice.cpp @ pinned SHA GGUF inference runtime — Apple Silicon
omnivoice-tts-darwin-x86_64 same Intel Mac
omnivoice-tts-linux-x86_64 same Linux
omnivoice-tts-windows-x86_64.exe same Windows
checksums.sha256 computed by scripts/build-omnivoice-tts.sh SHA-256 manifest — verified by OmniVoiceGGUFBackend.is_available()

The pinned commit SHA for omnivoice.cpp lives in backend/engines/omnivoice_gguf/quant_map.json _meta.runtime_commit_sha.

Building locally

scripts/build-omnivoice-tts.sh --platform <slug> --commit-sha <40hex>

See .github/workflows/ci.yml build-omnivoice-tts job for the CI matrix that produces these artifacts on every PR. The Apple Silicon slot (macos-14) is marked continue-on-error: true because the upstream omnivoice.cpp README does not publish a buildmetal.sh (Pitfall 1 in 04-RESEARCH.md); a failed Metal build is documented and the macOS Apple Silicon cloning default falls back to the in-process OmniVoiceBackend.

Placeholder note

Until the CI matrix produces real binaries, this directory may contain zero-byte placeholders. OmniVoiceGGUFBackend.is_available() returns (False, "...binary missing...") in that case so the engine reports honestly through the Engine Compatibility Matrix and the default selection falls back to the in-process OmniVoiceBackend.