Polyweave

@polyweave/deepgram (1.0.9)

Published 2026-07-11 15:23:04 +00:00 by Dvorak

Installation

@polyweave:registry=https://hub.kl1.tenere.ai/api/packages/Polyweave/npm/
npm install @polyweave/deepgram@1.0.9
"@polyweave/deepgram": "1.0.9"

About this package

@polyweave/deepgram

Deepgram multi-modal adapter for the Polyweave platform. Supports Speech-to-Text (HTTP batch and WebSocket streaming) and Text-to-Speech (HTTP REST and WebSocket streaming) via Polyweave frame protocol.

Published as @polyweave/deepgram.

Synopsis

import { createDeepgramAdapter } from '@polyweave/deepgram';

const adapter = createDeepgramAdapter({
  apiKey: process.env.DEEPGRAM_API_KEY,
  timeout: 30000
});

// STT: send AUDIO frames, receive TEXT frames
adapter.source.pipe(mySink);
adapter.sink.write({
  type: 'AUDIO',
  streamId: 'stt-1',
  content: { data: audioBuffer, encoding: 'linear16', sampleRate: 16000 }
});

// TTS: send TEXT frames, receive AUDIO frames
adapter.sink.write({
  type: 'PARAM',
  content: { key: 'task', value: 'tts' }
});
adapter.sink.write({
  type: 'TEXT',
  streamId: 'tts-1',
  content: { text: 'Hello, world!' }
});

Install

npm install @polyweave/deepgram

Why

Speech is the highest-bandwidth human–AI channel — and latency kills immersion. This adapter provides realtime streaming STT via Deepgram's WebSocket API with interim_results for sub-300ms Time-To-First-Partial, plus streaming TTS via WebSocket for incremental audio output. Both streaming and batch (HTTP) modes are available, with TTS supporting 12 Aura English voices. All modes emit Polyweave RECEIPT frames for cost tracking.

API

createDeepgramAdapter(config)

Creates a Deepgram adapter as a Polyweave frame duplex { source, sink }. Frames are routed to STT or TTS handlers based on frame type and the task parameter.

Parameters:

Name Type Required Default Description
config.apiKey string No process.env.DEEPGRAM_API_KEY Deepgram API key. Can also be set after creation via PARAM { key: 'apiKey' } frame or adapter.setReady(key).
config.timeout number No 30000 Request timeout in milliseconds.
config.name string No null Human-readable name exposed on adapter.name.

Returns: IFrameDuplex { source, sink, setReady, ready, apiKey, name }

Additional properties on the returned duplex:

Property Type Description
setReady(key) function Set the API key post-creation. Processes any buffered frames.
ready boolean (getter) Whether the adapter has an API key and is accepting frames.
apiKey string (getter) The current API key (or null).
name string | null Adapter name from config.

PARAM keys recognized by the sink:

Key Default Description
apiKey Triggers setReady().
model "nova-3" STT model.
language "en" ISO 639-1 language code.
punctuate true Add punctuation to transcripts.
smart_format true Smart formatting (dates, numbers, etc.).
diarize false Speaker diarization.
diarize_version undefined Diarization model version.
multichannel false Multi-channel audio input.
alternatives 1 Number of transcription alternatives.
numerals true Convert numerals to digits.
profanity_filter false Filter profanity.
redact undefined Array of redaction types ("pci", "numbers", "ssn").
replace undefined Find-and-replace term mappings.
search undefined Search for specific terms.
keywords undefined Array of keywords to boost.
filler_words false Include filler words in transcript.
paragraphs false Paragraph segmentation.
utterances false Utterance segmentation.
utt_split 0.8 Utterance split threshold in seconds.
interim_results true Stream interim (partial) results for low-latency STT.
endpointing 300 Milliseconds of silence before finalizing an utterance.
vad_events false Emit voice activity detection events.
encoding "linear16" Audio encoding: linear16, flac, mulaw, opus, etc.
sample_rate 16000 Audio sample rate in Hz.
channels 1 Number of audio channels.
tts_model "aura-asteria-en" TTS voice model.
streaming_stt true Use WebSocket streaming STT. Set false for HTTP batch.
streaming_tts false Use WebSocket streaming TTS.
task undefined Routes frames: "tts" / "t2a" / "text_to_speech" for TTS; default is TTS (TEXT frames always route to TTS, AUDIO frames always route to STT regardless of task).
receipt_mode "final" When receipts are emitted.
receipt_interval 50 Token/chunk interval for progressive receipts.

