@elevenlabs/client 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"lib.umd.js","sources":["../src/BaseConversation.ts","../src/utils/BaseConnection.ts","../src/version.ts","../src/utils/events.ts","../src/utils/overrides.ts","../src/utils/WebSocketConnection.ts","../src/utils/audio.ts","../src/utils/createWorkletModuleLoader.ts","../src/utils/rawAudioProcessor.ts","../src/utils/WebRTCConnection.ts","../src/utils/ConnectionFactory.ts","../src/utils/compatibility.ts","../src/utils/applyDelay.ts","../src/TextConversation.ts","../src/utils/input.ts","../src/utils/audioConcatProcessor.ts","../src/utils/output.ts","../src/VoiceConversation.ts","../src/index.ts","../src/utils/postOverallFeedback.ts"],"sourcesContent":["import type {\n BaseConnection,\n DisconnectionDetails,\n OnDisconnectCallback,\n SessionConfig,\n FormatConfig,\n} from \"./utils/BaseConnection\";\nimport type {\n AgentAudioEvent,\n AgentResponseEvent,\n ClientToolCallEvent,\n IncomingSocketEvent,\n InternalTentativeAgentResponseEvent,\n InterruptionEvent,\n UserTranscriptionEvent,\n VadScoreEvent,\n} from \"./utils/events\";\nimport type { InputConfig } from \"./utils/input\";\n\nexport type Role = \"user\" | \"ai\";\n\nexport type Mode = \"speaking\" | \"listening\";\n\nexport type Status =\n | \"connecting\"\n | \"connected\"\n | \"disconnecting\"\n | \"disconnected\";\n\nexport type Options = SessionConfig &\n Callbacks &\n ClientToolsConfig &\n InputConfig;\n\nexport type PartialOptions = SessionConfig &\n Partial<Callbacks> &\n Partial<ClientToolsConfig> &\n Partial<InputConfig> &\n Partial<FormatConfig>;\n\nexport type ClientToolsConfig = {\n clientTools: Record<\n string,\n (\n parameters: any\n ) => Promise<string | number | void> | string | number | void\n >;\n};\n\nexport type Callbacks = {\n onConnect?: (props: { conversationId: string }) => void;\n // internal debug events, not to be used\n onDebug?: (props: any) => void;\n onDisconnect?: OnDisconnectCallback;\n onError?: (message: string, context?: any) => void;\n onMessage?: (props: { message: string; source: Role }) => void;\n onAudio?: (base64Audio: string) => void;\n onModeChange?: (prop: { mode: Mode }) => void;\n onStatusChange?: (prop: { status: Status }) => void;\n onCanSendFeedbackChange?: (prop: { canSendFeedback: boolean }) => void;\n onUnhandledClientToolCall?: (\n params: ClientToolCallEvent[\"client_tool_call\"]\n ) => void;\n onVadScore?: (props: { vadScore: number }) => void;\n};\n\nconst EMPTY_FREQUENCY_DATA = new Uint8Array(0);\n\nexport class BaseConversation {\n protected lastInterruptTimestamp = 0;\n protected mode: Mode = \"listening\";\n protected status: Status = \"connecting\";\n protected volume = 1;\n protected currentEventId = 1;\n protected lastFeedbackEventId = 0;\n protected canSendFeedback = false;\n\n protected static getFullOptions(partialOptions: PartialOptions): Options {\n return {\n clientTools: {},\n onConnect: () => {},\n onDebug: () => {},\n onDisconnect: () => {},\n onError: () => {},\n onMessage: () => {},\n onAudio: () => {},\n onModeChange: () => {},\n onStatusChange: () => {},\n onCanSendFeedbackChange: () => {},\n ...partialOptions,\n };\n }\n\n protected constructor(\n protected readonly options: Options,\n protected readonly connection: BaseConnection\n ) {\n if (this.options.onConnect) {\n this.options.onConnect({ conversationId: connection.conversationId });\n }\n this.connection.onMessage(this.onMessage);\n this.connection.onDisconnect(this.endSessionWithDetails);\n this.connection.onModeChange(mode => this.updateMode(mode));\n this.updateStatus(\"connected\");\n }\n\n public endSession() {\n return this.endSessionWithDetails({ reason: \"user\" });\n }\n\n private endSessionWithDetails = async (details: DisconnectionDetails) => {\n if (this.status !== \"connected\" && this.status !== \"connecting\") return;\n this.updateStatus(\"disconnecting\");\n await this.handleEndSession();\n this.updateStatus(\"disconnected\");\n if (this.options.onDisconnect) {\n this.options.onDisconnect(details);\n }\n };\n\n protected async handleEndSession() {\n this.connection.close();\n }\n\n protected updateMode(mode: Mode) {\n if (mode !== this.mode) {\n this.mode = mode;\n if (this.options.onModeChange) {\n this.options.onModeChange({ mode });\n }\n }\n }\n\n protected updateStatus(status: Status) {\n if (status !== this.status) {\n this.status = status;\n if (this.options.onStatusChange) {\n this.options.onStatusChange({ status });\n }\n }\n }\n\n protected updateCanSendFeedback() {\n const canSendFeedback = this.currentEventId !== this.lastFeedbackEventId;\n if (this.canSendFeedback !== canSendFeedback) {\n this.canSendFeedback = canSendFeedback;\n if (this.options.onCanSendFeedbackChange) {\n this.options.onCanSendFeedbackChange({ canSendFeedback });\n }\n }\n }\n\n protected handleInterruption(event: InterruptionEvent) {\n if (event.interruption_event) {\n this.lastInterruptTimestamp = event.interruption_event.event_id;\n }\n }\n\n protected handleAgentResponse(event: AgentResponseEvent) {\n if (this.options.onMessage) {\n this.options.onMessage({\n source: \"ai\",\n message: event.agent_response_event.agent_response,\n });\n }\n }\n\n protected handleUserTranscript(event: UserTranscriptionEvent) {\n if (this.options.onMessage) {\n this.options.onMessage({\n source: \"user\",\n message: event.user_transcription_event.user_transcript,\n });\n }\n }\n\n protected handleTentativeAgentResponse(\n event: InternalTentativeAgentResponseEvent\n ) {\n if (this.options.onDebug) {\n this.options.onDebug({\n type: \"tentative_agent_response\",\n response:\n event.tentative_agent_response_internal_event\n .tentative_agent_response,\n });\n }\n }\n\n protected handleVadScore(event: VadScoreEvent) {\n if (this.options.onVadScore) {\n this.options.onVadScore({\n vadScore: event.vad_score_event.vad_score,\n });\n }\n }\n\n protected async handleClientToolCall(event: ClientToolCallEvent) {\n if (\n Object.prototype.hasOwnProperty.call(\n this.options.clientTools,\n event.client_tool_call.tool_name\n )\n ) {\n try {\n const result =\n (await this.options.clientTools[event.client_tool_call.tool_name](\n event.client_tool_call.parameters\n )) ?? \"Client tool execution successful.\"; // default client-tool call response\n\n // The API expects result to be a string, so we need to convert it if it's not already a string\n const formattedResult =\n typeof result === \"object\" ? JSON.stringify(result) : String(result);\n\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: event.client_tool_call.tool_call_id,\n result: formattedResult,\n is_error: false,\n });\n } catch (e) {\n this.onError(\n `Client tool execution failed with following error: ${(e as Error)?.message}`,\n {\n clientToolName: event.client_tool_call.tool_name,\n }\n );\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: event.client_tool_call.tool_call_id,\n result: `Client tool execution failed: ${(e as Error)?.message}`,\n is_error: true,\n });\n }\n } else {\n if (this.options.onUnhandledClientToolCall) {\n this.options.onUnhandledClientToolCall(event.client_tool_call);\n\n return;\n }\n\n this.onError(\n `Client tool with name ${event.client_tool_call.tool_name} is not defined on client`,\n {\n clientToolName: event.client_tool_call.tool_name,\n }\n );\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: event.client_tool_call.tool_call_id,\n result: `Client tool with name ${event.client_tool_call.tool_name} is not defined on client`,\n is_error: true,\n });\n }\n }\n\n protected handleAudio(event: AgentAudioEvent) {}\n\n private onMessage = async (parsedEvent: IncomingSocketEvent) => {\n switch (parsedEvent.type) {\n case \"interruption\": {\n this.handleInterruption(parsedEvent);\n return;\n }\n case \"agent_response\": {\n this.handleAgentResponse(parsedEvent);\n return;\n }\n case \"user_transcript\": {\n this.handleUserTranscript(parsedEvent);\n return;\n }\n case \"internal_tentative_agent_response\": {\n this.handleTentativeAgentResponse(parsedEvent);\n return;\n }\n case \"client_tool_call\": {\n try {\n await this.handleClientToolCall(parsedEvent);\n } catch (error) {\n this.onError(\n `Unexpected error in client tool call handling: ${error instanceof Error ? error.message : String(error)}`,\n {\n clientToolName: parsedEvent.client_tool_call.tool_name,\n toolCallId: parsedEvent.client_tool_call.tool_call_id,\n }\n );\n }\n return;\n }\n case \"audio\": {\n this.handleAudio(parsedEvent);\n return;\n }\n\n case \"vad_score\": {\n this.handleVadScore(parsedEvent);\n return;\n }\n\n case \"ping\": {\n this.connection.sendMessage({\n type: \"pong\",\n event_id: parsedEvent.ping_event.event_id,\n });\n // parsedEvent.ping_event.ping_ms can be used on client side, for example\n // to warn if ping is too high that experience might be degraded.\n return;\n }\n\n // unhandled events are expected to be internal events\n default: {\n if (this.options.onDebug) {\n this.options.onDebug(parsedEvent);\n }\n return;\n }\n }\n };\n\n private onError(message: string, context?: any) {\n console.error(message, context);\n if (this.options.onError) {\n this.options.onError(message, context);\n }\n }\n\n public getId() {\n return this.connection.conversationId;\n }\n\n public isOpen() {\n return this.status === \"connected\";\n }\n\n public setVolume = ({ volume }: { volume: number }) => {\n this.volume = volume;\n };\n\n public setMicMuted(isMuted: boolean) {\n this.connection.setMicMuted(isMuted);\n }\n\n public getInputByteFrequencyData(): Uint8Array {\n return EMPTY_FREQUENCY_DATA;\n }\n\n public getOutputByteFrequencyData(): Uint8Array {\n return EMPTY_FREQUENCY_DATA;\n }\n\n public getInputVolume() {\n return 0;\n }\n\n public getOutputVolume() {\n return 0;\n }\n\n public sendFeedback(like: boolean) {\n if (!this.canSendFeedback) {\n console.warn(\n this.lastFeedbackEventId === 0\n ? \"Cannot send feedback: the conversation has not started yet.\"\n : \"Cannot send feedback: feedback has already been sent for the current response.\"\n );\n return;\n }\n\n this.connection.sendMessage({\n type: \"feedback\",\n score: like ? \"like\" : \"dislike\",\n event_id: this.currentEventId,\n });\n this.lastFeedbackEventId = this.currentEventId;\n this.updateCanSendFeedback();\n }\n\n public sendContextualUpdate(text: string) {\n this.connection.sendMessage({\n type: \"contextual_update\",\n text,\n });\n }\n\n public sendUserMessage(text: string) {\n this.connection.sendMessage({\n type: \"user_message\",\n text,\n });\n }\n\n public sendUserActivity() {\n this.connection.sendMessage({\n type: \"user_activity\",\n });\n }\n\n public sendMCPToolApprovalResult(toolCallId: string, isApproved: boolean) {\n this.connection.sendMessage({\n type: \"mcp_tool_approval_result\",\n tool_call_id: toolCallId,\n is_approved: isApproved,\n });\n }\n}\n","import type { IncomingSocketEvent, OutgoingSocketEvent } from \"./events\";\nimport type { Mode } from \"../BaseConversation\";\n\nexport type Language =\n | \"en\"\n | \"ja\"\n | \"zh\"\n | \"de\"\n | \"hi\"\n | \"fr\"\n | \"ko\"\n | \"pt\"\n | \"pt-br\"\n | \"it\"\n | \"es\"\n | \"id\"\n | \"nl\"\n | \"tr\"\n | \"pl\"\n | \"sv\"\n | \"bg\"\n | \"ro\"\n | \"ar\"\n | \"cs\"\n | \"el\"\n | \"fi\"\n | \"ms\"\n | \"da\"\n | \"ta\"\n | \"uk\"\n | \"ru\"\n | \"hu\"\n | \"hr\"\n | \"sk\"\n | \"no\"\n | \"vi\"\n | \"tl\";\n\nexport type DelayConfig = {\n default: number;\n android?: number;\n ios?: number;\n};\n\nexport type FormatConfig = {\n format: \"pcm\" | \"ulaw\";\n sampleRate: number;\n outputDeviceId?: string;\n};\n\nexport type DisconnectionDetails =\n | {\n reason: \"error\";\n message: string;\n context: Event;\n }\n | {\n reason: \"agent\";\n context: CloseEvent;\n }\n | {\n reason: \"user\";\n };\n\nexport type OnDisconnectCallback = (details: DisconnectionDetails) => void;\nexport type OnMessageCallback = (event: IncomingSocketEvent) => void;\n\nexport type BaseSessionConfig = {\n origin?: string;\n authorization?: string;\n livekitUrl?: string;\n overrides?: {\n agent?: {\n prompt?: {\n prompt?: string;\n };\n firstMessage?: string;\n language?: Language;\n };\n tts?: {\n voiceId?: string;\n };\n conversation?: {\n textOnly?: boolean;\n };\n client?: {\n source?: string;\n version?: string;\n };\n };\n customLlmExtraBody?: unknown;\n dynamicVariables?: Record<string, string | number | boolean>;\n useWakeLock?: boolean;\n connectionDelay?: DelayConfig;\n textOnly?: boolean;\n userId?: string;\n};\n\nexport type ConnectionType = \"websocket\" | \"webrtc\";\n\nexport type PublicSessionConfig = BaseSessionConfig & {\n agentId: string;\n connectionType: ConnectionType;\n signedUrl?: never;\n conversationToken?: never;\n};\n\nexport type PrivateWebSocketSessionConfig = BaseSessionConfig & {\n signedUrl: string;\n connectionType?: \"websocket\";\n agentId?: never;\n conversationToken?: never;\n};\n\nexport type PrivateWebRTCSessionConfig = BaseSessionConfig & {\n conversationToken: string;\n connectionType?: \"webrtc\";\n agentId?: never;\n signedUrl?: never;\n};\n\n// Union type for all possible session configurations\nexport type SessionConfig =\n | PublicSessionConfig\n | PrivateWebSocketSessionConfig\n | PrivateWebRTCSessionConfig;\n\nexport abstract class BaseConnection {\n public abstract readonly conversationId: string;\n public abstract readonly inputFormat: FormatConfig;\n public abstract readonly outputFormat: FormatConfig;\n\n protected queue: IncomingSocketEvent[] = [];\n protected disconnectionDetails: DisconnectionDetails | null = null;\n protected onDisconnectCallback: OnDisconnectCallback | null = null;\n protected onMessageCallback: OnMessageCallback | null = null;\n protected onModeChangeCallback: ((mode: Mode) => void) | null = null;\n protected onDebug?: (info: unknown) => void;\n\n constructor(config: { onDebug?: (info: unknown) => void } = {}) {\n this.onDebug = config.onDebug;\n }\n\n protected debug(info: unknown) {\n if (this.onDebug) this.onDebug(info);\n }\n\n public abstract close(): void;\n public abstract sendMessage(message: OutgoingSocketEvent): void;\n public abstract setMicMuted(isMuted: boolean): Promise<void>;\n\n public onMessage(callback: OnMessageCallback) {\n this.onMessageCallback = callback;\n const queue = this.queue;\n this.queue = [];\n\n if (queue.length > 0) {\n // Make sure the queue is flushed after the constructors finishes and\n // classes are initialized.\n queueMicrotask(() => {\n queue.forEach(callback);\n });\n }\n }\n\n public onDisconnect(callback: OnDisconnectCallback) {\n this.onDisconnectCallback = callback;\n const details = this.disconnectionDetails;\n if (details) {\n // Make sure the event is triggered after the constructors finishes and\n // classes are initialized.\n queueMicrotask(() => {\n callback(details);\n });\n }\n }\n\n public onModeChange(callback: (mode: Mode) => void) {\n this.onModeChangeCallback = callback;\n }\n\n protected updateMode(mode: Mode) {\n this.onModeChangeCallback?.(mode);\n }\n\n protected disconnect(details: DisconnectionDetails) {\n if (!this.disconnectionDetails) {\n this.disconnectionDetails = details;\n this.onDisconnectCallback?.(details);\n }\n }\n\n protected handleMessage(parsedEvent: IncomingSocketEvent) {\n if (this.onMessageCallback) {\n this.onMessageCallback(parsedEvent);\n } else {\n this.queue.push(parsedEvent);\n }\n }\n}\n\nexport function parseFormat(format: string): FormatConfig {\n const [formatPart, sampleRatePart] = format.split(\"_\");\n if (![\"pcm\", \"ulaw\"].includes(formatPart)) {\n throw new Error(`Invalid format: ${format}`);\n }\n\n const sampleRate = Number.parseInt(sampleRatePart);\n if (Number.isNaN(sampleRate)) {\n throw new Error(`Invalid sample rate: ${sampleRatePart}`);\n }\n\n return {\n format: formatPart as FormatConfig[\"format\"],\n sampleRate,\n };\n}\n","// This file is auto-generated during build\nexport const PACKAGE_VERSION = \"0.6.2\";\n","import type { Language } from \"./connection\";\nimport type { CONVERSATION_INITIATION_CLIENT_DATA_TYPE } from \"./overrides\";\n\nexport type UserTranscriptionEvent = {\n type: \"user_transcript\";\n user_transcription_event: { user_transcript: string };\n};\nexport type AgentResponseEvent = {\n type: \"agent_response\";\n agent_response_event: { agent_response: string };\n};\nexport type AgentAudioEvent = {\n type: \"audio\";\n audio_event: {\n audio_base_64: string;\n event_id: number;\n };\n};\nexport type InterruptionEvent = {\n type: \"interruption\";\n interruption_event: {\n event_id: number;\n };\n};\nexport type InternalTentativeAgentResponseEvent = {\n type: \"internal_tentative_agent_response\";\n tentative_agent_response_internal_event: {\n tentative_agent_response: string;\n };\n};\nexport type ConfigEvent = {\n type: \"conversation_initiation_metadata\";\n conversation_initiation_metadata_event: {\n conversation_id: string;\n agent_output_audio_format: string;\n user_input_audio_format?: string;\n };\n};\nexport type PingEvent = {\n type: \"ping\";\n ping_event: {\n event_id: number;\n ping_ms?: number;\n };\n};\nexport type ClientToolCallEvent = {\n type: \"client_tool_call\";\n client_tool_call: {\n tool_name: string;\n tool_call_id: string;\n parameters: any;\n expects_response: boolean;\n };\n};\nexport type VadScoreEvent = {\n type: \"vad_score\";\n vad_score_event: {\n vad_score: number;\n };\n};\n\ninterface BaseMCPToolCallClientEventData {\n service_id: string;\n tool_call_id: string;\n tool_name: string;\n tool_description?: string;\n parameters: Record<string, any>;\n timestamp: string; // ISO string format\n}\n\ninterface MCPToolCallClientEventLoadingData\n extends BaseMCPToolCallClientEventData {\n state: \"loading\";\n}\n\ninterface MCPToolCallClientEventAwaitingApprovalData\n extends BaseMCPToolCallClientEventData {\n state: \"awaiting_approval\";\n approval_timeout_secs: number;\n}\n\ninterface MCPToolCallClientEventSuccessData\n extends BaseMCPToolCallClientEventData {\n state: \"success\";\n result: any[];\n}\n\ninterface MCPToolCallClientEventFailureData\n extends BaseMCPToolCallClientEventData {\n state: \"failure\";\n error_message: string;\n}\n\ntype MCPToolCallClientEventData =\n | MCPToolCallClientEventLoadingData\n | MCPToolCallClientEventAwaitingApprovalData\n | MCPToolCallClientEventSuccessData\n | MCPToolCallClientEventFailureData;\n\nexport type MCPToolCallClientEvent = {\n type: \"mcp_tool_call\";\n mcp_tool_call: MCPToolCallClientEventData;\n};\n\nexport type AgentResponseCorrectionEvent = {\n type: \"agent_response_correction\";\n agent_response_correction_event: {\n original_agent_response: string;\n corrected_agent_response: string;\n };\n};\n\nexport type IncomingSocketEvent =\n | UserTranscriptionEvent\n | AgentResponseEvent\n | AgentResponseCorrectionEvent\n | AgentAudioEvent\n | InterruptionEvent\n | InternalTentativeAgentResponseEvent\n | ConfigEvent\n | PingEvent\n | ClientToolCallEvent\n | VadScoreEvent\n | MCPToolCallClientEvent;\n\nexport type PongEvent = {\n type: \"pong\";\n event_id: number;\n};\nexport type UserAudioEvent = {\n user_audio_chunk: string;\n};\nexport type UserFeedbackEvent = {\n type: \"feedback\";\n score: \"like\" | \"dislike\";\n event_id: number;\n};\nexport type ClientToolResultEvent = {\n type: \"client_tool_result\";\n tool_call_id: string;\n result: any;\n is_error: boolean;\n};\nexport type InitiationClientDataEvent = {\n type: typeof CONVERSATION_INITIATION_CLIENT_DATA_TYPE;\n conversation_config_override?: {\n agent?: {\n prompt?: {\n prompt?: string;\n };\n first_message?: string;\n language?: Language;\n };\n tts?: {\n voice_id?: string;\n };\n conversation?: {\n text_only?: boolean;\n };\n };\n custom_llm_extra_body?: any;\n dynamic_variables?: Record<string, string | number | boolean>;\n user_id?: string;\n source_info?: {\n source?: string;\n version?: string;\n };\n};\nexport type ContextualUpdateEvent = {\n type: \"contextual_update\";\n text: string;\n};\nexport type UserMessageEvent = {\n type: \"user_message\";\n text: string;\n};\nexport type UserActivityEvent = {\n type: \"user_activity\";\n};\nexport type MCPToolApprovalResultEvent = {\n type: \"mcp_tool_approval_result\";\n tool_call_id: string;\n is_approved: boolean;\n};\nexport type OutgoingSocketEvent =\n | PongEvent\n | UserAudioEvent\n | InitiationClientDataEvent\n | UserFeedbackEvent\n | ClientToolResultEvent\n | ContextualUpdateEvent\n | UserMessageEvent\n | UserActivityEvent\n | MCPToolApprovalResultEvent;\n\nexport function isValidSocketEvent(event: any): event is IncomingSocketEvent {\n return !!event.type;\n}\n","import type { SessionConfig } from \"./BaseConnection\";\nimport type { InitiationClientDataEvent } from \"./events\";\n\nexport const CONVERSATION_INITIATION_CLIENT_DATA_TYPE =\n \"conversation_initiation_client_data\";\n\nexport function constructOverrides(\n config: SessionConfig\n): InitiationClientDataEvent {\n const overridesEvent: InitiationClientDataEvent = {\n type: CONVERSATION_INITIATION_CLIENT_DATA_TYPE,\n };\n\n if (config.overrides) {\n overridesEvent.conversation_config_override = {\n agent: {\n prompt: config.overrides.agent?.prompt,\n first_message: config.overrides.agent?.firstMessage,\n language: config.overrides.agent?.language,\n },\n tts: {\n voice_id: config.overrides.tts?.voiceId,\n },\n conversation: {\n text_only: config.overrides.conversation?.textOnly,\n },\n };\n }\n\n if (config.customLlmExtraBody) {\n overridesEvent.custom_llm_extra_body = config.customLlmExtraBody;\n }\n\n if (config.dynamicVariables) {\n overridesEvent.dynamic_variables = config.dynamicVariables;\n }\n\n if (config.userId) {\n overridesEvent.user_id = config.userId;\n }\n\n if (config.overrides?.client) {\n overridesEvent.source_info = {\n source: config.overrides.client.source,\n version: config.overrides.client.version,\n };\n }\n\n return overridesEvent;\n}\n","import {\n BaseConnection,\n type SessionConfig,\n type FormatConfig,\n parseFormat,\n} from \"./BaseConnection\";\nimport { PACKAGE_VERSION } from \"../version\";\nimport {\n type ConfigEvent,\n isValidSocketEvent,\n type OutgoingSocketEvent,\n} from \"./events\";\nimport { constructOverrides } from \"./overrides\";\n\nconst MAIN_PROTOCOL = \"convai\";\nconst WSS_API_ORIGIN = \"wss://api.elevenlabs.io\";\nconst WSS_API_PATHNAME = \"/v1/convai/conversation?agent_id=\";\n\nexport class WebSocketConnection extends BaseConnection {\n public readonly conversationId: string;\n public readonly inputFormat: FormatConfig;\n public readonly outputFormat: FormatConfig;\n\n private constructor(\n private readonly socket: WebSocket,\n conversationId: string,\n inputFormat: FormatConfig,\n outputFormat: FormatConfig\n ) {\n super();\n this.conversationId = conversationId;\n this.inputFormat = inputFormat;\n this.outputFormat = outputFormat;\n\n this.socket.addEventListener(\"error\", event => {\n // In case the error event is followed by a close event, we want the\n // latter to be the one that disconnects the session as it contains more\n // useful information.\n setTimeout(\n () =>\n this.disconnect({\n reason: \"error\",\n message: \"The connection was closed due to a socket error.\",\n context: event,\n }),\n 0\n );\n });\n\n this.socket.addEventListener(\"close\", event => {\n this.disconnect(\n event.code === 1000\n ? {\n reason: \"agent\",\n context: event,\n }\n : {\n reason: \"error\",\n message:\n event.reason || \"The connection was closed by the server.\",\n context: event,\n }\n );\n });\n\n this.socket.addEventListener(\"message\", event => {\n try {\n const parsedEvent = JSON.parse(event.data);\n if (!isValidSocketEvent(parsedEvent)) {\n this.debug({\n type: \"invalid_event\",\n message: \"Received invalid socket event\",\n data: event.data,\n });\n return;\n }\n this.handleMessage(parsedEvent);\n } catch (error) {\n this.debug({\n type: \"parsing_error\",\n message: \"Failed to parse socket message\",\n error: error instanceof Error ? error.message : String(error),\n data: event.data,\n });\n }\n });\n }\n\n public static async create(\n config: SessionConfig\n ): Promise<WebSocketConnection> {\n let socket: WebSocket | null = null;\n\n try {\n const origin = config.origin ?? WSS_API_ORIGIN;\n let url: string;\n\n const version = config.overrides?.client?.version || PACKAGE_VERSION;\n const source = config.overrides?.client?.source || \"js_sdk\";\n\n if (config.signedUrl) {\n const separator = config.signedUrl.includes(\"?\") ? \"&\" : \"?\";\n url = `${config.signedUrl}${separator}source=${source}&version=${version}`;\n } else {\n url = `${origin}${WSS_API_PATHNAME}${config.agentId}&source=${source}&version=${version}`;\n }\n\n const protocols = [MAIN_PROTOCOL];\n if (config.authorization) {\n protocols.push(`bearer.${config.authorization}`);\n }\n socket = new WebSocket(url, protocols);\n\n const conversationConfig = await new Promise<\n ConfigEvent[\"conversation_initiation_metadata_event\"]\n >((resolve, reject) => {\n socket!.addEventListener(\n \"open\",\n () => {\n const overridesEvent = constructOverrides(config);\n\n socket?.send(JSON.stringify(overridesEvent));\n },\n { once: true }\n );\n\n socket!.addEventListener(\"error\", event => {\n // In case the error event is followed by a close event, we want the\n // latter to be the one that rejects the promise as it contains more\n // useful information.\n setTimeout(() => reject(event), 0);\n });\n\n socket!.addEventListener(\"close\", reject);\n\n socket!.addEventListener(\n \"message\",\n (event: MessageEvent) => {\n const message = JSON.parse(event.data);\n\n if (!isValidSocketEvent(message)) {\n return;\n }\n\n if (message.type === \"conversation_initiation_metadata\") {\n resolve(message.conversation_initiation_metadata_event);\n } else {\n console.warn(\n \"First received message is not conversation metadata.\"\n );\n }\n },\n { once: true }\n );\n });\n\n const {\n conversation_id,\n agent_output_audio_format,\n user_input_audio_format,\n } = conversationConfig;\n\n const inputFormat = parseFormat(user_input_audio_format ?? \"pcm_16000\");\n const outputFormat = parseFormat(agent_output_audio_format);\n\n return new WebSocketConnection(\n socket,\n conversation_id,\n inputFormat,\n outputFormat\n );\n } catch (error) {\n socket?.close();\n throw error;\n }\n }\n\n public close() {\n this.socket.close();\n }\n\n public sendMessage(message: OutgoingSocketEvent) {\n this.socket.send(JSON.stringify(message));\n }\n\n public async setMicMuted(isMuted: boolean): Promise<void> {\n console.warn(\n `WebSocket connection setMicMuted called with ${isMuted}, but this is handled by VoiceConversation`\n );\n }\n}\n","export function arrayBufferToBase64(b: ArrayBufferLike) {\n const buffer = new Uint8Array(b);\n // @ts-ignore\n const base64Data = window.btoa(String.fromCharCode(...buffer));\n return base64Data;\n}\n\nexport function base64ToArrayBuffer(base64: string): ArrayBuffer {\n const binaryString = window.atob(base64);\n const len = binaryString.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n}\n","const URLCache = new Map<string, string>();\n\nexport function createWorkletModuleLoader(name: string, sourceCode: string) {\n return async (worklet: AudioWorklet) => {\n const url = URLCache.get(name);\n if (url) {\n return worklet.addModule(url);\n }\n\n const blob = new Blob([sourceCode], { type: \"application/javascript\" });\n const blobURL = URL.createObjectURL(blob);\n try {\n await worklet.addModule(blobURL);\n URLCache.set(name, blobURL);\n return;\n } catch {\n URL.revokeObjectURL(blobURL);\n }\n\n try {\n // Attempting to start a conversation in Safari inside an iframe will\n // throw a CORS error because the blob:// protocol is considered\n // cross-origin. In such cases, fall back to using a base64 data URL:\n const base64 = btoa(sourceCode);\n const moduleURL = `data:application/javascript;base64,${base64}`;\n await worklet.addModule(moduleURL);\n URLCache.set(name, moduleURL);\n } catch (error) {\n throw new Error(\n `Failed to load the ${name} worklet module. Make sure the browser supports AudioWorklets.`\n );\n }\n };\n}\n","/*\n * ulaw encoding logic taken from the wavefile library\n * https://github.com/rochars/wavefile/blob/master/lib/codecs/mulaw.js\n */\n\nimport { createWorkletModuleLoader } from \"./createWorkletModuleLoader\";\n\nexport const loadRawAudioProcessor = createWorkletModuleLoader(\n \"raw-audio-processor\",\n // language=JavaScript\n `\nconst BIAS = 0x84;\nconst CLIP = 32635;\nconst encodeTable = [\n 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,\n 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,\n 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,\n 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7\n];\n\nfunction encodeSample(sample) {\n let sign;\n let exponent;\n let mantissa;\n let muLawSample;\n sign = (sample >> 8) & 0x80;\n if (sign !== 0) sample = -sample;\n sample = sample + BIAS;\n if (sample > CLIP) sample = CLIP;\n exponent = encodeTable[(sample>>7) & 0xFF];\n mantissa = (sample >> (exponent+3)) & 0x0F;\n muLawSample = ~(sign | (exponent << 4) | mantissa);\n \n return muLawSample;\n}\n\nclass RawAudioProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n \n this.port.onmessage = ({ data }) => {\n switch (data.type) {\n case \"setFormat\":\n this.isMuted = false;\n this.buffer = []; // Initialize an empty buffer\n this.bufferSize = data.sampleRate / 4;\n this.format = data.format;\n\n if (globalThis.LibSampleRate && sampleRate !== data.sampleRate) {\n globalThis.LibSampleRate.create(1, sampleRate, data.sampleRate).then(resampler => {\n this.resampler = resampler;\n });\n }\n break;\n case \"setMuted\":\n this.isMuted = data.isMuted;\n break;\n }\n };\n }\n process(inputs) {\n if (!this.buffer) {\n return true;\n }\n \n const input = inputs[0]; // Get the first input node\n if (input.length > 0) {\n let channelData = input[0]; // Get the first channel's data\n\n // Resample the audio if necessary\n if (this.resampler) {\n channelData = this.resampler.full(channelData);\n }\n\n // Add channel data to the buffer\n this.buffer.push(...channelData);\n // Get max volume \n let sum = 0.0;\n for (let i = 0; i < channelData.length; i++) {\n sum += channelData[i] * channelData[i];\n }\n const maxVolume = Math.sqrt(sum / channelData.length);\n // Check if buffer size has reached or exceeded the threshold\n if (this.buffer.length >= this.bufferSize) {\n const float32Array = this.isMuted \n ? new Float32Array(this.buffer.length)\n : new Float32Array(this.buffer);\n\n let encodedArray = this.format === \"ulaw\"\n ? new Uint8Array(float32Array.length)\n : new Int16Array(float32Array.length);\n\n // Iterate through the Float32Array and convert each sample to PCM16\n for (let i = 0; i < float32Array.length; i++) {\n // Clamp the value to the range [-1, 1]\n let sample = Math.max(-1, Math.min(1, float32Array[i]));\n\n // Scale the sample to the range [-32768, 32767]\n let value = sample < 0 ? sample * 32768 : sample * 32767;\n if (this.format === \"ulaw\") {\n value = encodeSample(Math.round(value));\n }\n\n encodedArray[i] = value;\n }\n\n // Send the buffered data to the main script\n this.port.postMessage([encodedArray, maxVolume]);\n\n // Clear the buffer after sending\n this.buffer = [];\n }\n }\n return true; // Continue processing\n }\n}\nregisterProcessor(\"raw-audio-processor\", RawAudioProcessor);\n`\n);\n","import {\n BaseConnection,\n type SessionConfig,\n type FormatConfig,\n parseFormat,\n} from \"./BaseConnection\";\nimport { PACKAGE_VERSION } from \"../version\";\nimport { isValidSocketEvent, type OutgoingSocketEvent } from \"./events\";\nimport {\n Room,\n RoomEvent,\n Track,\n ConnectionState,\n createLocalAudioTrack,\n} from \"livekit-client\";\nimport type {\n RemoteAudioTrack,\n Participant,\n TrackPublication,\n} from \"livekit-client\";\nimport {\n constructOverrides,\n CONVERSATION_INITIATION_CLIENT_DATA_TYPE,\n} from \"./overrides\";\nimport { arrayBufferToBase64 } from \"./audio\";\nimport { loadRawAudioProcessor } from \"./rawAudioProcessor\";\n\nconst DEFAULT_LIVEKIT_WS_URL = \"wss://livekit.rtc.elevenlabs.io\";\nconst HTTPS_API_ORIGIN = \"https://api.elevenlabs.io\";\n\n// Convert WSS origin to HTTPS for API calls\nfunction convertWssToHttps(origin: string): string {\n return origin.replace(/^wss:\\/\\//, \"https://\");\n}\n\nexport type ConnectionConfig = SessionConfig & {\n onDebug?: (info: unknown) => void;\n};\n\nexport class WebRTCConnection extends BaseConnection {\n public conversationId: string;\n public readonly inputFormat: FormatConfig;\n public readonly outputFormat: FormatConfig;\n\n private room: Room;\n private isConnected = false;\n private audioEventId = 1;\n private audioCaptureContext: AudioContext | null = null;\n private audioElements: HTMLAudioElement[] = [];\n private outputDeviceId: string | null = null;\n\n private outputAnalyser: AnalyserNode | null = null;\n private outputFrequencyData: Uint8Array<ArrayBuffer> | null = null;\n\n private constructor(\n room: Room,\n conversationId: string,\n inputFormat: FormatConfig,\n outputFormat: FormatConfig,\n config: { onDebug?: (info: unknown) => void } = {}\n ) {\n super(config);\n this.room = room;\n this.conversationId = conversationId;\n this.inputFormat = inputFormat;\n this.outputFormat = outputFormat;\n\n this.setupRoomEventListeners();\n }\n\n public static async create(\n config: ConnectionConfig\n ): Promise<WebRTCConnection> {\n let conversationToken: string;\n\n // Handle different authentication scenarios\n if (\"conversationToken\" in config && config.conversationToken) {\n // Direct token provided\n conversationToken = config.conversationToken;\n } else if (\"agentId\" in config && config.agentId) {\n // Agent ID provided - fetch token from API\n try {\n const version = config.overrides?.client?.version || PACKAGE_VERSION;\n const source = config.overrides?.client?.source || \"js_sdk\";\n const configOrigin = config.origin ?? HTTPS_API_ORIGIN;\n const origin = convertWssToHttps(configOrigin); //origin is wss, not https\n const url = `${origin}/v1/convai/conversation/token?agent_id=${config.agentId}&source=${source}&version=${version}`;\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(\n `ElevenLabs API returned ${response.status} ${response.statusText}`\n );\n }\n\n const data = await response.json();\n conversationToken = data.token;\n\n if (!conversationToken) {\n throw new Error(\"No conversation token received from API\");\n }\n } catch (error) {\n let msg = error instanceof Error ? error.message : String(error);\n if (error instanceof Error && error.message.includes(\"401\")) {\n msg =\n \"Your agent has authentication enabled, but no signed URL or conversation token was provided.\";\n }\n\n throw new Error(\n `Failed to fetch conversation token for agent ${config.agentId}: ${msg}`\n );\n }\n } else {\n throw new Error(\n \"Either conversationToken or agentId is required for WebRTC connection\"\n );\n }\n\n const room = new Room();\n\n try {\n // Create connection instance first to set up event listeners\n const conversationId = `room_${Date.now()}`;\n const inputFormat = parseFormat(\"pcm_48000\");\n const outputFormat = parseFormat(\"pcm_48000\");\n const connection = new WebRTCConnection(\n room,\n conversationId,\n inputFormat,\n outputFormat,\n config\n );\n\n // Use configurable LiveKit URL or default if not provided\n const livekitUrl = config.livekitUrl || DEFAULT_LIVEKIT_WS_URL;\n\n // Connect to the LiveKit room and wait for the Connected event\n await room.connect(livekitUrl, conversationToken);\n\n // Wait for the Connected event to ensure isConnected is true\n await new Promise<void>(resolve => {\n if (connection.isConnected) {\n resolve();\n } else {\n const onConnected = () => {\n room.off(RoomEvent.Connected, onConnected);\n resolve();\n };\n room.on(RoomEvent.Connected, onConnected);\n }\n });\n\n if (room.name) {\n connection.conversationId =\n room.name.match(/(conv_[a-zA-Z0-9]+)/)?.[0] || room.name;\n }\n\n // Enable microphone and send overrides\n await room.localParticipant.setMicrophoneEnabled(true);\n\n const overridesEvent = constructOverrides(config);\n\n connection.debug({\n type: CONVERSATION_INITIATION_CLIENT_DATA_TYPE,\n message: overridesEvent,\n });\n\n await connection.sendMessage(overridesEvent);\n\n return connection;\n } catch (error) {\n await room.disconnect();\n throw error;\n }\n }\n\n private setupRoomEventListeners() {\n this.room.on(RoomEvent.Connected, async () => {\n this.isConnected = true;\n console.info(\"WebRTC room connected\");\n });\n\n this.room.on(RoomEvent.Disconnected, reason => {\n this.isConnected = false;\n this.disconnect({\n reason: \"agent\",\n context: new CloseEvent(\"close\", { reason: reason?.toString() }),\n });\n });\n\n this.room.on(RoomEvent.ConnectionStateChanged, state => {\n if (state === ConnectionState.Disconnected) {\n this.isConnected = false;\n this.disconnect({\n reason: \"error\",\n message: `LiveKit connection state changed to ${state}`,\n context: new Event(\"connection_state_changed\"),\n });\n }\n });\n\n // Handle incoming data messages\n this.room.on(\n RoomEvent.DataReceived,\n (payload: Uint8Array, _participant) => {\n try {\n const message = JSON.parse(new TextDecoder().decode(payload));\n\n // Filter out audio messages for WebRTC - they're handled via audio tracks\n if (message.type === \"audio\") {\n return;\n }\n\n if (isValidSocketEvent(message)) {\n this.handleMessage(message);\n } else {\n console.warn(\"Invalid socket event received:\", message);\n }\n } catch (error) {\n console.warn(\"Failed to parse incoming data message:\", error);\n console.warn(\"Raw payload:\", new TextDecoder().decode(payload));\n }\n }\n );\n\n this.room.on(\n RoomEvent.TrackSubscribed,\n async (\n track: Track,\n _publication: TrackPublication,\n participant: Participant\n ) => {\n if (\n track.kind === Track.Kind.Audio &&\n participant.identity.includes(\"agent\")\n ) {\n // Play the audio track\n const remoteAudioTrack = track as RemoteAudioTrack;\n const audioElement = remoteAudioTrack.attach();\n audioElement.autoplay = true;\n audioElement.controls = false;\n\n // Set output device if one was previously selected\n if (this.outputDeviceId && audioElement.setSinkId) {\n try {\n await audioElement.setSinkId(this.outputDeviceId);\n } catch (error) {\n console.warn(\n \"Failed to set output device for new audio element:\",\n error\n );\n }\n }\n\n // Add to DOM (hidden) to ensure it plays\n audioElement.style.display = \"none\";\n document.body.appendChild(audioElement);\n\n // Store reference for volume control\n this.audioElements.push(audioElement);\n\n // Apply current volume if it exists (for when volume was set before audio track arrived)\n if (this.audioElements.length === 1) {\n // First audio element - trigger a callback to sync with current volume\n this.onDebug?.({ type: \"audio_element_ready\" });\n }\n\n // Set up audio capture for onAudio callback\n await this.setupAudioCapture(remoteAudioTrack);\n }\n }\n );\n\n this.room.on(\n RoomEvent.ActiveSpeakersChanged,\n async (speakers: Participant[]) => {\n if (speakers.length > 0) {\n this.updateMode(\n speakers[0].identity.startsWith(\"agent\") ? \"speaking\" : \"listening\"\n );\n } else {\n this.updateMode(\"listening\");\n }\n }\n );\n }\n\n public close() {\n if (this.isConnected) {\n try {\n // Explicitly stop all local tracks before disconnecting to ensure microphone is released\n this.room.localParticipant.audioTrackPublications.forEach(\n publication => {\n if (publication.track) {\n publication.track.stop();\n }\n }\n );\n } catch (error) {\n console.warn(\"Error stopping local tracks:\", error);\n }\n\n // Clean up audio capture context (non-blocking)\n if (this.audioCaptureContext) {\n this.audioCaptureContext.close().catch(error => {\n console.warn(\"Error closing audio capture context:\", error);\n });\n this.audioCaptureContext = null;\n }\n\n // Clean up audio elements\n this.audioElements.forEach(element => {\n if (element.parentNode) {\n element.parentNode.removeChild(element);\n }\n });\n this.audioElements = [];\n\n this.room.disconnect();\n }\n }\n\n public async sendMessage(message: OutgoingSocketEvent) {\n if (!this.isConnected || !this.room.localParticipant) {\n console.warn(\n \"Cannot send message: room not connected or no local participant\"\n );\n return;\n }\n\n // In WebRTC mode, audio is sent via published tracks, not data messages\n if (\"user_audio_chunk\" in message) {\n // Ignore audio data messages - audio flows through WebRTC tracks\n return;\n }\n\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify(message));\n\n await this.room.localParticipant.publishData(data, { reliable: true });\n } catch (error) {\n this.debug({\n type: \"send_message_error\",\n message: {\n message,\n error,\n },\n });\n console.error(\"Failed to send message via WebRTC:\", error);\n }\n }\n\n // Get the room instance for advanced usage\n public getRoom(): Room {\n return this.room;\n }\n\n public async setMicMuted(isMuted: boolean): Promise<void> {\n if (!this.isConnected || !this.room.localParticipant) {\n console.warn(\n \"Cannot set microphone muted: room not connected or no local participant\"\n );\n return;\n }\n\n // Get the microphone track publication\n const micTrackPublication = this.room.localParticipant.getTrackPublication(\n Track.Source.Microphone\n );\n\n if (micTrackPublication?.track) {\n try {\n // Use LiveKit's built-in track muting\n if (isMuted) {\n await micTrackPublication.track.mute();\n } else {\n await micTrackPublication.track.unmute();\n }\n } catch (_error) {\n // If track muting fails, fall back to participant-level control\n await this.room.localParticipant.setMicrophoneEnabled(!isMuted);\n }\n } else {\n // No track found, use participant-level control directly\n await this.room.localParticipant.setMicrophoneEnabled(!isMuted);\n }\n }\n\n private async setupAudioCapture(track: RemoteAudioTrack) {\n try {\n // Create audio context for processing\n const audioContext = new AudioContext();\n this.audioCaptureContext = audioContext;\n\n // Create analyser for frequency data\n this.outputAnalyser = audioContext.createAnalyser();\n this.outputAnalyser.fftSize = 2048;\n this.outputAnalyser.smoothingTimeConstant = 0.8;\n\n // Create MediaStream from the track\n const mediaStream = new MediaStream([track.mediaStreamTrack]);\n\n // Create audio source from the stream\n const source = audioContext.createMediaStreamSource(mediaStream);\n\n // Connect source to analyser\n source.connect(this.outputAnalyser);\n\n await loadRawAudioProcessor(audioContext.audioWorklet);\n const worklet = new AudioWorkletNode(audioContext, \"raw-audio-processor\");\n\n // Connect analyser to worklet for processing\n this.outputAnalyser.connect(worklet);\n\n // Configure the processor for the output format\n worklet.port.postMessage({\n type: \"setFormat\",\n format: this.outputFormat.format,\n sampleRate: this.outputFormat.sampleRate,\n });\n\n // Handle processed audio data\n worklet.port.onmessage = (event: MessageEvent) => {\n const [audioData, maxVolume] = event.data;\n\n // Only send audio if there's significant volume (not just silence)\n const volumeThreshold = 0.01;\n\n if (maxVolume > volumeThreshold) {\n // Convert to base64\n const base64Audio = arrayBufferToBase64(audioData.buffer);\n\n // Use sequential event ID for proper feedback tracking\n const eventId = this.audioEventId++;\n\n // Trigger the onAudio callback by simulating an audio event\n this.handleMessage({\n type: \"audio\",\n audio_event: {\n audio_base_64: base64Audio,\n event_id: eventId,\n },\n });\n }\n };\n\n // Connect the audio processing chain\n source.connect(worklet);\n } catch (error) {\n console.warn(\"Failed to set up audio capture:\", error);\n }\n }\n\n public setAudioVolume(volume: number) {\n this.audioElements.forEach(element => {\n element.volume = volume;\n });\n }\n\n public async setAudioOutputDevice(deviceId: string): Promise<void> {\n if (!(\"setSinkId\" in HTMLAudioElement.prototype)) {\n throw new Error(\"setSinkId is not supported in this browser\");\n }\n\n // Set output device for all existing audio elements\n const promises = this.audioElements.map(async element => {\n try {\n await element.setSinkId(deviceId);\n } catch (error) {\n console.error(\"Failed to set sink ID for audio element:\", error);\n throw error;\n }\n });\n\n await Promise.all(promises);\n\n // Store the device ID for future audio elements\n this.outputDeviceId = deviceId;\n }\n\n public async setAudioInputDevice(deviceId: string): Promise<void> {\n if (!this.isConnected || !this.room.localParticipant) {\n throw new Error(\n \"Cannot change input device: room not connected or no local participant\"\n );\n }\n\n try {\n // Get the current microphone track publication\n const currentMicTrackPublication =\n this.room.localParticipant.getTrackPublication(Track.Source.Microphone);\n\n // Stop the current microphone track if it exists\n if (currentMicTrackPublication?.track) {\n await currentMicTrackPublication.track.stop();\n await this.room.localParticipant.unpublishTrack(\n currentMicTrackPublication.track\n );\n }\n\n // Create constraints for the new input device\n const audioConstraints: MediaTrackConstraints = {\n deviceId: { exact: deviceId },\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n channelCount: { ideal: 1 },\n };\n\n // Create new audio track with the specified device\n const audioTrack = await createLocalAudioTrack(audioConstraints);\n\n // Publish the new microphone track\n await this.room.localParticipant.publishTrack(audioTrack, {\n name: \"microphone\",\n source: Track.Source.Microphone,\n });\n } catch (error) {\n console.error(\"Failed to change input device:\", error);\n\n // Try to re-enable default microphone on failure\n try {\n await this.room.localParticipant.setMicrophoneEnabled(true);\n } catch (recoveryError) {\n console.error(\n \"Failed to recover microphone after device switch error:\",\n recoveryError\n );\n }\n\n throw error;\n }\n }\n\n public getOutputByteFrequencyData(): Uint8Array<ArrayBuffer> | null {\n if (!this.outputAnalyser) return null;\n\n this.outputFrequencyData ??= new Uint8Array(\n this.outputAnalyser.frequencyBinCount\n ) as Uint8Array<ArrayBuffer>;\n this.outputAnalyser.getByteFrequencyData(this.outputFrequencyData);\n return this.outputFrequencyData;\n }\n}\n","import type {\n BaseConnection,\n SessionConfig,\n ConnectionType,\n} from \"./BaseConnection\";\nimport { WebSocketConnection } from \"./WebSocketConnection\";\nimport { WebRTCConnection } from \"./WebRTCConnection\";\n\nfunction determineConnectionType(config: SessionConfig): ConnectionType {\n // If connectionType is explicitly specified, use it\n if (config.connectionType) {\n return config.connectionType;\n }\n\n // If conversationToken is provided, use WebRTC\n if (\"conversationToken\" in config && config.conversationToken) {\n return \"webrtc\";\n }\n\n // Default to WebSocket for backward compatibility\n return \"websocket\";\n}\n\nexport async function createConnection(\n config: SessionConfig\n): Promise<BaseConnection> {\n const connectionType = determineConnectionType(config);\n\n switch (connectionType) {\n case \"websocket\":\n return WebSocketConnection.create(config);\n case \"webrtc\":\n return WebRTCConnection.create(config);\n default:\n throw new Error(`Unknown connection type: ${connectionType}`);\n }\n}\n","export function isIosDevice() {\n return (\n [\n \"iPad Simulator\",\n \"iPhone Simulator\",\n \"iPod Simulator\",\n \"iPad\",\n \"iPhone\",\n \"iPod\",\n ].includes(navigator.platform) ||\n // iPad on iOS 13 detection\n (navigator.userAgent.includes(\"Mac\") && \"ontouchend\" in document)\n );\n}\n\nexport function isAndroidDevice() {\n return /android/i.test(navigator.userAgent);\n}\n","import { isAndroidDevice, isIosDevice } from \"./compatibility\";\nimport type { DelayConfig } from \"./connection\";\n\nexport async function applyDelay(\n delayConfig: DelayConfig = {\n default: 0,\n // Give the Android AudioManager enough time to switch to the correct audio mode\n android: 3_000,\n }\n) {\n let delay = delayConfig.default;\n if (isAndroidDevice()) {\n delay = delayConfig.android ?? delay;\n } else if (isIosDevice()) {\n delay = delayConfig.ios ?? delay;\n }\n\n if (delay > 0) {\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n}\n","import { createConnection } from \"./utils/ConnectionFactory\";\nimport type { BaseConnection } from \"./utils/BaseConnection\";\nimport { applyDelay } from \"./utils/applyDelay\";\nimport { BaseConversation, type PartialOptions } from \"./BaseConversation\";\n\nexport class TextConversation extends BaseConversation {\n public static async startSession(\n options: PartialOptions\n ): Promise<TextConversation> {\n const fullOptions = BaseConversation.getFullOptions(options);\n\n if (fullOptions.onStatusChange) {\n fullOptions.onStatusChange({ status: \"connecting\" });\n }\n if (fullOptions.onCanSendFeedbackChange) {\n fullOptions.onCanSendFeedbackChange({ canSendFeedback: false });\n }\n if (fullOptions.onModeChange) {\n fullOptions.onModeChange({ mode: \"listening\" });\n }\n if (fullOptions.onCanSendFeedbackChange) {\n fullOptions.onCanSendFeedbackChange({ canSendFeedback: false });\n }\n\n let connection: BaseConnection | null = null;\n try {\n await applyDelay(fullOptions.connectionDelay);\n connection = await createConnection(options);\n return new TextConversation(fullOptions, connection);\n } catch (error) {\n if (fullOptions.onStatusChange) {\n fullOptions.onStatusChange({ status: \"disconnected\" });\n }\n connection?.close();\n throw error;\n }\n }\n}\n","import { loadRawAudioProcessor } from \"./rawAudioProcessor\";\nimport type { FormatConfig } from \"./connection\";\nimport { isIosDevice } from \"./compatibility\";\n\nexport type InputConfig = {\n preferHeadphonesForIosDevices?: boolean;\n inputDeviceId?: string;\n};\n\nconst LIBSAMPLERATE_JS =\n \"https://cdn.jsdelivr.net/npm/@alexanderolsen/libsamplerate-js@2.1.2/dist/libsamplerate.worklet.js\";\n\nconst defaultConstraints = {\n echoCancellation: true,\n noiseSuppression: true,\n // Automatic gain control helps maintain a steady volume level with microphones: https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings/autoGainControl\n autoGainControl: true,\n // Mono audio for better echo cancellation\n channelCount: { ideal: 1 },\n};\n\nexport class Input {\n public static async create({\n sampleRate,\n format,\n preferHeadphonesForIosDevices,\n inputDeviceId,\n }: FormatConfig & InputConfig): Promise<Input> {\n let context: AudioContext | null = null;\n let inputStream: MediaStream | null = null;\n\n try {\n const options: MediaTrackConstraints = {\n sampleRate: { ideal: sampleRate },\n ...defaultConstraints,\n };\n\n if (isIosDevice() && preferHeadphonesForIosDevices) {\n const availableDevices =\n await window.navigator.mediaDevices.enumerateDevices();\n const idealDevice = availableDevices.find(\n d =>\n // cautious to include \"bluetooth\" in the search\n // as might trigger bluetooth speakers\n d.kind === \"audioinput\" &&\n [\"airpod\", \"headphone\", \"earphone\"].find(keyword =>\n d.label.toLowerCase().includes(keyword)\n )\n );\n if (idealDevice) {\n options.deviceId = { ideal: idealDevice.deviceId };\n }\n }\n\n if (inputDeviceId) {\n options.deviceId = { exact: inputDeviceId };\n }\n\n const supportsSampleRateConstraint =\n navigator.mediaDevices.getSupportedConstraints().sampleRate;\n\n context = new window.AudioContext(\n supportsSampleRateConstraint ? { sampleRate } : {}\n );\n const analyser = context.createAnalyser();\n if (!supportsSampleRateConstraint) {\n await context.audioWorklet.addModule(LIBSAMPLERATE_JS);\n }\n await loadRawAudioProcessor(context.audioWorklet);\n\n const constraints = { voiceIsolation: true, ...options };\n inputStream = await navigator.mediaDevices.getUserMedia({\n audio: constraints,\n });\n\n const source = context.createMediaStreamSource(inputStream);\n const worklet = new AudioWorkletNode(context, \"raw-audio-processor\");\n worklet.port.postMessage({ type: \"setFormat\", format, sampleRate });\n\n source.connect(analyser);\n analyser.connect(worklet);\n\n await context.resume();\n\n return new Input(context, analyser, worklet, inputStream, source);\n } catch (error) {\n inputStream?.getTracks().forEach(track => {\n track.stop();\n });\n context?.close();\n throw error;\n }\n }\n\n private constructor(\n public readonly context: AudioContext,\n public readonly analyser: AnalyserNode,\n public readonly worklet: AudioWorkletNode,\n public inputStream: MediaStream,\n private mediaStreamSource: MediaStreamAudioSourceNode\n ) {}\n\n public async close() {\n this.inputStream.getTracks().forEach(track => {\n track.stop();\n });\n this.mediaStreamSource.disconnect();\n await this.context.close();\n }\n\n public setMuted(isMuted: boolean) {\n this.worklet.port.postMessage({ type: \"setMuted\", isMuted });\n }\n\n public async setInputDevice(inputDeviceId: string): Promise<void> {\n if (!inputDeviceId) {\n throw new Error(\"Input device ID is required\");\n }\n\n try {\n // Create new constraints with the specified device\n const options: MediaTrackConstraints = {\n deviceId: { exact: inputDeviceId },\n ...defaultConstraints,\n };\n\n const constraints = { voiceIsolation: true, ...options };\n\n // Get new media stream with the specified device\n const newInputStream = await navigator.mediaDevices.getUserMedia({\n audio: constraints,\n });\n\n // Stop old tracks and disconnect old source\n this.inputStream.getTracks().forEach(track => {\n track.stop();\n });\n this.mediaStreamSource.disconnect();\n\n // Replace the stream and create new source\n this.inputStream = newInputStream;\n this.mediaStreamSource =\n this.context.createMediaStreamSource(newInputStream);\n\n // Reconnect the audio graph\n this.mediaStreamSource.connect(this.analyser);\n } catch (error) {\n console.error(\"Failed to switch input device:\", error);\n throw error;\n }\n }\n}\n","/*\n * ulaw decoding logic taken from the wavefile library\n * https://github.com/rochars/wavefile/blob/master/lib/codecs/mulaw.js\n */\n\nimport { createWorkletModuleLoader } from \"./createWorkletModuleLoader\";\n\nexport const loadAudioConcatProcessor = createWorkletModuleLoader(\n \"audio-concat-processor\",\n // language=JavaScript\n `\nconst decodeTable = [0,132,396,924,1980,4092,8316,16764];\n\nexport function decodeSample(muLawSample) {\n let sign;\n let exponent;\n let mantissa;\n let sample;\n muLawSample = ~muLawSample;\n sign = (muLawSample & 0x80);\n exponent = (muLawSample >> 4) & 0x07;\n mantissa = muLawSample & 0x0F;\n sample = decodeTable[exponent] + (mantissa << (exponent+3));\n if (sign !== 0) sample = -sample;\n\n return sample;\n}\n\nclass AudioConcatProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.buffers = []; // Initialize an empty buffer\n this.cursor = 0;\n this.currentBuffer = null;\n this.wasInterrupted = false;\n this.finished = false;\n \n this.port.onmessage = ({ data }) => {\n switch (data.type) {\n case \"setFormat\":\n this.format = data.format;\n break;\n case \"buffer\":\n this.wasInterrupted = false;\n this.buffers.push(\n this.format === \"ulaw\"\n ? new Uint8Array(data.buffer)\n : new Int16Array(data.buffer)\n );\n break;\n case \"interrupt\":\n this.wasInterrupted = true;\n break;\n case \"clearInterrupted\":\n if (this.wasInterrupted) {\n this.wasInterrupted = false;\n this.buffers = [];\n this.currentBuffer = null;\n }\n }\n };\n }\n process(_, outputs) {\n let finished = false;\n const output = outputs[0][0];\n for (let i = 0; i < output.length; i++) {\n if (!this.currentBuffer) {\n if (this.buffers.length === 0) {\n finished = true;\n break;\n }\n this.currentBuffer = this.buffers.shift();\n this.cursor = 0;\n }\n\n let value = this.currentBuffer[this.cursor];\n if (this.format === \"ulaw\") {\n value = decodeSample(value);\n }\n output[i] = value / 32768;\n this.cursor++;\n\n if (this.cursor >= this.currentBuffer.length) {\n this.currentBuffer = null;\n }\n }\n\n if (this.finished !== finished) {\n this.finished = finished;\n this.port.postMessage({ type: \"process\", finished });\n }\n\n return true; // Continue processing\n }\n}\n\nregisterProcessor(\"audio-concat-processor\", AudioConcatProcessor);\n`\n);\n","import { loadAudioConcatProcessor } from \"./audioConcatProcessor\";\nimport type { FormatConfig } from \"./connection\";\n\nexport class Output {\n public static async create({\n sampleRate,\n format,\n outputDeviceId,\n }: FormatConfig): Promise<Output> {\n let context: AudioContext | null = null;\n let audioElement: HTMLAudioElement | null = null;\n try {\n context = new AudioContext({ sampleRate });\n const analyser = context.createAnalyser();\n const gain = context.createGain();\n\n // Always create an audio element for device switching capability\n audioElement = new Audio();\n audioElement.src = \"\";\n audioElement.load();\n audioElement.autoplay = true;\n audioElement.style.display = \"none\";\n\n document.body.appendChild(audioElement);\n\n // Create media stream destination to route audio to the element\n const destination = context.createMediaStreamDestination();\n audioElement.srcObject = destination.stream;\n\n gain.connect(analyser);\n analyser.connect(destination);\n\n await loadAudioConcatProcessor(context.audioWorklet);\n const worklet = new AudioWorkletNode(context, \"audio-concat-processor\");\n worklet.port.postMessage({ type: \"setFormat\", format });\n worklet.connect(gain);\n\n await context.resume();\n\n // Set initial output device if provided\n if (outputDeviceId && audioElement.setSinkId) {\n await audioElement.setSinkId(outputDeviceId);\n }\n\n const newOutput = new Output(\n context,\n analyser,\n gain,\n worklet,\n audioElement\n );\n\n return newOutput;\n } catch (error) {\n // Clean up audio element from DOM\n if (audioElement?.parentNode) {\n audioElement.parentNode.removeChild(audioElement);\n }\n audioElement?.pause();\n if (context && context.state !== \"closed\") {\n await context.close();\n }\n\n throw error;\n }\n }\n\n private constructor(\n public readonly context: AudioContext,\n public readonly analyser: AnalyserNode,\n public readonly gain: GainNode,\n public readonly worklet: AudioWorkletNode,\n public readonly audioElement: HTMLAudioElement\n ) {}\n\n public async setOutputDevice(deviceId: string): Promise<void> {\n if (!(\"setSinkId\" in HTMLAudioElement.prototype)) {\n throw new Error(\"setSinkId is not supported in this browser\");\n }\n\n await this.audioElement.setSinkId(deviceId);\n }\n\n public async close() {\n // Remove audio element from DOM\n if (this.audioElement.parentNode) {\n this.audioElement.parentNode.removeChild(this.audioElement);\n }\n this.audioElement.pause();\n await this.context.close();\n }\n}\n","import { arrayBufferToBase64, base64ToArrayBuffer } from \"./utils/audio\";\nimport { Input, type InputConfig } from \"./utils/input\";\nimport { Output } from \"./utils/output\";\nimport { createConnection } from \"./utils/ConnectionFactory\";\nimport type { BaseConnection, FormatConfig } from \"./utils/BaseConnection\";\nimport { WebRTCConnection } from \"./utils/WebRTCConnection\";\nimport type { AgentAudioEvent, InterruptionEvent } from \"./utils/events\";\nimport { applyDelay } from \"./utils/applyDelay\";\nimport {\n BaseConversation,\n type Options,\n type PartialOptions,\n} from \"./BaseConversation\";\nimport { WebSocketConnection } from \"./utils/WebSocketConnection\";\n\nexport class VoiceConversation extends BaseConversation {\n public static async startSession(\n options: PartialOptions\n ): Promise<VoiceConversation> {\n const fullOptions = BaseConversation.getFullOptions(options);\n\n if (fullOptions.onStatusChange) {\n fullOptions.onStatusChange({ status: \"connecting\" });\n }\n if (fullOptions.onCanSendFeedbackChange) {\n fullOptions.onCanSendFeedbackChange({ canSendFeedback: false });\n }\n\n let input: Input | null = null;\n let connection: BaseConnection | null = null;\n let output: Output | null = null;\n let preliminaryInputStream: MediaStream | null = null;\n\n let wakeLock: WakeLockSentinel | null = null;\n if (options.useWakeLock ?? true) {\n try {\n wakeLock = await navigator.wakeLock.request(\"screen\");\n } catch (_e) {\n // Wake Lock is not required for the conversation to work\n }\n }\n\n try {\n // some browsers won't allow calling getSupportedConstraints or enumerateDevices\n // before getting approval for microphone access\n preliminaryInputStream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n\n await applyDelay(fullOptions.connectionDelay);\n connection = await createConnection(options);\n [input, output] = await Promise.all([\n Input.create({\n ...connection.inputFormat,\n preferHeadphonesForIosDevices: options.preferHeadphonesForIosDevices,\n inputDeviceId: options.inputDeviceId,\n }),\n Output.create({\n ...connection.outputFormat,\n outputDeviceId: options.outputDeviceId,\n }),\n ]);\n\n preliminaryInputStream?.getTracks().forEach(track => {\n track.stop();\n });\n preliminaryInputStream = null;\n\n return new VoiceConversation(\n fullOptions,\n connection,\n input,\n output,\n wakeLock\n );\n } catch (error) {\n if (fullOptions.onStatusChange) {\n fullOptions.onStatusChange({ status: \"disconnected\" });\n }\n preliminaryInputStream?.getTracks().forEach(track => {\n track.stop();\n });\n connection?.close();\n await input?.close();\n await output?.close();\n try {\n await wakeLock?.release();\n wakeLock = null;\n } catch (_e) {}\n throw error;\n }\n }\n\n private inputFrequencyData?: Uint8Array<ArrayBuffer>;\n private outputFrequencyData?: Uint8Array<ArrayBuffer>;\n\n protected constructor(\n options: Options,\n connection: BaseConnection,\n public input: Input,\n public output: Output,\n public wakeLock: WakeLockSentinel | null\n ) {\n super(options, connection);\n this.input.worklet.port.onmessage = this.onInputWorkletMessage;\n this.output.worklet.port.onmessage = this.onOutputWorkletMessage;\n }\n\n protected override async handleEndSession() {\n await super.handleEndSession();\n try {\n await this.wakeLock?.release();\n this.wakeLock = null;\n } catch (_e) {}\n\n await this.input.close();\n await this.output.close();\n }\n\n protected override handleInterruption(event: InterruptionEvent) {\n super.handleInterruption(event);\n this.fadeOutAudio();\n }\n\n protected override handleAudio(event: AgentAudioEvent) {\n if (this.lastInterruptTimestamp <= event.audio_event.event_id) {\n this.options.onAudio?.(event.audio_event.audio_base_64);\n\n // Only play audio through the output worklet for WebSocket connections\n // WebRTC connections handle audio playback directly through LiveKit tracks\n if (!(this.connection instanceof WebRTCConnection)) {\n this.addAudioBase64Chunk(event.audio_event.audio_base_64);\n }\n\n this.currentEventId = event.audio_event.event_id;\n this.updateCanSendFeedback();\n this.updateMode(\"speaking\");\n }\n }\n\n private onInputWorkletMessage = (event: MessageEvent): void => {\n const rawAudioPcmData = event.data[0];\n\n // TODO: When supported, maxVolume can be used to avoid sending silent audio\n // const maxVolume = event.data[1];\n\n if (this.status === \"connected\") {\n this.connection.sendMessage({\n user_audio_chunk: arrayBufferToBase64(rawAudioPcmData.buffer),\n });\n }\n };\n\n private onOutputWorkletMessage = ({ data }: MessageEvent): void => {\n if (data.type === \"process\") {\n this.updateMode(data.finished ? \"listening\" : \"speaking\");\n }\n };\n\n private addAudioBase64Chunk = (chunk: string) => {\n this.output.gain.gain.value = this.volume;\n this.output.worklet.port.postMessage({ type: \"clearInterrupted\" });\n this.output.worklet.port.postMessage({\n type: \"buffer\",\n buffer: base64ToArrayBuffer(chunk),\n });\n };\n\n private fadeOutAudio = () => {\n // mute agent\n this.updateMode(\"listening\");\n this.output.worklet.port.postMessage({ type: \"interrupt\" });\n this.output.gain.gain.exponentialRampToValueAtTime(\n 0.0001,\n this.output.context.currentTime + 2\n );\n\n // reset volume back\n setTimeout(() => {\n this.output.gain.gain.value = this.volume;\n this.output.worklet.port.postMessage({ type: \"clearInterrupted\" });\n }, 2000); // Adjust the duration as needed\n };\n\n private calculateVolume = (frequencyData: Uint8Array) => {\n if (frequencyData.length === 0) {\n return 0;\n }\n\n // TODO: Currently this averages all frequencies, but we should probably\n // bias towards the frequencies that are more typical for human voice\n let volume = 0;\n for (let i = 0; i < frequencyData.length; i++) {\n volume += frequencyData[i] / 255;\n }\n volume /= frequencyData.length;\n\n return volume < 0 ? 0 : volume > 1 ? 1 : volume;\n };\n\n public setMicMuted(isMuted: boolean) {\n // Use LiveKit track muting for WebRTC connections\n if (this.connection instanceof WebRTCConnection) {\n this.connection.setMicMuted(isMuted);\n } else {\n // Use input muting for WebSocket connections\n this.input.setMuted(isMuted);\n }\n }\n\n public getInputByteFrequencyData(): Uint8Array<ArrayBuffer> {\n this.inputFrequencyData ??= new Uint8Array(\n this.input.analyser.frequencyBinCount\n ) as Uint8Array<ArrayBuffer>;\n this.input.analyser.getByteFrequencyData(this.inputFrequencyData);\n return this.inputFrequencyData;\n }\n\n public getOutputByteFrequencyData(): Uint8Array<ArrayBuffer> {\n // Use WebRTC analyser if available\n if (this.connection instanceof WebRTCConnection) {\n const webrtcData = this.connection.getOutputByteFrequencyData();\n if (webrtcData) {\n return webrtcData as Uint8Array<ArrayBuffer>;\n }\n // Fallback to empty array if WebRTC analyser not ready\n return new Uint8Array(1024) as Uint8Array<ArrayBuffer>;\n }\n\n this.outputFrequencyData ??= new Uint8Array(\n this.output.analyser.frequencyBinCount\n ) as Uint8Array<ArrayBuffer>;\n this.output.analyser.getByteFrequencyData(this.outputFrequencyData);\n return this.outputFrequencyData;\n }\n\n public getInputVolume() {\n return this.calculateVolume(this.getInputByteFrequencyData());\n }\n\n public getOutputVolume() {\n return this.calculateVolume(this.getOutputByteFrequencyData());\n }\n\n public async changeInputDevice({\n sampleRate,\n format,\n preferHeadphonesForIosDevices,\n inputDeviceId,\n }: FormatConfig & InputConfig): Promise<Input> {\n try {\n // For WebSocket connections, try to change device on existing input first\n if (this.connection instanceof WebSocketConnection) {\n if (inputDeviceId) {\n try {\n await this.input.setInputDevice(inputDeviceId);\n return this.input;\n } catch (error) {\n console.warn(\n \"Failed to change device on existing input, recreating:\",\n error\n );\n // Fall back to recreating the input\n }\n }\n }\n\n // Handle WebRTC connections differently\n if (this.connection instanceof WebRTCConnection) {\n if (inputDeviceId) {\n await this.connection.setAudioInputDevice(inputDeviceId);\n }\n }\n\n // Fallback: recreate the input\n await this.input.close();\n\n const newInput = await Input.create({\n sampleRate,\n format,\n preferHeadphonesForIosDevices,\n inputDeviceId,\n });\n\n this.input = newInput;\n\n return this.input;\n } catch (error) {\n console.error(\"Error changing input device\", error);\n throw error;\n }\n }\n\n public async changeOutputDevice({\n sampleRate,\n format,\n outputDeviceId,\n }: FormatConfig): Promise<Output> {\n try {\n // For WebSocket connections, try to change device on existing output first\n if (this.connection instanceof WebSocketConnection) {\n if (outputDeviceId) {\n try {\n await this.output.setOutputDevice(outputDeviceId);\n return this.output;\n } catch (error) {\n console.warn(\n \"Failed to change device on existing output, recreating:\",\n error\n );\n // Fall back to recreating the output\n }\n }\n }\n\n // Handle WebRTC connections differently\n if (this.connection instanceof WebRTCConnection) {\n if (outputDeviceId) {\n await this.connection.setAudioOutputDevice(outputDeviceId);\n }\n }\n\n // Fallback: recreate the output\n await this.output.close();\n\n const newOutput = await Output.create({\n sampleRate,\n format,\n outputDeviceId,\n });\n\n this.output = newOutput;\n\n return this.output;\n } catch (error) {\n console.error(\"Error changing output device\", error);\n throw error;\n }\n }\n\n public setVolume = ({ volume }: { volume: number }) => {\n // clamp & coerce\n const clampedVolume = Number.isFinite(volume)\n ? Math.min(1, Math.max(0, volume))\n : 1;\n this.volume = clampedVolume;\n\n if (this.connection instanceof WebRTCConnection) {\n // For WebRTC connections, control volume via HTML audio elements\n this.connection.setAudioVolume(clampedVolume);\n } else {\n // For WebSocket connections, control volume via gain node\n this.output.gain.gain.value = clampedVolume;\n }\n };\n}\n","import { BaseConversation, type PartialOptions } from \"./BaseConversation\";\nimport { TextConversation } from \"./TextConversation\";\nimport { VoiceConversation } from \"./VoiceConversation\";\n\nexport type {\n Mode,\n Role,\n Options,\n PartialOptions,\n ClientToolsConfig,\n Callbacks,\n Status,\n} from \"./BaseConversation\";\nexport type { InputConfig } from \"./utils/input\";\nexport { Input } from \"./utils/input\";\nexport { Output } from \"./utils/output\";\nexport type { IncomingSocketEvent, VadScoreEvent } from \"./utils/events\";\nexport type {\n SessionConfig,\n BaseSessionConfig,\n DisconnectionDetails,\n Language,\n ConnectionType,\n FormatConfig,\n} from \"./utils/BaseConnection\";\nexport { createConnection } from \"./utils/ConnectionFactory\";\nexport { WebSocketConnection } from \"./utils/WebSocketConnection\";\nexport { WebRTCConnection } from \"./utils/WebRTCConnection\";\nexport { postOverallFeedback } from \"./utils/postOverallFeedback\";\nexport { VoiceConversation } from \"./VoiceConversation\";\nexport { TextConversation } from \"./TextConversation\";\n\nexport class Conversation extends BaseConversation {\n public static startSession(options: PartialOptions): Promise<Conversation> {\n return options.textOnly\n ? TextConversation.startSession(options)\n : VoiceConversation.startSession(options);\n }\n}\n","const HTTPS_API_ORIGIN = \"https://api.elevenlabs.io\";\n\nexport function postOverallFeedback(\n conversationId: string,\n like: boolean,\n origin: string = HTTPS_API_ORIGIN\n) {\n return fetch(`${origin}/v1/convai/conversations/${conversationId}/feedback`, {\n method: \"POST\",\n body: JSON.stringify({\n feedback: like ? \"like\" : \"dislike\",\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n}\n"],"names":["EMPTY_FREQUENCY_DATA","Uint8Array","BaseConversation","options","connection","_this3","this","_this","_this2","lastInterruptTimestamp","mode","status","volume","currentEventId","lastFeedbackEventId","canSendFeedback","endSessionWithDetails","details","Promise","resolve","updateStatus","handleEndSession","then","onDisconnect","e","reject","onMessage","parsedEvent","type","handleInterruption","handleAgentResponse","handleUserTranscript","handleTentativeAgentResponse","_temp","_catch","handleClientToolCall","error","onError","Error","message","String","clientToolName","client_tool_call","tool_name","toolCallId","tool_call_id","handleAudio","handleVadScore","sendMessage","event_id","ping_event","onDebug","setVolume","_ref","onConnect","conversationId","onModeChange","updateMode","getFullOptions","partialOptions","_extends","clientTools","onAudio","onStatusChange","onCanSendFeedbackChange","_proto","prototype","endSession","reason","close","updateCanSendFeedback","event","interruption_event","source","agent_response_event","agent_response","user_transcription_event","user_transcript","response","tentative_agent_response_internal_event","tentative_agent_response","onVadScore","vadScore","vad_score_event","vad_score","_this5","Object","hasOwnProperty","call","_temp2","parameters","result","formattedResult","JSON","stringify","is_error","onUnhandledClientToolCall","context","console","getId","isOpen","setMicMuted","isMuted","getInputByteFrequencyData","getOutputByteFrequencyData","getInputVolume","getOutputVolume","sendFeedback","like","score","warn","sendContextualUpdate","text","sendUserMessage","sendUserActivity","sendMCPToolApprovalResult","isApproved","is_approved","BaseConnection","config","queue","disconnectionDetails","onDisconnectCallback","onMessageCallback","onModeChangeCallback","debug","info","callback","length","queueMicrotask","forEach","_this$onModeChangeCal","disconnect","_this$onDisconnectCal","handleMessage","push","parseFormat","format","_format$split","split","formatPart","sampleRatePart","includes","sampleRate","Number","parseInt","isNaN","PACKAGE_VERSION","isValidSocketEvent","CONVERSATION_INITIATION_CLIENT_DATA_TYPE","constructOverrides","_config$overrides","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","_config$overrides$con","overridesEvent","overrides","conversation_config_override","agent","prompt","first_message","firstMessage","language","tts","voice_id","voiceId","conversation","text_only","textOnly","customLlmExtraBody","custom_llm_extra_body","dynamicVariables","dynamic_variables","userId","user_id","client","source_info","version","WebSocketConnection","_BaseConnection","socket","inputFormat","outputFormat","addEventListener","setTimeout","code","parse","data","_inheritsLoose","create","_config$origin","_config$overrides2","url","origin","signedUrl","separator","agentId","protocols","authorization","WebSocket","_socket","send","once","conversation_initiation_metadata_event","conversationConfig","conversation_id","agent_output_audio_format","user_input_audio_format","_socket2","arrayBufferToBase64","b","buffer","window","btoa","fromCharCode","apply","base64ToArrayBuffer","base64","binaryString","atob","len","bytes","i","charCodeAt","URLCache","Map","createWorkletModuleLoader","name","sourceCode","worklet","_exit","_result","moduleURL","addModule","set","get","blob","Blob","blobURL","URL","createObjectURL","revokeObjectURL","loadRawAudioProcessor","WebRTCConnection","room","isConnected","audioEventId","audioCaptureContext","audioElements","outputDeviceId","outputAnalyser","outputFrequencyData","setupRoomEventListeners","conversationToken","_result3","Room","Date","now","connect","livekitUrl","onConnected","off","RoomEvent","Connected","on","_room$name$match","match","localParticipant","setMicrophoneEnabled","replace","convertWssToHttps","fetch","ok","statusText","json","token","msg","_this4","Disconnected","CloseEvent","toString","ConnectionStateChanged","state","ConnectionState","Event","DataReceived","payload","_participant","TextDecoder","decode","TrackSubscribed","track","_publication","participant","_temp6","kind","Track","Kind","Audio","identity","_temp5","audioElement","style","display","document","body","appendChild","setupAudioCapture","remoteAudioTrack","attach","autoplay","controls","_temp4","setSinkId","_temp3","ActiveSpeakersChanged","speakers","startsWith","audioTrackPublications","publication","stop","element","parentNode","removeChild","_this6","_temp7","TextEncoder","encode","publishData","reliable","getRoom","_this7","micTrackPublication","getTrackPublication","Source","Microphone","_temp8","mute","unmute","_this8","_temp9","audioContext","AudioContext","createAnalyser","fftSize","smoothingTimeConstant","mediaStream","MediaStream","mediaStreamTrack","createMediaStreamSource","audioWorklet","AudioWorkletNode","port","postMessage","onmessage","_event$data","base64Audio","maxVolume","eventId","audio_event","audio_base_64","setAudioVolume","setAudioOutputDevice","deviceId","_this9","HTMLAudioElement","promises","map","all","setAudioInputDevice","_this0","_temp1","createLocalAudioTrack","exact","echoCancellation","noiseSuppression","autoGainControl","channelCount","ideal","audioTrack","publishTrack","currentMicTrackPublication","_temp0","unpublishTrack","_temp11","_temp10","recoveryError","frequencyBinCount","getByteFrequencyData","createConnection","connectionType","determineConnectionType","isIosDevice","navigator","platform","userAgent","applyDelay","delayConfig","default","android","_delayConfig$android","delay","test","_delayConfig$ios","ios","TextConversation","_BaseConversation","arguments","startSession","fullOptions","connectionDelay","_createConnection","_connection","defaultConstraints","Input","analyser","inputStream","mediaStreamSource","preferHeadphonesForIosDevices","inputDeviceId","constraints","voiceIsolation","mediaDevices","getUserMedia","audio","_navigator$mediaDevic","resume","supportsSampleRateConstraint","getSupportedConstraints","enumerateDevices","availableDevices","idealDevice","find","d","keyword","label","toLowerCase","_inputStream","_context","getTracks","setMuted","setInputDevice","newInputStream","loadAudioConcatProcessor","Output","gain","createGain","src","load","destination","createMediaStreamDestination","srcObject","stream","_audioElement","_audioElement2","pause","setOutputDevice","VoiceConversation","input","output","wakeLock","inputFrequencyData","onInputWorkletMessage","user_audio_chunk","onOutputWorkletMessage","finished","addAudioBase64Chunk","chunk","value","fadeOutAudio","exponentialRampToValueAtTime","currentTime","calculateVolume","frequencyData","_ref2","clampedVolume","isFinite","Math","min","max","preliminaryInputStream","_Promise$all","_preliminaryInputStre","_preliminaryInputStre2","_input","_output","_wakeLock","release","_options$useWakeLock","useWakeLock","request","_navigator$wakeLock$r","_this2$wakeLock","_this$options$onAudio","_this$options","_this$outputFrequency","changeInputDevice","_ref3","newInput","changeOutputDevice","_ref4","_exit2","_temp15","_result6","_temp13","newOutput","_temp12","_temp14","_this4$output","Conversation","method","feedback","headers"],"mappings":"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"}
1
+ {"version":3,"file":"lib.umd.js","sources":["../src/BaseConversation.ts","../src/utils/BaseConnection.ts","../src/version.ts","../src/utils/events.ts","../src/utils/overrides.ts","../src/utils/WebSocketConnection.ts","../src/utils/audio.ts","../src/utils/createWorkletModuleLoader.ts","../src/utils/rawAudioProcessor.generated.ts","../src/utils/WebRTCConnection.ts","../src/utils/ConnectionFactory.ts","../src/utils/compatibility.ts","../src/utils/applyDelay.ts","../src/TextConversation.ts","../src/utils/input.ts","../src/utils/audioConcatProcessor.generated.ts","../src/utils/output.ts","../src/VoiceConversation.ts","../src/index.ts","../src/utils/postOverallFeedback.ts"],"sourcesContent":["import { Callbacks, Mode, Status } from \"@elevenlabs/types\";\nimport type {\n BaseConnection,\n DisconnectionDetails,\n SessionConfig,\n FormatConfig,\n} from \"./utils/BaseConnection\";\nimport type {\n AgentAudioEvent,\n AgentResponseEvent,\n ClientToolCallEvent,\n IncomingSocketEvent,\n InternalTentativeAgentResponseEvent,\n InterruptionEvent,\n UserTranscriptionEvent,\n VadScoreEvent,\n MCPToolCallClientEvent,\n AgentToolResponseEvent,\n ConversationMetadataEvent,\n AsrInitiationMetadataEvent,\n MCPConnectionStatusEvent,\n} from \"./utils/events\";\nimport type { InputConfig } from \"./utils/input\";\nimport type { OutputConfig } from \"./utils/output\";\n\nexport type { Role, Mode, Status, Callbacks } from \"@elevenlabs/types\";\n\n/** Allows self-hosting the worklets to avoid whitelisting blob: and data: in the CSP script-src */\nexport type AudioWorkletConfig = {\n workletPaths?: {\n rawAudioProcessor?: string;\n audioConcatProcessor?: string;\n };\n libsampleratePath?: string;\n};\n\nexport type Options = SessionConfig &\n Callbacks &\n ClientToolsConfig &\n InputConfig &\n OutputConfig &\n AudioWorkletConfig;\n\nexport type PartialOptions = SessionConfig &\n Partial<Callbacks> &\n Partial<ClientToolsConfig> &\n Partial<InputConfig> &\n Partial<OutputConfig> &\n Partial<FormatConfig> &\n Partial<AudioWorkletConfig>;\n\nexport type ClientToolsConfig = {\n clientTools: Record<\n string,\n (\n parameters: any\n ) => Promise<string | number | void> | string | number | void\n >;\n};\n\nconst EMPTY_FREQUENCY_DATA = new Uint8Array(0);\n\nexport class BaseConversation {\n protected lastInterruptTimestamp = 0;\n protected mode: Mode = \"listening\";\n protected status: Status = \"connecting\";\n protected volume = 1;\n protected currentEventId = 1;\n protected lastFeedbackEventId = 0;\n protected canSendFeedback = false;\n\n protected static getFullOptions(partialOptions: PartialOptions): Options {\n return {\n clientTools: {},\n onConnect: () => {},\n onDebug: () => {},\n onDisconnect: () => {},\n onError: () => {},\n onMessage: () => {},\n onAudio: () => {},\n onModeChange: () => {},\n onStatusChange: () => {},\n onCanSendFeedbackChange: () => {},\n onInterruption: () => {},\n ...partialOptions,\n };\n }\n\n protected constructor(\n protected readonly options: Options,\n protected readonly connection: BaseConnection\n ) {\n if (this.options.onConnect) {\n this.options.onConnect({ conversationId: connection.conversationId });\n }\n this.connection.onMessage(this.onMessage);\n this.connection.onDisconnect(this.endSessionWithDetails);\n this.connection.onModeChange(mode => this.updateMode(mode));\n this.updateStatus(\"connected\");\n }\n\n public endSession() {\n return this.endSessionWithDetails({ reason: \"user\" });\n }\n\n private endSessionWithDetails = async (details: DisconnectionDetails) => {\n if (this.status !== \"connected\" && this.status !== \"connecting\") return;\n this.updateStatus(\"disconnecting\");\n await this.handleEndSession();\n this.updateStatus(\"disconnected\");\n if (this.options.onDisconnect) {\n this.options.onDisconnect(details);\n }\n };\n\n protected async handleEndSession() {\n this.connection.close();\n }\n\n protected updateMode(mode: Mode) {\n if (mode !== this.mode) {\n this.mode = mode;\n if (this.options.onModeChange) {\n this.options.onModeChange({ mode });\n }\n }\n }\n\n protected updateStatus(status: Status) {\n if (status !== this.status) {\n this.status = status;\n if (this.options.onStatusChange) {\n this.options.onStatusChange({ status });\n }\n }\n }\n\n protected updateCanSendFeedback() {\n const canSendFeedback = this.currentEventId !== this.lastFeedbackEventId;\n if (this.canSendFeedback !== canSendFeedback) {\n this.canSendFeedback = canSendFeedback;\n if (this.options.onCanSendFeedbackChange) {\n this.options.onCanSendFeedbackChange({ canSendFeedback });\n }\n }\n }\n\n protected handleInterruption(event: InterruptionEvent) {\n if (event.interruption_event) {\n this.lastInterruptTimestamp = event.interruption_event.event_id;\n\n if (this.options.onInterruption) {\n this.options.onInterruption({\n event_id: event.interruption_event.event_id,\n });\n }\n }\n }\n\n protected handleAgentResponse(event: AgentResponseEvent) {\n if (this.options.onMessage) {\n this.options.onMessage({\n source: \"ai\",\n message: event.agent_response_event.agent_response,\n });\n }\n }\n\n protected handleUserTranscript(event: UserTranscriptionEvent) {\n if (this.options.onMessage) {\n this.options.onMessage({\n source: \"user\",\n message: event.user_transcription_event.user_transcript,\n });\n }\n }\n\n protected handleTentativeAgentResponse(\n event: InternalTentativeAgentResponseEvent\n ) {\n if (this.options.onDebug) {\n this.options.onDebug({\n type: \"tentative_agent_response\",\n response:\n event.tentative_agent_response_internal_event\n .tentative_agent_response,\n });\n }\n }\n\n protected handleVadScore(event: VadScoreEvent) {\n if (this.options.onVadScore) {\n this.options.onVadScore({\n vadScore: event.vad_score_event.vad_score,\n });\n }\n }\n\n protected async handleClientToolCall(event: ClientToolCallEvent) {\n if (\n Object.prototype.hasOwnProperty.call(\n this.options.clientTools,\n event.client_tool_call.tool_name\n )\n ) {\n try {\n const result =\n (await this.options.clientTools[event.client_tool_call.tool_name](\n event.client_tool_call.parameters\n )) ?? \"Client tool execution successful.\"; // default client-tool call response\n\n // The API expects result to be a string, so we need to convert it if it's not already a string\n const formattedResult =\n typeof result === \"object\" ? JSON.stringify(result) : String(result);\n\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: event.client_tool_call.tool_call_id,\n result: formattedResult,\n is_error: false,\n });\n } catch (e) {\n this.onError(\n `Client tool execution failed with following error: ${(e as Error)?.message}`,\n {\n clientToolName: event.client_tool_call.tool_name,\n }\n );\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: event.client_tool_call.tool_call_id,\n result: `Client tool execution failed: ${(e as Error)?.message}`,\n is_error: true,\n });\n }\n } else {\n if (this.options.onUnhandledClientToolCall) {\n this.options.onUnhandledClientToolCall(event.client_tool_call);\n\n return;\n }\n\n this.onError(\n `Client tool with name ${event.client_tool_call.tool_name} is not defined on client`,\n {\n clientToolName: event.client_tool_call.tool_name,\n }\n );\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: event.client_tool_call.tool_call_id,\n result: `Client tool with name ${event.client_tool_call.tool_name} is not defined on client`,\n is_error: true,\n });\n }\n }\n\n protected handleAudio(event: AgentAudioEvent) {}\n\n protected handleMCPToolCall(event: MCPToolCallClientEvent) {\n if (this.options.onMCPToolCall) {\n this.options.onMCPToolCall(event.mcp_tool_call);\n }\n }\n\n protected handleMCPConnectionStatus(event: MCPConnectionStatusEvent) {\n if (this.options.onMCPConnectionStatus) {\n this.options.onMCPConnectionStatus(event.mcp_connection_status);\n }\n }\n\n protected handleAgentToolResponse(event: AgentToolResponseEvent) {\n if (this.options.onAgentToolResponse) {\n this.options.onAgentToolResponse(event.agent_tool_response);\n }\n }\n\n protected handleConversationMetadata(event: ConversationMetadataEvent) {\n if (this.options.onConversationMetadata) {\n this.options.onConversationMetadata(\n event.conversation_initiation_metadata_event\n );\n }\n }\n\n protected handleAsrInitiationMetadata(event: AsrInitiationMetadataEvent) {\n if (this.options.onAsrInitiationMetadata) {\n this.options.onAsrInitiationMetadata(event.asr_initiation_metadata_event);\n }\n }\n\n private onMessage = async (parsedEvent: IncomingSocketEvent) => {\n switch (parsedEvent.type) {\n case \"interruption\": {\n this.handleInterruption(parsedEvent);\n return;\n }\n case \"agent_response\": {\n this.handleAgentResponse(parsedEvent);\n return;\n }\n case \"user_transcript\": {\n this.handleUserTranscript(parsedEvent);\n return;\n }\n case \"internal_tentative_agent_response\": {\n this.handleTentativeAgentResponse(parsedEvent);\n return;\n }\n case \"client_tool_call\": {\n try {\n await this.handleClientToolCall(parsedEvent);\n } catch (error) {\n this.onError(\n `Unexpected error in client tool call handling: ${error instanceof Error ? error.message : String(error)}`,\n {\n clientToolName: parsedEvent.client_tool_call.tool_name,\n toolCallId: parsedEvent.client_tool_call.tool_call_id,\n }\n );\n }\n return;\n }\n case \"audio\": {\n this.handleAudio(parsedEvent);\n return;\n }\n\n case \"vad_score\": {\n this.handleVadScore(parsedEvent);\n return;\n }\n\n case \"ping\": {\n this.connection.sendMessage({\n type: \"pong\",\n event_id: parsedEvent.ping_event.event_id,\n });\n // parsedEvent.ping_event.ping_ms can be used on client side, for example\n // to warn if ping is too high that experience might be degraded.\n return;\n }\n\n case \"mcp_tool_call\": {\n this.handleMCPToolCall(parsedEvent);\n return;\n }\n\n case \"mcp_connection_status\": {\n this.handleMCPConnectionStatus(parsedEvent);\n return;\n }\n\n case \"agent_tool_response\": {\n this.handleAgentToolResponse(parsedEvent);\n return;\n }\n\n case \"conversation_initiation_metadata\": {\n this.handleConversationMetadata(parsedEvent);\n return;\n }\n\n case \"asr_initiation_metadata\": {\n this.handleAsrInitiationMetadata(parsedEvent);\n return;\n }\n\n // unhandled events are expected to be internal events\n default: {\n if (this.options.onDebug) {\n this.options.onDebug(parsedEvent);\n }\n return;\n }\n }\n };\n\n private onError(message: string, context?: any) {\n console.error(message, context);\n if (this.options.onError) {\n this.options.onError(message, context);\n }\n }\n\n public getId() {\n return this.connection.conversationId;\n }\n\n public isOpen() {\n return this.status === \"connected\";\n }\n\n public setVolume = ({ volume }: { volume: number }) => {\n this.volume = volume;\n };\n\n public setMicMuted(isMuted: boolean) {\n this.connection.setMicMuted(isMuted);\n }\n\n public getInputByteFrequencyData(): Uint8Array {\n return EMPTY_FREQUENCY_DATA;\n }\n\n public getOutputByteFrequencyData(): Uint8Array {\n return EMPTY_FREQUENCY_DATA;\n }\n\n public getInputVolume() {\n return 0;\n }\n\n public getOutputVolume() {\n return 0;\n }\n\n public sendFeedback(like: boolean) {\n if (!this.canSendFeedback) {\n console.warn(\n this.lastFeedbackEventId === 0\n ? \"Cannot send feedback: the conversation has not started yet.\"\n : \"Cannot send feedback: feedback has already been sent for the current response.\"\n );\n return;\n }\n\n this.connection.sendMessage({\n type: \"feedback\",\n score: like ? \"like\" : \"dislike\",\n event_id: this.currentEventId,\n });\n this.lastFeedbackEventId = this.currentEventId;\n this.updateCanSendFeedback();\n }\n\n public sendContextualUpdate(text: string) {\n this.connection.sendMessage({\n type: \"contextual_update\",\n text,\n });\n }\n\n public sendUserMessage(text: string) {\n this.connection.sendMessage({\n type: \"user_message\",\n text,\n });\n }\n\n public sendUserActivity() {\n this.connection.sendMessage({\n type: \"user_activity\",\n });\n }\n\n public sendMCPToolApprovalResult(toolCallId: string, isApproved: boolean) {\n this.connection.sendMessage({\n type: \"mcp_tool_approval_result\",\n tool_call_id: toolCallId,\n is_approved: isApproved,\n });\n }\n}\n","import type { IncomingSocketEvent, OutgoingSocketEvent } from \"./events\";\nimport type { Mode } from \"../BaseConversation\";\nimport type { ConversationConfigOverrideAgentLanguage as Language } from \"@elevenlabs/types/generated/types/asyncapi-types\";\nimport type { DisconnectionDetails } from \"@elevenlabs/types\";\n\nexport type {\n DisconnectionDetails,\n ConversationConfigOverrideAgentLanguage as Language,\n} from \"@elevenlabs/types\";\n\nexport type DelayConfig = {\n default: number;\n android?: number;\n ios?: number;\n};\n\nexport type FormatConfig = {\n format: \"pcm\" | \"ulaw\";\n sampleRate: number;\n outputDeviceId?: string;\n};\n\nexport type OnDisconnectCallback = (details: DisconnectionDetails) => void;\nexport type OnMessageCallback = (event: IncomingSocketEvent) => void;\n\nexport type BaseSessionConfig = {\n origin?: string;\n authorization?: string;\n livekitUrl?: string;\n overrides?: {\n agent?: {\n prompt?: {\n prompt?: string;\n };\n firstMessage?: string;\n language?: Language;\n };\n tts?: {\n voiceId?: string;\n };\n conversation?: {\n textOnly?: boolean;\n };\n client?: {\n source?: string;\n version?: string;\n };\n };\n customLlmExtraBody?: unknown;\n dynamicVariables?: Record<string, string | number | boolean>;\n useWakeLock?: boolean;\n connectionDelay?: DelayConfig;\n textOnly?: boolean;\n userId?: string;\n};\n\nexport type ConnectionType = \"websocket\" | \"webrtc\";\n\nexport type PublicSessionConfig = BaseSessionConfig & {\n agentId: string;\n connectionType: ConnectionType;\n signedUrl?: never;\n conversationToken?: never;\n};\n\nexport type PrivateWebSocketSessionConfig = BaseSessionConfig & {\n signedUrl: string;\n connectionType?: \"websocket\";\n agentId?: never;\n conversationToken?: never;\n};\n\nexport type PrivateWebRTCSessionConfig = BaseSessionConfig & {\n conversationToken: string;\n connectionType?: \"webrtc\";\n agentId?: never;\n signedUrl?: never;\n};\n\n// Union type for all possible session configurations\nexport type SessionConfig =\n | PublicSessionConfig\n | PrivateWebSocketSessionConfig\n | PrivateWebRTCSessionConfig;\n\nexport abstract class BaseConnection {\n public abstract readonly conversationId: string;\n public abstract readonly inputFormat: FormatConfig;\n public abstract readonly outputFormat: FormatConfig;\n\n protected queue: IncomingSocketEvent[] = [];\n protected disconnectionDetails: DisconnectionDetails | null = null;\n protected onDisconnectCallback: OnDisconnectCallback | null = null;\n protected onMessageCallback: OnMessageCallback | null = null;\n protected onModeChangeCallback: ((mode: Mode) => void) | null = null;\n protected onDebug?: (info: unknown) => void;\n\n constructor(config: { onDebug?: (info: unknown) => void } = {}) {\n this.onDebug = config.onDebug;\n }\n\n protected debug(info: unknown) {\n if (this.onDebug) this.onDebug(info);\n }\n\n public abstract close(): void;\n public abstract sendMessage(message: OutgoingSocketEvent): void;\n public abstract setMicMuted(isMuted: boolean): Promise<void>;\n\n public onMessage(callback: OnMessageCallback) {\n this.onMessageCallback = callback;\n const queue = this.queue;\n this.queue = [];\n\n if (queue.length > 0) {\n // Make sure the queue is flushed after the constructors finishes and\n // classes are initialized.\n queueMicrotask(() => {\n queue.forEach(callback);\n });\n }\n }\n\n public onDisconnect(callback: OnDisconnectCallback) {\n this.onDisconnectCallback = callback;\n const details = this.disconnectionDetails;\n if (details) {\n // Make sure the event is triggered after the constructors finishes and\n // classes are initialized.\n queueMicrotask(() => {\n callback(details);\n });\n }\n }\n\n public onModeChange(callback: (mode: Mode) => void) {\n this.onModeChangeCallback = callback;\n }\n\n protected updateMode(mode: Mode) {\n this.onModeChangeCallback?.(mode);\n }\n\n protected disconnect(details: DisconnectionDetails) {\n if (!this.disconnectionDetails) {\n this.disconnectionDetails = details;\n this.onDisconnectCallback?.(details);\n }\n }\n\n protected handleMessage(parsedEvent: IncomingSocketEvent) {\n if (this.onMessageCallback) {\n this.onMessageCallback(parsedEvent);\n } else {\n this.queue.push(parsedEvent);\n }\n }\n}\n\nexport function parseFormat(format: string): FormatConfig {\n const [formatPart, sampleRatePart] = format.split(\"_\");\n if (![\"pcm\", \"ulaw\"].includes(formatPart)) {\n throw new Error(`Invalid format: ${format}`);\n }\n\n const sampleRate = Number.parseInt(sampleRatePart);\n if (Number.isNaN(sampleRate)) {\n throw new Error(`Invalid sample rate: ${sampleRatePart}`);\n }\n\n return {\n format: formatPart as FormatConfig[\"format\"],\n sampleRate,\n };\n}\n","// This file is auto-generated during build\nexport const PACKAGE_VERSION = \"0.7.0\";\n","import { Outgoing } from \"@elevenlabs/types\";\nimport {\n AgentResponse,\n AgentResponseCorrection,\n AgentToolResponseClientEvent,\n AsrInitiationMetadataEvent as AsrMetadataEvent,\n Audio,\n ClientToolCallMessage,\n ConversationMetadata,\n Interruption,\n McpConnectionStatusClientEvent,\n McpToolCall,\n Ping,\n InternalTentativeAgentResponse as TentativeAgentResponseInternal,\n UserTranscript,\n VadScore,\n} from \"@elevenlabs/types/generated/types/asyncapi-types\";\n\n// Compatibility layer - incoming events\nexport type UserTranscriptionEvent = UserTranscript;\nexport type AgentResponseEvent = AgentResponse;\nexport type AgentAudioEvent = Audio;\nexport type InterruptionEvent = Interruption;\nexport type InternalTentativeAgentResponseEvent =\n TentativeAgentResponseInternal;\nexport type ConfigEvent = ConversationMetadata;\nexport type PingEvent = Ping;\nexport type ClientToolCallEvent = ClientToolCallMessage;\nexport type VadScoreEvent = VadScore;\nexport type MCPToolCallClientEvent = McpToolCall;\nexport type AgentResponseCorrectionEvent = AgentResponseCorrection;\nexport type AgentToolResponseEvent = AgentToolResponseClientEvent;\nexport type ConversationMetadataEvent = ConversationMetadata;\nexport type AsrInitiationMetadataEvent = AsrMetadataEvent;\nexport type MCPConnectionStatusEvent = McpConnectionStatusClientEvent;\n\nexport type IncomingSocketEvent =\n | UserTranscriptionEvent\n | AgentResponseEvent\n | AgentResponseCorrectionEvent\n | AgentAudioEvent\n | InterruptionEvent\n | InternalTentativeAgentResponseEvent\n | ConfigEvent\n | PingEvent\n | ClientToolCallEvent\n | VadScoreEvent\n | MCPToolCallClientEvent\n | AgentToolResponseEvent\n | ConversationMetadataEvent\n | AsrInitiationMetadataEvent\n | MCPConnectionStatusEvent;\n\n// Compatibility layer - outgoing events\nexport type PongEvent = Outgoing.PongClientToOrchestratorEvent;\nexport type UserAudioEvent = Outgoing.UserAudio;\nexport type UserFeedbackEvent = Outgoing.UserFeedbackClientToOrchestratorEvent;\nexport type ClientToolResultEvent =\n Outgoing.ClientToolResultClientToOrchestratorEvent;\nexport type InitiationClientDataEvent =\n Outgoing.ConversationInitiationClientToOrchestratorEvent;\nexport type ContextualUpdateEvent =\n Outgoing.ContextualUpdateClientToOrchestratorEvent;\nexport type UserMessageEvent = Outgoing.UserMessageClientToOrchestratorEvent;\nexport type UserActivityEvent = Outgoing.UserActivityClientToOrchestratorEvent;\nexport type MCPToolApprovalResultEvent =\n Outgoing.McpToolApprovalResultClientToOrchestratorEvent;\n\nexport type OutgoingSocketEvent =\n | PongEvent\n | UserAudioEvent\n | InitiationClientDataEvent\n | UserFeedbackEvent\n | ClientToolResultEvent\n | ContextualUpdateEvent\n | UserMessageEvent\n | UserActivityEvent\n | MCPToolApprovalResultEvent;\n\nexport function isValidSocketEvent(event: any): event is IncomingSocketEvent {\n return !!event.type;\n}\n","import type { SessionConfig } from \"./BaseConnection\";\nimport type { InitiationClientDataEvent } from \"./events\";\n\nexport const CONVERSATION_INITIATION_CLIENT_DATA_TYPE =\n \"conversation_initiation_client_data\";\n\nexport function constructOverrides(\n config: SessionConfig\n): InitiationClientDataEvent {\n const overridesEvent: InitiationClientDataEvent = {\n type: CONVERSATION_INITIATION_CLIENT_DATA_TYPE,\n };\n\n if (config.overrides) {\n overridesEvent.conversation_config_override = {\n agent: {\n prompt: config.overrides.agent?.prompt,\n first_message: config.overrides.agent?.firstMessage,\n language: config.overrides.agent?.language,\n },\n tts: {\n voice_id: config.overrides.tts?.voiceId,\n },\n conversation: {\n text_only: config.overrides.conversation?.textOnly,\n },\n };\n }\n\n if (config.customLlmExtraBody) {\n overridesEvent.custom_llm_extra_body = config.customLlmExtraBody;\n }\n\n if (config.dynamicVariables) {\n overridesEvent.dynamic_variables = config.dynamicVariables;\n }\n\n if (config.userId) {\n overridesEvent.user_id = config.userId;\n }\n\n if (config.overrides?.client) {\n overridesEvent.source_info = {\n source: config.overrides.client.source,\n version: config.overrides.client.version,\n };\n }\n\n return overridesEvent;\n}\n","import {\n BaseConnection,\n type SessionConfig,\n type FormatConfig,\n parseFormat,\n} from \"./BaseConnection\";\nimport { PACKAGE_VERSION } from \"../version\";\nimport {\n type ConfigEvent,\n isValidSocketEvent,\n type OutgoingSocketEvent,\n} from \"./events\";\nimport { constructOverrides } from \"./overrides\";\n\nconst MAIN_PROTOCOL = \"convai\";\nconst WSS_API_ORIGIN = \"wss://api.elevenlabs.io\";\nconst WSS_API_PATHNAME = \"/v1/convai/conversation?agent_id=\";\n\nexport class WebSocketConnection extends BaseConnection {\n public readonly conversationId: string;\n public readonly inputFormat: FormatConfig;\n public readonly outputFormat: FormatConfig;\n\n private constructor(\n private readonly socket: WebSocket,\n conversationId: string,\n inputFormat: FormatConfig,\n outputFormat: FormatConfig\n ) {\n super();\n this.conversationId = conversationId;\n this.inputFormat = inputFormat;\n this.outputFormat = outputFormat;\n\n this.socket.addEventListener(\"error\", event => {\n // In case the error event is followed by a close event, we want the\n // latter to be the one that disconnects the session as it contains more\n // useful information.\n setTimeout(\n () =>\n this.disconnect({\n reason: \"error\",\n message: \"The connection was closed due to a socket error.\",\n context: event,\n }),\n 0\n );\n });\n\n this.socket.addEventListener(\"close\", event => {\n this.disconnect(\n event.code === 1000\n ? {\n reason: \"agent\",\n context: event,\n }\n : {\n reason: \"error\",\n message:\n event.reason || \"The connection was closed by the server.\",\n context: event,\n }\n );\n });\n\n this.socket.addEventListener(\"message\", event => {\n try {\n const parsedEvent = JSON.parse(event.data);\n if (!isValidSocketEvent(parsedEvent)) {\n this.debug({\n type: \"invalid_event\",\n message: \"Received invalid socket event\",\n data: event.data,\n });\n return;\n }\n this.handleMessage(parsedEvent);\n } catch (error) {\n this.debug({\n type: \"parsing_error\",\n message: \"Failed to parse socket message\",\n error: error instanceof Error ? error.message : String(error),\n data: event.data,\n });\n }\n });\n }\n\n public static async create(\n config: SessionConfig\n ): Promise<WebSocketConnection> {\n let socket: WebSocket | null = null;\n\n try {\n const origin = config.origin ?? WSS_API_ORIGIN;\n let url: string;\n\n const version = config.overrides?.client?.version || PACKAGE_VERSION;\n const source = config.overrides?.client?.source || \"js_sdk\";\n\n if (config.signedUrl) {\n const separator = config.signedUrl.includes(\"?\") ? \"&\" : \"?\";\n url = `${config.signedUrl}${separator}source=${source}&version=${version}`;\n } else {\n url = `${origin}${WSS_API_PATHNAME}${config.agentId}&source=${source}&version=${version}`;\n }\n\n const protocols = [MAIN_PROTOCOL];\n if (config.authorization) {\n protocols.push(`bearer.${config.authorization}`);\n }\n socket = new WebSocket(url, protocols);\n\n const conversationConfig = await new Promise<\n ConfigEvent[\"conversation_initiation_metadata_event\"]\n >((resolve, reject) => {\n socket!.addEventListener(\n \"open\",\n () => {\n const overridesEvent = constructOverrides(config);\n\n socket?.send(JSON.stringify(overridesEvent));\n },\n { once: true }\n );\n\n socket!.addEventListener(\"error\", event => {\n // In case the error event is followed by a close event, we want the\n // latter to be the one that rejects the promise as it contains more\n // useful information.\n setTimeout(() => reject(event), 0);\n });\n\n socket!.addEventListener(\"close\", reject);\n\n socket!.addEventListener(\n \"message\",\n (event: MessageEvent) => {\n const message = JSON.parse(event.data);\n\n if (!isValidSocketEvent(message)) {\n return;\n }\n\n if (message.type === \"conversation_initiation_metadata\") {\n resolve(message.conversation_initiation_metadata_event);\n } else {\n console.warn(\n \"First received message is not conversation metadata.\"\n );\n }\n },\n { once: true }\n );\n });\n\n const {\n conversation_id,\n agent_output_audio_format,\n user_input_audio_format,\n } = conversationConfig;\n\n const inputFormat = parseFormat(user_input_audio_format ?? \"pcm_16000\");\n const outputFormat = parseFormat(agent_output_audio_format);\n\n return new WebSocketConnection(\n socket,\n conversation_id,\n inputFormat,\n outputFormat\n );\n } catch (error) {\n socket?.close();\n throw error;\n }\n }\n\n public close() {\n this.socket.close();\n }\n\n public sendMessage(message: OutgoingSocketEvent) {\n this.socket.send(JSON.stringify(message));\n }\n\n public async setMicMuted(isMuted: boolean): Promise<void> {\n console.warn(\n `WebSocket connection setMicMuted called with ${isMuted}, but this is handled by VoiceConversation`\n );\n }\n}\n","export function arrayBufferToBase64(b: ArrayBufferLike) {\n const buffer = new Uint8Array(b);\n // @ts-ignore\n const base64Data = window.btoa(String.fromCharCode(...buffer));\n return base64Data;\n}\n\nexport function base64ToArrayBuffer(base64: string): ArrayBuffer {\n const binaryString = window.atob(base64);\n const len = binaryString.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n}\n","const URLCache = new Map<string, string>();\n\nexport function createWorkletModuleLoader(name: string, sourceCode: string) {\n return async (worklet: AudioWorklet, path?: string) => {\n const cachedUrl = URLCache.get(name);\n if (cachedUrl) {\n return worklet.addModule(cachedUrl);\n }\n\n // If a path is provided, use it directly (CSP-friendly approach)\n if (path) {\n try {\n await worklet.addModule(path);\n URLCache.set(name, path);\n return;\n } catch (error) {\n throw new Error(\n `Failed to load the ${name} worklet module from path: ${path}. Error: ${error}`\n );\n }\n }\n\n const blob = new Blob([sourceCode], { type: \"application/javascript\" });\n const blobURL = URL.createObjectURL(blob);\n try {\n await worklet.addModule(blobURL);\n URLCache.set(name, blobURL);\n return;\n } catch {\n URL.revokeObjectURL(blobURL);\n }\n\n try {\n // Attempting to start a conversation in Safari inside an iframe will\n // throw a CORS error because the blob:// protocol is considered\n // cross-origin. In such cases, fall back to using a base64 data URL:\n const base64 = btoa(sourceCode);\n const moduleURL = `data:application/javascript;base64,${base64}`;\n await worklet.addModule(moduleURL);\n URLCache.set(name, moduleURL);\n } catch (error) {\n throw new Error(\n `Failed to load the ${name} worklet module. Make sure the browser supports AudioWorklets. If you are using a strict CSP, you may need to self-host the worklet files.`\n );\n }\n };\n}\n","// AUTO-GENERATED BY packages/client/scripts/generateWorklets.js\nimport { createWorkletModuleLoader } from \"./createWorkletModuleLoader\";\n\nexport const loadRawAudioProcessor = createWorkletModuleLoader(\n \"rawAudioProcessor\",\n // language=JavaScript\n `/*\n * ulaw encoding logic taken from the wavefile library\n * https://github.com/rochars/wavefile/blob/master/lib/codecs/mulaw.js\n * USED BY @elevenlabs/client\n */\n\nconst BIAS = 0x84;\nconst CLIP = 32635;\nconst encodeTable = [\n 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,\n 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,\n 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,\n 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7\n];\n\nfunction encodeSample(sample) {\n let sign;\n let exponent;\n let mantissa;\n let muLawSample;\n sign = (sample >> 8) & 0x80;\n if (sign !== 0) sample = -sample;\n sample = sample + BIAS;\n if (sample > CLIP) sample = CLIP;\n exponent = encodeTable[(sample>>7) & 0xFF];\n mantissa = (sample >> (exponent+3)) & 0x0F;\n muLawSample = ~(sign | (exponent << 4) | mantissa);\n \n return muLawSample;\n}\n\nclass RawAudioProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n \n this.port.onmessage = ({ data }) => {\n switch (data.type) {\n case \"setFormat\":\n this.isMuted = false;\n this.buffer = []; // Initialize an empty buffer\n this.bufferSize = data.sampleRate / 4;\n this.format = data.format;\n\n if (globalThis.LibSampleRate && sampleRate !== data.sampleRate) {\n globalThis.LibSampleRate.create(1, sampleRate, data.sampleRate).then(resampler => {\n this.resampler = resampler;\n });\n }\n break;\n case \"setMuted\":\n this.isMuted = data.isMuted;\n break;\n }\n };\n }\n process(inputs) {\n if (!this.buffer) {\n return true;\n }\n \n const input = inputs[0]; // Get the first input node\n if (input.length > 0) {\n let channelData = input[0]; // Get the first channel's data\n\n // Resample the audio if necessary\n if (this.resampler) {\n channelData = this.resampler.full(channelData);\n }\n\n // Add channel data to the buffer\n this.buffer.push(...channelData);\n // Get max volume \n let sum = 0.0;\n for (let i = 0; i < channelData.length; i++) {\n sum += channelData[i] * channelData[i];\n }\n const maxVolume = Math.sqrt(sum / channelData.length);\n // Check if buffer size has reached or exceeded the threshold\n if (this.buffer.length >= this.bufferSize) {\n const float32Array = this.isMuted \n ? new Float32Array(this.buffer.length)\n : new Float32Array(this.buffer);\n\n let encodedArray = this.format === \"ulaw\"\n ? new Uint8Array(float32Array.length)\n : new Int16Array(float32Array.length);\n\n // Iterate through the Float32Array and convert each sample to PCM16\n for (let i = 0; i < float32Array.length; i++) {\n // Clamp the value to the range [-1, 1]\n let sample = Math.max(-1, Math.min(1, float32Array[i]));\n\n // Scale the sample to the range [-32768, 32767]\n let value = sample < 0 ? sample * 32768 : sample * 32767;\n if (this.format === \"ulaw\") {\n value = encodeSample(Math.round(value));\n }\n\n encodedArray[i] = value;\n }\n\n // Send the buffered data to the main script\n this.port.postMessage([encodedArray, maxVolume]);\n\n // Clear the buffer after sending\n this.buffer = [];\n }\n }\n return true; // Continue processing\n }\n}\nregisterProcessor(\"rawAudioProcessor\", RawAudioProcessor);\n`\n);\n","import {\n BaseConnection,\n type SessionConfig,\n type FormatConfig,\n parseFormat,\n} from \"./BaseConnection\";\nimport { PACKAGE_VERSION } from \"../version\";\nimport { isValidSocketEvent, type OutgoingSocketEvent } from \"./events\";\nimport {\n Room,\n RoomEvent,\n Track,\n ConnectionState,\n createLocalAudioTrack,\n} from \"livekit-client\";\nimport type {\n RemoteAudioTrack,\n Participant,\n TrackPublication,\n} from \"livekit-client\";\nimport {\n constructOverrides,\n CONVERSATION_INITIATION_CLIENT_DATA_TYPE,\n} from \"./overrides\";\nimport { arrayBufferToBase64 } from \"./audio\";\nimport { loadRawAudioProcessor } from \"./rawAudioProcessor.generated\";\n\nconst DEFAULT_LIVEKIT_WS_URL = \"wss://livekit.rtc.elevenlabs.io\";\nconst HTTPS_API_ORIGIN = \"https://api.elevenlabs.io\";\n\n// Convert WSS origin to HTTPS for API calls\nfunction convertWssToHttps(origin: string): string {\n return origin.replace(/^wss:\\/\\//, \"https://\");\n}\n\nexport type ConnectionConfig = SessionConfig & {\n onDebug?: (info: unknown) => void;\n};\n\nexport class WebRTCConnection extends BaseConnection {\n public conversationId: string;\n public readonly inputFormat: FormatConfig;\n public readonly outputFormat: FormatConfig;\n\n private room: Room;\n private isConnected = false;\n private audioEventId = 1;\n private audioCaptureContext: AudioContext | null = null;\n private audioElements: HTMLAudioElement[] = [];\n private outputDeviceId: string | null = null;\n\n private outputAnalyser: AnalyserNode | null = null;\n private outputFrequencyData: Uint8Array<ArrayBuffer> | null = null;\n\n private constructor(\n room: Room,\n conversationId: string,\n inputFormat: FormatConfig,\n outputFormat: FormatConfig,\n config: { onDebug?: (info: unknown) => void } = {}\n ) {\n super(config);\n this.room = room;\n this.conversationId = conversationId;\n this.inputFormat = inputFormat;\n this.outputFormat = outputFormat;\n\n this.setupRoomEventListeners();\n }\n\n public static async create(\n config: ConnectionConfig\n ): Promise<WebRTCConnection> {\n let conversationToken: string;\n\n // Handle different authentication scenarios\n if (\"conversationToken\" in config && config.conversationToken) {\n // Direct token provided\n conversationToken = config.conversationToken;\n } else if (\"agentId\" in config && config.agentId) {\n // Agent ID provided - fetch token from API\n try {\n const version = config.overrides?.client?.version || PACKAGE_VERSION;\n const source = config.overrides?.client?.source || \"js_sdk\";\n const configOrigin = config.origin ?? HTTPS_API_ORIGIN;\n const origin = convertWssToHttps(configOrigin); //origin is wss, not https\n const url = `${origin}/v1/convai/conversation/token?agent_id=${config.agentId}&source=${source}&version=${version}`;\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(\n `ElevenLabs API returned ${response.status} ${response.statusText}`\n );\n }\n\n const data = await response.json();\n conversationToken = data.token;\n\n if (!conversationToken) {\n throw new Error(\"No conversation token received from API\");\n }\n } catch (error) {\n let msg = error instanceof Error ? error.message : String(error);\n if (error instanceof Error && error.message.includes(\"401\")) {\n msg =\n \"Your agent has authentication enabled, but no signed URL or conversation token was provided.\";\n }\n\n throw new Error(\n `Failed to fetch conversation token for agent ${config.agentId}: ${msg}`\n );\n }\n } else {\n throw new Error(\n \"Either conversationToken or agentId is required for WebRTC connection\"\n );\n }\n\n const room = new Room();\n\n try {\n // Create connection instance first to set up event listeners\n const conversationId = `room_${Date.now()}`;\n const inputFormat = parseFormat(\"pcm_48000\");\n const outputFormat = parseFormat(\"pcm_48000\");\n const connection = new WebRTCConnection(\n room,\n conversationId,\n inputFormat,\n outputFormat,\n config\n );\n\n // Use configurable LiveKit URL or default if not provided\n const livekitUrl = config.livekitUrl || DEFAULT_LIVEKIT_WS_URL;\n\n // Connect to the LiveKit room and wait for the Connected event\n await room.connect(livekitUrl, conversationToken);\n\n // Wait for the Connected event to ensure isConnected is true\n await new Promise<void>(resolve => {\n if (connection.isConnected) {\n resolve();\n } else {\n const onConnected = () => {\n room.off(RoomEvent.Connected, onConnected);\n resolve();\n };\n room.on(RoomEvent.Connected, onConnected);\n }\n });\n\n if (room.name) {\n connection.conversationId =\n room.name.match(/(conv_[a-zA-Z0-9]+)/)?.[0] || room.name;\n }\n\n // Enable microphone and send overrides\n await room.localParticipant.setMicrophoneEnabled(true);\n\n const overridesEvent = constructOverrides(config);\n\n connection.debug({\n type: CONVERSATION_INITIATION_CLIENT_DATA_TYPE,\n message: overridesEvent,\n });\n\n await connection.sendMessage(overridesEvent);\n\n return connection;\n } catch (error) {\n await room.disconnect();\n throw error;\n }\n }\n\n private setupRoomEventListeners() {\n this.room.on(RoomEvent.Connected, async () => {\n this.isConnected = true;\n console.info(\"WebRTC room connected\");\n });\n\n this.room.on(RoomEvent.Disconnected, reason => {\n this.isConnected = false;\n this.disconnect({\n reason: \"agent\",\n context: new CloseEvent(\"close\", { reason: reason?.toString() }),\n });\n });\n\n this.room.on(RoomEvent.ConnectionStateChanged, state => {\n if (state === ConnectionState.Disconnected) {\n this.isConnected = false;\n this.disconnect({\n reason: \"error\",\n message: `LiveKit connection state changed to ${state}`,\n context: new Event(\"connection_state_changed\"),\n });\n }\n });\n\n // Handle incoming data messages\n this.room.on(\n RoomEvent.DataReceived,\n (payload: Uint8Array, _participant) => {\n try {\n const message = JSON.parse(new TextDecoder().decode(payload));\n\n // Filter out audio messages for WebRTC - they're handled via audio tracks\n if (message.type === \"audio\") {\n return;\n }\n\n if (isValidSocketEvent(message)) {\n this.handleMessage(message);\n } else {\n console.warn(\"Invalid socket event received:\", message);\n }\n } catch (error) {\n console.warn(\"Failed to parse incoming data message:\", error);\n console.warn(\"Raw payload:\", new TextDecoder().decode(payload));\n }\n }\n );\n\n this.room.on(\n RoomEvent.TrackSubscribed,\n async (\n track: Track,\n _publication: TrackPublication,\n participant: Participant\n ) => {\n if (\n track.kind === Track.Kind.Audio &&\n participant.identity.includes(\"agent\")\n ) {\n // Play the audio track\n const remoteAudioTrack = track as RemoteAudioTrack;\n const audioElement = remoteAudioTrack.attach();\n audioElement.autoplay = true;\n audioElement.controls = false;\n\n // Set output device if one was previously selected\n if (this.outputDeviceId && audioElement.setSinkId) {\n try {\n await audioElement.setSinkId(this.outputDeviceId);\n } catch (error) {\n console.warn(\n \"Failed to set output device for new audio element:\",\n error\n );\n }\n }\n\n // Add to DOM (hidden) to ensure it plays\n audioElement.style.display = \"none\";\n document.body.appendChild(audioElement);\n\n // Store reference for volume control\n this.audioElements.push(audioElement);\n\n // Apply current volume if it exists (for when volume was set before audio track arrived)\n if (this.audioElements.length === 1) {\n // First audio element - trigger a callback to sync with current volume\n this.onDebug?.({ type: \"audio_element_ready\" });\n }\n\n // Set up audio capture for onAudio callback\n await this.setupAudioCapture(remoteAudioTrack);\n }\n }\n );\n\n this.room.on(\n RoomEvent.ActiveSpeakersChanged,\n async (speakers: Participant[]) => {\n if (speakers.length > 0) {\n this.updateMode(\n speakers[0].identity.startsWith(\"agent\") ? \"speaking\" : \"listening\"\n );\n } else {\n this.updateMode(\"listening\");\n }\n }\n );\n }\n\n public close() {\n if (this.isConnected) {\n try {\n // Explicitly stop all local tracks before disconnecting to ensure microphone is released\n this.room.localParticipant.audioTrackPublications.forEach(\n publication => {\n if (publication.track) {\n publication.track.stop();\n }\n }\n );\n } catch (error) {\n console.warn(\"Error stopping local tracks:\", error);\n }\n\n // Clean up audio capture context (non-blocking)\n if (this.audioCaptureContext) {\n this.audioCaptureContext.close().catch(error => {\n console.warn(\"Error closing audio capture context:\", error);\n });\n this.audioCaptureContext = null;\n }\n\n // Clean up audio elements\n this.audioElements.forEach(element => {\n if (element.parentNode) {\n element.parentNode.removeChild(element);\n }\n });\n this.audioElements = [];\n\n this.room.disconnect();\n }\n }\n\n public async sendMessage(message: OutgoingSocketEvent) {\n if (!this.isConnected || !this.room.localParticipant) {\n console.warn(\n \"Cannot send message: room not connected or no local participant\"\n );\n return;\n }\n\n // In WebRTC mode, audio is sent via published tracks, not data messages\n if (\"user_audio_chunk\" in message) {\n // Ignore audio data messages - audio flows through WebRTC tracks\n return;\n }\n\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify(message));\n\n await this.room.localParticipant.publishData(data, { reliable: true });\n } catch (error) {\n this.debug({\n type: \"send_message_error\",\n message: {\n message,\n error,\n },\n });\n console.error(\"Failed to send message via WebRTC:\", error);\n }\n }\n\n // Get the room instance for advanced usage\n public getRoom(): Room {\n return this.room;\n }\n\n public async setMicMuted(isMuted: boolean): Promise<void> {\n if (!this.isConnected || !this.room.localParticipant) {\n console.warn(\n \"Cannot set microphone muted: room not connected or no local participant\"\n );\n return;\n }\n\n // Get the microphone track publication\n const micTrackPublication = this.room.localParticipant.getTrackPublication(\n Track.Source.Microphone\n );\n\n if (micTrackPublication?.track) {\n try {\n // Use LiveKit's built-in track muting\n if (isMuted) {\n await micTrackPublication.track.mute();\n } else {\n await micTrackPublication.track.unmute();\n }\n } catch (_error) {\n // If track muting fails, fall back to participant-level control\n await this.room.localParticipant.setMicrophoneEnabled(!isMuted);\n }\n } else {\n // No track found, use participant-level control directly\n await this.room.localParticipant.setMicrophoneEnabled(!isMuted);\n }\n }\n\n private async setupAudioCapture(track: RemoteAudioTrack) {\n try {\n // Create audio context for processing\n const audioContext = new AudioContext();\n this.audioCaptureContext = audioContext;\n\n // Create analyser for frequency data\n this.outputAnalyser = audioContext.createAnalyser();\n this.outputAnalyser.fftSize = 2048;\n this.outputAnalyser.smoothingTimeConstant = 0.8;\n\n // Create MediaStream from the track\n const mediaStream = new MediaStream([track.mediaStreamTrack]);\n\n // Create audio source from the stream\n const source = audioContext.createMediaStreamSource(mediaStream);\n\n // Connect source to analyser\n source.connect(this.outputAnalyser);\n\n await loadRawAudioProcessor(audioContext.audioWorklet);\n const worklet = new AudioWorkletNode(audioContext, \"rawAudioProcessor\");\n\n // Connect analyser to worklet for processing\n this.outputAnalyser.connect(worklet);\n\n // Configure the processor for the output format\n worklet.port.postMessage({\n type: \"setFormat\",\n format: this.outputFormat.format,\n sampleRate: this.outputFormat.sampleRate,\n });\n\n // Handle processed audio data\n worklet.port.onmessage = (event: MessageEvent) => {\n const [audioData, maxVolume] = event.data;\n\n // Only send audio if there's significant volume (not just silence)\n const volumeThreshold = 0.01;\n\n if (maxVolume > volumeThreshold) {\n // Convert to base64\n const base64Audio = arrayBufferToBase64(audioData.buffer);\n\n // Use sequential event ID for proper feedback tracking\n const eventId = this.audioEventId++;\n\n // Trigger the onAudio callback by simulating an audio event\n this.handleMessage({\n type: \"audio\",\n audio_event: {\n audio_base_64: base64Audio,\n event_id: eventId,\n },\n });\n }\n };\n\n // Connect the audio processing chain\n source.connect(worklet);\n } catch (error) {\n console.warn(\"Failed to set up audio capture:\", error);\n }\n }\n\n public setAudioVolume(volume: number) {\n this.audioElements.forEach(element => {\n element.volume = volume;\n });\n }\n\n public async setAudioOutputDevice(deviceId: string): Promise<void> {\n if (!(\"setSinkId\" in HTMLAudioElement.prototype)) {\n throw new Error(\"setSinkId is not supported in this browser\");\n }\n\n // Set output device for all existing audio elements\n const promises = this.audioElements.map(async element => {\n try {\n await element.setSinkId(deviceId);\n } catch (error) {\n console.error(\"Failed to set sink ID for audio element:\", error);\n throw error;\n }\n });\n\n await Promise.all(promises);\n\n // Store the device ID for future audio elements\n this.outputDeviceId = deviceId;\n }\n\n public async setAudioInputDevice(deviceId: string): Promise<void> {\n if (!this.isConnected || !this.room.localParticipant) {\n throw new Error(\n \"Cannot change input device: room not connected or no local participant\"\n );\n }\n\n try {\n // Get the current microphone track publication\n const currentMicTrackPublication =\n this.room.localParticipant.getTrackPublication(Track.Source.Microphone);\n\n // Stop the current microphone track if it exists\n if (currentMicTrackPublication?.track) {\n await currentMicTrackPublication.track.stop();\n await this.room.localParticipant.unpublishTrack(\n currentMicTrackPublication.track\n );\n }\n\n // Create constraints for the new input device\n const audioConstraints: MediaTrackConstraints = {\n deviceId: { exact: deviceId },\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n channelCount: { ideal: 1 },\n };\n\n // Create new audio track with the specified device\n const audioTrack = await createLocalAudioTrack(audioConstraints);\n\n // Publish the new microphone track\n await this.room.localParticipant.publishTrack(audioTrack, {\n name: \"microphone\",\n source: Track.Source.Microphone,\n });\n } catch (error) {\n console.error(\"Failed to change input device:\", error);\n\n // Try to re-enable default microphone on failure\n try {\n await this.room.localParticipant.setMicrophoneEnabled(true);\n } catch (recoveryError) {\n console.error(\n \"Failed to recover microphone after device switch error:\",\n recoveryError\n );\n }\n\n throw error;\n }\n }\n\n public getOutputByteFrequencyData(): Uint8Array<ArrayBuffer> | null {\n if (!this.outputAnalyser) return null;\n\n this.outputFrequencyData ??= new Uint8Array(\n this.outputAnalyser.frequencyBinCount\n ) as Uint8Array<ArrayBuffer>;\n this.outputAnalyser.getByteFrequencyData(this.outputFrequencyData);\n return this.outputFrequencyData;\n }\n}\n","import type {\n BaseConnection,\n SessionConfig,\n ConnectionType,\n} from \"./BaseConnection\";\nimport { WebSocketConnection } from \"./WebSocketConnection\";\nimport { WebRTCConnection } from \"./WebRTCConnection\";\n\nfunction determineConnectionType(config: SessionConfig): ConnectionType {\n // If connectionType is explicitly specified, use it\n if (config.connectionType) {\n return config.connectionType;\n }\n\n // If conversationToken is provided, use WebRTC\n if (\"conversationToken\" in config && config.conversationToken) {\n return \"webrtc\";\n }\n\n // Default to WebSocket for backward compatibility\n return \"websocket\";\n}\n\nexport async function createConnection(\n config: SessionConfig\n): Promise<BaseConnection> {\n const connectionType = determineConnectionType(config);\n\n switch (connectionType) {\n case \"websocket\":\n return WebSocketConnection.create(config);\n case \"webrtc\":\n return WebRTCConnection.create(config);\n default:\n throw new Error(`Unknown connection type: ${connectionType}`);\n }\n}\n","export function isIosDevice() {\n return (\n [\n \"iPad Simulator\",\n \"iPhone Simulator\",\n \"iPod Simulator\",\n \"iPad\",\n \"iPhone\",\n \"iPod\",\n ].includes(navigator.platform) ||\n // iPad on iOS 13 detection\n (navigator.userAgent.includes(\"Mac\") && \"ontouchend\" in document)\n );\n}\n\nexport function isAndroidDevice() {\n return /android/i.test(navigator.userAgent);\n}\n","import { isAndroidDevice, isIosDevice } from \"./compatibility\";\nimport type { DelayConfig } from \"./connection\";\n\nexport async function applyDelay(\n delayConfig: DelayConfig = {\n default: 0,\n // Give the Android AudioManager enough time to switch to the correct audio mode\n android: 3_000,\n }\n) {\n let delay = delayConfig.default;\n if (isAndroidDevice()) {\n delay = delayConfig.android ?? delay;\n } else if (isIosDevice()) {\n delay = delayConfig.ios ?? delay;\n }\n\n if (delay > 0) {\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n}\n","import { createConnection } from \"./utils/ConnectionFactory\";\nimport type { BaseConnection } from \"./utils/BaseConnection\";\nimport { applyDelay } from \"./utils/applyDelay\";\nimport { BaseConversation, type PartialOptions } from \"./BaseConversation\";\n\nexport class TextConversation extends BaseConversation {\n public static async startSession(\n options: PartialOptions\n ): Promise<TextConversation> {\n const fullOptions = BaseConversation.getFullOptions(options);\n\n if (fullOptions.onStatusChange) {\n fullOptions.onStatusChange({ status: \"connecting\" });\n }\n if (fullOptions.onCanSendFeedbackChange) {\n fullOptions.onCanSendFeedbackChange({ canSendFeedback: false });\n }\n if (fullOptions.onModeChange) {\n fullOptions.onModeChange({ mode: \"listening\" });\n }\n if (fullOptions.onCanSendFeedbackChange) {\n fullOptions.onCanSendFeedbackChange({ canSendFeedback: false });\n }\n\n let connection: BaseConnection | null = null;\n try {\n await applyDelay(fullOptions.connectionDelay);\n connection = await createConnection(options);\n return new TextConversation(fullOptions, connection);\n } catch (error) {\n if (fullOptions.onStatusChange) {\n fullOptions.onStatusChange({ status: \"disconnected\" });\n }\n connection?.close();\n throw error;\n }\n }\n}\n","import { loadRawAudioProcessor } from \"./rawAudioProcessor.generated\";\nimport type { FormatConfig } from \"./connection\";\nimport { isIosDevice } from \"./compatibility\";\nimport type { AudioWorkletConfig } from \"../BaseConversation\";\n\nexport type InputConfig = {\n preferHeadphonesForIosDevices?: boolean;\n inputDeviceId?: string;\n};\n\nconst LIBSAMPLERATE_JS =\n \"https://cdn.jsdelivr.net/npm/@alexanderolsen/libsamplerate-js@2.1.2/dist/libsamplerate.worklet.js\";\n\nconst defaultConstraints = {\n echoCancellation: true,\n noiseSuppression: true,\n // Automatic gain control helps maintain a steady volume level with microphones: https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings/autoGainControl\n autoGainControl: true,\n // Mono audio for better echo cancellation\n channelCount: { ideal: 1 },\n};\n\nexport class Input {\n public static async create({\n sampleRate,\n format,\n preferHeadphonesForIosDevices,\n inputDeviceId,\n workletPaths,\n libsampleratePath,\n }: FormatConfig & InputConfig & AudioWorkletConfig): Promise<Input> {\n let context: AudioContext | null = null;\n let inputStream: MediaStream | null = null;\n\n try {\n const options: MediaTrackConstraints = {\n sampleRate: { ideal: sampleRate },\n ...defaultConstraints,\n };\n\n if (isIosDevice() && preferHeadphonesForIosDevices) {\n const availableDevices =\n await window.navigator.mediaDevices.enumerateDevices();\n const idealDevice = availableDevices.find(\n d =>\n // cautious to include \"bluetooth\" in the search\n // as might trigger bluetooth speakers\n d.kind === \"audioinput\" &&\n [\"airpod\", \"headphone\", \"earphone\"].find(keyword =>\n d.label.toLowerCase().includes(keyword)\n )\n );\n if (idealDevice) {\n options.deviceId = { ideal: idealDevice.deviceId };\n }\n }\n\n if (inputDeviceId) {\n options.deviceId = { exact: inputDeviceId };\n }\n\n const supportsSampleRateConstraint =\n navigator.mediaDevices.getSupportedConstraints().sampleRate;\n\n context = new window.AudioContext(\n supportsSampleRateConstraint ? { sampleRate } : {}\n );\n const analyser = context.createAnalyser();\n if (!supportsSampleRateConstraint) {\n // Use custom libsamplerate path if provided, otherwise fallback to CDN\n const libsamplerateUrl = libsampleratePath || LIBSAMPLERATE_JS;\n await context.audioWorklet.addModule(libsamplerateUrl);\n }\n await loadRawAudioProcessor(\n context.audioWorklet,\n workletPaths?.[\"rawAudioProcessor\"]\n );\n\n const constraints = { voiceIsolation: true, ...options };\n inputStream = await navigator.mediaDevices.getUserMedia({\n audio: constraints,\n });\n\n const source = context.createMediaStreamSource(inputStream);\n const worklet = new AudioWorkletNode(context, \"rawAudioProcessor\");\n worklet.port.postMessage({ type: \"setFormat\", format, sampleRate });\n\n source.connect(analyser);\n analyser.connect(worklet);\n\n await context.resume();\n\n return new Input(context, analyser, worklet, inputStream, source);\n } catch (error) {\n inputStream?.getTracks().forEach(track => {\n track.stop();\n });\n context?.close();\n throw error;\n }\n }\n\n private constructor(\n public readonly context: AudioContext,\n public readonly analyser: AnalyserNode,\n public readonly worklet: AudioWorkletNode,\n public inputStream: MediaStream,\n private mediaStreamSource: MediaStreamAudioSourceNode\n ) {}\n\n public async close() {\n this.inputStream.getTracks().forEach(track => {\n track.stop();\n });\n this.mediaStreamSource.disconnect();\n await this.context.close();\n }\n\n public setMuted(isMuted: boolean) {\n this.worklet.port.postMessage({ type: \"setMuted\", isMuted });\n }\n\n public async setInputDevice(inputDeviceId: string): Promise<void> {\n if (!inputDeviceId) {\n throw new Error(\"Input device ID is required\");\n }\n\n try {\n // Create new constraints with the specified device\n const options: MediaTrackConstraints = {\n deviceId: { exact: inputDeviceId },\n ...defaultConstraints,\n };\n\n const constraints = { voiceIsolation: true, ...options };\n\n // Get new media stream with the specified device\n const newInputStream = await navigator.mediaDevices.getUserMedia({\n audio: constraints,\n });\n\n // Stop old tracks and disconnect old source\n this.inputStream.getTracks().forEach(track => {\n track.stop();\n });\n this.mediaStreamSource.disconnect();\n\n // Replace the stream and create new source\n this.inputStream = newInputStream;\n this.mediaStreamSource =\n this.context.createMediaStreamSource(newInputStream);\n\n // Reconnect the audio graph\n this.mediaStreamSource.connect(this.analyser);\n } catch (error) {\n console.error(\"Failed to switch input device:\", error);\n throw error;\n }\n }\n}\n","// AUTO-GENERATED BY packages/client/scripts/generateWorklets.js\nimport { createWorkletModuleLoader } from \"./createWorkletModuleLoader\";\n\nexport const loadAudioConcatProcessor = createWorkletModuleLoader(\n \"audioConcatProcessor\",\n // language=JavaScript\n `/*\n * ulaw decoding logic taken from the wavefile library\n * https://github.com/rochars/wavefile/blob/master/lib/codecs/mulaw.js\n * USED BY @elevenlabs/client\n */\n\nconst decodeTable = [0,132,396,924,1980,4092,8316,16764];\n\nfunction decodeSample(muLawSample) {\n let sign;\n let exponent;\n let mantissa;\n let sample;\n muLawSample = ~muLawSample;\n sign = (muLawSample & 0x80);\n exponent = (muLawSample >> 4) & 0x07;\n mantissa = muLawSample & 0x0F;\n sample = decodeTable[exponent] + (mantissa << (exponent+3));\n if (sign !== 0) sample = -sample;\n\n return sample;\n}\n\nclass AudioConcatProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.buffers = []; // Initialize an empty buffer\n this.cursor = 0;\n this.currentBuffer = null;\n this.wasInterrupted = false;\n this.finished = false;\n \n this.port.onmessage = ({ data }) => {\n switch (data.type) {\n case \"setFormat\":\n this.format = data.format;\n break;\n case \"buffer\":\n this.wasInterrupted = false;\n this.buffers.push(\n this.format === \"ulaw\"\n ? new Uint8Array(data.buffer)\n : new Int16Array(data.buffer)\n );\n break;\n case \"interrupt\":\n this.wasInterrupted = true;\n break;\n case \"clearInterrupted\":\n if (this.wasInterrupted) {\n this.wasInterrupted = false;\n this.buffers = [];\n this.currentBuffer = null;\n }\n }\n };\n }\n process(_, outputs) {\n let finished = false;\n const output = outputs[0][0];\n for (let i = 0; i < output.length; i++) {\n if (!this.currentBuffer) {\n if (this.buffers.length === 0) {\n finished = true;\n break;\n }\n this.currentBuffer = this.buffers.shift();\n this.cursor = 0;\n }\n\n let value = this.currentBuffer[this.cursor];\n if (this.format === \"ulaw\") {\n value = decodeSample(value);\n }\n output[i] = value / 32768;\n this.cursor++;\n\n if (this.cursor >= this.currentBuffer.length) {\n this.currentBuffer = null;\n }\n }\n\n if (this.finished !== finished) {\n this.finished = finished;\n this.port.postMessage({ type: \"process\", finished });\n }\n\n return true; // Continue processing\n }\n}\n\nregisterProcessor(\"audioConcatProcessor\", AudioConcatProcessor);\n`\n);\n","import { loadAudioConcatProcessor } from \"./audioConcatProcessor.generated\";\nimport type { FormatConfig } from \"./connection\";\nimport type { AudioWorkletConfig } from \"../BaseConversation\";\n\nexport type OutputConfig = {\n outputDeviceId?: string;\n};\n\nexport class Output {\n public static async create({\n sampleRate,\n format,\n outputDeviceId,\n workletPaths,\n }: FormatConfig & OutputConfig & AudioWorkletConfig): Promise<Output> {\n let context: AudioContext | null = null;\n let audioElement: HTMLAudioElement | null = null;\n try {\n context = new AudioContext({ sampleRate });\n const analyser = context.createAnalyser();\n const gain = context.createGain();\n\n // Always create an audio element for device switching capability\n audioElement = new Audio();\n audioElement.src = \"\";\n audioElement.load();\n audioElement.autoplay = true;\n audioElement.style.display = \"none\";\n\n document.body.appendChild(audioElement);\n\n // Create media stream destination to route audio to the element\n const destination = context.createMediaStreamDestination();\n audioElement.srcObject = destination.stream;\n\n gain.connect(analyser);\n analyser.connect(destination);\n\n await loadAudioConcatProcessor(\n context.audioWorklet,\n workletPaths?.[\"audioConcatProcessor\"]\n );\n const worklet = new AudioWorkletNode(context, \"audioConcatProcessor\");\n worklet.port.postMessage({ type: \"setFormat\", format });\n worklet.connect(gain);\n\n await context.resume();\n\n // Set initial output device if provided\n if (outputDeviceId && audioElement.setSinkId) {\n await audioElement.setSinkId(outputDeviceId);\n }\n\n const newOutput = new Output(\n context,\n analyser,\n gain,\n worklet,\n audioElement\n );\n\n return newOutput;\n } catch (error) {\n // Clean up audio element from DOM\n if (audioElement?.parentNode) {\n audioElement.parentNode.removeChild(audioElement);\n }\n audioElement?.pause();\n if (context && context.state !== \"closed\") {\n await context.close();\n }\n\n throw error;\n }\n }\n\n private constructor(\n public readonly context: AudioContext,\n public readonly analyser: AnalyserNode,\n public readonly gain: GainNode,\n public readonly worklet: AudioWorkletNode,\n public readonly audioElement: HTMLAudioElement\n ) {}\n\n public async setOutputDevice(deviceId: string): Promise<void> {\n if (!(\"setSinkId\" in HTMLAudioElement.prototype)) {\n throw new Error(\"setSinkId is not supported in this browser\");\n }\n\n await this.audioElement.setSinkId(deviceId);\n }\n\n public async close() {\n // Remove audio element from DOM\n if (this.audioElement.parentNode) {\n this.audioElement.parentNode.removeChild(this.audioElement);\n }\n this.audioElement.pause();\n await this.context.close();\n }\n}\n","import { arrayBufferToBase64, base64ToArrayBuffer } from \"./utils/audio\";\nimport { Input, type InputConfig } from \"./utils/input\";\nimport { Output } from \"./utils/output\";\nimport { createConnection } from \"./utils/ConnectionFactory\";\nimport type { BaseConnection, FormatConfig } from \"./utils/BaseConnection\";\nimport { WebRTCConnection } from \"./utils/WebRTCConnection\";\nimport type { AgentAudioEvent, InterruptionEvent } from \"./utils/events\";\nimport { applyDelay } from \"./utils/applyDelay\";\nimport {\n BaseConversation,\n type Options,\n type PartialOptions,\n} from \"./BaseConversation\";\nimport { WebSocketConnection } from \"./utils/WebSocketConnection\";\n\nexport class VoiceConversation extends BaseConversation {\n public static async startSession(\n options: PartialOptions\n ): Promise<VoiceConversation> {\n const fullOptions = BaseConversation.getFullOptions(options);\n\n if (fullOptions.onStatusChange) {\n fullOptions.onStatusChange({ status: \"connecting\" });\n }\n if (fullOptions.onCanSendFeedbackChange) {\n fullOptions.onCanSendFeedbackChange({ canSendFeedback: false });\n }\n\n let input: Input | null = null;\n let connection: BaseConnection | null = null;\n let output: Output | null = null;\n let preliminaryInputStream: MediaStream | null = null;\n\n let wakeLock: WakeLockSentinel | null = null;\n if (options.useWakeLock ?? true) {\n try {\n wakeLock = await navigator.wakeLock.request(\"screen\");\n } catch (_e) {\n // Wake Lock is not required for the conversation to work\n }\n }\n\n try {\n // some browsers won't allow calling getSupportedConstraints or enumerateDevices\n // before getting approval for microphone access\n preliminaryInputStream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n\n await applyDelay(fullOptions.connectionDelay);\n connection = await createConnection(options);\n [input, output] = await Promise.all([\n Input.create({\n ...connection.inputFormat,\n preferHeadphonesForIosDevices: options.preferHeadphonesForIosDevices,\n inputDeviceId: options.inputDeviceId,\n workletPaths: options.workletPaths,\n libsampleratePath: options.libsampleratePath,\n }),\n Output.create({\n ...connection.outputFormat,\n outputDeviceId: options.outputDeviceId,\n workletPaths: options.workletPaths,\n }),\n ]);\n\n preliminaryInputStream?.getTracks().forEach(track => {\n track.stop();\n });\n preliminaryInputStream = null;\n\n return new VoiceConversation(\n fullOptions,\n connection,\n input,\n output,\n wakeLock\n );\n } catch (error) {\n if (fullOptions.onStatusChange) {\n fullOptions.onStatusChange({ status: \"disconnected\" });\n }\n preliminaryInputStream?.getTracks().forEach(track => {\n track.stop();\n });\n connection?.close();\n await input?.close();\n await output?.close();\n try {\n await wakeLock?.release();\n wakeLock = null;\n } catch (_e) {}\n throw error;\n }\n }\n\n private inputFrequencyData?: Uint8Array<ArrayBuffer>;\n private outputFrequencyData?: Uint8Array<ArrayBuffer>;\n\n protected constructor(\n options: Options,\n connection: BaseConnection,\n public input: Input,\n public output: Output,\n public wakeLock: WakeLockSentinel | null\n ) {\n super(options, connection);\n this.input.worklet.port.onmessage = this.onInputWorkletMessage;\n this.output.worklet.port.onmessage = this.onOutputWorkletMessage;\n }\n\n protected override async handleEndSession() {\n await super.handleEndSession();\n try {\n await this.wakeLock?.release();\n this.wakeLock = null;\n } catch (_e) {}\n\n await this.input.close();\n await this.output.close();\n }\n\n protected override handleInterruption(event: InterruptionEvent) {\n super.handleInterruption(event);\n this.fadeOutAudio();\n }\n\n protected override handleAudio(event: AgentAudioEvent) {\n if (this.lastInterruptTimestamp <= event.audio_event.event_id) {\n this.options.onAudio?.(event.audio_event.audio_base_64);\n\n // Only play audio through the output worklet for WebSocket connections\n // WebRTC connections handle audio playback directly through LiveKit tracks\n if (!(this.connection instanceof WebRTCConnection)) {\n this.addAudioBase64Chunk(event.audio_event.audio_base_64);\n }\n\n this.currentEventId = event.audio_event.event_id;\n this.updateCanSendFeedback();\n this.updateMode(\"speaking\");\n }\n }\n\n private onInputWorkletMessage = (event: MessageEvent): void => {\n const rawAudioPcmData = event.data[0];\n\n // TODO: When supported, maxVolume can be used to avoid sending silent audio\n // const maxVolume = event.data[1];\n\n if (this.status === \"connected\") {\n this.connection.sendMessage({\n user_audio_chunk: arrayBufferToBase64(rawAudioPcmData.buffer),\n });\n }\n };\n\n private onOutputWorkletMessage = ({ data }: MessageEvent): void => {\n if (data.type === \"process\") {\n this.updateMode(data.finished ? \"listening\" : \"speaking\");\n }\n };\n\n private addAudioBase64Chunk = (chunk: string) => {\n this.output.gain.gain.value = this.volume;\n this.output.worklet.port.postMessage({ type: \"clearInterrupted\" });\n this.output.worklet.port.postMessage({\n type: \"buffer\",\n buffer: base64ToArrayBuffer(chunk),\n });\n };\n\n private fadeOutAudio = () => {\n // mute agent\n this.updateMode(\"listening\");\n this.output.worklet.port.postMessage({ type: \"interrupt\" });\n this.output.gain.gain.exponentialRampToValueAtTime(\n 0.0001,\n this.output.context.currentTime + 2\n );\n\n // reset volume back\n setTimeout(() => {\n this.output.gain.gain.value = this.volume;\n this.output.worklet.port.postMessage({ type: \"clearInterrupted\" });\n }, 2000); // Adjust the duration as needed\n };\n\n private calculateVolume = (frequencyData: Uint8Array) => {\n if (frequencyData.length === 0) {\n return 0;\n }\n\n // TODO: Currently this averages all frequencies, but we should probably\n // bias towards the frequencies that are more typical for human voice\n let volume = 0;\n for (let i = 0; i < frequencyData.length; i++) {\n volume += frequencyData[i] / 255;\n }\n volume /= frequencyData.length;\n\n return volume < 0 ? 0 : volume > 1 ? 1 : volume;\n };\n\n public setMicMuted(isMuted: boolean) {\n // Use LiveKit track muting for WebRTC connections\n if (this.connection instanceof WebRTCConnection) {\n this.connection.setMicMuted(isMuted);\n } else {\n // Use input muting for WebSocket connections\n this.input.setMuted(isMuted);\n }\n }\n\n public getInputByteFrequencyData(): Uint8Array<ArrayBuffer> {\n this.inputFrequencyData ??= new Uint8Array(\n this.input.analyser.frequencyBinCount\n ) as Uint8Array<ArrayBuffer>;\n this.input.analyser.getByteFrequencyData(this.inputFrequencyData);\n return this.inputFrequencyData;\n }\n\n public getOutputByteFrequencyData(): Uint8Array<ArrayBuffer> {\n // Use WebRTC analyser if available\n if (this.connection instanceof WebRTCConnection) {\n const webrtcData = this.connection.getOutputByteFrequencyData();\n if (webrtcData) {\n return webrtcData as Uint8Array<ArrayBuffer>;\n }\n // Fallback to empty array if WebRTC analyser not ready\n return new Uint8Array(1024) as Uint8Array<ArrayBuffer>;\n }\n\n this.outputFrequencyData ??= new Uint8Array(\n this.output.analyser.frequencyBinCount\n ) as Uint8Array<ArrayBuffer>;\n this.output.analyser.getByteFrequencyData(this.outputFrequencyData);\n return this.outputFrequencyData;\n }\n\n public getInputVolume() {\n return this.calculateVolume(this.getInputByteFrequencyData());\n }\n\n public getOutputVolume() {\n return this.calculateVolume(this.getOutputByteFrequencyData());\n }\n\n public async changeInputDevice({\n sampleRate,\n format,\n preferHeadphonesForIosDevices,\n inputDeviceId,\n }: FormatConfig & InputConfig): Promise<Input> {\n try {\n // For WebSocket connections, try to change device on existing input first\n if (this.connection instanceof WebSocketConnection) {\n if (inputDeviceId) {\n try {\n await this.input.setInputDevice(inputDeviceId);\n return this.input;\n } catch (error) {\n console.warn(\n \"Failed to change device on existing input, recreating:\",\n error\n );\n // Fall back to recreating the input\n }\n }\n }\n\n // Handle WebRTC connections differently\n if (this.connection instanceof WebRTCConnection) {\n if (inputDeviceId) {\n await this.connection.setAudioInputDevice(inputDeviceId);\n }\n }\n\n // Fallback: recreate the input\n await this.input.close();\n\n const newInput = await Input.create({\n sampleRate,\n format,\n preferHeadphonesForIosDevices,\n inputDeviceId,\n });\n\n this.input = newInput;\n\n return this.input;\n } catch (error) {\n console.error(\"Error changing input device\", error);\n throw error;\n }\n }\n\n public async changeOutputDevice({\n sampleRate,\n format,\n outputDeviceId,\n }: FormatConfig): Promise<Output> {\n try {\n // For WebSocket connections, try to change device on existing output first\n if (this.connection instanceof WebSocketConnection) {\n if (outputDeviceId) {\n try {\n await this.output.setOutputDevice(outputDeviceId);\n return this.output;\n } catch (error) {\n console.warn(\n \"Failed to change device on existing output, recreating:\",\n error\n );\n // Fall back to recreating the output\n }\n }\n }\n\n // Handle WebRTC connections differently\n if (this.connection instanceof WebRTCConnection) {\n if (outputDeviceId) {\n await this.connection.setAudioOutputDevice(outputDeviceId);\n }\n }\n\n // Fallback: recreate the output\n await this.output.close();\n\n const newOutput = await Output.create({\n sampleRate,\n format,\n outputDeviceId,\n });\n\n this.output = newOutput;\n\n return this.output;\n } catch (error) {\n console.error(\"Error changing output device\", error);\n throw error;\n }\n }\n\n public setVolume = ({ volume }: { volume: number }) => {\n // clamp & coerce\n const clampedVolume = Number.isFinite(volume)\n ? Math.min(1, Math.max(0, volume))\n : 1;\n this.volume = clampedVolume;\n\n if (this.connection instanceof WebRTCConnection) {\n // For WebRTC connections, control volume via HTML audio elements\n this.connection.setAudioVolume(clampedVolume);\n } else {\n // For WebSocket connections, control volume via gain node\n this.output.gain.gain.value = clampedVolume;\n }\n };\n}\n","import { BaseConversation, type PartialOptions } from \"./BaseConversation\";\nimport { TextConversation } from \"./TextConversation\";\nimport { VoiceConversation } from \"./VoiceConversation\";\n\nexport type {\n Mode,\n Role,\n Options,\n PartialOptions,\n ClientToolsConfig,\n Callbacks,\n Status,\n AudioWorkletConfig,\n} from \"./BaseConversation\";\nexport type { InputConfig } from \"./utils/input\";\nexport type { OutputConfig } from \"./utils/output\";\nexport { Input } from \"./utils/input\";\nexport { Output } from \"./utils/output\";\nexport type { IncomingSocketEvent, VadScoreEvent } from \"./utils/events\";\nexport type {\n SessionConfig,\n BaseSessionConfig,\n DisconnectionDetails,\n Language,\n ConnectionType,\n FormatConfig,\n} from \"./utils/BaseConnection\";\nexport { createConnection } from \"./utils/ConnectionFactory\";\nexport { WebSocketConnection } from \"./utils/WebSocketConnection\";\nexport { WebRTCConnection } from \"./utils/WebRTCConnection\";\nexport { postOverallFeedback } from \"./utils/postOverallFeedback\";\nexport { VoiceConversation } from \"./VoiceConversation\";\nexport { TextConversation } from \"./TextConversation\";\n\nexport class Conversation extends BaseConversation {\n public static startSession(options: PartialOptions): Promise<Conversation> {\n return options.textOnly\n ? TextConversation.startSession(options)\n : VoiceConversation.startSession(options);\n }\n}\n","const HTTPS_API_ORIGIN = \"https://api.elevenlabs.io\";\n\nexport function postOverallFeedback(\n conversationId: string,\n like: boolean,\n origin: string = HTTPS_API_ORIGIN\n) {\n return fetch(`${origin}/v1/convai/conversations/${conversationId}/feedback`, {\n method: \"POST\",\n body: JSON.stringify({\n feedback: like ? \"like\" : \"dislike\",\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n}\n"],"names":["EMPTY_FREQUENCY_DATA","Uint8Array","BaseConversation","options","connection","_this3","this","_this","_this2","lastInterruptTimestamp","mode","status","volume","currentEventId","lastFeedbackEventId","canSendFeedback","endSessionWithDetails","details","Promise","resolve","updateStatus","handleEndSession","then","onDisconnect","e","reject","onMessage","parsedEvent","type","handleInterruption","handleAgentResponse","handleUserTranscript","handleTentativeAgentResponse","_temp","_catch","handleClientToolCall","error","onError","Error","message","String","clientToolName","client_tool_call","tool_name","toolCallId","tool_call_id","handleAudio","handleVadScore","sendMessage","event_id","ping_event","handleMCPToolCall","handleMCPConnectionStatus","handleAgentToolResponse","handleConversationMetadata","handleAsrInitiationMetadata","onDebug","setVolume","_ref","onConnect","conversationId","onModeChange","updateMode","getFullOptions","partialOptions","_extends","clientTools","onAudio","onStatusChange","onCanSendFeedbackChange","onInterruption","_proto","prototype","endSession","reason","close","updateCanSendFeedback","event","interruption_event","source","agent_response_event","agent_response","user_transcription_event","user_transcript","response","tentative_agent_response_internal_event","tentative_agent_response","onVadScore","vadScore","vad_score_event","vad_score","_this5","Object","hasOwnProperty","call","_temp2","parameters","result","formattedResult","JSON","stringify","is_error","onUnhandledClientToolCall","onMCPToolCall","mcp_tool_call","onMCPConnectionStatus","mcp_connection_status","onAgentToolResponse","agent_tool_response","onConversationMetadata","conversation_initiation_metadata_event","onAsrInitiationMetadata","asr_initiation_metadata_event","context","console","getId","isOpen","setMicMuted","isMuted","getInputByteFrequencyData","getOutputByteFrequencyData","getInputVolume","getOutputVolume","sendFeedback","like","score","warn","sendContextualUpdate","text","sendUserMessage","sendUserActivity","sendMCPToolApprovalResult","isApproved","is_approved","BaseConnection","config","queue","disconnectionDetails","onDisconnectCallback","onMessageCallback","onModeChangeCallback","debug","info","callback","length","queueMicrotask","forEach","_this$onModeChangeCal","disconnect","_this$onDisconnectCal","handleMessage","push","parseFormat","format","_format$split","split","formatPart","sampleRatePart","includes","sampleRate","Number","parseInt","isNaN","PACKAGE_VERSION","isValidSocketEvent","CONVERSATION_INITIATION_CLIENT_DATA_TYPE","constructOverrides","_config$overrides","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","_config$overrides$con","overridesEvent","overrides","conversation_config_override","agent","prompt","first_message","firstMessage","language","tts","voice_id","voiceId","conversation","text_only","textOnly","customLlmExtraBody","custom_llm_extra_body","dynamicVariables","dynamic_variables","userId","user_id","client","source_info","version","WebSocketConnection","_BaseConnection","socket","inputFormat","outputFormat","addEventListener","setTimeout","code","parse","data","_inheritsLoose","create","_config$origin","_config$overrides2","url","origin","signedUrl","separator","agentId","protocols","authorization","WebSocket","_socket","send","once","conversationConfig","conversation_id","agent_output_audio_format","user_input_audio_format","_socket2","arrayBufferToBase64","b","buffer","window","btoa","fromCharCode","apply","base64ToArrayBuffer","base64","binaryString","atob","len","bytes","i","charCodeAt","URLCache","Map","createWorkletModuleLoader","name","sourceCode","worklet","path","_exit","_temp4","_result","_exit2","_result2","moduleURL","addModule","set","blob","Blob","blobURL","URL","createObjectURL","revokeObjectURL","cachedUrl","get","_temp3","loadRawAudioProcessor","WebRTCConnection","room","isConnected","audioEventId","audioCaptureContext","audioElements","outputDeviceId","outputAnalyser","outputFrequencyData","setupRoomEventListeners","conversationToken","_result3","Room","Date","now","connect","livekitUrl","onConnected","off","RoomEvent","Connected","on","_room$name$match","match","localParticipant","setMicrophoneEnabled","replace","convertWssToHttps","fetch","ok","statusText","json","token","msg","_this4","Disconnected","CloseEvent","toString","ConnectionStateChanged","state","ConnectionState","Event","DataReceived","payload","_participant","TextDecoder","decode","TrackSubscribed","track","_publication","participant","_temp6","kind","Track","Kind","Audio","identity","_temp5","audioElement","style","display","document","body","appendChild","setupAudioCapture","remoteAudioTrack","attach","autoplay","controls","setSinkId","ActiveSpeakersChanged","speakers","startsWith","audioTrackPublications","publication","stop","element","parentNode","removeChild","_this6","_temp7","TextEncoder","encode","publishData","reliable","getRoom","_this7","micTrackPublication","getTrackPublication","Source","Microphone","_temp8","mute","unmute","_this8","_temp9","audioContext","AudioContext","createAnalyser","fftSize","smoothingTimeConstant","mediaStream","MediaStream","mediaStreamTrack","createMediaStreamSource","audioWorklet","AudioWorkletNode","port","postMessage","onmessage","_event$data","base64Audio","maxVolume","eventId","audio_event","audio_base_64","setAudioVolume","setAudioOutputDevice","deviceId","_this9","HTMLAudioElement","promises","map","all","setAudioInputDevice","_this0","_temp1","createLocalAudioTrack","exact","echoCancellation","noiseSuppression","autoGainControl","channelCount","ideal","audioTrack","publishTrack","currentMicTrackPublication","_temp0","unpublishTrack","_temp11","_temp10","recoveryError","frequencyBinCount","getByteFrequencyData","createConnection","connectionType","determineConnectionType","isIosDevice","navigator","platform","userAgent","applyDelay","delayConfig","default","android","_delayConfig$android","delay","test","_delayConfig$ios","ios","TextConversation","_BaseConversation","arguments","startSession","fullOptions","connectionDelay","_createConnection","_connection","defaultConstraints","Input","analyser","inputStream","mediaStreamSource","preferHeadphonesForIosDevices","inputDeviceId","workletPaths","libsampleratePath","constraints","voiceIsolation","mediaDevices","getUserMedia","audio","_navigator$mediaDevic","resume","supportsSampleRateConstraint","getSupportedConstraints","enumerateDevices","availableDevices","idealDevice","find","d","keyword","label","toLowerCase","_inputStream","_context","getTracks","setMuted","setInputDevice","newInputStream","loadAudioConcatProcessor","Output","gain","createGain","src","load","destination","createMediaStreamDestination","srcObject","stream","_audioElement","_audioElement2","pause","setOutputDevice","VoiceConversation","input","output","wakeLock","inputFrequencyData","onInputWorkletMessage","user_audio_chunk","onOutputWorkletMessage","finished","addAudioBase64Chunk","chunk","value","fadeOutAudio","exponentialRampToValueAtTime","currentTime","calculateVolume","frequencyData","_ref2","clampedVolume","isFinite","Math","min","max","preliminaryInputStream","_Promise$all","_preliminaryInputStre","_preliminaryInputStre2","_input","_output","_wakeLock","release","_options$useWakeLock","useWakeLock","request","_navigator$wakeLock$r","_this2$wakeLock","_this$options$onAudio","_this$options","_this$outputFrequency","changeInputDevice","_ref3","newInput","changeOutputDevice","_ref4","_temp15","_result6","_temp13","newOutput","_temp12","_temp14","_this4$output","Conversation","method","feedback","headers"],"mappings":"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"}