{"version":3,"file":"lib.cjs","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/WebRTCConnection.ts","../src/utils/ConnectionFactory.ts","../src/utils/compatibility.ts","../src/utils/applyDelay.ts","../src/TextConversation.ts","../src/utils/audio.ts","../src/utils/createWorkletModuleLoader.ts","../src/utils/rawAudioProcessor.ts","../src/utils/input.ts","../src/utils/audioConcatProcessor.ts","../src/utils/output.ts","../src/VoiceConversation.ts","../src/index.ts","../src/utils/postOverallFeedback.ts"],"sourcesContent":["import type {\n  BaseConnection,\n  DisconnectionDetails,\n  OnDisconnectCallback,\n  SessionConfig,\n} from \"./utils/BaseConnection\";\nimport type {\n  AgentAudioEvent,\n  AgentResponseEvent,\n  ClientToolCallEvent,\n  IncomingSocketEvent,\n  InternalTentativeAgentResponseEvent,\n  InterruptionEvent,\n  UserTranscriptionEvent,\n} from \"./utils/events\";\nimport type { InputConfig } from \"./utils/input\";\n\nexport type Role = \"user\" | \"ai\";\n\nexport type Mode = \"speaking\" | \"listening\";\n\nexport type Status =\n  | \"connecting\"\n  | \"connected\"\n  | \"disconnecting\"\n  | \"disconnected\";\n\nexport type Options = SessionConfig &\n  Callbacks &\n  ClientToolsConfig &\n  InputConfig;\n\nexport type PartialOptions = SessionConfig &\n  Partial<Callbacks> &\n  Partial<ClientToolsConfig> &\n  Partial<InputConfig>;\n\nexport type ClientToolsConfig = {\n  clientTools: Record<\n    string,\n    (\n      parameters: any\n    ) => Promise<string | number | void> | string | number | void\n  >;\n};\n\nexport type Callbacks = {\n  onConnect: (props: { conversationId: string }) => void;\n  // internal debug events, not to be used\n  onDebug: (props: any) => void;\n  onDisconnect: OnDisconnectCallback;\n  onError: (message: string, context?: any) => void;\n  onMessage: (props: { message: string; source: Role }) => void;\n  onAudio: (base64Audio: string) => void;\n  onModeChange: (prop: { mode: Mode }) => void;\n  onStatusChange: (prop: { status: Status }) => void;\n  onCanSendFeedbackChange: (prop: { canSendFeedback: boolean }) => void;\n  onUnhandledClientToolCall?: (\n    params: ClientToolCallEvent[\"client_tool_call\"]\n  ) => void;\n};\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 = 1;\n  protected canSendFeedback = false;\n\n  protected static getFullOptions(partialOptions: PartialOptions): Options {\n    return {\n      clientTools: {},\n      onConnect: () => {},\n      onDebug: () => {},\n      onDisconnect: () => {},\n      onError: () => {},\n      onMessage: () => {},\n      onAudio: () => {},\n      onModeChange: () => {},\n      onStatusChange: () => {},\n      onCanSendFeedbackChange: () => {},\n      ...partialOptions,\n    };\n  }\n\n  protected constructor(\n    protected readonly options: Options,\n    protected readonly connection: BaseConnection\n  ) {\n    this.options.onConnect({ conversationId: connection.conversationId });\n    this.connection.onMessage(this.onMessage);\n    this.connection.onDisconnect(this.endSessionWithDetails);\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    this.options.onDisconnect(details);\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      this.options.onModeChange({ mode });\n    }\n  }\n\n  protected updateStatus(status: Status) {\n    if (status !== this.status) {\n      this.status = status;\n      this.options.onStatusChange({ status });\n    }\n  }\n\n  protected 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  protected handleInterruption(event: InterruptionEvent) {\n    if (event.interruption_event) {\n      this.lastInterruptTimestamp = event.interruption_event.event_id;\n    }\n  }\n\n  protected handleAgentResponse(event: AgentResponseEvent) {\n    this.options.onMessage({\n      source: \"ai\",\n      message: event.agent_response_event.agent_response,\n    });\n  }\n\n  protected handleUserTranscript(event: UserTranscriptionEvent) {\n    this.options.onMessage({\n      source: \"user\",\n      message: event.user_transcription_event.user_transcript,\n    });\n  }\n\n  protected handleTentativeAgentResponse(\n    event: InternalTentativeAgentResponseEvent\n  ) {\n    this.options.onDebug({\n      type: \"tentative_agent_response\",\n      response:\n        event.tentative_agent_response_internal_event.tentative_agent_response,\n    });\n  }\n\n  protected async handleClientToolCall(event: ClientToolCallEvent) {\n    if (\n      Object.prototype.hasOwnProperty.call(\n        this.options.clientTools,\n        event.client_tool_call.tool_name\n      )\n    ) {\n      try {\n        const result =\n          (await this.options.clientTools[event.client_tool_call.tool_name](\n            event.client_tool_call.parameters\n          )) ?? \"Client tool execution successful.\"; // default client-tool call response\n\n        // The API expects result to be a string, so we need to convert it if it's not already a string\n        const formattedResult =\n          typeof result === \"object\" ? JSON.stringify(result) : String(result);\n\n        this.connection.sendMessage({\n          type: \"client_tool_result\",\n          tool_call_id: event.client_tool_call.tool_call_id,\n          result: formattedResult,\n          is_error: false,\n        });\n      } catch (e) {\n        this.onError(\n          `Client tool execution failed with following error: ${(e as Error)?.message}`,\n          {\n            clientToolName: event.client_tool_call.tool_name,\n          }\n        );\n        this.connection.sendMessage({\n          type: \"client_tool_result\",\n          tool_call_id: event.client_tool_call.tool_call_id,\n          result: `Client tool execution failed: ${(e as Error)?.message}`,\n          is_error: true,\n        });\n      }\n    } else {\n      if (this.options.onUnhandledClientToolCall) {\n        this.options.onUnhandledClientToolCall(event.client_tool_call);\n\n        return;\n      }\n\n      this.onError(\n        `Client tool with name ${event.client_tool_call.tool_name} is not defined on client`,\n        {\n          clientToolName: event.client_tool_call.tool_name,\n        }\n      );\n      this.connection.sendMessage({\n        type: \"client_tool_result\",\n        tool_call_id: event.client_tool_call.tool_call_id,\n        result: `Client tool with name ${event.client_tool_call.tool_name} is not defined on client`,\n        is_error: true,\n      });\n    }\n  }\n\n  protected handleAudio(event: AgentAudioEvent) {}\n\n  private onMessage = async (parsedEvent: IncomingSocketEvent) => {\n    switch (parsedEvent.type) {\n      case \"interruption\": {\n        this.handleInterruption(parsedEvent);\n        return;\n      }\n      case \"agent_response\": {\n        this.handleAgentResponse(parsedEvent);\n        return;\n      }\n      case \"user_transcript\": {\n        this.handleUserTranscript(parsedEvent);\n        return;\n      }\n      case \"internal_tentative_agent_response\": {\n        this.handleTentativeAgentResponse(parsedEvent);\n        return;\n      }\n      case \"client_tool_call\": {\n        await this.handleClientToolCall(parsedEvent);\n        return;\n      }\n      case \"audio\": {\n        this.handleAudio(parsedEvent);\n        return;\n      }\n\n      case \"ping\": {\n        this.connection.sendMessage({\n          type: \"pong\",\n          event_id: parsedEvent.ping_event.event_id,\n        });\n        // parsedEvent.ping_event.ping_ms can be used on client side, for example\n        // to warn if ping is too high that experience might be degraded.\n        return;\n      }\n\n      // unhandled events are expected to be internal events\n      default: {\n        this.options.onDebug(parsedEvent);\n        return;\n      }\n    }\n  };\n\n  private onError(message: string, context?: any) {\n    console.error(message, context);\n    this.options.onError(message, context);\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\n  public getInputByteFrequencyData() {\n    return EMPTY_FREQUENCY_DATA;\n  }\n\n  public getOutputByteFrequencyData() {\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\";\n\nexport type Language =\n  | \"en\"\n  | \"ja\"\n  | \"zh\"\n  | \"de\"\n  | \"hi\"\n  | \"fr\"\n  | \"ko\"\n  | \"pt\"\n  | \"pt-br\"\n  | \"it\"\n  | \"es\"\n  | \"id\"\n  | \"nl\"\n  | \"tr\"\n  | \"pl\"\n  | \"sv\"\n  | \"bg\"\n  | \"ro\"\n  | \"ar\"\n  | \"cs\"\n  | \"el\"\n  | \"fi\"\n  | \"ms\"\n  | \"da\"\n  | \"ta\"\n  | \"uk\"\n  | \"ru\"\n  | \"hu\"\n  | \"hr\"\n  | \"sk\"\n  | \"no\"\n  | \"vi\";\n\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};\n\nexport type DisconnectionDetails =\n  | {\n      reason: \"error\";\n      message: string;\n      context: Event;\n    }\n  | {\n      reason: \"agent\";\n      context: CloseEvent;\n    }\n  | {\n      reason: \"user\";\n    };\n\nexport type OnDisconnectCallback = (details: DisconnectionDetails) => void;\nexport type OnMessageCallback = (event: IncomingSocketEvent) => void;\n\nexport type BaseSessionConfig = {\n  origin?: string;\n  authorization?: string;\n  livekitUrl?: string;\n  overrides?: {\n    agent?: {\n      prompt?: {\n        prompt?: string;\n      };\n      firstMessage?: string;\n      language?: Language;\n    };\n    tts?: {\n      voiceId?: string;\n    };\n    conversation?: {\n      textOnly?: boolean;\n    };\n    client?: {\n      source?: string;\n      version?: string;\n    };\n  };\n  customLlmExtraBody?: unknown;\n  dynamicVariables?: Record<string, string | number | boolean>;\n  useWakeLock?: boolean;\n  connectionDelay?: DelayConfig;\n  textOnly?: boolean;\n  userId?: string;\n};\n\nexport type ConnectionType = \"websocket\" | \"webrtc\";\n\nexport type PublicSessionConfig = BaseSessionConfig & {\n  agentId: string;\n  connectionType: ConnectionType;\n  signedUrl?: never;\n  conversationToken?: never;\n};\n\nexport type PrivateWebSocketSessionConfig = BaseSessionConfig & {\n  signedUrl: string;\n  connectionType?: \"websocket\";\n  agentId?: never;\n  conversationToken?: never;\n};\n\nexport type PrivateWebRTCSessionConfig = BaseSessionConfig & {\n  conversationToken: string;\n  connectionType?: \"webrtc\";\n  agentId?: never;\n  signedUrl?: never;\n};\n\n// Union type for all possible session configurations\nexport type SessionConfig =\n  | PublicSessionConfig\n  | PrivateWebSocketSessionConfig\n  | PrivateWebRTCSessionConfig;\n\nexport abstract class BaseConnection {\n  public abstract readonly conversationId: string;\n  public abstract readonly inputFormat: FormatConfig;\n  public abstract readonly outputFormat: FormatConfig;\n\n  protected queue: IncomingSocketEvent[] = [];\n  protected disconnectionDetails: DisconnectionDetails | null = null;\n  protected onDisconnectCallback: OnDisconnectCallback | null = null;\n  protected onMessageCallback: OnMessageCallback | null = null;\n  protected 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\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  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.4.0\";\n","import type { Language } from \"./connection\";\nimport type { CONVERSATION_INITIATION_CLIENT_DATA_TYPE } from \"./overrides\";\n\nexport type UserTranscriptionEvent = {\n  type: \"user_transcript\";\n  user_transcription_event: { user_transcript: string };\n};\nexport type AgentResponseEvent = {\n  type: \"agent_response\";\n  agent_response_event: { agent_response: string };\n};\nexport type AgentAudioEvent = {\n  type: \"audio\";\n  audio_event: {\n    audio_base_64: string;\n    event_id: number;\n  };\n};\nexport type InterruptionEvent = {\n  type: \"interruption\";\n  interruption_event: {\n    event_id: number;\n  };\n};\nexport type InternalTentativeAgentResponseEvent = {\n  type: \"internal_tentative_agent_response\";\n  tentative_agent_response_internal_event: {\n    tentative_agent_response: string;\n  };\n};\nexport type ConfigEvent = {\n  type: \"conversation_initiation_metadata\";\n  conversation_initiation_metadata_event: {\n    conversation_id: string;\n    agent_output_audio_format: string;\n    user_input_audio_format?: string;\n  };\n};\nexport type PingEvent = {\n  type: \"ping\";\n  ping_event: {\n    event_id: number;\n    ping_ms?: number;\n  };\n};\nexport type ClientToolCallEvent = {\n  type: \"client_tool_call\";\n  client_tool_call: {\n    tool_name: string;\n    tool_call_id: string;\n    parameters: any;\n    expects_response: boolean;\n  };\n};\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: typeof CONVERSATION_INITIATION_CLIENT_DATA_TYPE;\n  conversation_config_override?: {\n    agent?: {\n      prompt?: {\n        prompt?: string;\n      };\n      first_message?: string;\n      language?: Language;\n    };\n    tts?: {\n      voice_id?: string;\n    };\n    conversation?: {\n      text_only?: boolean;\n    };\n  };\n  custom_llm_extra_body?: any;\n  dynamic_variables?: Record<string, string | number | boolean>;\n  user_id?: string;\n};\nexport type ContextualUpdateEvent = {\n  type: \"contextual_update\";\n  text: string;\n};\nexport type UserMessageEvent = {\n  type: \"user_message\";\n  text: string;\n};\nexport type UserActivityEvent = {\n  type: \"user_activity\";\n};\nexport type MCPToolApprovalResultEvent = {\n  type: \"mcp_tool_approval_result\";\n  tool_call_id: string;\n  is_approved: boolean;\n};\nexport type OutgoingSocketEvent =\n  | PongEvent\n  | UserAudioEvent\n  | InitiationClientDataEvent\n  | UserFeedbackEvent\n  | ClientToolResultEvent\n  | ContextualUpdateEvent\n  | UserMessageEvent\n  | UserActivityEvent\n  | MCPToolApprovalResultEvent;\n\nexport function isValidSocketEvent(event: any): event is IncomingSocketEvent {\n  return !!event.type;\n}\n","import type { SessionConfig } from \"./BaseConnection\";\nimport type { InitiationClientDataEvent } from \"./events\";\n\nexport const CONVERSATION_INITIATION_CLIENT_DATA_TYPE =\n  \"conversation_initiation_client_data\";\n\nexport function constructOverrides(\n  config: SessionConfig\n): InitiationClientDataEvent {\n  const overridesEvent: InitiationClientDataEvent = {\n    type: CONVERSATION_INITIATION_CLIENT_DATA_TYPE,\n  };\n\n  if (config.overrides) {\n    overridesEvent.conversation_config_override = {\n      agent: {\n        prompt: config.overrides.agent?.prompt,\n        first_message: config.overrides.agent?.firstMessage,\n        language: config.overrides.agent?.language,\n      },\n      tts: {\n        voice_id: config.overrides.tts?.voiceId,\n      },\n      conversation: {\n        text_only: config.overrides.conversation?.textOnly,\n      },\n    };\n  }\n\n  if (config.customLlmExtraBody) {\n    overridesEvent.custom_llm_extra_body = config.customLlmExtraBody;\n  }\n\n  if (config.dynamicVariables) {\n    overridesEvent.dynamic_variables = config.dynamicVariables;\n  }\n\n  if (config.userId) {\n    overridesEvent.user_id = config.userId;\n  }\n\n  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          return;\n        }\n        this.handleMessage(parsedEvent);\n      } catch (_) {}\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","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 { Room, RoomEvent, Track, ConnectionState } 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\";\n\nconst DEFAULT_LIVEKIT_WS_URL = \"wss://livekit.rtc.elevenlabs.io\";\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\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 url = `https://api.elevenlabs.io/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 = `webrtc-${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      // Update conversation ID with actual room name if available\n      if (room.name) {\n        connection.conversationId = 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(RoomEvent.DataReceived, (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    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          // Add to DOM (hidden) to ensure it plays\n          audioElement.style.display = \"none\";\n          document.body.appendChild(audioElement);\n        }\n      }\n    );\n  }\n\n  public close() {\n    if (this.isConnected) {\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","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    fullOptions.onStatusChange({ status: \"connecting\" });\n    fullOptions.onCanSendFeedbackChange({ canSendFeedback: false });\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      fullOptions.onStatusChange({ status: \"disconnected\" });\n      connection?.close();\n      throw error;\n    }\n  }\n}\n","export function arrayBufferToBase64(b: ArrayBufferLike) {\n  const buffer = new Uint8Array(b);\n  // @ts-ignore\n  const base64Data = window.btoa(String.fromCharCode(...buffer));\n  return base64Data;\n}\n\nexport function base64ToArrayBuffer(base64: string): ArrayBuffer {\n  const binaryString = window.atob(base64);\n  const len = binaryString.length;\n  const bytes = new Uint8Array(len);\n  for (let i = 0; i < len; i++) {\n    bytes[i] = binaryString.charCodeAt(i);\n  }\n  return bytes.buffer;\n}\n","const URLCache = new Map<string, string>();\n\nexport function createWorkletModuleLoader(name: string, sourceCode: string) {\n  return async (worklet: AudioWorklet) => {\n    const url = URLCache.get(name);\n    if (url) {\n      return worklet.addModule(url);\n    }\n\n    const blob = new Blob([sourceCode], { type: \"application/javascript\" });\n    const blobURL = URL.createObjectURL(blob);\n    try {\n      await worklet.addModule(blobURL);\n      URLCache.set(name, blobURL);\n      return;\n    } catch {\n      URL.revokeObjectURL(blobURL);\n    }\n\n    try {\n      // Attempting to start a conversation in Safari inside an iframe will\n      // throw a CORS error because the blob:// protocol is considered\n      // cross-origin. In such cases, fall back to using a base64 data URL:\n      const base64 = btoa(sourceCode);\n      const moduleURL = `data:application/javascript;base64,${base64}`;\n      await worklet.addModule(moduleURL);\n      URLCache.set(name, moduleURL);\n    } catch (error) {\n      throw new Error(\n        `Failed to load the ${name} worklet module. Make sure the browser supports AudioWorklets.`\n      );\n    }\n  };\n}\n","/*\n * ulaw encoding logic taken from the wavefile library\n * https://github.com/rochars/wavefile/blob/master/lib/codecs/mulaw.js\n */\n\nimport { createWorkletModuleLoader } from \"./createWorkletModuleLoader\";\n\nexport const loadRawAudioProcessor = createWorkletModuleLoader(\n  \"raw-audio-processor\",\n  // language=JavaScript\n  `\nconst BIAS = 0x84;\nconst CLIP = 32635;\nconst encodeTable = [\n  0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,\n  4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,\n  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,\n  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,\n  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,\n  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,\n  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7\n];\n\nfunction encodeSample(sample) {\n  let sign;\n  let exponent;\n  let mantissa;\n  let muLawSample;\n  sign = (sample >> 8) & 0x80;\n  if (sign !== 0) sample = -sample;\n  sample = sample + BIAS;\n  if (sample > CLIP) sample = CLIP;\n  exponent = encodeTable[(sample>>7) & 0xFF];\n  mantissa = (sample >> (exponent+3)) & 0x0F;\n  muLawSample = ~(sign | (exponent << 4) | mantissa);\n  \n  return muLawSample;\n}\n\nclass RawAudioProcessor extends AudioWorkletProcessor {\n  constructor() {\n    super();\n              \n    this.port.onmessage = ({ data }) => {\n      switch (data.type) {\n        case \"setFormat\":\n          this.isMuted = false;\n          this.buffer = []; // Initialize an empty buffer\n          this.bufferSize = data.sampleRate / 4;\n          this.format = data.format;\n\n          if (globalThis.LibSampleRate && sampleRate !== data.sampleRate) {\n            globalThis.LibSampleRate.create(1, sampleRate, data.sampleRate).then(resampler => {\n              this.resampler = resampler;\n            });\n          }\n          break;\n        case \"setMuted\":\n          this.isMuted = data.isMuted;\n          break;\n      }\n    };\n  }\n  process(inputs) {\n    if (!this.buffer) {\n      return true;\n    }\n    \n    const input = inputs[0]; // Get the first input node\n    if (input.length > 0) {\n      let channelData = input[0]; // Get the first channel's data\n\n      // Resample the audio if necessary\n      if (this.resampler) {\n        channelData = this.resampler.full(channelData);\n      }\n\n      // Add channel data to the buffer\n      this.buffer.push(...channelData);\n      // Get max volume \n      let sum = 0.0;\n      for (let i = 0; i < channelData.length; i++) {\n        sum += channelData[i] * channelData[i];\n      }\n      const maxVolume = Math.sqrt(sum / channelData.length);\n      // Check if buffer size has reached or exceeded the threshold\n      if (this.buffer.length >= this.bufferSize) {\n        const float32Array = this.isMuted \n          ? new Float32Array(this.buffer.length)\n          : new Float32Array(this.buffer);\n\n        let encodedArray = this.format === \"ulaw\"\n          ? new Uint8Array(float32Array.length)\n          : new Int16Array(float32Array.length);\n\n        // Iterate through the Float32Array and convert each sample to PCM16\n        for (let i = 0; i < float32Array.length; i++) {\n          // Clamp the value to the range [-1, 1]\n          let sample = Math.max(-1, Math.min(1, float32Array[i]));\n\n          // Scale the sample to the range [-32768, 32767]\n          let value = sample < 0 ? sample * 32768 : sample * 32767;\n          if (this.format === \"ulaw\") {\n            value = encodeSample(Math.round(value));\n          }\n\n          encodedArray[i] = value;\n        }\n\n        // Send the buffered data to the main script\n        this.port.postMessage([encodedArray, maxVolume]);\n\n        // Clear the buffer after sending\n        this.buffer = [];\n      }\n    }\n    return true; // Continue processing\n  }\n}\nregisterProcessor(\"raw-audio-processor\", RawAudioProcessor);\n`\n);\n","import { loadRawAudioProcessor } from \"./rawAudioProcessor\";\nimport type { 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 loadRawAudioProcessor(context.audioWorklet);\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\nimport { createWorkletModuleLoader } from \"./createWorkletModuleLoader\";\n\nexport const loadAudioConcatProcessor = createWorkletModuleLoader(\n  \"audio-concat-processor\",\n  // language=JavaScript\n  `\nconst decodeTable = [0,132,396,924,1980,4092,8316,16764];\n\nexport function decodeSample(muLawSample) {\n  let sign;\n  let exponent;\n  let mantissa;\n  let sample;\n  muLawSample = ~muLawSample;\n  sign = (muLawSample & 0x80);\n  exponent = (muLawSample >> 4) & 0x07;\n  mantissa = muLawSample & 0x0F;\n  sample = decodeTable[exponent] + (mantissa << (exponent+3));\n  if (sign !== 0) sample = -sample;\n\n  return sample;\n}\n\nclass AudioConcatProcessor extends AudioWorkletProcessor {\n  constructor() {\n    super();\n    this.buffers = []; // Initialize an empty buffer\n    this.cursor = 0;\n    this.currentBuffer = null;\n    this.wasInterrupted = false;\n    this.finished = false;\n    \n    this.port.onmessage = ({ data }) => {\n      switch (data.type) {\n        case \"setFormat\":\n          this.format = data.format;\n          break;\n        case \"buffer\":\n          this.wasInterrupted = false;\n          this.buffers.push(\n            this.format === \"ulaw\"\n              ? new Uint8Array(data.buffer)\n              : new Int16Array(data.buffer)\n          );\n          break;\n        case \"interrupt\":\n          this.wasInterrupted = true;\n          break;\n        case \"clearInterrupted\":\n          if (this.wasInterrupted) {\n            this.wasInterrupted = false;\n            this.buffers = [];\n            this.currentBuffer = null;\n          }\n      }\n    };\n  }\n  process(_, outputs) {\n    let finished = false;\n    const output = outputs[0][0];\n    for (let i = 0; i < output.length; i++) {\n      if (!this.currentBuffer) {\n        if (this.buffers.length === 0) {\n          finished = true;\n          break;\n        }\n        this.currentBuffer = this.buffers.shift();\n        this.cursor = 0;\n      }\n\n      let value = this.currentBuffer[this.cursor];\n      if (this.format === \"ulaw\") {\n        value = decodeSample(value);\n      }\n      output[i] = value / 32768;\n      this.cursor++;\n\n      if (this.cursor >= this.currentBuffer.length) {\n        this.currentBuffer = null;\n      }\n    }\n\n    if (this.finished !== finished) {\n      this.finished = finished;\n      this.port.postMessage({ type: \"process\", finished });\n    }\n\n    return true; // Continue processing\n  }\n}\n\nregisterProcessor(\"audio-concat-processor\", AudioConcatProcessor);\n`\n);\n","import { loadAudioConcatProcessor } from \"./audioConcatProcessor\";\nimport type { FormatConfig } from \"./connection\";\n\nexport class Output {\n  public static async create({\n    sampleRate,\n    format,\n  }: 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 loadAudioConcatProcessor(context.audioWorklet);\n      const worklet = new AudioWorkletNode(context, \"audio-concat-processor\");\n      worklet.port.postMessage({ type: \"setFormat\", format });\n      worklet.connect(gain);\n\n      await context.resume();\n\n      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 { arrayBufferToBase64, base64ToArrayBuffer } from \"./utils/audio\";\nimport { Input } from \"./utils/input\";\nimport { Output } from \"./utils/output\";\nimport { createConnection } from \"./utils/ConnectionFactory\";\nimport type { BaseConnection } from \"./utils/BaseConnection\";\nimport type { AgentAudioEvent, InterruptionEvent } from \"./utils/events\";\nimport { applyDelay } from \"./utils/applyDelay\";\nimport {\n  BaseConversation,\n  type Options,\n  type PartialOptions,\n} from \"./BaseConversation\";\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    fullOptions.onStatusChange({ status: \"connecting\" });\n    fullOptions.onCanSendFeedbackChange({ canSendFeedback: false });\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        }),\n        Output.create(connection.outputFormat),\n      ]);\n\n      preliminaryInputStream?.getTracks().forEach(track => track.stop());\n      preliminaryInputStream = null;\n\n      return new VoiceConversation(\n        fullOptions,\n        connection,\n        input,\n        output,\n        wakeLock\n      );\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      try {\n        await wakeLock?.release();\n        wakeLock = null;\n      } catch (e) {}\n      throw error;\n    }\n  }\n\n  private inputFrequencyData?: Uint8Array;\n  private outputFrequencyData?: Uint8Array;\n\n  protected constructor(\n    options: Options,\n    connection: BaseConnection,\n    public readonly input: Input,\n    public readonly 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      this.addAudioBase64Chunk(event.audio_event.audio_base_64);\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    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","import { BaseConversation, type PartialOptions } from \"./BaseConversation\";\nimport { TextConversation } from \"./TextConversation\";\nimport { VoiceConversation } from \"./VoiceConversation\";\n\nexport type {\n  Mode,\n  Role,\n  Options,\n  PartialOptions,\n  ClientToolsConfig,\n  Callbacks,\n  Status,\n} from \"./BaseConversation\";\nexport type { InputConfig } from \"./utils/input\";\nexport type { IncomingSocketEvent } from \"./utils/events\";\nexport type {\n  SessionConfig,\n  BaseSessionConfig,\n  DisconnectionDetails,\n  Language,\n  ConnectionType,\n} from \"./utils/BaseConnection\";\nexport { createConnection } from \"./utils/ConnectionFactory\";\nexport { WebSocketConnection } from \"./utils/WebSocketConnection\";\nexport { WebRTCConnection } from \"./utils/WebRTCConnection\";\nexport { postOverallFeedback } from \"./utils/postOverallFeedback\";\n\nexport class Conversation extends BaseConversation {\n  public static startSession(options: PartialOptions): Promise<Conversation> {\n    return options.textOnly\n      ? TextConversation.startSession(options)\n      : VoiceConversation.startSession(options);\n  }\n}\n","const HTTPS_API_ORIGIN = \"https://api.elevenlabs.io\";\n\nexport function postOverallFeedback(\n  conversationId: string,\n  like: boolean,\n  origin: string = HTTPS_API_ORIGIN\n) {\n  return fetch(`${origin}/v1/convai/conversations/${conversationId}/feedback`, {\n    method: \"POST\",\n    body: JSON.stringify({\n      feedback: like ? \"like\" : \"dislike\",\n    }),\n    headers: {\n      \"Content-Type\": \"application/json\",\n    },\n  });\n}\n"],"names":["EMPTY_FREQUENCY_DATA","Uint8Array","BaseConversation","options","connection","_this3","_this","this","_this2","lastInterruptTimestamp","mode","status","volume","currentEventId","lastFeedbackEventId","canSendFeedback","endSessionWithDetails","details","Promise","resolve","updateStatus","handleEndSession","then","onDisconnect","e","reject","onMessage","parsedEvent","type","handleInterruption","handleAgentResponse","handleUserTranscript","handleTentativeAgentResponse","handleClientToolCall","handleAudio","sendMessage","event_id","ping_event","onDebug","setVolume","_ref","onConnect","conversationId","getFullOptions","partialOptions","_extends","clientTools","onError","onAudio","onModeChange","onStatusChange","onCanSendFeedbackChange","_proto","prototype","endSession","reason","close","updateMode","updateCanSendFeedback","event","interruption_event","source","message","agent_response_event","agent_response","user_transcription_event","user_transcript","response","tentative_agent_response_internal_event","tentative_agent_response","_this5","Object","hasOwnProperty","call","client_tool_call","tool_name","_temp","parameters","result","formattedResult","JSON","stringify","String","tool_call_id","is_error","_catch","clientToolName","onUnhandledClientToolCall","context","console","error","getId","isOpen","setMicMuted","isMuted","getInputByteFrequencyData","getOutputByteFrequencyData","getInputVolume","getOutputVolume","sendFeedback","like","score","warn","sendContextualUpdate","text","sendUserMessage","sendUserActivity","sendMCPToolApprovalResult","toolCallId","isApproved","is_approved","BaseConnection","config","queue","disconnectionDetails","onDisconnectCallback","onMessageCallback","debug","info","callback","length","queueMicrotask","forEach","disconnect","_this$onDisconnectCal","handleMessage","push","parseFormat","format","_format$split","split","formatPart","sampleRatePart","includes","Error","sampleRate","Number","parseInt","isNaN","PACKAGE_VERSION","isValidSocketEvent","CONVERSATION_INITIATION_CLIENT_DATA_TYPE","constructOverrides","_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","WebSocketConnection","_BaseConnection","socket","inputFormat","outputFormat","addEventListener","setTimeout","code","parse","data","_","_inheritsLoose","create","_config$origin","_config$overrides","_config$overrides2","url","origin","version","client","signedUrl","separator","agentId","protocols","authorization","WebSocket","_socket","send","once","conversation_initiation_metadata_event","conversationConfig","conversation_id","agent_output_audio_format","user_input_audio_format","_socket2","WebRTCConnection","room","isConnected","setupRoomEventListeners","conversationToken","_temp2","_result3","Room","Date","now","connect","livekitUrl","onConnected","off","RoomEvent","Connected","on","name","localParticipant","setMicrophoneEnabled","_exit","fetch","ok","statusText","json","token","msg","Disconnected","CloseEvent","toString","ConnectionStateChanged","state","ConnectionState","Event","DataReceived","payload","participant","TextDecoder","decode","TrackSubscribed","track","publication","kind","Track","Kind","Audio","identity","audioElement","attach","autoplay","controls","style","display","document","body","appendChild","_this4","_temp3","TextEncoder","encode","publishData","reliable","getRoom","createConnection","connectionType","determineConnectionType","isIosDevice","navigator","platform","userAgent","applyDelay","delayConfig","default","android","_delayConfig$android","delay","test","_delayConfig$ios","ios","TextConversation","_BaseConversation","apply","arguments","startSession","fullOptions","connectionDelay","_createConnection","_connection","base64ToArrayBuffer","base64","binaryString","window","atob","len","bytes","i","charCodeAt","buffer","URLCache","Map","createWorkletModuleLoader","sourceCode","worklet","_result","moduleURL","btoa","addModule","set","get","blob","Blob","blobURL","URL","createObjectURL","revokeObjectURL","loadRawAudioProcessor","Input","analyser","inputStream","preferHeadphonesForIosDevices","_temp4","audioWorklet","mediaDevices","getUserMedia","audio","_navigator$mediaDevic","createMediaStreamSource","AudioWorkletNode","port","postMessage","resume","supportsSampleRateConstraint","getSupportedConstraints","AudioContext","createAnalyser","ideal","echoCancellation","noiseSuppression","enumerateDevices","availableDevices","idealDevice","find","d","keyword","label","toLowerCase","deviceId","_inputStream","_context","getTracks","stop","setMuted","loadAudioConcatProcessor","Output","gain","createGain","destination","VoiceConversation","input","output","wakeLock","inputFrequencyData","outputFrequencyData","onInputWorkletMessage","b","user_audio_chunk","fromCharCode","onOutputWorkletMessage","finished","addAudioBase64Chunk","chunk","value","fadeOutAudio","exponentialRampToValueAtTime","currentTime","calculateVolume","frequencyData","onmessage","_temp5","preliminaryInputStream","all","_Promise$all","_preliminaryInputStre","_preliminaryInputStre2","_input","_output","_wakeLock","release","_options$useWakeLock","useWakeLock","request","_navigator$wakeLock$r","_temp7","_temp6","_this2$wakeLock","audio_event","audio_base_64","_this$inputFrequencyD","frequencyBinCount","getByteFrequencyData","Conversation","method","feedback","headers"],"mappings":"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"}