Frame protocol:

Input frame type Action
TEXT Routes to TTS handler. Emits AUDIO (audio buffer) → RECEIPTEND.
AUDIO Routes to realtime STT (WebSocket, if streaming_stt is true) or HTTP batch STT. Emits TEXT (transcript, possibly multiple for interim results) → RECEIPTEND.
PARAM Accumulates configuration. key: "apiKey" triggers setReady().
START Ignored (passthrough).
END For streaming STT: signals session close.
TOPOLOGY_SCAN Responds with TOPOLOGY_REPORT containing adapter metadata and state.
TEST_INJECT Injects frame arrays for testing.
TEST_SNAPSHOT Returns adapter paused state for testing.

Output frame types emitted:

Frame type Content
TEXT Transcript text. Metadata includes partial (boolean), committed, streaming, speechFinal, confidence, words, ttft (time-to-first-text in ms).
AUDIO TTS audio buffer. Metadata includes format (mp3, pcm, opus, flac, aac, mulaw), mimeType, sampleRate, ttfb (time-to-first-byte), streaming, chunkIndex, ttfa (time-to-first-audio).
RECEIPT Cost information: inputCost, outputCost, totalCost, audioSeconds, characters, audioChunksSent.
ERROR Maps Deepgram errors to ErrorCode values (see error mapping below). Always followed by an END frame with metadata.error: true.
END Marks stream completion. Metadata includes timing and audio statistics.
TOPOLOGY_REPORT / TEST_SNAPSHOT Protocol frames for topology scanning and testing.

Error mapping (from utils/errorMapper.js):

Error pattern Mapped ErrorCode Retryable
401 / Unauthorized / Invalid API key AUTHENTICATION_ERROR No
402 / Payment Required / quota QUOTA_EXCEEDED No
429 / rate limit / Too Many Requests RATE_LIMIT_EXCEEDED Yes
400 / Bad Request / Invalid INVALID_INPUT No
500 / 503 / Server Error PROVIDER_ERROR Yes
timeout / ETIMEDOUT / ECONNRESET QUEUE_TIMEOUT Yes
WebSocket / connection PROTOCOL_ERROR Yes
All other errors PROVIDER_ERROR No

Runtime errors (thrown synchronously by routeFrame):

Frame type Error
Unsupported frame type (not TEXT, AUDIO, or END) "Unsupported frame type: {type}. Supported types: TEXT, AUDIO"

This throw is caught by the sink.write try/catch and converted to an ERROR + END frame pair.

Ready-state buffering:

If no apiKey is provided at creation time, all incoming frames are buffered until a PARAM { key: 'apiKey', value: '...' } frame or setReady(key) call provides the key. Buffered frames are then replayed through the sink.

Cleanup on end:

duplex.sink.end() destroys all active HTTP requests and closes all WebSocket sessions (STT + TTS) before calling the original end handler.

handleTtsHttp(frame, duplex, params, sharedState) (exported from src/handlers/ttsHttp.js)

HTTP TTS handler. Sends text to POST https://api.deepgram.com/v1/speak, receives audio buffer, emits AUDIO + RECEIPT + END frames. Not part of the public API — used internally by routeFrame.

handleSttRealtime(frame, duplex, params, sharedState) (exported from src/handlers/sttRealtime.js)

WebSocket streaming STT handler. Creates persistent sessions per streamId. Opens a WebSocket to wss://api.deepgram.com/v1/listen, sends audio chunks as binary frames, receives Results JSON with interim/final transcripts. Emits TEXT frames for each result. Tracks TTFP (time-to-first-partial) and accumulated audio duration.

