@applica-software-guru/persona-sdk 0.1.79 → 0.1.80

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.
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * This source code is licensed under the MIT license found in the
8
8
  * LICENSE file in the root directory of this source tree.
9
- */var Ji;function Oo(){if(Ji)return ne;Ji=1;var y=Symbol.for("react.transitional.element"),p=Symbol.for("react.fragment");function i(w,m,C){var b=null;if(C!==void 0&&(b=""+C),m.key!==void 0&&(b=""+m.key),"key"in m){C={};for(var I in m)I!=="key"&&(C[I]=m[I])}else C=m;return m=C.ref,{$$typeof:y,type:w,key:b,ref:m!==void 0?m:null,props:C}}return ne.Fragment=p,ne.jsx=i,ne.jsxs=i,ne}Ki.exports=Oo();var xr=Ki.exports;function Wo(y){return y.filter(p=>p.finishReason==="stop"?p.text!==null&&p.text.trim()!=="":!0)}function Yi(y){const p=[];let i=null;for(const m of y)m.type!=="transaction"&&(m.functionCalls?(i&&p.push(i),p.push(m),i=null):m.functionResponse?p[p.length-1]={...p[p.length-1],functionResponse:m.functionResponse}:i&&m.type===i.type&&m.protocol===i.protocol&&i.role===m.role?(i.text+=m.file?"":m.text,i.file=i.file||m.file):(i&&p.push(i),i={...m}));return i&&p.push(i),Wo(p)}function Mo(y){var i;const p=y.file?[{type:"file",data:y.file.url,mimeType:y.file.contentType}]:[];return y.role==="function"?{id:y.id,role:"assistant",status:(y==null?void 0:y.functionResponse)===null?{type:"running"}:{type:"complete",reason:"stop"},content:((i=y.functionCalls)==null?void 0:i.map(w=>{var m;return{type:"tool-call",toolName:w.name,toolCallId:w.id,args:w.args,result:(m=y.functionResponse)==null?void 0:m.result}}))??[]}:{id:y.id,role:y.role,content:y.type==="reasoning"?[{type:"reasoning",text:y.text},...p]:[{type:"text",text:y.text},...p]}}class te{constructor(){E(this,"statusChangeCallbacks",[]);E(this,"messageCallbacks",[])}addStatusChangeListener(p){this.statusChangeCallbacks.push(p)}addPacketListener(p){this.messageCallbacks.push(p)}async syncSession(p){this.session=p}async notifyPacket(p){this.messageCallbacks.forEach(i=>i(p))}async notifyPackets(p){p.forEach(i=>{this.messageCallbacks.forEach(w=>w(i))})}async setSession(p){this.session=p}async setStatus(p){const i=this.status!==p;this.status=p,i&&this.statusChangeCallbacks.forEach(w=>w(p))}clearListeners(){this.statusChangeCallbacks=[],this.messageCallbacks=[]}onTransaction(p){}}class Sr extends te{constructor(i){super();E(this,"status");E(this,"autostart");E(this,"session");E(this,"config");E(this,"notify",!0);E(this,"context",{});E(this,"tools",[]);this.config=i,this.status="disconnected",this.autostart=!0}getName(){return"rest"}getPriority(){return 100}async connect(i){return this.setStatus("connected"),i}async disconnect(){this.setStatus("disconnected"),this.session=null}async syncSession(i){this.session=i}async sendPacket(i){var $,rn,bn,un,Rn;const{apiUrl:w,apiKey:m,agentId:C}=this.config,b=this.session??"new";if(i.type==="command"&&(($=i==null?void 0:i.payload)==null?void 0:$.command)=="set_initial_context"){this.context=(rn=i==null?void 0:i.payload)==null?void 0:rn.arguments;return}else if(i.type==="command"&&((bn=i==null?void 0:i.payload)==null?void 0:bn.command)=="set_local_tools"){const pn=(un=i==null?void 0:i.payload)==null?void 0:un.arguments.tools;(pn==null?void 0:pn.length)>0&&this.notifyPacket({type:"message",payload:{type:"text",role:"assistant",text:"Local tools with rest protocol are not supported."}});return}const I=i.payload;try{const Tn=await(await fetch(`${w}/sessions/${b}/messages`,{body:JSON.stringify({agentId:C,userMessage:I,initialContext:this.context,tools:this.tools}),method:"POST",headers:{"Content-Type":"application/json","x-persona-apikey":m}})).json();this.notifyPackets(Tn.response.messages.map(gt=>({type:"message",payload:gt})))}catch(pn){this.notifyPacket({type:"message",payload:{role:"assistant",type:"text",text:"An error occurred while processing your request. Please try again later."}}),(Rn=this.config.logger)==null||Rn.error("Error sending packet:",pn)}}}class Ar extends te{constructor(i){super();E(this,"status");E(this,"autostart");E(this,"session");E(this,"config");E(this,"webSocket");this.config=i,this.status="disconnected",this.autostart=!0,this.session=null,this.webSocket=null}getName(){return"websocket"}getPriority(){return 500}async syncSession(i){var w;(w=this.config.logger)==null||w.debug("Syncing session with WebSocket protocol:",i),this.session=i,this.webSocket&&this.status==="connected"&&(this.disconnect(),this.connect(i))}connect(i){var I;if(this.webSocket!==null&&this.status==="connected")return Promise.resolve(this.session);const w=i||this.session||"new";(I=this.config.logger)==null||I.debug("Connecting to WebSocket with sessionId:",w);const m=encodeURIComponent(this.config.apiKey),C=this.config.agentId,b=`${this.config.webSocketUrl}?sessionCode=${w}&agentId=${C}&apiKey=${m}`;return this.setStatus("connecting"),this.webSocket=new WebSocket(b),this.webSocket.addEventListener("open",()=>{this.setStatus("connected")}),this.webSocket.addEventListener("message",$=>{const rn=JSON.parse($.data);this.notifyPacket(rn)}),this.webSocket.addEventListener("close",$=>{var rn;this.setStatus("disconnected"),this.webSocket=null,$.code!==1e3&&(this.notifyPacket({type:"message",payload:{role:"assistant",type:"text",text:"Oops! The connection to the server was lost. Please try again later."}}),(rn=this.config.logger)==null||rn.warn("WebSocket connection closed"))}),this.webSocket.addEventListener("error",()=>{var $;this.setStatus("disconnected"),this.webSocket=null,($=this.config.logger)==null||$.error("WebSocket connection error")}),Promise.resolve(w)}disconnect(){var i;return(i=this.config.logger)==null||i.debug("Disconnecting WebSocket"),this.webSocket&&this.status==="connected"&&(this.webSocket.close(),this.setStatus("disconnected"),this.webSocket=null),Promise.resolve()}sendPacket(i){return this.webSocket&&this.status==="connected"?(this.webSocket.send(JSON.stringify(i)),Promise.resolve()):Promise.reject(new Error("WebSocket is not connected"))}}class Fo{constructor(p){E(this,"config");E(this,"pc",null);E(this,"ws",null);E(this,"localStream",null);E(this,"remoteStream",new MediaStream);E(this,"audioCtx",null);E(this,"localAnalyser",null);E(this,"remoteAnalyser",null);E(this,"analyzerFrame",null);E(this,"dataChannel",null);E(this,"isConnected",!1);E(this,"visualizerCallbacks",[]);E(this,"messageCallbacks",[]);E(this,"errorCallbacks",[]);E(this,"queuedMessages",[]);this.config=p}async connect(p){var w;if(this.isConnected)return;this.isConnected=!0;try{this.localStream=await navigator.mediaDevices.getUserMedia({audio:!0})}catch(m){(w=this.config.logger)==null||w.error("Error accessing microphone:",m);return}this.pc=new RTCPeerConnection({iceServers:this.config.iceServers||[{urls:"stun:34.38.108.251:3478"},{urls:"turn:34.38.108.251:3478",username:"webrtc",credential:"webrtc"}]}),this.localStream.getTracks().forEach(m=>{this.pc.addTrack(m,this.localStream)}),this.pc.ontrack=m=>{m.streams[0].getTracks().forEach(b=>{this.remoteStream.addTrack(b)}),this.audioCtx||this._startAnalyzers();const C=new Audio;C.srcObject=this.remoteStream,C.play().catch(b=>{var I;(I=this.config.logger)==null||I.error("Error playing remote audio:",b)})},this.pc.onicecandidate=m=>{var C;m.candidate&&((C=this.ws)==null?void 0:C.readyState)===WebSocket.OPEN&&this.ws.send(JSON.stringify({type:"CANDIDATE",src:"client",payload:{candidate:m.candidate}}))},this.pc.ondatachannel=m=>{const C=m.channel;C.onmessage=b=>{this.messageCallbacks.forEach(I=>{I(b)})},C.onopen=()=>{var b;for(;this.queuedMessages.length>0;){const I=this.queuedMessages.shift();I&&(C.send(JSON.stringify(I)),(b=this.config.logger)==null||b.info("Sent queued message:",I))}}};const i=this.config.webrtcUrl||"wss://persona.applica.guru/api/webrtc";this.ws=new WebSocket(`${i}?apiKey=${encodeURIComponent(this.config.apiKey)}`),this.ws.onopen=async()=>{var I,$;const m=await this.pc.createOffer();await this.pc.setLocalDescription(m);const C={apiKey:this.config.apiKey,agentId:this.config.agentId,sessionCode:p};(I=this.config.logger)==null||I.debug("Opening connection to WebRTC server: ",C);const b={type:"OFFER",src:(($=crypto.randomUUID)==null?void 0:$.call(crypto))||"client_"+Date.now(),payload:{sdp:{sdp:m.sdp,type:m.type},connectionId:(Date.now()%1e6).toString(),metadata:C}};this.ws.send(JSON.stringify(b))},this.ws.onmessage=async m=>{var b;const C=JSON.parse(m.data);if(C.type==="ANSWER")await this.pc.setRemoteDescription(new RTCSessionDescription(C.payload.sdp));else if(C.type==="CANDIDATE")try{await this.pc.addIceCandidate(new RTCIceCandidate(C.payload.candidate))}catch(I){(b=this.config.logger)==null||b.error("Error adding ICE candidate:",I)}},this.ws.onclose=m=>{m.code!==1e3&&this.errorCallbacks.forEach(C=>{C("Oops! The connection to the server was lost. Please try again later.")}),this._stopAnalyzers()}}async disconnect(){var p;this.isConnected&&(this.isConnected=!1,((p=this.ws)==null?void 0:p.readyState)===WebSocket.OPEN&&this.ws.close(),this.pc&&this.pc.close(),this.localStream&&this.localStream.getTracks().forEach(i=>i.stop()),this.remoteStream=new MediaStream,this.audioCtx&&(await this.audioCtx.close(),this.audioCtx=null),this._stopAnalyzers())}addVisualizerCallback(p){this.visualizerCallbacks.push(p)}addMessageCallback(p){this.messageCallbacks.push(p)}addErrorCallback(p){this.errorCallbacks.push(p)}createDataChannel(p="messages"){this.pc&&(this.dataChannel=this.pc.createDataChannel(p),this.dataChannel.onopen=()=>{var i,w;for((i=this.config.logger)==null||i.info("Data channel opened");this.queuedMessages.length>0;){const m=this.queuedMessages.shift();m&&(this.dataChannel.send(JSON.stringify(m)),(w=this.config.logger)==null||w.info("Sent queued message:",m))}},this.dataChannel.onmessage=i=>{this.messageCallbacks.forEach(w=>{w(i)})})}sendPacket(p){var i;if(!this.dataChannel||this.dataChannel.readyState!=="open"){this.queuedMessages.push(p);return}this.dataChannel.send(JSON.stringify(p)),(i=this.config.logger)==null||i.info("Sent message:",p)}_startAnalyzers(){if(!this.localStream||!this.remoteStream||this.visualizerCallbacks.length===0)return;this.audioCtx=new(window.AudioContext||window.webkitAudioContext);const p=this.audioCtx.createMediaStreamSource(this.localStream),i=this.audioCtx.createMediaStreamSource(this.remoteStream);this.localAnalyser=this.audioCtx.createAnalyser(),this.remoteAnalyser=this.audioCtx.createAnalyser(),this.localAnalyser.fftSize=256,this.remoteAnalyser.fftSize=256,p.connect(this.localAnalyser),i.connect(this.remoteAnalyser);const w=()=>{if(!this.localAnalyser||!this.remoteAnalyser||this.visualizerCallbacks.length===0)return;const m=new Uint8Array(this.localAnalyser.frequencyBinCount),C=new Uint8Array(this.remoteAnalyser.frequencyBinCount);this.localAnalyser.getByteFrequencyData(m),this.remoteAnalyser.getByteFrequencyData(C);const b=m.reduce(($,rn)=>$+rn,0)/m.length,I=C.reduce(($,rn)=>$+rn,0)/C.length;this.visualizerCallbacks.length>0&&this.visualizerCallbacks.forEach($=>{$({localAmplitude:b,remoteAmplitude:I})}),this.analyzerFrame=requestAnimationFrame(w)};this.analyzerFrame=requestAnimationFrame(w)}_stopAnalyzers(){this.analyzerFrame&&(cancelAnimationFrame(this.analyzerFrame),this.analyzerFrame=null),this.localAnalyser=null,this.remoteAnalyser=null}}class Cr extends te{constructor(i){super();E(this,"status");E(this,"session");E(this,"autostart");E(this,"config");E(this,"webRTCClient");this.config=i,this.status="disconnected",this.session=null,this.autostart=(i==null?void 0:i.autostart)??!1,this.webRTCClient=new Fo(i),this.webRTCClient.addMessageCallback(w=>{const m=JSON.parse(w.data);this.notifyPacket(m)}),this.webRTCClient.addErrorCallback(w=>{var m;(m=this.config.logger)==null||m.error("WebRTC error:",w),this.notifyPacket({type:"message",payload:{type:"text",role:"assistant",text:w}})})}getName(){return"webrtc"}getPriority(){return 1e3}async syncSession(i){super.syncSession(i),this.status==="connected"&&(await this.disconnect(),await this.connect(i))}async connect(i){var w;return this.status==="connected"?Promise.resolve(this.session):(this.session=i||this.session||"new",this.setStatus("connecting"),(w=this.config.logger)==null||w.debug("Connecting to WebRTC with sessionId:",this.session),await this.webRTCClient.connect(this.session),this.setStatus("connected"),await this.webRTCClient.createDataChannel(),this.session)}async disconnect(){var i,w,m;if(this.status==="disconnected")return(i=this.config.logger)==null||i.warn("Already disconnected"),Promise.resolve();await this.webRTCClient.disconnect(),this.setStatus("disconnected"),(m=(w=this.config)==null?void 0:w.logger)==null||m.debug("Disconnected from WebRTC")}sendPacket(i){return this.status!=="connected"?Promise.reject(new Error("Not connected")):(this.webRTCClient.sendPacket(i),Promise.resolve())}}var be={exports:{}};/**
9
+ */var Ji;function Oo(){if(Ji)return ne;Ji=1;var y=Symbol.for("react.transitional.element"),p=Symbol.for("react.fragment");function i(w,m,C){var b=null;if(C!==void 0&&(b=""+C),m.key!==void 0&&(b=""+m.key),"key"in m){C={};for(var I in m)I!=="key"&&(C[I]=m[I])}else C=m;return m=C.ref,{$$typeof:y,type:w,key:b,ref:m!==void 0?m:null,props:C}}return ne.Fragment=p,ne.jsx=i,ne.jsxs=i,ne}Ki.exports=Oo();var xr=Ki.exports;function Wo(y){return y.filter(p=>p.finishReason==="stop"?p.text!==null&&p.text.trim()!=="":!0)}function Yi(y){const p=[];let i=null;for(const m of y)if(m.type!=="transaction")if(m.file){i&&(p.push(i),i=null),p.push(m);continue}else m.functionCalls?(i&&p.push(i),p.push(m),i=null):m.functionResponse?p[p.length-1]={...p[p.length-1],functionResponse:m.functionResponse}:i&&m.type===i.type&&m.protocol===i.protocol&&i.role===m.role?(i.text+=m.text,i.file=i.file||m.file):(i&&p.push(i),i={...m,text:m.file?"":m.text,finishReason:m.file?void 0:m.finishReason});return i&&p.push(i),Wo(p)}function Mo(y){var i;const p=y.file?[{type:"file",data:y.file.url,mimeType:y.file.contentType}]:[];return y.role==="function"?{id:y.id,role:"assistant",status:(y==null?void 0:y.functionResponse)===null?{type:"running"}:{type:"complete",reason:"stop"},content:((i=y.functionCalls)==null?void 0:i.map(w=>{var m;return{type:"tool-call",toolName:w.name,toolCallId:w.id,args:w.args,result:(m=y.functionResponse)==null?void 0:m.result}}))??[]}:{id:y.id,role:y.role,content:y.type==="reasoning"?[{type:"reasoning",text:y.text},...p]:[{type:"text",text:y.text},...p]}}class te{constructor(){E(this,"statusChangeCallbacks",[]);E(this,"messageCallbacks",[])}addStatusChangeListener(p){this.statusChangeCallbacks.push(p)}addPacketListener(p){this.messageCallbacks.push(p)}async syncSession(p){this.session=p}async notifyPacket(p){this.messageCallbacks.forEach(i=>i(p))}async notifyPackets(p){p.forEach(i=>{this.messageCallbacks.forEach(w=>w(i))})}async setSession(p){this.session=p}async setStatus(p){const i=this.status!==p;this.status=p,i&&this.statusChangeCallbacks.forEach(w=>w(p))}clearListeners(){this.statusChangeCallbacks=[],this.messageCallbacks=[]}onTransaction(p){}}class Sr extends te{constructor(i){super();E(this,"status");E(this,"autostart");E(this,"session");E(this,"config");E(this,"notify",!0);E(this,"context",{});E(this,"tools",[]);this.config=i,this.status="disconnected",this.autostart=!0}getName(){return"rest"}getPriority(){return 100}async connect(i){return this.setStatus("connected"),i}async disconnect(){this.setStatus("disconnected"),this.session=null}async syncSession(i){this.session=i}async sendPacket(i){var $,rn,bn,un,Rn;const{apiUrl:w,apiKey:m,agentId:C}=this.config,b=this.session??"new";if(i.type==="command"&&(($=i==null?void 0:i.payload)==null?void 0:$.command)=="set_initial_context"){this.context=(rn=i==null?void 0:i.payload)==null?void 0:rn.arguments;return}else if(i.type==="command"&&((bn=i==null?void 0:i.payload)==null?void 0:bn.command)=="set_local_tools"){const pn=(un=i==null?void 0:i.payload)==null?void 0:un.arguments.tools;(pn==null?void 0:pn.length)>0&&this.notifyPacket({type:"message",payload:{type:"text",role:"assistant",text:"Local tools with rest protocol are not supported."}});return}const I=i.payload;try{const Tn=await(await fetch(`${w}/sessions/${b}/messages`,{body:JSON.stringify({agentId:C,userMessage:I,initialContext:this.context,tools:this.tools}),method:"POST",headers:{"Content-Type":"application/json","x-persona-apikey":m}})).json();this.notifyPackets(Tn.response.messages.map(gt=>({type:"message",payload:gt})))}catch(pn){this.notifyPacket({type:"message",payload:{role:"assistant",type:"text",text:"An error occurred while processing your request. Please try again later."}}),(Rn=this.config.logger)==null||Rn.error("Error sending packet:",pn)}}}class Ar extends te{constructor(i){super();E(this,"status");E(this,"autostart");E(this,"session");E(this,"config");E(this,"webSocket");this.config=i,this.status="disconnected",this.autostart=!0,this.session=null,this.webSocket=null}getName(){return"websocket"}getPriority(){return 500}async syncSession(i){var w;(w=this.config.logger)==null||w.debug("Syncing session with WebSocket protocol:",i),this.session=i,this.webSocket&&this.status==="connected"&&(this.disconnect(),this.connect(i))}connect(i){var I;if(this.webSocket!==null&&this.status==="connected")return Promise.resolve(this.session);const w=i||this.session||"new";(I=this.config.logger)==null||I.debug("Connecting to WebSocket with sessionId:",w);const m=encodeURIComponent(this.config.apiKey),C=this.config.agentId,b=`${this.config.webSocketUrl}?sessionCode=${w}&agentId=${C}&apiKey=${m}`;return this.setStatus("connecting"),this.webSocket=new WebSocket(b),this.webSocket.addEventListener("open",()=>{this.setStatus("connected")}),this.webSocket.addEventListener("message",$=>{const rn=JSON.parse($.data);this.notifyPacket(rn)}),this.webSocket.addEventListener("close",$=>{var rn;this.setStatus("disconnected"),this.webSocket=null,$.code!==1e3&&(this.notifyPacket({type:"message",payload:{role:"assistant",type:"text",text:"Oops! The connection to the server was lost. Please try again later."}}),(rn=this.config.logger)==null||rn.warn("WebSocket connection closed"))}),this.webSocket.addEventListener("error",()=>{var $;this.setStatus("disconnected"),this.webSocket=null,($=this.config.logger)==null||$.error("WebSocket connection error")}),Promise.resolve(w)}disconnect(){var i;return(i=this.config.logger)==null||i.debug("Disconnecting WebSocket"),this.webSocket&&this.status==="connected"&&(this.webSocket.close(),this.setStatus("disconnected"),this.webSocket=null),Promise.resolve()}sendPacket(i){return this.webSocket&&this.status==="connected"?(this.webSocket.send(JSON.stringify(i)),Promise.resolve()):Promise.reject(new Error("WebSocket is not connected"))}}class Fo{constructor(p){E(this,"config");E(this,"pc",null);E(this,"ws",null);E(this,"localStream",null);E(this,"remoteStream",new MediaStream);E(this,"audioCtx",null);E(this,"localAnalyser",null);E(this,"remoteAnalyser",null);E(this,"analyzerFrame",null);E(this,"dataChannel",null);E(this,"isConnected",!1);E(this,"visualizerCallbacks",[]);E(this,"messageCallbacks",[]);E(this,"errorCallbacks",[]);E(this,"queuedMessages",[]);this.config=p}async connect(p){var w;if(this.isConnected)return;this.isConnected=!0;try{this.localStream=await navigator.mediaDevices.getUserMedia({audio:!0})}catch(m){(w=this.config.logger)==null||w.error("Error accessing microphone:",m);return}this.pc=new RTCPeerConnection({iceServers:this.config.iceServers||[{urls:"stun:34.38.108.251:3478"},{urls:"turn:34.38.108.251:3478",username:"webrtc",credential:"webrtc"}]}),this.localStream.getTracks().forEach(m=>{this.pc.addTrack(m,this.localStream)}),this.pc.ontrack=m=>{m.streams[0].getTracks().forEach(b=>{this.remoteStream.addTrack(b)}),this.audioCtx||this._startAnalyzers();const C=new Audio;C.srcObject=this.remoteStream,C.play().catch(b=>{var I;(I=this.config.logger)==null||I.error("Error playing remote audio:",b)})},this.pc.onicecandidate=m=>{var C;m.candidate&&((C=this.ws)==null?void 0:C.readyState)===WebSocket.OPEN&&this.ws.send(JSON.stringify({type:"CANDIDATE",src:"client",payload:{candidate:m.candidate}}))},this.pc.ondatachannel=m=>{const C=m.channel;C.onmessage=b=>{this.messageCallbacks.forEach(I=>{I(b)})},C.onopen=()=>{var b;for(;this.queuedMessages.length>0;){const I=this.queuedMessages.shift();I&&(C.send(JSON.stringify(I)),(b=this.config.logger)==null||b.info("Sent queued message:",I))}}};const i=this.config.webrtcUrl||"wss://persona.applica.guru/api/webrtc";this.ws=new WebSocket(`${i}?apiKey=${encodeURIComponent(this.config.apiKey)}`),this.ws.onopen=async()=>{var I,$;const m=await this.pc.createOffer();await this.pc.setLocalDescription(m);const C={apiKey:this.config.apiKey,agentId:this.config.agentId,sessionCode:p};(I=this.config.logger)==null||I.debug("Opening connection to WebRTC server: ",C);const b={type:"OFFER",src:(($=crypto.randomUUID)==null?void 0:$.call(crypto))||"client_"+Date.now(),payload:{sdp:{sdp:m.sdp,type:m.type},connectionId:(Date.now()%1e6).toString(),metadata:C}};this.ws.send(JSON.stringify(b))},this.ws.onmessage=async m=>{var b;const C=JSON.parse(m.data);if(C.type==="ANSWER")await this.pc.setRemoteDescription(new RTCSessionDescription(C.payload.sdp));else if(C.type==="CANDIDATE")try{await this.pc.addIceCandidate(new RTCIceCandidate(C.payload.candidate))}catch(I){(b=this.config.logger)==null||b.error("Error adding ICE candidate:",I)}},this.ws.onclose=m=>{m.code!==1e3&&this.errorCallbacks.forEach(C=>{C("Oops! The connection to the server was lost. Please try again later.")}),this._stopAnalyzers()}}async disconnect(){var p;this.isConnected&&(this.isConnected=!1,((p=this.ws)==null?void 0:p.readyState)===WebSocket.OPEN&&this.ws.close(),this.pc&&this.pc.close(),this.localStream&&this.localStream.getTracks().forEach(i=>i.stop()),this.remoteStream=new MediaStream,this.audioCtx&&(await this.audioCtx.close(),this.audioCtx=null),this._stopAnalyzers())}addVisualizerCallback(p){this.visualizerCallbacks.push(p)}addMessageCallback(p){this.messageCallbacks.push(p)}addErrorCallback(p){this.errorCallbacks.push(p)}createDataChannel(p="messages"){this.pc&&(this.dataChannel=this.pc.createDataChannel(p),this.dataChannel.onopen=()=>{var i,w;for((i=this.config.logger)==null||i.info("Data channel opened");this.queuedMessages.length>0;){const m=this.queuedMessages.shift();m&&(this.dataChannel.send(JSON.stringify(m)),(w=this.config.logger)==null||w.info("Sent queued message:",m))}},this.dataChannel.onmessage=i=>{this.messageCallbacks.forEach(w=>{w(i)})})}sendPacket(p){var i;if(!this.dataChannel||this.dataChannel.readyState!=="open"){this.queuedMessages.push(p);return}this.dataChannel.send(JSON.stringify(p)),(i=this.config.logger)==null||i.info("Sent message:",p)}_startAnalyzers(){if(!this.localStream||!this.remoteStream||this.visualizerCallbacks.length===0)return;this.audioCtx=new(window.AudioContext||window.webkitAudioContext);const p=this.audioCtx.createMediaStreamSource(this.localStream),i=this.audioCtx.createMediaStreamSource(this.remoteStream);this.localAnalyser=this.audioCtx.createAnalyser(),this.remoteAnalyser=this.audioCtx.createAnalyser(),this.localAnalyser.fftSize=256,this.remoteAnalyser.fftSize=256,p.connect(this.localAnalyser),i.connect(this.remoteAnalyser);const w=()=>{if(!this.localAnalyser||!this.remoteAnalyser||this.visualizerCallbacks.length===0)return;const m=new Uint8Array(this.localAnalyser.frequencyBinCount),C=new Uint8Array(this.remoteAnalyser.frequencyBinCount);this.localAnalyser.getByteFrequencyData(m),this.remoteAnalyser.getByteFrequencyData(C);const b=m.reduce(($,rn)=>$+rn,0)/m.length,I=C.reduce(($,rn)=>$+rn,0)/C.length;this.visualizerCallbacks.length>0&&this.visualizerCallbacks.forEach($=>{$({localAmplitude:b,remoteAmplitude:I})}),this.analyzerFrame=requestAnimationFrame(w)};this.analyzerFrame=requestAnimationFrame(w)}_stopAnalyzers(){this.analyzerFrame&&(cancelAnimationFrame(this.analyzerFrame),this.analyzerFrame=null),this.localAnalyser=null,this.remoteAnalyser=null}}class Cr extends te{constructor(i){super();E(this,"status");E(this,"session");E(this,"autostart");E(this,"config");E(this,"webRTCClient");this.config=i,this.status="disconnected",this.session=null,this.autostart=(i==null?void 0:i.autostart)??!1,this.webRTCClient=new Fo(i),this.webRTCClient.addMessageCallback(w=>{const m=JSON.parse(w.data);this.notifyPacket(m)}),this.webRTCClient.addErrorCallback(w=>{var m;(m=this.config.logger)==null||m.error("WebRTC error:",w),this.notifyPacket({type:"message",payload:{type:"text",role:"assistant",text:w}})})}getName(){return"webrtc"}getPriority(){return 1e3}async syncSession(i){super.syncSession(i),this.status==="connected"&&(await this.disconnect(),await this.connect(i))}async connect(i){var w;return this.status==="connected"?Promise.resolve(this.session):(this.session=i||this.session||"new",this.setStatus("connecting"),(w=this.config.logger)==null||w.debug("Connecting to WebRTC with sessionId:",this.session),await this.webRTCClient.connect(this.session),this.setStatus("connected"),await this.webRTCClient.createDataChannel(),this.session)}async disconnect(){var i,w,m;if(this.status==="disconnected")return(i=this.config.logger)==null||i.warn("Already disconnected"),Promise.resolve();await this.webRTCClient.disconnect(),this.setStatus("disconnected"),(m=(w=this.config)==null?void 0:w.logger)==null||m.debug("Disconnected from WebRTC")}sendPacket(i){return this.status!=="connected"?Promise.reject(new Error("Not connected")):(this.webRTCClient.sendPacket(i),Promise.resolve())}}var be={exports:{}};/**
10
10
  * @license
11
11
  * Lodash <https://lodash.com/>
12
12
  * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>