@vanira/sdk 0.0.14 → 0.0.15

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.
@@ -20,20 +20,20 @@ var we=Object.defineProperty;var ue=(C,f,x)=>f in C?we(C,f,{enumerable:!0,config
20
20
  }
21
21
  }
22
22
  }
23
- `;try{const r=(i=(await(await fetch(f,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:e,variables:{id:t}})})).json()).data)==null?void 0:i.app_widget_by_pk;if(!r)throw new Error(`Widget configuration not found for ID: ${t}`);if(r.client_id){const c=await(await fetch(f,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:`
23
+ `;try{const r=(i=(await(await fetch(f,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:e,variables:{id:t}})})).json()).data)==null?void 0:i.app_widget_by_pk;if(!r)throw new Error(`Widget configuration not found for ID: ${t}`);if(r.client_id){const A=await(await fetch(f,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:`
24
24
  query GetClientDetails($id: uuid!) {
25
25
  client_by_pk(id: $id) {
26
26
  base_prospect_group_id
27
27
  }
28
28
  }
29
- `,variables:{id:r.client_id}})})).json();(s=c.data)!=null&&s.client_by_pk&&(r.client=c.data.client_by_pk)}return r}catch(n){throw console.error("[VaniraAI] Failed to fetch widget config:",n),n}}}const _="https://coredb.travelr.club/v1/graphql";let k="https://inboxapi.travelr.club";class v{static setChatUrl(t){k=t}static async createChatProspect(t){var i,s;const e=`
29
+ `,variables:{id:r.client_id}})})).json();(s=A.data)!=null&&s.client_by_pk&&(r.client=A.data.client_by_pk)}return r}catch(n){throw console.error("[VaniraAI] Failed to fetch widget config:",n),n}}}const _="https://coredb.travelr.club/v1/graphql";let k="https://inboxapi.travelr.club";class v{static setChatUrl(t){k=t}static async createChatProspect(t){var i,s;const e=`
30
30
  mutation CreateChatProspect($prospectGroupId: uuid!, $name: String!) {
31
31
  insert_prospects_one(object: {prospect_group_id: $prospectGroupId, name: $name, source: WEBSITE_WIDGET}) {
32
32
  id
33
33
  }
34
34
  }