handleTtsWebSocket(frame, duplex, params, sharedState) (exported from src/handlers/ttsWebSocket.js)

WebSocket streaming TTS handler. Creates sessions per streamId. Opens a WebSocket to wss://api.deepgram.com/v1/speak, sends {"type":"Speak","text":"..."} JSON frames, receives binary audio chunks. Sends {"type":"Close"} to flush and close. Tracks TTFA (time-to-first-audio) and total characters sent.

AURA_VOICES (exported from src/handlers/ttsHttp.js)

Named map of supported Deepgram Aura English voices:

Key Description
aura-asteria-en Asteria (English, Female)
aura-luna-en Luna (English, Female)
aura-stella-en Stella (English, Female)
aura-athena-en Athena (English, Female)
aura-hera-en Hera (English, Female)
aura-orion-en Orion (English, Male)
aura-arcas-en Arcas (English, Male)
aura-perseus-en Perseus (English, Male)
aura-angus-en Angus (English, Male)
aura-orpheus-en Orpheus (English, Male)
aura-helios-en Helios (English, Male)
aura-zeus-en Zeus (English, Male)

Cost functions (exported from src/costs.js)

getModelCost(model)

Returns the cost object for a given model name, or null if unknown.

Model Per-minute cost
nova-2 $0.0043
nova $0.0059
enhanced $0.0145
base $0.0125

calculateCost(model, minutes)

Returns total cost: minutes * getModelCost(model).perMinute. Returns 0 if the model is unknown or has no perMinute property.

mapDeepgramError(error, frame) (exported from src/utils/errorMapper.js)

Maps a DeepgramError to a Polyweave error frame with the appropriate ErrorCode, retryable flag, and provider metadata.

Tests

npm test

Runs node --test test/deepgram.test.js test/rigor.test.js. Covering: adapter creation with and without API key, ready-state buffering, PARAM accumulation, STT and TTS frame routing, error mapping for all error patterns, cost calculation, topology scan, and test injection/snapshot frames.

Requirements

  • Node.js >= 22.0.0
  • ESM only
  • Runtime dependencies: @polyweave/push-websocket, ws (^8.19.0)
  • Peer dependencies: @polyweave/core, @polyweave/errors — must be installed alongside.
  • Deepgram API key (set via DEEPGRAM_API_KEY env var, config option, or PARAM frame).

Caveats

  • The default streaming_stt is true. Set it to false via PARAM to use HTTP batch STT (higher latency, but works without persistent WebSocket connections).
  • The default streaming_tts is false. Set it to true via PARAM to enable WebSocket TTS for lower time-to-first-audio at the cost of a persistent connection.
  • WebSocket sessions are created lazily on the first AUDIO (STT) or TEXT (TTS) frame. Audio/text sent before the WebSocket connects is queued and flushed on open.
  • TTS pricing uses a hardcoded $0.015/1000 characters estimate. STT pricing uses a hardcoded $0.0043/minute (Nova-3) rate. Check src/costs.js for the latest values.
  • HTTP TTS supports the following output encodings: linear16 (PCM), mp3, opus, flac, aac, mulaw. Unrecognized encodings default to mp3.
  • HTTP STT auto-detects audio format from magic bytes (RIFF/WAV, MP3, FLAC) if encoding is not one of the recognized values.

Dependencies

Dependencies

ID Version
@polyweave/push-websocket *
ws ^8.19.0

Development Dependencies

ID Version
@rigor/core *

Peer Dependencies

ID Version
@polyweave/core *
@polyweave/costs *
@polyweave/errors *

Keywords

polyweave deepgram stt speech-to-text ai adapter
Details
npm
2026-07-11 15:23:04 +00:00
5
John Dvorak
SEE LICENSE IN LICENSE
latest
16 KiB
Assets (1)
Versions (5) View all
1.0.9 2026-07-11
1.0.6 2026-07-10
1.0.5 2026-07-10
1.0.4 2026-07-10
1.0.3 2026-07-10