@chainlit/react-client 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,14 +1,312 @@
1
1
  import { atom, selector, DefaultValue, useRecoilValue, useRecoilState, useSetRecoilState, useResetRecoilState } from 'recoil';
2
2
  import { isEqual, debounce } from 'lodash';
3
3
  import { v4 } from 'uuid';
4
- import { createContext, useContext, useMemo, useEffect, useCallback, useRef, useState } from 'react';
5
- import ee from 'jwt-decode';
6
- import Zt from 'swr';
7
- import ue from 'socket.io-client';
4
+ import { createContext, useContext, useMemo, useEffect, useCallback } from 'react';
5
+ import Ct from 'jwt-decode';
6
+ import vt from 'swr';
7
+ import Lt from 'socket.io-client';
8
8
  export { Socket } from 'socket.io-client';
9
9
 
10
- var Et=s=>{let t={},e=new Date,n=new Date;n.setDate(e.getDate()-1);let o=new Date;o.setDate(e.getDate()-7);let r=new Date;return r.setDate(e.getDate()-30),s.forEach(c=>{let a=new Date(c.createdAt),g=a.toDateString()===e.toDateString(),m=a.toDateString()===n.toDateString(),f=a>=o,y=a>=r,S;g?S="Today":m?S="Yesterday":f?S="Previous 7 days":y?S="Previous 30 days":S=a.toLocaleString("default",{month:"long",year:"numeric"}).split(" ").slice(0,1).join(" "),t[S]||(t[S]=[]),t[S].push(c);}),t};var st=atom({key:"ThreadIdToResume",default:void 0}),Pt=atom({key:"ChatProfile",default:void 0}),Dt=atom({key:"SessionId",default:v4()}),et=selector({key:"SessionIdSelector",get:({get:s})=>s(Dt),set:({set:s},t)=>s(Dt,t instanceof DefaultValue?v4():t)}),B=atom({key:"Session",dangerouslyAllowMutability:!0,default:void 0}),V=atom({key:"Actions",default:[]}),j=atom({key:"Messages",dangerouslyAllowMutability:!0,default:[]}),ot=atom({key:"TokenCount",default:0}),$=atom({key:"Loading",default:!1}),H=atom({key:"AskUser",default:void 0}),rt=atom({key:"CallFn",default:void 0}),U=atom({key:"ChatSettings",default:[]}),mt=selector({key:"ChatSettingsValue/Default",get:({get:s})=>s(U).reduce((e,n)=>(e[n.id]=n.initial,e),{})}),O=atom({key:"ChatSettingsValue",default:mt}),q=atom({key:"DisplayElements",default:[]}),K=atom({key:"TasklistElements",default:[]}),W=atom({key:"FirstUserInteraction",default:void 0}),z=atom({key:"AccessToken",default:void 0}),Ut=atom({key:"User",default:null}),vt=atom({key:"ChainlitConfig",default:void 0}),Lt=atom({key:"ThreadHistory",default:{threads:void 0,currentThreadId:void 0,timeGroupedThreads:void 0,pageInfo:void 0},effects:[({setSelf:s,onSet:t})=>{t((e,n)=>{let o=e?.timeGroupedThreads;e?.threads&&!isEqual(e.threads,n?.timeGroupedThreads)&&(o=Et(e.threads)),s({...e,timeGroupedThreads:o});});}]}),Bt=atom({key:"SideView",default:void 0}),G=atom({key:"CurrentThreadId",default:void 0});var be=()=>{let s=useRecoilValue($),t=useRecoilValue(q),e=useRecoilValue(K),n=useRecoilValue(V),o=useRecoilValue(B),r=useRecoilValue(H),c=useRecoilValue(rt),a=useRecoilValue(U),g=useRecoilValue(O),m=useRecoilValue(mt),f=o?.socket.connected&&!o?.error,y=!f||s||r?.spec.type==="file"||r?.spec.type==="action";return {actions:n,askUser:r,callFn:c,chatSettingsDefaultValue:m,chatSettingsInputs:a,chatSettingsValue:g,connected:f,disabled:y,elements:t,error:o?.error,loading:s,tasklists:e}};var we=s=>{let t=[];for(let e of s)t=D(t,e);return t},Re=(s,t)=>{if(s.length-1===t)return !0;for(let e=t+1;e<s.length;e++)if(!s[e].streaming)return !1;return !0},D=(s,t)=>{let e=["assistant_message","user_message"],n=[...e,"tool"],o=e.includes(t.type),r=n.includes(t.type),c=!t.parentId;if(c&&!r)return s;let a=c?void 0:ht(s,t.parentId),g=(c||a?.type!=="assistant_message")&&t.type==="tool";if(at(s,t.id))return ct(s,t.id,t);if(g){let m=s.length>0?s[s.length-1]:void 0,f=m?.type==="assistant_message"&&m?.id.startsWith("wrap_");return m&&f?[...s.slice(0,s.length-1),{...m,steps:[...m.steps||[],t]}]:[...s,{...t,name:"",input:"",output:"",id:"wrap_"+t.id,type:"assistant_message",steps:[t]}]}else return !o&&"parentId"in t&&t.parentId?jt(s,t.parentId,t):"indent"in t&&t.indent&&t.indent>0?Vt(s,t.indent,t):[...s,t]},Vt=(s,t,e,n=0)=>{let o=[...s];if(o.length===0)return [...o,e];{let r=o.length-1,c=o[r];return c.steps=c.steps||[],n+1===t?(c.steps=[...c.steps,e],o[r]={...c},o):(c.steps=Vt(c.steps,t,e,n+1),o[r]={...c},o)}},jt=(s,t,e)=>{let n=[...s];for(let o=0;o<n.length;o++){let r=n[o];isEqual(r.id,t)?(r.steps=r.steps?[...r.steps,e]:[e],n[o]={...r}):at(n,t)&&r.steps&&(r.steps=jt(r.steps,t,e),n[o]={...r});}return n},ht=(s,t)=>{for(let e of s){if(isEqual(e.id,t))return e;if(e.steps&&e.steps.length>0){let n=ht(e.steps,t);if(n)return n}}},at=(s,t)=>ht(s,t)!==void 0,ct=(s,t,e)=>{let n=[...s];for(let o=0;o<n.length;o++){let r=n[o];isEqual(r.id,t)?n[o]={steps:r.steps,...e}:at(n,t)&&r.steps&&(r.steps=ct(r.steps,t,e),n[o]={...r});}return n},St=(s,t)=>{let e=[...s];for(let n=0;n<e.length;n++){let o=e[n];o.id===t?e=[...e.slice(0,n),...e.slice(n+1)]:at(e,t)&&o.steps&&(o.steps=St(o.steps,t),e[n]={...o});}return e},It=(s,t,e,n,o)=>{let r=[...s];for(let c=0;c<r.length;c++){let a=r[c];isEqual(a.id,t)?("content"in a&&a.content!==void 0?n?a.content=e:a.content+=e:o?"input"in a&&a.input!==void 0&&(n?a.input=e:a.input+=e):"output"in a&&a.output!==void 0&&(n?a.output=e:a.output+=e),r[c]={...a}):a.steps&&(a.steps=It(a.steps,t,e,n,o),r[c]={...a});}return r};var kt="token";function yt(){try{return localStorage.getItem(kt)}catch{return}}function $t(s){try{return localStorage.setItem(kt,s)}catch{return}}function lt(){try{return localStorage.removeItem(kt)}catch{return}}var te=async(s,t,e)=>(await s.get(t,e))?.json();function dt(s,{token:t,...e}={}){let n=useContext(P),o=useRecoilValue(z);o=t||o;let r=useMemo(()=>([a,g])=>te(n,a,g),[n]),c=useMemo(()=>s?[s,o]:null,[s,o]);return Zt(c,r,e)}var qt=()=>{let s=useContext(P),{data:t,isLoading:e}=dt("/auth/config"),[n,o]=useRecoilState(z),r=useSetRecoilState(Lt),[c,a]=useRecoilState(Ut),g=!!(!e&&t),m=async()=>{await s.logout(),a(null),lt(),o(""),r(void 0);},f=S=>{if(!S){m();return}try{let{exp:w,...F}=ee(S);$t(S),o(`Bearer ${S}`),a(F);}catch(w){console.error("Invalid token, clearing token from local storage","error:",w),m();}};useEffect(()=>{if(!c&&yt()){f(yt());return}},[]);let y=!!n;return t&&!t.requireLogin?{data:t,user:null,isReady:g,isAuthenticated:!0,accessToken:"",logout:()=>{},setAccessToken:()=>{}}:{data:t,user:c,isAuthenticated:y,isReady:g,accessToken:n,logout:m,setAccessToken:f}};var ut=class extends Error{constructor(e,n){super(e);this.detail=n;}toString(){return this.detail?`${this.message}: ${this.detail}`:this.message}},Tt=class{constructor(t,e,n,o){this.httpEndpoint=t;this.type=e;this.on401=n;this.onError=o;}buildEndpoint(t){return this.httpEndpoint.endsWith("/")?`${this.httpEndpoint.slice(0,-1)}${t}`:`${this.httpEndpoint}${t}`}checkToken(t){let e="Bearer ";return t.startsWith(e)?t:e+t}async fetch(t,e,n,o,r){try{let c={};n&&(c.Authorization=this.checkToken(n));let a;o instanceof FormData?a=o:(c["Content-Type"]="application/json",a=o?JSON.stringify(o):null);let g=await fetch(this.buildEndpoint(e),{method:t,headers:c,signal:r,body:a});if(!g.ok){let m=await g.json();throw g.status===401&&this.on401&&(lt(),this.on401()),new ut(g.statusText,m.detail)}return g}catch(c){throw c instanceof ut&&this.onError&&this.onError(c),console.error(c),c}}async get(t,e){return await this.fetch("GET",t,e)}async post(t,e,n,o){return await this.fetch("POST",t,n,e,o)}async put(t,e,n){return await this.fetch("PUT",t,n,e)}async patch(t,e,n){return await this.fetch("PATCH",t,n,e)}async delete(t,e,n){return await this.fetch("DELETE",t,n,e)}},ft=class extends Tt{async headerAuth(){return (await this.post("/auth/header",{})).json()}async passwordAuth(t){return (await this.post("/login",t)).json()}async logout(){return (await this.post("/logout",{})).json()}async setFeedback(t,e){return (await this.put("/feedback",{feedback:t},e)).json()}async deleteFeedback(t,e){return (await this.delete("/feedback",{feedbackId:t},e)).json()}async listThreads(t,e,n){return (await this.post("/project/threads",{pagination:t,filter:e},n)).json()}async deleteThread(t,e){return (await this.delete("/project/thread",{threadId:t},e)).json()}uploadFile(t,e,n,o){let r=new XMLHttpRequest,c=new Promise((a,g)=>{let m=new FormData;m.append("file",t),r.open("POST",this.buildEndpoint(`/project/file?session_id=${n}`),!0),o&&r.setRequestHeader("Authorization",this.checkToken(o)),r.upload.onprogress=function(f){if(f.lengthComputable){let y=f.loaded/f.total*100;e(y);}},r.onload=function(){if(r.status===200){let f=JSON.parse(r.responseText);a(f);}else g("Upload failed");},r.onerror=function(){g("Upload error");},r.send(m);});return {xhr:r,promise:c}}getElementUrl(t,e){let n=`?session_id=${e}`;return this.buildEndpoint(`/project/file/${t}${n}`)}getLogoEndpoint(t){return this.buildEndpoint(`/logo?theme=${t}`)}getOAuthEndpoint(t){return this.buildEndpoint(`/auth/oauth/${t}`)}};var Qe=void 0,P=createContext(new ft("http://localhost:8000","webapp"));var Kt=()=>{let s=useContext(P),t=useRecoilValue(z),e=useRecoilValue(B),n=useRecoilValue(H),o=useRecoilValue(et),r=useResetRecoilState(U),c=useResetRecoilState(et),a=useResetRecoilState(O),g=useSetRecoilState(W),m=useSetRecoilState($),f=useSetRecoilState(j),y=useSetRecoilState(q),S=useSetRecoilState(K),w=useSetRecoilState(V),F=useSetRecoilState(ot),R=useSetRecoilState(st),v=useSetRecoilState(Bt),N=useSetRecoilState(G),X=useCallback(()=>{e?.socket.emit("clear_session"),e?.socket.disconnect(),R(void 0),c(),g(void 0),f([]),y([]),S([]),w([]),F(0),r(),a(),v(void 0),N(void 0);},[e]),L=useCallback((p,h=[])=>{p.id||(p.id=v4()),p.createdAt||(p.createdAt=new Date().toISOString()),f(d=>D(d,p)),e?.socket.emit("client_message",{message:p,fileReferences:h});},[e?.socket]),J=useCallback((p,h,d,i)=>{e?.socket.emit("audio_chunk",{isStart:p,mimeType:h,elapsedTime:d,data:i});},[e?.socket]),Y=useCallback(p=>{e?.socket.emit("audio_end",{fileReferences:p});},[e?.socket]),Q=useCallback(p=>{n&&(f(h=>D(h,p)),n.callback(p));},[n]),Z=useCallback(p=>{e?.socket.emit("chat_settings_change",p);},[e?.socket]),x=useCallback(()=>{f(p=>p.map(h=>(h.streaming=!1,h))),m(!1),e?.socket.emit("stop");},[e?.socket]),E=useCallback(p=>{let h=e?.socket;if(!h)return;let d=new Promise((i,l)=>{h.once("action_response",u=>{u.status?i(u):l(u);});});return h.emit("action_call",p),d},[e?.socket]);return {uploadFile:useCallback((p,h)=>s.uploadFile(p,h,o,t),[o,t]),callAction:E,clear:X,replyMessage:Q,sendMessage:L,sendAudioChunk:J,endAudioStream:Y,stopTask:x,setIdToResume:R,updateChatSettings:Z}};var dn=()=>{let s=useRecoilValue(j),t=useRecoilValue(W);return {threadId:useRecoilValue(G),messages:s,firstInteraction:t}};var kn=()=>{let s=useContext(P),t=useRecoilValue(et),[e,n]=useRecoilState(B),o=useResetRecoilState(O),r=useSetRecoilState(W),c=useSetRecoilState($),a=useSetRecoilState(j),g=useSetRecoilState(H),m=useSetRecoilState(rt),f=useSetRecoilState(q),y=useSetRecoilState(K),S=useSetRecoilState(V),w=useSetRecoilState(U),F=useSetRecoilState(ot),[R,v]=useRecoilState(Pt),N=useRecoilValue(st),X=useSetRecoilState(G),L=useCallback(({userEnv:Q,accessToken:Z})=>{let{protocol:x,host:E,pathname:C}=new URL(s.httpEndpoint),p=`${x}//${E}`,h=C&&C!=="/"?`${C}/ws/socket.io`:"/ws/socket.io",d=ue(p,{path:h,extraHeaders:{Authorization:Z||"","X-Chainlit-Client-Type":s.type,"X-Chainlit-Session-Id":t,"X-Chainlit-Thread-Id":N||"","user-env":JSON.stringify(Q),"X-Chainlit-Chat-Profile":R?encodeURIComponent(R):""}});n(i=>(i?.socket?.removeAllListeners(),i?.socket?.close(),{socket:d})),d.on("connect",()=>{d.emit("connection_successful"),n(i=>({...i,error:!1}));}),d.on("connect_error",i=>{n(l=>({...l,error:!0}));}),d.on("task_start",()=>{c(!0);}),d.on("task_end",()=>{c(!1);}),d.on("reload",()=>{d.emit("clear_session"),window.location.reload();}),d.on("resume_thread",i=>{let l=[];for(let k of i.steps)l=D(l,k);i.metadata?.chat_profile&&v(i.metadata?.chat_profile),a(l);let u=i.elements||[];y(u.filter(k=>k.type==="tasklist")),f(u.filter(k=>["avatar","tasklist"].indexOf(k.type)===-1));}),d.on("new_message",i=>{a(l=>D(l,i));}),d.on("first_interaction",i=>{r(i.interaction),X(i.thread_id);}),d.on("update_message",i=>{a(l=>ct(l,i.id,i));}),d.on("delete_message",i=>{a(l=>St(l,i.id));}),d.on("stream_start",i=>{a(l=>D(l,i));}),d.on("stream_token",({id:i,token:l,isSequence:u,isInput:k})=>{a(gt=>It(gt,i,l,u,k));}),d.on("ask",({msg:i,spec:l},u)=>{g({spec:l,callback:u}),a(k=>D(k,i)),c(!1);}),d.on("ask_timeout",()=>{g(void 0),c(!1);}),d.on("clear_ask",()=>{g(void 0);}),d.on("call_fn",({name:i,args:l},u)=>{m({name:i,args:l,callback:u});}),d.on("clear_call_fn",()=>{m(void 0);}),d.on("call_fn_timeout",()=>{m(void 0);}),d.on("chat_settings",i=>{w(i),o();}),d.on("element",i=>{!i.url&&i.chainlitKey&&(i.url=s.getElementUrl(i.chainlitKey,t)),i.type==="tasklist"?y(l=>{let u=l.findIndex(k=>k.id===i.id);return u===-1?[...l,i]:[...l.slice(0,u),i,...l.slice(u+1)]}):f(l=>{let u=l.findIndex(k=>k.id===i.id);return u===-1?[...l,i]:[...l.slice(0,u),i,...l.slice(u+1)]});}),d.on("remove_element",i=>{f(l=>l.filter(u=>u.id!==i.id)),y(l=>l.filter(u=>u.id!==i.id));}),d.on("action",i=>{S(l=>[...l,i]);}),d.on("remove_action",i=>{S(l=>{let u=l.findIndex(k=>k.id===i.id);return u===-1?l:[...l.slice(0,u),...l.slice(u+1)]});}),d.on("token_usage",i=>{F(l=>l+i);});},[n,t,R]),J=useCallback(debounce(L,200),[L]),Y=useCallback(()=>{e?.socket&&(e.socket.removeAllListeners(),e.socket.close());},[e]);return {connect:J,disconnect:Y,session:e,sessionId:t,chatProfile:R,idToResume:N,setChatProfile:v}};var fe={enabled:!0,min_decibels:-45,initial_silence_timeout:3e3,silence_timeout:1500,max_duration:15e3,chunk_duration:1e3},Cn=(s=fe)=>{let t=useRef(null),e=useRef(!1),{sendAudioChunk:n,endAudioStream:o}=Kt(),[r,c]=useState(!1),[a,g]=useState(void 0),[m,f]=useState(!1),[y,S]=useState(void 0),[w,F]=useState(!1),R=useCallback(()=>{!r||!t.current||(e.current=!0,t.current.stop());},[r]),v=useCallback(()=>{!r||!t.current||t.current.stop();},[r]);return {startRecording:useCallback(X=>{if(r||!s)return;F(!1),S(void 0),clearTimeout(a),e.current=!1;let{min_decibels:L,silence_timeout:J,initial_silence_timeout:Y,chunk_duration:Q,max_duration:Z}=s;navigator.mediaDevices.getUserMedia({audio:!0}).then(x=>{let E=!1,C=!1,p=!0,h=null,d=Date.now(),i=new MediaRecorder(x);t.current=i,i.addEventListener("start",()=>{c(!0),d=Date.now();}),i.addEventListener("dataavailable",async T=>{if(E||(h?h=new Blob([h,T.data],{type:T.data.type}):h=new Blob([T.data],{type:T.data.type})),i.state==="inactive")return;let tt=Date.now()-d;if(tt>=Z){i.stop(),x.getTracks().forEach(Nt=>Nt.stop());return}f(C);let[Rt,me]=i.mimeType.split(";");h?(await n(p,Rt,tt,new Blob([h,T.data])),h=null):await n(p,Rt,tt,T.data),p&&(p=!1);}),i.addEventListener("stop",async()=>{c(!1),f(!1),E&&!e.current&&(F(!0),await o(X));});let l=new AudioContext,u=l.createMediaStreamSource(x),k=l.createAnalyser();k.minDecibels=L,u.connect(k);let gt=k.frequencyBinCount,_t=new Uint8Array(gt);i.start(Q);let wt=()=>{if(i.state==="inactive")return;k.getByteFrequencyData(_t);let T=_t.some(tt=>tt>0);C||(C=T),!E&&T&&(f(C),E=!0),requestAnimationFrame(wt);};wt(),setTimeout(()=>{E?g(setInterval(()=>{C?C=!1:(i.stop(),x.getTracks().forEach(T=>T.stop()));},J)):(i.stop(),x.getTracks().forEach(T=>T.stop()));},Y);}).catch(x=>{S(x.message);});},[a,r,s,n,o]),stopRecording:v,cancelRecording:R,isRecording:r,isSpeaking:m,isRecordingFinished:w,error:y}};var En=s=>{let[t,e]=useRecoilState(vt),{isAuthenticated:n}=qt(),o=navigator.language||"en-US",{data:r,error:c,isLoading:a}=dt(!t&&n?`/project/settings?language=${o}`:null,{token:s});return useEffect(()=>{r&&e(r);},[r,e]),{config:t,error:c,isLoading:a,language:o}};
10
+ var ze=i=>{let e={},t=new Date,s=new Date;s.setDate(t.getDate()-1);let n=new Date;n.setDate(t.getDate()-7);let r=new Date;return r.setDate(t.getDate()-30),i.forEach(o=>{let a=new Date(o.createdAt),u=a.toDateString()===t.toDateString(),d=a.toDateString()===s.toDateString(),c=a>=n,f=a>=r,p;u?p="Today":d?p="Yesterday":c?p="Previous 7 days":f?p="Previous 30 days":p=a.toLocaleString("default",{month:"long",year:"numeric"}).split(" ").slice(0,1).join(" "),e[p]||(e[p]=[]),e[p].push(o);}),e};var Ne=[4186.01,4434.92,4698.63,4978.03,5274.04,5587.65,5919.91,6271.93,6644.88,7040,7458.62,7902.13],dt=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],E=[],oe=[];for(let i=1;i<=8;i++)for(let e=0;e<Ne.length;e++){let t=Ne[e];E.push(t/Math.pow(2,8-i)),oe.push(dt[e]+i);}var re=[32,2e3],Pe=E.filter((i,e)=>E[e]>re[0]&&E[e]<re[1]),We=oe.filter((i,e)=>E[e]>re[0]&&E[e]<re[1]);var F=class i{static getFrequencies(e,t,s,n="frequency",r=-100,o=-30){s||(s=new Float32Array(e.frequencyBinCount),e.getFloatFrequencyData(s));let a=t/2,u=1/s.length*a,d,c,f;if(n==="music"||n==="voice"){let m=n==="voice"?Pe:E,y=Array(m.length).fill(r);for(let C=0;C<s.length;C++){let Y=C*u,J=s[C];for(let v=m.length-1;v>=0;v--)if(Y>m[v]){y[v]=Math.max(y[v],J);break}}d=y,c=n==="voice"?Pe:E,f=n==="voice"?We:oe;}else d=Array.from(s),c=d.map((m,y)=>u*y),f=c.map(m=>`${m.toFixed(2)} Hz`);let p=d.map(m=>Math.max(0,Math.min((m-r)/(o-r),1)));return {values:new Float32Array(p),frequencies:c,labels:f}}constructor(e,t=null){if(this.fftResults=[],t){let{length:s,sampleRate:n}=t,r=new OfflineAudioContext({length:s,sampleRate:n}),o=r.createBufferSource();o.buffer=t;let a=r.createAnalyser();a.fftSize=8192,a.smoothingTimeConstant=.1,o.connect(a);let u=1/60,d=s/n,c=f=>{let p=u*f;p<d&&r.suspend(p).then(()=>{let k=new Float32Array(a.frequencyBinCount);a.getFloatFrequencyData(k),this.fftResults.push(k),c(f+1);}),f===1?r.startRendering():r.resume();};o.start(0),c(1),this.audio=e,this.context=r,this.analyser=a,this.sampleRate=n,this.audioBuffer=t;}else {let s=new AudioContext,n=s.createMediaElementSource(e),r=s.createAnalyser();r.fftSize=8192,r.smoothingTimeConstant=.1,n.connect(r),r.connect(s.destination),this.audio=e,this.context=s,this.analyser=r,this.sampleRate=this.context.sampleRate,this.audioBuffer=null;}}getFrequencies(e="frequency",t=-100,s=-30){let n=null;if(this.audioBuffer&&this.fftResults.length){let r=this.audio.currentTime/this.audio.duration,o=Math.min(r*this.fftResults.length|0,this.fftResults.length-1);n=this.fftResults[o];}return i.getFrequencies(this.analyser,this.sampleRate,n,e,t,s)}async resumeIfSuspended(){return this.context.state==="suspended"&&await this.context.resume(),!0}};globalThis.AudioAnalysis=F;var T=class{static floatTo16BitPCM(e){let t=new ArrayBuffer(e.length*2),s=new DataView(t),n=0;for(let r=0;r<e.length;r++,n+=2){let o=Math.max(-1,Math.min(1,e[r]));s.setInt16(n,o<0?o*32768:o*32767,!0);}return t}static mergeBuffers(e,t){let s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}_packData(e,t){return [new Uint8Array([t,t>>8]),new Uint8Array([t,t>>8,t>>16,t>>24])][e]}pack(e,t){if(t?.bitsPerSample)if(t?.channels){if(!t?.data)throw new Error('Missing "data"')}else throw new Error('Missing "channels"');else throw new Error('Missing "bitsPerSample"');let{bitsPerSample:s,channels:n,data:r}=t,o=["RIFF",this._packData(1,4+(8+24)+(8+8)),"WAVE","fmt ",this._packData(1,16),this._packData(0,1),this._packData(0,n.length),this._packData(1,e),this._packData(1,e*n.length*s/8),this._packData(0,n.length*s/8),this._packData(0,s),"data",this._packData(1,n[0].length*n.length*s/8),r],a=new Blob(o,{type:"audio/mpeg"}),u=URL.createObjectURL(a);return {blob:a,url:u,channelCount:n.length,sampleRate:e,duration:r.byteLength/(n.length*e*2)}}};globalThis.WavPacker=T;var pt=`
11
+ class AudioProcessor extends AudioWorkletProcessor {
11
12
 
12
- export { Tt as APIBase, ft as ChainlitAPI, P as ChainlitContext, ut as ClientError, z as accessTokenState, V as actionState, D as addMessage, jt as addMessageToParent, H as askUserState, rt as callFnState, Pt as chatProfileState, mt as chatSettingsDefaultValueSelector, U as chatSettingsInputsState, O as chatSettingsValueState, vt as configState, G as currentThreadIdState, Qe as defaultChainlitContext, St as deleteMessageById, q as elementState, te as fetcher, W as firstUserInteraction, at as hasMessageById, Re as isLastMessage, $ as loadingState, j as messagesState, we as nestMessages, et as sessionIdState, B as sessionState, Bt as sideViewState, K as tasklistState, Lt as threadHistoryState, st as threadIdToResumeState, ot as tokenCountState, ct as updateMessageById, It as updateMessageContentById, dt as useApi, Cn as useAudio, qt as useAuth, be as useChatData, Kt as useChatInteract, dn as useChatMessages, kn as useChatSession, En as useConfig, Ut as userState };
13
+ constructor() {
14
+ super();
15
+ this.port.onmessage = this.receive.bind(this);
16
+ this.initialize();
17
+ }
18
+
19
+ initialize() {
20
+ this.foundAudio = false;
21
+ this.recording = false;
22
+ this.chunks = [];
23
+ }
24
+
25
+ /**
26
+ * Concatenates sampled chunks into channels
27
+ * Format is chunk[Left[], Right[]]
28
+ */
29
+ readChannelData(chunks, channel = -1, maxChannels = 9) {
30
+ let channelLimit;
31
+ if (channel !== -1) {
32
+ if (chunks[0] && chunks[0].length - 1 < channel) {
33
+ throw new Error(
34
+ \`Channel \${channel} out of range: max \${chunks[0].length}\`
35
+ );
36
+ }
37
+ channelLimit = channel + 1;
38
+ } else {
39
+ channel = 0;
40
+ channelLimit = Math.min(chunks[0] ? chunks[0].length : 1, maxChannels);
41
+ }
42
+ const channels = [];
43
+ for (let n = channel; n < channelLimit; n++) {
44
+ const length = chunks.reduce((sum, chunk) => {
45
+ return sum + chunk[n].length;
46
+ }, 0);
47
+ const buffers = chunks.map((chunk) => chunk[n]);
48
+ const result = new Float32Array(length);
49
+ let offset = 0;
50
+ for (let i = 0; i < buffers.length; i++) {
51
+ result.set(buffers[i], offset);
52
+ offset += buffers[i].length;
53
+ }
54
+ channels[n] = result;
55
+ }
56
+ return channels;
57
+ }
58
+
59
+ /**
60
+ * Combines parallel audio data into correct format,
61
+ * channels[Left[], Right[]] to float32Array[LRLRLRLR...]
62
+ */
63
+ formatAudioData(channels) {
64
+ if (channels.length === 1) {
65
+ // Simple case is only one channel
66
+ const float32Array = channels[0].slice();
67
+ const meanValues = channels[0].slice();
68
+ return { float32Array, meanValues };
69
+ } else {
70
+ const float32Array = new Float32Array(
71
+ channels[0].length * channels.length
72
+ );
73
+ const meanValues = new Float32Array(channels[0].length);
74
+ for (let i = 0; i < channels[0].length; i++) {
75
+ const offset = i * channels.length;
76
+ let meanValue = 0;
77
+ for (let n = 0; n < channels.length; n++) {
78
+ float32Array[offset + n] = channels[n][i];
79
+ meanValue += channels[n][i];
80
+ }
81
+ meanValues[i] = meanValue / channels.length;
82
+ }
83
+ return { float32Array, meanValues };
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Converts 32-bit float data to 16-bit integers
89
+ */
90
+ floatTo16BitPCM(float32Array) {
91
+ const buffer = new ArrayBuffer(float32Array.length * 2);
92
+ const view = new DataView(buffer);
93
+ let offset = 0;
94
+ for (let i = 0; i < float32Array.length; i++, offset += 2) {
95
+ let s = Math.max(-1, Math.min(1, float32Array[i]));
96
+ view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);
97
+ }
98
+ return buffer;
99
+ }
100
+
101
+ /**
102
+ * Retrieves the most recent amplitude values from the audio stream
103
+ * @param {number} channel
104
+ */
105
+ getValues(channel = -1) {
106
+ const channels = this.readChannelData(this.chunks, channel);
107
+ const { meanValues } = this.formatAudioData(channels);
108
+ return { meanValues, channels };
109
+ }
110
+
111
+ /**
112
+ * Exports chunks as an audio/wav file
113
+ */
114
+ export() {
115
+ const channels = this.readChannelData(this.chunks);
116
+ const { float32Array, meanValues } = this.formatAudioData(channels);
117
+ const audioData = this.floatTo16BitPCM(float32Array);
118
+ return {
119
+ meanValues: meanValues,
120
+ audio: {
121
+ bitsPerSample: 16,
122
+ channels: channels,
123
+ data: audioData,
124
+ },
125
+ };
126
+ }
127
+
128
+ receive(e) {
129
+ const { event, id } = e.data;
130
+ let receiptData = {};
131
+ switch (event) {
132
+ case 'start':
133
+ this.recording = true;
134
+ break;
135
+ case 'stop':
136
+ this.recording = false;
137
+ break;
138
+ case 'clear':
139
+ this.initialize();
140
+ break;
141
+ case 'export':
142
+ receiptData = this.export();
143
+ break;
144
+ case 'read':
145
+ receiptData = this.getValues();
146
+ break;
147
+ default:
148
+ break;
149
+ }
150
+ // Always send back receipt
151
+ this.port.postMessage({ event: 'receipt', id, data: receiptData });
152
+ }
153
+
154
+ sendChunk(chunk) {
155
+ const channels = this.readChannelData([chunk]);
156
+ const { float32Array, meanValues } = this.formatAudioData(channels);
157
+ const rawAudioData = this.floatTo16BitPCM(float32Array);
158
+ const monoAudioData = this.floatTo16BitPCM(meanValues);
159
+ this.port.postMessage({
160
+ event: 'chunk',
161
+ data: {
162
+ mono: monoAudioData,
163
+ raw: rawAudioData,
164
+ },
165
+ });
166
+ }
167
+
168
+ process(inputList, outputList, parameters) {
169
+ // Copy input to output (e.g. speakers)
170
+ // Note that this creates choppy sounds with Mac products
171
+ const sourceLimit = Math.min(inputList.length, outputList.length);
172
+ for (let inputNum = 0; inputNum < sourceLimit; inputNum++) {
173
+ const input = inputList[inputNum];
174
+ const output = outputList[inputNum];
175
+ const channelCount = Math.min(input.length, output.length);
176
+ for (let channelNum = 0; channelNum < channelCount; channelNum++) {
177
+ input[channelNum].forEach((sample, i) => {
178
+ output[channelNum][i] = sample;
179
+ });
180
+ }
181
+ }
182
+ const inputs = inputList[0];
183
+ // There's latency at the beginning of a stream before recording starts
184
+ // Make sure we actually receive audio data before we start storing chunks
185
+ let sliceIndex = 0;
186
+ if (!this.foundAudio) {
187
+ for (const channel of inputs) {
188
+ sliceIndex = 0; // reset for each channel
189
+ if (this.foundAudio) {
190
+ break;
191
+ }
192
+ if (channel) {
193
+ for (const value of channel) {
194
+ if (value !== 0) {
195
+ // find only one non-zero entry in any channel
196
+ this.foundAudio = true;
197
+ break;
198
+ } else {
199
+ sliceIndex++;
200
+ }
201
+ }
202
+ }
203
+ }
204
+ }
205
+ if (inputs && inputs[0] && this.foundAudio && this.recording) {
206
+ // We need to copy the TypedArray, because the \`process\`
207
+ // internals will reuse the same buffer to hold each input
208
+ const chunk = inputs.map((input) => input.slice(sliceIndex));
209
+ this.chunks.push(chunk);
210
+ this.sendChunk(chunk);
211
+ }
212
+ return true;
213
+ }
214
+ }
215
+
216
+ registerProcessor('audio_processor', AudioProcessor);
217
+ `,mt=new Blob([pt],{type:"application/javascript"}),gt=URL.createObjectURL(mt),He=gt;var q=class{constructor({sampleRate:e=24e3,outputToSpeakers:t=!1,debug:s=!1}={}){this.scriptSrc=He,this.sampleRate=e,this.outputToSpeakers=t,this.debug=!!s,this._deviceChangeCallback=null,this._devices=[],this.stream=null,this.processor=null,this.source=null,this.node=null,this.recording=!1,this._lastEventId=0,this.eventReceipts={},this.eventTimeout=5e3,this._chunkProcessor=()=>{},this._chunkProcessorSize=void 0,this._chunkProcessorBuffer={raw:new ArrayBuffer(0),mono:new ArrayBuffer(0)};}static async decode(e,t=24e3,s=-1){let n=new AudioContext({sampleRate:t}),r,o;if(e instanceof Blob){if(s!==-1)throw new Error('Can not specify "fromSampleRate" when reading from Blob');o=e,r=await o.arrayBuffer();}else if(e instanceof ArrayBuffer){if(s!==-1)throw new Error('Can not specify "fromSampleRate" when reading from ArrayBuffer');r=e,o=new Blob([r],{type:"audio/wav"});}else {let c,f;if(e instanceof Int16Array){f=e,c=new Float32Array(e.length);for(let y=0;y<e.length;y++)c[y]=e[y]/32768;}else if(e instanceof Float32Array)c=e;else if(e instanceof Array)c=new Float32Array(e);else throw new Error('"audioData" must be one of: Blob, Float32Arrray, Int16Array, ArrayBuffer, Array<number>');if(s===-1)throw new Error('Must specify "fromSampleRate" when reading from Float32Array, In16Array or Array');if(s<3e3)throw new Error('Minimum "fromSampleRate" is 3000 (3kHz)');f||(f=T.floatTo16BitPCM(c));let p={bitsPerSample:16,channels:[c],data:f};o=new T().pack(s,p).blob,r=await o.arrayBuffer();}let a=await n.decodeAudioData(r),u=a.getChannelData(0),d=URL.createObjectURL(o);return {blob:o,url:d,values:u,audioBuffer:a}}log(){return this.debug&&this.log(...arguments),!0}getSampleRate(){return this.sampleRate}getStatus(){return this.processor?this.recording?"recording":"paused":"ended"}async _event(e,t={},s=null){if(s=s||this.processor,!s)throw new Error("Can not send events without recording first");let n={event:e,id:this._lastEventId++,data:t};s.port.postMessage(n);let r=new Date().valueOf();for(;!this.eventReceipts[n.id];){if(new Date().valueOf()-r>this.eventTimeout)throw new Error(`Timeout waiting for "${e}" event`);await new Promise(a=>setTimeout(()=>a(!0),1));}let o=this.eventReceipts[n.id];return delete this.eventReceipts[n.id],o}listenForDeviceChange(e){if(e===null&&this._deviceChangeCallback)navigator.mediaDevices.removeEventListener("devicechange",this._deviceChangeCallback),this._deviceChangeCallback=null;else if(e!==null){let t=0,s=[],n=o=>o.map(a=>a.deviceId).sort().join(","),r=async()=>{let o=++t,a=await this.listDevices();o===t&&n(s)!==n(a)&&(s=a,e(a.slice()));};navigator.mediaDevices.addEventListener("devicechange",r),r(),this._deviceChangeCallback=r;}return !0}async requestPermission(){let e=await navigator.permissions.query({name:"microphone"});if(e.state==="denied")window.alert("You must grant microphone access to use this feature.");else if(e.state==="prompt")try{(await navigator.mediaDevices.getUserMedia({audio:!0})).getTracks().forEach(n=>n.stop());}catch{window.alert("You must grant microphone access to use this feature.");}return !0}async listDevices(){if(!navigator.mediaDevices||!("enumerateDevices"in navigator.mediaDevices))throw new Error("Could not request user devices");await this.requestPermission();let t=(await navigator.mediaDevices.enumerateDevices()).filter(r=>r.kind==="audioinput"),s=t.findIndex(r=>r.deviceId==="default"),n=[];if(s!==-1){let r=t.splice(s,1)[0],o=t.findIndex(a=>a.groupId===r.groupId);o!==-1&&(r=t.splice(o,1)[0]),r.default=!0,n.push(r);}return n.concat(t)}async begin(e){if(this.processor)throw new Error("Already connected: please call .end() to start a new session");if(!navigator.mediaDevices||!("getUserMedia"in navigator.mediaDevices))throw new Error("Could not request user media");try{let a={audio:!0};e&&(a.audio={deviceId:{exact:e}}),this.stream=await navigator.mediaDevices.getUserMedia(a);}catch{throw new Error("Could not start media stream")}let t=new AudioContext({sampleRate:this.sampleRate}),s=t.createMediaStreamSource(this.stream);try{await t.audioWorklet.addModule(this.scriptSrc);}catch(a){throw console.error(a),new Error(`Could not add audioWorklet module: ${this.scriptSrc}`)}let n=new AudioWorkletNode(t,"audio_processor");n.port.onmessage=a=>{let{event:u,id:d,data:c}=a.data;if(u==="receipt")this.eventReceipts[d]=c;else if(u==="chunk")if(this._chunkProcessorSize){let f=this._chunkProcessorBuffer;this._chunkProcessorBuffer={raw:T.mergeBuffers(f.raw,c.raw),mono:T.mergeBuffers(f.mono,c.mono)},this._chunkProcessorBuffer.mono.byteLength>=this._chunkProcessorSize&&(this._chunkProcessor(this._chunkProcessorBuffer),this._chunkProcessorBuffer={raw:new ArrayBuffer(0),mono:new ArrayBuffer(0)});}else this._chunkProcessor(c);};let r=s.connect(n),o=t.createAnalyser();return o.fftSize=8192,o.smoothingTimeConstant=.1,r.connect(o),this.outputToSpeakers&&(console.warn(`Warning: Output to speakers may affect sound quality,
218
+ especially due to system audio feedback preventative measures.
219
+ use only for debugging`),o.connect(t.destination)),this.source=s,this.node=r,this.analyser=o,this.processor=n,!0}getFrequencies(e="frequency",t=-100,s=-30){if(!this.processor)throw new Error("Session ended: please call .begin() first");return F.getFrequencies(this.analyser,this.sampleRate,null,e,t,s)}async pause(){if(this.processor){if(!this.recording)throw new Error("Already paused: please call .record() first")}else throw new Error("Session ended: please call .begin() first");return this._chunkProcessorBuffer.raw.byteLength&&this._chunkProcessor(this._chunkProcessorBuffer),this.log("Pausing ..."),await this._event("stop"),this.recording=!1,!0}async record(e=()=>{},t=8192){if(this.processor){if(this.recording)throw new Error("Already recording: please call .pause() first");if(typeof e!="function")throw new Error("chunkProcessor must be a function")}else throw new Error("Session ended: please call .begin() first");return this._chunkProcessor=e,this._chunkProcessorSize=t,this._chunkProcessorBuffer={raw:new ArrayBuffer(0),mono:new ArrayBuffer(0)},this.log("Recording ..."),await this._event("start"),this.recording=!0,!0}async clear(){if(!this.processor)throw new Error("Session ended: please call .begin() first");return await this._event("clear"),!0}async read(){if(!this.processor)throw new Error("Session ended: please call .begin() first");return this.log("Reading ..."),await this._event("read")}async save(e=!1){if(!this.processor)throw new Error("Session ended: please call .begin() first");if(!e&&this.recording)throw new Error("Currently recording: please call .pause() first, or call .save(true) to force");this.log("Exporting ...");let t=await this._event("export");return new T().pack(this.sampleRate,t.audio)}async end(){if(!this.processor)throw new Error("Session ended: please call .begin() first");let e=this.processor;this.log("Stopping ..."),await this._event("stop"),this.recording=!1,this.stream.getTracks().forEach(o=>o.stop()),this.log("Exporting ...");let s=await this._event("export",{},e);return this.processor.disconnect(),this.source.disconnect(),this.node.disconnect(),this.analyser.disconnect(),this.stream=null,this.processor=null,this.source=null,this.node=null,new T().pack(this.sampleRate,s.audio)}async quit(){return this.listenForDeviceChange(null),this.processor&&await this.end(),!0}};globalThis.WavRecorder=q;var yt=`
220
+ class StreamProcessor extends AudioWorkletProcessor {
221
+ constructor() {
222
+ super();
223
+ this.hasStarted = false;
224
+ this.hasInterrupted = false;
225
+ this.outputBuffers = [];
226
+ this.bufferLength = 128;
227
+ this.write = { buffer: new Float32Array(this.bufferLength), trackId: null };
228
+ this.writeOffset = 0;
229
+ this.trackSampleOffsets = {};
230
+ this.port.onmessage = (event) => {
231
+ if (event.data) {
232
+ const payload = event.data;
233
+ if (payload.event === 'write') {
234
+ const int16Array = payload.buffer;
235
+ const float32Array = new Float32Array(int16Array.length);
236
+ for (let i = 0; i < int16Array.length; i++) {
237
+ float32Array[i] = int16Array[i] / 0x8000; // Convert Int16 to Float32
238
+ }
239
+ this.writeData(float32Array, payload.trackId);
240
+ } else if (
241
+ payload.event === 'offset' ||
242
+ payload.event === 'interrupt'
243
+ ) {
244
+ const requestId = payload.requestId;
245
+ const trackId = this.write.trackId;
246
+ const offset = this.trackSampleOffsets[trackId] || 0;
247
+ this.port.postMessage({
248
+ event: 'offset',
249
+ requestId,
250
+ trackId,
251
+ offset,
252
+ });
253
+ if (payload.event === 'interrupt') {
254
+ this.hasInterrupted = true;
255
+ }
256
+ } else {
257
+ throw new Error(\`Unhandled event "\${payload.event}"\`);
258
+ }
259
+ }
260
+ };
261
+ }
262
+
263
+ writeData(float32Array, trackId = null) {
264
+ let { buffer } = this.write;
265
+ let offset = this.writeOffset;
266
+ for (let i = 0; i < float32Array.length; i++) {
267
+ buffer[offset++] = float32Array[i];
268
+ if (offset >= buffer.length) {
269
+ this.outputBuffers.push(this.write);
270
+ this.write = { buffer: new Float32Array(this.bufferLength), trackId };
271
+ buffer = this.write.buffer;
272
+ offset = 0;
273
+ }
274
+ }
275
+ this.writeOffset = offset;
276
+ return true;
277
+ }
278
+
279
+ process(inputs, outputs, parameters) {
280
+ const output = outputs[0];
281
+ const outputChannelData = output[0];
282
+ const outputBuffers = this.outputBuffers;
283
+ if (this.hasInterrupted) {
284
+ this.port.postMessage({ event: 'stop' });
285
+ return false;
286
+ } else if (outputBuffers.length) {
287
+ this.hasStarted = true;
288
+ const { buffer, trackId } = outputBuffers.shift();
289
+ for (let i = 0; i < outputChannelData.length; i++) {
290
+ outputChannelData[i] = buffer[i] || 0;
291
+ }
292
+ if (trackId) {
293
+ this.trackSampleOffsets[trackId] =
294
+ this.trackSampleOffsets[trackId] || 0;
295
+ this.trackSampleOffsets[trackId] += buffer.length;
296
+ }
297
+ return true;
298
+ } else if (this.hasStarted) {
299
+ this.port.postMessage({ event: 'stop' });
300
+ return false;
301
+ } else {
302
+ return true;
303
+ }
304
+ }
305
+ }
306
+
307
+ registerProcessor('stream_processor', StreamProcessor);
308
+ `,kt=new Blob([yt],{type:"application/javascript"}),St=URL.createObjectURL(kt),Ke=St;var U=class{constructor({sampleRate:e=24e3,onStop:t}={}){this.scriptSrc=Ke,this.onStop=t,this.sampleRate=e,this.context=null,this.stream=null,this.analyser=null,this.trackSampleOffsets={},this.interruptedTrackIds={};}async connect(){this.context=new AudioContext({sampleRate:this.sampleRate}),this.context.state==="suspended"&&await this.context.resume();try{await this.context.audioWorklet.addModule(this.scriptSrc);}catch(t){throw console.error(t),new Error(`Could not add audioWorklet module: ${this.scriptSrc}`)}let e=this.context.createAnalyser();return e.fftSize=8192,e.smoothingTimeConstant=.1,this.analyser=e,!0}getFrequencies(e="frequency",t=-100,s=-30){if(!this.analyser)throw new Error("Not connected, please call .connect() first");return F.getFrequencies(this.analyser,this.sampleRate,null,e,t,s)}_start(){let e=new AudioWorkletNode(this.context,"stream_processor");return e.connect(this.context.destination),e.port.onmessage=t=>{let{event:s}=t.data;if(s==="stop")this.onStop?.(),e.disconnect(),this.stream=null;else if(s==="offset"){let{requestId:n,trackId:r,offset:o}=t.data,a=o/this.sampleRate;this.trackSampleOffsets[n]={trackId:r,offset:o,currentTime:a};}},this.analyser.disconnect(),e.connect(this.analyser),this.stream=e,!0}add16BitPCM(e,t="default"){if(typeof t!="string")throw new Error("trackId must be a string");if(this.interruptedTrackIds[t])return;this.stream||this._start();let s;if(e instanceof Int16Array)s=e;else if(e instanceof ArrayBuffer)s=new Int16Array(e);else throw new Error("argument must be Int16Array or ArrayBuffer");return this.stream.port.postMessage({event:"write",buffer:s,trackId:t}),s}async getTrackSampleOffset(e=!1){if(!this.stream)return null;let t=crypto.randomUUID();this.stream.port.postMessage({event:e?"interrupt":"offset",requestId:t});let s;for(;!s;)s=this.trackSampleOffsets[t],await new Promise(r=>setTimeout(()=>r(),1));let{trackId:n}=s;return e&&n&&(this.interruptedTrackIds[n]=!0),s}async interrupt(){return this.getTrackSampleOffset(!0)}};globalThis.WavStreamPlayer=U;var ie=atom({key:"ThreadIdToResume",default:void 0}),Je=atom({key:"ChatProfile",default:void 0}),Ge=atom({key:"SessionId",default:v4()}),Z=selector({key:"SessionIdSelector",get:({get:i})=>i(Ge),set:({set:i},e)=>i(Ge,e instanceof DefaultValue?v4():e)}),V=atom({key:"Session",dangerouslyAllowMutability:!0,default:void 0}),O=atom({key:"Actions",default:[]}),j=atom({key:"Messages",dangerouslyAllowMutability:!0,default:[]}),ae=atom({key:"TokenCount",default:0}),$=atom({key:"Loading",default:!1}),z=atom({key:"AskUser",default:void 0}),ce=atom({key:"WavRecorder",dangerouslyAllowMutability:!0,default:new q}),le=atom({key:"WavStreamPlayer",dangerouslyAllowMutability:!0,default:new U}),ue=atom({key:"AudioConnection",default:"off"}),fe=atom({key:"isAiSpeaking",default:!1}),he=atom({key:"CallFn",default:void 0}),L=atom({key:"ChatSettings",default:[]}),_e=selector({key:"ChatSettingsValue/Default",get:({get:i})=>i(L).reduce((t,s)=>(t[s.id]=s.initial,t),{})}),N=atom({key:"ChatSettingsValue",default:_e}),W=atom({key:"DisplayElements",default:[]}),H=atom({key:"TasklistElements",default:[]}),K=atom({key:"FirstUserInteraction",default:void 0}),G=atom({key:"AccessToken",default:void 0}),Qe=atom({key:"User",default:null}),Ze=atom({key:"ChainlitConfig",default:void 0}),et=atom({key:"AuthConfig",default:void 0}),tt=atom({key:"ThreadHistory",default:{threads:void 0,currentThreadId:void 0,timeGroupedThreads:void 0,pageInfo:void 0},effects:[({setSelf:i,onSet:e})=>{e((t,s)=>{let n=t?.timeGroupedThreads;t?.threads&&!isEqual(t.threads,s?.timeGroupedThreads)&&(n=ze(t.threads)),i({...t,timeGroupedThreads:n});});}]}),st=atom({key:"SideView",default:void 0}),X=atom({key:"CurrentThreadId",default:void 0});var ms=()=>{let i=useRecoilValue($),e=useRecoilValue(W),t=useRecoilValue(H),s=useRecoilValue(O),n=useRecoilValue(V),r=useRecoilValue(z),o=useRecoilValue(he),a=useRecoilValue(L),u=useRecoilValue(N),d=useRecoilValue(_e),c=n?.socket.connected&&!n?.error,f=!c||i||r?.spec.type==="file"||r?.spec.type==="action";return {actions:s,askUser:r,callFn:o,chatSettingsDefaultValue:d,chatSettingsInputs:a,chatSettingsValue:u,connected:c,disabled:f,elements:e,error:n?.error,loading:i,tasklists:t}};var ks=i=>{let e=[];for(let t of i)e=R(e,t);return e},Ss=(i,e)=>{if(i.length-1===e)return !0;for(let t=e+1;t<i.length;t++)if(!i[t].streaming)return !1;return !0},R=(i,e)=>pe(i,e.id)?me(i,e.id,e):"parentId"in e&&e.parentId?rt(i,e.parentId,e):"indent"in e&&e.indent&&e.indent>0?nt(i,e.indent,e):[...i,e],nt=(i,e,t,s=0)=>{let n=[...i];if(n.length===0)return [...n,t];{let r=n.length-1,o=n[r];return o.steps=o.steps||[],s+1===e?(o.steps=[...o.steps,t],n[r]={...o},n):(o.steps=nt(o.steps,e,t,s+1),n[r]={...o},n)}},rt=(i,e,t)=>{let s=[...i];for(let n=0;n<s.length;n++){let r=s[n];isEqual(r.id,e)?(r.steps=r.steps?[...r.steps,t]:[t],s[n]={...r}):pe(s,e)&&r.steps&&(r.steps=rt(r.steps,e,t),s[n]={...r});}return s},ot=(i,e)=>{for(let t of i){if(isEqual(t.id,e))return t;if(t.steps&&t.steps.length>0){let s=ot(t.steps,e);if(s)return s}}},pe=(i,e)=>ot(i,e)!==void 0,me=(i,e,t)=>{let s=[...i];for(let n=0;n<s.length;n++){let r=s[n];isEqual(r.id,e)?s[n]={steps:r.steps,...t}:pe(s,e)&&r.steps&&(r.steps=me(r.steps,e,t),s[n]={...r});}return s},De=(i,e)=>{let t=[...i];for(let s=0;s<t.length;s++){let n=t[s];n.id===e?t=[...t.slice(0,s),...t.slice(s+1)]:pe(t,e)&&n.steps&&(n.steps=De(n.steps,e),t[s]={...n});}return t},Me=(i,e,t,s,n)=>{let r=[...i];for(let o=0;o<r.length;o++){let a=r[o];isEqual(a.id,e)?("content"in a&&a.content!==void 0?s?a.content=t:a.content+=t:n?"input"in a&&a.input!==void 0&&(s?a.input=t:a.input+=t):"output"in a&&a.output!==void 0&&(s?a.output=t:a.output+=t),r[o]={...a}):a.steps&&(a.steps=Me(a.steps,e,t,s,n),r[o]={...a});}return r};var Ee="token";function Re(){try{return localStorage.getItem(Ee)}catch{return}}function it(i){try{return localStorage.setItem(Ee,i)}catch{return}}function ge(){try{return localStorage.removeItem(Ee)}catch{return}}var bt=async(i,e,t)=>(await i.get(e,t))?.json();function ye(i,{token:e,...t}={}){let s=useContext(B),n=useRecoilValue(G);n=e||n;let r=useMemo(()=>([a,u])=>bt(s,a,u),[s]),o=useMemo(()=>i?[i,n]:null,[i,n]);return vt(o,r,t)}var lt=()=>{let i=useContext(B),[e,t]=useRecoilState(et),[s,n]=useRecoilState(Qe),{data:r,isLoading:o}=ye(e?null:"/auth/config"),[a,u]=useRecoilState(G),d=useSetRecoilState(tt);useEffect(()=>{r&&t(r);},[r,t]);let c=!!(!o&&e),f=async(m=!1)=>{await i.logout(),n(null),ge(),u(""),d(void 0),m&&window.location.reload();},p=m=>{if(!m){f();return}try{let{exp:y,...C}=Ct(m);it(m),u(`Bearer ${m}`),n(C);}catch(y){console.error("Invalid token, clearing token from local storage","error:",y),f();}};useEffect(()=>{if(!s&&Re()){p(Re());return}},[]);let k=!!a;return e&&!e.requireLogin?{authConfig:e,user:null,isReady:c,isAuthenticated:!0,accessToken:"",logout:()=>{},setAccessToken:()=>{}}:{data:e,user:s,isAuthenticated:k,isReady:c,accessToken:a,logout:f,setAccessToken:p}};var ke=class extends Error{constructor(t,s){super(t);this.detail=s;}toString(){return this.detail?`${this.message}: ${this.detail}`:this.message}},Be=class{constructor(e,t,s,n){this.httpEndpoint=e;this.type=t;this.on401=s;this.onError=n;}buildEndpoint(e){return this.httpEndpoint.endsWith("/")?`${this.httpEndpoint.slice(0,-1)}${e}`:`${this.httpEndpoint}${e}`}checkToken(e){let t="Bearer ";return e.startsWith(t)?e:t+e}async fetch(e,t,s,n,r){try{let o={};s&&(o.Authorization=this.checkToken(s));let a;n instanceof FormData?a=n:(o["Content-Type"]="application/json",a=n?JSON.stringify(n):null);let u=await fetch(this.buildEndpoint(t),{method:e,headers:o,signal:r,body:a});if(!u.ok){let d=await u.json();throw u.status===401&&this.on401&&(ge(),this.on401()),new ke(u.statusText,d.detail)}return u}catch(o){throw o instanceof ke&&this.onError&&this.onError(o),console.error(o),o}}async get(e,t){return await this.fetch("GET",e,t)}async post(e,t,s,n){return await this.fetch("POST",e,s,t,n)}async put(e,t,s){return await this.fetch("PUT",e,s,t)}async patch(e,t,s){return await this.fetch("PATCH",e,s,t)}async delete(e,t,s){return await this.fetch("DELETE",e,s,t)}},Se=class extends Be{async headerAuth(){return (await this.post("/auth/header",{})).json()}async passwordAuth(e){return (await this.post("/login",e)).json()}async logout(){return (await this.post("/logout",{})).json()}async setFeedback(e,t){return (await this.put("/feedback",{feedback:e},t)).json()}async deleteFeedback(e,t){return (await this.delete("/feedback",{feedbackId:e},t)).json()}async listThreads(e,t,s){return (await this.post("/project/threads",{pagination:e,filter:t},s)).json()}async deleteThread(e,t){return (await this.delete("/project/thread",{threadId:e},t)).json()}uploadFile(e,t,s,n){let r=new XMLHttpRequest,o=new Promise((a,u)=>{let d=new FormData;d.append("file",e),r.open("POST",this.buildEndpoint(`/project/file?session_id=${s}`),!0),n&&r.setRequestHeader("Authorization",this.checkToken(n)),r.upload.onprogress=function(c){if(c.lengthComputable){let f=c.loaded/c.total*100;t(f);}},r.onload=function(){if(r.status===200){let c=JSON.parse(r.responseText);a(c);}else u("Upload failed");},r.onerror=function(){u("Upload error");},r.send(d);});return {xhr:r,promise:o}}getElementUrl(e,t){let s=`?session_id=${t}`;return this.buildEndpoint(`/project/file/${e}${s}`)}getLogoEndpoint(e){return this.buildEndpoint(`/logo?theme=${e}`)}getOAuthEndpoint(e){return this.buildEndpoint(`/auth/oauth/${e}`)}};var zs=void 0,B=createContext(new Se("http://localhost:8000","webapp"));var ut=()=>{let i=useContext(B),e=useRecoilValue(G),t=useRecoilValue(V),s=useRecoilValue(z),n=useRecoilValue(Z),r=useResetRecoilState(L),o=useResetRecoilState(Z),a=useResetRecoilState(N),u=useSetRecoilState(K),d=useSetRecoilState($),c=useSetRecoilState(j),f=useSetRecoilState(W),p=useSetRecoilState(H),k=useSetRecoilState(O),m=useSetRecoilState(ae),y=useSetRecoilState(ie),C=useSetRecoilState(st),Y=useSetRecoilState(X),J=useCallback(()=>{t?.socket.emit("clear_session"),t?.socket.disconnect(),y(void 0),o(),u(void 0),c([]),f([]),p([]),k([]),m(0),r(),a(),C(void 0),Y(void 0);},[t]),v=useCallback((I,x=[])=>{I.id||(I.id=v4()),I.createdAt||(I.createdAt=new Date().toISOString()),c(M=>R(M,I)),t?.socket.emit("client_message",{message:I,fileReferences:x});},[t?.socket]),ee=useCallback(I=>{t?.socket.emit("edit_message",{message:I});},[t?.socket]),te=useCallback(()=>{t?.socket.emit("audio_start");},[t?.socket]),se=useCallback((I,x,M,Q)=>{t?.socket.emit("audio_chunk",{isStart:I,mimeType:x,elapsedTime:M,data:Q});},[t?.socket]),Ae=useCallback(()=>{t?.socket.emit("audio_end");},[t?.socket]),ne=useCallback(I=>{s&&(c(x=>R(x,I)),s.callback(I));},[s]),xe=useCallback(I=>{t?.socket.emit("chat_settings_change",I);},[t?.socket]),ve=useCallback(()=>{c(I=>I.map(x=>(x.streaming=!1,x))),d(!1),t?.socket.emit("stop");},[t?.socket]),be=useCallback(I=>{let x=t?.socket;if(!x)return;let M=new Promise((Q,Ce)=>{x.once("action_response",g=>{g.status?Q(g):Ce(g);});});return x.emit("action_call",I),M},[t?.socket]);return {uploadFile:useCallback((I,x)=>i.uploadFile(I,x,n,e),[n,e]),callAction:be,clear:J,replyMessage:ne,sendMessage:v,editMessage:ee,startAudioStream:te,sendAudioChunk:se,endAudioStream:Ae,stopTask:ve,setIdToResume:y,updateChatSettings:xe}};var en=()=>{let i=useRecoilValue(j),e=useRecoilValue(K);return {threadId:useRecoilValue(X),messages:i,firstInteraction:e}};var un=()=>{let i=useContext(B),e=useRecoilValue(Z),[t,s]=useRecoilState(V),n=useSetRecoilState(fe),r=useSetRecoilState(ue),o=useResetRecoilState(N),a=useSetRecoilState(K),u=useSetRecoilState($),d=useRecoilValue(le),c=useRecoilValue(ce),f=useSetRecoilState(j),p=useSetRecoilState(z),k=useSetRecoilState(he),m=useSetRecoilState(W),y=useSetRecoilState(H),C=useSetRecoilState(O),Y=useSetRecoilState(L),J=useSetRecoilState(ae),[v,ee]=useRecoilState(Je),te=useRecoilValue(ie),[se,Ae]=useRecoilState(X);useEffect(()=>{t?.socket&&(t.socket.io.opts.extraHeaders["X-Chainlit-Thread-Id"]=se||"");},[se]);let ne=useCallback(({userEnv:be,accessToken:$e})=>{let{protocol:I,host:x,pathname:M}=new URL(i.httpEndpoint),Q=`${I}//${x}`,Ce=M&&M!=="/"?`${M}/ws/socket.io`:"/ws/socket.io",g=Lt(Q,{path:Ce,extraHeaders:{Authorization:$e||"","X-Chainlit-Client-Type":i.type,"X-Chainlit-Session-Id":e,"X-Chainlit-Thread-Id":te||"","user-env":JSON.stringify(be),"X-Chainlit-Chat-Profile":v?encodeURIComponent(v):""}});s(l=>(l?.socket?.removeAllListeners(),l?.socket?.close(),{socket:g})),g.on("connect",()=>{g.emit("connection_successful"),s(l=>({...l,error:!1}));}),g.on("connect_error",l=>{s(h=>({...h,error:!0}));}),g.on("task_start",()=>{u(!0);}),g.on("task_end",()=>{u(!1);}),g.on("reload",()=>{g.emit("clear_session"),window.location.reload();}),g.on("audio_connection",async l=>{if(l==="on"){let h=!0,S=Date.now(),A="pcm16";await c.begin(),await d.connect(),await c.record(async Te=>{let ht=Date.now()-S;g.emit("audio_chunk",{isStart:h,mimeType:A,elapsedTime:ht,data:Te.mono}),h=!1;}),d.onStop=()=>n(!1);}else await c.end(),await d.interrupt();r(l);}),g.on("audio_chunk",l=>{d.add16BitPCM(l.data,l.track),n(!0);}),g.on("audio_interrupt",()=>{d.interrupt();}),g.on("resume_thread",l=>{let h=[];for(let A of l.steps)h=R(h,A);l.metadata?.chat_profile&&ee(l.metadata?.chat_profile),f(h);let S=l.elements||[];y(S.filter(A=>A.type==="tasklist")),m(S.filter(A=>["avatar","tasklist"].indexOf(A.type)===-1));}),g.on("new_message",l=>{f(h=>R(h,l));}),g.on("first_interaction",l=>{a(l.interaction),Ae(l.thread_id);}),g.on("update_message",l=>{f(h=>me(h,l.id,l));}),g.on("delete_message",l=>{f(h=>De(h,l.id));}),g.on("stream_start",l=>{f(h=>R(h,l));}),g.on("stream_token",({id:l,token:h,isSequence:S,isInput:A})=>{f(Te=>Me(Te,l,h,S,A));}),g.on("ask",({msg:l,spec:h},S)=>{p({spec:h,callback:S}),f(A=>R(A,l)),u(!1);}),g.on("ask_timeout",()=>{p(void 0),u(!1);}),g.on("clear_ask",()=>{p(void 0);}),g.on("call_fn",({name:l,args:h},S)=>{k({name:l,args:h,callback:S});}),g.on("clear_call_fn",()=>{k(void 0);}),g.on("call_fn_timeout",()=>{k(void 0);}),g.on("chat_settings",l=>{Y(l),o();}),g.on("element",l=>{!l.url&&l.chainlitKey&&(l.url=i.getElementUrl(l.chainlitKey,e)),l.type==="tasklist"?y(h=>{let S=h.findIndex(A=>A.id===l.id);return S===-1?[...h,l]:[...h.slice(0,S),l,...h.slice(S+1)]}):m(h=>{let S=h.findIndex(A=>A.id===l.id);return S===-1?[...h,l]:[...h.slice(0,S),l,...h.slice(S+1)]});}),g.on("remove_element",l=>{m(h=>h.filter(S=>S.id!==l.id)),y(h=>h.filter(S=>S.id!==l.id));}),g.on("action",l=>{C(h=>[...h,l]);}),g.on("remove_action",l=>{C(h=>{let S=h.findIndex(A=>A.id===l.id);return S===-1?h:[...h.slice(0,S),...h.slice(S+1)]});}),g.on("token_usage",l=>{J(h=>h+l);});},[s,e,v]),xe=useCallback(debounce(ne,200),[ne]),ve=useCallback(()=>{t?.socket&&(t.socket.removeAllListeners(),t.socket.close());},[t]);return {connect:xe,disconnect:ve,session:t,sessionId:e,chatProfile:v,idToResume:te,setChatProfile:ee}};var gn=()=>{let[i,e]=useRecoilState(ue),t=useRecoilValue(ce),s=useRecoilValue(le),n=useRecoilValue(fe),{startAudioStream:r,endAudioStream:o}=ut(),a=useCallback(async()=>{e("connecting"),await r();},[r]),u=useCallback(async()=>{e("off"),await t.end(),await s.interrupt(),await o();},[o,t,s]);return {startConversation:a,endConversation:u,audioConnection:i,isAiSpeaking:n,wavRecorder:t,wavStreamPlayer:s}};var An=i=>{let[e,t]=useRecoilState(Ze),{isAuthenticated:s}=lt(),n=navigator.language||"en-US",{data:r,error:o,isLoading:a}=ye(!e&&s?`/project/settings?language=${n}`:null,{token:i});return useEffect(()=>{r&&t(r);},[r,t]),{config:e,error:o,isLoading:a,language:n}};var je=new WeakMap,Ot=(i,e,t=!1,s=!1)=>{let n,r,o;if(s&&(r=e.toString(),o=t.toString(),n=je.has(i)?je.get(i):{},je.set(i,n),n[r]=n[r]||{},n[r][o]))return n[r][o];let a=i.length,u=new Array(e);if(e<=a){u.fill(0);let d=new Array(e).fill(0);for(let c=0;c<a;c++){let f=Math.floor(c*(e/a));t?u[f]=Math.max(u[f],Math.abs(i[c])):u[f]+=Math.abs(i[c]),d[f]++;}if(!t)for(let c=0;c<u.length;c++)u[c]=u[c]/d[c];}else for(let d=0;d<e;d++){let c=d*(a-1)/(e-1),f=Math.floor(c),p=Math.ceil(c),k=c-f;p>=a?u[d]=i[a-1]:u[d]=i[f]*(1-k)+i[p]*k;}return s&&(n[r][o]=u),u},jt={drawBars:(i,e,t,s,n,r=0,o=0,a=0,u=!1)=>{r=Math.floor(Math.min(r,(t-a)/(Math.max(o,1)+a))),r||(r=Math.floor((t-a)/(Math.max(o,1)+a))),o||(o=(t-a)/r-a);let d=Ot(e,r,!0);for(let c=0;c<r;c++){let f=Math.abs(d[c]),p=Math.max(1,f*s),k=a+c*(o+a),m=u?(s-p)/2:s-p,y=Math.min(o/2,p/2);i.fillStyle=n,i.beginPath(),i.moveTo(k+y,m),i.lineTo(k+o-y,m),i.arcTo(k+o,m,k+o,m+y,y),i.lineTo(k+o,m+p-y),i.arcTo(k+o,m+p,k+o-y,m+p,y),i.lineTo(k+y,m+p),i.arcTo(k,m+p,k,m+p-y,y),i.lineTo(k,m+y),i.arcTo(k,m,k+y,m,y),i.closePath(),i.fill();}}};
309
+
310
+ export { Be as APIBase, Se as ChainlitAPI, B as ChainlitContext, ke as ClientError, jt as WavRenderer, G as accessTokenState, O as actionState, R as addMessage, rt as addMessageToParent, z as askUserState, ue as audioConnectionState, et as authState, he as callFnState, Je as chatProfileState, _e as chatSettingsDefaultValueSelector, L as chatSettingsInputsState, N as chatSettingsValueState, Ze as configState, X as currentThreadIdState, zs as defaultChainlitContext, De as deleteMessageById, W as elementState, bt as fetcher, K as firstUserInteraction, pe as hasMessageById, fe as isAiSpeakingState, Ss as isLastMessage, $ as loadingState, j as messagesState, ks as nestMessages, Z as sessionIdState, V as sessionState, st as sideViewState, H as tasklistState, tt as threadHistoryState, ie as threadIdToResumeState, ae as tokenCountState, me as updateMessageById, Me as updateMessageContentById, ye as useApi, gn as useAudio, lt as useAuth, ms as useChatData, ut as useChatInteract, en as useChatMessages, un as useChatSession, An as useConfig, Qe as userState, ce as wavRecorderState, le as wavStreamPlayerState };
13
311
  //# sourceMappingURL=out.js.map
14
312
  //# sourceMappingURL=index.mjs.map