import type { Buffer } from "node:buffer"; export type ClientLinkKind = "discord-bot" | "desktop" | "mobile" | "device" | "browser"; export type ClientLinkChannel = "control" | "audio" | "tools" | "events"; export type ClientLinkCapabilities = { channels: ClientLinkChannel[]; /** Whether the client handles wakeword detection itself, or wants the server to */ wakeword?: "client" | "server"; }; export type ClientLinkIdentity = { /** Stable UUID across reconnects for the same logical client */ linkId: string; kind: ClientLinkKind; displayName: string; }; /** Text JSON frame envelope */ export type ClientLinkFrame = { channel: ClientLinkChannel; type: string; payload: unknown; }; export declare const AUDIO_HEADER_BYTES = 4; export declare const AUDIO_CODEC_BYTE: { readonly opus: 0; readonly pcm16: 1; }; export declare const AUDIO_FLAG: { readonly ACTIVITY_START: 1; readonly ACTIVITY_END: 2; }; export type AudioCodec = "opus" | "pcm16"; export type HelloPayload = { /** JWT access token for the user that owns this link */ token: string; identity: ClientLinkIdentity; capabilities: ClientLinkCapabilities; }; export type WelcomePayload = { linkId: string; serverVersion: string; }; export type PingPayload = { ts: number; }; export type PongPayload = { ts: number; serverTs: number; }; export type ErrorPayload = { code: string; message: string; }; export type VoiceRoomMode = "off" | "transcribe" | "realtime"; export type AudioOpenPayload = { roomExternalRef: string; roomKind: "discord" | "phone" | "device"; mode?: VoiceRoomMode; wakewordHandledBy?: "client" | "server"; }; export type AudioClosePayload = { roomExternalRef: string; }; export type AudioOpenedPayload = { roomId: string; mode: VoiceRoomMode; inputSampleRate: number; outputSampleRate: number; }; export type AudioWakewordPayload = { speakerId: string; confidence: number; }; export type InboundAudioFrame = { /** Server currently emits a fixed "assistant" speakerId for outbound model audio */ speakerId: string; data: Buffer; codec: AudioCodec; seqNum: number; activityStart: boolean; activityEnd: boolean; };