Inworld
Text-to-speech with InworldTTSService (WebSocket) and InworldHttpTTSService (HTTP).
Overview
pipedog ports both of Pipecat's Inworld text-to-speech services:
InworldTTSService: Inworld TTS over a bidirectional WebSocket, with several audio contexts on one connection and word-level timestamps. Lowest latency.InworldHttpTTSService: Inworld TTS over HTTP, streaming (/tts/v1/voice:stream) or in one piece (/tts/v1/voice), also with word-level timestamps.
Upstream page
Pipecat's documentation for the same services.
Source
packages/inworld/src/tts.ts.
Inworld docs
Inworld TTS models and voices.
Installation
bun add @pipedog/inworldimport { InworldHttpTTSService, InworldTTSService } from "@pipedog/inworld/tts";Prerequisites
- An Inworld account and an API key from the Inworld portal.
- Pass the key as
apiKey(the Base64 key Inworld gives you). The examples read it fromINWORLD_API_KEY.
InworldTTSService
Configuration
Prop
Type
Settings
Runtime-updatable settings, passed as settings: new InworldTTSService.Settings({...})
(InworldTTSSettings). Any setting you leave out keeps the default below.
InworldHttpTTSService uses the same settings class.
| Setting | Type | Default | Description |
|---|---|---|---|
voice | string | "Ashley" | Inworld voice id. |
model | string | "inworld-tts-2" | TTS model. |
language | Language | null | null | Language of the text. |
speakingRate | number | null | null | Speaking rate. |
temperature | number | null | null | Sampling temperature. |
deliveryMode | "STABLE" | "BALANCED" | "CREATIVE" | null | null | Stability vs. expressiveness. Only inworld-tts-2. |
Usage
import { TTSUpdateSettingsFrame } from "@pipedog/core/frames/frames";
import { Language } from "@pipedog/core/transcriptions/language";
import { InworldHttpTTSService, InworldTTSService } from "@pipedog/inworld/tts";
const tts = new InworldTTSService({
apiKey: process.env.INWORLD_API_KEY ?? "",
settings: new InworldTTSService.Settings({
voice: "Ashley",
model: "inworld-tts-2",
language: Language.EN,
deliveryMode: "BALANCED",
}),
});Change the voice mid-call with a TTSUpdateSettingsFrame:
// Applies from the next context the service opens.
const update = new TTSUpdateSettingsFrame({
delta: new InworldTTSService.Settings({ voice: "Dennis", temperature: 0.9 }),
});InworldHttpTTSService
Configuration
Prop
Type
Usage
const httpTts = new InworldHttpTTSService({
apiKey: process.env.INWORLD_API_KEY ?? "",
// false posts to /tts/v1/voice and gets the audio in one piece.
streaming: true,
settings: new InworldHttpTTSService.Settings({ voice: "Ashley", speakingRate: 1.1 }),
});Notes
- Both output PCM at the pipeline's sample rate and push
TTSTextFrames aligned to Inworld's word timestamps. When no timestamps arrive, the text is pushed as a whole. InworldTTSServicelets the server decide when to flush buffered text (autoMode, on by default) and closes a context on interruption.
Runtime notes
| Runtime | Works | What it needs |
|---|---|---|
| Bun | ✅ yes | Nothing. |
| Node.js | ✅ yes | Nothing. |
| Deno | ✅ yes | Nothing. |
| Cloudflare Workers | ✅ yes | Nothing. |
Generated from pipecat.runtimes and pipecat.compat in packages/inworld/package.json: ✅ means the compat smoke test passes on that runtime.
InworldTTSServiceopens its socket withwebsocketConnect()from core, with the key in theAuthorizationheader (throughfetchon Cloudflare Workers).InworldHttpTTSServiceuses the globalfetch; passfetchto use another one (upstream takes an aiohttp session).- Deprecated options are not ported:
voiceId,modelandparams(InputParams) on the constructor, andaggregateSentences. The WebSocket buffer settings that onlyparamscould set always use their defaults.
pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.
Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).