persona-voice
The real-time voice trunk for Open Persona — LiveKit WebRTC transport, streaming STT/TTS, turn-taking, and persona-conditioned generation.
persona-voice is the voice layer of the Open Persona
stack: a real-time, full-duplex voice surface that layers sub-second-latency
audio onto the same persona, typed memory, and tier-routed runtime the text
stack uses. The voice persona is the persona — never a thin prompt bypass.
What it is / where it fits
persona-voice runs in-process with persona-core (no separate language,
no cross-process IPC) so the typed-memory stores, audit log, and credits
service compose directly. From V5 it also composes
persona-runtime (prompt builder, router, shared
retrieval) so a voice turn is conditioned exactly like a text turn. The
layering stays acyclic: voice → runtime → core; runtime never imports voice.
WebRTC transport is provided by a LiveKit OSS substrate. The browser joins
a LiveKit room; an in-process agent worker joins the same room and becomes the
persona. The package's HTTP surface is a single endpoint —
POST /v1/voice/token — that mints a short-lived LiveKit AccessToken after
auth, ownership, and credit pre-flights.
Like the rest of the stack, it carries an edition stance (PERSONA_EDITION):
- cloud — the token endpoint verifies the Clerk JWT (today's deployed behavior), scopes DB access by RLS, and meters credits.
- community — no-auth local voice: a fixed local owner, no JWT, unmetered, single-owner ownership.
Features
- V1 — WebRTC transport. LiveKit OSS substrate (
livekit>=1.1), thePOST /v1/voice/tokenAccessToken endpoint, aVoiceRoomfacade (inbound resample to PCM16 mono 16 kHz, outbound 24 kHz publish), aSessionstate machine, and per-user voice-call concurrency viapg_try_advisory_xact_lock. - V2 — Streaming STT. A provider-independent
StreamingSTTprotocol (mirroring the coreChatBackendadapter boundary), a Deepgram Nova-3 backend, and a Silero VAD (ONNX-only) endpointing adapter. - V3 — Streaming TTS. A provider-independent
StreamingTTSprotocol, a Cartesia Sonic backend, per-persona voice as a first-class identity attribute, and mid-utterancecancel()(the barge-in foundation). - V4 — Turn-taking + barge-in. A four-state conversational machine (Listening / UserSpeaking / Processing / PersonaSpeaking), automatic endpointing, fast-and-discriminating interruption, a cancel watchdog, and full-loop latency attribution — pure-Python decision logic on the V1/V2/V3 seams.
- V5 — Persona / runtime / memory integration. Fills V4's reply-producer seam with real persona-conditioned, tier-routed, streaming, cancellable generation, and writes voice turns to the same episodic store as text (unified memory) — plus a voice latency-routing gate, off-critical-path history compaction, conversational voice tools, and barge-over-honest memory.
- V6 — Frontend voice client (in development). Browser-side audio plumbing
- UI in
persona-web; an optional dev agent launcher fires from the token endpoint.
- UI in
Install / run
persona-voice is a uv workspace package. From the repo root:
uv sync # install the workspace
persona-voice is consumed by persona-api; there is no standalone CLI. The
token-issuance app boots from persona_voice.http.app:
uv run uvicorn persona_voice.http.app:create_app --factory --port 8001
You also need a running LiveKit OSS Server (docker compose up -d livekit)
and, for real STT/TTS, a Deepgram key (PERSONA_STT_API_KEY) and a Cartesia
key (PERSONA_TTS_API_KEY). For local web development, packages/api/run-local.sh
boots the api (:8000) and persona-voice (:8001) together.
Test
uv run pytest packages/voice # unit (default)
uv run pytest packages/voice -m integration # live LiveKit + Postgres
uv run pytest packages/voice -m external # live Deepgram / Cartesia
uv run mypy packages/voice/src
uv run ruff check packages/voice
Usage / key surfaces
The token flow. A client that wants a voice call calls
POST /v1/voice/token with a persona_id (and optional conversation_id):
- auth — cloud verifies the Clerk JWT; community returns a fixed local owner with no token required.
- pre-flight — RLS-scoped persona-ownership check + credit gate (both no-ops in community).
- mint — a short-lived LiveKit AccessToken is signed with the LiveKit API secret, granting access to a per-session room.
- response —
{ token, room_name, livekit_url }. The client joins the room over WebRTC; the in-process agent joins the same room as the persona.
GET /v1/voices returns the provider voice catalogue (optionally filtered by
language) for the persona voice-selector, degrading to an empty list when TTS
is unconfigured.
Architecture (brief)
browser ──WebRTC──▶ LiveKit OSS Server ◀──WebRTC── agent worker (in-process)
▲ │
└── POST /v1/voice/token ──▶ persona-voice ──▶ persona-runtime ──▶ persona-core
(auth · ownership · credits · mint) (STT → turn-taking → reply → TTS)
The trunk owns the LiveKit substrate, audio frame plumbing, the streaming STT
and TTS protocols + concrete backends, the session lifecycle, voice-call
concurrency, the persona-conditioned reply producer + unified-memory write, and
the additive VoiceLog. Per-minute billing and the V6 frontend land later.
License
persona-voice is licensed under the MIT License — see LICENSE.
It is true OSI open source: free for any use, including commercial. It
is part of the MIT-licensed Open Persona engine
(persona-core / persona-runtime / persona-voice); the application layer
(persona-api / persona-web) is separately licensed
PolyForm Noncommercial 1.0.0 (source-available, noncommercial).
Links
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file persona_voice-1.0.0.tar.gz.
File metadata
- Download URL: persona_voice-1.0.0.tar.gz
- Upload date:
- Size: 250.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37aa9619ff9c1de7344fb3b460c411bcd71e09ddb2fa66141ae982e31aad8f78
|
|
| MD5 |
3d21e03107e40e7cd7bc6e3bea9e1ed4
|
|
| BLAKE2b-256 |
bf7a43166ae9eb350a8e3a54d7037fc93ad1a94f7dd1595d0468965a71590d7f
|
File details
Details for the file persona_voice-1.0.0-py3-none-any.whl.
File metadata
- Download URL: persona_voice-1.0.0-py3-none-any.whl
- Upload date:
- Size: 175.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
00041c8487465dd19f5a262aa60059487fad6cac584b618be2bfa06efa6d1c13
|
|
| MD5 |
f9222dd8ead91e2f12118a508dbd599e
|
|
| BLAKE2b-256 |
f6bed91db53b831042d0a40e2c64d7fdd1f1d6b25a165808f059af395bdbeb77
|