Renames what users see. The app, the installers, the window title, the
docs and all 21 locales now say VoiceStudio, with "(previously
OmniVoice-Studio)" noted near the title of each doc surface so people
recognise it.
Deliberately NOT renamed, because renaming any of them silently breaks
an existing install — there is no legacy-path fallback anywhere in this
codebase:
- bundle identifier com.debpalash.omnivoice-studio (MSI UpgradeCode,
macOS TCC grants, managed venv, WebView localStorage, the
single-instance lock)
- data directories OmniVoice / .omnivoice and omnivoice.db
- the ~150 OMNIVOICE_* environment variables
- the X-OmniVoice-* HTTP headers (a wire protocol)
- the published Docker image paths
- the OmniVoice ENGINE, which is a model name and not this product
tests/test_identity_paths_survive_the_rename.py pins every one of those
so a future well-meaning sweep cannot orphan a user's library.
Linux .deb users install a new package name and should apt remove
omnivoice-studio; that note is in the changelog.
3.5 KiB
Agentic voice: VoiceStudio as a TTS/STT provider
VoiceStudio exposes an OpenAI-compatible API, so any agent framework that speaks to OpenAI's audio endpoints can use your local VoiceStudio for speech — in your own cloned voice, with nothing leaving your machine. You bring the agent runtime; VoiceStudio is the voice.
This is "agentic v1": VoiceStudio is a provider, not the orchestrator. You wire your own agent (a support line, a desk assistant, a Discord persona) and point its TTS/STT at VoiceStudio.
Scope. This page covers VoiceStudio-as-provider. Outbound phone calls are a separate, deferred milestone (they need a paid carrier — there is no fully-local path to the PSTN) and ship only behind explicit consent guardrails. See the roadmap in
docs/competitive-analysis.md(§R1).
The endpoints
VoiceStudio serves these on http://localhost:3900/v1 (or your
remote backend URL):
| OpenAI route | VoiceStudio support |
|---|---|
POST /v1/audio/speech |
TTS. model = engine id, voice = a voice-profile id (your clone) or preset, response_format incl. pcm and wav, speed. Default output is 24 kHz. |
POST /v1/audio/transcriptions |
STT (Whisper-family). |
GET /v1/audio/voices |
list available voices (VoiceStudio extension). |
A contract test (tests/test_agentic_provider_contract.py) pins this request
shape in CI, so the recipes below won't silently break.
pipecat (recommended)
pipecat (BSD-2) runs as a Python library inside your own process — no extra server. Point its OpenAI TTS/STT services at VoiceStudio:
from pipecat.services.openai.tts import OpenAITTSService
from pipecat.services.openai.stt import OpenAISTTService
tts = OpenAITTSService(
base_url="http://localhost:3900/v1",
api_key="not-needed-locally", # any string; VoiceStudio ignores it unless OMNIVOICE_API_KEY is set
voice="<your-voice-profile-id>", # from GET /v1/audio/voices, or "default"
model="omnivoice", # or any installed engine id
sample_rate=24000, # matches VoiceStudio's default output
)
stt = OpenAISTTService(
base_url="http://localhost:3900/v1",
api_key="not-needed-locally",
)
Drop those into any pipecat pipeline (VAD, turn-taking, and LLM stay local
too). A minimal runnable example is in
examples/agentic/pipecat_minimal.py.
LiveKit Agents
LiveKit Agents (Apache-2.0) needs a
LiveKit media server alongside, but its OpenAI plugin takes the same
base_url:
from livekit.plugins import openai
tts = openai.TTS(base_url="http://localhost:3900/v1", api_key="x", voice="<profile-id>")
stt = openai.STT(base_url="http://localhost:3900/v1", api_key="x")
Choose LiveKit over pipecat only when you need its WebRTC/SIP scale; for a single local agent, pipecat is lighter.
Remote backend
Running VoiceStudio on a remote GPU box? Use that backend's URL
as base_url and pass its OMNIVOICE_API_KEY as the api_key — the same
bearer the rest of the app uses. Keep it on your tailnet, not the open
internet.
Use your own voice responsibly
When an agent speaks in a cloned voice, prefer a profile you've marked verified own voice (Settings → a voice profile → Voice ownership). That consent lock is what gates the heavier agentic features as they land, and it's the honest default for "an AI is speaking as me."