@11labs/client 0.0.7-beta.1 → 0.0.8-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"lib.umd.js","sources":["../src/utils/audio.ts","../src/utils/rawAudioProcessor.ts","../src/utils/compatibility.ts","../src/utils/input.ts","../src/utils/audioConcatProcessor.ts","../src/utils/output.ts","../src/utils/events.ts","../src/utils/connection.ts","../src/index.ts"],"sourcesContent":["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","/*\n * ulaw encoding logic taken from the wavefile library\n * https://github.com/rochars/wavefile/blob/master/lib/codecs/mulaw.js\n */\n\nconst blob = new Blob(\n [\n // language=JavaScript\n `\n const BIAS = 0x84;\n const CLIP = 32635;\n const 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 \n function 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 \n class RawAudioProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n \n this.port.onmessage = ({ data }) => {\n this.buffer = []; // Initialize an empty buffer\n this.bufferSize = data.sampleRate / 4;\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 };\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 = new Float32Array(this.buffer)\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 }\n registerProcessor(\"raw-audio-processor\", RawAudioProcessor);\n `,\n ],\n { type: \"application/javascript\" }\n);\n\nexport const rawAudioProcessor = URL.createObjectURL(blob);\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 { rawAudioProcessor } from \"./rawAudioProcessor\";\nimport { FormatConfig } from \"./connection\";\nimport { isIosDevice } from \"./compatibility\";\n\nexport type InputConfig = {\n preferHeadphonesForIosDevices?: boolean;\n};\n\nconst LIBSAMPLERATE_JS =\n \"https://cdn.jsdelivr.net/npm/@alexanderolsen/libsamplerate-js@2.1.2/dist/libsamplerate.worklet.js\";\n\nexport class Input {\n public static async create({\n sampleRate,\n format,\n preferHeadphonesForIosDevices,\n }: FormatConfig & InputConfig): Promise<Input> {\n let context: AudioContext | null = null;\n let inputStream: MediaStream | null = null;\n\n try {\n const options: MediaTrackConstraints = {\n sampleRate: { ideal: sampleRate },\n echoCancellation: { ideal: true },\n noiseSuppression: { ideal: true },\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 const supportsSampleRateConstraint =\n navigator.mediaDevices.getSupportedConstraints().sampleRate;\n\n context = new window.AudioContext(\n supportsSampleRateConstraint ? { sampleRate } : {}\n );\n const analyser = context.createAnalyser();\n if (!supportsSampleRateConstraint) {\n await context.audioWorklet.addModule(LIBSAMPLERATE_JS);\n }\n await context.audioWorklet.addModule(rawAudioProcessor);\n\n inputStream = await navigator.mediaDevices.getUserMedia({\n audio: options,\n });\n\n const source = context.createMediaStreamSource(inputStream);\n const worklet = new AudioWorkletNode(context, \"raw-audio-processor\");\n worklet.port.postMessage({ type: \"setFormat\", format, sampleRate });\n\n source.connect(analyser);\n analyser.connect(worklet);\n\n await context.resume();\n\n return new Input(context, analyser, worklet, inputStream);\n } catch (error) {\n inputStream?.getTracks().forEach(track => track.stop());\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 readonly inputStream: MediaStream\n ) {}\n\n public async close() {\n this.inputStream.getTracks().forEach(track => track.stop());\n await this.context.close();\n }\n}\n","/*\n * ulaw decoding logic taken from the wavefile library\n * https://github.com/rochars/wavefile/blob/master/lib/codecs/mulaw.js\n */\n\nconst blob = new Blob(\n [\n // language=JavaScript\n `\n const decodeTable = [0,132,396,924,1980,4092,8316,16764];\n \n export function decodeSample(muLawSample) {\n let sign;\n let exponent;\n let mantissa;\n let sample;\n muLawSample = ~muLawSample;\n sign = (muLawSample & 0x80);\n exponent = (muLawSample >> 4) & 0x07;\n mantissa = muLawSample & 0x0F;\n sample = decodeTable[exponent] + (mantissa << (exponent+3));\n if (sign !== 0) sample = -sample;\n\n return sample;\n }\n \n class 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\n registerProcessor(\"audio-concat-processor\", AudioConcatProcessor);\n `,\n ],\n { type: \"application/javascript\" }\n);\n\nexport const audioConcatProcessor = URL.createObjectURL(blob);\n","import { audioConcatProcessor } from \"./audioConcatProcessor\";\nimport { FormatConfig } from \"./connection\";\n\nexport class Output {\n public static async create({\n sampleRate,\n format,\n }: FormatConfig): Promise<Output> {\n let context: AudioContext | null = null;\n try {\n context = new AudioContext({ sampleRate });\n const analyser = context.createAnalyser();\n const gain = context.createGain();\n gain.connect(analyser);\n analyser.connect(context.destination);\n await context.audioWorklet.addModule(audioConcatProcessor);\n const worklet = new AudioWorkletNode(context, \"audio-concat-processor\");\n worklet.port.postMessage({ type: \"setFormat\", format });\n worklet.connect(gain);\n\n await context.resume();\n\n return new Output(context, analyser, gain, worklet);\n } catch (error) {\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 gain: GainNode,\n public readonly worklet: AudioWorkletNode\n ) {}\n\n public async close() {\n await this.context.close();\n }\n}\n","import { Language } from \"./connection\";\n\nexport type UserTranscriptionEvent = {\n type: \"user_transcript\";\n user_transcription_event: { user_transcript: string };\n};\nexport type AgentResponseEvent = {\n type: \"agent_response\";\n agent_response_event: { agent_response: string };\n};\nexport type AgentAudioEvent = {\n type: \"audio\";\n audio_event: {\n audio_base_64: string;\n event_id: number;\n };\n};\nexport type InterruptionEvent = {\n type: \"interruption\";\n interruption_event: {\n event_id: number;\n };\n};\nexport type InternalTentativeAgentResponseEvent = {\n type: \"internal_tentative_agent_response\";\n tentative_agent_response_internal_event: {\n tentative_agent_response: string;\n };\n};\nexport type ConfigEvent = {\n type: \"conversation_initiation_metadata\";\n conversation_initiation_metadata_event: {\n conversation_id: string;\n agent_output_audio_format: string;\n user_input_audio_format?: string;\n };\n};\nexport type PingEvent = {\n type: \"ping\";\n ping_event: {\n event_id: number;\n ping_ms?: number;\n };\n};\nexport type ClientToolCallEvent = {\n type: \"client_tool_call\";\n client_tool_call: {\n tool_name: string;\n tool_call_id: string;\n parameters: any;\n expects_response: boolean;\n };\n};\n\n// TODO correction missing\nexport type IncomingSocketEvent =\n | UserTranscriptionEvent\n | AgentResponseEvent\n | AgentAudioEvent\n | InterruptionEvent\n | InternalTentativeAgentResponseEvent\n | ConfigEvent\n | PingEvent\n | ClientToolCallEvent;\n\nexport type PongEvent = {\n type: \"pong\";\n event_id: number;\n};\nexport type UserAudioEvent = {\n user_audio_chunk: string;\n};\nexport type UserFeedbackEvent = {\n type: \"feedback\";\n score: \"like\" | \"dislike\";\n event_id: number;\n};\nexport type ClientToolResultEvent = {\n type: \"client_tool_result\";\n tool_call_id: string;\n result: any;\n is_error: boolean;\n};\nexport type InitiationClientDataEvent = {\n type: \"conversation_initiation_client_data\";\n conversation_config_override?: {\n agent?: {\n prompt?: {\n prompt?: string;\n };\n first_message?: string;\n language?: Language;\n };\n tts?: {\n voice_id?: string;\n };\n };\n custom_llm_extra_body?: any;\n dynamic_variables?: Record<string, string | number | boolean>;\n};\nexport type OutgoingSocketEvent =\n | PongEvent\n | UserAudioEvent\n | InitiationClientDataEvent\n | UserFeedbackEvent\n | ClientToolResultEvent;\n\nexport function isValidSocketEvent(event: any): event is IncomingSocketEvent {\n return !!event.type;\n}\n","import {\n InitiationClientDataEvent,\n ConfigEvent,\n isValidSocketEvent,\n OutgoingSocketEvent,\n IncomingSocketEvent,\n} from \"./events\";\n\nconst MAIN_PROTOCOL = \"convai\";\n\nexport type Language =\n | \"en\"\n | \"ja\"\n | \"zh\"\n | \"de\"\n | \"hi\"\n | \"fr\"\n | \"ko\"\n | \"pt\"\n | \"it\"\n | \"es\"\n | \"id\"\n | \"nl\"\n | \"tr\"\n | \"pl\"\n | \"sv\"\n | \"bg\"\n | \"ro\"\n | \"ar\"\n | \"cs\"\n | \"el\"\n | \"fi\"\n | \"ms\"\n | \"da\"\n | \"ta\"\n | \"uk\"\n | \"ru\"\n | \"hu\"\n | \"no\"\n | \"vi\";\nexport type SessionConfig = {\n origin?: string;\n authorization?: 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 };\n customLlmExtraBody?: any;\n dynamicVariables?: Record<string, string | number | boolean>;\n connectionDelay?: {\n default: number;\n android?: number;\n ios?: number;\n };\n} & (\n | { signedUrl: string; agentId?: undefined }\n | { agentId: string; signedUrl?: undefined }\n);\nexport type FormatConfig = {\n format: \"pcm\" | \"ulaw\";\n sampleRate: number;\n};\nexport type DisconnectionDetails =\n | {\n reason: \"error\";\n message: string;\n context: Event;\n }\n | {\n reason: \"agent\";\n context: CloseEvent;\n }\n | {\n reason: \"user\";\n };\nexport type OnDisconnectCallback = (details: DisconnectionDetails) => void;\nexport type OnMessageCallback = (event: IncomingSocketEvent) => void;\n\nconst WSS_API_ORIGIN = \"wss://api.elevenlabs.io\";\nconst WSS_API_PATHNAME = \"/v1/convai/conversation?agent_id=\";\n\nexport class Connection {\n public static async create(config: SessionConfig): Promise<Connection> {\n let socket: WebSocket | null = null;\n\n try {\n const origin = config.origin ?? WSS_API_ORIGIN;\n const url = config.signedUrl\n ? config.signedUrl\n : origin + WSS_API_PATHNAME + config.agentId;\n\n const protocols = [MAIN_PROTOCOL];\n if (config.authorization) {\n protocols.push(`bearer.${config.authorization}`);\n }\n socket = new WebSocket(url, protocols);\n const conversationConfig = await new Promise<\n ConfigEvent[\"conversation_initiation_metadata_event\"]\n >((resolve, reject) => {\n socket!.addEventListener(\n \"open\",\n () => {\n const overridesEvent: InitiationClientDataEvent = {\n type: \"conversation_initiation_client_data\",\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 };\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 socket?.send(JSON.stringify(overridesEvent));\n },\n { once: true }\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 socket!.addEventListener(\"close\", reject);\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 Connection(socket, conversation_id, inputFormat, outputFormat);\n } catch (error) {\n socket?.close();\n throw error;\n }\n }\n\n private queue: IncomingSocketEvent[] = [];\n private disconnectionDetails: DisconnectionDetails | null = null;\n private onDisconnectCallback: OnDisconnectCallback | null = null;\n private onMessageCallback: OnMessageCallback | null = null;\n\n private constructor(\n public readonly socket: WebSocket,\n public readonly conversationId: string,\n public readonly inputFormat: FormatConfig,\n public readonly outputFormat: FormatConfig\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 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 this.socket.addEventListener(\"message\", event => {\n try {\n const parsedEvent = JSON.parse(event.data);\n if (!isValidSocketEvent(parsedEvent)) {\n return;\n }\n\n if (this.onMessageCallback) {\n this.onMessageCallback(parsedEvent);\n } else {\n this.queue.push(parsedEvent);\n }\n } catch (_) {}\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 onMessage(callback: OnMessageCallback) {\n this.onMessageCallback = callback;\n this.queue.forEach(callback);\n this.queue = [];\n }\n\n public onDisconnect(callback: OnDisconnectCallback) {\n this.onDisconnectCallback = callback;\n if (this.disconnectionDetails) {\n callback(this.disconnectionDetails);\n }\n }\n\n private disconnect(details: DisconnectionDetails) {\n if (!this.disconnectionDetails) {\n this.disconnectionDetails = details;\n this.onDisconnectCallback?.(details);\n }\n }\n}\n\nfunction 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 = parseInt(sampleRatePart);\n if (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","import { arrayBufferToBase64, base64ToArrayBuffer } from \"./utils/audio\";\nimport { Input, InputConfig } from \"./utils/input\";\nimport { Output } from \"./utils/output\";\nimport {\n Connection,\n DisconnectionDetails,\n OnDisconnectCallback,\n SessionConfig,\n} from \"./utils/connection\";\nimport { ClientToolCallEvent, IncomingSocketEvent } from \"./utils/events\";\nimport { isAndroidDevice, isIosDevice } from \"./utils/compatibility\";\n\nexport type { IncomingSocketEvent } from \"./utils/events\";\nexport type { SessionConfig, DisconnectionDetails } from \"./utils/connection\";\nexport type Role = \"user\" | \"ai\";\nexport type Mode = \"speaking\" | \"listening\";\nexport type Status =\n | \"connecting\"\n | \"connected\"\n | \"disconnecting\"\n | \"disconnected\";\nexport type Options = SessionConfig &\n Callbacks &\n ClientToolsConfig &\n InputConfig;\nexport type ClientToolsConfig = {\n clientTools: Record<\n string,\n (\n parameters: any\n ) => Promise<string | number | void> | string | number | void\n >;\n};\nexport type Callbacks = {\n onConnect: (props: { conversationId: string }) => void;\n // internal debug events, not to be used\n onDebug: (props: any) => void;\n onDisconnect: OnDisconnectCallback;\n onError: (message: string, context?: any) => void;\n onMessage: (props: { message: string; source: Role }) => void;\n onModeChange: (prop: { mode: Mode }) => void;\n onStatusChange: (prop: { status: Status }) => void;\n onCanSendFeedbackChange: (prop: { canSendFeedback: boolean }) => void;\n onUnhandledClientToolCall?: (\n params: ClientToolCallEvent[\"client_tool_call\"]\n ) => void;\n};\n\nconst defaultClientTools = { clientTools: {} };\nconst defaultCallbacks: Callbacks = {\n onConnect: () => {},\n onDebug: () => {},\n onDisconnect: () => {},\n onError: () => {},\n onMessage: () => {},\n onModeChange: () => {},\n onStatusChange: () => {},\n onCanSendFeedbackChange: () => {},\n};\n\nconst HTTPS_API_ORIGIN = \"https://api.elevenlabs.io\";\n\nexport class Conversation {\n public static async startSession(\n options: SessionConfig &\n Partial<Callbacks> &\n Partial<ClientToolsConfig> &\n Partial<InputConfig>\n ): Promise<Conversation> {\n const fullOptions: Options = {\n ...defaultClientTools,\n ...defaultCallbacks,\n ...options,\n };\n\n fullOptions.onStatusChange({ status: \"connecting\" });\n fullOptions.onCanSendFeedbackChange({ canSendFeedback: false });\n\n let input: Input | null = null;\n let connection: Connection | null = null;\n let output: Output | null = null;\n let preliminaryInputStream: MediaStream | null = null;\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 const delayConfig = options.connectionDelay ?? {\n default: 0,\n // Give the Android AudioManager enough time to switch to the correct audio mode\n android: 3_000,\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 connection = await Connection.create(options);\n [input, output] = await Promise.all([\n Input.create({\n ...connection.inputFormat,\n preferHeadphonesForIosDevices: options.preferHeadphonesForIosDevices,\n }),\n Output.create(connection.outputFormat),\n ]);\n\n preliminaryInputStream?.getTracks().forEach(track => track.stop());\n preliminaryInputStream = null;\n\n return new Conversation(fullOptions, connection, input, output);\n } catch (error) {\n fullOptions.onStatusChange({ status: \"disconnected\" });\n preliminaryInputStream?.getTracks().forEach(track => track.stop());\n connection?.close();\n await input?.close();\n await output?.close();\n throw error;\n }\n }\n\n private lastInterruptTimestamp: number = 0;\n private mode: Mode = \"listening\";\n private status: Status = \"connecting\";\n private inputFrequencyData?: Uint8Array;\n private outputFrequencyData?: Uint8Array;\n private volume: number = 1;\n private currentEventId: number = 1;\n private lastFeedbackEventId: number = 1;\n private canSendFeedback: boolean = false;\n\n private constructor(\n private readonly options: Options,\n private readonly connection: Connection,\n public readonly input: Input,\n public readonly output: Output\n ) {\n this.options.onConnect({ conversationId: connection.conversationId });\n\n this.connection.onDisconnect(this.endSessionWithDetails);\n this.connection.onMessage(this.onMessage);\n\n this.input.worklet.port.onmessage = this.onInputWorkletMessage;\n this.output.worklet.port.onmessage = this.onOutputWorkletMessage;\n this.updateStatus(\"connected\");\n }\n\n public endSession = () => this.endSessionWithDetails({ reason: \"user\" });\n\n private endSessionWithDetails = async (details: DisconnectionDetails) => {\n if (this.status !== \"connected\" && this.status !== \"connecting\") return;\n this.updateStatus(\"disconnecting\");\n\n this.connection.close();\n await this.input.close();\n await this.output.close();\n\n this.updateStatus(\"disconnected\");\n this.options.onDisconnect(details);\n };\n\n private updateMode = (mode: Mode) => {\n if (mode !== this.mode) {\n this.mode = mode;\n this.options.onModeChange({ mode });\n }\n };\n\n private updateStatus = (status: Status) => {\n if (status !== this.status) {\n this.status = status;\n this.options.onStatusChange({ status });\n }\n };\n\n private updateCanSendFeedback = () => {\n const canSendFeedback = this.currentEventId !== this.lastFeedbackEventId;\n if (this.canSendFeedback !== canSendFeedback) {\n this.canSendFeedback = canSendFeedback;\n this.options.onCanSendFeedbackChange({ canSendFeedback });\n }\n };\n\n private onMessage = async (parsedEvent: IncomingSocketEvent) => {\n switch (parsedEvent.type) {\n case \"interruption\": {\n if (parsedEvent.interruption_event) {\n this.lastInterruptTimestamp = parsedEvent.interruption_event.event_id;\n }\n this.fadeOutAudio();\n break;\n }\n\n case \"agent_response\": {\n this.options.onMessage({\n source: \"ai\",\n message: parsedEvent.agent_response_event.agent_response,\n });\n break;\n }\n\n case \"user_transcript\": {\n this.options.onMessage({\n source: \"user\",\n message: parsedEvent.user_transcription_event.user_transcript,\n });\n break;\n }\n\n case \"internal_tentative_agent_response\": {\n this.options.onDebug({\n type: \"tentative_agent_response\",\n response:\n parsedEvent.tentative_agent_response_internal_event\n .tentative_agent_response,\n });\n break;\n }\n\n case \"client_tool_call\": {\n if (\n this.options.clientTools.hasOwnProperty(\n parsedEvent.client_tool_call.tool_name\n )\n ) {\n try {\n const result =\n (await this.options.clientTools[\n parsedEvent.client_tool_call.tool_name\n ](parsedEvent.client_tool_call.parameters)) ??\n \"Client tool execution successful.\"; // default client-tool call response\n\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: parsedEvent.client_tool_call.tool_call_id,\n result: result,\n is_error: false,\n });\n } catch (e) {\n this.onError(\n \"Client tool execution failed with following error: \" +\n (e as Error)?.message,\n {\n clientToolName: parsedEvent.client_tool_call.tool_name,\n }\n );\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: parsedEvent.client_tool_call.tool_call_id,\n result: \"Client tool execution failed: \" + (e as Error)?.message,\n is_error: true,\n });\n }\n\n break;\n }\n\n if (this.options.onUnhandledClientToolCall) {\n this.options.onUnhandledClientToolCall(parsedEvent.client_tool_call);\n\n break;\n }\n\n this.onError(\n `Client tool with name ${parsedEvent.client_tool_call.tool_name} is not defined on client`,\n {\n clientToolName: parsedEvent.client_tool_call.tool_name,\n }\n );\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: parsedEvent.client_tool_call.tool_call_id,\n result: `Client tool with name ${parsedEvent.client_tool_call.tool_name} is not defined on client`,\n is_error: true,\n });\n\n break;\n }\n\n case \"audio\": {\n if (this.lastInterruptTimestamp <= parsedEvent.audio_event.event_id) {\n this.addAudioBase64Chunk(parsedEvent.audio_event.audio_base_64);\n this.currentEventId = parsedEvent.audio_event.event_id;\n this.updateCanSendFeedback();\n this.updateMode(\"speaking\");\n }\n break;\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 break;\n }\n\n // unhandled events are expected to be internal events\n default: {\n this.options.onDebug(parsedEvent);\n break;\n }\n }\n };\n\n private onInputWorkletMessage = (event: MessageEvent): void => {\n const rawAudioPcmData = event.data[0];\n const maxVolume = event.data[1];\n\n // check if the sound was loud enough, so we don't send unnecessary chunks\n // then forward audio to websocket\n //if (maxVolume > 0.001) {\n if (this.status === \"connected\") {\n this.connection.sendMessage({\n user_audio_chunk: arrayBufferToBase64(rawAudioPcmData.buffer),\n //sample_rate: this.inputAudioContext?.inputSampleRate || this.inputSampleRate,\n });\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 onError = (message: string, context?: any) => {\n console.error(message, context);\n this.options.onError(message, context);\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 getId = () => this.connection.conversationId;\n\n public isOpen = () => this.status === \"connected\";\n\n public setVolume = ({ volume }: { volume: number }) => {\n this.volume = volume;\n };\n\n public getInputByteFrequencyData = () => {\n this.inputFrequencyData ??= new Uint8Array(\n this.input.analyser.frequencyBinCount\n );\n this.input.analyser.getByteFrequencyData(this.inputFrequencyData);\n return this.inputFrequencyData;\n };\n\n public getOutputByteFrequencyData = () => {\n this.outputFrequencyData ??= new Uint8Array(\n this.output.analyser.frequencyBinCount\n );\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 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\nexport function postOverallFeedback(\n conversationId: string,\n like: boolean,\n origin: string = HTTPS_API_ORIGIN\n) {\n return fetch(`${origin}/v1/convai/conversations/${conversationId}/feedback`, {\n method: \"POST\",\n body: JSON.stringify({\n feedback: like ? \"like\" : \"dislike\",\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n}\n"],"names":["base64ToArrayBuffer","base64","binaryString","window","atob","len","length","bytes","Uint8Array","i","charCodeAt","buffer","blob","Blob","type","rawAudioProcessor","URL","createObjectURL","isIosDevice","includes","navigator","platform","userAgent","document","Input","context","analyser","worklet","inputStream","this","create","_ref","sampleRate","format","preferHeadphonesForIosDevices","Promise","resolve","_temp4","_temp2","audioWorklet","addModule","then","mediaDevices","getUserMedia","audio","options","_navigator$mediaDevic","source","createMediaStreamSource","AudioWorkletNode","port","postMessage","connect","resume","supportsSampleRateConstraint","getSupportedConstraints","AudioContext","createAnalyser","_temp","ideal","echoCancellation","noiseSuppression","_temp3","enumerateDevices","availableDevices","idealDevice","find","d","kind","keyword","label","toLowerCase","deviceId","_catch","error","_inputStream","_context","getTracks","forEach","track","stop","close","e","reject","prototype","audioConcatProcessor","Output","gain","createGain","destination","_proto","isValidSocketEvent","event","Connection","socket","conversationId","inputFormat","outputFormat","_this","queue","disconnectionDetails","onDisconnectCallback","onMessageCallback","addEventListener","setTimeout","disconnect","reason","message","code","parsedEvent","JSON","parse","data","push","_","config","origin","_config$origin","url","signedUrl","agentId","protocols","authorization","WebSocket","_socket","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","overridesEvent","overrides","conversation_config_override","agent","prompt","first_message","firstMessage","language","tts","voice_id","voiceId","customLlmExtraBody","custom_llm_extra_body","dynamicVariables","dynamic_variables","send","stringify","once","conversation_initiation_metadata_event","console","warn","conversationConfig","conversation_id","agent_output_audio_format","user_input_audio_format","parseFormat","_socket2","sendMessage","onMessage","callback","onDisconnect","details","_this$onDisconnectCal","call","_format$split","split","formatPart","sampleRatePart","Error","parseInt","isNaN","defaultClientTools","clientTools","_settle","pact","state","value","s","_Pact","bind","v","o","defaultCallbacks","onConnect","onDebug","onError","onModeChange","onStatusChange","onCanSendFeedbackChange","onFulfilled","onRejected","result","Conversation","connection","input","output","_this2","_this3","lastInterruptTimestamp","mode","status","inputFrequencyData","outputFrequencyData","volume","currentEventId","lastFeedbackEventId","canSendFeedback","endSession","endSessionWithDetails","updateStatus","updateMode","updateCanSendFeedback","_interrupt","_temp5","_switch","interruption_event","event_id","fadeOutAudio","agent_response_event","agent_response","user_transcription_event","user_transcript","response","tentative_agent_response_internal_event","tentative_agent_response","onUnhandledClientToolCall","client_tool_call","tool_name","clientToolName","tool_call_id","is_error","hasOwnProperty","parameters","audio_event","addAudioBase64Chunk","audio_base_64","ping_event","onInputWorkletMessage","b","user_audio_chunk","btoa","String","fromCharCode","apply","onOutputWorkletMessage","finished","chunk","exponentialRampToValueAtTime","currentTime","calculateVolume","frequencyData","getId","isOpen","setVolume","_ref2","getInputByteFrequencyData","frequencyBinCount","getByteFrequencyData","getOutputByteFrequencyData","_this$outputFrequency","getInputVolume","getOutputVolume","sendFeedback","like","score","onmessage","startSession","fullOptions","_extends","preliminaryInputStream","_options$connectionDe","_temp7","_Connection$create","all","_Promise$all","_preliminaryInputStre","_delayConfig$android","delayConfig","connectionDelay","default","android","delay","test","_delayConfig$ios","ios","_temp6","_preliminaryInputStre2","_connection","_input","_output","fetch","method","body","feedback","headers"],"mappings":"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"}
1
+ {"version":3,"file":"lib.umd.js","sources":["../src/utils/audio.ts","../src/utils/rawAudioProcessor.ts","../src/utils/compatibility.ts","../src/utils/input.ts","../src/utils/audioConcatProcessor.ts","../src/utils/output.ts","../src/utils/events.ts","../src/utils/connection.ts","../src/index.ts"],"sourcesContent":["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","/*\n * ulaw encoding logic taken from the wavefile library\n * https://github.com/rochars/wavefile/blob/master/lib/codecs/mulaw.js\n */\n\nconst blob = new Blob(\n [\n // language=JavaScript\n `\n const BIAS = 0x84;\n const CLIP = 32635;\n const 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 \n function 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 \n class 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 }\n registerProcessor(\"raw-audio-processor\", RawAudioProcessor);\n `,\n ],\n { type: \"application/javascript\" }\n);\n\nexport const rawAudioProcessor = URL.createObjectURL(blob);\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 { rawAudioProcessor } from \"./rawAudioProcessor\";\nimport { FormatConfig } from \"./connection\";\nimport { isIosDevice } from \"./compatibility\";\n\nexport type InputConfig = {\n preferHeadphonesForIosDevices?: boolean;\n};\n\nconst LIBSAMPLERATE_JS =\n \"https://cdn.jsdelivr.net/npm/@alexanderolsen/libsamplerate-js@2.1.2/dist/libsamplerate.worklet.js\";\n\nexport class Input {\n public static async create({\n sampleRate,\n format,\n preferHeadphonesForIosDevices,\n }: FormatConfig & InputConfig): Promise<Input> {\n let context: AudioContext | null = null;\n let inputStream: MediaStream | null = null;\n\n try {\n const options: MediaTrackConstraints = {\n sampleRate: { ideal: sampleRate },\n echoCancellation: { ideal: true },\n noiseSuppression: { ideal: true },\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 const supportsSampleRateConstraint =\n navigator.mediaDevices.getSupportedConstraints().sampleRate;\n\n context = new window.AudioContext(\n supportsSampleRateConstraint ? { sampleRate } : {}\n );\n const analyser = context.createAnalyser();\n if (!supportsSampleRateConstraint) {\n await context.audioWorklet.addModule(LIBSAMPLERATE_JS);\n }\n await context.audioWorklet.addModule(rawAudioProcessor);\n\n inputStream = await navigator.mediaDevices.getUserMedia({\n audio: options,\n });\n\n const source = context.createMediaStreamSource(inputStream);\n const worklet = new AudioWorkletNode(context, \"raw-audio-processor\");\n worklet.port.postMessage({ type: \"setFormat\", format, sampleRate });\n\n source.connect(analyser);\n analyser.connect(worklet);\n\n await context.resume();\n\n return new Input(context, analyser, worklet, inputStream);\n } catch (error) {\n inputStream?.getTracks().forEach(track => track.stop());\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 readonly inputStream: MediaStream\n ) {}\n\n public async close() {\n this.inputStream.getTracks().forEach(track => track.stop());\n await this.context.close();\n }\n\n public setMuted(isMuted: boolean) {\n this.worklet.port.postMessage({ type: \"setMuted\", isMuted });\n }\n}\n","/*\n * ulaw decoding logic taken from the wavefile library\n * https://github.com/rochars/wavefile/blob/master/lib/codecs/mulaw.js\n */\n\nconst blob = new Blob(\n [\n // language=JavaScript\n `\n const decodeTable = [0,132,396,924,1980,4092,8316,16764];\n \n export function decodeSample(muLawSample) {\n let sign;\n let exponent;\n let mantissa;\n let sample;\n muLawSample = ~muLawSample;\n sign = (muLawSample & 0x80);\n exponent = (muLawSample >> 4) & 0x07;\n mantissa = muLawSample & 0x0F;\n sample = decodeTable[exponent] + (mantissa << (exponent+3));\n if (sign !== 0) sample = -sample;\n\n return sample;\n }\n \n class 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\n registerProcessor(\"audio-concat-processor\", AudioConcatProcessor);\n `,\n ],\n { type: \"application/javascript\" }\n);\n\nexport const audioConcatProcessor = URL.createObjectURL(blob);\n","import { audioConcatProcessor } from \"./audioConcatProcessor\";\nimport { FormatConfig } from \"./connection\";\n\nexport class Output {\n public static async create({\n sampleRate,\n format,\n }: FormatConfig): Promise<Output> {\n let context: AudioContext | null = null;\n try {\n context = new AudioContext({ sampleRate });\n const analyser = context.createAnalyser();\n const gain = context.createGain();\n gain.connect(analyser);\n analyser.connect(context.destination);\n await context.audioWorklet.addModule(audioConcatProcessor);\n const worklet = new AudioWorkletNode(context, \"audio-concat-processor\");\n worklet.port.postMessage({ type: \"setFormat\", format });\n worklet.connect(gain);\n\n await context.resume();\n\n return new Output(context, analyser, gain, worklet);\n } catch (error) {\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 gain: GainNode,\n public readonly worklet: AudioWorkletNode\n ) {}\n\n public async close() {\n await this.context.close();\n }\n}\n","import { Language } from \"./connection\";\n\nexport type UserTranscriptionEvent = {\n type: \"user_transcript\";\n user_transcription_event: { user_transcript: string };\n};\nexport type AgentResponseEvent = {\n type: \"agent_response\";\n agent_response_event: { agent_response: string };\n};\nexport type AgentAudioEvent = {\n type: \"audio\";\n audio_event: {\n audio_base_64: string;\n event_id: number;\n };\n};\nexport type InterruptionEvent = {\n type: \"interruption\";\n interruption_event: {\n event_id: number;\n };\n};\nexport type InternalTentativeAgentResponseEvent = {\n type: \"internal_tentative_agent_response\";\n tentative_agent_response_internal_event: {\n tentative_agent_response: string;\n };\n};\nexport type ConfigEvent = {\n type: \"conversation_initiation_metadata\";\n conversation_initiation_metadata_event: {\n conversation_id: string;\n agent_output_audio_format: string;\n user_input_audio_format?: string;\n };\n};\nexport type PingEvent = {\n type: \"ping\";\n ping_event: {\n event_id: number;\n ping_ms?: number;\n };\n};\nexport type ClientToolCallEvent = {\n type: \"client_tool_call\";\n client_tool_call: {\n tool_name: string;\n tool_call_id: string;\n parameters: any;\n expects_response: boolean;\n };\n};\n\n// TODO correction missing\nexport type IncomingSocketEvent =\n | UserTranscriptionEvent\n | AgentResponseEvent\n | AgentAudioEvent\n | InterruptionEvent\n | InternalTentativeAgentResponseEvent\n | ConfigEvent\n | PingEvent\n | ClientToolCallEvent;\n\nexport type PongEvent = {\n type: \"pong\";\n event_id: number;\n};\nexport type UserAudioEvent = {\n user_audio_chunk: string;\n};\nexport type UserFeedbackEvent = {\n type: \"feedback\";\n score: \"like\" | \"dislike\";\n event_id: number;\n};\nexport type ClientToolResultEvent = {\n type: \"client_tool_result\";\n tool_call_id: string;\n result: any;\n is_error: boolean;\n};\nexport type InitiationClientDataEvent = {\n type: \"conversation_initiation_client_data\";\n conversation_config_override?: {\n agent?: {\n prompt?: {\n prompt?: string;\n };\n first_message?: string;\n language?: Language;\n };\n tts?: {\n voice_id?: string;\n };\n };\n custom_llm_extra_body?: any;\n dynamic_variables?: Record<string, string | number | boolean>;\n};\nexport type OutgoingSocketEvent =\n | PongEvent\n | UserAudioEvent\n | InitiationClientDataEvent\n | UserFeedbackEvent\n | ClientToolResultEvent;\n\nexport function isValidSocketEvent(event: any): event is IncomingSocketEvent {\n return !!event.type;\n}\n","import {\n InitiationClientDataEvent,\n ConfigEvent,\n isValidSocketEvent,\n OutgoingSocketEvent,\n IncomingSocketEvent,\n} from \"./events\";\n\nconst MAIN_PROTOCOL = \"convai\";\n\nexport type Language =\n | \"en\"\n | \"ja\"\n | \"zh\"\n | \"de\"\n | \"hi\"\n | \"fr\"\n | \"ko\"\n | \"pt\"\n | \"it\"\n | \"es\"\n | \"id\"\n | \"nl\"\n | \"tr\"\n | \"pl\"\n | \"sv\"\n | \"bg\"\n | \"ro\"\n | \"ar\"\n | \"cs\"\n | \"el\"\n | \"fi\"\n | \"ms\"\n | \"da\"\n | \"ta\"\n | \"uk\"\n | \"ru\"\n | \"hu\"\n | \"no\"\n | \"vi\";\nexport type SessionConfig = {\n origin?: string;\n authorization?: 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 };\n customLlmExtraBody?: any;\n dynamicVariables?: Record<string, string | number | boolean>;\n connectionDelay?: {\n default: number;\n android?: number;\n ios?: number;\n };\n} & (\n | { signedUrl: string; agentId?: undefined }\n | { agentId: string; signedUrl?: undefined }\n);\nexport type FormatConfig = {\n format: \"pcm\" | \"ulaw\";\n sampleRate: number;\n};\nexport type DisconnectionDetails =\n | {\n reason: \"error\";\n message: string;\n context: Event;\n }\n | {\n reason: \"agent\";\n context: CloseEvent;\n }\n | {\n reason: \"user\";\n };\nexport type OnDisconnectCallback = (details: DisconnectionDetails) => void;\nexport type OnMessageCallback = (event: IncomingSocketEvent) => void;\n\nconst WSS_API_ORIGIN = \"wss://api.elevenlabs.io\";\nconst WSS_API_PATHNAME = \"/v1/convai/conversation?agent_id=\";\n\nexport class Connection {\n public static async create(config: SessionConfig): Promise<Connection> {\n let socket: WebSocket | null = null;\n\n try {\n const origin = config.origin ?? WSS_API_ORIGIN;\n const url = config.signedUrl\n ? config.signedUrl\n : origin + WSS_API_PATHNAME + config.agentId;\n\n const protocols = [MAIN_PROTOCOL];\n if (config.authorization) {\n protocols.push(`bearer.${config.authorization}`);\n }\n socket = new WebSocket(url, protocols);\n const conversationConfig = await new Promise<\n ConfigEvent[\"conversation_initiation_metadata_event\"]\n >((resolve, reject) => {\n socket!.addEventListener(\n \"open\",\n () => {\n const overridesEvent: InitiationClientDataEvent = {\n type: \"conversation_initiation_client_data\",\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 };\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 socket?.send(JSON.stringify(overridesEvent));\n },\n { once: true }\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 socket!.addEventListener(\"close\", reject);\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 Connection(socket, conversation_id, inputFormat, outputFormat);\n } catch (error) {\n socket?.close();\n throw error;\n }\n }\n\n private queue: IncomingSocketEvent[] = [];\n private disconnectionDetails: DisconnectionDetails | null = null;\n private onDisconnectCallback: OnDisconnectCallback | null = null;\n private onMessageCallback: OnMessageCallback | null = null;\n\n private constructor(\n public readonly socket: WebSocket,\n public readonly conversationId: string,\n public readonly inputFormat: FormatConfig,\n public readonly outputFormat: FormatConfig\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 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 this.socket.addEventListener(\"message\", event => {\n try {\n const parsedEvent = JSON.parse(event.data);\n if (!isValidSocketEvent(parsedEvent)) {\n return;\n }\n\n if (this.onMessageCallback) {\n this.onMessageCallback(parsedEvent);\n } else {\n this.queue.push(parsedEvent);\n }\n } catch (_) {}\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 onMessage(callback: OnMessageCallback) {\n this.onMessageCallback = callback;\n this.queue.forEach(callback);\n this.queue = [];\n }\n\n public onDisconnect(callback: OnDisconnectCallback) {\n this.onDisconnectCallback = callback;\n if (this.disconnectionDetails) {\n callback(this.disconnectionDetails);\n }\n }\n\n private disconnect(details: DisconnectionDetails) {\n if (!this.disconnectionDetails) {\n this.disconnectionDetails = details;\n this.onDisconnectCallback?.(details);\n }\n }\n}\n\nfunction 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 = parseInt(sampleRatePart);\n if (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","import { arrayBufferToBase64, base64ToArrayBuffer } from \"./utils/audio\";\nimport { Input, InputConfig } from \"./utils/input\";\nimport { Output } from \"./utils/output\";\nimport {\n Connection,\n DisconnectionDetails,\n OnDisconnectCallback,\n SessionConfig,\n} from \"./utils/connection\";\nimport { ClientToolCallEvent, IncomingSocketEvent } from \"./utils/events\";\nimport { isAndroidDevice, isIosDevice } from \"./utils/compatibility\";\n\nexport type { InputConfig } from \"./utils/input\";\nexport type { IncomingSocketEvent } from \"./utils/events\";\nexport type { SessionConfig, DisconnectionDetails, Language } from \"./utils/connection\";\nexport type Role = \"user\" | \"ai\";\nexport type Mode = \"speaking\" | \"listening\";\nexport type Status =\n | \"connecting\"\n | \"connected\"\n | \"disconnecting\"\n | \"disconnected\";\nexport type Options = SessionConfig &\n Callbacks &\n ClientToolsConfig &\n InputConfig;\nexport type ClientToolsConfig = {\n clientTools: Record<\n string,\n (\n parameters: any\n ) => Promise<string | number | void> | string | number | void\n >;\n};\nexport type Callbacks = {\n onConnect: (props: { conversationId: string }) => void;\n // internal debug events, not to be used\n onDebug: (props: any) => void;\n onDisconnect: OnDisconnectCallback;\n onError: (message: string, context?: any) => void;\n onMessage: (props: { message: string; source: Role }) => void;\n onModeChange: (prop: { mode: Mode }) => void;\n onStatusChange: (prop: { status: Status }) => void;\n onCanSendFeedbackChange: (prop: { canSendFeedback: boolean }) => void;\n onUnhandledClientToolCall?: (\n params: ClientToolCallEvent[\"client_tool_call\"]\n ) => void;\n};\n\nconst defaultClientTools = { clientTools: {} };\nconst defaultCallbacks: Callbacks = {\n onConnect: () => {},\n onDebug: () => {},\n onDisconnect: () => {},\n onError: () => {},\n onMessage: () => {},\n onModeChange: () => {},\n onStatusChange: () => {},\n onCanSendFeedbackChange: () => {},\n};\n\nconst HTTPS_API_ORIGIN = \"https://api.elevenlabs.io\";\n\nexport class Conversation {\n public static async startSession(\n options: SessionConfig &\n Partial<Callbacks> &\n Partial<ClientToolsConfig> &\n Partial<InputConfig>\n ): Promise<Conversation> {\n const fullOptions: Options = {\n ...defaultClientTools,\n ...defaultCallbacks,\n ...options,\n };\n\n fullOptions.onStatusChange({ status: \"connecting\" });\n fullOptions.onCanSendFeedbackChange({ canSendFeedback: false });\n\n let input: Input | null = null;\n let connection: Connection | null = null;\n let output: Output | null = null;\n let preliminaryInputStream: MediaStream | null = null;\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 const delayConfig = options.connectionDelay ?? {\n default: 0,\n // Give the Android AudioManager enough time to switch to the correct audio mode\n android: 3_000,\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 connection = await Connection.create(options);\n [input, output] = await Promise.all([\n Input.create({\n ...connection.inputFormat,\n preferHeadphonesForIosDevices: options.preferHeadphonesForIosDevices,\n }),\n Output.create(connection.outputFormat),\n ]);\n\n preliminaryInputStream?.getTracks().forEach(track => track.stop());\n preliminaryInputStream = null;\n\n return new Conversation(fullOptions, connection, input, output);\n } catch (error) {\n fullOptions.onStatusChange({ status: \"disconnected\" });\n preliminaryInputStream?.getTracks().forEach(track => track.stop());\n connection?.close();\n await input?.close();\n await output?.close();\n throw error;\n }\n }\n\n private lastInterruptTimestamp: number = 0;\n private mode: Mode = \"listening\";\n private status: Status = \"connecting\";\n private inputFrequencyData?: Uint8Array;\n private outputFrequencyData?: Uint8Array;\n private volume: number = 1;\n private currentEventId: number = 1;\n private lastFeedbackEventId: number = 1;\n private canSendFeedback: boolean = false;\n\n private constructor(\n private readonly options: Options,\n private readonly connection: Connection,\n public readonly input: Input,\n public readonly output: Output\n ) {\n this.options.onConnect({ conversationId: connection.conversationId });\n\n this.connection.onDisconnect(this.endSessionWithDetails);\n this.connection.onMessage(this.onMessage);\n\n this.input.worklet.port.onmessage = this.onInputWorkletMessage;\n this.output.worklet.port.onmessage = this.onOutputWorkletMessage;\n this.updateStatus(\"connected\");\n }\n\n public endSession = () => this.endSessionWithDetails({ reason: \"user\" });\n\n private endSessionWithDetails = async (details: DisconnectionDetails) => {\n if (this.status !== \"connected\" && this.status !== \"connecting\") return;\n this.updateStatus(\"disconnecting\");\n\n this.connection.close();\n await this.input.close();\n await this.output.close();\n\n this.updateStatus(\"disconnected\");\n this.options.onDisconnect(details);\n };\n\n private updateMode = (mode: Mode) => {\n if (mode !== this.mode) {\n this.mode = mode;\n this.options.onModeChange({ mode });\n }\n };\n\n private updateStatus = (status: Status) => {\n if (status !== this.status) {\n this.status = status;\n this.options.onStatusChange({ status });\n }\n };\n\n private updateCanSendFeedback = () => {\n const canSendFeedback = this.currentEventId !== this.lastFeedbackEventId;\n if (this.canSendFeedback !== canSendFeedback) {\n this.canSendFeedback = canSendFeedback;\n this.options.onCanSendFeedbackChange({ canSendFeedback });\n }\n };\n\n private onMessage = async (parsedEvent: IncomingSocketEvent) => {\n switch (parsedEvent.type) {\n case \"interruption\": {\n if (parsedEvent.interruption_event) {\n this.lastInterruptTimestamp = parsedEvent.interruption_event.event_id;\n }\n this.fadeOutAudio();\n break;\n }\n\n case \"agent_response\": {\n this.options.onMessage({\n source: \"ai\",\n message: parsedEvent.agent_response_event.agent_response,\n });\n break;\n }\n\n case \"user_transcript\": {\n this.options.onMessage({\n source: \"user\",\n message: parsedEvent.user_transcription_event.user_transcript,\n });\n break;\n }\n\n case \"internal_tentative_agent_response\": {\n this.options.onDebug({\n type: \"tentative_agent_response\",\n response:\n parsedEvent.tentative_agent_response_internal_event\n .tentative_agent_response,\n });\n break;\n }\n\n case \"client_tool_call\": {\n if (\n this.options.clientTools.hasOwnProperty(\n parsedEvent.client_tool_call.tool_name\n )\n ) {\n try {\n const result =\n (await this.options.clientTools[\n parsedEvent.client_tool_call.tool_name\n ](parsedEvent.client_tool_call.parameters)) ??\n \"Client tool execution successful.\"; // default client-tool call response\n\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: parsedEvent.client_tool_call.tool_call_id,\n result: result,\n is_error: false,\n });\n } catch (e) {\n this.onError(\n \"Client tool execution failed with following error: \" +\n (e as Error)?.message,\n {\n clientToolName: parsedEvent.client_tool_call.tool_name,\n }\n );\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: parsedEvent.client_tool_call.tool_call_id,\n result: \"Client tool execution failed: \" + (e as Error)?.message,\n is_error: true,\n });\n }\n\n break;\n }\n\n if (this.options.onUnhandledClientToolCall) {\n this.options.onUnhandledClientToolCall(parsedEvent.client_tool_call);\n\n break;\n }\n\n this.onError(\n `Client tool with name ${parsedEvent.client_tool_call.tool_name} is not defined on client`,\n {\n clientToolName: parsedEvent.client_tool_call.tool_name,\n }\n );\n this.connection.sendMessage({\n type: \"client_tool_result\",\n tool_call_id: parsedEvent.client_tool_call.tool_call_id,\n result: `Client tool with name ${parsedEvent.client_tool_call.tool_name} is not defined on client`,\n is_error: true,\n });\n\n break;\n }\n\n case \"audio\": {\n if (this.lastInterruptTimestamp <= parsedEvent.audio_event.event_id) {\n this.addAudioBase64Chunk(parsedEvent.audio_event.audio_base_64);\n this.currentEventId = parsedEvent.audio_event.event_id;\n this.updateCanSendFeedback();\n this.updateMode(\"speaking\");\n }\n break;\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 break;\n }\n\n // unhandled events are expected to be internal events\n default: {\n this.options.onDebug(parsedEvent);\n break;\n }\n }\n };\n\n private onInputWorkletMessage = (event: MessageEvent): void => {\n const rawAudioPcmData = event.data[0];\n const maxVolume = event.data[1];\n\n // check if the sound was loud enough, so we don't send unnecessary chunks\n // then forward audio to websocket\n //if (maxVolume > 0.001) {\n if (this.status === \"connected\") {\n this.connection.sendMessage({\n user_audio_chunk: arrayBufferToBase64(rawAudioPcmData.buffer),\n //sample_rate: this.inputAudioContext?.inputSampleRate || this.inputSampleRate,\n });\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 onError = (message: string, context?: any) => {\n console.error(message, context);\n this.options.onError(message, context);\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 getId = () => this.connection.conversationId;\n\n public isOpen = () => this.status === \"connected\";\n\n public setVolume = ({ volume }: { volume: number }) => {\n this.volume = volume;\n };\n\n public setMicMuted = (isMuted: boolean) => {\n this.input.setMuted(isMuted);\n }\n\n public getInputByteFrequencyData = () => {\n this.inputFrequencyData ??= new Uint8Array(\n this.input.analyser.frequencyBinCount\n );\n this.input.analyser.getByteFrequencyData(this.inputFrequencyData);\n return this.inputFrequencyData;\n };\n\n public getOutputByteFrequencyData = () => {\n this.outputFrequencyData ??= new Uint8Array(\n this.output.analyser.frequencyBinCount\n );\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 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\nexport function postOverallFeedback(\n conversationId: string,\n like: boolean,\n origin: string = HTTPS_API_ORIGIN\n) {\n return fetch(`${origin}/v1/convai/conversations/${conversationId}/feedback`, {\n method: \"POST\",\n body: JSON.stringify({\n feedback: like ? \"like\" : \"dislike\",\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n}\n"],"names":["base64ToArrayBuffer","base64","binaryString","window","atob","len","length","bytes","Uint8Array","i","charCodeAt","buffer","blob","Blob","type","rawAudioProcessor","URL","createObjectURL","isIosDevice","includes","navigator","platform","userAgent","document","Input","context","analyser","worklet","inputStream","this","create","_ref","sampleRate","format","preferHeadphonesForIosDevices","Promise","resolve","_temp4","_temp2","audioWorklet","addModule","then","mediaDevices","getUserMedia","audio","options","_navigator$mediaDevic","source","createMediaStreamSource","AudioWorkletNode","port","postMessage","connect","resume","supportsSampleRateConstraint","getSupportedConstraints","AudioContext","createAnalyser","_temp","ideal","echoCancellation","noiseSuppression","_temp3","enumerateDevices","availableDevices","idealDevice","find","d","kind","keyword","label","toLowerCase","deviceId","_catch","error","_inputStream","_context","getTracks","forEach","track","stop","close","e","reject","_proto","prototype","setMuted","isMuted","audioConcatProcessor","Output","gain","createGain","destination","isValidSocketEvent","event","Connection","socket","conversationId","inputFormat","outputFormat","_this","queue","disconnectionDetails","onDisconnectCallback","onMessageCallback","addEventListener","setTimeout","disconnect","reason","message","code","parsedEvent","JSON","parse","data","push","_","config","origin","_config$origin","url","signedUrl","agentId","protocols","authorization","WebSocket","_socket","_config$overrides$age","_config$overrides$age2","_config$overrides$age3","_config$overrides$tts","overridesEvent","overrides","conversation_config_override","agent","prompt","first_message","firstMessage","language","tts","voice_id","voiceId","customLlmExtraBody","custom_llm_extra_body","dynamicVariables","dynamic_variables","send","stringify","once","conversation_initiation_metadata_event","console","warn","conversationConfig","conversation_id","agent_output_audio_format","user_input_audio_format","parseFormat","_socket2","sendMessage","onMessage","callback","onDisconnect","details","_this$onDisconnectCal","call","_format$split","split","formatPart","sampleRatePart","Error","parseInt","isNaN","defaultClientTools","clientTools","_settle","pact","state","value","s","_Pact","bind","v","o","defaultCallbacks","onConnect","onDebug","onError","onModeChange","onStatusChange","onCanSendFeedbackChange","onFulfilled","onRejected","result","Conversation","connection","input","output","_this2","_this3","lastInterruptTimestamp","mode","status","inputFrequencyData","outputFrequencyData","volume","currentEventId","lastFeedbackEventId","canSendFeedback","endSession","endSessionWithDetails","updateStatus","updateMode","updateCanSendFeedback","_interrupt","_temp5","_switch","interruption_event","event_id","fadeOutAudio","agent_response_event","agent_response","user_transcription_event","user_transcript","response","tentative_agent_response_internal_event","tentative_agent_response","onUnhandledClientToolCall","client_tool_call","tool_name","clientToolName","tool_call_id","is_error","hasOwnProperty","parameters","audio_event","addAudioBase64Chunk","audio_base_64","ping_event","onInputWorkletMessage","b","user_audio_chunk","btoa","String","fromCharCode","apply","onOutputWorkletMessage","finished","chunk","exponentialRampToValueAtTime","currentTime","calculateVolume","frequencyData","getId","isOpen","setVolume","_ref2","setMicMuted","getInputByteFrequencyData","frequencyBinCount","getByteFrequencyData","getOutputByteFrequencyData","getInputVolume","getOutputVolume","sendFeedback","like","score","onmessage","startSession","fullOptions","_extends","preliminaryInputStream","_options$connectionDe","_temp7","_Connection$create","all","_Promise$all","_preliminaryInputStre","_delayConfig$android","delayConfig","connectionDelay","default","android","delay","test","_delayConfig$ios","ios","_temp6","_preliminaryInputStre2","_connection","_input","_output","fetch","method","body","feedback","headers"],"mappings":"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"}
@@ -10,4 +10,5 @@ export declare class Input {
10
10
  static create({ sampleRate, format, preferHeadphonesForIosDevices, }: FormatConfig & InputConfig): Promise<Input>;
11
11
  private constructor();
12
12
  close(): Promise<void>;
13
+ setMuted(isMuted: boolean): void;
13
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@11labs/client",
3
- "version": "0.0.7-beta.1",
3
+ "version": "0.0.8-beta.1",
4
4
  "description": "ElevenLabs JavaScript Client Library",
5
5
  "main": "./dist/lib.umd.js",
6
6
  "module": "./dist/lib.module.js",