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

xAI

Realtime speech-to-text with XAISTTService, over xAI's WebSocket API.

Overview

  • XAISTTService: streams audio over a persistent WebSocket to xAI's speech-to-text endpoint. Interim results and chunk finals become InterimTranscriptionFrames; the utterance final becomes a TranscriptionFrame.

Installation

bun add @pipedog/xai
import { XAISTTService } from "@pipedog/xai/stt";

Prerequisites

  • An xAI account and an API key from the xAI console.
  • Pass the key as apiKey. The examples read it from XAI_API_KEY.

XAISTTService

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

Configuration

Prop

Type

Settings

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

SettingTypeDefaultDescription
modelstring"grok-voice-transcribe-2.0"Transcription model.
languageLanguage | nullLanguage.ENLanguage of the audio, sent as a two-letter code.
interimResultsbooleantruePartial transcripts about every 500 ms.
endpointingnumber | nullnullSilence, in ms (0 to 5000), that ends an utterance. The server default is 400.
multichannelboolean | nullnullTranscribe each interleaved channel on its own. Needs channels of 2 or more.
channelsnumber | nullnullNumber of interleaved channels (2 to 8).
diarizeboolean | nullnullAttach a speaker to each word.

Usage

stt.ts
import { STTUpdateSettingsFrame } from "@pipedog/core/frames/frames";
import { XAISTTService } from "@pipedog/xai/stt";

const stt = new XAISTTService({
  apiKey: process.env.XAI_API_KEY ?? "",
  settings: new XAISTTService.Settings({ endpointing: 300 }),
});

Change settings mid-call with an STTUpdateSettingsFrame:

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

Event handlers

EventDescription
on_connectedThe WebSocket connected.
on_disconnectedThe WebSocket closed.

Notes

  • encoding is "pcm" (16-bit little-endian) by default; "mulaw" and "alaw" also work. sampleRate defaults to the pipeline's input rate.
  • Settings are query parameters of the connection, so any settings change reconnects.
  • Audio is only sent once the server reports the session ready (transcript.created).

Runtime notes

RuntimeWorksWhat it needs
Bun✅ yesNothing.
Node.js✅ yesNothing.
Deno✅ yesNothing.
Cloudflare Workers✅ yesNothing.

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

  • The WebSocket goes through the core websocketConnect, with headers on the handshake. It works on Bun, Node, Deno and Cloudflare Workers.
  • Tested against a local WebSocket server, as upstream's tests do, not against xAI 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