Skip to main content

echospeaks

echospeaks.ai

Sentence-level TTS audio cache for pipecat voice pipelines. Audio lives in echo-server (the pod-shared cache service; it keeps its own L1/L2 internally) - there is no client-side store. Caching is enabled by passing an api_key in cache_config; without it everything passes through untouched and the pipeline behaves fully stock. To get a key, visit echospeaks.ai and contact us.

Layout

echospeaks/
  defaults.py   SDK-wide defaults
  common/       shared dataclasses + logger
  cache/        cache keys + the echo-server client
  pipecat_tts/  the pipecat integration (read.py, write.py, plan.py)

How it works

Two pipeline processors around the host's completely stock TTS service:

  • Read - EchoTTSCacheRead (echospeaks.pipecat_tts.read): placed before the tts. Aggregates LLM tokens into sentences (the TTS receives pre-aggregated sentences, so its own aggregator never engages) and asks echo-server per sentence (0.5s bounded) - a hit is swallowed (the TTS never sees it); a miss flows through and is registered in the shared turn plan for capture.
  • Write - EchoTTSCacheWrite (echospeaks.pipecat_tts.write): placed right after the tts. Slices each miss sentence's audio out of the turn's shared provider context by word timestamps and fire-and-forgets a POST to echo-server (audio base64-encoded inside the v1 JSON envelope; decoded on fetch), and injects cached hit audio at the exact sentence boundary so sentences always play in LLM order. Interruptions discard partial buffers, so truncated audio is never stored.

Standalone utterances (TTSSpeakFrame) are cached too. Fixed prompts the host pushes directly (never through the LLM) are cached as one entry over the full utterance. A miss forwards the original frame and captures its audio; a hit swallows it and replays the cached audio with the same frame sequence a live utterance produces. Fixed prompts repeat on every call, making them the highest-value entries in the cache.

echo-server behavior is strictly fail-open: the lookup is bounded by a 0.5s timeout and every error (down, slow, 401, 5xx) degrades to a plain miss.

Install

pip install echospeaks

pipecat-ai comes from your own app (the pipeline the processors go into); pip install "echospeaks[pipecat]" pulls it in for a standalone install.

Usage

The TTS service stays completely stock: the cache is two pipeline processors around it. The read side aggregates LLM tokens into sentences (so the TTS receives pre-aggregated sentences and its own aggregator never engages), swallows cache hits, and forwards misses; the paired writer captures each miss sentence's audio for storing and injects cached hit audio at the exact sentence boundary, so sentences always play in LLM order for any hit/miss pattern.

from pipecat.services.elevenlabs.tts import ElevenLabsTTSService
from echospeaks.pipecat_tts import EchoTTSCacheRead, EchoTTSCacheWrite

tts = ElevenLabsTTSService(                          # untouched, fully stock
    api_key=ELEVENLABS_API_KEY,
    settings=ElevenLabsTTSService.Settings(model="eleven_turbo_v2_5", voice=VOICE_ID),
)

EchoTTSCacheRead.configure({
    "api_key": ECHO_SERVER_API_KEY,
    "provider": "elevenlabs",
    "voice_id": VOICE_ID,
    "model_id": "eleven_turbo_v2_5",
    "tag": "my-campaign",
})

pipeline = Pipeline([
    ...,
    llm,
    EchoTTSCacheRead(),    # picks up the configure()d config
    tts,
    EchoTTSCacheWrite(),   # pairs itself with the read upstream at StartFrame
    transport.output(),
    ...,
])

EchoTTSCacheRead.current() returns this call's instance, whose stats property exposes the raw counters for the host's own logs/metrics:

s = EchoTTSCacheRead.current().stats
# {"hits": 6, "misses": 3, "hit_chars": 214, "miss_chars": 101,
#  "total_chars": 315, "total_sentences": 9, "hit_rate": 0.679}
log.info(f"cache hits={s['hits']} misses={s['misses']} hit_rate={s['hit_rate']:.0%}")

hit_rate is character-weighted (characters are what synthesis costs), 0..1.

Without an api_key (or the keying inputs) everything passes through untouched. Segmentation and in-order injection use word timestamps; ElevenLabs and Cartesia both provide them. Without word timestamps the writer degrades gracefully: single-sentence turns still store, mid-turn hits inject at turn end.

TTSSpeakFrames need no extra wiring - they pass through the same read processor and are cached whole. One trade-off to know: a speak utterance waits for its lookup before synthesis starts, so its time-to-first-audio shifts by the lookup round trip (~60-250ms, bounded at 0.5s fail-open) on a miss - and skips synthesis entirely on a hit.

cache_config reference

One dict holds every host tunable. Missing or None keys fall back to the defaults in echospeaks/defaults.py; unknown keys are warned about and ignored (never a crash).

Key Default What it does
api_key (unset) echo-server API key; setting it enables the cache. Get one at echospeaks.ai.
provider / voice_id / model_id (unset) Identify the downstream TTS for cache keying. Missing any of them disables caching.
cache_settings (unset) Optional dict of audio-affecting settings folded into the cache key. Supported: speed, stability, similarity_boost, style, use_speaker_boost, language, controls, emotion, pitch, pronunciation_dict_id. Other keys are ignored.
replay_chunk_bytes 960 Hit-replay slice size (~30 ms). Smaller = finer barge-in stop, more frame overhead.
tag (unset) Grouping label (agent id, campaign, ...) recorded per store for filtered listings (?tag=). Not part of the cache key.
debug False Verbose per-frame DEBUG logs (word attribution, holds, cuts). INFO HIT/MISS lines are always on.

How the dict is sourced is the host's business - env vars, a config file, a per-tenant document; the SDK only sees the final dict.

Tests

uv sync && uv run pytest

Includes an HTTP round-trip test against an in-process fake echo-server (auth, miss, store, hit, delete, fail-open).

Metadata

Release files for echospeaks 0.3.2

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

Source distribution (sdist)

Source distribution for echospeaks 0.3.2
File Size Uploaded Provenance Actions
echospeaks-0.3.2.tar.gz 28.9 kB Without provenance Details for echospeaks-0.3.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for echospeaks 0.3.2
File Interpreter ABI Platform Actions
echospeaks-0.3.2-py3-none-any.whl Python 3 none any Details for echospeaks-0.3.2-py3-none-any.whl

Total release size: 55.6 kB

Release files / echospeaks-0.3.2.tar.gz

Download URL echospeaks-0.3.2.tar.gz
Size 28.9 kB
Tags Source
SHA-256 checksum
How to use checksums
49280e26b8bd8fe4db6199d07bc6f0d4870592a91a5bb33b89f06613c3df58b2
BLAKE2b-256 checksum
How to use checksums
b6de3a7ea4102603d054f72371fb0d470d6194dee1d2743cfc9ed60a3010b1b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.5

Release files / echospeaks-0.3.2-py3-none-any.whl

Download URL echospeaks-0.3.2-py3-none-any.whl
Size 26.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
60d137c5be2db70aafa5afa607a720cf0ff48b00e66743e24e4c8334f7d26937
BLAKE2b-256 checksum
How to use checksums
8a742705137fc227c855e76f46f309a877a9adc6320bc57a71a12a9db3a0512c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.5

Security for echospeaks 0.3.2

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.

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