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

Smallest AI

Realtime speech-to-text with SmallestSTTService, over Smallest AI's Pulse WebSocket API.

Overview

  • SmallestSTTService: streams audio over a persistent WebSocket to Smallest AI's Pulse speech-to-text endpoint. Interim transcripts become InterimTranscriptionFrames; when the VAD sees the user stop, the service sends finalize and the final becomes a TranscriptionFrame.

Installation

bun add @pipedog/smallest
import { SmallestSTTService } from "@pipedog/smallest/stt";

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.

SmallestSTTService

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

Configuration

Prop

Type

Settings

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

SettingTypeDefaultDescription
model"pulse" | "pulse-2""pulse"pulse-2 is English-only and adds per-utterance emotion and gender.
languageLanguageLanguage.ENLanguage of the audio. A non-English language with pulse-2 throws.
wordTimestampsbooleanfalseWord-level timestamps.
fullTranscriptbooleanfalseInclude the cumulative transcript.
sentenceTimestampsbooleanfalseSentence-level timestamps.
redactPiibooleanfalseRedact personally identifiable information.
redactPcibooleanfalseRedact payment card information.
numeralsstring"auto"Convert spoken numerals to digits.
diarizebooleanfalseSpeaker diarization.
endpointingbooleantrueFinalize promptly on trailing silence. No effect on pulse-2.
keywordsstring""Comma-separated KEYWORD:INTENSIFIER pairs, such as "NVIDIA:2".
formatbooleantruePunctuation and capitalization.
emotionDetectionbooleantruepulse-2 only: a six-class emotion on each final.
genderDetectionbooleantruepulse-2 only: a gender estimate on each final.
itnNormalizebooleanfalseInverse text normalization ("twenty five" becomes "25").
noFormatDelaybooleanfalseWith itnNormalize, emit finals at once instead of holding back a number still being dictated.

Usage

stt.ts
import { Language } from "@pipedog/core/transcriptions/language";
import { SmallestSTTService } from "@pipedog/smallest/stt";

const stt = new SmallestSTTService({
  apiKey: process.env.SMALLEST_API_KEY ?? "",
  settings: new SmallestSTTService.Settings({ language: Language.EN, wordTimestamps: true }),
});

Pulse 2.0, English only:

const pulse2 = new SmallestSTTService({
  apiKey: process.env.SMALLEST_API_KEY ?? "",
  settings: new SmallestSTTService.Settings({ model: "pulse-2" }),
});

Change settings mid-call with an STTUpdateSettingsFrame:

import { STTUpdateSettingsFrame } from "@pipedog/core/frames/frames";

// Queue it on the worker, or push it from a processor upstream of the service.
const update = new STTUpdateSettingsFrame({
  delta: new SmallestSTTService.Settings({ redactPii: true }),
});

Event handlers

EventDescription
on_connectedThe WebSocket connected.
on_disconnectedThe WebSocket closed.

Notes

  • encoding is "linear16" by default. sampleRate defaults to the pipeline's input rate.
  • Settings are query parameters of the connection, so changing one reconnects.
  • The same package has Smallest AI's LLM and text-to-speech 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.
  • Upstream sets a keepalive interval without implementing the keepalive message, so an idle connection logs a warning every few seconds. The port behaves the same way.
  • 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