API reference
All functions accept a stream that is either an EventEmitter emitting text chunks or an async iterable (e.g. a direct LLM SDK stream).
For the config objects and exported types referenced below (RtpConfig, SrtpConfig, TransportStream, LLMMetadata, T140RtpError, …) see Types & interfaces. For hiding packets in cover media, see Steganography.
- Processing functions
- Transport factories
- Pre-connecting transports
- Utilities
- Classes
- TransportStream interface
Processing functions
processAIStream(stream, [websocketUrl], [options])
Sends the stream's text chunks as T.140 over a WebSocket.
stream— the streaming data source.websocketUrlstring— optional, defaults tows://localhost:8765.optionsobject— optional:handleMetadata,metadataCallback,sendMetadataOverWebsocket,processBackspaces.- returns
void.
processAIStreamToRtp(stream, remoteAddress, [remotePort], [rtpConfig])
Sends text chunks directly as T.140 over RTP. With FEC enabled, adds Forward Error Correction packets per RFC 5109. A custom transport, if provided, replaces the default UDP socket.
remoteAddressstring— remote IP (ignored when a custom transport is set).remotePortnumber— optional, defaults to5004.rtpConfigRtpConfig— optional:payloadTypenumber— default96.ssrcnumber— default: a cryptographically secure random value.initialSequenceNumbernumber— default0.initialTimestampnumber— default0.timestampIncrementnumber— default160.fecEnabledboolean— defaultfalse.fecPayloadTypenumber— default97.fecGroupSizenumber— media packets protected per FEC packet, default3.redEnabledboolean— enable T.140 redundancy.customTransportTransportStream— replaces the UDP socket.
- returns
T140RtpTransport.
processAIStreamToSrtp(stream, remoteAddress, [remotePort], srtpConfig)
Same as processAIStreamToRtp, but encrypts with SRTP.
remotePortnumber— optional, defaults to5006.srtpConfigSrtpConfig:masterKeyBuffer— required.masterSaltBuffer— required.profileSrtpProtectionProfile— optional (valid0x0001–0x0008).customTransportTransportStream— optional.
- returns
T140RtpTransport.
processAIStreamToDirectSocket(stream, [socketPath], [rtpConfig])
Sends RTP-framed T.140 straight to a Unix SEQPACKET socket, skipping the WebSocket hop.
socketPathstring— optional, defaults to the library's default socket path.rtpConfigRtpConfig— optional, same options asprocessAIStreamToRtp.- returns
T140RtpTransport.
processAIStreamsToMultiplexedRtp(streams, remoteAddress, [remotePort], [rtpConfig])
Combines multiple streams into one multiplexed RTP output.
streamsMap<string, TextDataStream>— stream IDs to streams.remotePortnumber— optional, defaults to5004.rtpConfigRtpConfig— optional, plus:multiplexEnabledboolean— required, settrue.useCsrcForStreamIdboolean— use the RTP CSRC field for stream IDs (recommended), defaultfalse.charRateLimitnumber— combined character rate limit, default30.
- returns
T140RtpMultiplexer.
Transport factories
Each factory creates a transport up front and returns an attachStream(stream, [options]) function, letting you connect before the LLM stream exists. See Pre-connecting transports.
createT140WebSocketTransport(websocketUrl, [options])
websocketUrlstring— optional, defaults tows://localhost:8765.options.tlsOptionsobject— optional TLS options for secure WebSocket.- returns
{ connection, attachStream }.
createDirectSocketTransport(socketPath, [rtpConfig])
- returns
{ transport, attachStream, rtpState }wherertpStateis{ sequenceNumber, timestamp, ssrc }.
createT140RtpTransport(remoteAddress, [remotePort], [rtpConfig])
remotePort— optional, defaults to5004.- returns
{ transport, attachStream }.
createT140SrtpTransport(remoteAddress, [remotePort], srtpConfig)
remotePort— optional, defaults to5006.- returns
{ transport, attachStream }.
createT140RtpMultiplexer(remoteAddress, [remotePort], [multiplexConfig])
multiplexConfig.multiplexEnabledboolean— required, settrue.multiplexConfig.useCsrcForStreamIdboolean— optional, defaultfalse.- returns
T140RtpMultiplexer.
Pre-connecting transports
Establishing the transport before the stream is available reduces startup latency and lets one transport serve multiple streams.
import { createT140WebSocketTransport } from "t140llm";
const { connection, attachStream } = createT140WebSocketTransport("ws://localhost:5004");
function handleLLMResponse(llmStream) {
attachStream(llmStream, { processBackspaces: true, handleMetadata: true });
}The same pattern applies to createDirectSocketTransport, createT140RtpTransport, and createT140SrtpTransport. See examples/pre_connect_example.js.
Utilities
createRtpPacket(sequenceNumber, timestamp, payload, [options])
Builds an RTP packet with a T.140 payload. options is Partial<RtpConfig>. Returns Buffer.
createSrtpKeysFromPassphrase(passphrase)
Derives { masterKey, masterSalt } from a passphrase. For production, use a stronger key derivation function and exchange keys securely.
Classes
T140RtpTransport
Manages an RTP/SRTP connection for sending T.140.
constructor(remoteAddress, [remotePort = 5004], [config])—configacceptsRtpConfig, includingcustomTransport.setupSrtp(srtpConfig)— initializes SRTP. Returnsvoid.sendText(text)— sends text as T.140, generating FEC packets when enabled. Returnsvoid.close()— closes the socket/transport, flushing any remaining FEC packets. Returnsvoid.
T140RtpMultiplexer
Multiplexes multiple LLM streams into one RTP output.
constructor(remoteAddress, [remotePort = 5004], [config]).addStream(id, stream, [streamConfig], [processorOptions])— returnsboolean.removeStream(id)— returnsboolean.getStreamCount()— returnsnumber.getStreamIds()— returnsstring[].close()— closes the multiplexer and all streams.
Events: streamAdded, streamRemoved, streamError, metadata, error.
T140StreamDemultiplexer
Extracts individual streams from multiplexed RTP packets on the receiving end.
constructor().processPacket(data, [useCSRC = false])— parses an RTP packet and routes it. Returnsvoid.getStream(streamId)— returnsDemultiplexedStream | undefined.getStreamIds()— returnsstring[].
Events: stream, data, error.
import { T140StreamDemultiplexer } from "t140llm";
import * as dgram from "dgram";
const socket = dgram.createSocket("udp4");
const demux = new T140StreamDemultiplexer();
socket.on("message", (msg) => demux.processPacket(msg, true));
demux.on("stream", (streamId, stream) => {
stream.on("data", (text) => console.log(`[${streamId}] ${text}`));
});
socket.bind(5004);TransportStream interface
Implement this to plug in your own transport (WebRTC data channel, custom socket, steganographic carrier, …). Anything satisfying it can be passed as customTransport.
send(data, [callback])— sends aBuffer;callback(error?)fires on completion. Returnsvoid.close()— optional; releases resources. Returnsvoid.
class MyTransport {
send(data, callback) {
// ...deliver data...
if (callback) callback();
}
close() {}
}
processAIStreamToRtp(stream, "unused", 0, { customTransport: new MyTransport() });