35
- `;try{const a=await(await fetch(_,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:e,variables:{prospectGroupId:t,name:`Widget Guest ${new Date().toLocaleString()}`}})})).json();return a.errors?(console.warn("[VaniraAI] Prospect creation failed, using anonymous ID",a.errors),`anon_${Date.now()}_${Math.random().toString(36).substr(2,9)}`):((s=(i=a.data)==null?void 0:i.insert_prospects_one)==null?void 0:s.id)||`anon_${Date.now()}`}catch(n){return console.error("[VaniraAI] Failed to create prospect:",n),`anon_${Date.now()}`}}static async fetchWelcomeMessage(t,e,i){var s,n;try{const a=await fetch(`${k}/widget/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent_id:t,...i?{widget_id:i}:{},message:"",prospect_id:e,stream:!1})});if(!a.ok)throw new Error("Failed to fetch welcome message");const r=await a.json();let l=r.response||"Hello! How can I help you today?",A;const c=r.chat_id||r.inbox_id;if(r.widget){A=r.widget;const d={text:l};A.type==="carousel"&&((s=A.data)!=null&&s.cards)?d.cards=A.data.cards:A.type==="button_list"&&((n=A.data)!=null&&n.buttons)&&(d.buttons=A.data.buttons),l=JSON.stringify(d)}return{role:"assistant",content:l,widget:A,chatId:c}}catch(a){return console.error("[VaniraAI] Failed to fetch welcome message:",a),{role:"assistant",content:"Hello! How can I help you today?"}}}static async sendChatMessage(t,e,i,s,n,a,r,l){var A,c,d,g;try{const w={agent_id:t,message:i,prospect_id:e,stream:!0};s&&(w.inbox_id=s),l&&(w.widget_id=l);const m=await fetch(`${k}/widget/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(w)});if(!m.ok)throw new Error("Chat request failed");const E=(A=m.body)==null?void 0:A.getReader(),T=new TextDecoder;if(!E)throw new Error("No reader");let Q="",I="",M=null;for(;;){const{done:he,value:ge}=await E.read();if(he)break;I+=T.decode(ge,{stream:!0});const K=I.split(`
36
- `);I=K.pop()||"";for(const pe of K){const G=pe.trim();if(G&&G.startsWith("data: ")){const q=G.slice(6);if(q==="[DONE]"){r(M);return}try{const y=JSON.parse(q);if(y.type==="metadata"&&y.chat_id){M=y.chat_id;continue}const Z=(g=(d=(c=y.choices)==null?void 0:c[0])==null?void 0:d.delta)==null?void 0:g.content;Z&&(Q+=Z,n(Q)),y.widget&&a(y.widget),y.chat_id&&!M&&(M=y.chat_id)}catch{}}}}r(M)}catch(w){console.error("[VaniraAI] Chat error:",w),n("Sorry, I encountered an error. Please try again."),r(null)}}static listenForAdminReplies(t,e,i){const s=`${k}/inbox/stream?inbox_id=${t}&sender=${encodeURIComponent(e)}`;let n=null,a=0,r=!1;const l=()=>{r||(n=new EventSource(s),console.log(`[VaniraAI] Subscribed to SSE EventSource at ${n.url}`),n.onopen=()=>{console.log("[VaniraAI] SSE connection opened successfully."),a=0},n.onmessage=A=>{console.log("[VaniraAI] 📡 Raw SSE Event triggered:",A.data);try{const c=JSON.parse(A.data);console.log("[VaniraAI] SSE stream JSON parsed:",c);const d=c.direction==="outgoing",g=!!c.content,w=c.source!=="ai";d&&g&&w&&(console.log("[VaniraAI] đŸŽ¯ Displaying admin message in chat UI:",c.content),i(c.content))}catch(c){console.error("[VaniraAI] SSE parse error",c)}},n.onerror=A=>{if(console.error("[VaniraAI] SSE connection error or disconnect",A),n&&(n.close(),n=null),r)return;const c=Math.min(2e3*Math.pow(2,a),3e4);console.log(`[VaniraAI] Reconnecting SSE in ${c}ms (Attempt ${a+1})...`),a++,setTimeout(l,c)})};return l(),{close:()=>{r=!0,n&&(n.close(),n=null,console.log("[VaniraAI] SSE connection manually closed."))}}}static async createCall(t,e,i,s){try{const n=await fetch("https://wfapi.travelr.club/webhook/create-web-call",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent_id:t,client_id:e,prospect_id:i,is_avatar_call:s.includes("avatar")})}),a=await n.json();if(!n.ok)throw new Error(`[VaniraAI] Call creation failed HTTP ${n.status}`);if(!a.worker_url)throw new Error("[VaniraAI] Worker URL missing from response. Call cannot proceed.");let r;try{r=new URL(a.worker_url).origin}catch{r=a.worker_url}return{callId:a.call_id||a.id||`web_${Date.now()}`,workerUrl:r}}catch(n){throw console.error("[VaniraAI] Failed to create call:",n),n}}}class ${constructor(t){o(this,"config");o(this,"root",null);this.config=t}async initialize(t){this.config=t}}class S{constructor(t){o(this,"serverUrl");o(this,"agentId");o(this,"callId");o(this,"onConnected");o(this,"onDisconnected");o(this,"onError");o(this,"onTranscription");o(this,"onRemoteTrack");o(this,"onClientToolCall");o(this,"pc",null);o(this,"dataChannel",null);o(this,"audioElement",null);o(this,"connected",!1);o(this,"iceServers");o(this,"token");if(!t.serverUrl)throw new Error("serverUrl is required");if(!t.agentId)throw new Error("agentId is required");this.serverUrl=t.serverUrl.replace(/\/$/,""),this.agentId=t.agentId,this.callId=t.callId||this.generateCallId(),this.iceServers=t.iceServers,this.token=t.token,this.onConnected=t.onConnected||(()=>{}),this.onDisconnected=t.onDisconnected||(()=>{}),this.onError=t.onError||(e=>console.error("[WebRTC]",e)),this.onTranscription=t.onTranscription||(()=>{}),this.onRemoteTrack=t.onRemoteTrack||(()=>{}),this.onClientToolCall=t.onClientToolCall||(()=>{})}async connect(){console.log("đŸ”ĩ [WebRTC] Starting connection...");try{if(!this.iceServers&&this.token)try{this.iceServers=await S.fetchIceServers(this.token)}catch(a){console.warn("âš ī¸ [WebRTC] Failed to fetch ICE servers:",a)}this.pc=new RTCPeerConnection({iceServers:this.iceServers||[{urls:"stun:global.relay.metered.ca:80"},{urls:["turns:global.relay.metered.ca:443?transport=tcp","turn:global.relay.metered.ca:80?transport=tcp","turn:global.relay.metered.ca:443?transport=tcp"],username:"fa97658be3343d21da3b65e6",credential:"HXHDoqeHbvZrmCuf"}]}),this.pc.addTransceiver("video",{direction:"recvonly"});const t=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,sampleRate:{ideal:16e3},channelCount:1}});if(console.log("🎤 [WebRTC] Microphone access granted"),!this.pc){console.log("[WebRTC] Connection aborted: peer connection closed during setup"),t.getTracks().forEach(a=>a.stop());return}if(t.getTracks().forEach(a=>{var r;(r=this.pc)==null||r.addTrack(a,t)}),!this.pc)throw new Error("RTCPeerConnection was closed unexpectedly");this.dataChannel=this.pc.createDataChannel("control"),this.dataChannel.onopen=()=>console.log("📡 [WebRTC] DataChannel opened"),this.dataChannel.onmessage=a=>{if(typeof a.data=="string")try{this.handleControlEvent(JSON.parse(a.data))}catch{console.warn("[WebRTC] Failed to parse message:",a.data)}else if(a.data instanceof ArrayBuffer)try{const r=new TextDecoder().decode(a.data);try{const l=JSON.parse(r);l&&typeof l=="object"&&l.event==="client_tool_call"?(console.log("[VaniraAI] Safely decoding binary tool_call to JSON:",l),this.handleControlEvent(l)):console.log("[VaniraAI] Decoded JSON from binary (inspect only):",l)}catch{console.log("[VaniraAI] Decoded String from binary:",r)}}catch{console.log("[VaniraAI] Received binary data:",a.data.byteLength,"bytes (not decodable)")}else a.data instanceof Blob&&a.data.text().then(r=>{try{this.handleControlEvent(JSON.parse(r))}catch{console.warn("[WebRTC] Failed to parse blob data:",r)}})},this.dataChannel.onerror=a=>console.error("❌ [WebRTC] DataChannel error:",a),this.pc.ontrack=a=>{const r=a.track,l=a.streams[0];console.log(`đŸ“Ĩ [WebRTC] Received ${r.kind} track`),r.kind==="audio"?(console.log("🔊 [WebRTC] Received audio track from server"),this.audioElement=new Audio,this.audioElement.srcObject=l,this.audioElement.play().catch(A=>console.warn("Audio autoplay blocked:",A)),this.audioElement.onended=()=>{this.sendEvent("playedStream"),console.log("✅ [WebRTC] TTS playback complete")}):r.kind==="video"&&(console.log("📹 [WebRTC] Video track received"),this.onRemoteTrack(r,l))};const e=()=>{var l,A,c,d,g,w,m,E,T,Q,I;console.log("🔄 [WebRTC] State:",(l=this.pc)==null?void 0:l.connectionState,"| ICE:",(A=this.pc)==null?void 0:A.iceConnectionState);const a=((c=this.pc)==null?void 0:c.connectionState)==="connected"||((d=this.pc)==null?void 0:d.iceConnectionState)==="connected"||((g=this.pc)==null?void 0:g.iceConnectionState)==="completed",r=((w=this.pc)==null?void 0:w.connectionState)==="failed"||((m=this.pc)==null?void 0:m.iceConnectionState)==="failed"||((E=this.pc)==null?void 0:E.connectionState)==="closed"||((T=this.pc)==null?void 0:T.iceConnectionState)==="closed"||((Q=this.pc)==null?void 0:Q.connectionState)==="disconnected"||((I=this.pc)==null?void 0:I.iceConnectionState)==="disconnected";a&&!this.connected?(this.connected=!0,this.onConnected()):r&&this.connected&&(this.connected=!1,this.onDisconnected())};this.pc.onconnectionstatechange=e,this.pc.oniceconnectionstatechange=e;const i=await this.pc.createOffer();await this.pc.setLocalDescription(i),console.log("📝 [WebRTC] Created offer, waiting for ICE gathering..."),await this.waitForIceGathering(),console.log("🧊 [WebRTC] ICE gathering complete"),console.log("📤 [WebRTC] Sending offer via HTTP...");const s=await fetch(`${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({offer:this.pc.localDescription,agentId:this.agentId,callId:this.callId})});if(!s.ok){const a=await s.json();throw new Error(a.error||`HTTP ${s.status}`)}const{answer:n}=await s.json();console.log("đŸ“Ĩ [WebRTC] Received answer from server"),await this.pc.setRemoteDescription(n),console.log("✅ [WebRTC] Connection established!")}catch(t){throw console.error("❌ [WebRTC] Connection failed:",t),this.disconnect(),this.onError(t.message||t),t}}waitForIceGathering(){return new Promise(t=>{if(!this.pc)return t();if(this.pc.iceGatheringState==="complete")t();else{const e=()=>{var i,s;((i=this.pc)==null?void 0:i.iceGatheringState)==="complete"&&((s=this.pc)==null||s.removeEventListener("icegatheringstatechange",e),t())};this.pc.addEventListener("icegatheringstatechange",e),setTimeout(()=>{var i;(i=this.pc)==null||i.removeEventListener("icegatheringstatechange",e),console.warn("âš ī¸ [WebRTC] ICE gathering timeout, proceeding anyway"),t()},5e3)}})}sendEvent(t,e={}){var i;((i=this.dataChannel)==null?void 0:i.readyState)==="open"&&this.dataChannel.send(JSON.stringify({event:t,...e}))}handleControlEvent(t){var e;switch(t.event){case"clearAudio":console.log("🛑 [WebRTC] Interrupt: clearAudio received (leaving stream unpaused)");break;case"transcription":console.log("📝 [WebRTC] Transcription:",t.text),this.onTranscription(t.text,t.isFinal);break;case"mark":console.log("đŸˇī¸ [WebRTC] Mark:",t.name);break;case"client_tool_call":{const i=t.tool_call||t.data||t,s=(i==null?void 0:i.tool_call_id)||(i==null?void 0:i.call_id)||t.tool_call_id||"";s&&((e=this.dataChannel)==null?void 0:e.readyState)==="open"?(this.dataChannel.send(JSON.stringify({event:"client_tool_ack",data:{tool_call_id:s}})),console.log("✅ [VaniraAI] Sent client_tool_ack for:",s)):s||console.warn("âš ī¸ [VaniraAI] client_tool_call received without tool_call_id — ack skipped"),console.log("đŸ› ī¸ [VaniraAI] Client Tool Call:",t),this.onClientToolCall(i);break}default:console.log("â„šī¸ [WebRTC] Unknown event:",t.event)}}disconnect(){console.log("🔴 [WebRTC] Disconnecting..."),this.audioElement&&(this.audioElement.pause(),this.audioElement.srcObject=null),this.dataChannel&&(this.dataChannel.close(),this.dataChannel=null),this.pc&&(this.pc.getSenders().forEach(t=>{t.track&&t.track.stop()}),this.pc.close(),this.pc=null),this.connected=!1,this.onDisconnected()}generateCallId(){return"web_"+Date.now()+"_"+Math.random().toString(36).substr(2,8)}sendToolResult(t,e){this.sendEvent("client_tool_result",{call_id:t,result:e})}sendToolAck(t){var e;((e=this.dataChannel)==null?void 0:e.readyState)==="open"?(this.dataChannel.send(JSON.stringify({event:"client_tool_ack",data:{tool_call_id:t}})),console.log("✅ [VaniraAI] Sent client_tool_ack for:",t)):console.warn("âš ī¸ [VaniraAI] Cannot send tool_ack: DataChannel not open")}sendContextUpdate(t){this.sendEvent("client_context_update",{data:{context:t}})}sendActionTrigger(t,e={}){this.sendEvent("client_action_trigger",{data:{action_name:t,data:e}})}triggerActionInterrupt(){this.sendEvent("action_interrupt"),console.log("🛑 [VaniraAI] Triggered client-side action interrupt")}static async fetchIceServers(t,e="https://coredb.travelr.club/v1/graphql"){var i;try{const n=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authorization:t},body:JSON.stringify({query:`
35
+ `;try{const a=await(await fetch(_,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:e,variables:{prospectGroupId:t,name:`Widget Guest ${new Date().toLocaleString()}`}})})).json();return a.errors?(console.warn("[VaniraAI] Prospect creation failed, using anonymous ID",a.errors),`anon_${Date.now()}_${Math.random().toString(36).substr(2,9)}`):((s=(i=a.data)==null?void 0:i.insert_prospects_one)==null?void 0:s.id)||`anon_${Date.now()}`}catch(n){return console.error("[VaniraAI] Failed to create prospect:",n),`anon_${Date.now()}`}}static async fetchWelcomeMessage(t,e,i){var s,n;try{const a=await fetch(`${k}/widget/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent_id:t,...i?{widget_id:i}:{},message:"",prospect_id:e,stream:!1})});if(!a.ok)throw new Error("Failed to fetch welcome message");const r=await a.json();let c=r.response||"Hello! How can I help you today?",l;const A=r.chat_id||r.inbox_id;if(r.widget){l=r.widget;const d={text:c};l.type==="carousel"&&((s=l.data)!=null&&s.cards)?d.cards=l.data.cards:l.type==="button_list"&&((n=l.data)!=null&&n.buttons)&&(d.buttons=l.data.buttons),c=JSON.stringify(d)}return{role:"assistant",content:c,widget:l,chatId:A}}catch(a){return console.error("[VaniraAI] Failed to fetch welcome message:",a),{role:"assistant",content:"Hello! How can I help you today?"}}}static async sendChatMessage(t,e,i,s,n,a,r,c){var l,A,d,g;try{const w={agent_id:t,message:i,prospect_id:e,stream:!0};s&&(w.inbox_id=s),c&&(w.widget_id=c);const m=await fetch(`${k}/widget/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(w)});if(!m.ok)throw new Error("Chat request failed");const E=(l=m.body)==null?void 0:l.getReader(),T=new TextDecoder;if(!E)throw new Error("No reader");let Q="",I="",M=null;for(;;){const{done:he,value:ge}=await E.read();if(he)break;I+=T.decode(ge,{stream:!0});const K=I.split(`
36
+ `);I=K.pop()||"";for(const pe of K){const G=pe.trim();if(G&&G.startsWith("data: ")){const q=G.slice(6);if(q==="[DONE]"){r(M);return}try{const y=JSON.parse(q);if(y.type==="metadata"&&y.chat_id){M=y.chat_id;continue}const Z=(g=(d=(A=y.choices)==null?void 0:A[0])==null?void 0:d.delta)==null?void 0:g.content;Z&&(Q+=Z,n(Q)),y.widget&&a(y.widget),y.chat_id&&!M&&(M=y.chat_id)}catch{}}}}r(M)}catch(w){console.error("[VaniraAI] Chat error:",w),n("Sorry, I encountered an error. Please try again."),r(null)}}static listenForAdminReplies(t,e,i){const s=`${k}/inbox/stream?inbox_id=${t}&sender=${encodeURIComponent(e)}`;let n=null,a=0,r=!1;const c=()=>{r||(n=new EventSource(s),console.log(`[VaniraAI] Subscribed to SSE EventSource at ${n.url}`),n.onopen=()=>{console.log("[VaniraAI] SSE connection opened successfully."),a=0},n.onmessage=l=>{console.log("[VaniraAI] 📡 Raw SSE Event triggered:",l.data);try{const A=JSON.parse(l.data);console.log("[VaniraAI] SSE stream JSON parsed:",A);const d=A.direction==="outgoing",g=!!A.content,w=A.source!=="ai";d&&g&&w&&(console.log("[VaniraAI] đŸŽ¯ Displaying admin message in chat UI:",A.content),i(A.content))}catch(A){console.error("[VaniraAI] SSE parse error",A)}},n.onerror=l=>{if(console.error("[VaniraAI] SSE connection error or disconnect",l),n&&(n.close(),n=null),r)return;const A=Math.min(2e3*Math.pow(2,a),3e4);console.log(`[VaniraAI] Reconnecting SSE in ${A}ms (Attempt ${a+1})...`),a++,setTimeout(c,A)})};return c(),{close:()=>{r=!0,n&&(n.close(),n=null,console.log("[VaniraAI] SSE connection manually closed."))}}}static async createCall(t,e,i,s){try{const n=await fetch("https://wfapi.travelr.club/webhook/create-web-call",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({agent_id:t,client_id:e,prospect_id:i,is_avatar_call:s.includes("avatar")})}),a=await n.json();if(!n.ok)throw new Error(`[VaniraAI] Call creation failed HTTP ${n.status}`);if(!a.worker_url)throw new Error("[VaniraAI] Worker URL missing from response. Call cannot proceed.");let r;try{r=new URL(a.worker_url).origin}catch{r=a.worker_url}return{callId:a.call_id||a.id||`web_${Date.now()}`,workerUrl:r}}catch(n){throw console.error("[VaniraAI] Failed to create call:",n),n}}}class ${constructor(t){o(this,"config");o(this,"root",null);this.config=t}async initialize(t){this.config=t}}class S{constructor(t){o(this,"serverUrl");o(this,"agentId");o(this,"callId");o(this,"onConnected");o(this,"onDisconnected");o(this,"onError");o(this,"onTranscription");o(this,"onRemoteTrack");o(this,"onClientToolCall");o(this,"pc",null);o(this,"dataChannel",null);o(this,"audioElement",null);o(this,"connected",!1);o(this,"iceServers");o(this,"token");if(!t.serverUrl)throw new Error("serverUrl is required");if(!t.agentId)throw new Error("agentId is required");this.serverUrl=t.serverUrl.replace(/\/$/,""),this.agentId=t.agentId,this.callId=t.callId||this.generateCallId(),this.iceServers=t.iceServers,this.token=t.token,this.onConnected=t.onConnected||(()=>{}),this.onDisconnected=t.onDisconnected||(()=>{}),this.onError=t.onError||(e=>console.error("[WebRTC]",e)),this.onTranscription=t.onTranscription||(()=>{}),this.onRemoteTrack=t.onRemoteTrack||(()=>{}),this.onClientToolCall=t.onClientToolCall||(()=>{})}async connect(){console.log("đŸ”ĩ [WebRTC] Starting connection...");try{if(!this.iceServers&&this.token)try{this.iceServers=await S.fetchIceServers(this.token)}catch(a){console.warn("âš ī¸ [WebRTC] Failed to fetch ICE servers:",a)}this.pc=new RTCPeerConnection({iceServers:this.iceServers||[{urls:"stun:global.relay.metered.ca:80"},{urls:["turns:global.relay.metered.ca:443?transport=tcp","turn:global.relay.metered.ca:80?transport=tcp","turn:global.relay.metered.ca:443?transport=tcp"],username:"fa97658be3343d21da3b65e6",credential:"HXHDoqeHbvZrmCuf"}]}),this.pc.addTransceiver("video",{direction:"recvonly"});const t=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,sampleRate:{ideal:16e3},channelCount:1}});if(console.log("🎤 [WebRTC] Microphone access granted"),!this.pc){console.log("[WebRTC] Connection aborted: peer connection closed during setup"),t.getTracks().forEach(a=>a.stop());return}if(t.getTracks().forEach(a=>{var r;(r=this.pc)==null||r.addTrack(a,t)}),!this.pc)throw new Error("RTCPeerConnection was closed unexpectedly");this.dataChannel=this.pc.createDataChannel("control"),this.dataChannel.onopen=()=>console.log("📡 [WebRTC] DataChannel opened"),this.dataChannel.onmessage=a=>{if(typeof a.data=="string")try{this.handleControlEvent(JSON.parse(a.data))}catch{console.warn("[WebRTC] Failed to parse message:",a.data)}else if(a.data instanceof ArrayBuffer)try{const r=new TextDecoder().decode(a.data);try{const c=JSON.parse(r);c&&typeof c=="object"&&c.event==="client_tool_call"?(console.log("[VaniraAI] Safely decoding binary tool_call to JSON:",c),this.handleControlEvent(c)):console.log("[VaniraAI] Decoded JSON from binary (inspect only):",c)}catch{console.log("[VaniraAI] Decoded String from binary:",r)}}catch{console.log("[VaniraAI] Received binary data:",a.data.byteLength,"bytes (not decodable)")}else a.data instanceof Blob&&a.data.text().then(r=>{try{this.handleControlEvent(JSON.parse(r))}catch{console.warn("[WebRTC] Failed to parse blob data:",r)}})},this.dataChannel.onerror=a=>console.error("❌ [WebRTC] DataChannel error:",a),this.pc.ontrack=a=>{const r=a.track,c=a.streams[0];console.log(`đŸ“Ĩ [WebRTC] Received ${r.kind} track`),r.kind==="audio"?(console.log("🔊 [WebRTC] Received audio track from server"),this.audioElement=new Audio,this.audioElement.srcObject=c,this.audioElement.play().catch(l=>console.warn("Audio autoplay blocked:",l)),this.audioElement.onended=()=>{this.sendEvent("playedStream"),console.log("✅ [WebRTC] TTS playback complete")}):r.kind==="video"&&(console.log("📹 [WebRTC] Video track received"),this.onRemoteTrack(r,c))};const e=()=>{var c,l,A,d,g,w,m,E,T,Q,I;console.log("🔄 [WebRTC] State:",(c=this.pc)==null?void 0:c.connectionState,"| ICE:",(l=this.pc)==null?void 0:l.iceConnectionState);const a=((A=this.pc)==null?void 0:A.connectionState)==="connected"||((d=this.pc)==null?void 0:d.iceConnectionState)==="connected"||((g=this.pc)==null?void 0:g.iceConnectionState)==="completed",r=((w=this.pc)==null?void 0:w.connectionState)==="failed"||((m=this.pc)==null?void 0:m.iceConnectionState)==="failed"||((E=this.pc)==null?void 0:E.connectionState)==="closed"||((T=this.pc)==null?void 0:T.iceConnectionState)==="closed"||((Q=this.pc)==null?void 0:Q.connectionState)==="disconnected"||((I=this.pc)==null?void 0:I.iceConnectionState)==="disconnected";a&&!this.connected?(this.connected=!0,this.onConnected()):r&&this.connected&&(this.connected=!1,this.onDisconnected())};this.pc.onconnectionstatechange=e,this.pc.oniceconnectionstatechange=e;const i=await this.pc.createOffer();await this.pc.setLocalDescription(i),console.log("📝 [WebRTC] Created offer, waiting for ICE gathering..."),await this.waitForIceGathering(),console.log("🧊 [WebRTC] ICE gathering complete"),console.log("📤 [WebRTC] Sending offer via HTTP...");const s=await fetch(`${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({offer:this.pc.localDescription,agentId:this.agentId,callId:this.callId})});if(!s.ok){const a=await s.json();throw new Error(a.error||`HTTP ${s.status}`)}const{answer:n}=await s.json();console.log("đŸ“Ĩ [WebRTC] Received answer from server"),await this.pc.setRemoteDescription(n),console.log("✅ [WebRTC] Connection established!")}catch(t){throw console.error("❌ [WebRTC] Connection failed:",t),this.disconnect(),this.onError(t.message||t),t}}waitForIceGathering(){return new Promise(t=>{if(!this.pc)return t();if(this.pc.iceGatheringState==="complete")t();else{const e=()=>{var i,s;((i=this.pc)==null?void 0:i.iceGatheringState)==="complete"&&((s=this.pc)==null||s.removeEventListener("icegatheringstatechange",e),t())};this.pc.addEventListener("icegatheringstatechange",e),setTimeout(()=>{var i;(i=this.pc)==null||i.removeEventListener("icegatheringstatechange",e),console.warn("âš ī¸ [WebRTC] ICE gathering timeout, proceeding anyway"),t()},5e3)}})}sendEvent(t,e={}){var i;((i=this.dataChannel)==null?void 0:i.readyState)==="open"&&this.dataChannel.send(JSON.stringify({event:t,...e}))}handleControlEvent(t){var e;switch(t.event){case"clearAudio":console.log("🛑 [WebRTC] Interrupt: clearAudio received (leaving stream unpaused)");break;case"transcription":console.log("📝 [WebRTC] Transcription:",t.text),this.onTranscription(t.text,t.isFinal);break;case"mark":console.log("đŸˇī¸ [WebRTC] Mark:",t.name);break;case"client_tool_call":{const i=t.tool_call||t.data||t,s=(i==null?void 0:i.tool_call_id)||(i==null?void 0:i.call_id)||t.tool_call_id||"";s&&((e=this.dataChannel)==null?void 0:e.readyState)==="open"?(this.dataChannel.send(JSON.stringify({event:"client_tool_ack",data:{tool_call_id:s}})),console.log("✅ [VaniraAI] Sent client_tool_ack for:",s)):s||console.warn("âš ī¸ [VaniraAI] client_tool_call received without tool_call_id — ack skipped"),console.log("đŸ› ī¸ [VaniraAI] Client Tool Call:",t),this.onClientToolCall(i);break}default:console.log("â„šī¸ [WebRTC] Unknown event:",t.event)}}disconnect(){console.log("🔴 [WebRTC] Disconnecting..."),this.audioElement&&(this.audioElement.pause(),this.audioElement.srcObject=null),this.dataChannel&&(this.dataChannel.close(),this.dataChannel=null),this.pc&&(this.pc.getSenders().forEach(t=>{t.track&&t.track.stop()}),this.pc.close(),this.pc=null),this.connected=!1,this.onDisconnected()}generateCallId(){return"web_"+Date.now()+"_"+Math.random().toString(36).substr(2,8)}sendToolResult(t,e){this.sendEvent("client_tool_result",{call_id:t,result:e})}sendToolAck(t){var e;((e=this.dataChannel)==null?void 0:e.readyState)==="open"?(this.dataChannel.send(JSON.stringify({event:"client_tool_ack",data:{tool_call_id:t}})),console.log("✅ [VaniraAI] Sent client_tool_ack for:",t)):console.warn("âš ī¸ [VaniraAI] Cannot send tool_ack: DataChannel not open")}sendContextUpdate(t){this.sendEvent("client_context_update",{data:{context:t}})}sendActionTrigger(t,e={}){this.sendEvent("client_action_trigger",{data:{action_name:t,data:e}})}triggerActionInterrupt(){this.sendEvent("action_interrupt"),console.log("🛑 [VaniraAI] Triggered client-side action interrupt")}static async fetchIceServers(t,e="https://coredb.travelr.club/v1/graphql"){var i;try{const n=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authorization:t},body:JSON.stringify({query:`
37
37
  query GetIceServers {
38
38
  ice_servers(where: {enabled: {_eq: true}}) {
39
39
  urls
@@ -942,7 +942,7 @@ overflow: hidden;
942
942
  < img src = "${L}" style = "width: 100%; height: 100%; object-fit: cover;" />
943
943
  </div>
944
944
  </div>
945
- `});class j{constructor(t,e=p.chat){o(this,"element");o(this,"iconContainer");o(this,"isDragging",!1);o(this,"startX",0);o(this,"startY",0);o(this,"currentX",0);o(this,"currentY",0);o(this,"hasMoved",!1);this.onClick=t,this.element=document.createElement("button"),this.element.className="widget-fab",this.element.onpointerdown=this.dragStart.bind(this),this.iconContainer=document.createElement("div"),this.iconContainer.style.display="flex",this.iconContainer.style.alignItems="center",this.iconContainer.style.justifyContent="center",this.iconContainer.style.width="100%",this.iconContainer.style.height="100%",this.iconContainer.innerHTML=e,this.element.appendChild(this.iconContainer)}dragStart(t){const e=this.element.getBoundingClientRect();this.isDragging=!0,this.hasMoved=!1,this.startX=t.clientX-e.left,this.startY=t.clientY-e.top,this.element.setPointerCapture(t.pointerId),this.element.style.transition="none",this.element.style.cursor="grabbing";const i=n=>{if(!this.isDragging)return;this.hasMoved=!0,this.currentX=n.clientX-this.startX,this.currentY=n.clientY-this.startY;const a=window.innerWidth-this.element.offsetWidth,r=window.innerHeight-this.element.offsetHeight;this.currentX=Math.max(0,Math.min(this.currentX,a)),this.currentY=Math.max(0,Math.min(this.currentY,r)),this.element.style.left=`${this.currentX}px`,this.element.style.top=`${this.currentY}px`,this.element.style.right="auto",this.element.style.bottom="auto"},s=n=>{this.isDragging=!1,this.element.hasPointerCapture(n.pointerId)&&this.element.releasePointerCapture(n.pointerId),this.element.style.transition="all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",this.element.style.cursor="pointer",window.removeEventListener("pointermove",i),window.removeEventListener("pointerup",s),this.hasMoved||this.onClick()};window.addEventListener("pointermove",i),window.addEventListener("pointerup",s)}getElement(){return this.element}setIcon(t){this.iconContainer.innerHTML=t}setPosition(t){t.split(";").filter(i=>i.trim()).forEach(i=>{const[s,n]=i.split(":").map(a=>a.trim());s&&n&&(this.element.style[s]=n)}),this.element.style.position="fixed"}static get styles(){return`
945
+ `});class j{constructor(t,e,i,s=p.chat){o(this,"element");o(this,"iconContainer");o(this,"posX",0);o(this,"posY",0);o(this,"isDragging",!1);o(this,"startX",0);o(this,"startY",0);o(this,"currentX",0);o(this,"currentY",0);o(this,"hasMoved",!1);this.onClick=t,this.onMove=e,this.onMoveEnd=i,this.element=document.createElement("button"),this.element.className="widget-fab",this.element.onpointerdown=this.dragStart.bind(this),this.iconContainer=document.createElement("div"),this.iconContainer.style.cssText="display:flex; align-items:center; justify-content:center; width:100%; height:100%;",this.iconContainer.innerHTML=s,this.element.appendChild(this.iconContainer)}dragStart(t){if(t.button!==0)return;const e=this.element.getBoundingClientRect();this.isDragging=!0,this.hasMoved=!1,this.startX=t.clientX,this.startY=t.clientY,this.currentX=e.left,this.currentY=e.top,this.element.setPointerCapture(t.pointerId),this.element.style.transition="none",this.element.style.cursor="grabbing";const i=n=>{var c;if(!this.isDragging)return;const a=n.clientX-this.startX,r=n.clientY-this.startY;(Math.abs(a)>5||Math.abs(r)>5)&&(this.hasMoved=!0),this.hasMoved&&(this.posX=this.currentX+a,this.posY=this.currentY+r,this.posX=Math.max(0,Math.min(this.posX,window.innerWidth-this.element.offsetWidth)),this.posY=Math.max(0,Math.min(this.posY,window.innerHeight-this.element.offsetHeight)),this.element.style.left=`${this.posX}px`,this.element.style.top=`${this.posY}px`,this.element.style.right="auto",this.element.style.bottom="auto",(c=this.onMove)==null||c.call(this,this.posX,this.posY))},s=n=>{var a;this.isDragging=!1,this.element.hasPointerCapture(n.pointerId)&&this.element.releasePointerCapture(n.pointerId),this.element.style.transition="all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",this.element.style.cursor="pointer",window.removeEventListener("pointermove",i),window.removeEventListener("pointerup",s),this.hasMoved?(a=this.onMoveEnd)==null||a.call(this,this.posX,this.posY):this.onClick()};window.addEventListener("pointermove",i),window.addEventListener("pointerup",s)}getElement(){return this.element}setIcon(t){this.iconContainer.innerHTML=t}setPosition(t){this.element.style.cssText="",t.split(";").filter(i=>i.trim()).forEach(i=>{const[s,n]=i.split(":").map(a=>a.trim());s&&n&&(this.element.style[s]=n)}),this.element.style.position="fixed",this.element.style.zIndex="2147483647"}updateCoordinates(t,e){this.element.style.left=`${t}px`,this.element.style.top=`${e}px`,this.element.style.right="auto",this.element.style.bottom="auto"}static get styles(){return`
946
946
  .widget-fab {
947
947
  position: fixed;
948
948
  z-index: 9999;
@@ -977,7 +977,7 @@ overflow: hidden;
977
977
  height: 26px;
978
978
  color: white;
979
979
  }
980
- `}}class N{constructor(t,e="Assistant"){o(this,"element");o(this,"header");o(this,"titleElement");o(this,"contentArea");o(this,"maximizeBtn");o(this,"closeBtn");o(this,"isMaximized",!1);this.onClose=t,this.title=e,this.element=document.createElement("div"),this.element.className="widget-panel hidden",this.header=document.createElement("div"),this.header.className="widget-header",this.titleElement=document.createElement("h3"),this.titleElement.className="widget-title",this.titleElement.textContent=this.title;const i=document.createElement("div");i.style.display="flex",i.style.alignItems="center",i.style.gap="8px",i.style.marginLeft="auto",this.maximizeBtn=document.createElement("button"),this.maximizeBtn.className="close-btn maximize-btn",this.maximizeBtn.innerHTML=p.maximize2,this.maximizeBtn.onclick=()=>this.toggleMaximize(),this.closeBtn=document.createElement("button"),this.closeBtn.className="close-btn",this.closeBtn.innerHTML=p.close,this.closeBtn.onclick=this.onClose,i.appendChild(this.maximizeBtn),i.appendChild(this.closeBtn),this.header.appendChild(i),this.contentArea=document.createElement("div"),this.contentArea.className="widget-body",this.contentArea.style.flex="1",this.contentArea.style.display="flex",this.contentArea.style.flexDirection="column",this.contentArea.style.overflow="hidden",this.contentArea.style.padding="0",this.element.appendChild(this.header),this.element.appendChild(this.contentArea)}getElement(){return this.element}setContent(t){this.contentArea.innerHTML="",this.contentArea.appendChild(t)}addToContent(t){this.contentArea.appendChild(t)}setTitle(t){this.titleElement.textContent=t}open(t){this.element.classList.remove("hidden"),Object.assign(this.element.style,t)}close(){this.element.classList.add("hidden")}toggleMaximize(){this.isMaximized=!this.isMaximized,this.isMaximized?(this.element.classList.add("maximized"),this.maximizeBtn.innerHTML=p.minimize2):(this.element.classList.remove("maximized"),this.maximizeBtn.innerHTML=p.maximize2)}static get styles(){return`
980
+ `}}class N{constructor(t,e="Assistant"){o(this,"element");o(this,"header");o(this,"titleElement");o(this,"contentArea");o(this,"maximizeBtn");o(this,"closeBtn");o(this,"isMaximized",!1);this.onClose=t,this.title=e,this.element=document.createElement("div"),this.element.className="widget-panel hidden",this.header=document.createElement("div"),this.header.className="widget-header",this.titleElement=document.createElement("h3"),this.titleElement.className="widget-title",this.titleElement.textContent=this.title;const i=document.createElement("div");i.style.display="flex",i.style.alignItems="center",i.style.gap="8px",i.style.marginLeft="auto",this.maximizeBtn=document.createElement("button"),this.maximizeBtn.className="close-btn maximize-btn",this.maximizeBtn.innerHTML=p.maximize2,this.maximizeBtn.onclick=()=>this.toggleMaximize(),this.closeBtn=document.createElement("button"),this.closeBtn.className="close-btn",this.closeBtn.innerHTML=p.close,this.closeBtn.onclick=this.onClose,i.appendChild(this.maximizeBtn),i.appendChild(this.closeBtn),this.header.appendChild(i),this.contentArea=document.createElement("div"),this.contentArea.className="widget-body",this.contentArea.style.flex="1",this.contentArea.style.display="flex",this.contentArea.style.flexDirection="column",this.contentArea.style.overflow="hidden",this.contentArea.style.padding="0",this.element.appendChild(this.header),this.element.appendChild(this.contentArea)}getElement(){return this.element}setContent(t){this.contentArea.innerHTML="",this.contentArea.appendChild(t)}addToContent(t){this.contentArea.appendChild(t)}setTitle(t){this.titleElement.textContent=t}open(t){this.element.classList.remove("hidden"),this.updatePosition(t)}updatePosition(t){this.element.style.top="auto",this.element.style.bottom="auto",this.element.style.left="auto",this.element.style.right="auto",Object.assign(this.element.style,t),this.element.style.position="fixed",this.element.style.zIndex="2147483647"}close(){this.element.classList.add("hidden")}toggleMaximize(){this.isMaximized=!this.isMaximized,this.isMaximized?(this.element.classList.add("maximized"),this.maximizeBtn.innerHTML=p.minimize2):(this.element.classList.remove("maximized"),this.maximizeBtn.innerHTML=p.maximize2)}static get styles(){return`
981
981
  /* Panel Styles handled in widget.css.ts mostly, specific overrides here */
982
982
  `}}class O{constructor(t,e="#6366f1",i="#a855f7",s){o(this,"element");o(this,"contentContainer");o(this,"orbWrapper");o(this,"connectingRing");o(this,"errorRing");o(this,"waveLayers",[]);o(this,"outerGlow");o(this,"wave1");o(this,"wave2");o(this,"wave3");o(this,"centerIcon");o(this,"statusArea");o(this,"connectingLabel");o(this,"connectedBadge");o(this,"errorLabel");o(this,"retryBtn");o(this,"timerEl");o(this,"transcriptionEl");o(this,"hangupBtn");o(this,"videoContainer");o(this,"videoElement");o(this,"prepareBadge");o(this,"statusBadge");o(this,"startTime",null);o(this,"timerInterval",null);o(this,"isAvatarMode",!1);o(this,"callStartedAt",null);this.onHangup=t,this.primaryColor=e,this.secondaryColor=i,this.onCallEnded=s,this.element=document.createElement("div"),this.element.id="voice-active-overlay",this.element.style.cssText=`
983
983
  position: absolute; top: 0; left: 0; width: 100%; height: 100%;
@@ -1049,11 +1049,11 @@ overflow: hidden;
1049
1049
  display: none; align-items: center; gap: 8px;
1050
1050
  padding: 5px 16px; background: #f0fdf4;
1051
1051
  border-radius: 9999px; border: 1px solid #dcfce7;
1052
- `;const r=document.createElement("div");r.style.cssText="width:8px; height:8px; border-radius:50%; background:#22c55e; animation:pulse 2s infinite; box-shadow:0 0 8px rgba(34,197,94,0.6);";const l=document.createElement("span");l.textContent="Connected",l.style.cssText="font-size:11px; font-weight:600; color:#15803d; text-transform:uppercase; letter-spacing:0.1em;",this.connectedBadge.appendChild(r),this.connectedBadge.appendChild(l),this.statusArea.appendChild(this.connectedBadge),this.timerEl=document.createElement("div"),this.timerEl.textContent="00:00",this.timerEl.style.cssText="font-size:13px; color:#6b7280; font-variant-numeric:tabular-nums; display:none;",this.statusArea.appendChild(this.timerEl),this.errorLabel=document.createElement("p"),this.errorLabel.textContent="Connection failed",this.errorLabel.style.cssText="font-size:12px; color:#ef4444; font-weight:500; margin:0; display:none;",this.statusArea.appendChild(this.errorLabel),this.retryBtn=document.createElement("button"),this.retryBtn.textContent="â†ģ Retry Connection",this.retryBtn.style.cssText=`
1052
+ `;const r=document.createElement("div");r.style.cssText="width:8px; height:8px; border-radius:50%; background:#22c55e; animation:pulse 2s infinite; box-shadow:0 0 8px rgba(34,197,94,0.6);";const c=document.createElement("span");c.textContent="Connected",c.style.cssText="font-size:11px; font-weight:600; color:#15803d; text-transform:uppercase; letter-spacing:0.1em;",this.connectedBadge.appendChild(r),this.connectedBadge.appendChild(c),this.statusArea.appendChild(this.connectedBadge),this.timerEl=document.createElement("div"),this.timerEl.textContent="00:00",this.timerEl.style.cssText="font-size:13px; color:#6b7280; font-variant-numeric:tabular-nums; display:none;",this.statusArea.appendChild(this.timerEl),this.errorLabel=document.createElement("p"),this.errorLabel.textContent="Connection failed",this.errorLabel.style.cssText="font-size:12px; color:#ef4444; font-weight:500; margin:0; display:none;",this.statusArea.appendChild(this.errorLabel),this.retryBtn=document.createElement("button"),this.retryBtn.textContent="â†ģ Retry Connection",this.retryBtn.style.cssText=`
1053
1053
  display:none; padding:6px 14px; background:#f3f4f6; border:none;
1054
1054
  border-radius:9999px; font-size:12px; font-weight:500; color:#374151;
1055
1055
  cursor:pointer; transition:background 0.2s; pointer-events:auto;
1056
- `,this.retryBtn.onmouseover=()=>this.retryBtn.style.background="#e5e7eb",this.retryBtn.onmouseout=()=>this.retryBtn.style.background="#f3f4f6",this.statusArea.appendChild(this.retryBtn),this.prepareBadge=document.createElement("p"),this.prepareBadge.style.cssText="display:none; font-size:11px; font-weight:600; color:#a855f7; text-transform:uppercase; letter-spacing:0.1em; margin:0; animation:pulse 1.5s infinite;",this.statusArea.appendChild(this.prepareBadge),this.statusBadge=document.createElement("div"),this.statusBadge.style.cssText="display:none; align-items:center; gap:8px; padding:5px 16px; background:#f0fdf4; border-radius:9999px; border:1px solid #dcfce7;";const A=document.createElement("div");A.style.cssText="width:8px; height:8px; border-radius:50%; background:#22c55e; animation:pulse 2s infinite;";const c=document.createElement("span");c.textContent="Connected",c.style.cssText="font-size:11px; font-weight:600; color:#15803d; text-transform:uppercase; letter-spacing:0.1em;",this.statusBadge.appendChild(A),this.statusBadge.appendChild(c),this.statusArea.appendChild(this.statusBadge),this.contentContainer.appendChild(this.statusArea),this.transcriptionEl=document.createElement("div"),this.transcriptionEl.style.cssText=`
1056
+ `,this.retryBtn.onmouseover=()=>this.retryBtn.style.background="#e5e7eb",this.retryBtn.onmouseout=()=>this.retryBtn.style.background="#f3f4f6",this.statusArea.appendChild(this.retryBtn),this.prepareBadge=document.createElement("p"),this.prepareBadge.style.cssText="display:none; font-size:11px; font-weight:600; color:#a855f7; text-transform:uppercase; letter-spacing:0.1em; margin:0; animation:pulse 1.5s infinite;",this.statusArea.appendChild(this.prepareBadge),this.statusBadge=document.createElement("div"),this.statusBadge.style.cssText="display:none; align-items:center; gap:8px; padding:5px 16px; background:#f0fdf4; border-radius:9999px; border:1px solid #dcfce7;";const l=document.createElement("div");l.style.cssText="width:8px; height:8px; border-radius:50%; background:#22c55e; animation:pulse 2s infinite;";const A=document.createElement("span");A.textContent="Connected",A.style.cssText="font-size:11px; font-weight:600; color:#15803d; text-transform:uppercase; letter-spacing:0.1em;",this.statusBadge.appendChild(l),this.statusBadge.appendChild(A),this.statusArea.appendChild(this.statusBadge),this.contentContainer.appendChild(this.statusArea),this.transcriptionEl=document.createElement("div"),this.transcriptionEl.style.cssText=`
1057
1057
  margin-top: 14px; padding: 0 20px; text-align: center;
1058
1058
  min-height: 36px; max-height: 72px; overflow-y: auto;
1059
1059
  font-size: 13px; color: #9ca3af; font-style: italic;
@@ -1105,7 +1105,7 @@ overflow: hidden;
1105
1105
  </div>
1106
1106
  <div class="voice-status-text">Tap to speak</div>
1107
1107
  <div class="voice-status-subtext">Start a conversation</div>
1108
- `;const e=this.element.querySelector(".central-orb-container");e&&(e.onclick=this.onClick)}getElement(){return this.element}}class U{constructor(t){o(this,"element");o(this,"chips",[]);this.onChipClick=t,this.element=document.createElement("div"),this.element.className="welcome-chips-container"}setChips(t){this.chips=t,this.render()}getElement(){return this.element}setPosition(t){let e=t;e.includes("bottom:")?e=e.replace(/bottom:\s*[\d]+px/,"bottom: 100px"):e.includes("top:")&&(e=e.replace(/top:\s*[\d]+px/,"top: 100px")),this.element.setAttribute("style",e)}render(){this.element.innerHTML="",this.chips.forEach((t,e)=>{const i=document.createElement("button");i.className="welcome-chip-btn",i.textContent=t.title,i.onclick=s=>{s.stopPropagation(),this.onChipClick(t.title)},i.style.animationDelay=`${e*.1}s`,this.element.appendChild(i)})}static get styles(){return`
1108
+ `;const e=this.element.querySelector(".central-orb-container");e&&(e.onclick=this.onClick)}getElement(){return this.element}}class U{constructor(t){o(this,"element");o(this,"chips",[]);this.onChipClick=t,this.element=document.createElement("div"),this.element.className="welcome-chips-container"}setChips(t){this.chips=t,this.render()}getElement(){return this.element}setPosition(t){this.element.style.cssText="",t.split(";").filter(i=>i.trim()).forEach(i=>{const[s,n]=i.split(":").map(a=>a.trim());s&&n&&(this.element.style[s]=n)}),this.element.style.bottom?this.element.style.bottom=parseInt(this.element.style.bottom)+76+"px":this.element.style.top&&(this.element.style.top=parseInt(this.element.style.top)+76+"px"),this.element.style.position="fixed",this.element.style.zIndex="2147483646",this.element.style.alignItems=this.element.style.left?"flex-start":"flex-end"}updateCoordinates(t,e,i=!0){this.element.style.left=`${t}px`,i?(this.element.style.top="auto",this.element.style.bottom=`${window.innerHeight-e+16}px`):(this.element.style.bottom="auto",this.element.style.top=`${e+76}px`),this.element.style.right="auto"}render(){this.element.innerHTML="",this.chips.forEach((t,e)=>{const i=document.createElement("button");i.className="welcome-chip-btn",i.textContent=t.title,i.onclick=s=>{s.stopPropagation(),this.onChipClick(t.title)},i.style.animationDelay=`${e*.1}s`,this.element.appendChild(i)})}static get styles(){return`
1109
1109
  .welcome-chips-container {
1110
1110
  position: fixed;
1111
1111
  z-index: 9998;
@@ -1161,7 +1161,7 @@ overflow: hidden;
1161
1161
  transform: translateY(0);
1162
1162
  }
1163
1163
  }
1164
- `}}class V{constructor(t,e,i="#6366f1",s="#a855f7",n){o(this,"element");o(this,"overlay");o(this,"onStartCall");o(this,"onHangup");o(this,"primaryColor");o(this,"secondaryColor");o(this,"onCallEnded");this.onStartCall=t,this.onHangup=e,this.primaryColor=i,this.secondaryColor=s,this.onCallEnded=n,this.element=document.createElement("div"),this.element.style.height="100%",this.element.style.position="relative"}initOverlay(){this.overlay=new O(()=>this.onHangup(),this.primaryColor,this.secondaryColor,this.onCallEnded),this.element.appendChild(this.overlay.getElement())}getElement(){return this.element}setCallActive(t){t?this.overlay.show():this.overlay.hide()}setStatus(t){this.overlay.setStatus(t)}setTranscription(t,e){this.overlay.setTranscription(t,e)}setVideoTrack(t){this.overlay.setVideoTrack(t)}}class oe extends V{constructor(e,i,s="#6366f1",n="#a855f7",a){super(e,i,s,n,a);o(this,"voiceOrb");this.element.style.background="#f9fafb",this.voiceOrb=new ne(()=>this.onStartCall()),this.element.appendChild(this.voiceOrb.getElement()),this.initOverlay()}}class ae{constructor(t){o(this,"element");o(this,"chatWindow");this.onSendMessage=t,this.element=document.createElement("div"),this.element.style.flex="1",this.element.style.width="100%",this.element.style.minHeight="0",this.element.style.display="flex",this.element.style.flexDirection="column",this.chatWindow=new W(e=>this.onSendMessage(e)),this.element.appendChild(this.chatWindow.getElement())}getElement(){return this.element}getChatWindow(){return this.chatWindow}}class X{constructor(t,e,i,s="#6366f1",n="#a855f7",a){o(this,"element");o(this,"chatWindow");o(this,"overlay");o(this,"voiceTrigger");this.onSendMessage=t,this.onStartCall=e,this.onHangup=i,this.primaryColor=s,this.secondaryColor=n,this.onCallEnded=a,this.element=document.createElement("div"),this.element.style.flex="1",this.element.style.display="flex",this.element.style.flexDirection="column",this.element.style.minHeight="0",this.element.style.position="relative"}setupChat(){this.chatWindow=new W(e=>this.onSendMessage(e));const t=this.chatWindow.getElement();t.style.flex="1",this.element.appendChild(t),this.injectVoiceTrigger(),this.overlay=new O(()=>this.onHangup(),this.primaryColor,this.secondaryColor,this.onCallEnded),this.element.appendChild(this.overlay.getElement())}injectVoiceTrigger(){const t=document.createElement("button");this.voiceTrigger=t,t.className="voice-btn-simple",t.innerHTML=`<div class="voice-btn-icon">${p.audioLines}</div>`,t.onclick=()=>this.onStartCall();const e=this.chatWindow.getElement().querySelector(".chat-input-area");e?e.insertBefore(this.voiceTrigger,e.firstChild):console.warn("VaniraSDK: Failed to inject voice trigger",{inputArea:e})}getElement(){return this.element}getChatWindow(){return this.chatWindow}setCallActive(t){t?(this.overlay.show(),this.chatWindow&&(this.chatWindow.getElement().style.display="none")):(this.overlay.hide(),this.chatWindow&&(this.chatWindow.getElement().style.display="flex"))}setStatus(t){this.overlay.setStatus(t)}setTranscription(t,e){this.overlay.setTranscription(t,e)}setVideoTrack(t){this.overlay.setVideoTrack(t)}}class re extends X{constructor(t,e,i,s="#6366f1",n="#a855f7",a){super(t,e,i,s,n,a),this.setupChat()}}class le extends V{constructor(e,i,s="#6366f1",n="#a855f7",a){super(e,i,s,n,a);o(this,"avatarView");o(this,"startCallBtn");o(this,"controlsContainer");this.element.style.display="flex",this.element.style.flexDirection="column",this.avatarView=new se;const r=this.avatarView.getElement();r.style.width="100%",r.style.maxWidth="300px",r.style.aspectRatio="1/1",r.style.borderRadius="16px",r.style.overflow="hidden",r.style.margin="auto",r.style.position="relative",this.element.appendChild(r),this.controlsContainer=document.createElement("div"),this.controlsContainer.className="widget-body",this.controlsContainer.style.position="absolute",this.controlsContainer.style.bottom="20px",this.controlsContainer.style.width="100%",this.controlsContainer.style.zIndex="10";const l=document.createElement("div");l.className="controls",this.startCallBtn=document.createElement("button"),this.startCallBtn.className="control-btn primary",this.startCallBtn.innerHTML=`${p.phone} <span>Start Call</span>`,this.startCallBtn.onclick=()=>this.onStartCall(),l.appendChild(this.startCallBtn),this.controlsContainer.appendChild(l),this.element.appendChild(this.controlsContainer),this.initOverlay(),this.overlay.setMode("avatar")}getAvatarView(){return this.avatarView}setCallActive(e){e&&this.overlay.setMode("avatar"),super.setCallActive(e),e?this.controlsContainer.style.display="none":this.controlsContainer.style.display="block"}}class Ae extends X{constructor(t,e,i,s="#6366f1",n="#a855f7",a){super(t,e,i,s,n,a),this.setupChat(),this.overlay.setMode("avatar")}injectVoiceTrigger(){const t=document.createElement("button");this.voiceTrigger=t,t.className="voice-btn-simple",t.style.overflow="hidden",t.style.padding="0",t.style.border="1.5px solid #e5e7eb",t.innerHTML=`
1164
+ `}}class V{constructor(t,e,i="#6366f1",s="#a855f7",n){o(this,"element");o(this,"overlay");o(this,"onStartCall");o(this,"onHangup");o(this,"primaryColor");o(this,"secondaryColor");o(this,"onCallEnded");this.onStartCall=t,this.onHangup=e,this.primaryColor=i,this.secondaryColor=s,this.onCallEnded=n,this.element=document.createElement("div"),this.element.style.height="100%",this.element.style.position="relative"}initOverlay(){this.overlay=new O(()=>this.onHangup(),this.primaryColor,this.secondaryColor,this.onCallEnded),this.element.appendChild(this.overlay.getElement())}getElement(){return this.element}setCallActive(t){t?this.overlay.show():this.overlay.hide()}setStatus(t){this.overlay.setStatus(t)}setTranscription(t,e){this.overlay.setTranscription(t,e)}setVideoTrack(t){this.overlay.setVideoTrack(t)}}class oe extends V{constructor(e,i,s="#6366f1",n="#a855f7",a){super(e,i,s,n,a);o(this,"voiceOrb");this.element.style.background="#f9fafb",this.voiceOrb=new ne(()=>this.onStartCall()),this.element.appendChild(this.voiceOrb.getElement()),this.initOverlay()}}class ae{constructor(t){o(this,"element");o(this,"chatWindow");this.onSendMessage=t,this.element=document.createElement("div"),this.element.style.flex="1",this.element.style.width="100%",this.element.style.minHeight="0",this.element.style.display="flex",this.element.style.flexDirection="column",this.chatWindow=new W(e=>this.onSendMessage(e)),this.element.appendChild(this.chatWindow.getElement())}getElement(){return this.element}getChatWindow(){return this.chatWindow}}class X{constructor(t,e,i,s="#6366f1",n="#a855f7",a){o(this,"element");o(this,"chatWindow");o(this,"overlay");o(this,"voiceTrigger");this.onSendMessage=t,this.onStartCall=e,this.onHangup=i,this.primaryColor=s,this.secondaryColor=n,this.onCallEnded=a,this.element=document.createElement("div"),this.element.style.flex="1",this.element.style.display="flex",this.element.style.flexDirection="column",this.element.style.minHeight="0",this.element.style.position="relative"}setupChat(){this.chatWindow=new W(e=>this.onSendMessage(e));const t=this.chatWindow.getElement();t.style.flex="1",this.element.appendChild(t),this.injectVoiceTrigger(),this.overlay=new O(()=>this.onHangup(),this.primaryColor,this.secondaryColor,this.onCallEnded),this.element.appendChild(this.overlay.getElement())}injectVoiceTrigger(){const t=document.createElement("button");this.voiceTrigger=t,t.className="voice-btn-simple",t.innerHTML=`<div class="voice-btn-icon">${p.audioLines}</div>`,t.onclick=()=>this.onStartCall();const e=this.chatWindow.getElement().querySelector(".chat-input-area");e?e.insertBefore(this.voiceTrigger,e.firstChild):console.warn("VaniraSDK: Failed to inject voice trigger",{inputArea:e})}getElement(){return this.element}getChatWindow(){return this.chatWindow}setCallActive(t){t?(this.overlay.show(),this.chatWindow&&(this.chatWindow.getElement().style.display="none")):(this.overlay.hide(),this.chatWindow&&(this.chatWindow.getElement().style.display="flex"))}setStatus(t){this.overlay.setStatus(t)}setTranscription(t,e){this.overlay.setTranscription(t,e)}setVideoTrack(t){this.overlay.setVideoTrack(t)}}class re extends X{constructor(t,e,i,s="#6366f1",n="#a855f7",a){super(t,e,i,s,n,a),this.setupChat()}}class le extends V{constructor(e,i,s="#6366f1",n="#a855f7",a){super(e,i,s,n,a);o(this,"avatarView");o(this,"startCallBtn");o(this,"controlsContainer");this.element.style.display="flex",this.element.style.flexDirection="column",this.avatarView=new se;const r=this.avatarView.getElement();r.style.width="100%",r.style.maxWidth="300px",r.style.aspectRatio="1/1",r.style.borderRadius="16px",r.style.overflow="hidden",r.style.margin="auto",r.style.position="relative",this.element.appendChild(r),this.controlsContainer=document.createElement("div"),this.controlsContainer.className="widget-body",this.controlsContainer.style.position="absolute",this.controlsContainer.style.bottom="20px",this.controlsContainer.style.width="100%",this.controlsContainer.style.zIndex="10";const c=document.createElement("div");c.className="controls",this.startCallBtn=document.createElement("button"),this.startCallBtn.className="control-btn primary",this.startCallBtn.innerHTML=`${p.phone} <span>Start Call</span>`,this.startCallBtn.onclick=()=>this.onStartCall(),c.appendChild(this.startCallBtn),this.controlsContainer.appendChild(c),this.element.appendChild(this.controlsContainer),this.initOverlay(),this.overlay.setMode("avatar")}getAvatarView(){return this.avatarView}setCallActive(e){e&&this.overlay.setMode("avatar"),super.setCallActive(e),e?this.controlsContainer.style.display="none":this.controlsContainer.style.display="block"}}class Ae extends X{constructor(t,e,i,s="#6366f1",n="#a855f7",a){super(t,e,i,s,n,a),this.setupChat(),this.overlay.setMode("avatar")}injectVoiceTrigger(){const t=document.createElement("button");this.voiceTrigger=t,t.className="voice-btn-simple",t.style.overflow="hidden",t.style.padding="0",t.style.border="1.5px solid #e5e7eb",t.innerHTML=`
1165
1165
  <video
1166
1166
  src="https://www.simli.com/jenna.mp4"
1167
1167
  autoplay loop muted pip="false" playsinline
@@ -1170,7 +1170,7 @@ overflow: hidden;
1170
1170
  <div style="position: absolute; bottom: -2px; right: -2px; background: white; border-radius: 50%; padding: 2px; box-shadow: 0 1px 2px rgba(0,0,0,0.1);">
1171
1171
  ${p.audioLines.replace('width="24"','width="12"').replace('height="24"','height="12"')}
1172
1172
  </div>
1173
- `;const e=t.querySelector("div");if(e){const n=e.querySelector("svg");n&&(n.style.width="12px",n.style.height="12px")}t.onclick=()=>this.onStartCall();const i=this.chatWindow.getElement().querySelector(".chat-input-area"),s=i==null?void 0:i.querySelector(".chat-send-btn");i&&s?i.insertBefore(this.voiceTrigger,s):console.warn("VaniraSDK: Failed to inject voice trigger",{inputArea:i,sendBtn:s})}}class ce{async sendMessage(t,e,i,s,n,a,r,l){return v.sendChatMessage(e,i,t,s,A=>{a&&a(A)},n,A=>{r&&A&&r(A)},l)}async sendFile(t){throw console.warn("sendFile not implemented for VaniraChatAdapter yet - Incompatible function adapted",t),new Error("Method not implemented.")}async likeDislike(t,e){console.warn("likeDislike not implemented for VaniraChatAdapter yet - Incompatible function adapted",t,e)}}const B=class B extends ${constructor(e){super(e);o(this,"vaniraClient",null);o(this,"currentView",null);o(this,"isPanelOpen",!1);o(this,"callActive",!1);o(this,"eventSource",null);o(this,"floatingButton",null);o(this,"floatingWelcomeChips",null);o(this,"panel",null);o(this,"welcomeChipsData",[]);o(this,"chatAdapter");o(this,"sessionManager",null);o(this,"sessionActive",!1);o(this,"widgetMode","voice_only");o(this,"agentId","");o(this,"prospectGroupId","");o(this,"chatServerUrl","");o(this,"prospectId","");o(this,"chatId",null);o(this,"widgetId","");o(this,"primaryColor","#6366f1");o(this,"secondaryColor","#4f46e5");o(this,"gradient",null);o(this,"position","bottom-right");o(this,"widgetIcon",null);o(this,"chatWelcomeMessage",null);this.chatAdapter=new ce,this.processConfig(e)}initSessionManager(){const e=this.widgetId||this.agentId||"default";this.sessionManager=new P(e),this.sessionManager.on("tab_took_over",()=>{console.warn("[VaniraAI] Session taken over by another tab."),this.sessionActive=!1,this.showTabConflictBanner("taken_over")}),this.sessionManager.on("session_cleared",()=>{console.log("[VaniraAI] Session cleared externally.")});const i=this.sessionManager.claimSession();return this.sessionActive=i,i}restoreSessionMessages(){var l,A,c;const e=(l=this.sessionManager)==null?void 0:l.getSession();if(!e)return;const i=(c=(A=this.currentView)==null?void 0:A.getChatWindow)==null?void 0:c.call(A);if(!i)return;const s=e.messages.filter(d=>d.content.trim()!==""),n=`vanira_calls_${this.widgetId||this.agentId}`,a=JSON.parse(localStorage.getItem(n)||"[]");if(s.length===0&&a.length===0)return;i.clearMessages();const r=[...s.map((d,g)=>({type:"msg",role:d.role,content:d.content,ts:d.timestamp??g})),...a.map(d=>({type:"call",durationMs:d.durationMs,startedAt:d.startedAt,ts:d.startedAt}))];r.sort((d,g)=>d.ts-g.ts),r.forEach(d=>{d.type==="msg"?i.addMessage(d.role,d.content,d.ts):i.addCallRecord(d.durationMs,d.startedAt)}),console.log(`[VaniraAI] Restored ${s.length} messages + ${a.length} call records from session.`)}showTabConflictBanner(e){var i,s;this.root&&((i=this.root.querySelector(".vanira-tab-conflict-banner"))==null||i.remove(),e==="conflict"&&((s=this.sessionManager)==null||s.forceClaimSession(),this.sessionActive=!0,this.widgetMode.includes("chat")&&this.initializeChatSession(!1)))}playMessageSound(e){try{if(!B.audioContext){const r=window.AudioContext||window.webkitAudioContext;if(!r)return;B.audioContext=new r}const i=B.audioContext;i.state==="suspended"&&i.resume().catch(()=>{});const s=i.createOscillator(),n=i.createGain();s.connect(n),n.connect(i.destination);const a=i.currentTime;e==="send"?(s.type="sine",s.frequency.setValueAtTime(300,a),s.frequency.exponentialRampToValueAtTime(500,a+.05),n.gain.setValueAtTime(0,a),n.gain.linearRampToValueAtTime(.1,a+.01),n.gain.exponentialRampToValueAtTime(.001,a+.1),s.start(a),s.stop(a+.1)):(s.type="sine",s.frequency.setValueAtTime(500,a),s.frequency.exponentialRampToValueAtTime(800,a+.1),n.gain.setValueAtTime(0,a),n.gain.linearRampToValueAtTime(.15,a+.02),n.gain.exponentialRampToValueAtTime(.001,a+.2),s.start(a),s.stop(a+.2))}catch(i){console.warn("[VaniraAI] Audio feedback failed",i)}}handleWelcomePayload(e,i="assistant"){var a,r,l,A,c,d;if(!e||this.widgetMode==="voice_only")return;e.buttons&&Array.isArray(e.buttons)?this.welcomeChipsData=e.buttons:((a=e.widget)==null?void 0:a.type)==="button_list"&&((r=e.widget.data)!=null&&r.buttons)&&(this.welcomeChipsData=e.widget.data.buttons),this.updateWelcomeChipsVisibility();const s=(A=(l=this.currentView)==null?void 0:l.getChatWindow)==null?void 0:A.call(l),n=e.text||e.response||"";if(console.log("[VaniraAI] Processing Welcome Payload:",{hasText:!!n,chipsCount:this.welcomeChipsData.length,hasChatWindow:!!s,mode:this.widgetMode}),s){if(!n&&this.welcomeChipsData.length===0)return;const g=(c=this.sessionManager)==null?void 0:c.getSession();(g==null?void 0:g.messages.some(m=>m.content===n&&m.role===i))||(n&&(s.addMessage(i,n),(d=this.sessionManager)==null||d.pushMessage(i,n)),this.welcomeChipsData.length>0&&s.addButtons(this.welcomeChipsData))}}async initializeChatSession(e=!1){var i,s,n,a,r,l;if(this.sessionActive)try{v.setChatUrl(this.chatServerUrl);const A=(i=this.sessionManager)==null?void 0:i.getSession();if(!e&&(A!=null&&A.prospectId)){this.prospectId=A.prospectId,this.chatId=A.chatId,console.log(`[VaniraAI] Session restored — tab: ${(s=this.sessionManager)==null?void 0:s.getTabId()}, prospect: ${this.prospectId}`),this.restoreSessionMessages(),this.chatId&&!this.eventSource&&(this.eventSource=v.listenForAdminReplies(this.chatId,this.prospectId,d=>{var g,w,m;(w=(g=this.currentView)==null?void 0:g.getChatWindow)==null||w.call(g).addMessage("assistant",d),(m=this.sessionManager)==null||m.pushMessage("assistant",d),this.playMessageSound("receive")}));return}this.prospectGroupId?this.prospectId=await v.createChatProspect(this.prospectGroupId):this.prospectId=`anon_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;const c=await v.fetchWelcomeMessage(this.agentId,this.prospectId,this.widgetId||void 0);c!=null&&c.chatId&&!this.chatId&&(this.chatId=c.chatId,this.eventSource||(this.eventSource=v.listenForAdminReplies(this.chatId,this.prospectId,d=>{var g,w,m;(w=(g=this.currentView)==null?void 0:g.getChatWindow)==null||w.call(g).addMessage("assistant",d),(m=this.sessionManager)==null||m.pushMessage("assistant",d),this.playMessageSound("receive")}))),(n=this.sessionManager)==null||n.saveIds(this.prospectId,this.chatId)}catch(A){console.error("[VaniraAI] Chat init failed",A);const c="Hello! How can I help you today?";(r=(a=this.currentView)==null?void 0:a.getChatWindow)==null||r.call(a).addMessage("assistant",c),(l=this.sessionManager)==null||l.pushMessage("assistant",c)}}async initialize(e){await super.initialize(e),this.processConfig(e),this.root&&this.ui_renderer(this.root)}processConfig(e){var i,s;if(this.widgetId=e.widgetId||e.widget_id||"",this.agentId=e.agentId||e.agent_id||"",this.prospectGroupId=e.prospectGroupId||((i=e.client)==null?void 0:i.base_prospect_group_id)||"",this.widgetMode=e.widgetMode||e.mode||"voice_only",this.widgetId=e.widgetId||e.widget_id||"",this.primaryColor=e.primaryColor||e.primary_color||"#6366f1",this.secondaryColor=e.secondaryColor||e.secondary_color||"#a855f7",this.gradient=e.gradient||null,this.position=e.position||"bottom-right",this.widgetIcon=e.widgetIcon||e.icon||null,this.chatWelcomeMessage=e.chatWelcomeMessage||e.chat_welcome_message||((s=e.agent)==null?void 0:s.chat_welcome_message)||null,console.log("[VaniraAI] processConfig:",{hasPrimary:!!this.primaryColor,hasSecondary:!!this.secondaryColor,hasWelcome:!!this.chatWelcomeMessage}),typeof this.chatWelcomeMessage=="string")try{this.chatWelcomeMessage=JSON.parse(this.chatWelcomeMessage)}catch(n){console.warn("[VaniraAI] Failed to parse chatWelcomeMessage string",n)}this.chatServerUrl=e.serverUrl||e.chatServerUrl||"https://inboxapi.travelr.club",this.updateWelcomeChipsVisibility()}async create_call(){var e;if(!(this.callActive||!this.agentId)){this.sessionActive||((e=this.sessionManager)==null||e.forceClaimSession(),this.sessionActive=!0);try{this.callActive=!0,this.updateViewCallState(!0),this.updateViewStatus("connecting");const i=await v.createCall(this.agentId,null,this.prospectId||null,this.widgetMode),s=new H({agentId:this.agentId,callId:i.callId,serverUrl:i.workerUrl});s.on("connected",()=>this.updateViewStatus("connected")).on("disconnected",()=>this.end_call()).on("error",n=>{console.error("[VaniraAI Widget] Call error:",n),this.updateViewStatus("error")}).on("transcription",({text:n,isFinal:a})=>{var r,l;(l=(r=this.currentView)==null?void 0:r.setTranscription)==null||l.call(r,n,a)}).on("track",({track:n})=>{var a;this.widgetMode.includes("avatar")&&n.kind==="video"&&((a=this.currentView)!=null&&a.setVideoTrack)&&this.currentView.setVideoTrack(n)}).on("tool_call",n=>{var r,l;const a=new CustomEvent("vaniraai:tool_call",{detail:n,bubbles:!0,composed:!0});(l=(r=this.root)==null?void 0:r.host)==null||l.dispatchEvent(a),console.log("[VaniraAI Widget] Tool call dispatched:",n.name,n.arguments),n.execution_mode}),this.vaniraClient=s,await s.start()}catch(i){console.error("[VaniraAI Widget] Call failed",i),this.updateViewStatus("error")}}}end_call(){this.callActive=!1;const e=this.vaniraClient;this.vaniraClient=null,e&&e.stop(),this.updateViewCallState(!1)}updateViewCallState(e){var i;(i=this.currentView)!=null&&i.setCallActive&&this.currentView.setCallActive(e)}updateViewStatus(e){var i;(i=this.currentView)!=null&&i.setStatus&&this.currentView.setStatus(e)}ui_renderer(e){this.root=e,this.root.innerHTML="";const i=document.createElement("style");i.textContent=`@keyframes vanira-slide-up {
1173
+ `;const e=t.querySelector("div");if(e){const n=e.querySelector("svg");n&&(n.style.width="12px",n.style.height="12px")}t.onclick=()=>this.onStartCall();const i=this.chatWindow.getElement().querySelector(".chat-input-area"),s=i==null?void 0:i.querySelector(".chat-send-btn");i&&s?i.insertBefore(this.voiceTrigger,s):console.warn("VaniraSDK: Failed to inject voice trigger",{inputArea:i,sendBtn:s})}}class ce{async sendMessage(t,e,i,s,n,a,r,c){return v.sendChatMessage(e,i,t,s,l=>{a&&a(l)},n,l=>{r&&l&&r(l)},c)}async sendFile(t){throw console.warn("sendFile not implemented for VaniraChatAdapter yet - Incompatible function adapted",t),new Error("Method not implemented.")}async likeDislike(t,e){console.warn("likeDislike not implemented for VaniraChatAdapter yet - Incompatible function adapted",t,e)}}const B=class B extends ${constructor(e){super(e);o(this,"vaniraClient",null);o(this,"currentView",null);o(this,"isPanelOpen",!1);o(this,"callActive",!1);o(this,"eventSource",null);o(this,"floatingButton",null);o(this,"floatingWelcomeChips",null);o(this,"panel",null);o(this,"welcomeChipsData",[]);o(this,"chatAdapter");o(this,"sessionManager",null);o(this,"sessionActive",!1);o(this,"widgetMode","voice_only");o(this,"agentId","");o(this,"prospectGroupId","");o(this,"chatServerUrl","");o(this,"prospectId","");o(this,"chatId",null);o(this,"widgetId","");o(this,"primaryColor","#6366f1");o(this,"secondaryColor","#4f46e5");o(this,"gradient",null);o(this,"position","bottom-right");o(this,"widgetIcon",null);o(this,"chatWelcomeMessage",null);this.chatAdapter=new ce,this.processConfig(e)}initSessionManager(){const e=this.widgetId||this.agentId||"default";this.sessionManager=new P(e),this.sessionManager.on("tab_took_over",()=>{console.warn("[VaniraAI] Session taken over by another tab."),this.sessionActive=!1,this.showTabConflictBanner("taken_over")}),this.sessionManager.on("session_cleared",()=>{console.log("[VaniraAI] Session cleared externally.")});const i=this.sessionManager.claimSession();return this.sessionActive=i,i}restoreSessionMessages(){var c,l,A;const e=(c=this.sessionManager)==null?void 0:c.getSession();if(!e)return;const i=(A=(l=this.currentView)==null?void 0:l.getChatWindow)==null?void 0:A.call(l);if(!i)return;const s=e.messages.filter(d=>d.content.trim()!==""),n=`vanira_calls_${this.widgetId||this.agentId}`,a=JSON.parse(localStorage.getItem(n)||"[]");if(s.length===0&&a.length===0)return;i.clearMessages();const r=[...s.map((d,g)=>({type:"msg",role:d.role,content:d.content,ts:d.timestamp??g})),...a.map(d=>({type:"call",durationMs:d.durationMs,startedAt:d.startedAt,ts:d.startedAt}))];r.sort((d,g)=>d.ts-g.ts),r.forEach(d=>{d.type==="msg"?i.addMessage(d.role,d.content,d.ts):i.addCallRecord(d.durationMs,d.startedAt)}),console.log(`[VaniraAI] Restored ${s.length} messages + ${a.length} call records from session.`)}showTabConflictBanner(e){var i,s;this.root&&((i=this.root.querySelector(".vanira-tab-conflict-banner"))==null||i.remove(),e==="conflict"&&((s=this.sessionManager)==null||s.forceClaimSession(),this.sessionActive=!0,this.widgetMode.includes("chat")&&this.initializeChatSession(!1)))}playMessageSound(e){try{if(!B.audioContext){const r=window.AudioContext||window.webkitAudioContext;if(!r)return;B.audioContext=new r}const i=B.audioContext;i.state==="suspended"&&i.resume().catch(()=>{});const s=i.createOscillator(),n=i.createGain();s.connect(n),n.connect(i.destination);const a=i.currentTime;e==="send"?(s.type="sine",s.frequency.setValueAtTime(300,a),s.frequency.exponentialRampToValueAtTime(500,a+.05),n.gain.setValueAtTime(0,a),n.gain.linearRampToValueAtTime(.1,a+.01),n.gain.exponentialRampToValueAtTime(.001,a+.1),s.start(a),s.stop(a+.1)):(s.type="sine",s.frequency.setValueAtTime(500,a),s.frequency.exponentialRampToValueAtTime(800,a+.1),n.gain.setValueAtTime(0,a),n.gain.linearRampToValueAtTime(.15,a+.02),n.gain.exponentialRampToValueAtTime(.001,a+.2),s.start(a),s.stop(a+.2))}catch(i){console.warn("[VaniraAI] Audio feedback failed",i)}}handleWelcomePayload(e,i="assistant"){var a,r,c,l,A,d;if(!e||this.widgetMode==="voice_only")return;e.buttons&&Array.isArray(e.buttons)?this.welcomeChipsData=e.buttons:((a=e.widget)==null?void 0:a.type)==="button_list"&&((r=e.widget.data)!=null&&r.buttons)&&(this.welcomeChipsData=e.widget.data.buttons),this.updateWelcomeChipsVisibility();const s=(l=(c=this.currentView)==null?void 0:c.getChatWindow)==null?void 0:l.call(c),n=e.text||e.response||"";if(console.log("[VaniraAI] Processing Welcome Payload:",{hasText:!!n,chipsCount:this.welcomeChipsData.length,hasChatWindow:!!s,mode:this.widgetMode}),s){if(!n&&this.welcomeChipsData.length===0)return;const g=(A=this.sessionManager)==null?void 0:A.getSession();(g==null?void 0:g.messages.some(m=>m.content===n&&m.role===i))||(n&&(s.addMessage(i,n),(d=this.sessionManager)==null||d.pushMessage(i,n)),this.welcomeChipsData.length>0&&s.addButtons(this.welcomeChipsData))}}async initializeChatSession(e=!1){var i,s,n,a,r,c;if(this.sessionActive)try{v.setChatUrl(this.chatServerUrl);const l=(i=this.sessionManager)==null?void 0:i.getSession();if(!e&&(l!=null&&l.prospectId)){this.prospectId=l.prospectId,this.chatId=l.chatId,console.log(`[VaniraAI] Session restored — tab: ${(s=this.sessionManager)==null?void 0:s.getTabId()}, prospect: ${this.prospectId}`),this.restoreSessionMessages(),this.chatId&&!this.eventSource&&(this.eventSource=v.listenForAdminReplies(this.chatId,this.prospectId,d=>{var g,w,m;(w=(g=this.currentView)==null?void 0:g.getChatWindow)==null||w.call(g).addMessage("assistant",d),(m=this.sessionManager)==null||m.pushMessage("assistant",d),this.playMessageSound("receive")}));return}this.prospectGroupId?this.prospectId=await v.createChatProspect(this.prospectGroupId):this.prospectId=`anon_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;const A=await v.fetchWelcomeMessage(this.agentId,this.prospectId,this.widgetId||void 0);A!=null&&A.chatId&&!this.chatId&&(this.chatId=A.chatId,this.eventSource||(this.eventSource=v.listenForAdminReplies(this.chatId,this.prospectId,d=>{var g,w,m;(w=(g=this.currentView)==null?void 0:g.getChatWindow)==null||w.call(g).addMessage("assistant",d),(m=this.sessionManager)==null||m.pushMessage("assistant",d),this.playMessageSound("receive")}))),(n=this.sessionManager)==null||n.saveIds(this.prospectId,this.chatId)}catch(l){console.error("[VaniraAI] Chat init failed",l);const A="Hello! How can I help you today?";(r=(a=this.currentView)==null?void 0:a.getChatWindow)==null||r.call(a).addMessage("assistant",A),(c=this.sessionManager)==null||c.pushMessage("assistant",A)}}async initialize(e){await super.initialize(e),this.processConfig(e),this.root&&this.ui_renderer(this.root)}processConfig(e){var i,s;if(this.widgetId=e.widgetId||e.widget_id||"",this.agentId=e.agentId||e.agent_id||"",this.prospectGroupId=e.prospectGroupId||((i=e.client)==null?void 0:i.base_prospect_group_id)||"",this.widgetMode=e.widgetMode||e.mode||"voice_only",this.widgetId=e.widgetId||e.widget_id||"",this.primaryColor=e.primaryColor||e.primary_color||"#6366f1",this.secondaryColor=e.secondaryColor||e.secondary_color||"#a855f7",this.gradient=e.gradient||null,this.position=e.position||"bottom-right",this.widgetIcon=e.widgetIcon||e.icon||null,this.chatWelcomeMessage=e.chatWelcomeMessage||e.chat_welcome_message||((s=e.agent)==null?void 0:s.chat_welcome_message)||null,console.log("[VaniraAI] processConfig:",{hasPrimary:!!this.primaryColor,hasSecondary:!!this.secondaryColor,hasWelcome:!!this.chatWelcomeMessage}),typeof this.chatWelcomeMessage=="string")try{this.chatWelcomeMessage=JSON.parse(this.chatWelcomeMessage)}catch(n){console.warn("[VaniraAI] Failed to parse chatWelcomeMessage string",n)}this.chatServerUrl=e.serverUrl||e.chatServerUrl||"https://inboxapi.travelr.club",this.updateWelcomeChipsVisibility()}async create_call(){var e;if(!(this.callActive||!this.agentId)){this.sessionActive||((e=this.sessionManager)==null||e.forceClaimSession(),this.sessionActive=!0);try{this.callActive=!0,this.updateViewCallState(!0),this.updateViewStatus("connecting");const i=await v.createCall(this.agentId,null,this.prospectId||null,this.widgetMode),s=new H({agentId:this.agentId,callId:i.callId,serverUrl:i.workerUrl});s.on("connected",()=>this.updateViewStatus("connected")).on("disconnected",()=>this.end_call()).on("error",n=>{console.error("[VaniraAI Widget] Call error:",n),this.updateViewStatus("error")}).on("transcription",({text:n,isFinal:a})=>{var r,c;(c=(r=this.currentView)==null?void 0:r.setTranscription)==null||c.call(r,n,a)}).on("track",({track:n})=>{var a;this.widgetMode.includes("avatar")&&n.kind==="video"&&((a=this.currentView)!=null&&a.setVideoTrack)&&this.currentView.setVideoTrack(n)}).on("tool_call",n=>{var r,c;const a=new CustomEvent("vaniraai:tool_call",{detail:n,bubbles:!0,composed:!0});(c=(r=this.root)==null?void 0:r.host)==null||c.dispatchEvent(a),console.log("[VaniraAI Widget] Tool call dispatched:",n.name,n.arguments),n.execution_mode}),this.vaniraClient=s,await s.start()}catch(i){console.error("[VaniraAI Widget] Call failed",i),this.updateViewStatus("error")}}}end_call(){this.callActive=!1;const e=this.vaniraClient;this.vaniraClient=null,e&&e.stop(),this.updateViewCallState(!1)}updateViewCallState(e){var i;(i=this.currentView)!=null&&i.setCallActive&&this.currentView.setCallActive(e)}updateViewStatus(e){var i;(i=this.currentView)!=null&&i.setStatus&&this.currentView.setStatus(e)}ui_renderer(e){this.root=e,this.root.innerHTML="";const i=document.createElement("style");i.textContent=`@keyframes vanira-slide-up {
1174
1174
  from { opacity:0; transform:translateY(16px); }
1175
1175
  to { opacity:1; transform:translateY(0); }
1176
1176
  }`,this.root.appendChild(i);const s=document.createElement("style");s.textContent=`
@@ -1180,5 +1180,5 @@ overflow: hidden;
1180
1180
  ${U.styles}
1181
1181
  ${N.styles}
1182
1182
  ${this.gradient?`.widget-fab { background: ${this.gradient} !important; }`:""}
1183
- `,this.root.appendChild(s),this.floatingButton=new j(()=>this.togglePanel()),this.floatingButton.setIcon(this.getFabIcon()),this.floatingButton.setPosition(this.getPosStyle()),this.floatingWelcomeChips=new U(a=>this.handleFloatingChipClick(a)),this.floatingWelcomeChips.setPosition(this.getPosStyle()),this.panel=new N(()=>this.closePanel(),this.getPanelTitle()),this.root.appendChild(this.floatingWelcomeChips.getElement()),this.root.appendChild(this.floatingButton.getElement()),this.root.appendChild(this.panel.getElement()),this.setupPanelContent(),this.chatWelcomeMessage&&this.handleWelcomePayload(this.chatWelcomeMessage),this.initSessionManager()?this.widgetMode.includes("chat")&&this.initializeChatSession():this.showTabConflictBanner("conflict")}getFabIcon(){return this.widgetIcon&&D[this.widgetIcon]?D[this.widgetIcon]:this.widgetMode.includes("chat")?p.chat:p.voice_orb}getPanelTitle(){return"Assistant"}getPosStyle(){const e={"bottom-right":"bottom: 24px; right: 24px;","bottom-left":"bottom: 24px; left: 24px;","top-right":"top: 24px; right: 24px;","top-left":"top: 24px; left: 24px;"};return e[this.position]||e["bottom-right"]}setupPanelContent(){const e=(i,s)=>{var l,A;const n=(A=(l=this.currentView)==null?void 0:l.getChatWindow)==null?void 0:A.call(l);n&&n.addCallRecord(i,s);const a=`vanira_calls_${this.widgetId||this.agentId}`,r=JSON.parse(localStorage.getItem(a)||"[]");r.push({durationMs:i,startedAt:s}),r.length>50&&r.splice(0,r.length-50),localStorage.setItem(a,JSON.stringify(r))};switch(this.widgetMode){case"chat_only":this.currentView=new ae(i=>this.handleChatSend(i));break;case"chat_voice":this.currentView=new re(i=>this.handleChatSend(i),()=>this.create_call(),()=>this.end_call(),this.primaryColor,this.secondaryColor,e);break;case"avatar_only":this.currentView=new le(()=>this.create_call(),()=>this.end_call(),this.primaryColor,this.secondaryColor,e);break;case"chat_avatar":this.currentView=new Ae(i=>this.handleChatSend(i),()=>this.create_call(),()=>this.end_call(),this.primaryColor,this.secondaryColor,e);break;case"voice_only":default:this.currentView=new oe(()=>this.create_call(),()=>this.end_call(),this.primaryColor,this.secondaryColor,e);break}this.currentView&&this.panel&&this.panel.setContent(this.currentView.getElement())}async handleChatSend(e){var s,n,a,r,l;if(!e)return;this.sessionActive||((s=this.sessionManager)==null||s.forceClaimSession(),this.sessionActive=!0,this.widgetMode.includes("chat")&&await this.initializeChatSession(!1));const i=(a=(n=this.currentView)==null?void 0:n.getChatWindow)==null?void 0:a.call(n);if(i){this.chatId&&!this.eventSource&&(this.eventSource=v.listenForAdminReplies(this.chatId,this.prospectId,A=>{var c,d,g;(d=(c=this.currentView)==null?void 0:c.getChatWindow)==null||d.call(c).addMessage("assistant",A),(g=this.sessionManager)==null||g.pushMessage("assistant",A),this.playMessageSound("receive")})),i.addMessage("user",e),(r=this.sessionManager)==null||r.pushMessage("user",e),i.setTyping(!0),(l=this.sessionManager)==null||l.pushMessage("assistant","");try{let A=!1;await this.chatAdapter.sendMessage(e,this.agentId,this.prospectId,this.chatId,c=>{var d;A||(this.playMessageSound("receive"),A=!0),i.setTyping(!1),(c==null?void 0:c.type)==="button_list"&&((d=c.data)!=null&&d.buttons)&&(i.addButtons(c.data.buttons),this.welcomeChipsData=c.data.buttons,this.updateWelcomeChipsVisibility())},c=>{var d;A||(this.playMessageSound("receive"),A=!0),i.setTyping(!1),i.updateLastAssistantMessage(c),(d=this.sessionManager)==null||d.updateLastAssistantMessage(c)},c=>{var d;c&&(this.chatId=c,(d=this.sessionManager)==null||d.saveIds(this.prospectId,c))})}catch(A){i.setTyping(!1),console.error("[VaniraAI] Send message failed",A),i.addMessage("assistant","Error sending message.")}}}togglePanel(){this.isPanelOpen?this.closePanel():this.openPanel()}openPanel(){var e,i;this.isPanelOpen=!0,this.updateWelcomeChipsVisibility(),(e=this.panel)==null||e.open({bottom:this.position.includes("bottom")?"100px":void 0,top:this.position.includes("top")?"100px":void 0,right:this.position.includes("right")?"24px":void 0,left:this.position.includes("left")?"24px":void 0}),(i=this.root)!=null&&i.host&&this.root.host.classList.add("vanira-panel-open")}closePanel(){var e,i;this.isPanelOpen=!1,this.updateWelcomeChipsVisibility(),(e=this.panel)==null||e.close(),(i=this.root)!=null&&i.host&&this.root.host.classList.remove("vanira-panel-open")}updateWelcomeChipsVisibility(){if(!this.floatingWelcomeChips)return;const e=!this.isPanelOpen&&this.welcomeChipsData.length>0;console.log("[VaniraAI] updateWelcomeChipsVisibility:",{visible:e,isPanelOpen:this.isPanelOpen,chipsCount:this.welcomeChipsData.length}),e?(this.floatingWelcomeChips.setChips(this.welcomeChipsData),this.floatingWelcomeChips.getElement().style.display="flex"):this.floatingWelcomeChips.getElement().style.display="none"}handleFloatingChipClick(e){this.openPanel(),this.handleChatSend(e)}};o(B,"audioContext",null);let Y=B;class de{static getProvider(t){return new Y(t)}}class F extends HTMLElement{constructor(){super();o(this,"shadow");o(this,"provider",null);o(this,"widgetId","");o(this,"agentId","");o(this,"serverUrl","https://inboxapi.travelr.club");o(this,"position","bottom-right");o(this,"primaryColor","#000000");o(this,"secondaryColor","#000000");o(this,"gradient",null);this.shadow=this.attachShadow({mode:"open"})}static get observedAttributes(){return["widget-id","agent-id","position","primary-color","secondary-color","server-url","gradient"]}connectedCallback(){console.log("[VaniraAI Widget] Initializing..."),this.readAttributes();const e={widgetId:this.widgetId,agentId:this.agentId,serverUrl:this.serverUrl,position:this.position,primaryColor:this.primaryColor,secondaryColor:this.secondaryColor,gradient:this.gradient};this.provider=de.getProvider(e),this.provider&&this.provider.ui_renderer(this.shadow),this.widgetId&&!this.agentId&&this.initializeExpandedConfig()}readAttributes(){this.widgetId=this.getAttribute("widget-id")||"",this.agentId=this.getAttribute("agent-id")||"",this.serverUrl=this.getAttribute("server-url")||"https://inboxapi.travelr.club",this.position=this.getAttribute("position")||"bottom-right",this.primaryColor=this.getAttribute("primary-color")||"#000000",this.secondaryColor=this.getAttribute("secondary-color")||this.primaryColor,this.gradient=this.getAttribute("gradient")}async initializeExpandedConfig(){try{const e=await x.fetchWidgetConfig(this.widgetId);this.provider&&await this.provider.initialize(e)}catch(e){console.error("[VaniraAI Widget] Config failed:",e)}}}customElements.get("vanira-convai")||customElements.define("vanira-convai",F),typeof window<"u"&&(window.VaniraConvAI=F,window.VaniraAI=H);const u=document.currentScript;if(u){const h=u.getAttribute("data-widget-id")||u.getAttribute("widget-id"),t=u.getAttribute("data-agent-id")||u.getAttribute("agent-id");if(h||t){const e=u.getAttribute("data-position")||"bottom-right",i=u.getAttribute("data-primary-color")||u.getAttribute("primary-color")||"#6366f1",s=u.getAttribute("data-secondary-color")||u.getAttribute("secondary-color"),n=u.getAttribute("data-gradient")||u.getAttribute("gradient"),a=u.getAttribute("data-server-url")||u.getAttribute("server-url"),r=document.createElement("vanira-convai");h&&r.setAttribute("widget-id",h),t&&r.setAttribute("agent-id",t),r.setAttribute("position",e),r.setAttribute("primary-color",i),s&&r.setAttribute("secondary-color",s),n&&r.setAttribute("gradient",n),a&&r.setAttribute("server-url",a),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>document.body.appendChild(r)):document.body.appendChild(r),r.addEventListener("vaniraai:tool_call",l=>{const A=l.detail;console.log("[VaniraAI Widget] Tool call received by host page:",A.name,A.arguments),typeof window.__vaniraai_tool_handler=="function"&&window.__vaniraai_tool_handler(A,{sendResult:c=>{console.log("[VaniraAI] sendResult called:",c)}})})}}})();
1183
+ `,this.root.appendChild(s);const n=`vanira_pos_${this.widgetId||this.agentId}`,a=localStorage.getItem(n);let r=null;if(a)try{r=JSON.parse(a)}catch{}this.floatingButton=new j(()=>this.togglePanel(),(l,A)=>{var d,g;(d=this.floatingWelcomeChips)==null||d.updateCoordinates(l,A,A>window.innerHeight/2),this.isPanelOpen&&((g=this.panel)==null||g.updatePosition({left:`${Math.max(20,Math.min(l-170,window.innerWidth-420))}px`,top:A>window.innerHeight/2?"auto":`${A+80}px`,bottom:A>window.innerHeight/2?`${window.innerHeight-A+20}px`:"auto"}))},(l,A)=>{localStorage.setItem(n,JSON.stringify({x:l,y:A}))}),this.floatingButton.setIcon(this.getFabIcon()),r?this.floatingButton.updateCoordinates(r.x,r.y):this.floatingButton.setPosition(this.getPosStyle()),this.floatingWelcomeChips=new U(l=>this.handleFloatingChipClick(l)),r?this.floatingWelcomeChips.updateCoordinates(r.x,r.y,r.y>window.innerHeight/2):this.floatingWelcomeChips.setPosition(this.getPosStyle()),this.panel=new N(()=>this.closePanel(),this.getPanelTitle()),this.root.appendChild(this.floatingWelcomeChips.getElement()),this.root.appendChild(this.floatingButton.getElement()),this.root.appendChild(this.panel.getElement()),this.setupPanelContent(),this.chatWelcomeMessage&&this.handleWelcomePayload(this.chatWelcomeMessage),this.initSessionManager()?this.widgetMode.includes("chat")&&this.initializeChatSession():this.showTabConflictBanner("conflict")}getFabIcon(){return this.widgetIcon&&D[this.widgetIcon]?D[this.widgetIcon]:this.widgetMode.includes("chat")?p.chat:p.voice_orb}getPanelTitle(){return"Assistant"}getPosStyle(){const e={"bottom-right":"bottom: 24px; right: 24px;","bottom-left":"bottom: 24px; left: 24px;","top-right":"top: 24px; right: 24px;","top-left":"top: 24px; left: 24px;"};return e[this.position]||e["bottom-right"]}setupPanelContent(){const e=(i,s)=>{var c,l;const n=(l=(c=this.currentView)==null?void 0:c.getChatWindow)==null?void 0:l.call(c);n&&n.addCallRecord(i,s);const a=`vanira_calls_${this.widgetId||this.agentId}`,r=JSON.parse(localStorage.getItem(a)||"[]");r.push({durationMs:i,startedAt:s}),r.length>50&&r.splice(0,r.length-50),localStorage.setItem(a,JSON.stringify(r))};switch(this.widgetMode){case"chat_only":this.currentView=new ae(i=>this.handleChatSend(i));break;case"chat_voice":this.currentView=new re(i=>this.handleChatSend(i),()=>this.create_call(),()=>this.end_call(),this.primaryColor,this.secondaryColor,e);break;case"avatar_only":this.currentView=new le(()=>this.create_call(),()=>this.end_call(),this.primaryColor,this.secondaryColor,e);break;case"chat_avatar":this.currentView=new Ae(i=>this.handleChatSend(i),()=>this.create_call(),()=>this.end_call(),this.primaryColor,this.secondaryColor,e);break;case"voice_only":default:this.currentView=new oe(()=>this.create_call(),()=>this.end_call(),this.primaryColor,this.secondaryColor,e);break}this.currentView&&this.panel&&this.panel.setContent(this.currentView.getElement())}async handleChatSend(e){var s,n,a,r,c;if(!e)return;this.sessionActive||((s=this.sessionManager)==null||s.forceClaimSession(),this.sessionActive=!0,this.widgetMode.includes("chat")&&await this.initializeChatSession(!1));const i=(a=(n=this.currentView)==null?void 0:n.getChatWindow)==null?void 0:a.call(n);if(i){this.chatId&&!this.eventSource&&(this.eventSource=v.listenForAdminReplies(this.chatId,this.prospectId,l=>{var A,d,g;(d=(A=this.currentView)==null?void 0:A.getChatWindow)==null||d.call(A).addMessage("assistant",l),(g=this.sessionManager)==null||g.pushMessage("assistant",l),this.playMessageSound("receive")})),i.addMessage("user",e),(r=this.sessionManager)==null||r.pushMessage("user",e),i.setTyping(!0),(c=this.sessionManager)==null||c.pushMessage("assistant","");try{let l=!1;await this.chatAdapter.sendMessage(e,this.agentId,this.prospectId,this.chatId,A=>{var d;l||(this.playMessageSound("receive"),l=!0),i.setTyping(!1),(A==null?void 0:A.type)==="button_list"&&((d=A.data)!=null&&d.buttons)&&(i.addButtons(A.data.buttons),this.welcomeChipsData=A.data.buttons,this.updateWelcomeChipsVisibility())},A=>{var d;l||(this.playMessageSound("receive"),l=!0),i.setTyping(!1),i.updateLastAssistantMessage(A),(d=this.sessionManager)==null||d.updateLastAssistantMessage(A)},A=>{var d;A&&(this.chatId=A,(d=this.sessionManager)==null||d.saveIds(this.prospectId,A))})}catch(l){i.setTyping(!1),console.error("[VaniraAI] Send message failed",l),i.addMessage("assistant","Error sending message.")}}}togglePanel(){this.isPanelOpen?this.closePanel():this.openPanel()}openPanel(){var i,s,n,a;this.isPanelOpen=!0,this.updateWelcomeChipsVisibility();const e=(i=this.floatingButton)==null?void 0:i.getElement().getBoundingClientRect();if(e){const r=e.top>window.innerHeight/2;(s=this.panel)==null||s.open({left:`${Math.max(20,Math.min(e.left-170,window.innerWidth-420))}px`,bottom:r?`${window.innerHeight-e.top+20}px`:void 0,top:r?void 0:`${e.top+80}px`})}else(n=this.panel)==null||n.open({bottom:this.position.includes("bottom")?"100px":void 0,top:this.position.includes("top")?"100px":void 0,right:this.position.includes("right")?"24px":void 0,left:this.position.includes("left")?"24px":void 0});(a=this.root)!=null&&a.host&&this.root.host.classList.add("vanira-panel-open")}closePanel(){var e,i;this.isPanelOpen=!1,this.updateWelcomeChipsVisibility(),(e=this.panel)==null||e.close(),(i=this.root)!=null&&i.host&&this.root.host.classList.remove("vanira-panel-open")}updateWelcomeChipsVisibility(){if(!this.floatingWelcomeChips)return;const e=!this.isPanelOpen&&this.welcomeChipsData.length>0;console.log("[VaniraAI] updateWelcomeChipsVisibility:",{visible:e,isPanelOpen:this.isPanelOpen,chipsCount:this.welcomeChipsData.length}),e?(this.floatingWelcomeChips.setChips(this.welcomeChipsData),this.floatingWelcomeChips.getElement().style.display="flex"):this.floatingWelcomeChips.getElement().style.display="none"}handleFloatingChipClick(e){this.openPanel(),this.handleChatSend(e)}};o(B,"audioContext",null);let Y=B;class de{static getProvider(t){return new Y(t)}}class F extends HTMLElement{constructor(){super();o(this,"shadow");o(this,"provider",null);o(this,"widgetId","");o(this,"agentId","");o(this,"serverUrl","https://inboxapi.travelr.club");o(this,"position","bottom-right");o(this,"primaryColor","#000000");o(this,"secondaryColor","#000000");o(this,"gradient",null);this.shadow=this.attachShadow({mode:"open"})}static get observedAttributes(){return["widget-id","agent-id","position","primary-color","secondary-color","server-url","gradient"]}connectedCallback(){console.log("[VaniraAI Widget] Initializing..."),this.readAttributes();const e={widgetId:this.widgetId,agentId:this.agentId,serverUrl:this.serverUrl,position:this.position,primaryColor:this.primaryColor,secondaryColor:this.secondaryColor,gradient:this.gradient};this.provider=de.getProvider(e),this.provider&&this.provider.ui_renderer(this.shadow),this.widgetId&&!this.agentId&&this.initializeExpandedConfig()}readAttributes(){this.widgetId=this.getAttribute("widget-id")||"",this.agentId=this.getAttribute("agent-id")||"",this.serverUrl=this.getAttribute("server-url")||"https://inboxapi.travelr.club",this.position=this.getAttribute("position")||"bottom-right",this.primaryColor=this.getAttribute("primary-color")||"#000000",this.secondaryColor=this.getAttribute("secondary-color")||this.primaryColor,this.gradient=this.getAttribute("gradient")}async initializeExpandedConfig(){try{const e=await x.fetchWidgetConfig(this.widgetId);this.provider&&await this.provider.initialize(e)}catch(e){console.error("[VaniraAI Widget] Config failed:",e)}}}customElements.get("vanira-convai")||customElements.define("vanira-convai",F),typeof window<"u"&&(window.VaniraConvAI=F,window.VaniraAI=H);const u=document.currentScript;if(u){const h=u.getAttribute("data-widget-id")||u.getAttribute("widget-id"),t=u.getAttribute("data-agent-id")||u.getAttribute("agent-id");if(h||t){const e=u.getAttribute("data-position")||"bottom-right",i=u.getAttribute("data-primary-color")||u.getAttribute("primary-color")||"#6366f1",s=u.getAttribute("data-secondary-color")||u.getAttribute("secondary-color"),n=u.getAttribute("data-gradient")||u.getAttribute("gradient"),a=u.getAttribute("data-server-url")||u.getAttribute("server-url"),r=document.createElement("vanira-convai");h&&r.setAttribute("widget-id",h),t&&r.setAttribute("agent-id",t),r.setAttribute("position",e),r.setAttribute("primary-color",i),s&&r.setAttribute("secondary-color",s),n&&r.setAttribute("gradient",n),a&&r.setAttribute("server-url",a),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>document.body.appendChild(r)):document.body.appendChild(r),r.addEventListener("vaniraai:tool_call",c=>{const l=c.detail;console.log("[VaniraAI Widget] Tool call received by host page:",l.name,l.arguments),typeof window.__vaniraai_tool_handler=="function"&&window.__vaniraai_tool_handler(l,{sendResult:A=>{console.log("[VaniraAI] sendResult called:",A)}})})}}})();
1184
1184
  //# sourceMappingURL=vanira-sdk.js.map