Skip to main content

Server-side Python SDK for Vox-hosted WebRTC sessions.

Project description

vox-rtc-server

Trusted Python SDK for Vox-hosted WebRTC conversations. It creates sessions over HTTP and controls them over PondSocket.

Install

pip install vox-rtc-server

Pass api_key=... or set VOX_API_KEY.

PondSocket session

import asyncio
import os

from vox_rtc_server import ClientEventEnvelope, SessionConfig, VoxRtcServerClient


async def main() -> None:
    client = VoxRtcServerClient(
        http_base="http://vox-service.vox.svc.cluster.local:11435",
        api_key=os.environ.get("VOX_API_KEY"),
    )
    bootstrap, session = await client.create_controlled_session()
    session.on_transcript(
        lambda event: print("user said:", event.transcript, event.speech_context)
    )
    session.on_browser_event(lambda event: print(event.event, event.payload))
    session.configure(SessionConfig(
        stt_model="parakeet-stt:tdt-0.6b-v3",
        tts_model="kokoro-tts:v1.0",
        voice="af_heart",
        turn_profile="browser_default",
        speech_context=True,
    ))
    session.send_text_response("Hello from Python.")
    session.send_client_event(ClientEventEnvelope(event="render.ready", payload=True))
    print("session:", bootstrap.session_id)


asyncio.run(main())

Speech context is opt-in and final-only. When enabled, the final TranscriptEvent.speech_context is a typed SpeechContext; otherwise it is None.

Schema v2 exposes timestamped emotions and vocal speaker spans plus environmental sounds. Sound spans also carry a score from 0 to 1:

def handle_transcript(event: TranscriptEvent) -> None:
    context = event.speech_context
    if context is None:
        return

    for span in context.emotions or []:
        print("emotion", span.label, span.start_ms, span.end_ms)
    for span in context.vocal or []:
        print("vocal event", span.label, span.start_ms, span.end_ms)
    for sound in context.sounds or []:
        print("environment", sound.label, sound.score)

    if context.status != "complete":
        print("unavailable tracks", context.unavailable)

A partial result identifies the unavailable "speaker" or "sounds" track; a failed result identifies both. Unsupported or malformed context is decoded as None without dropping the transcript event.

Acknowledged response starts

start_response stays fire-and-forget. When you want the positive acknowledgement before pumping deltas, use start_response_and_wait, which correlates the response.created event (or the typed error) with the generation_id it sent:

from vox_rtc_server import ResponseOptions, ResponseOutputOptions

ack = await session.start_response_and_wait(
    ResponseOptions(
        output=ResponseOutputOptions(
            model="qwen3-tts:0.6b-clone",
            voice="samantha",
            language="fr",
            speed=0.9,
            params={"temperature": 0.7},
        )
    )
)
if ack.accepted:
    print("effective output:", ack.output)
    session.append_response_text("Hello.")
    session.commit_response()
else:
    print("start rejected:", ack.error.code if ack.error else None)

You can also thread your own generation id through every response command via ResponseOptions(generation_id="gen-42"); response lifecycle events (ResponseEvent, InterruptionEvent) expose the echoed generation_id. The response-scoped output is optional. Vox fills omitted fields from the session configuration and echoes the immutable effective selection on the acknowledgement and ResponseEvent.

Error handling

ErrorEvent carries code (stable slug), recoverable, and an optional generation_id scoping the failure to one response generation. Known codes are exported as ERROR_CODE_* constants (response_rejected_turn_state, response_rejected_user_speech, response_stale_generation, response_already_active, response_failed, command_invalid, session_failed).

Only recoverable is False (or the transport itself closing) should end the call. Recoverable errors are per-command failures: handle them and keep the session running. Old Vox servers omit code and recoverable; the SDK then defaults recoverable to True, so treat such errors as recoverable unless the transport closed.

on_signaling_error surfaces the rtc.signaling_error control event (WebRTC signaling failures such as a rejected local description) as a SignalingErrorEvent carrying message and a numeric generation. This event is terminal: Vox closes the session immediately after emitting it, so there is no recoverable field — treat it as the end of the call, not a per-command error like the conversation error stream.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vox_rtc_server-0.2.5.tar.gz (47.5 kB view details)

Uploaded Source

Built Distribution

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

vox_rtc_server-0.2.5-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file vox_rtc_server-0.2.5.tar.gz.

File metadata

  • Download URL: vox_rtc_server-0.2.5.tar.gz
  • Upload date:
  • Size: 47.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for vox_rtc_server-0.2.5.tar.gz
Algorithm Hash digest
SHA256 676c824ee2b893cf3549d79c0ce83b47921efcea97b02d430b298d83a2743996
MD5 61193a5de0cc7dc5e1c298b70a3ddef4
BLAKE2b-256 51a1b5b85b99ef9173d31ffc989dcc040ca26aad53f27884eacb769159a4339d

See more details on using hashes here.

File details

Details for the file vox_rtc_server-0.2.5-py3-none-any.whl.

File metadata

  • Download URL: vox_rtc_server-0.2.5-py3-none-any.whl
  • Upload date:
  • Size: 12.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for vox_rtc_server-0.2.5-py3-none-any.whl
Algorithm Hash digest
SHA256 056baf598483680019fad9f9ef5124c630b4b4d9ac62a146cf864f68f3613ec8
MD5 e54510b1d038250919970338230ac6dd
BLAKE2b-256 8f2e3f4b32f0fe31b90a5342c8176ca298debfe80b9120be0bbb0bc69de52a84

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