pipecat-floe
Floe services for Pipecat. Meter every leg of a voice agent — LLM, STT, TTS — per call, on one Floe key, with pre-call spend caps.
BYOK-first. Keep your own vendor key (e.g. OpenAI) and route the LLM and TTS
legs through Floe with provider_key=...: Floe meters the call and enforces your
spend caps, and bills only its service fee — your model bill stays with your
vendor. Prefer no vendor accounts? Drop provider_key and go keyless — Floe
manages the provider keys for you. Streaming STT is keyless today (Floe-managed
Deepgram). Either way: one Floe key, one ledger, one budget.
Three drop-in Pipecat services:
FloeLLMService— OpenAI-compatible LLM routed through Floe.FloeTTSService— OpenAI-compatible text-to-speech routed through Floe.FloeSTTService— streaming speech-to-text over Floe's WebSocket.
Built and maintained by Floe Labs — the company behind Floe, the service these adapters route to.
Community integration. Tested with
pipecat-ai1.7.0 (Python 3.11+).
Install
pip install pipecat-floe
This pulls in pipecat-ai, websockets, httpx, and loguru. For the
example bot you also want a transport + VAD:
pip install "pipecat-ai[silero,websocket]"
Pipecat version compatibility
Built and verified against pipecat-ai 1.7.0 (Python 3.11+). The services
subclass Pipecat's own OpenAILLMService, OpenAITTSService, and
WebsocketSTTService. Those base classes are stable, but Pipecat's import paths
and constructor kwargs do shift between releases — pin pipecat-ai and
re-verify when you upgrade.
Quickstart
One key powers all three legs. Set FLOE_API_KEY in your environment (get a key
at dev-dashboard.floelabs.xyz) — that alone
runs the keyless path. The BYOK snippet below additionally reads your own
vendor key (OPENAI_API_KEY); drop provider_key= to run keyless with no vendor
key at all.
import os
from pipecat_floe import FloeSTTService, FloeLLMService, FloeTTSService
# BYOK — bring your own vendor key; Floe meters + caps and bills only its fee.
oai = os.environ["OPENAI_API_KEY"]
llm = FloeLLMService(model="openai/gpt-4o-mini", provider_key=oai)
tts = FloeTTSService(model="openai/tts-1", voice="alloy", provider_key=oai)
stt = FloeSTTService() # streaming STT — keyless (Floe-managed Deepgram)
# ...or go fully keyless: drop provider_key and Floe manages the vendor keys.
# Then drop stt / llm / tts into a Pipecat Pipeline as usual.
Three legs, one Floe key, one budget. Each service reads FLOE_API_KEY from the
environment (or pass api_key=...) — that's your Floe auth, separate from the
optional provider_key (your upstream vendor key, BYOK). A single spend cap on
the agent bounds the whole run — STT, LLM, and TTS together.
See examples/bot.py for a runnable pipeline wiring a
WebSocket transport → STT → LLM → TTS.
Run the example
cd examples
pip install -r requirements.txt
cp .env.example .env # fill in FLOE_API_KEY
python bot.py # WebSocket server on ws://localhost:8765
Connect an audio WebSocket client to ws://localhost:8765 and talk. Full
instructions in examples/README.md.
Public API
FloeLLMService(
*, model="openai/gpt-4o-mini", api_key=None,
base_url="https://credit-api.floelabs.xyz/v1", task_id=None,
provider_key=None, **kwargs
)
FloeTTSService(
*, model="openai/tts-1", voice="alloy", api_key=None,
base_url="https://credit-api.floelabs.xyz/v1", task_id=None,
provider_key=None, **kwargs
)
FloeSTTService(
*, model="deepgram/nova-3", encoding="linear16", sample_rate=16000,
language="en", api_key=None,
base_url="wss://credit-api.floelabs.xyz/v1/audio/transcriptions/stream",
**kwargs
)
api_keydefaults to theFLOE_API_KEYenvironment variable; aValueErroris raised if neither is set.task_id(LLM/TTS) tags calls with anX-Floe-Task-Idheader so a per-task budget can bound one conversation.provider_key(LLM/TTS — BYOK) sends your upstream vendor key as theX-Floe-Provider-Keyheader, so Floe routes the call on your key and bills only its service fee (still metered, still spend-capped). Omit it for the keyless path. Streaming STT has no per-request BYOK — it uses Floe's managed Deepgram key.**kwargspass through to the underlying Pipecat base class (temperature, custom settings, keepalive, reconnect options, ...).
Limits / footguns
| Limit | Detail |
|---|---|
| STT is a dedicated plugin, not a base-URL swap | The LLM and TTS legs are OpenAI-compatible base-URL swaps. Streaming STT is not — FloeSTTService speaks Floe's own WebSocket protocol (raw PCM up, JSON transcripts down). You cannot point Pipecat's OpenAISTTService at Floe for streaming. |
| Model IDs must be fully qualified | Use provider/model, e.g. openai/gpt-4o-mini, anthropic/claude-sonnet-4-6, deepgram/nova-3, openai/tts-1. A bare gpt-4o-mini will be rejected by Floe. |
| STT audio format | PCM only, in the declared encoding (linear16 / mulaw / alaw) at sample_rate 8000–48000. Pipecat delivers linear16 PCM by default, which matches. |
| TTS sample rate | The underlying OpenAI TTS service emits 24 kHz PCM; passing a different sample_rate logs a warning. |
| BYOK is LLM/TTS only | provider_key (BYOK) is honored on the LLM and TTS legs — the keyless gateway accepts an optional X-Floe-Provider-Key header. Streaming STT has no per-request BYOK: it runs on Floe's managed Deepgram key regardless of provider_key. |
task_id / provider_key on TTS |
Attached via a custom httpx client's default headers. If you pass your own http_client, both are ignored for TTS (add the headers to that client yourself). |
| Welcome credit | A new Floe agent key comes with welcome credit that covers the first calls. After that, keep the agent funded or capped — an empty balance surfaces as a {"type":"error","code":"insufficient_balance"} on STT and an error frame on LLM/TTS. |
| Pipecat version | Pinned to pipecat-ai 1.7.0 (see above). Re-verify on upgrade. |
How it works
- LLM / TTS — thin subclasses of Pipecat's
OpenAILLMService/OpenAITTSServicepointed athttps://credit-api.floelabs.xyz/v1with your Floe key. Passprovider_key=and it rides as anX-Floe-Provider-Keyheader, so Floe meters + caps the call but bills only its fee on your upstream key (BYOK); omit it for keyless. Streaming, metrics (usage + TTFB), and OpenTelemetry tracing are inherited unchanged. - STT — a subclass of Pipecat's
WebsocketSTTService(the same base used by Deepgram and Gladia). It openswss://credit-api.floelabs.xyz/v1/audio/transcriptions/streamwith anAuthorization: Bearer <FLOE_API_KEY>header, streamsframe.audioPCM up, and mapsis_final:false→InterimTranscriptionFrame,is_final:true→TranscriptionFrame. A server{"type":"error"}is pushed to the pipeline as anErrorFrameand the stream is torn down cleanly. Reconnect-with-backoff and audio buffering come from the base class.
Per-turn cost receipt
FloeLLMService logs a one-line cost receipt after every LLM turn — on by
default (pipecat-floe is a metering-branded service, so showing the cost is
on-brand). One line to disable:
llm = FloeLLMService(model="openai/gpt-4o-mini", cost_receipts=False)
The receipt is logged at INFO via loguru (real line, captured against prod):
floe · gpt-4o · $0.0012 est · left $99.88
The cost half is priced locally by floe-guard
(free, offline, no key — est means a local estimate). The left $… budget half
only appears when FLOE_API_KEY is set: it's a best-effort, fail-closed read of
your hosted Floe balance (fetched off the event loop and cached ~30s, so it never
stalls a turn), so a failed read simply drops the budget and still shows the
cost. Without a key you get the cost line alone (floe · gpt-4o · $0.0075 est).
A model floe-guard can't price logs nothing — fail-closed, never a
fabricated $0. A live-prod screenshot with the budget half is captured
separately with a funded key.
License
MIT — see LICENSE.
Metadata
Release files for pipecat-floe 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pipecat_floe-0.3.0.tar.gz | 20.3 kB | Without provenance | Details for pipecat_floe-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pipecat_floe-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for pipecat_floe-0.3.0-py3-none-any.whl |
Total release size: 36.6 kB
Release files / pipecat_floe-0.3.0.tar.gz
| Download URL | pipecat_floe-0.3.0.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f7cfd5f8216722e1953a08665b6163ceea6689c6e194b6e1d65c5d3a4eaf5df6
|
|
BLAKE2b-256 checksum How to use checksums |
7103780fcf8cd1472d3356d155ce9d91c7b25d0d6ea461443e813f6b1446849f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / pipecat_floe-0.3.0-py3-none-any.whl
| Download URL | pipecat_floe-0.3.0-py3-none-any.whl |
|---|---|
| Size | 16.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dbbc79d03f84fbe83fd4d1ed91549abfcdadb746d3361263bd7986debec65fef
|
|
BLAKE2b-256 checksum How to use checksums |
68d4bb202040d2c0652f9ec65b0755b233f6bc23ac80001301ebca917c2c1390
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for pipecat-floe 0.3.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.