Skip to main content

tuner-tts-observer

TTS observability for Tuner. Wraps your TTS provider's synthesis stream to capture agent transcript and latency — Tuner observes synthesis, it does not own or drive it. Removing the context managers leaves your synthesis code completely unaffected.

Supported adapters

Provider Adapter Status
Cartesia CartesiaAdapter ✅ Supported
ElevenLabs — SOON
OpenAI TTS — SOON

Need a provider that isn't listed? Extend BaseTTSAdapter — see Custom providers below.

Installation

pip install tuner-core tuner-tts-observer

WebSocket support (recommended) requires the websockets extra:

pip install "tuner-tts-observer[cartesia]"
# equivalent to: pip install "cartesia[websockets]>=1.0"

Usage

WebSocket is the production-standard pattern for real-time voice agents. It supports word-level interruption detection — when the user interrupts the agent, Tuner records only the words actually spoken, not the full intended response.

import os
from cartesia import AsyncCartesia
from tuner_core import TunerConfig, TunerSession
from tuner_tts_observer import CartesiaAdapter

cartesia_client = AsyncCartesia(api_key=os.environ["CARTESIA_API_KEY"])

session = TunerSession(config=TunerConfig.from_env(), call_id=call_id)
adapter = session.attach(CartesiaAdapter())

# Open one WebSocket connection per call — reused across turns
async with cartesia_client.tts.websocket_connect() as tts_ws:

    # Per turn:
    ctx = await tts_ws.context(
        model_id="sonic-2",
        voice={"id": "your-voice-id", "mode": "id"},
        output_format={"container": "raw", "encoding": "pcm_s16le", "sample_rate": 16000},
        add_timestamps=True,  # required for word-level interruption detection
    )
    await ctx.push(agent_text)
    await ctx.no_more_inputs()

    async with adapter.track_ws(agent_text) as tracked:
        async for chunk in tracked(ctx.receive()):
            if barge_in_event.is_set():
                break  # interrupted — Tuner records only what was spoken
            if chunk.audio:
                await websocket.send_bytes(chunk.audio)

await session.flush()

SSE (legacy)

SSE is the simpler pattern, available for HTTP-only stacks or existing integrations. Interruption detection is supported but spoken text cannot be cut accurately.

import os
from cartesia import Cartesia
from tuner_core import TunerConfig, TunerSession
from tuner_tts_observer import CartesiaAdapter

cartesia_client = Cartesia(api_key=os.environ["CARTESIA_API_KEY"])

session = TunerSession(config=TunerConfig.from_env(), call_id=call_id)
adapter = session.attach(CartesiaAdapter())

with adapter.track(agent_text) as tracked:
    for chunk in tracked(cartesia_client.tts.sse(
        model_id="sonic-2",
        transcript=agent_text,
        voice={"id": "your-voice-id", "mode": "id"},
        output_format={"container": "raw", "encoding": "pcm_s16le", "sample_rate": 16000},
    )):
        if chunk.audio:
            await websocket.send_bytes(chunk.audio)

await session.flush()

Custom providers

For providers other than Cartesia, extend BaseTTSAdapter from tuner_tts_observer — its docstring documents the full contract (timestamping, _record_agent_turn() / _record_tts_usage(), mark_interrupted()) with a worked example.

What gets captured automatically

Signal SSE WebSocket
Agent transcript text ✓ full text ✓ spoken words only on interruption
Turn start timestamp ✓ (first audio chunk) ✓
Turn duration ✓ (acoustic length) ✓
TTS TTFB ✓ ✓
E2e latency ✓ ✓
LLM latency ✓ ✓
interrupted: true on barge-in ✓ ✓
Word-accurate spoken text cut ✗ ✓

Development

uv sync
make test

Metadata

Release files for tuner-tts-observer 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tuner-tts-observer 0.1.0
File Size Uploaded Provenance Actions
tuner_tts_observer-0.1.0.tar.gz 16.2 kB Without provenance Details for tuner_tts_observer-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for tuner-tts-observer 0.1.0
File Interpreter ABI Platform Actions
tuner_tts_observer-0.1.0-py3-none-any.whl Python 3 none any Details for tuner_tts_observer-0.1.0-py3-none-any.whl

Total release size: 29.0 kB

Release files / tuner_tts_observer-0.1.0.tar.gz

Download URL tuner_tts_observer-0.1.0.tar.gz
Size 16.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d21799475913aae39e74336bb233f67c51e85f02a205e32030bb3850da285277
BLAKE2b-256 checksum
How to use checksums
d0ee00b3908c9f4c434be56d8b72f45b6b19aed2af16267ce813a760b6f5b1ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Release files / tuner_tts_observer-0.1.0-py3-none-any.whl

Download URL tuner_tts_observer-0.1.0-py3-none-any.whl
Size 12.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
260b616f7dd4b4678fa2bc837b354159bf50cc8661a81727eacedda11d6e87c6
BLAKE2b-256 checksum
How to use checksums
46c897fd65754592e598732db1ddfbb5b349975f162c4756dc1f3a5d6875a737
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Security for tuner-tts-observer 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page