pipedog is an unofficial community port of Pipecat, not affiliated with Daily.
pipedog
Text-to-speech

Smallest AI

Realtime text-to-speech with SmallestTTSService, over Smallest AI's WebSocket API, with word timestamps.

Overview

  • SmallestTTSService: streams text over a WebSocket and pushes audio as it arrives. Fragments of one LLM turn share a continuation context, so the voice keeps its prosody across them. An interruption reconnects the socket.

Installation

bun add @pipedog/smallest
import { SmallestTTSService } from "@pipedog/smallest/tts";

Prerequisites

  • A Smallest AI account and an API key from Smallest AI.
  • Pass the key as apiKey. The examples read it from SMALLEST_API_KEY.

SmallestTTSService

Connects to wss://api.smallest.ai, with the key as a Bearer token on the handshake.

Configuration

Prop

Type

Settings

Runtime-updatable settings, passed as settings: new SmallestTTSService.Settings({...}) (SmallestTTSSettings). Any setting you leave out keeps the default below.

SettingTypeDefaultDescription
model"lightning_v3.1" | "lightning_v3.1_pro""lightning_v3.1_pro"Speech model.
voicestring"meher" ("sophia" for lightning_v3.1)Voice.
languageLanguageLanguage.ENLanguage.
speednumber | nullnullSpeed multiplier, 0.5 to 2.0. null uses the API default.
mathNotationboolean | nullnullRead operators between digits as words ("2 + 2" as "two plus two").
contentFilter"reject" | "flag" | "redact" | string | nullnullCheck the text against a profanity list; "reject" fails the request, "flag" synthesizes and records the match, "redact" drops the matched term and speaks the rest.
dateFormat"EU" | "US" | string | nullnullRead all-numeric dates day-first ("EU") or month-first ("US").

Usage

tts.ts
import { TTSUpdateSettingsFrame } from "@pipedog/core/frames/frames";
import { Language } from "@pipedog/core/transcriptions/language";
import { SmallestTTSService } from "@pipedog/smallest/tts";

const tts = new SmallestTTSService({
  apiKey: process.env.SMALLEST_API_KEY ?? "",
  settings: new SmallestTTSService.Settings({ voice: "sophia", language: Language.EN }),
});

Change settings mid-call with a TTSUpdateSettingsFrame:

// Queue it on the worker, or push it from a processor upstream of the service.
const update = new TTSUpdateSettingsFrame({
  delta: new SmallestTTSService.Settings({ speed: 1.1 }),
});

Notes

  • outputFormat is "pcm" by default; it is fixed when the service is created.
  • wordTimestamps (on by default) makes the service push aligned per-word TTSTextFrames. It works on meher, devansh, kartik, maithili, liam and avery; other voices send no word events, so leaving it on is safe.
  • maxBufferDelayMs (0 to 5000) bounds how long the server holds a continuation fragment. null keeps the server's 3000 ms.
  • The same package has Smallest AI's LLM and speech-to-text services.
RuntimeWorksWhat it needs
Bun✅ yesNothing.
Node.js✅ yesNothing.
Deno✅ yesNothing.
Cloudflare Workers✅ yesNothing.

Generated from pipecat.runtimes and pipecat.compat in packages/smallest/package.json: ✅ means the compat smoke test passes on that runtime.

Runtime notes

  • The WebSocket goes through the core websocketConnect, with headers on the handshake.
  • Tested against local WebSocket servers, as upstream's tests do, not against Smallest AI itself.

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).

On this page