@elevenlabs/client 0.8.1 → 0.9.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.
- package/.turbo/turbo-build.log +13 -12
- package/.turbo/turbo-generate-version.log +1 -1
- package/README.md +359 -0
- package/dist/index.d.ts +2 -0
- package/dist/lib.cjs +1 -1
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.modern.js +1 -1
- package/dist/lib.modern.js.map +1 -1
- package/dist/lib.module.js +1 -1
- package/dist/lib.module.js.map +1 -1
- package/dist/lib.umd.js +1 -1
- package/dist/lib.umd.js.map +1 -1
- package/dist/scribe/connection.d.ts +174 -0
- package/dist/scribe/index.d.ts +6 -0
- package/dist/scribe/scribe.d.ts +118 -0
- package/dist/utils/scribeAudioProcessor.generated.d.ts +1 -0
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/scripts/generateWorklets.js +9 -3
- package/worklets/scribeAudioProcessor.js +52 -0
package/dist/lib.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.module.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/utils/postOverallFeedback.ts","../src/index.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 AgentChatResponsePartEvent,\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 ErrorMessageEvent,\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 protected handleAgentChatResponsePart(event: AgentChatResponsePartEvent) {\n if (this.options.onAgentChatResponsePart) {\n this.options.onAgentChatResponsePart(event.text_response_part);\n }\n }\n\n protected handleErrorEvent(event: ErrorMessageEvent) {\n const errorType = event.error_event.error_type;\n const message =\n event.error_event.message || event.error_event.reason || \"Unknown error\";\n\n if (errorType === \"max_duration_exceeded\") {\n this.endSessionWithDetails({\n reason: \"error\",\n message: message,\n context: new Event(\"max_duration_exceeded\"),\n });\n return;\n }\n\n this.onError(`Server error: ${message}`, {\n errorType,\n code: event.error_event.code,\n debugMessage: event.error_event.debug_message,\n details: event.error_event.details,\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 case \"agent_chat_response_part\": {\n this.handleAgentChatResponsePart(parsedEvent);\n return;\n }\n\n case \"error\": {\n this.handleErrorEvent(parsedEvent);\n return;\n }\n\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.8.1\";\n","import { Outgoing } from \"@elevenlabs/types\";\nimport {\n AgentChatResponsePartClientEvent,\n AgentResponse,\n AgentResponseCorrection,\n AgentToolResponseClientEvent,\n AsrInitiationMetadataEvent as AsrMetadataEvent,\n Audio,\n ClientToolCallMessage,\n ConversationMetadata,\n ErrorMessage,\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;\nexport type AgentChatResponsePartEvent = AgentChatResponsePartClientEvent;\nexport type ErrorMessageEvent = ErrorMessage;\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 | AgentChatResponsePartEvent\n | ErrorMessageEvent;\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 try {\n // Create new constraints with the specified device or use default\n const options: MediaTrackConstraints = {\n ...defaultConstraints,\n };\n\n if (inputDeviceId) {\n options.deviceId = { exact: inputDeviceId };\n }\n // If inputDeviceId is undefined, don't set deviceId constraint - browser uses default\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 // If deviceId is undefined, use empty string which resets to default device\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 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 // Handle WebRTC connections differently\n if (this.connection instanceof WebRTCConnection) {\n await this.connection.setAudioInputDevice(inputDeviceId || \"\");\n }\n\n // Fallback: recreate the input\n await this.input.close();\n\n const newInput = await Input.create({\n sampleRate: sampleRate ?? this.connection.inputFormat.sampleRate,\n format: format ?? this.connection.inputFormat.format,\n preferHeadphonesForIosDevices,\n inputDeviceId,\n workletPaths: this.options.workletPaths,\n libsampleratePath: this.options.libsampleratePath,\n });\n\n this.input = newInput;\n this.input.worklet.port.onmessage = this.onInputWorkletMessage;\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 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 // Handle WebRTC connections differently\n if (this.connection instanceof WebRTCConnection) {\n await this.connection.setAudioOutputDevice(outputDeviceId || \"\");\n }\n\n // Fallback: recreate the output\n await this.output.close();\n\n const newOutput = await Output.create({\n sampleRate: sampleRate ?? this.connection.outputFormat.sampleRate,\n format: format ?? this.connection.outputFormat.format,\n outputDeviceId,\n workletPaths: this.options.workletPaths,\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","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","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"],"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","handleAgentChatResponsePart","handleErrorEvent","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","onAgentChatResponsePart","text_response_part","errorType","error_event","error_type","code","debugMessage","debug_message","context","Event","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","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","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","changeInputDevice","_ref3","newInput","_this3$input","changeOutputDevice","_ref4","_temp13","_result4","newOutput","_temp12","_this4$output","postOverallFeedback","method","feedback","headers","Conversation"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lib.module.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/utils/postOverallFeedback.ts","../src/scribe/connection.ts","../src/scribe/scribe.ts","../src/utils/scribeAudioProcessor.generated.ts","../src/index.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 AgentChatResponsePartEvent,\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 ErrorMessageEvent,\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 protected handleAgentChatResponsePart(event: AgentChatResponsePartEvent) {\n if (this.options.onAgentChatResponsePart) {\n this.options.onAgentChatResponsePart(event.text_response_part);\n }\n }\n\n protected handleErrorEvent(event: ErrorMessageEvent) {\n const errorType = event.error_event.error_type;\n const message =\n event.error_event.message || event.error_event.reason || \"Unknown error\";\n\n if (errorType === \"max_duration_exceeded\") {\n this.endSessionWithDetails({\n reason: \"error\",\n message: message,\n context: new Event(\"max_duration_exceeded\"),\n });\n return;\n }\n\n this.onError(`Server error: ${message}`, {\n errorType,\n code: event.error_event.code,\n debugMessage: event.error_event.debug_message,\n details: event.error_event.details,\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 case \"agent_chat_response_part\": {\n this.handleAgentChatResponsePart(parsedEvent);\n return;\n }\n\n case \"error\": {\n this.handleErrorEvent(parsedEvent);\n return;\n }\n\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.9.0\";\n","import { Outgoing } from \"@elevenlabs/types\";\nimport {\n AgentChatResponsePartClientEvent,\n AgentResponse,\n AgentResponseCorrection,\n AgentToolResponseClientEvent,\n AsrInitiationMetadataEvent as AsrMetadataEvent,\n Audio,\n ClientToolCallMessage,\n ConversationMetadata,\n ErrorMessage,\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;\nexport type AgentChatResponsePartEvent = AgentChatResponsePartClientEvent;\nexport type ErrorMessageEvent = ErrorMessage;\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 | AgentChatResponsePartEvent\n | ErrorMessageEvent;\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 try {\n // Create new constraints with the specified device or use default\n const options: MediaTrackConstraints = {\n ...defaultConstraints,\n };\n\n if (inputDeviceId) {\n options.deviceId = { exact: inputDeviceId };\n }\n // If inputDeviceId is undefined, don't set deviceId constraint - browser uses default\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 // If deviceId is undefined, use empty string which resets to default device\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 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 // Handle WebRTC connections differently\n if (this.connection instanceof WebRTCConnection) {\n await this.connection.setAudioInputDevice(inputDeviceId || \"\");\n }\n\n // Fallback: recreate the input\n await this.input.close();\n\n const newInput = await Input.create({\n sampleRate: sampleRate ?? this.connection.inputFormat.sampleRate,\n format: format ?? this.connection.inputFormat.format,\n preferHeadphonesForIosDevices,\n inputDeviceId,\n workletPaths: this.options.workletPaths,\n libsampleratePath: this.options.libsampleratePath,\n });\n\n this.input = newInput;\n this.input.worklet.port.onmessage = this.onInputWorkletMessage;\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 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 // Handle WebRTC connections differently\n if (this.connection instanceof WebRTCConnection) {\n await this.connection.setAudioOutputDevice(outputDeviceId || \"\");\n }\n\n // Fallback: recreate the output\n await this.output.close();\n\n const newOutput = await Output.create({\n sampleRate: sampleRate ?? this.connection.outputFormat.sampleRate,\n format: format ?? this.connection.outputFormat.format,\n outputDeviceId,\n workletPaths: this.options.workletPaths,\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","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","import type {\n InputAudioChunk,\n SessionStartedMessage,\n PartialTranscriptMessage,\n FinalTranscriptMessage,\n FinalTranscriptWithTimestampsMessage,\n ScribeErrorMessage,\n ScribeAuthErrorMessage,\n} from \"@elevenlabs/types\";\n\n// Re-export types for public API\nexport type {\n SessionStartedMessage,\n PartialTranscriptMessage,\n FinalTranscriptMessage,\n FinalTranscriptWithTimestampsMessage,\n ScribeErrorMessage,\n ScribeAuthErrorMessage,\n};\n\nexport type WebSocketMessage =\n | SessionStartedMessage\n | PartialTranscriptMessage\n | FinalTranscriptMessage\n | FinalTranscriptWithTimestampsMessage\n | ScribeErrorMessage\n | ScribeAuthErrorMessage;\n\n/**\n * Simple EventEmitter implementation for browser compatibility.\n */\nclass EventEmitter {\n private listeners: Map<string, Set<(...args: unknown[]) => void>> = new Map();\n\n on(event: string, listener: (...args: unknown[]) => void): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.add(listener);\n }\n }\n\n off(event: string, listener: (...args: unknown[]) => void): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.delete(listener);\n }\n }\n\n emit(event: string, ...args: unknown[]): void {\n const eventListeners = this.listeners.get(event);\n if (eventListeners) {\n eventListeners.forEach(listener => {\n listener(...args);\n });\n }\n }\n}\n\n/**\n * Events emitted by the RealtimeConnection.\n */\nexport enum RealtimeEvents {\n /** Emitted when the session is successfully started */\n SESSION_STARTED = \"session_started\",\n /** Emitted when a partial (interim) transcript is available */\n PARTIAL_TRANSCRIPT = \"partial_transcript\",\n /** Emitted when a final transcript is available */\n FINAL_TRANSCRIPT = \"final_transcript\",\n /** Emitted when a final transcript with timestamps is available */\n FINAL_TRANSCRIPT_WITH_TIMESTAMPS = \"final_transcript_with_timestamps\",\n /** Emitted when an authentication error occurs */\n AUTH_ERROR = \"auth_error\",\n /** Emitted when an error occurs */\n ERROR = \"error\",\n /** Emitted when the WebSocket connection is opened */\n OPEN = \"open\",\n /** Emitted when the WebSocket connection is closed */\n CLOSE = \"close\",\n}\n\n/**\n * Manages a real-time transcription WebSocket connection.\n *\n * @example\n * ```typescript\n * const connection = await Scribe.connect({\n * token: \"...\",\n * modelId: \"scribe_realtime_v2\",\n * audioFormat: AudioFormat.PCM_16000,\n * sampleRate: 16000,\n * });\n *\n * connection.on(RealtimeEvents.SESSION_STARTED, (data) => {\n * console.log(\"Session started\");\n * });\n *\n * connection.on(RealtimeEvents.PARTIAL_TRANSCRIPT, (data) => {\n * console.log(\"Partial:\", data.transcript);\n * });\n *\n * connection.on(RealtimeEvents.FINAL_TRANSCRIPT, (data) => {\n * console.log(\"Final:\", data.transcript);\n * connection.close();\n * });\n *\n * // Send audio data\n * connection.send({ audioBase64: base64String });\n *\n * // Commit and close\n * connection.commit();\n * ```\n */\nexport class RealtimeConnection {\n private websocket: WebSocket | null = null;\n private eventEmitter: EventEmitter = new EventEmitter();\n private currentSampleRate: number = 16000;\n public _audioCleanup?: () => void;\n\n constructor(sampleRate: number) {\n this.currentSampleRate = sampleRate;\n }\n\n /**\n * @internal\n * Used internally by ScribeRealtime to attach the WebSocket after connection is created.\n */\n public setWebSocket(websocket: WebSocket): void {\n this.websocket = websocket;\n\n // If WebSocket is already open, emit OPEN event immediately\n if (this.websocket.readyState === WebSocket.OPEN) {\n this.eventEmitter.emit(RealtimeEvents.OPEN);\n } else {\n // Otherwise, wait for the open event\n this.websocket.addEventListener(\"open\", () => {\n this.eventEmitter.emit(RealtimeEvents.OPEN);\n });\n }\n\n this.websocket.addEventListener(\"message\", (event: MessageEvent) => {\n try {\n const data = JSON.parse(event.data) as WebSocketMessage;\n\n switch (data.message_type) {\n case \"session_started\":\n this.eventEmitter.emit(RealtimeEvents.SESSION_STARTED, data);\n break;\n case \"partial_transcript\":\n this.eventEmitter.emit(RealtimeEvents.PARTIAL_TRANSCRIPT, data);\n break;\n case \"final_transcript\":\n this.eventEmitter.emit(RealtimeEvents.FINAL_TRANSCRIPT, data);\n break;\n case \"final_transcript_with_timestamps\":\n this.eventEmitter.emit(\n RealtimeEvents.FINAL_TRANSCRIPT_WITH_TIMESTAMPS,\n data\n );\n break;\n case \"auth_error\":\n this.eventEmitter.emit(RealtimeEvents.AUTH_ERROR, data);\n break;\n case \"error\":\n this.eventEmitter.emit(RealtimeEvents.ERROR, data);\n break;\n default:\n console.warn(\"Unknown message type:\", data);\n }\n } catch (error) {\n console.error(\"Failed to parse WebSocket message:\", error, event.data);\n this.eventEmitter.emit(\n RealtimeEvents.ERROR,\n new Error(`Failed to parse message: ${error}`)\n );\n }\n });\n\n this.websocket.addEventListener(\"error\", (error: Event) => {\n console.error(\"WebSocket error:\", error);\n this.eventEmitter.emit(RealtimeEvents.ERROR, error);\n });\n\n this.websocket.addEventListener(\"close\", (event: CloseEvent) => {\n console.log(\n `WebSocket closed: code=${event.code}, reason=\"${event.reason}\", wasClean=${event.wasClean}`\n );\n\n // Emit error if close was not clean or had an error code\n if (!event.wasClean || (event.code !== 1000 && event.code !== 1005)) {\n const errorMessage = `WebSocket closed unexpectedly: ${event.code} - ${event.reason || \"No reason provided\"}`;\n console.error(errorMessage);\n this.eventEmitter.emit(RealtimeEvents.ERROR, new Error(errorMessage));\n }\n\n this.eventEmitter.emit(RealtimeEvents.CLOSE, event);\n });\n }\n\n /**\n * Attaches an event listener for the specified event.\n *\n * @param event - The event to listen for (use RealtimeEvents enum)\n * @param listener - The callback function to execute when the event fires\n *\n * @example\n * ```typescript\n * connection.on(RealtimeEvents.SESSION_STARTED, (data) => {\n * console.log(\"Session started\", data);\n * });\n *\n * connection.on(RealtimeEvents.PARTIAL_TRANSCRIPT, (data) => {\n * console.log(\"Partial:\", data.transcript);\n * });\n *\n * connection.on(RealtimeEvents.FINAL_TRANSCRIPT, (data) => {\n * console.log(\"Final:\", data.transcript);\n * });\n * ```\n */\n public on(\n event: RealtimeEvents,\n listener: (...args: unknown[]) => void\n ): void {\n this.eventEmitter.on(event, listener);\n }\n\n /**\n * Removes an event listener for the specified event.\n *\n * @param event - The event to stop listening for\n * @param listener - The callback function to remove\n *\n * @example\n * ```typescript\n * const handler = (data) => console.log(data);\n * connection.on(RealtimeEvents.PARTIAL_TRANSCRIPT, handler);\n *\n * // Later, remove the listener\n * connection.off(RealtimeEvents.PARTIAL_TRANSCRIPT, handler);\n * ```\n */\n public off(\n event: RealtimeEvents,\n listener: (...args: unknown[]) => void\n ): void {\n this.eventEmitter.off(event, listener);\n }\n\n /**\n * Sends audio data to the transcription service.\n *\n * @param data - Audio data configuration\n * @param data.audioBase64 - Base64-encoded audio data\n * @param data.commit - Whether to commit the transcription after this chunk. You likely want to use connection.commit() instead (default: false)\n * @param data.sampleRate - Sample rate of the audio (default: configured sample rate)\n *\n * @throws {Error} If the WebSocket connection is not open\n *\n * @example\n * ```typescript\n * // Send audio chunk without committing\n * connection.send({\n * audioBase64: base64EncodedAudio,\n * });\n *\n * // Send audio chunk with custom sample rate\n * connection.send({\n * audioBase64: base64EncodedAudio,\n * sampleRate: 16000,\n * });\n * ```\n */\n public send(data: {\n audioBase64: string;\n commit?: boolean;\n sampleRate?: number;\n }): void {\n if (!this.websocket || this.websocket.readyState !== WebSocket.OPEN) {\n throw new Error(\"WebSocket is not connected\");\n }\n\n const message: InputAudioChunk = {\n message_type: \"input_audio_chunk\",\n audio_base_64: data.audioBase64,\n commit: data.commit ?? false,\n sample_rate: data.sampleRate ?? this.currentSampleRate,\n };\n\n this.websocket.send(JSON.stringify(message));\n }\n\n /**\n * Commits the transcription, signaling that all audio has been sent.\n * This finalizes the transcription and triggers a FINAL_TRANSCRIPT event.\n *\n * @throws {Error} If the WebSocket connection is not open\n *\n * @remarks\n * Only needed when using CommitStrategy.MANUAL.\n * When using CommitStrategy.VAD, commits are handled automatically by the server.\n *\n * @example\n * ```typescript\n * // Send all audio chunks\n * for (const chunk of audioChunks) {\n * connection.send({ audioBase64: chunk });\n * }\n *\n * // Finalize the transcription\n * connection.commit();\n * ```\n */\n public commit(): void {\n if (!this.websocket || this.websocket.readyState !== WebSocket.OPEN) {\n throw new Error(\"WebSocket is not connected\");\n }\n\n const message: InputAudioChunk = {\n message_type: \"input_audio_chunk\",\n audio_base_64: \"\",\n commit: true,\n sample_rate: this.currentSampleRate,\n };\n\n this.websocket.send(JSON.stringify(message));\n }\n\n /**\n * Closes the WebSocket connection and cleans up resources.\n * This will terminate any ongoing transcription and stop microphone streaming if active.\n *\n * @remarks\n * After calling close(), this connection cannot be reused.\n * Create a new connection if you need to start transcribing again.\n *\n * @example\n * ```typescript\n * connection.on(RealtimeEvents.FINAL_TRANSCRIPT, (data) => {\n * console.log(\"Final:\", data.transcript);\n * connection.close();\n * });\n * ```\n */\n public close(): void {\n // Cleanup audio resources (microphone stream, audio context)\n if (this._audioCleanup) {\n this._audioCleanup();\n }\n\n // Close WebSocket connection\n if (this.websocket) {\n this.websocket.close();\n }\n }\n}\n","import { RealtimeConnection } from \"./connection\";\nimport { loadScribeAudioProcessor } from \"../utils/scribeAudioProcessor.generated\";\n\nexport enum AudioFormat {\n PCM_8000 = \"pcm_8000\",\n PCM_16000 = \"pcm_16000\",\n PCM_22050 = \"pcm_22050\",\n PCM_24000 = \"pcm_24000\",\n PCM_44100 = \"pcm_44100\",\n PCM_48000 = \"pcm_48000\",\n ULAW_8000 = \"ulaw_8000\",\n}\n\nexport enum CommitStrategy {\n MANUAL = \"manual\",\n VAD = \"vad\",\n}\n\ninterface BaseOptions {\n /**\n * Token to use for the WebSocket connection. Obtained from the ElevenLabs API.\n */\n token: string;\n /**\n * Strategy for committing transcriptions.\n * @default CommitStrategy.MANUAL\n */\n commitStrategy?: CommitStrategy;\n /**\n * Silence threshold in seconds for VAD (Voice Activity Detection).\n * Must be a positive number between 0.3 and 3.0\n */\n vadSilenceThresholdSecs?: number;\n /**\n * Threshold for voice activity detection.\n * Must be between 0.1 and 0.9.\n */\n vadThreshold?: number;\n /**\n * Minimum speech duration in milliseconds.\n * Must be a positive integer between 50 and 2000.\n */\n minSpeechDurationMs?: number;\n /**\n * Minimum silence duration in milliseconds.\n * Must be a positive integer between 50 and 2000.\n */\n minSilenceDurationMs?: number;\n /**\n * Model ID to use for transcription.\n * Must be a valid model ID.\n */\n modelId: string;\n /**\n * An ISO-639-1 or ISO-639-3 language_code corresponding to the language of the audio file.\n * Can sometimes improve transcription performance if known beforehand.\n */\n languageCode?: string;\n /**\n * Base URI to use for the WebSocket connection.\n * If not provided, the default URI will be used.\n */\n baseUri?: string;\n}\n\nexport interface AudioOptions extends BaseOptions {\n audioFormat: AudioFormat;\n sampleRate: number;\n microphone?: never;\n}\n\n/**\n * Options for automatic microphone streaming in the browser.\n */\nexport interface MicrophoneOptions extends BaseOptions {\n microphone?: {\n deviceId?: string;\n echoCancellation?: boolean;\n noiseSuppression?: boolean;\n autoGainControl?: boolean;\n channelCount?: number;\n };\n audioFormat?: never;\n sampleRate?: never;\n}\n\n/**\n * Real-time speech-to-text transcription client for browser environments.\n * Supports microphone streaming and manual audio chunk transmission.\n */\n\n// biome-ignore lint/complexity/noStaticOnlyClass: This class is static only because it is a singleton\nexport class ScribeRealtime {\n private static readonly DEFAULT_BASE_URI = \"wss://api.elevenlabs.io\";\n\n private static getWebSocketUri(\n baseUri: string = ScribeRealtime.DEFAULT_BASE_URI\n ): string {\n return `${baseUri}/v1/speech-to-text/realtime-beta`;\n }\n\n private static buildWebSocketUri(\n options: AudioOptions | MicrophoneOptions\n ): string {\n const baseUri = ScribeRealtime.getWebSocketUri(options.baseUri);\n const params = new URLSearchParams();\n\n // Model ID is required, so no check required\n params.append(\"model_id\", options.modelId);\n\n params.append(\"token\", options.token);\n\n // Add optional parameters if provided, with validation\n if (options.commitStrategy !== undefined) {\n params.append(\"commit_strategy\", options.commitStrategy);\n }\n if (options.vadSilenceThresholdSecs !== undefined) {\n if (\n options.vadSilenceThresholdSecs <= 0.3 ||\n options.vadSilenceThresholdSecs > 3.0\n ) {\n throw new Error(\"vadSilenceThresholdSecs must be between 0.3 and 3.0\");\n }\n params.append(\n \"vad_silence_threshold_secs\",\n options.vadSilenceThresholdSecs.toString()\n );\n }\n if (options.vadThreshold !== undefined) {\n if (options.vadThreshold < 0.1 || options.vadThreshold > 0.9) {\n throw new Error(\"vadThreshold must be between 0.1 and 0.9\");\n }\n params.append(\"vad_threshold\", options.vadThreshold.toString());\n }\n if (options.minSpeechDurationMs !== undefined) {\n if (\n options.minSpeechDurationMs <= 50 ||\n options.minSpeechDurationMs > 2000\n ) {\n throw new Error(\"minSpeechDurationMs must be between 50 and 2000\");\n }\n params.append(\n \"min_speech_duration_ms\",\n options.minSpeechDurationMs.toString()\n );\n }\n if (options.minSilenceDurationMs !== undefined) {\n if (\n options.minSilenceDurationMs <= 50 ||\n options.minSilenceDurationMs > 2000\n ) {\n throw new Error(\"minSilenceDurationMs must be between 50 and 2000\");\n }\n params.append(\n \"min_silence_duration_ms\",\n options.minSilenceDurationMs.toString()\n );\n }\n\n if (options.languageCode !== undefined) {\n params.append(\"language_code\", options.languageCode);\n }\n\n const queryString = params.toString();\n return queryString ? `${baseUri}?${queryString}` : baseUri;\n }\n\n /**\n * Establishes a WebSocket connection for real-time speech-to-text transcription.\n *\n * @param options - Configuration options for the connection\n * @returns A RealtimeConnection instance\n *\n * @example\n * ```typescript\n * // Manual audio streaming\n * const connection = Scribe.connect({\n * token: \"...\",\n * modelId: \"scribe_realtime_v2\",\n * audioFormat: AudioFormat.PCM_16000,\n * sampleRate: 16000,\n * });\n *\n * // Automatic microphone streaming\n * const connection = Scribe.connect({\n * token: \"...\",\n * modelId: \"scribe_realtime_v2\",\n * microphone: {\n * echoCancellation: true,\n * noiseSuppression: true\n * }\n * });\n * ```\n */\n public static connect(\n options: AudioOptions | MicrophoneOptions\n ): RealtimeConnection {\n if (!options.modelId) {\n throw new Error(\"modelId is required\");\n }\n\n // Create connection object first so users can attach event listeners before messages arrive\n const sampleRate =\n \"microphone\" in options && options.microphone\n ? 16000\n : (options as AudioOptions).sampleRate;\n const connection = new RealtimeConnection(sampleRate);\n\n // Build WebSocket URI with query parameters\n const uri = ScribeRealtime.buildWebSocketUri(options);\n\n const websocket = new WebSocket(uri);\n\n // If microphone mode, set up streaming handler\n if (\"microphone\" in options && options.microphone) {\n websocket.addEventListener(\"open\", () => {\n ScribeRealtime.streamFromMicrophone(\n options as MicrophoneOptions,\n connection\n );\n });\n }\n\n connection.setWebSocket(websocket);\n\n return connection;\n }\n\n private static async streamFromMicrophone(\n options: MicrophoneOptions,\n connection: RealtimeConnection\n ): Promise<void> {\n try {\n // Get microphone access\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: {\n deviceId: options.microphone?.deviceId,\n echoCancellation: options.microphone?.echoCancellation ?? true,\n noiseSuppression: options.microphone?.noiseSuppression ?? true,\n autoGainControl: options.microphone?.autoGainControl ?? true,\n channelCount: options.microphone?.channelCount ?? 1,\n sampleRate: { ideal: 16000 },\n },\n });\n\n // Create audio context at 16kHz (Scribe's default)\n const audioContext = new AudioContext({ sampleRate: 16000 });\n\n // Load scribe worklet\n await loadScribeAudioProcessor(audioContext.audioWorklet);\n\n // Set up audio pipeline\n const source = audioContext.createMediaStreamSource(stream);\n const workletNode = new AudioWorkletNode(\n audioContext,\n \"scribeAudioProcessor\"\n );\n\n // Handle audio data from worklet\n workletNode.port.onmessage = event => {\n const { audioData } = event.data;\n // Convert ArrayBuffer to base64\n const bytes = new Uint8Array(audioData);\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n const base64Audio = btoa(binary);\n\n connection.send({ audioBase64: base64Audio });\n };\n\n // Connect audio pipeline\n source.connect(workletNode);\n\n // Resume audio context if needed\n if (audioContext.state === \"suspended\") {\n await audioContext.resume();\n }\n\n // Store cleanup function\n connection._audioCleanup = () => {\n stream.getTracks().forEach(track => {\n track.stop();\n });\n source.disconnect();\n workletNode.disconnect();\n audioContext.close();\n };\n } catch (error) {\n console.error(\"Failed to start microphone streaming:\", error);\n throw error;\n }\n }\n}\n","// AUTO-GENERATED BY packages/client/scripts/generateWorklets.js\nimport { createWorkletModuleLoader } from \"./createWorkletModuleLoader\";\n\nexport const loadScribeAudioProcessor = createWorkletModuleLoader(\n \"scribeAudioProcessor\",\n // language=JavaScript\n `/*\n * Scribe Audio Processor for converting microphone audio to PCM16 format\n * USED BY @elevenlabs/client\n */\n\nclass ScribeAudioProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n this.buffer = [];\n this.bufferSize = 4096; // Buffer size for optimal chunk transmission\n }\n\n process(inputs) {\n const input = inputs[0];\n if (input.length > 0) {\n const channelData = input[0]; // Get first channel (mono)\n\n // Add incoming audio to buffer\n this.buffer.push(...channelData);\n\n // When buffer reaches threshold, convert and send\n if (this.buffer.length >= this.bufferSize) {\n const float32Array = new Float32Array(this.buffer);\n const int16Array = new Int16Array(float32Array.length);\n\n // Convert Float32 [-1, 1] to Int16 [-32768, 32767]\n for (let i = 0; i < float32Array.length; i++) {\n // Clamp the value to prevent overflow\n const sample = Math.max(-1, Math.min(1, float32Array[i]));\n // Scale to PCM16 range\n int16Array[i] = sample < 0 ? sample * 32768 : sample * 32767;\n }\n\n // Send to main thread as transferable ArrayBuffer\n this.port.postMessage(\n {\n audioData: int16Array.buffer\n },\n [int16Array.buffer]\n );\n\n // Clear buffer\n this.buffer = [];\n }\n }\n\n return true; // Continue processing\n }\n}\n\nregisterProcessor(\"scribeAudioProcessor\", ScribeAudioProcessor);\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\n// Scribe exports\nexport {\n Scribe,\n AudioFormat,\n CommitStrategy,\n RealtimeEvents,\n RealtimeConnection,\n} from \"./scribe\";\nexport type {\n AudioOptions,\n MicrophoneOptions,\n WebSocketMessage,\n PartialTranscriptMessage,\n FinalTranscriptMessage,\n FinalTranscriptWithTimestampsMessage,\n ScribeErrorMessage,\n ScribeAuthErrorMessage,\n} from \"./scribe\";\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"],"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","handleAgentChatResponsePart","handleErrorEvent","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","onAgentChatResponsePart","text_response_part","errorType","error_event","error_type","code","debugMessage","debug_message","context","Event","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","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","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","changeInputDevice","_ref3","newInput","_this3$input","changeOutputDevice","_ref4","_temp13","_result4","newOutput","_temp12","_this4$output","postOverallFeedback","method","feedback","headers","RealtimeEvents","EventEmitter","listeners","listener","has","Set","eventListeners","add","emit","_arguments","slice","AudioFormat","CommitStrategy","RealtimeConnection","websocket","eventEmitter","currentSampleRate","_audioCleanup","_proto2","setWebSocket","readyState","OPEN","message_type","SESSION_STARTED","PARTIAL_TRANSCRIPT","FINAL_TRANSCRIPT","FINAL_TRANSCRIPT_WITH_TIMESTAMPS","AUTH_ERROR","ERROR","log","wasClean","errorMessage","CLOSE","_data$commit","_data$sampleRate","audioBase64","commit","sample_rate","loadScribeAudioProcessor","ScribeRealtime","getWebSocketUri","baseUri","DEFAULT_BASE_URI","buildWebSocketUri","params","URLSearchParams","append","modelId","undefined","commitStrategy","vadSilenceThresholdSecs","vadThreshold","minSpeechDurationMs","minSilenceDurationMs","languageCode","queryString","microphone","uri","streamFromMicrophone","_options$microphone","_options$microphone$e","_options$microphone2","_options$microphone$n","_options$microphone3","_options$microphone$a","_options$microphone4","_options$microphone$c","_options$microphone5","workletNode","audioData","binary","Conversation"],"mappings":"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"}
|