{"version":3,"sources":["../src/useChatData.ts","../src/state.ts","../src/utils/group.ts","../src/wavtools/analysis/constants.js","../src/wavtools/analysis/audio_analysis.js","../src/wavtools/wav_packer.js","../src/wavtools/worklets/audio_processor.js","../src/wavtools/wav_recorder.js","../src/wavtools/worklets/stream_processor.js","../src/wavtools/wav_stream_player.js","../src/useChatInteract.ts","../src/utils/message.ts","../src/context.ts","../src/api/hooks/auth/config.ts","../src/api/hooks/api.ts","../src/api/hooks/auth/state.ts","../src/api/hooks/auth/sessionManagement.ts","../src/api/hooks/auth/userManagement.ts","../src/api/hooks/auth/index.ts","../src/api/index.tsx","../src/useChatMessages.ts","../src/useChatSession.ts","../src/useAudio.ts","../src/useConfig.ts","../src/index.ts","../src/wavtools/wav_renderer.ts"],"names":["useRecoilValue","isEqual","DefaultValue","atom","selector","uuidv4","groupByDate","data","groupedData","today","a","b","item","threadDate","daysDiff","category","octave8Frequencies","octave8FrequencyLabels","noteFrequencies","noteFrequencyLabels","i","f","freq","voiceFrequencyRange","voiceFrequencies","_","voiceFrequencyLabels","AudioAnalysis","_AudioAnalysis","analyser","sampleRate","fftResult","analysisType","minDecibels","maxDecibels","nyquistFrequency","frequencyStep","outputValues","frequencies","labels","useFrequencies","aggregateOutput","frequency","amplitude","n","normalizedOutput","v","audioElement","audioBuffer","length","offlineAudioContext","source","renderQuantumInSeconds","durationInSeconds","analyze","index","suspendTime","audioContext","track","pct","WavPacker","float32Array","buffer","view","offset","s","leftBuffer","rightBuffer","tmpArray","size","arg","audio","bitsPerSample","channels","output","blob","url","AudioProcessorWorklet","script","src","AudioProcessorSrc","WavRecorder","outputToSpeakers","debug","audioData","fromSampleRate","context","arrayBuffer","values","name","_processor","message","t0","res","payload","callback","lastId","lastDevices","serializeDevices","devices","d","cb","id","permissionStatus","audioDevices","device","defaultDeviceIndex","deviceList","defaultDevice","existingIndex","deviceId","config","e","processor","event","node","chunkProcessor","chunkSize","force","exportData","StreamProcessorWorklet","StreamProcessorSrc","WavStreamPlayer","onStop","streamNode","requestId","trackId","currentTime","interrupt","trackSampleOffset","threadIdToResumeState","resumeThreadErrorState","chatProfileState","sessionIdAtom","sessionIdState","get","set","newValue","sessionState","actionState","messagesState","commandsState","tokenCountState","loadingState","askUserState","wavRecorderState","wavStreamPlayerState","audioConnectionState","isAiSpeakingState","callFnState","chatSettingsInputsState","chatSettingsDefaultValueSelector","form","input","chatSettingsValueState","elementState","tasklistState","firstUserInteraction","userState","configState","authState","threadHistoryState","setSelf","onSet","oldValue","timeGroupedThreads","sideViewState","currentThreadIdState","localStorageEffect","key","savedValue","error","isReset","mcpState","useChatData","loading","elements","tasklists","actions","session","askUser","callFn","chatSettingsInputs","chatSettingsValue","chatSettingsDefaultValue","connected","disabled","useCallback","useContext","useResetRecoilState","useSetRecoilState","nestMessages","messages","nestedMessages","addMessage","isLastMessage","hasMessageById","updateMessageById","addMessageToParent","addIndentMessage","indent","newMessage","currentIndentation","nextMessages","msg","parentId","findMessageById","messageId","foundMessage","updatedMessage","deleteMessageById","updateMessageContentById","updatedContent","isSequence","isInput","createContext","useEffect","useMemo","useSWR","SWRConfig","useRecoilState","useAuthState","authConfig","setAuthConfig","user","setUser","setThreadHistory","fetcher","client","endpoint","cloneClient","newClient","ChainlitAPI","useApi","path","swrConfig","ChainlitContext","memoizedFetcher","args","err","useApiClient","swrKey","useAuthConfig","authConfigData","isLoading","useSessionManagement","apiClient","reload","useUserManagement","userData","setUserFromAPI","useAuth","logout","isReady","ClientError","status","detail","APIBase","httpEndpoint","type","on401","onError","method","signal","headers","body","token","feedback","feedbackId","pagination","filter","threadId","file","onProgress","sessionId","xhr","promise","resolve","reject","formData","percentage","response","contentType","action","element","fullCommand","queryParams","theme","provider","defaultChainlitContext","useChatInteract","resetChatSettings","resetSessionId","resetChatSettingsValue","setFirstUserInteraction","setLoading","setMessages","setElements","setTasklists","setActions","setTokenCount","setIdToResume","setSideView","setCurrentThreadId","clear","sendMessage","fileReferences","oldMessages","editMessage","windowMessage","startAudioStream","sendAudioChunk","isStart","mimeType","elapsedTime","endAudioStream","replyMessage","updateChatSettings","stopTask","m","useChatMessages","firstInteraction","debounce","io","toast","useChatSession","setSession","setIsAiSpeaking","setAudioConnection","setChatSettingsValue","setMcps","wavStreamPlayer","wavRecorder","setAskUser","setCallFn","setCommands","setChatSettingsInputs","chatProfile","setChatProfile","idToResume","setThreadResumeError","currentThreadId","_connect","transports","userEnv","protocol","host","pathname","uri","socket","old","prev","mcp","success","existingMcp","state","isFirstChunk","startTime","chunk","thread","step","spec","inputs","commands","title","remove","count","connect","disconnect","useAudio","audioConnection","isAiSpeaking","startConversation","endConversation","useConfig","setConfig","isAuthenticated","language","Socket","dataMap","normalizeArray","downsamplePeaks","memoize","cache","mKey","dKey","result","low","high","t","WavRenderer","ctx","cssWidth","cssHeight","color","pointCount","barWidth","barSpacing","center","points","height","x","y","radius"],"mappings":"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","sourcesContent":["import { useRecoilValue } from 'recoil';\n\nimport {\n  actionState,\n  askUserState,\n  callFnState,\n  chatSettingsDefaultValueSelector,\n  chatSettingsInputsState,\n  chatSettingsValueState,\n  elementState,\n  loadingState,\n  sessionState,\n  tasklistState\n} from './state';\n\nexport interface IToken {\n  id: number | string;\n  token: string;\n  isSequence: boolean;\n  isInput: boolean;\n}\n\nconst useChatData = () => {\n  const loading = useRecoilValue(loadingState);\n  const elements = useRecoilValue(elementState);\n  const tasklists = useRecoilValue(tasklistState);\n  const actions = useRecoilValue(actionState);\n  const session = useRecoilValue(sessionState);\n  const askUser = useRecoilValue(askUserState);\n  const callFn = useRecoilValue(callFnState);\n  const chatSettingsInputs = useRecoilValue(chatSettingsInputsState);\n  const chatSettingsValue = useRecoilValue(chatSettingsValueState);\n  const chatSettingsDefaultValue = useRecoilValue(\n    chatSettingsDefaultValueSelector\n  );\n\n  const connected = session?.socket.connected && !session?.error;\n  const disabled =\n    !connected ||\n    loading ||\n    askUser?.spec.type === 'file' ||\n    askUser?.spec.type === 'action';\n\n  return {\n    actions,\n    askUser,\n    callFn,\n    chatSettingsDefaultValue,\n    chatSettingsInputs,\n    chatSettingsValue,\n    connected,\n    disabled,\n    elements,\n    error: session?.error,\n    loading,\n    tasklists\n  };\n};\n\nexport { useChatData };\n","import { isEqual } from 'lodash';\nimport { AtomEffect, DefaultValue, atom, selector } from 'recoil';\nimport { Socket } from 'socket.io-client';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { ICommand } from './types/command';\n\nimport {\n  IAction,\n  IAsk,\n  IAuthConfig,\n  ICallFn,\n  IChainlitConfig,\n  IMcp,\n  IMessageElement,\n  IStep,\n  ITasklistElement,\n  IUser,\n  ThreadHistory\n} from './types';\nimport { groupByDate } from './utils/group';\nimport { WavRecorder, WavStreamPlayer } from './wavtools';\n\nexport interface ISession {\n  socket: Socket;\n  error?: boolean;\n}\n\nexport const threadIdToResumeState = atom<string | undefined>({\n  key: 'ThreadIdToResume',\n  default: undefined\n});\n\nexport const resumeThreadErrorState = atom<string | undefined>({\n  key: 'ResumeThreadErrorState',\n  default: undefined\n});\n\nexport const chatProfileState = atom<string | undefined>({\n  key: 'ChatProfile',\n  default: undefined\n});\n\nconst sessionIdAtom = atom<string>({\n  key: 'SessionId',\n  default: uuidv4()\n});\n\nexport const sessionIdState = selector({\n  key: 'SessionIdSelector',\n  get: ({ get }) => get(sessionIdAtom),\n  set: ({ set }, newValue) =>\n    set(sessionIdAtom, newValue instanceof DefaultValue ? uuidv4() : newValue)\n});\n\nexport const sessionState = atom<ISession | undefined>({\n  key: 'Session',\n  dangerouslyAllowMutability: true,\n  default: undefined\n});\n\nexport const actionState = atom<IAction[]>({\n  key: 'Actions',\n  default: []\n});\n\nexport const messagesState = atom<IStep[]>({\n  key: 'Messages',\n  dangerouslyAllowMutability: true,\n  default: []\n});\n\nexport const commandsState = atom<ICommand[]>({\n  key: 'Commands',\n  default: []\n});\n\nexport const tokenCountState = atom<number>({\n  key: 'TokenCount',\n  default: 0\n});\n\nexport const loadingState = atom<boolean>({\n  key: 'Loading',\n  default: false\n});\n\nexport const askUserState = atom<IAsk | undefined>({\n  key: 'AskUser',\n  default: undefined\n});\n\nexport const wavRecorderState = atom({\n  key: 'WavRecorder',\n  dangerouslyAllowMutability: true,\n  default: new WavRecorder()\n});\n\nexport const wavStreamPlayerState = atom({\n  key: 'WavStreamPlayer',\n  dangerouslyAllowMutability: true,\n  default: new WavStreamPlayer()\n});\n\nexport const audioConnectionState = atom<'connecting' | 'on' | 'off'>({\n  key: 'AudioConnection',\n  default: 'off'\n});\n\nexport const isAiSpeakingState = atom({\n  key: 'isAiSpeaking',\n  default: false\n});\n\nexport const callFnState = atom<ICallFn | undefined>({\n  key: 'CallFn',\n  default: undefined\n});\n\nexport const chatSettingsInputsState = atom<any>({\n  key: 'ChatSettings',\n  default: []\n});\n\nexport const chatSettingsDefaultValueSelector = selector({\n  key: 'ChatSettingsValue/Default',\n  get: ({ get }) => {\n    const chatSettings = get(chatSettingsInputsState);\n    return chatSettings.reduce(\n      (form: { [key: string]: any }, input: any) => (\n        (form[input.id] = input.initial), form\n      ),\n      {}\n    );\n  }\n});\n\nexport const chatSettingsValueState = atom({\n  key: 'ChatSettingsValue',\n  default: chatSettingsDefaultValueSelector\n});\n\nexport const elementState = atom<IMessageElement[]>({\n  key: 'DisplayElements',\n  default: []\n});\n\nexport const tasklistState = atom<ITasklistElement[]>({\n  key: 'TasklistElements',\n  default: []\n});\n\nexport const firstUserInteraction = atom<string | undefined>({\n  key: 'FirstUserInteraction',\n  default: undefined\n});\n\nexport const userState = atom<IUser | undefined | null>({\n  key: 'User',\n  default: undefined\n});\n\nexport const configState = atom<IChainlitConfig | undefined>({\n  key: 'ChainlitConfig',\n  default: undefined\n});\n\nexport const authState = atom<IAuthConfig | undefined>({\n  key: 'AuthConfig',\n  default: undefined\n});\n\nexport const threadHistoryState = atom<ThreadHistory | undefined>({\n  key: 'ThreadHistory',\n  default: {\n    threads: undefined,\n    currentThreadId: undefined,\n    timeGroupedThreads: undefined,\n    pageInfo: undefined\n  },\n  effects: [\n    ({ setSelf, onSet }: { setSelf: any; onSet: any }) => {\n      onSet(\n        (\n          newValue: ThreadHistory | undefined,\n          oldValue: ThreadHistory | undefined\n        ) => {\n          let timeGroupedThreads = newValue?.timeGroupedThreads;\n          if (\n            newValue?.threads &&\n            !isEqual(newValue.threads, oldValue?.timeGroupedThreads)\n          ) {\n            timeGroupedThreads = groupByDate(newValue.threads);\n          }\n\n          setSelf({\n            ...newValue,\n            timeGroupedThreads\n          });\n        }\n      );\n    }\n  ]\n});\n\nexport const sideViewState = atom<\n  { title: string; elements: IMessageElement[] } | undefined\n>({\n  key: 'SideView',\n  default: undefined\n});\n\nexport const currentThreadIdState = atom<string | undefined>({\n  key: 'CurrentThreadId',\n  default: undefined\n});\n\nconst localStorageEffect =\n  <T>(key: string): AtomEffect<T> =>\n  ({ setSelf, onSet }) => {\n    // When the atom is first initialized, try to get its value from localStorage\n    const savedValue = localStorage.getItem(key);\n    if (savedValue != null) {\n      try {\n        setSelf(JSON.parse(savedValue));\n      } catch (error) {\n        console.error(\n          `Error parsing localStorage value for key \"${key}\":`,\n          error\n        );\n      }\n    }\n\n    // Subscribe to state changes and update localStorage\n    onSet((newValue, _, isReset) => {\n      if (isReset) {\n        localStorage.removeItem(key);\n      } else {\n        localStorage.setItem(key, JSON.stringify(newValue));\n      }\n    });\n  };\n\nexport const mcpState = atom<IMcp[]>({\n  key: 'Mcp',\n  default: [],\n  effects: [localStorageEffect<IMcp[]>('mcp_storage_key')]\n});\n","import { IThread } from 'src/types';\n\nexport const groupByDate = (data: IThread[]) => {\n  const groupedData: { [key: string]: IThread[] } = {};\n\n  const today = new Date();\n  today.setHours(0, 0, 0, 0);\n\n  [...data]\n    .sort(\n      (a, b) =>\n        new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n    )\n    .forEach((item) => {\n      const threadDate = new Date(item.createdAt);\n      threadDate.setHours(0, 0, 0, 0);\n\n      const daysDiff = Math.floor(\n        (today.getTime() - threadDate.getTime()) / 86400000\n      );\n\n      let category: string;\n      if (daysDiff === 0) {\n        category = 'Today';\n      } else if (daysDiff === 1) {\n        category = 'Yesterday';\n      } else if (daysDiff <= 7) {\n        category = 'Previous 7 days';\n      } else if (daysDiff <= 30) {\n        category = 'Previous 30 days';\n      } else {\n        category = threadDate.toLocaleString('default', {\n          month: 'long',\n          year: 'numeric'\n        });\n      }\n\n      groupedData[category] ??= [];\n      groupedData[category].push(item);\n    });\n\n  return groupedData;\n};\n","/**\n * Constants for help with visualization\n * Helps map frequency ranges from Fast Fourier Transform\n * to human-interpretable ranges, notably music ranges and\n * human vocal ranges.\n */\n\n// Eighth octave frequencies\nconst octave8Frequencies = [\n  4186.01, 4434.92, 4698.63, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93,\n  6644.88, 7040.0, 7458.62, 7902.13\n];\n\n// Labels for each of the above frequencies\nconst octave8FrequencyLabels = [\n  'C',\n  'C#',\n  'D',\n  'D#',\n  'E',\n  'F',\n  'F#',\n  'G',\n  'G#',\n  'A',\n  'A#',\n  'B'\n];\n\n/**\n * All note frequencies from 1st to 8th octave\n * in format \"A#8\" (A#, 8th octave)\n */\nexport const noteFrequencies = [];\nexport const noteFrequencyLabels = [];\nfor (let i = 1; i <= 8; i++) {\n  for (let f = 0; f < octave8Frequencies.length; f++) {\n    const freq = octave8Frequencies[f];\n    noteFrequencies.push(freq / Math.pow(2, 8 - i));\n    noteFrequencyLabels.push(octave8FrequencyLabels[f] + i);\n  }\n}\n\n/**\n * Subset of the note frequencies between 32 and 2000 Hz\n * 6 octave range: C1 to B6\n */\nconst voiceFrequencyRange = [32.0, 2000.0];\nexport const voiceFrequencies = noteFrequencies.filter((_, i) => {\n  return (\n    noteFrequencies[i] > voiceFrequencyRange[0] &&\n    noteFrequencies[i] < voiceFrequencyRange[1]\n  );\n});\nexport const voiceFrequencyLabels = noteFrequencyLabels.filter((_, i) => {\n  return (\n    noteFrequencies[i] > voiceFrequencyRange[0] &&\n    noteFrequencies[i] < voiceFrequencyRange[1]\n  );\n});\n","import {\n  noteFrequencies,\n  noteFrequencyLabels,\n  voiceFrequencies,\n  voiceFrequencyLabels\n} from './constants.js';\n\n/**\n * Output of AudioAnalysis for the frequency domain of the audio\n * @typedef {Object} AudioAnalysisOutputType\n * @property {Float32Array} values Amplitude of this frequency between {0, 1} inclusive\n * @property {number[]} frequencies Raw frequency bucket values\n * @property {string[]} labels Labels for the frequency bucket values\n */\n\n/**\n * Analyzes audio for visual output\n * @class\n */\nexport class AudioAnalysis {\n  /**\n   * Retrieves frequency domain data from an AnalyserNode adjusted to a decibel range\n   * returns human-readable formatting and labels\n   * @param {AnalyserNode} analyser\n   * @param {number} sampleRate\n   * @param {Float32Array} [fftResult]\n   * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n   * @param {number} [minDecibels] default -100\n   * @param {number} [maxDecibels] default -30\n   * @returns {AudioAnalysisOutputType}\n   */\n  static getFrequencies(\n    analyser,\n    sampleRate,\n    fftResult,\n    analysisType = 'frequency',\n    minDecibels = -100,\n    maxDecibels = -30\n  ) {\n    if (!fftResult) {\n      fftResult = new Float32Array(analyser.frequencyBinCount);\n      analyser.getFloatFrequencyData(fftResult);\n    }\n    const nyquistFrequency = sampleRate / 2;\n    const frequencyStep = (1 / fftResult.length) * nyquistFrequency;\n    let outputValues;\n    let frequencies;\n    let labels;\n    if (analysisType === 'music' || analysisType === 'voice') {\n      const useFrequencies =\n        analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n      const aggregateOutput = Array(useFrequencies.length).fill(minDecibels);\n      for (let i = 0; i < fftResult.length; i++) {\n        const frequency = i * frequencyStep;\n        const amplitude = fftResult[i];\n        for (let n = useFrequencies.length - 1; n >= 0; n--) {\n          if (frequency > useFrequencies[n]) {\n            aggregateOutput[n] = Math.max(aggregateOutput[n], amplitude);\n            break;\n          }\n        }\n      }\n      outputValues = aggregateOutput;\n      frequencies =\n        analysisType === 'voice' ? voiceFrequencies : noteFrequencies;\n      labels =\n        analysisType === 'voice' ? voiceFrequencyLabels : noteFrequencyLabels;\n    } else {\n      outputValues = Array.from(fftResult);\n      frequencies = outputValues.map((_, i) => frequencyStep * i);\n      labels = frequencies.map((f) => `${f.toFixed(2)} Hz`);\n    }\n    // We normalize to {0, 1}\n    const normalizedOutput = outputValues.map((v) => {\n      return Math.max(\n        0,\n        Math.min((v - minDecibels) / (maxDecibels - minDecibels), 1)\n      );\n    });\n    const values = new Float32Array(normalizedOutput);\n    return {\n      values,\n      frequencies,\n      labels\n    };\n  }\n\n  /**\n   * Creates a new AudioAnalysis instance for an HTMLAudioElement\n   * @param {HTMLAudioElement} audioElement\n   * @param {AudioBuffer|null} [audioBuffer] If provided, will cache all frequency domain data from the buffer\n   * @returns {AudioAnalysis}\n   */\n  constructor(audioElement, audioBuffer = null) {\n    this.fftResults = [];\n    if (audioBuffer) {\n      /**\n       * Modified from\n       * https://stackoverflow.com/questions/75063715/using-the-web-audio-api-to-analyze-a-song-without-playing\n       *\n       * We do this to populate FFT values for the audio if provided an `audioBuffer`\n       * The reason to do this is that Safari fails when using `createMediaElementSource`\n       * This has a non-zero RAM cost so we only opt-in to run it on Safari, Chrome is better\n       */\n      const { length, sampleRate } = audioBuffer;\n      const offlineAudioContext = new OfflineAudioContext({\n        length,\n        sampleRate\n      });\n      const source = offlineAudioContext.createBufferSource();\n      source.buffer = audioBuffer;\n      const analyser = offlineAudioContext.createAnalyser();\n      analyser.fftSize = 8192;\n      analyser.smoothingTimeConstant = 0.1;\n      source.connect(analyser);\n      // limit is :: 128 / sampleRate;\n      // but we just want 60fps - cuts ~1s from 6MB to 1MB of RAM\n      const renderQuantumInSeconds = 1 / 60;\n      const durationInSeconds = length / sampleRate;\n      const analyze = (index) => {\n        const suspendTime = renderQuantumInSeconds * index;\n        if (suspendTime < durationInSeconds) {\n          offlineAudioContext.suspend(suspendTime).then(() => {\n            const fftResult = new Float32Array(analyser.frequencyBinCount);\n            analyser.getFloatFrequencyData(fftResult);\n            this.fftResults.push(fftResult);\n            analyze(index + 1);\n          });\n        }\n        if (index === 1) {\n          offlineAudioContext.startRendering();\n        } else {\n          offlineAudioContext.resume();\n        }\n      };\n      source.start(0);\n      analyze(1);\n      this.audio = audioElement;\n      this.context = offlineAudioContext;\n      this.analyser = analyser;\n      this.sampleRate = sampleRate;\n      this.audioBuffer = audioBuffer;\n    } else {\n      const audioContext = new AudioContext();\n      const track = audioContext.createMediaElementSource(audioElement);\n      const analyser = audioContext.createAnalyser();\n      analyser.fftSize = 8192;\n      analyser.smoothingTimeConstant = 0.1;\n      track.connect(analyser);\n      analyser.connect(audioContext.destination);\n      this.audio = audioElement;\n      this.context = audioContext;\n      this.analyser = analyser;\n      this.sampleRate = this.context.sampleRate;\n      this.audioBuffer = null;\n    }\n  }\n\n  /**\n   * Gets the current frequency domain data from the playing audio track\n   * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n   * @param {number} [minDecibels] default -100\n   * @param {number} [maxDecibels] default -30\n   * @returns {AudioAnalysisOutputType}\n   */\n  getFrequencies(\n    analysisType = 'frequency',\n    minDecibels = -100,\n    maxDecibels = -30\n  ) {\n    let fftResult = null;\n    if (this.audioBuffer && this.fftResults.length) {\n      const pct = this.audio.currentTime / this.audio.duration;\n      const index = Math.min(\n        (pct * this.fftResults.length) | 0,\n        this.fftResults.length - 1\n      );\n      fftResult = this.fftResults[index];\n    }\n    return AudioAnalysis.getFrequencies(\n      this.analyser,\n      this.sampleRate,\n      fftResult,\n      analysisType,\n      minDecibels,\n      maxDecibels\n    );\n  }\n\n  /**\n   * Resume the internal AudioContext if it was suspended due to the lack of\n   * user interaction when the AudioAnalysis was instantiated.\n   * @returns {Promise<true>}\n   */\n  async resumeIfSuspended() {\n    if (this.context.state === 'suspended') {\n      await this.context.resume();\n    }\n    return true;\n  }\n}\n\nglobalThis.AudioAnalysis = AudioAnalysis;\n","/**\n * Raw wav audio file contents\n * @typedef {Object} WavPackerAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {number} channelCount\n * @property {number} sampleRate\n * @property {number} duration\n */\n\n/**\n * Utility class for assembling PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavPacker {\n  /**\n   * Converts Float32Array of amplitude data to ArrayBuffer in Int16Array format\n   * @param {Float32Array} float32Array\n   * @returns {ArrayBuffer}\n   */\n  static floatTo16BitPCM(float32Array) {\n    const buffer = new ArrayBuffer(float32Array.length * 2);\n    const view = new DataView(buffer);\n    let offset = 0;\n    for (let i = 0; i < float32Array.length; i++, offset += 2) {\n      let s = Math.max(-1, Math.min(1, float32Array[i]));\n      view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n    }\n    return buffer;\n  }\n\n  /**\n   * Concatenates two ArrayBuffers\n   * @param {ArrayBuffer} leftBuffer\n   * @param {ArrayBuffer} rightBuffer\n   * @returns {ArrayBuffer}\n   */\n  static mergeBuffers(leftBuffer, rightBuffer) {\n    const tmpArray = new Uint8Array(\n      leftBuffer.byteLength + rightBuffer.byteLength\n    );\n    tmpArray.set(new Uint8Array(leftBuffer), 0);\n    tmpArray.set(new Uint8Array(rightBuffer), leftBuffer.byteLength);\n    return tmpArray.buffer;\n  }\n\n  /**\n   * Packs data into an Int16 format\n   * @private\n   * @param {number} size 0 = 1x Int16, 1 = 2x Int16\n   * @param {number} arg value to pack\n   * @returns\n   */\n  _packData(size, arg) {\n    return [\n      new Uint8Array([arg, arg >> 8]),\n      new Uint8Array([arg, arg >> 8, arg >> 16, arg >> 24])\n    ][size];\n  }\n\n  /**\n   * Packs audio into \"audio/wav\" Blob\n   * @param {number} sampleRate\n   * @param {{bitsPerSample: number, channels: Array<Float32Array>, data: Int16Array}} audio\n   * @returns {WavPackerAudioType}\n   */\n  pack(sampleRate, audio) {\n    if (!audio?.bitsPerSample) {\n      throw new Error(`Missing \"bitsPerSample\"`);\n    } else if (!audio?.channels) {\n      throw new Error(`Missing \"channels\"`);\n    } else if (!audio?.data) {\n      throw new Error(`Missing \"data\"`);\n    }\n    const { bitsPerSample, channels, data } = audio;\n    const output = [\n      // Header\n      'RIFF',\n      this._packData(\n        1,\n        4 + (8 + 24) /* chunk 1 length */ + (8 + 8) /* chunk 2 length */\n      ), // Length\n      'WAVE',\n      // chunk 1\n      'fmt ', // Sub-chunk identifier\n      this._packData(1, 16), // Chunk length\n      this._packData(0, 1), // Audio format (1 is linear quantization)\n      this._packData(0, channels.length),\n      this._packData(1, sampleRate),\n      this._packData(1, (sampleRate * channels.length * bitsPerSample) / 8), // Byte rate\n      this._packData(0, (channels.length * bitsPerSample) / 8),\n      this._packData(0, bitsPerSample),\n      // chunk 2\n      'data', // Sub-chunk identifier\n      this._packData(\n        1,\n        (channels[0].length * channels.length * bitsPerSample) / 8\n      ), // Chunk length\n      data\n    ];\n    const blob = new Blob(output, { type: 'audio/mpeg' });\n    const url = URL.createObjectURL(blob);\n    return {\n      blob,\n      url,\n      channelCount: channels.length,\n      sampleRate,\n      duration: data.byteLength / (channels.length * sampleRate * 2)\n    };\n  }\n}\n\nglobalThis.WavPacker = WavPacker;\n","const AudioProcessorWorklet = `\nclass AudioProcessor extends AudioWorkletProcessor {\n\n  constructor() {\n    super();\n    this.port.onmessage = this.receive.bind(this);\n    this.initialize();\n  }\n\n  initialize() {\n    this.foundAudio = false;\n    this.recording = false;\n    this.chunks = [];\n  }\n\n  /**\n   * Concatenates sampled chunks into channels\n   * Format is chunk[Left[], Right[]]\n   */\n  readChannelData(chunks, channel = -1, maxChannels = 9) {\n    let channelLimit;\n    if (channel !== -1) {\n      if (chunks[0] && chunks[0].length - 1 < channel) {\n        throw new Error(\n          \\`Channel \\${channel} out of range: max \\${chunks[0].length}\\`\n        );\n      }\n      channelLimit = channel + 1;\n    } else {\n      channel = 0;\n      channelLimit = Math.min(chunks[0] ? chunks[0].length : 1, maxChannels);\n    }\n    const channels = [];\n    for (let n = channel; n < channelLimit; n++) {\n      const length = chunks.reduce((sum, chunk) => {\n        return sum + chunk[n].length;\n      }, 0);\n      const buffers = chunks.map((chunk) => chunk[n]);\n      const result = new Float32Array(length);\n      let offset = 0;\n      for (let i = 0; i < buffers.length; i++) {\n        result.set(buffers[i], offset);\n        offset += buffers[i].length;\n      }\n      channels[n] = result;\n    }\n    return channels;\n  }\n\n  /**\n   * Combines parallel audio data into correct format,\n   * channels[Left[], Right[]] to float32Array[LRLRLRLR...]\n   */\n  formatAudioData(channels) {\n    if (channels.length === 1) {\n      // Simple case is only one channel\n      const float32Array = channels[0].slice();\n      const meanValues = channels[0].slice();\n      return { float32Array, meanValues };\n    } else {\n      const float32Array = new Float32Array(\n        channels[0].length * channels.length\n      );\n      const meanValues = new Float32Array(channels[0].length);\n      for (let i = 0; i < channels[0].length; i++) {\n        const offset = i * channels.length;\n        let meanValue = 0;\n        for (let n = 0; n < channels.length; n++) {\n          float32Array[offset + n] = channels[n][i];\n          meanValue += channels[n][i];\n        }\n        meanValues[i] = meanValue / channels.length;\n      }\n      return { float32Array, meanValues };\n    }\n  }\n\n  /**\n   * Converts 32-bit float data to 16-bit integers\n   */\n  floatTo16BitPCM(float32Array) {\n    const buffer = new ArrayBuffer(float32Array.length * 2);\n    const view = new DataView(buffer);\n    let offset = 0;\n    for (let i = 0; i < float32Array.length; i++, offset += 2) {\n      let s = Math.max(-1, Math.min(1, float32Array[i]));\n      view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);\n    }\n    return buffer;\n  }\n\n  /**\n   * Retrieves the most recent amplitude values from the audio stream\n   * @param {number} channel\n   */\n  getValues(channel = -1) {\n    const channels = this.readChannelData(this.chunks, channel);\n    const { meanValues } = this.formatAudioData(channels);\n    return { meanValues, channels };\n  }\n\n  /**\n   * Exports chunks as an audio/wav file\n   */\n  export() {\n    const channels = this.readChannelData(this.chunks);\n    const { float32Array, meanValues } = this.formatAudioData(channels);\n    const audioData = this.floatTo16BitPCM(float32Array);\n    return {\n      meanValues: meanValues,\n      audio: {\n        bitsPerSample: 16,\n        channels: channels,\n        data: audioData,\n      },\n    };\n  }\n\n  receive(e) {\n    const { event, id } = e.data;\n    let receiptData = {};\n    switch (event) {\n      case 'start':\n        this.recording = true;\n        break;\n      case 'stop':\n        this.recording = false;\n        break;\n      case 'clear':\n        this.initialize();\n        break;\n      case 'export':\n        receiptData = this.export();\n        break;\n      case 'read':\n        receiptData = this.getValues();\n        break;\n      default:\n        break;\n    }\n    // Always send back receipt\n    this.port.postMessage({ event: 'receipt', id, data: receiptData });\n  }\n\n  sendChunk(chunk) {\n    const channels = this.readChannelData([chunk]);\n    const { float32Array, meanValues } = this.formatAudioData(channels);\n    const rawAudioData = this.floatTo16BitPCM(float32Array);\n    const monoAudioData = this.floatTo16BitPCM(meanValues);\n    this.port.postMessage({\n      event: 'chunk',\n      data: {\n        mono: monoAudioData,\n        raw: rawAudioData,\n      },\n    });\n  }\n\n  process(inputList, outputList, parameters) {\n    // Copy input to output (e.g. speakers)\n    // Note that this creates choppy sounds with Mac products\n    const sourceLimit = Math.min(inputList.length, outputList.length);\n    for (let inputNum = 0; inputNum < sourceLimit; inputNum++) {\n      const input = inputList[inputNum];\n      const output = outputList[inputNum];\n      const channelCount = Math.min(input.length, output.length);\n      for (let channelNum = 0; channelNum < channelCount; channelNum++) {\n        input[channelNum].forEach((sample, i) => {\n          output[channelNum][i] = sample;\n        });\n      }\n    }\n    const inputs = inputList[0];\n    // There's latency at the beginning of a stream before recording starts\n    // Make sure we actually receive audio data before we start storing chunks\n    let sliceIndex = 0;\n    if (!this.foundAudio) {\n      for (const channel of inputs) {\n        sliceIndex = 0; // reset for each channel\n        if (this.foundAudio) {\n          break;\n        }\n        if (channel) {\n          for (const value of channel) {\n            if (value !== 0) {\n              // find only one non-zero entry in any channel\n              this.foundAudio = true;\n              break;\n            } else {\n              sliceIndex++;\n            }\n          }\n        }\n      }\n    }\n    if (inputs && inputs[0] && this.foundAudio && this.recording) {\n      // We need to copy the TypedArray, because the \\`process\\`\n      // internals will reuse the same buffer to hold each input\n      const chunk = inputs.map((input) => input.slice(sliceIndex));\n      this.chunks.push(chunk);\n      this.sendChunk(chunk);\n    }\n    return true;\n  }\n}\n\nregisterProcessor('audio_processor', AudioProcessor);\n`;\n\nconst script = new Blob([AudioProcessorWorklet], {\n  type: 'application/javascript'\n});\nconst src = URL.createObjectURL(script);\nexport const AudioProcessorSrc = src;\n","import { AudioAnalysis } from './analysis/audio_analysis.js';\nimport { WavPacker } from './wav_packer.js';\nimport { AudioProcessorSrc } from './worklets/audio_processor.js';\n\n/**\n * Decodes audio into a wav file\n * @typedef {Object} DecodedAudioType\n * @property {Blob} blob\n * @property {string} url\n * @property {Float32Array} values\n * @property {AudioBuffer} audioBuffer\n */\n\n/**\n * Records live stream of user audio as PCM16 \"audio/wav\" data\n * @class\n */\nexport class WavRecorder {\n  /**\n   * Create a new WavRecorder instance\n   * @param {{sampleRate?: number, outputToSpeakers?: boolean, debug?: boolean}} [options]\n   * @returns {WavRecorder}\n   */\n  constructor({\n    sampleRate = 24000,\n    outputToSpeakers = false,\n    debug = false\n  } = {}) {\n    // Script source\n    this.scriptSrc = AudioProcessorSrc;\n    // Config\n    this.sampleRate = sampleRate;\n    this.outputToSpeakers = outputToSpeakers;\n    this.debug = !!debug;\n    this._deviceChangeCallback = null;\n    this._devices = [];\n    // State variables\n    this.stream = null;\n    this.processor = null;\n    this.source = null;\n    this.node = null;\n    this.recording = false;\n    // Event handling with AudioWorklet\n    this._lastEventId = 0;\n    this.eventReceipts = {};\n    this.eventTimeout = 5000;\n    // Process chunks of audio\n    this._chunkProcessor = () => {};\n    this._chunkProcessorSize = void 0;\n    this._chunkProcessorBuffer = {\n      raw: new ArrayBuffer(0),\n      mono: new ArrayBuffer(0)\n    };\n  }\n\n  /**\n   * Decodes audio data from multiple formats to a Blob, url, Float32Array and AudioBuffer\n   * @param {Blob|Float32Array|Int16Array|ArrayBuffer|number[]} audioData\n   * @param {number} sampleRate\n   * @param {number} fromSampleRate\n   * @returns {Promise<DecodedAudioType>}\n   */\n  static async decode(audioData, sampleRate = 24000, fromSampleRate = -1) {\n    const context = new AudioContext({ sampleRate });\n    let arrayBuffer;\n    let blob;\n    if (audioData instanceof Blob) {\n      if (fromSampleRate !== -1) {\n        throw new Error(\n          `Can not specify \"fromSampleRate\" when reading from Blob`\n        );\n      }\n      blob = audioData;\n      arrayBuffer = await blob.arrayBuffer();\n    } else if (audioData instanceof ArrayBuffer) {\n      if (fromSampleRate !== -1) {\n        throw new Error(\n          `Can not specify \"fromSampleRate\" when reading from ArrayBuffer`\n        );\n      }\n      arrayBuffer = audioData;\n      blob = new Blob([arrayBuffer], { type: 'audio/wav' });\n    } else {\n      let float32Array;\n      let data;\n      if (audioData instanceof Int16Array) {\n        data = audioData;\n        float32Array = new Float32Array(audioData.length);\n        for (let i = 0; i < audioData.length; i++) {\n          float32Array[i] = audioData[i] / 0x8000;\n        }\n      } else if (audioData instanceof Float32Array) {\n        float32Array = audioData;\n      } else if (audioData instanceof Array) {\n        float32Array = new Float32Array(audioData);\n      } else {\n        throw new Error(\n          `\"audioData\" must be one of: Blob, Float32Arrray, Int16Array, ArrayBuffer, Array<number>`\n        );\n      }\n      if (fromSampleRate === -1) {\n        throw new Error(\n          `Must specify \"fromSampleRate\" when reading from Float32Array, In16Array or Array`\n        );\n      } else if (fromSampleRate < 3000) {\n        throw new Error(`Minimum \"fromSampleRate\" is 3000 (3kHz)`);\n      }\n      if (!data) {\n        data = WavPacker.floatTo16BitPCM(float32Array);\n      }\n      const audio = {\n        bitsPerSample: 16,\n        channels: [float32Array],\n        data\n      };\n      const packer = new WavPacker();\n      const result = packer.pack(fromSampleRate, audio);\n      blob = result.blob;\n      arrayBuffer = await blob.arrayBuffer();\n    }\n    const audioBuffer = await context.decodeAudioData(arrayBuffer);\n    const values = audioBuffer.getChannelData(0);\n    const url = URL.createObjectURL(blob);\n    return {\n      blob,\n      url,\n      values,\n      audioBuffer\n    };\n  }\n\n  /**\n   * Logs data in debug mode\n   * @param {...any} arguments\n   * @returns {true}\n   */\n  log() {\n    if (this.debug) {\n      this.log(...arguments);\n    }\n    return true;\n  }\n\n  /**\n   * Retrieves the current sampleRate for the recorder\n   * @returns {number}\n   */\n  getSampleRate() {\n    return this.sampleRate;\n  }\n\n  /**\n   * Retrieves the current status of the recording\n   * @returns {\"ended\"|\"paused\"|\"recording\"}\n   */\n  getStatus() {\n    if (!this.processor) {\n      return 'ended';\n    } else if (!this.recording) {\n      return 'paused';\n    } else {\n      return 'recording';\n    }\n  }\n\n  /**\n   * Sends an event to the AudioWorklet\n   * @private\n   * @param {string} name\n   * @param {{[key: string]: any}} data\n   * @param {AudioWorkletNode} [_processor]\n   * @returns {Promise<{[key: string]: any}>}\n   */\n  async _event(name, data = {}, _processor = null) {\n    _processor = _processor || this.processor;\n    if (!_processor) {\n      throw new Error('Can not send events without recording first');\n    }\n    const message = {\n      event: name,\n      id: this._lastEventId++,\n      data\n    };\n    _processor.port.postMessage(message);\n    const t0 = new Date().valueOf();\n    while (!this.eventReceipts[message.id]) {\n      if (new Date().valueOf() - t0 > this.eventTimeout) {\n        throw new Error(`Timeout waiting for \"${name}\" event`);\n      }\n      await new Promise((res) => setTimeout(() => res(true), 1));\n    }\n    const payload = this.eventReceipts[message.id];\n    delete this.eventReceipts[message.id];\n    return payload;\n  }\n\n  /**\n   * Sets device change callback, remove if callback provided is `null`\n   * @param {(Array<MediaDeviceInfo & {default: boolean}>): void|null} callback\n   * @returns {true}\n   */\n  listenForDeviceChange(callback) {\n    if (callback === null && this._deviceChangeCallback) {\n      navigator.mediaDevices.removeEventListener(\n        'devicechange',\n        this._deviceChangeCallback\n      );\n      this._deviceChangeCallback = null;\n    } else if (callback !== null) {\n      // Basically a debounce; we only want this called once when devices change\n      // And we only want the most recent callback() to be executed\n      // if a few are operating at the same time\n      let lastId = 0;\n      let lastDevices = [];\n      const serializeDevices = (devices) =>\n        devices\n          .map((d) => d.deviceId)\n          .sort()\n          .join(',');\n      const cb = async () => {\n        let id = ++lastId;\n        const devices = await this.listDevices();\n        if (id === lastId) {\n          if (serializeDevices(lastDevices) !== serializeDevices(devices)) {\n            lastDevices = devices;\n            callback(devices.slice());\n          }\n        }\n      };\n      navigator.mediaDevices.addEventListener('devicechange', cb);\n      cb();\n      this._deviceChangeCallback = cb;\n    }\n    return true;\n  }\n\n  /**\n   * Manually request permission to use the microphone\n   * @returns {Promise<true>}\n   */\n  async requestPermission() {\n    const permissionStatus = await navigator.permissions.query({\n      name: 'microphone'\n    });\n    if (permissionStatus.state === 'denied') {\n      window.alert('You must grant microphone access to use this feature.');\n    } else if (permissionStatus.state === 'prompt') {\n      try {\n        const stream = await navigator.mediaDevices.getUserMedia({\n          audio: true\n        });\n        const tracks = stream.getTracks();\n        tracks.forEach((track) => track.stop());\n      } catch (e) {\n        window.alert('You must grant microphone access to use this feature.');\n      }\n    }\n    return true;\n  }\n\n  /**\n   * List all eligible devices for recording, will request permission to use microphone\n   * @returns {Promise<Array<MediaDeviceInfo & {default: boolean}>>}\n   */\n  async listDevices() {\n    if (\n      !navigator.mediaDevices ||\n      !('enumerateDevices' in navigator.mediaDevices)\n    ) {\n      throw new Error('Could not request user devices');\n    }\n    await this.requestPermission();\n    const devices = await navigator.mediaDevices.enumerateDevices();\n    const audioDevices = devices.filter(\n      (device) => device.kind === 'audioinput'\n    );\n    const defaultDeviceIndex = audioDevices.findIndex(\n      (device) => device.deviceId === 'default'\n    );\n    const deviceList = [];\n    if (defaultDeviceIndex !== -1) {\n      let defaultDevice = audioDevices.splice(defaultDeviceIndex, 1)[0];\n      let existingIndex = audioDevices.findIndex(\n        (device) => device.groupId === defaultDevice.groupId\n      );\n      if (existingIndex !== -1) {\n        defaultDevice = audioDevices.splice(existingIndex, 1)[0];\n      }\n      defaultDevice.default = true;\n      deviceList.push(defaultDevice);\n    }\n    return deviceList.concat(audioDevices);\n  }\n\n  /**\n   * Begins a recording session and requests microphone permissions if not already granted\n   * Microphone recording indicator will appear on browser tab but status will be \"paused\"\n   * @param {string} [deviceId] if no device provided, default device will be used\n   * @returns {Promise<true>}\n   */\n  async begin(deviceId) {\n    if (this.processor) {\n      throw new Error(\n        `Already connected: please call .end() to start a new session`\n      );\n    }\n\n    if (\n      !navigator.mediaDevices ||\n      !('getUserMedia' in navigator.mediaDevices)\n    ) {\n      throw new Error('Could not request user media');\n    }\n    try {\n      const config = { audio: true };\n      if (deviceId) {\n        config.audio = { deviceId: { exact: deviceId } };\n      }\n      this.stream = await navigator.mediaDevices.getUserMedia(config);\n    } catch (err) {\n      throw new Error('Could not start media stream');\n    }\n\n    const context = new AudioContext({ sampleRate: this.sampleRate });\n    const source = context.createMediaStreamSource(this.stream);\n    // Load and execute the module script.\n    try {\n      await context.audioWorklet.addModule(this.scriptSrc);\n    } catch (e) {\n      console.error(e);\n      throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n    }\n    const processor = new AudioWorkletNode(context, 'audio_processor');\n    processor.port.onmessage = (e) => {\n      const { event, id, data } = e.data;\n      if (event === 'receipt') {\n        this.eventReceipts[id] = data;\n      } else if (event === 'chunk') {\n        if (this._chunkProcessorSize) {\n          const buffer = this._chunkProcessorBuffer;\n          this._chunkProcessorBuffer = {\n            raw: WavPacker.mergeBuffers(buffer.raw, data.raw),\n            mono: WavPacker.mergeBuffers(buffer.mono, data.mono)\n          };\n          if (\n            this._chunkProcessorBuffer.mono.byteLength >=\n            this._chunkProcessorSize\n          ) {\n            this._chunkProcessor(this._chunkProcessorBuffer);\n            this._chunkProcessorBuffer = {\n              raw: new ArrayBuffer(0),\n              mono: new ArrayBuffer(0)\n            };\n          }\n        } else {\n          this._chunkProcessor(data);\n        }\n      }\n    };\n\n    const node = source.connect(processor);\n    const analyser = context.createAnalyser();\n    analyser.fftSize = 8192;\n    analyser.smoothingTimeConstant = 0.1;\n    node.connect(analyser);\n    if (this.outputToSpeakers) {\n      // eslint-disable-next-line no-console\n      console.warn(\n        'Warning: Output to speakers may affect sound quality,\\n' +\n          'especially due to system audio feedback preventative measures.\\n' +\n          'use only for debugging'\n      );\n      analyser.connect(context.destination);\n    }\n\n    this.source = source;\n    this.node = node;\n    this.analyser = analyser;\n    this.processor = processor;\n    return true;\n  }\n\n  /**\n   * Gets the current frequency domain data from the recording track\n   * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n   * @param {number} [minDecibels] default -100\n   * @param {number} [maxDecibels] default -30\n   * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n   */\n  getFrequencies(\n    analysisType = 'frequency',\n    minDecibels = -100,\n    maxDecibels = -30\n  ) {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    }\n    return AudioAnalysis.getFrequencies(\n      this.analyser,\n      this.sampleRate,\n      null,\n      analysisType,\n      minDecibels,\n      maxDecibels\n    );\n  }\n\n  /**\n   * Pauses the recording\n   * Keeps microphone stream open but halts storage of audio\n   * @returns {Promise<true>}\n   */\n  async pause() {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    } else if (!this.recording) {\n      throw new Error('Already paused: please call .record() first');\n    }\n    if (this._chunkProcessorBuffer.raw.byteLength) {\n      this._chunkProcessor(this._chunkProcessorBuffer);\n    }\n    this.log('Pausing ...');\n    await this._event('stop');\n    this.recording = false;\n    return true;\n  }\n\n  /**\n   * Start recording stream and storing to memory from the connected audio source\n   * @param {(data: { mono: Int16Array; raw: Int16Array }) => any} [chunkProcessor]\n   * @param {number} [chunkSize] chunkProcessor will not be triggered until this size threshold met in mono audio\n   * @returns {Promise<true>}\n   */\n  async record(chunkProcessor = () => {}, chunkSize = 8192) {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    } else if (this.recording) {\n      throw new Error('Already recording: please call .pause() first');\n    } else if (typeof chunkProcessor !== 'function') {\n      throw new Error(`chunkProcessor must be a function`);\n    }\n    this._chunkProcessor = chunkProcessor;\n    this._chunkProcessorSize = chunkSize;\n    this._chunkProcessorBuffer = {\n      raw: new ArrayBuffer(0),\n      mono: new ArrayBuffer(0)\n    };\n    this.log('Recording ...');\n    await this._event('start');\n    this.recording = true;\n    return true;\n  }\n\n  /**\n   * Clears the audio buffer, empties stored recording\n   * @returns {Promise<true>}\n   */\n  async clear() {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    }\n    await this._event('clear');\n    return true;\n  }\n\n  /**\n   * Reads the current audio stream data\n   * @returns {Promise<{meanValues: Float32Array, channels: Array<Float32Array>}>}\n   */\n  async read() {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    }\n    this.log('Reading ...');\n    const result = await this._event('read');\n    return result;\n  }\n\n  /**\n   * Saves the current audio stream to a file\n   * @param {boolean} [force] Force saving while still recording\n   * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n   */\n  async save(force = false) {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    }\n    if (!force && this.recording) {\n      throw new Error(\n        'Currently recording: please call .pause() first, or call .save(true) to force'\n      );\n    }\n    this.log('Exporting ...');\n    const exportData = await this._event('export');\n    const packer = new WavPacker();\n    const result = packer.pack(this.sampleRate, exportData.audio);\n    return result;\n  }\n\n  /**\n   * Ends the current recording session and saves the result\n   * @returns {Promise<import('./wav_packer.js').WavPackerAudioType>}\n   */\n  async end() {\n    if (!this.processor) {\n      throw new Error('Session ended: please call .begin() first');\n    }\n\n    const _processor = this.processor;\n\n    this.log('Stopping ...');\n    await this._event('stop');\n    this.recording = false;\n    const tracks = this.stream.getTracks();\n    tracks.forEach((track) => track.stop());\n\n    this.log('Exporting ...');\n    const exportData = await this._event('export', {}, _processor);\n\n    this.processor.disconnect();\n    this.source.disconnect();\n    this.node.disconnect();\n    this.analyser.disconnect();\n    this.stream = null;\n    this.processor = null;\n    this.source = null;\n    this.node = null;\n\n    const packer = new WavPacker();\n    const result = packer.pack(this.sampleRate, exportData.audio);\n    return result;\n  }\n\n  /**\n   * Performs a full cleanup of WavRecorder instance\n   * Stops actively listening via microphone and removes existing listeners\n   * @returns {Promise<true>}\n   */\n  async quit() {\n    this.listenForDeviceChange(null);\n    if (this.processor) {\n      await this.end();\n    }\n    return true;\n  }\n}\n\nglobalThis.WavRecorder = WavRecorder;\n","export const StreamProcessorWorklet = `\nclass StreamProcessor extends AudioWorkletProcessor {\n  constructor() {\n    super();\n    this.hasStarted = false;\n    this.hasInterrupted = false;\n    this.outputBuffers = [];\n    this.bufferLength = 128;\n    this.write = { buffer: new Float32Array(this.bufferLength), trackId: null };\n    this.writeOffset = 0;\n    this.trackSampleOffsets = {};\n    this.port.onmessage = (event) => {\n      if (event.data) {\n        const payload = event.data;\n        if (payload.event === 'write') {\n          const int16Array = payload.buffer;\n          const float32Array = new Float32Array(int16Array.length);\n          for (let i = 0; i < int16Array.length; i++) {\n            float32Array[i] = int16Array[i] / 0x8000; // Convert Int16 to Float32\n          }\n          this.writeData(float32Array, payload.trackId);\n        } else if (\n          payload.event === 'offset' ||\n          payload.event === 'interrupt'\n        ) {\n          const requestId = payload.requestId;\n          const trackId = this.write.trackId;\n          const offset = this.trackSampleOffsets[trackId] || 0;\n          this.port.postMessage({\n            event: 'offset',\n            requestId,\n            trackId,\n            offset,\n          });\n          if (payload.event === 'interrupt') {\n            this.hasInterrupted = true;\n          }\n        } else {\n          throw new Error(\\`Unhandled event \"\\${payload.event}\"\\`);\n        }\n      }\n    };\n  }\n\n  writeData(float32Array, trackId = null) {\n    let { buffer } = this.write;\n    let offset = this.writeOffset;\n    for (let i = 0; i < float32Array.length; i++) {\n      buffer[offset++] = float32Array[i];\n      if (offset >= buffer.length) {\n        this.outputBuffers.push(this.write);\n        this.write = { buffer: new Float32Array(this.bufferLength), trackId };\n        buffer = this.write.buffer;\n        offset = 0;\n      }\n    }\n    this.writeOffset = offset;\n    return true;\n  }\n\n  process(inputs, outputs, parameters) {\n    const output = outputs[0];\n    const outputChannelData = output[0];\n    const outputBuffers = this.outputBuffers;\n    if (this.hasInterrupted) {\n      this.port.postMessage({ event: 'stop' });\n      return false;\n    } else if (outputBuffers.length) {\n      this.hasStarted = true;\n      const { buffer, trackId } = outputBuffers.shift();\n      for (let i = 0; i < outputChannelData.length; i++) {\n        outputChannelData[i] = buffer[i] || 0;\n      }\n      if (trackId) {\n        this.trackSampleOffsets[trackId] =\n          this.trackSampleOffsets[trackId] || 0;\n        this.trackSampleOffsets[trackId] += buffer.length;\n      }\n      return true;\n    } else if (this.hasStarted) {\n      this.port.postMessage({ event: 'stop' });\n      return false;\n    } else {\n      return true;\n    }\n  }\n}\n\nregisterProcessor('stream_processor', StreamProcessor);\n`;\n\nconst script = new Blob([StreamProcessorWorklet], {\n  type: 'application/javascript'\n});\nconst src = URL.createObjectURL(script);\nexport const StreamProcessorSrc = src;\n","import { AudioAnalysis } from './analysis/audio_analysis.js';\nimport { StreamProcessorSrc } from './worklets/stream_processor.js';\n\n/**\n * Plays audio streams received in raw PCM16 chunks from the browser\n * @class\n */\nexport class WavStreamPlayer {\n  /**\n   * Creates a new WavStreamPlayer instance\n   * @param {{sampleRate?: number}} options\n   * @returns {WavStreamPlayer}\n   */\n  constructor({ sampleRate = 24000, onStop } = {}) {\n    this.scriptSrc = StreamProcessorSrc;\n    this.onStop = onStop;\n    this.sampleRate = sampleRate;\n    this.context = null;\n    this.stream = null;\n    this.analyser = null;\n    this.trackSampleOffsets = {};\n    this.interruptedTrackIds = {};\n  }\n\n  /**\n   * Connects the audio context and enables output to speakers\n   * @returns {Promise<true>}\n   */\n  async connect() {\n    this.context = new AudioContext({ sampleRate: this.sampleRate });\n    if (this.context.state === 'suspended') {\n      await this.context.resume();\n    }\n    try {\n      await this.context.audioWorklet.addModule(this.scriptSrc);\n    } catch (e) {\n      console.error(e);\n      throw new Error(`Could not add audioWorklet module: ${this.scriptSrc}`);\n    }\n    const analyser = this.context.createAnalyser();\n    analyser.fftSize = 8192;\n    analyser.smoothingTimeConstant = 0.1;\n    this.analyser = analyser;\n    return true;\n  }\n\n  /**\n   * Gets the current frequency domain data from the playing track\n   * @param {\"frequency\"|\"music\"|\"voice\"} [analysisType]\n   * @param {number} [minDecibels] default -100\n   * @param {number} [maxDecibels] default -30\n   * @returns {import('./analysis/audio_analysis.js').AudioAnalysisOutputType}\n   */\n  getFrequencies(\n    analysisType = 'frequency',\n    minDecibels = -100,\n    maxDecibels = -30\n  ) {\n    if (!this.analyser) {\n      throw new Error('Not connected, please call .connect() first');\n    }\n    return AudioAnalysis.getFrequencies(\n      this.analyser,\n      this.sampleRate,\n      null,\n      analysisType,\n      minDecibels,\n      maxDecibels\n    );\n  }\n\n  /**\n   * Starts audio streaming\n   * @private\n   * @returns {Promise<true>}\n   */\n  _start() {\n    const streamNode = new AudioWorkletNode(this.context, 'stream_processor');\n    streamNode.connect(this.context.destination);\n    streamNode.port.onmessage = (e) => {\n      const { event } = e.data;\n      if (event === 'stop') {\n        this.onStop?.();\n        streamNode.disconnect();\n        this.stream = null;\n      } else if (event === 'offset') {\n        const { requestId, trackId, offset } = e.data;\n        const currentTime = offset / this.sampleRate;\n        this.trackSampleOffsets[requestId] = { trackId, offset, currentTime };\n      }\n    };\n    this.analyser.disconnect();\n    streamNode.connect(this.analyser);\n    this.stream = streamNode;\n    return true;\n  }\n\n  /**\n   * Adds 16BitPCM data to the currently playing audio stream\n   * You can add chunks beyond the current play point and they will be queued for play\n   * @param {ArrayBuffer|Int16Array} arrayBuffer\n   * @param {string} [trackId]\n   * @returns {Int16Array}\n   */\n  add16BitPCM(arrayBuffer, trackId = 'default') {\n    if (typeof trackId !== 'string') {\n      throw new Error(`trackId must be a string`);\n    } else if (this.interruptedTrackIds[trackId]) {\n      return;\n    }\n    if (!this.stream) {\n      this._start();\n    }\n    let buffer;\n    if (arrayBuffer instanceof Int16Array) {\n      buffer = arrayBuffer;\n    } else if (arrayBuffer instanceof ArrayBuffer) {\n      buffer = new Int16Array(arrayBuffer);\n    } else {\n      throw new Error(`argument must be Int16Array or ArrayBuffer`);\n    }\n    this.stream.port.postMessage({ event: 'write', buffer, trackId });\n    return buffer;\n  }\n\n  /**\n   * Gets the offset (sample count) of the currently playing stream\n   * @param {boolean} [interrupt]\n   * @returns {{trackId: string|null, offset: number, currentTime: number}}\n   */\n  async getTrackSampleOffset(interrupt = false) {\n    if (!this.stream) {\n      return null;\n    }\n    const requestId = crypto.randomUUID();\n    this.stream.port.postMessage({\n      event: interrupt ? 'interrupt' : 'offset',\n      requestId\n    });\n    let trackSampleOffset;\n    while (!trackSampleOffset) {\n      trackSampleOffset = this.trackSampleOffsets[requestId];\n      await new Promise((r) => setTimeout(() => r(), 1));\n    }\n    const { trackId } = trackSampleOffset;\n    if (interrupt && trackId) {\n      this.interruptedTrackIds[trackId] = true;\n    }\n    return trackSampleOffset;\n  }\n\n  /**\n   * Strips the current stream and returns the sample offset of the audio\n   * @param {boolean} [interrupt]\n   * @returns {{trackId: string|null, offset: number, currentTime: number}}\n   */\n  async interrupt() {\n    return this.getTrackSampleOffset(true);\n  }\n}\n\nglobalThis.WavStreamPlayer = WavStreamPlayer;\n","import { useCallback, useContext } from 'react';\nimport { useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil';\nimport {\n  actionState,\n  askUserState,\n  chatSettingsInputsState,\n  chatSettingsValueState,\n  currentThreadIdState,\n  elementState,\n  firstUserInteraction,\n  loadingState,\n  messagesState,\n  sessionIdState,\n  sessionState,\n  sideViewState,\n  tasklistState,\n  threadIdToResumeState,\n  tokenCountState\n} from 'src/state';\nimport { IFileRef, IStep } from 'src/types';\nimport { addMessage } from 'src/utils/message';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { ChainlitContext } from './context';\n\ntype PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\nconst useChatInteract = () => {\n  const client = useContext(ChainlitContext);\n  const session = useRecoilValue(sessionState);\n  const askUser = useRecoilValue(askUserState);\n  const sessionId = useRecoilValue(sessionIdState);\n\n  const resetChatSettings = useResetRecoilState(chatSettingsInputsState);\n  const resetSessionId = useResetRecoilState(sessionIdState);\n  const resetChatSettingsValue = useResetRecoilState(chatSettingsValueState);\n\n  const setFirstUserInteraction = useSetRecoilState(firstUserInteraction);\n  const setLoading = useSetRecoilState(loadingState);\n  const setMessages = useSetRecoilState(messagesState);\n  const setElements = useSetRecoilState(elementState);\n  const setTasklists = useSetRecoilState(tasklistState);\n  const setActions = useSetRecoilState(actionState);\n  const setTokenCount = useSetRecoilState(tokenCountState);\n  const setIdToResume = useSetRecoilState(threadIdToResumeState);\n  const setSideView = useSetRecoilState(sideViewState);\n  const setCurrentThreadId = useSetRecoilState(currentThreadIdState);\n\n  const clear = useCallback(() => {\n    session?.socket.emit('clear_session');\n    session?.socket.disconnect();\n    setIdToResume(undefined);\n    resetSessionId();\n    setFirstUserInteraction(undefined);\n    setMessages([]);\n    setElements([]);\n    setTasklists([]);\n    setActions([]);\n    setTokenCount(0);\n    resetChatSettings();\n    resetChatSettingsValue();\n    setSideView(undefined);\n    setCurrentThreadId(undefined);\n  }, [session]);\n\n  const sendMessage = useCallback(\n    (\n      message: PartialBy<IStep, 'createdAt' | 'id'>,\n      fileReferences: IFileRef[] = []\n    ) => {\n      if (!message.id) {\n        message.id = uuidv4();\n      }\n      if (!message.createdAt) {\n        message.createdAt = new Date().toISOString();\n      }\n      setMessages((oldMessages) => addMessage(oldMessages, message as IStep));\n\n      session?.socket.emit('client_message', { message, fileReferences });\n    },\n    [session?.socket]\n  );\n\n  const editMessage = useCallback(\n    (message: IStep) => {\n      session?.socket.emit('edit_message', { message });\n    },\n    [session?.socket]\n  );\n\n  const windowMessage = useCallback(\n    (data: any) => {\n      session?.socket.emit('window_message', data);\n    },\n    [session?.socket]\n  );\n\n  const startAudioStream = useCallback(() => {\n    session?.socket.emit('audio_start');\n  }, [session?.socket]);\n\n  const sendAudioChunk = useCallback(\n    (\n      isStart: boolean,\n      mimeType: string,\n      elapsedTime: number,\n      data: Int16Array\n    ) => {\n      session?.socket.emit('audio_chunk', {\n        isStart,\n        mimeType,\n        elapsedTime,\n        data\n      });\n    },\n    [session?.socket]\n  );\n\n  const endAudioStream = useCallback(() => {\n    session?.socket.emit('audio_end');\n  }, [session?.socket]);\n\n  const replyMessage = useCallback(\n    (message: IStep) => {\n      if (askUser) {\n        if (askUser.parentId) message.parentId = askUser.parentId;\n        setMessages((oldMessages) => addMessage(oldMessages, message));\n        askUser.callback(message);\n      }\n    },\n    [askUser]\n  );\n\n  const updateChatSettings = useCallback(\n    (values: object) => {\n      session?.socket.emit('chat_settings_change', values);\n    },\n    [session?.socket]\n  );\n\n  const stopTask = useCallback(() => {\n    setMessages((oldMessages) =>\n      oldMessages.map((m) => {\n        m.streaming = false;\n        return m;\n      })\n    );\n\n    setLoading(false);\n\n    session?.socket.emit('stop');\n  }, [session?.socket]);\n\n  const uploadFile = useCallback(\n    (file: File, onProgress: (progress: number) => void) => {\n      return client.uploadFile(file, onProgress, sessionId);\n    },\n    [sessionId]\n  );\n\n  return {\n    uploadFile,\n    clear,\n    replyMessage,\n    sendMessage,\n    editMessage,\n    windowMessage,\n    startAudioStream,\n    sendAudioChunk,\n    endAudioStream,\n    stopTask,\n    setIdToResume,\n    updateChatSettings\n  };\n};\n\nexport { useChatInteract };\n","import { isEqual } from 'lodash';\n\nimport { IStep } from '..';\n\nconst nestMessages = (messages: IStep[]): IStep[] => {\n  let nestedMessages: IStep[] = [];\n\n  for (const message of messages) {\n    nestedMessages = addMessage(nestedMessages, message);\n  }\n\n  return nestedMessages;\n};\n\nconst isLastMessage = (messages: IStep[], index: number) => {\n  if (messages.length - 1 === index) {\n    return true;\n  }\n\n  for (let i = index + 1; i < messages.length; i++) {\n    if (messages[i].streaming) {\n      continue;\n    } else {\n      return false;\n    }\n  }\n\n  return true;\n};\n\n// Nested messages utils\n\nconst addMessage = (messages: IStep[], message: IStep): IStep[] => {\n  if (hasMessageById(messages, message.id)) {\n    return updateMessageById(messages, message.id, message);\n  } else if ('parentId' in message && message.parentId) {\n    return addMessageToParent(messages, message.parentId, message);\n  } else if ('indent' in message && message.indent && message.indent > 0) {\n    return addIndentMessage(messages, message.indent, message);\n  } else {\n    return [...messages, message];\n  }\n};\n\nconst addIndentMessage = (\n  messages: IStep[],\n  indent: number,\n  newMessage: IStep,\n  currentIndentation: number = 0\n): IStep[] => {\n  const nextMessages = [...messages];\n\n  if (nextMessages.length === 0) {\n    return [...nextMessages, newMessage];\n  } else {\n    const index = nextMessages.length - 1;\n    const msg = nextMessages[index];\n    msg.steps = msg.steps || [];\n\n    if (currentIndentation + 1 === indent) {\n      msg.steps = [...msg.steps, newMessage];\n      nextMessages[index] = { ...msg };\n\n      return nextMessages;\n    } else {\n      msg.steps = addIndentMessage(\n        msg.steps,\n        indent,\n        newMessage,\n        currentIndentation + 1\n      );\n\n      nextMessages[index] = { ...msg };\n      return nextMessages;\n    }\n  }\n};\n\nconst addMessageToParent = (\n  messages: IStep[],\n  parentId: string,\n  newMessage: IStep\n): IStep[] => {\n  const nextMessages = [...messages];\n\n  for (let index = 0; index < nextMessages.length; index++) {\n    const msg = nextMessages[index];\n\n    if (isEqual(msg.id, parentId)) {\n      msg.steps = msg.steps ? [...msg.steps, newMessage] : [newMessage];\n      nextMessages[index] = { ...msg };\n    } else if (hasMessageById(nextMessages, parentId) && msg.steps) {\n      msg.steps = addMessageToParent(msg.steps, parentId, newMessage);\n      nextMessages[index] = { ...msg };\n    }\n  }\n\n  return nextMessages;\n};\n\nconst findMessageById = (\n  messages: IStep[],\n  messageId: string\n): IStep | undefined => {\n  for (const message of messages) {\n    if (isEqual(message.id, messageId)) {\n      return message;\n    } else if (message.steps && message.steps.length > 0) {\n      const foundMessage = findMessageById(message.steps, messageId);\n      if (foundMessage) {\n        return foundMessage;\n      }\n    }\n  }\n  return undefined;\n};\n\nconst hasMessageById = (messages: IStep[], messageId: string): boolean => {\n  return findMessageById(messages, messageId) !== undefined;\n};\n\nconst updateMessageById = (\n  messages: IStep[],\n  messageId: string,\n  updatedMessage: IStep\n): IStep[] => {\n  const nextMessages = [...messages];\n\n  for (let index = 0; index < nextMessages.length; index++) {\n    const msg = nextMessages[index];\n\n    if (isEqual(msg.id, messageId)) {\n      nextMessages[index] = { steps: msg.steps, ...updatedMessage };\n    } else if (hasMessageById(nextMessages, messageId) && msg.steps) {\n      msg.steps = updateMessageById(msg.steps, messageId, updatedMessage);\n      nextMessages[index] = { ...msg };\n    }\n  }\n\n  return nextMessages;\n};\n\nconst deleteMessageById = (messages: IStep[], messageId: string) => {\n  let nextMessages = [...messages];\n\n  for (let index = 0; index < nextMessages.length; index++) {\n    const msg = nextMessages[index];\n\n    if (msg.id === messageId) {\n      nextMessages = [\n        ...nextMessages.slice(0, index),\n        ...nextMessages.slice(index + 1)\n      ];\n    } else if (hasMessageById(nextMessages, messageId) && msg.steps) {\n      msg.steps = deleteMessageById(msg.steps, messageId);\n      nextMessages[index] = { ...msg };\n    }\n  }\n\n  return nextMessages;\n};\n\nconst updateMessageContentById = (\n  messages: IStep[],\n  messageId: number | string,\n  updatedContent: string,\n  isSequence: boolean,\n  isInput: boolean\n): IStep[] => {\n  const nextMessages = [...messages];\n  for (let index = 0; index < nextMessages.length; index++) {\n    const msg = nextMessages[index];\n\n    if (isEqual(msg.id, messageId)) {\n      if ('content' in msg && msg.content !== undefined) {\n        if (isSequence) {\n          msg.content = updatedContent;\n        } else {\n          msg.content += updatedContent;\n        }\n      } else if (isInput) {\n        if ('input' in msg && msg.input !== undefined) {\n          if (isSequence) {\n            msg.input = updatedContent;\n          } else {\n            msg.input += updatedContent;\n          }\n        }\n      } else {\n        if ('output' in msg && msg.output !== undefined) {\n          if (isSequence) {\n            msg.output = updatedContent;\n          } else {\n            msg.output += updatedContent;\n          }\n        }\n      }\n\n      nextMessages[index] = { ...msg };\n    } else if (msg.steps) {\n      msg.steps = updateMessageContentById(\n        msg.steps,\n        messageId,\n        updatedContent,\n        isSequence,\n        isInput\n      );\n      nextMessages[index] = { ...msg };\n    }\n  }\n\n  return nextMessages;\n};\n\nexport {\n  addMessageToParent,\n  addMessage,\n  deleteMessageById,\n  hasMessageById,\n  isLastMessage,\n  nestMessages,\n  updateMessageById,\n  updateMessageContentById\n};\n","import { createContext } from 'react';\n\nimport { ChainlitAPI } from './api';\n\nconst defaultChainlitContext = undefined;\n\nconst ChainlitContext = createContext<ChainlitAPI>(\n  new ChainlitAPI('http://localhost:8000', 'webapp')\n);\n\nexport { ChainlitContext, defaultChainlitContext };\n","import { useEffect } from 'react';\nimport { IAuthConfig } from 'src/index';\n\nimport { useApi } from '../api';\nimport { useAuthState } from './state';\n\nexport const useAuthConfig = () => {\n  const { authConfig, setAuthConfig } = useAuthState();\n  const { data: authConfigData, isLoading } = useApi<IAuthConfig>(\n    authConfig ? null : '/auth/config'\n  );\n\n  useEffect(() => {\n    if (authConfigData) {\n      setAuthConfig(authConfigData);\n    }\n  }, [authConfigData, setAuthConfig]);\n\n  return { authConfig, isLoading };\n};\n","import { useContext, useMemo } from 'react';\nimport { ChainlitAPI } from 'src/api';\nimport { ChainlitContext } from 'src/context';\nimport useSWR, { SWRConfig, SWRConfiguration } from 'swr';\n\nimport { useAuthState } from './auth/state';\n\nconst fetcher = async (client: ChainlitAPI, endpoint: string) => {\n  const res = await client.get(endpoint);\n  return res?.json();\n};\n\nconst cloneClient = (client: ChainlitAPI): ChainlitAPI => {\n  // Shallow clone API client.\n  // TODO: Move me to core API.\n\n  // Create new client\n  const newClient = new ChainlitAPI('', 'webapp');\n\n  // Assign old properties to new client\n  Object.assign(newClient, client);\n\n  return newClient;\n};\n\n/**\n * React hook for cached API data fetching using SWR (stale-while-revalidate).\n * Optimized for GET requests with automatic caching and revalidation.\n *\n * Key features:\n * - Automatic data caching and revalidation\n * - Integration with React component lifecycle\n * - Loading state management\n * - Recoil state integration for global state\n * - Memoized fetcher function to prevent unnecessary rerenders\n *\n * @param path - API endpoint path or null to disable the request\n * @param config - Optional SWR configuration\n * @returns SWR response object containing:\n *          - data: The fetched data\n *          - error: Any error that occurred\n *          - isValidating: Whether a request is in progress\n *          - mutate: Function to mutate the cached data\n *\n * @example\n * const { data, error, isValidating } = useApi<UserData>('/user');\n */\nfunction useApi<T>(\n  path?: string | null,\n  { ...swrConfig }: SWRConfiguration = {}\n) {\n  const client = useContext(ChainlitContext);\n  const { setUser } = useAuthState();\n\n  // Memoize the fetcher function to avoid recreating it on every render\n  const memoizedFetcher = useMemo(\n    () =>\n      ([url]: [url: string]) => {\n        if (!swrConfig.onErrorRetry) {\n          swrConfig.onErrorRetry = (...args) => {\n            const [err] = args;\n\n            // Don't do automatic retry for 401 - it just means we're not logged in (yet).\n            if (err.status === 401) {\n              setUser(null);\n              return;\n            }\n\n            // Fall back to default behavior.\n            return SWRConfig.defaultValue.onErrorRetry(...args);\n          };\n        }\n\n        const useApiClient = cloneClient(client);\n        useApiClient.on401 = useApiClient.onError = undefined;\n        return fetcher(useApiClient, url);\n      },\n    [client]\n  );\n\n  // Use a stable key for useSWR\n  const swrKey = useMemo(() => {\n    return path ? [path] : null;\n  }, [path]);\n\n  return useSWR<T, Error>(swrKey, memoizedFetcher, swrConfig);\n}\n\nexport { useApi, fetcher };\n","import { useRecoilState, useSetRecoilState } from 'recoil';\nimport { authState, threadHistoryState, userState } from 'src/state';\n\nexport const useAuthState = () => {\n  const [authConfig, setAuthConfig] = useRecoilState(authState);\n  const [user, setUser] = useRecoilState(userState);\n  const setThreadHistory = useSetRecoilState(threadHistoryState);\n\n  return {\n    authConfig,\n    setAuthConfig,\n    user,\n    setUser,\n    setThreadHistory\n  };\n};\n","import { useContext } from 'react';\nimport { ChainlitContext } from 'src/index';\n\nimport { useAuthState } from './state';\n\nexport const useSessionManagement = () => {\n  const apiClient = useContext(ChainlitContext);\n  const { setUser, setThreadHistory } = useAuthState();\n\n  const logout = async (reload = false): Promise<void> => {\n    await apiClient.logout();\n    setUser(undefined);\n    setThreadHistory(undefined);\n\n    if (reload) {\n      window.location.reload();\n    }\n  };\n\n  return { logout };\n};\n","import { useEffect } from 'react';\nimport { IUser } from 'src/types';\n\nimport { useApi } from '../api';\nimport { useAuthState } from './state';\n\nexport const useUserManagement = () => {\n  const { user, setUser } = useAuthState();\n\n  const {\n    data: userData,\n    error,\n    isLoading,\n    mutate: setUserFromAPI\n  } = useApi<IUser>('/user');\n\n  useEffect(() => {\n    if (userData) {\n      setUser(userData);\n    } else if (isLoading) {\n      setUser(undefined);\n    }\n  }, [userData, isLoading, setUser]);\n\n  useEffect(() => {\n    if (error) {\n      setUser(null);\n    }\n  }, [error]);\n\n  return { user, setUserFromAPI };\n};\n","import { IAuthConfig, IUser } from 'src/types';\n\nimport { useAuthConfig } from './config';\nimport { useSessionManagement } from './sessionManagement';\nimport { useUserManagement } from './userManagement';\n\nexport const useAuth = () => {\n  const { authConfig } = useAuthConfig();\n  const { logout } = useSessionManagement();\n  const { user, setUserFromAPI } = useUserManagement();\n\n  const isReady =\n    !!authConfig && (!authConfig.requireLogin || user !== undefined);\n\n  if (authConfig && !authConfig.requireLogin) {\n    return {\n      data: authConfig,\n      user: null,\n      isReady,\n      isAuthenticated: true,\n      logout: () => Promise.resolve(),\n      setUserFromAPI: () => Promise.resolve()\n    };\n  }\n\n  return {\n    data: authConfig,\n    user,\n    isReady,\n    isAuthenticated: !!user,\n    logout,\n    setUserFromAPI\n  };\n};\n\nexport type { IAuthConfig, IUser };\n","import { IElement, IThread, IUser } from 'src/types';\n\nimport { IAction } from 'src/types/action';\nimport { IFeedback } from 'src/types/feedback';\n\nexport * from './hooks/auth';\nexport * from './hooks/api';\n\nexport interface IThreadFilters {\n  search?: string;\n  feedback?: number;\n}\n\nexport interface IPageInfo {\n  hasNextPage: boolean;\n  endCursor?: string;\n}\n\nexport interface IPagination {\n  first: number;\n  cursor?: string | number;\n}\n\nexport class ClientError extends Error {\n  status: number;\n  detail?: string;\n\n  constructor(message: string, status: number, detail?: string) {\n    super(message);\n    this.status = status;\n    this.detail = detail;\n  }\n\n  toString() {\n    if (this.detail) {\n      return `${this.message}: ${this.detail}`;\n    } else {\n      return this.message;\n    }\n  }\n}\n\ntype Payload = FormData | any;\n\nexport class APIBase {\n  constructor(\n    public httpEndpoint: string,\n    public type: 'webapp' | 'copilot' | 'teams' | 'slack' | 'discord',\n    public on401?: () => void,\n    public onError?: (error: ClientError) => void\n  ) {}\n\n  buildEndpoint(path: string) {\n    if (this.httpEndpoint.endsWith('/')) {\n      // remove trailing slash on httpEndpoint\n      return `${this.httpEndpoint.slice(0, -1)}${path}`;\n    } else {\n      return `${this.httpEndpoint}${path}`;\n    }\n  }\n\n  private async getDetailFromErrorResponse(\n    res: Response\n  ): Promise<string | undefined> {\n    try {\n      const body = await res.json();\n      return body?.detail;\n    } catch (error: any) {\n      console.error('Unable to parse error response', error);\n    }\n    return undefined;\n  }\n\n  private handleRequestError(error: any) {\n    if (error instanceof ClientError) {\n      if (error.status === 401 && this.on401) {\n        this.on401();\n      }\n      if (this.onError) {\n        this.onError(error);\n      }\n    }\n    console.error(error);\n  }\n\n  /**\n   * Low-level HTTP request handler for direct API interactions.\n   * Provides full control over HTTP methods, request configuration, and error handling.\n   *\n   * Key features:\n   * - Supports all HTTP methods (GET, POST, PUT, PATCH, DELETE)\n   * - Handles both FormData and JSON payloads\n   * - Manages authentication headers\n   * - Custom error handling with ClientError class\n   * - Support for request cancellation via AbortSignal\n   *\n   * @param method - HTTP method to use (GET, POST, etc.)\n   * @param path - API endpoint path\n   * @param data - Optional request payload (FormData or JSON-serializable data)\n   * @param signal - Optional AbortSignal for request cancellation\n   * @returns Promise<Response>\n   * @throws ClientError for HTTP errors, including 401 unauthorized\n   */\n  async fetch(\n    method: string,\n    path: string,\n    data?: Payload,\n    signal?: AbortSignal,\n    headers: { Authorization?: string; 'Content-Type'?: string } = {}\n  ): Promise<Response> {\n    try {\n      let body;\n\n      if (data instanceof FormData) {\n        body = data;\n      } else {\n        headers['Content-Type'] = 'application/json';\n        body = data ? JSON.stringify(data) : null;\n      }\n\n      const res = await fetch(this.buildEndpoint(path), {\n        method,\n        credentials: 'include',\n        headers,\n        signal,\n        body\n      });\n\n      if (!res.ok) {\n        const detail = await this.getDetailFromErrorResponse(res);\n\n        throw new ClientError(res.statusText, res.status, detail);\n      }\n\n      return res;\n    } catch (error: any) {\n      this.handleRequestError(error);\n      throw error;\n    }\n  }\n\n  async get(endpoint: string) {\n    return await this.fetch('GET', endpoint);\n  }\n\n  async post(endpoint: string, data: Payload, signal?: AbortSignal) {\n    return await this.fetch('POST', endpoint, data, signal);\n  }\n\n  async put(endpoint: string, data: Payload) {\n    return await this.fetch('PUT', endpoint, data);\n  }\n\n  async patch(endpoint: string, data: Payload) {\n    return await this.fetch('PATCH', endpoint, data);\n  }\n\n  async delete(endpoint: string, data: Payload) {\n    return await this.fetch('DELETE', endpoint, data);\n  }\n}\n\nexport class ChainlitAPI extends APIBase {\n  async headerAuth() {\n    const res = await this.post(`/auth/header`, {});\n    return res.json();\n  }\n\n  async jwtAuth(token: string) {\n    const res = await this.fetch('POST', '/auth/jwt', undefined, undefined, {\n      Authorization: `Bearer ${token}`\n    });\n    return res.json();\n  }\n\n  async passwordAuth(data: FormData) {\n    const res = await this.post(`/login`, data);\n    return res.json();\n  }\n\n  async getUser(): Promise<IUser> {\n    const res = await this.get(`/user`);\n    return res.json();\n  }\n\n  async logout() {\n    const res = await this.post(`/logout`, {});\n    return res.json();\n  }\n\n  async setFeedback(\n    feedback: IFeedback\n  ): Promise<{ success: boolean; feedbackId: string }> {\n    const res = await this.put(`/feedback`, { feedback });\n    return res.json();\n  }\n\n  async deleteFeedback(feedbackId: string): Promise<{ success: boolean }> {\n    const res = await this.delete(`/feedback`, { feedbackId });\n    return res.json();\n  }\n\n  async listThreads(\n    pagination: IPagination,\n    filter: IThreadFilters\n  ): Promise<{\n    pageInfo: IPageInfo;\n    data: IThread[];\n  }> {\n    const res = await this.post(`/project/threads`, { pagination, filter });\n\n    return res.json();\n  }\n\n  async renameThread(threadId: string, name: string) {\n    const res = await this.put(`/project/thread`, { threadId, name });\n\n    return res.json();\n  }\n\n  async deleteThread(threadId: string) {\n    const res = await this.delete(`/project/thread`, { threadId });\n\n    return res.json();\n  }\n\n  uploadFile(\n    file: File,\n    onProgress: (progress: number) => void,\n    sessionId: string\n  ) {\n    const xhr = new XMLHttpRequest();\n    xhr.withCredentials = true;\n\n    const promise = new Promise<{ id: string }>((resolve, reject) => {\n      const formData = new FormData();\n      formData.append('file', file);\n\n      xhr.open(\n        'POST',\n        this.buildEndpoint(`/project/file?session_id=${sessionId}`),\n        true\n      );\n\n      // Track the progress of the upload\n      xhr.upload.onprogress = function (event) {\n        if (event.lengthComputable) {\n          const percentage = (event.loaded / event.total) * 100;\n          onProgress(percentage);\n        }\n      };\n\n      xhr.onload = function () {\n        if (xhr.status === 200) {\n          const response = JSON.parse(xhr.responseText);\n          resolve(response);\n          return;\n        }\n        const contentType = xhr.getResponseHeader('Content-Type');\n        if (contentType && contentType.includes('application/json')) {\n          const response = JSON.parse(xhr.responseText);\n          reject(response.detail);\n        } else {\n          reject('Upload failed');\n        }\n      };\n\n      xhr.onerror = function () {\n        reject('Upload error');\n      };\n\n      xhr.send(formData);\n    });\n\n    return { xhr, promise };\n  }\n\n  async callAction(action: IAction, sessionId: string) {\n    const res = await this.post(`/project/action`, { sessionId, action });\n\n    return res.json();\n  }\n\n  async updateElement(element: IElement, sessionId: string) {\n    const res = await this.put(`/project/element`, { sessionId, element });\n\n    return res.json();\n  }\n\n  async deleteElement(element: IElement, sessionId: string) {\n    const res = await this.delete(`/project/element`, { sessionId, element });\n\n    return res.json();\n  }\n\n  async connectStdioMCP(sessionId: string, name: string, fullCommand: string) {\n    const res = await this.post(`/mcp`, {\n      sessionId,\n      name,\n      fullCommand,\n      clientType: 'stdio'\n    });\n    return res.json();\n  }\n\n  async connectSseMCP(sessionId: string, name: string, url: string) {\n    const res = await this.post(`/mcp`, {\n      sessionId,\n      name,\n      url,\n      clientType: 'sse'\n    });\n    return res.json();\n  }\n\n  async disconnectMcp(sessionId: string, name: string) {\n    const res = await this.delete(`/mcp`, { sessionId, name });\n    return res.json();\n  }\n\n  getElementUrl(id: string, sessionId: string) {\n    const queryParams = `?session_id=${sessionId}`;\n    return this.buildEndpoint(`/project/file/${id}${queryParams}`);\n  }\n\n  getLogoEndpoint(theme: string) {\n    return this.buildEndpoint(`/logo?theme=${theme}`);\n  }\n\n  getOAuthEndpoint(provider: string) {\n    return this.buildEndpoint(`/auth/oauth/${provider}`);\n  }\n}\n","import { useRecoilValue } from 'recoil';\n\nimport {\n  currentThreadIdState,\n  firstUserInteraction,\n  messagesState\n} from './state';\n\nconst useChatMessages = () => {\n  const messages = useRecoilValue(messagesState);\n  const firstInteraction = useRecoilValue(firstUserInteraction);\n  const threadId = useRecoilValue(currentThreadIdState);\n\n  return {\n    threadId,\n    messages,\n    firstInteraction\n  };\n};\n\nexport { useChatMessages };\n","import { debounce } from 'lodash';\nimport { useCallback, useContext, useEffect } from 'react';\nimport {\n  useRecoilState,\n  useRecoilValue,\n  useResetRecoilState,\n  useSetRecoilState\n} from 'recoil';\nimport io from 'socket.io-client';\nimport { toast } from 'sonner';\nimport {\n  actionState,\n  askUserState,\n  audioConnectionState,\n  callFnState,\n  chatProfileState,\n  chatSettingsInputsState,\n  chatSettingsValueState,\n  commandsState,\n  currentThreadIdState,\n  elementState,\n  firstUserInteraction,\n  isAiSpeakingState,\n  loadingState,\n  mcpState,\n  messagesState,\n  resumeThreadErrorState,\n  sessionIdState,\n  sessionState,\n  sideViewState,\n  tasklistState,\n  threadIdToResumeState,\n  tokenCountState,\n  wavRecorderState,\n  wavStreamPlayerState\n} from 'src/state';\nimport {\n  IAction,\n  ICommand,\n  IElement,\n  IMessageElement,\n  IStep,\n  ITasklistElement,\n  IThread\n} from 'src/types';\nimport {\n  addMessage,\n  deleteMessageById,\n  updateMessageById,\n  updateMessageContentById\n} from 'src/utils/message';\n\nimport { OutputAudioChunk } from './types/audio';\n\nimport { ChainlitContext } from './context';\nimport type { IToken } from './useChatData';\n\nconst useChatSession = () => {\n  const client = useContext(ChainlitContext);\n  const sessionId = useRecoilValue(sessionIdState);\n\n  const [session, setSession] = useRecoilState(sessionState);\n  const setIsAiSpeaking = useSetRecoilState(isAiSpeakingState);\n  const setAudioConnection = useSetRecoilState(audioConnectionState);\n  const resetChatSettingsValue = useResetRecoilState(chatSettingsValueState);\n  const setChatSettingsValue = useSetRecoilState(chatSettingsValueState);\n  const setFirstUserInteraction = useSetRecoilState(firstUserInteraction);\n  const setLoading = useSetRecoilState(loadingState);\n  const setMcps = useSetRecoilState(mcpState);\n  const wavStreamPlayer = useRecoilValue(wavStreamPlayerState);\n  const wavRecorder = useRecoilValue(wavRecorderState);\n  const setMessages = useSetRecoilState(messagesState);\n  const setAskUser = useSetRecoilState(askUserState);\n  const setCallFn = useSetRecoilState(callFnState);\n  const setCommands = useSetRecoilState(commandsState);\n  const setSideView = useSetRecoilState(sideViewState);\n  const setElements = useSetRecoilState(elementState);\n  const setTasklists = useSetRecoilState(tasklistState);\n  const setActions = useSetRecoilState(actionState);\n  const setChatSettingsInputs = useSetRecoilState(chatSettingsInputsState);\n  const setTokenCount = useSetRecoilState(tokenCountState);\n  const [chatProfile, setChatProfile] = useRecoilState(chatProfileState);\n  const idToResume = useRecoilValue(threadIdToResumeState);\n  const setThreadResumeError = useSetRecoilState(resumeThreadErrorState);\n\n  const [currentThreadId, setCurrentThreadId] =\n    useRecoilState(currentThreadIdState);\n\n  // Use currentThreadId as thread id in websocket header\n  useEffect(() => {\n    if (session?.socket) {\n      session.socket.auth['threadId'] = currentThreadId || '';\n    }\n  }, [currentThreadId]);\n\n  const _connect = useCallback(\n    ({\n      transports,\n      userEnv\n    }: {\n      transports?: string[];\n      userEnv: Record<string, string>;\n    }) => {\n      const { protocol, host, pathname } = new URL(client.httpEndpoint);\n      const uri = `${protocol}//${host}`;\n      const path =\n        pathname && pathname !== '/'\n          ? `${pathname}/ws/socket.io`\n          : '/ws/socket.io';\n\n      const socket = io(uri, {\n        path,\n        withCredentials: true,\n        transports,\n        auth: {\n          clientType: client.type,\n          sessionId,\n          threadId: idToResume || '',\n          userEnv: JSON.stringify(userEnv),\n          chatProfile: chatProfile ? encodeURIComponent(chatProfile) : ''\n        }\n      });\n      setSession((old) => {\n        old?.socket?.removeAllListeners();\n        old?.socket?.close();\n        return {\n          socket\n        };\n      });\n\n      socket.on('connect', () => {\n        socket.emit('connection_successful');\n        setSession((s) => ({ ...s!, error: false }));\n        setMcps((prev) =>\n          prev.map((mcp) => {\n            const promise =\n              mcp.clientType === 'sse'\n                ? client.connectSseMCP(sessionId, mcp.name, mcp.url!)\n                : client.connectStdioMCP(sessionId, mcp.name, mcp.command!);\n            promise\n              .then(async ({ success, mcp }) => {\n                setMcps((prev) =>\n                  prev.map((existingMcp) => {\n                    if (existingMcp.name === mcp.name) {\n                      return {\n                        ...existingMcp,\n                        status: success ? 'connected' : 'failed',\n                        tools: mcp ? mcp.tools : existingMcp.tools\n                      };\n                    }\n                    return existingMcp;\n                  })\n                );\n              })\n              .catch(() => {\n                setMcps((prev) =>\n                  prev.map((existingMcp) => {\n                    if (existingMcp.name === mcp.name) {\n                      return {\n                        ...existingMcp,\n                        status: 'failed'\n                      };\n                    }\n                    return existingMcp;\n                  })\n                );\n              });\n            return { ...mcp, status: 'connecting' };\n          })\n        );\n      });\n\n      socket.on('connect_error', (_) => {\n        setSession((s) => ({ ...s!, error: true }));\n      });\n\n      socket.on('task_start', () => {\n        setLoading(true);\n      });\n\n      socket.on('task_end', () => {\n        setLoading(false);\n      });\n\n      socket.on('reload', () => {\n        socket.emit('clear_session');\n        window.location.reload();\n      });\n\n      socket.on('audio_connection', async (state: 'on' | 'off') => {\n        if (state === 'on') {\n          let isFirstChunk = true;\n          const startTime = Date.now();\n          const mimeType = 'pcm16';\n          // Connect to microphone\n          await wavRecorder.begin();\n          await wavStreamPlayer.connect();\n          await wavRecorder.record(async (data) => {\n            const elapsedTime = Date.now() - startTime;\n            socket.emit('audio_chunk', {\n              isStart: isFirstChunk,\n              mimeType,\n              elapsedTime,\n              data: data.mono\n            });\n            isFirstChunk = false;\n          });\n          wavStreamPlayer.onStop = () => setIsAiSpeaking(false);\n        } else {\n          await wavRecorder.end();\n          await wavStreamPlayer.interrupt();\n        }\n        setAudioConnection(state);\n      });\n\n      socket.on('audio_chunk', (chunk: OutputAudioChunk) => {\n        wavStreamPlayer.add16BitPCM(chunk.data, chunk.track);\n        setIsAiSpeaking(true);\n      });\n\n      socket.on('audio_interrupt', () => {\n        wavStreamPlayer.interrupt();\n      });\n\n      socket.on('resume_thread', (thread: IThread) => {\n        let messages: IStep[] = [];\n        for (const step of thread.steps) {\n          messages = addMessage(messages, step);\n        }\n        if (thread.metadata?.chat_profile) {\n          setChatProfile(thread.metadata?.chat_profile);\n        }\n        if (thread.metadata?.chat_settings) {\n          setChatSettingsValue(thread.metadata?.chat_settings);\n        }\n        setMessages(messages);\n        const elements = thread.elements || [];\n        setTasklists(\n          (elements as ITasklistElement[]).filter((e) => e.type === 'tasklist')\n        );\n        setElements(\n          (elements as IMessageElement[]).filter(\n            (e) => ['avatar', 'tasklist'].indexOf(e.type) === -1\n          )\n        );\n      });\n\n      socket.on('resume_thread_error', (error?: string) => {\n        setThreadResumeError(error);\n      });\n\n      socket.on('new_message', (message: IStep) => {\n        setMessages((oldMessages) => addMessage(oldMessages, message));\n      });\n\n      socket.on(\n        'first_interaction',\n        (event: { interaction: string; thread_id: string }) => {\n          setFirstUserInteraction(event.interaction);\n          setCurrentThreadId(event.thread_id);\n        }\n      );\n\n      socket.on('update_message', (message: IStep) => {\n        setMessages((oldMessages) =>\n          updateMessageById(oldMessages, message.id, message)\n        );\n      });\n\n      socket.on('delete_message', (message: IStep) => {\n        setMessages((oldMessages) =>\n          deleteMessageById(oldMessages, message.id)\n        );\n      });\n\n      socket.on('stream_start', (message: IStep) => {\n        setMessages((oldMessages) => addMessage(oldMessages, message));\n      });\n\n      socket.on(\n        'stream_token',\n        ({ id, token, isSequence, isInput }: IToken) => {\n          setMessages((oldMessages) =>\n            updateMessageContentById(\n              oldMessages,\n              id,\n              token,\n              isSequence,\n              isInput\n            )\n          );\n        }\n      );\n\n      socket.on('ask', ({ msg, spec }, callback) => {\n        setAskUser({ spec, callback, parentId: msg.parentId });\n        setMessages((oldMessages) => addMessage(oldMessages, msg));\n\n        setLoading(false);\n      });\n\n      socket.on('ask_timeout', () => {\n        setAskUser(undefined);\n        setLoading(false);\n      });\n\n      socket.on('clear_ask', () => {\n        setAskUser(undefined);\n      });\n\n      socket.on('call_fn', ({ name, args }, callback) => {\n        setCallFn({ name, args, callback });\n      });\n\n      socket.on('clear_call_fn', () => {\n        setCallFn(undefined);\n      });\n\n      socket.on('call_fn_timeout', () => {\n        setCallFn(undefined);\n      });\n\n      socket.on('chat_settings', (inputs: any) => {\n        setChatSettingsInputs(inputs);\n        resetChatSettingsValue();\n      });\n\n      socket.on('set_commands', (commands: ICommand[]) => {\n        setCommands(commands);\n      });\n\n      socket.on('set_sidebar_title', (title: string) => {\n        setSideView((prev) => {\n          return { title, elements: prev?.elements || [] };\n        });\n      });\n\n      socket.on('set_sidebar_elements', (elements: IMessageElement[]) => {\n        if (!elements.length) {\n          setSideView(undefined);\n        } else {\n          elements.forEach((element) => {\n            if (!element.url && element.chainlitKey) {\n              element.url = client.getElementUrl(\n                element.chainlitKey,\n                sessionId\n              );\n            }\n          });\n          setSideView((prev) => {\n            return { title: prev?.title || '', elements: elements };\n          });\n        }\n      });\n\n      socket.on('element', (element: IElement) => {\n        if (!element.url && element.chainlitKey) {\n          element.url = client.getElementUrl(element.chainlitKey, sessionId);\n        }\n\n        if (element.type === 'tasklist') {\n          setTasklists((old) => {\n            const index = old.findIndex((e) => e.id === element.id);\n            if (index === -1) {\n              return [...old, element];\n            } else {\n              return [...old.slice(0, index), element, ...old.slice(index + 1)];\n            }\n          });\n        } else {\n          setElements((old) => {\n            const index = old.findIndex((e) => e.id === element.id);\n            if (index === -1) {\n              return [...old, element];\n            } else {\n              return [...old.slice(0, index), element, ...old.slice(index + 1)];\n            }\n          });\n        }\n      });\n\n      socket.on('remove_element', (remove: { id: string }) => {\n        setElements((old) => {\n          return old.filter((e) => e.id !== remove.id);\n        });\n        setTasklists((old) => {\n          return old.filter((e) => e.id !== remove.id);\n        });\n      });\n\n      socket.on('action', (action: IAction) => {\n        setActions((old) => [...old, action]);\n      });\n\n      socket.on('remove_action', (action: IAction) => {\n        setActions((old) => {\n          const index = old.findIndex((a) => a.id === action.id);\n          if (index === -1) return old;\n          return [...old.slice(0, index), ...old.slice(index + 1)];\n        });\n      });\n\n      socket.on('token_usage', (count: number) => {\n        setTokenCount((old) => old + count);\n      });\n\n      socket.on('window_message', (data: any) => {\n        if (window.parent) {\n          window.parent.postMessage(data, '*');\n        }\n      });\n\n      socket.on('toast', (data: { message: string; type: string }) => {\n        if (!data.message) {\n          console.warn('No message received for toast.');\n          return;\n        }\n\n        switch (data.type) {\n          case 'info':\n            toast.info(data.message);\n            break;\n          case 'error':\n            toast.error(data.message);\n            break;\n          case 'success':\n            toast.success(data.message);\n            break;\n          case 'warning':\n            toast.warning(data.message);\n            break;\n          default:\n            toast(data.message);\n            break;\n        }\n      });\n    },\n    [setSession, sessionId, idToResume, chatProfile]\n  );\n\n  const connect = useCallback(debounce(_connect, 200), [_connect]);\n\n  const disconnect = useCallback(() => {\n    if (session?.socket) {\n      session.socket.removeAllListeners();\n      session.socket.close();\n    }\n  }, [session]);\n\n  return {\n    connect,\n    disconnect,\n    session,\n    sessionId,\n    chatProfile,\n    idToResume,\n    setChatProfile\n  };\n};\n\nexport { useChatSession };\n","import { useCallback } from 'react';\nimport { useRecoilState, useRecoilValue } from 'recoil';\n\nimport {\n  audioConnectionState,\n  isAiSpeakingState,\n  wavRecorderState,\n  wavStreamPlayerState\n} from './state';\nimport { useChatInteract } from './useChatInteract';\n\nconst useAudio = () => {\n  const [audioConnection, setAudioConnection] =\n    useRecoilState(audioConnectionState);\n  const wavRecorder = useRecoilValue(wavRecorderState);\n  const wavStreamPlayer = useRecoilValue(wavStreamPlayerState);\n  const isAiSpeaking = useRecoilValue(isAiSpeakingState);\n\n  const { startAudioStream, endAudioStream } = useChatInteract();\n\n  const startConversation = useCallback(async () => {\n    setAudioConnection('connecting');\n    await startAudioStream();\n  }, [startAudioStream]);\n\n  const endConversation = useCallback(async () => {\n    setAudioConnection('off');\n    await wavRecorder.end();\n    await wavStreamPlayer.interrupt();\n    await endAudioStream();\n  }, [endAudioStream, wavRecorder, wavStreamPlayer]);\n\n  return {\n    startConversation,\n    endConversation,\n    audioConnection,\n    isAiSpeaking,\n    wavRecorder,\n    wavStreamPlayer\n  };\n};\n\nexport { useAudio };\n","import { useEffect } from 'react';\nimport { useRecoilState } from 'recoil';\n\nimport { useApi, useAuth } from './api';\nimport { configState } from './state';\nimport { IChainlitConfig } from './types';\n\nconst useConfig = () => {\n  const [config, setConfig] = useRecoilState(configState);\n  const { isAuthenticated } = useAuth();\n  const language = navigator.language || 'en-US';\n\n  const { data, error, isLoading } = useApi<IChainlitConfig>(\n    !config && isAuthenticated ? `/project/settings?language=${language}` : null\n  );\n\n  useEffect(() => {\n    if (!data) return;\n    setConfig(data);\n  }, [data, setConfig]);\n\n  return { config, error, isLoading, language };\n};\n\nexport { useConfig };\n","export * from './useChatData';\nexport * from './useChatInteract';\nexport * from './useChatMessages';\nexport * from './useChatSession';\nexport * from './useAudio';\nexport * from './useConfig';\nexport * from './api';\nexport * from './types';\nexport * from './context';\nexport * from './state';\nexport * from './utils/message';\n\nexport { Socket } from 'socket.io-client';\n\nexport { WavRenderer } from './wavtools/wav_renderer';\n","const dataMap = new WeakMap();\n\n/**\n * Normalizes a Float32Array to Array(m): We use this to draw amplitudes on a graph\n * If we're rendering the same audio data, then we'll often be using\n * the same (data, m, downsamplePeaks) triplets so we give option to memoize\n */\nconst normalizeArray = (\n  data: Float32Array,\n  m: number,\n  downsamplePeaks: boolean = false,\n  memoize: boolean = false\n) => {\n  let cache, mKey, dKey;\n  if (memoize) {\n    mKey = m.toString();\n    dKey = downsamplePeaks.toString();\n    cache = dataMap.has(data) ? dataMap.get(data) : {};\n    dataMap.set(data, cache);\n    cache[mKey] = cache[mKey] || {};\n    if (cache[mKey][dKey]) {\n      return cache[mKey][dKey];\n    }\n  }\n  const n = data.length;\n  const result = new Array(m);\n  if (m <= n) {\n    // Downsampling\n    result.fill(0);\n    const count = new Array(m).fill(0);\n    for (let i = 0; i < n; i++) {\n      const index = Math.floor(i * (m / n));\n      if (downsamplePeaks) {\n        // take highest result in the set\n        result[index] = Math.max(result[index], Math.abs(data[i]));\n      } else {\n        result[index] += Math.abs(data[i]);\n      }\n      count[index]++;\n    }\n    if (!downsamplePeaks) {\n      for (let i = 0; i < result.length; i++) {\n        result[i] = result[i] / count[i];\n      }\n    }\n  } else {\n    for (let i = 0; i < m; i++) {\n      const index = (i * (n - 1)) / (m - 1);\n      const low = Math.floor(index);\n      const high = Math.ceil(index);\n      const t = index - low;\n      if (high >= n) {\n        result[i] = data[n - 1];\n      } else {\n        result[i] = data[low] * (1 - t) + data[high] * t;\n      }\n    }\n  }\n  if (memoize) {\n    cache[mKey as string][dKey as string] = result;\n  }\n  return result;\n};\n\nexport const WavRenderer = {\n  /**\n   * Renders a point-in-time snapshot of an audio sample, usually frequency values\n   * @param ctx\n   * @param data\n   * @param color\n   * @param cssWidth\n   * @param cssHeight\n   * @param pointCount number of bars to render\n   * @param barWidth width of bars in px\n   * @param barSpacing spacing between bars in px\n   * @param center vertically center the bars\n   */\n  drawBars: (\n    ctx: CanvasRenderingContext2D,\n    data: Float32Array,\n    cssWidth: number,\n    cssHeight: number,\n    color: string,\n    pointCount: number = 0,\n    barWidth: number = 0,\n    barSpacing: number = 0,\n    center: boolean = false\n  ) => {\n    pointCount = Math.floor(\n      Math.min(\n        pointCount,\n        (cssWidth - barSpacing) / (Math.max(barWidth, 1) + barSpacing)\n      )\n    );\n    if (!pointCount) {\n      pointCount = Math.floor(\n        (cssWidth - barSpacing) / (Math.max(barWidth, 1) + barSpacing)\n      );\n    }\n    if (!barWidth) {\n      barWidth = (cssWidth - barSpacing) / pointCount - barSpacing;\n    }\n    const points = normalizeArray(data, pointCount, true);\n    for (let i = 0; i < pointCount; i++) {\n      const amplitude = Math.abs(points[i]);\n      const height = Math.max(1, amplitude * cssHeight);\n      const x = barSpacing + i * (barWidth + barSpacing);\n      const y = center ? (cssHeight - height) / 2 : cssHeight - height;\n      const radius = Math.min(barWidth / 2, height / 2); // Calculate the radius for rounded corners\n\n      ctx.fillStyle = color;\n      ctx.beginPath();\n      ctx.moveTo(x + radius, y);\n      ctx.lineTo(x + barWidth - radius, y);\n      ctx.arcTo(x + barWidth, y, x + barWidth, y + radius, radius);\n      ctx.lineTo(x + barWidth, y + height - radius);\n      ctx.arcTo(\n        x + barWidth,\n        y + height,\n        x + barWidth - radius,\n        y + height,\n        radius\n      );\n      ctx.lineTo(x + radius, y + height);\n      ctx.arcTo(x, y + height, x, y + height - radius, radius);\n      ctx.lineTo(x, y + radius);\n      ctx.arcTo(x, y, x + radius, y, radius);\n      ctx.closePath();\n      ctx.fill();\n    }\n  }\n};\n"]}