Skip to main content

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), the POST /v1/voice/token AccessToken endpoint, a VoiceRoom facade (inbound resample to PCM16 mono 16 kHz, outbound 24 kHz publish), a Session state machine, and per-user voice-call concurrency via pg_try_advisory_xact_lock.
  • V2 — Streaming STT. A provider-independent StreamingSTT protocol (mirroring the core ChatBackend adapter boundary), a Deepgram Nova-3 backend, and a Silero VAD (ONNX-only) endpointing adapter.
  • V3 — Streaming TTS. A provider-independent StreamingTTS protocol, a Cartesia Sonic backend, per-persona voice as a first-class identity attribute, and mid-utterance cancel() (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.

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):

  1. auth — cloud verifies the Clerk JWT; community returns a fixed local owner with no token required.
  2. pre-flight — RLS-scoped persona-ownership check + credit gate (both no-ops in community).
  3. mint — a short-lived LiveKit AccessToken is signed with the LiveKit API secret, granting access to a per-session room.
  4. 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

persona_voice-1.0.0.tar.gz (250.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

persona_voice-1.0.0-py3-none-any.whl (175.5 kB view details)

Uploaded Python 3

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

Hashes for persona_voice-1.0.0.tar.gz
Algorithm Hash digest
SHA256 37aa9619ff9c1de7344fb3b460c411bcd71e09ddb2fa66141ae982e31aad8f78
MD5 3d21e03107e40e7cd7bc6e3bea9e1ed4
BLAKE2b-256 bf7a43166ae9eb350a8e3a54d7037fc93ad1a94f7dd1595d0468965a71590d7f

See more details on using hashes here.

File details

Details for the file persona_voice-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for persona_voice-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 00041c8487465dd19f5a262aa60059487fad6cac584b618be2bfa06efa6d1c13
MD5 f9222dd8ead91e2f12118a508dbd599e
BLAKE2b-256 f6bed91db53b831042d0a40e2c64d7fdd1f1d6b25a165808f059af395bdbeb77

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page