@vanira/sdk 0.0.22 → 0.0.24

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.
@@ -1,11 +1,11 @@
1
- var we=Object.defineProperty;var ue=(f,C,b)=>C in f?we(f,C,{enumerable:!0,configurable:!0,writable:!0,value:b}):f[C]=b;var o=(f,C,b)=>ue(f,typeof C!="symbol"?C+"":C,b);(function(){"use strict";var f=typeof document<"u"?document.currentScript:null;const C="https://vaniraapi.travelr.club";class b{static async fetchWidgetConfig(t,e){var s;const i={"Content-Type":"application/json"};e&&(i["X-API-Key"]=e);try{const n=await fetch(`${C}/assistant/widget/${t}/config`,{method:"GET",headers:i});if(!n.ok)throw new Error(`Widget config fetch failed: HTTP ${n.status}`);const a=await n.json();return(s=a.agent)!=null&&s.client&&(a.client=a.agent.client),a}catch(n){throw console.error("[VaniraAI] Failed to fetch widget config:",n),n}}}const q="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=`
1
+ var we=Object.defineProperty;var ue=(f,C,x)=>C in f?we(f,C,{enumerable:!0,configurable:!0,writable:!0,value:x}):f[C]=x;var o=(f,C,x)=>ue(f,typeof C!="symbol"?C+"":C,x);(function(){"use strict";var f=typeof document<"u"?document.currentScript:null;const C="https://vaniraapi.travelr.club";class x{static async fetchWidgetConfig(t,e){var s;const i={"Content-Type":"application/json"};e&&(i["X-API-Key"]=e);try{const n=await fetch(`${C}/assistant/widget/${t}/config`,{method:"GET",headers:i});if(!n.ok)throw new Error(`Widget config fetch failed: HTTP ${n.status}`);const a=await n.json();return(s=a.agent)!=null&&s.client&&(a.client=a.agent.client),a}catch(n){throw console.error("[VaniraAI] Failed to fetch widget config:",n),n}}}const q="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=`
2
2
  mutation CreateChatProspect($prospectGroupId: uuid!, $name: String!) {
3
3
  insert_prospects_one(object: {prospect_group_id: $prospectGroupId, name: $name, source: WEBSITE_WIDGET}) {
4
4
  id
5
5
  }
6
6
  }
7
- `;try{const a=await(await fetch(q,{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){try{const s=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(!s.ok)throw new Error("Failed to fetch welcome message");const n=await s.json();let a=n.response||"Hey! how can I help you ?",r;const l=n.chat_id||n.inbox_id;return n.widget&&(r=n.widget),{role:"assistant",content:a,widget:r,chatId:l}}catch(s){return console.error("[VaniraAI] Failed to fetch welcome message:",s),{role:"assistant",content:"Hey! how can I help you ?"}}}static async sendChatMessage(t,e,i,s,n,a,r,l){var c,A,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 p=await fetch(`${k}/widget/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(w)});if(!p.ok)throw new Error("Chat request failed");const E=(c=p.body)==null?void 0:c.getReader(),x=new TextDecoder;if(!E)throw new Error("No reader");let M="",Q="",D=null;for(;;){const{done:he,value:ge}=await E.read();if(he)break;Q+=x.decode(ge,{stream:!0});const F=Q.split(`
8
- `);Q=F.pop()||"";for(const pe of F){const Y=pe.trim();if(Y&&Y.startsWith("data: ")){const K=Y.slice(6);if(K==="[DONE]"){r(D);return}try{const y=JSON.parse(K);if(y.type==="metadata"&&y.chat_id){D=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&&(M+=Z,n(M)),y.widget&&a(y.widget),y.chat_id&&!D&&(D=y.chat_id)}catch{}}}}r(D)}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=c=>{console.log("[VaniraAI] 📡 Raw SSE Event triggered:",c.data);try{const A=JSON.parse(c.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=c=>{if(console.error("[VaniraAI] SSE connection error or disconnect",c),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(l,A)})};return l(),{close:()=>{r=!0,n&&(n.close(),n=null,console.log("[VaniraAI] SSE connection manually closed."))}}}static async createCall(t,e,i,s,n){try{const a="https://vaniraapi.travelr.club",r={"Content-Type":"application/json"};n&&(r["X-API-Key"]=n);const l=await fetch(`${a}/calls/create`,{method:"POST",headers:r,body:JSON.stringify({agent_id:t,prospect_id:i||void 0,type:"web"})}),c=await l.json();if(!l.ok)throw new Error(`[VaniraAI] Call creation failed HTTP ${l.status}`);if(!c.worker_url)throw new Error("[VaniraAI] Worker URL missing from response. Call cannot proceed.");let A;try{A=new URL(c.worker_url).origin}catch{A=c.worker_url}return{callId:c.call_id||c.id||`web_${Date.now()}`,workerUrl:A}}catch(a){throw console.error("[VaniraAI] Failed to create call:",a),a}}}class _{constructor(t){o(this,"config");o(this,"root",null);this.config=t}async initialize(t){this.config=t}}class ${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);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.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{this.pc=new RTCPeerConnection({iceServers:[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"},{urls:"stun:global.relay.metered.ca:80"},{urls:["turns:global.relay.metered.ca:443?transport=tcp","turn:global.relay.metered.ca:443?transport=tcp","turn:global.relay.metered.ca:80?transport=tcp"],username:"fa97658be3343d21da3b65e6",credential:"HXHDoqeHbvZrmCuf"}],iceTransportPolicy:"all"}),console.log("using ice servers:",[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"}]);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(c=>console.warn("Audio autoplay blocked:",c)),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,c,A,d,g,w,p,E,x,M,Q;console.log("🔄 [WebRTC] State:",(l=this.pc)==null?void 0:l.connectionState,"| ICE:",(c=this.pc)==null?void 0:c.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"||((p=this.pc)==null?void 0:p.iceConnectionState)==="failed"||((E=this.pc)==null?void 0:E.connectionState)==="closed"||((x=this.pc)==null?void 0:x.iceConnectionState)==="closed"||((M=this.pc)==null?void 0:M.connectionState)==="disconnected"||((Q=this.pc)==null?void 0:Q.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:`
7
+ `;try{const a=await(await fetch(q,{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){try{const s=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(!s.ok)throw new Error("Failed to fetch welcome message");const n=await s.json();let a=n.response||"Hey! how can I help you ?",r;const l=n.chat_id||n.inbox_id;return n.widget&&(r=n.widget),{role:"assistant",content:a,widget:r,chatId:l}}catch(s){return console.error("[VaniraAI] Failed to fetch welcome message:",s),{role:"assistant",content:"Hey! how can I help you ?"}}}static async sendChatMessage(t,e,i,s,n,a,r,l){var c,A,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 p=await fetch(`${k}/widget/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(w)});if(!p.ok)throw new Error("Chat request failed");const E=(c=p.body)==null?void 0:c.getReader(),b=new TextDecoder;if(!E)throw new Error("No reader");let M="",Q="",D=null;for(;;){const{done:he,value:ge}=await E.read();if(he)break;Q+=b.decode(ge,{stream:!0});const K=Q.split(`
8
+ `);Q=K.pop()||"";for(const pe of K){const Y=pe.trim();if(Y&&Y.startsWith("data: ")){const F=Y.slice(6);if(F==="[DONE]"){r(D);return}try{const y=JSON.parse(F);if(y.type==="metadata"&&y.chat_id){D=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&&(M+=Z,n(M)),y.widget&&a(y.widget),y.chat_id&&!D&&(D=y.chat_id)}catch{}}}}r(D)}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=c=>{console.log("[VaniraAI] 📡 Raw SSE Event triggered:",c.data);try{const A=JSON.parse(c.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=c=>{if(console.error("[VaniraAI] SSE connection error or disconnect",c),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(l,A)})};return l(),{close:()=>{r=!0,n&&(n.close(),n=null,console.log("[VaniraAI] SSE connection manually closed."))}}}static async createCall(t,e,i,s,n){try{const a="https://vaniraapi.travelr.club",r={"Content-Type":"application/json"};n&&(r["X-API-Key"]=n);const l=await fetch(`${a}/calls/create`,{method:"POST",headers:r,body:JSON.stringify({agent_id:t,prospect_id:i||void 0,type:"web"})}),c=await l.json();if(!l.ok)throw new Error(`[VaniraAI] Call creation failed HTTP ${l.status}`);if(!c.worker_url)throw new Error("[VaniraAI] Worker URL missing from response. Call cannot proceed.");let A;try{A=new URL(c.worker_url).origin}catch{A=c.worker_url}return{callId:c.call_id||c.id||`web_${Date.now()}`,workerUrl:A}}catch(a){throw console.error("[VaniraAI] Failed to create call:",a),a}}}class _{constructor(t){o(this,"config");o(this,"root",null);this.config=t}async initialize(t){this.config=t}}class ${constructor(t){o(this,"serverUrl");o(this,"agentId");o(this,"callId");o(this,"apiKey");o(this,"backendUrl");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);if(!t.agentId)throw new Error("agentId is required");if(!t.serverUrl&&!t.apiKey)throw new Error("Provide either serverUrl or apiKey (to use createCall())");this.agentId=t.agentId,this.serverUrl=t.serverUrl?t.serverUrl.replace(/\/$/,""):"",this.callId=t.callId||this.generateCallId(),this.apiKey=t.apiKey,this.backendUrl=(t.backendUrl||"https://vaniraapi.travelr.club").replace(/\/$/,""),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 createCall(){var s;if(!this.apiKey)throw new Error("[VaniraAI] apiKey is required to use createCall()");const t={"Content-Type":"application/json","X-API-Key":this.apiKey},e=await fetch(`${this.backendUrl}/calls/create`,{method:"POST",headers:t,body:JSON.stringify({agent_id:this.agentId,type:"web"})});if(!e.ok){const n=await e.json().catch(()=>({}));throw new Error(`[VaniraAI] createCall failed (${e.status}): ${((s=n==null?void 0:n.detail)==null?void 0:s.message)||(n==null?void 0:n.message)||e.statusText}`)}const i=await e.json();if(!i.call_id||!i.worker_url)throw new Error("[VaniraAI] createCall response missing call_id or worker_url");this.callId=i.call_id,this.serverUrl=i.worker_url.replace(/\/$/,""),await this.connect()}async connect(){if(this.apiKey&&!this.serverUrl){await this.createCall();return}if(!this.serverUrl)throw new Error("[VaniraAI] serverUrl is missing. Provide apiKey or serverUrl.");console.log("đŸ”ĩ [WebRTC] Starting connection...");try{this.pc=new RTCPeerConnection({iceServers:[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"},{urls:"stun:global.relay.metered.ca:80"},{urls:["turns:global.relay.metered.ca:443?transport=tcp","turn:global.relay.metered.ca:443?transport=tcp","turn:global.relay.metered.ca:80?transport=tcp"],username:"fa97658be3343d21da3b65e6",credential:"HXHDoqeHbvZrmCuf"}],iceTransportPolicy:"all"}),console.log("using ice servers:",[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"}]);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(c=>console.warn("Audio autoplay blocked:",c)),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,c,A,d,g,w,p,E,b,M,Q;console.log("🔄 [WebRTC] State:",(l=this.pc)==null?void 0:l.connectionState,"| ICE:",(c=this.pc)==null?void 0:c.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"||((p=this.pc)==null?void 0:p.iceConnectionState)==="failed"||((E=this.pc)==null?void 0:E.connectionState)==="closed"||((b=this.pc)==null?void 0:b.iceConnectionState)==="closed"||((M=this.pc)==null?void 0:M.connectionState)==="disconnected"||((Q=this.pc)==null?void 0:Q.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:`
9
9
  query GetIceServers {
10
10
  ice_servers(where: {enabled: {_eq: true}}) {
11
11
  urls
@@ -976,7 +976,7 @@ overflow: hidden;
976
976
  cursor: pointer; pointer-events: auto;
977
977
  transition: background-color 0.2s;
978
978
  box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
979
- `,this.hangupBtn.onmouseover=()=>this.hangupBtn.style.backgroundColor="#dc2626",this.hangupBtn.onmouseout=()=>this.hangupBtn.style.backgroundColor="#ef4444",this.hangupBtn.onclick=()=>{const g=this.callStartedAt?Date.now()-this.callStartedAt:0,w=this.callStartedAt??Date.now();this.onCallEnded&&g>0&&this.onCallEnded(g,w),this.onHangup()},d.appendChild(this.hangupBtn),this.element.appendChild(d)}getElement(){return this.element}setMode(t){this.isAvatarMode=t==="avatar"}setVideoTrack(t){if(this.isAvatarMode=!0,t.kind==="video"&&this.videoElement){const e=new MediaStream([t]);this.videoElement.srcObject=e,this.videoContainer.style.display="block",this.orbWrapper.style.display="none",this.connectingLabel.style.display="none",this.timerEl.style.display="none",this.videoElement.onplaying=()=>{this.prepareBadge.style.display="none",this.statusBadge.style.display="flex"},this.videoElement.play().catch(i=>console.warn("Video play error",i))}}setStatus(t){if(t==="connecting")this.centerIcon.style.background="#4b5563",this.centerIcon.innerHTML='<div style="width:18px;height:18px;border:2px solid #ffffff;border-top-color:transparent;border-radius:50%;animation:spin 1s linear infinite;"></div>',this.isAvatarMode?(this.videoContainer.style.display="block",this.orbWrapper.style.display="none",this.prepareBadge.textContent="CONNECTING...",this.prepareBadge.style.display="block",this.statusBadge.style.display="none",this.connectingLabel.style.display="none"):(this.orbWrapper.style.display="flex",this.videoContainer.style.display="none",this.connectingRing.style.display="block",this.errorRing.style.display="none",this.waveLayers.forEach(e=>e.style.display="none"),this.connectingLabel.style.display="block",this.connectedBadge.style.display="none",this.timerEl.style.display="none",this.errorLabel.style.display="none",this.retryBtn.style.display="none"),this.stopTimer();else if(t==="connected"){this.centerIcon.style.background="#1f2937",this.centerIcon.innerHTML=u.phone;const e=this.centerIcon.querySelector("svg");e&&(e.style.cssText="width:20px;height:20px;"),this.isAvatarMode?this.videoElement&&!this.videoElement.paused&&this.videoElement.readyState>2?(this.prepareBadge.style.display="none",this.statusBadge.style.display="flex"):(this.prepareBadge.textContent="AGENT IS ON THE WAY...",this.prepareBadge.style.display="block",setTimeout(()=>{this.prepareBadge.style.display!=="none"&&(this.prepareBadge.style.display="none",this.statusBadge.style.display="flex")},5e3)):(this.connectingRing.style.display="none",this.errorRing.style.display="none",this.waveLayers.forEach(i=>i.style.display="flex"),this.connectingLabel.style.display="none",this.connectedBadge.style.display="flex",this.timerEl.style.display="block",this.errorLabel.style.display="none",this.retryBtn.style.display="none",this.startTimer())}else t==="error"&&(this.centerIcon.style.background="#dc2626",this.centerIcon.innerHTML=u.phone,this.connectingRing.style.display="none",this.errorRing.style.display="block",this.waveLayers.forEach(e=>e.style.display="none"),this.connectingLabel.style.display="none",this.connectedBadge.style.display="none",this.timerEl.style.display="none",this.errorLabel.style.display="block",this.retryBtn.style.display="block",this.stopTimer())}setTranscription(t,e){this.transcriptionEl.textContent=`"${t}"`,this.transcriptionEl.style.color=e?"#1f2937":"#9ca3af",this.transcriptionEl.style.fontStyle=e?"normal":"italic"}show(){this.callStartedAt=Date.now(),this.element.style.display="flex",this.setStatus("connecting")}hide(){this.element.style.display="none",this.reset()}reset(){this.videoElement&&(this.videoElement.srcObject=null),this.isAvatarMode=!1,this.callStartedAt=null,this.stopTimer(),this.transcriptionEl.textContent="",this.videoContainer.style.display="none",this.orbWrapper.style.display="flex",this.connectingRing.style.display="none",this.errorRing.style.display="none",this.waveLayers.forEach(e=>e.style.display="none"),this.connectingLabel.style.display="none",this.connectedBadge.style.display="none",this.timerEl.style.display="none",this.errorLabel.style.display="none",this.retryBtn.style.display="none",this.prepareBadge.style.display="none",this.statusBadge.style.display="none",this.centerIcon.style.background="#374151",this.centerIcon.innerHTML=u.phone;const t=this.centerIcon.querySelector("svg");t&&(t.style.cssText="width:20px;height:20px;")}startTimer(){this.timerInterval&&clearInterval(this.timerInterval),this.startTime=Date.now(),this.timerEl.textContent="00:00",this.timerInterval=setInterval(()=>{if(!this.startTime)return;const t=Math.floor((Date.now()-this.startTime)/1e3),e=Math.floor(t/60).toString().padStart(2,"0"),i=(t%60).toString().padStart(2,"0");this.timerEl.textContent=`${e}:${i}`},1e3)}stopTimer(){this.timerInterval&&(clearInterval(this.timerInterval),this.timerInterval=null),this.timerEl.textContent=""}setFullScreen(t){t?(this.videoContainer.style.position="absolute",this.videoContainer.style.top="0",this.videoContainer.style.left="0",this.videoContainer.style.width="100%",this.videoContainer.style.height="100%",this.videoContainer.style.maxWidth="none",this.videoContainer.style.borderRadius="0",this.videoContainer.style.margin="0",this.videoContainer.style.zIndex="0"):(this.videoContainer.style.position="relative",this.videoContainer.style.width="100%",this.videoContainer.style.maxWidth="260px",this.videoContainer.style.height="auto",this.videoContainer.style.aspectRatio="1/1",this.videoContainer.style.borderRadius="16px",this.videoContainer.style.marginBottom="16px")}}class W{constructor(t){o(this,"element");o(this,"messageContainer");o(this,"inputArea");o(this,"input");o(this,"sendBtn");o(this,"typingIndicator",null);this.onSend=t,this.element=document.createElement("div"),this.element.style.display="flex",this.element.style.flexDirection="column",this.element.style.flex="1",this.element.style.overflow="hidden",this.element.style.minHeight="0",this.messageContainer=document.createElement("div"),this.messageContainer.className="chat-messages",this.inputArea=document.createElement("div"),this.inputArea.className="chat-input-area",this.input=document.createElement("input"),this.input.className="chat-input",this.input.placeholder="Type a message...",this.input.addEventListener("keypress",i=>{i.key==="Enter"&&this.handleSend()}),this.sendBtn=document.createElement("button"),this.sendBtn.className="chat-send-btn",this.sendBtn.innerHTML=u.send,this.sendBtn.onclick=()=>this.handleSend(),this.inputArea.appendChild(this.input),this.inputArea.appendChild(this.sendBtn);const e=document.createElement("div");e.className="branding-footer",e.innerHTML="Technology Powered by <b>Vanira AI</b>",this.element.appendChild(this.messageContainer),this.element.appendChild(this.inputArea),this.element.appendChild(e)}getElement(){return this.element}formatTime(t=new Date){return t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}addMessage(t,e,i){const s=document.createElement("div");s.style.cssText=`
979
+ `,this.hangupBtn.onmouseover=()=>this.hangupBtn.style.backgroundColor="#dc2626",this.hangupBtn.onmouseout=()=>this.hangupBtn.style.backgroundColor="#ef4444",this.hangupBtn.onclick=()=>{const g=this.callStartedAt?Date.now()-this.callStartedAt:0,w=this.callStartedAt??Date.now();this.onCallEnded&&g>0&&this.onCallEnded(g,w),this.onHangup()},d.appendChild(this.hangupBtn),this.element.appendChild(d)}getElement(){return this.element}setMode(t){this.isAvatarMode=t==="avatar"}setVideoTrack(t){if(this.isAvatarMode=!0,t.kind==="video"&&this.videoElement){const e=new MediaStream([t]);this.videoElement.srcObject=e,this.videoContainer.style.display="block",this.orbWrapper.style.display="none",this.connectingLabel.style.display="none",this.timerEl.style.display="none",this.videoElement.onplaying=()=>{this.prepareBadge.style.display="none",this.statusBadge.style.display="flex"},this.videoElement.play().catch(i=>console.warn("Video play error",i))}}setStatus(t){if(t==="connecting")this.centerIcon.style.background="#4b5563",this.centerIcon.innerHTML='<div style="width:18px;height:18px;border:2px solid #ffffff;border-top-color:transparent;border-radius:50%;animation:spin 1s linear infinite;"></div>',this.isAvatarMode?(this.videoContainer.style.display="block",this.orbWrapper.style.display="none",this.prepareBadge.textContent="CONNECTING...",this.prepareBadge.style.display="block",this.statusBadge.style.display="none",this.connectingLabel.style.display="none"):(this.orbWrapper.style.display="flex",this.videoContainer.style.display="none",this.connectingRing.style.display="block",this.errorRing.style.display="none",this.waveLayers.forEach(e=>e.style.display="none"),this.connectingLabel.style.display="block",this.connectedBadge.style.display="none",this.timerEl.style.display="none",this.errorLabel.style.display="none",this.retryBtn.style.display="none"),this.stopTimer();else if(t==="connected"){this.centerIcon.style.background="#1f2937",this.centerIcon.innerHTML=u.phone;const e=this.centerIcon.querySelector("svg");e&&(e.style.cssText="width:20px;height:20px;"),this.isAvatarMode?this.videoElement&&!this.videoElement.paused&&this.videoElement.readyState>2?(this.prepareBadge.style.display="none",this.statusBadge.style.display="flex"):(this.prepareBadge.textContent="AGENT IS ON THE WAY...",this.prepareBadge.style.display="block",setTimeout(()=>{this.prepareBadge.style.display!=="none"&&(this.prepareBadge.style.display="none",this.statusBadge.style.display="flex")},5e3)):(this.connectingRing.style.display="none",this.errorRing.style.display="none",this.waveLayers.forEach(i=>i.style.display="flex"),this.connectingLabel.style.display="none",this.connectedBadge.style.display="flex",this.timerEl.style.display="block",this.errorLabel.style.display="none",this.retryBtn.style.display="none",this.startTimer())}else t==="error"&&(this.centerIcon.style.background="#dc2626",this.centerIcon.innerHTML=u.phone,this.connectingRing.style.display="none",this.errorRing.style.display="block",this.waveLayers.forEach(e=>e.style.display="none"),this.connectingLabel.style.display="none",this.connectedBadge.style.display="none",this.timerEl.style.display="none",this.errorLabel.style.display="block",this.retryBtn.style.display="block",this.stopTimer())}setTranscription(t,e){this.transcriptionEl.textContent=`"${t}"`,this.transcriptionEl.style.color=e?"#1f2937":"#9ca3af",this.transcriptionEl.style.fontStyle=e?"normal":"italic"}show(){this.callStartedAt=Date.now(),this.element.style.display="flex",this.setStatus("connecting")}hide(){this.element.style.display="none",this.reset()}reset(){this.videoElement&&(this.videoElement.srcObject=null),this.isAvatarMode=!1,this.callStartedAt=null,this.stopTimer(),this.transcriptionEl.textContent="",this.videoContainer.style.display="none",this.orbWrapper.style.display="flex",this.connectingRing.style.display="none",this.errorRing.style.display="none",this.waveLayers.forEach(e=>e.style.display="none"),this.connectingLabel.style.display="none",this.connectedBadge.style.display="none",this.timerEl.style.display="none",this.errorLabel.style.display="none",this.retryBtn.style.display="none",this.prepareBadge.style.display="none",this.statusBadge.style.display="none",this.centerIcon.style.background="#374151",this.centerIcon.innerHTML=u.phone;const t=this.centerIcon.querySelector("svg");t&&(t.style.cssText="width:20px;height:20px;")}startTimer(){this.timerInterval&&clearInterval(this.timerInterval),this.startTime=Date.now(),this.timerEl.textContent="00:00",this.timerInterval=setInterval(()=>{if(!this.startTime)return;const t=Math.floor((Date.now()-this.startTime)/1e3),e=Math.floor(t/60).toString().padStart(2,"0"),i=(t%60).toString().padStart(2,"0");this.timerEl.textContent=`${e}:${i}`},1e3)}stopTimer(){this.timerInterval&&(clearInterval(this.timerInterval),this.timerInterval=null),this.timerEl.textContent=""}setFullScreen(t){t?(this.videoContainer.style.position="absolute",this.videoContainer.style.top="0",this.videoContainer.style.left="0",this.videoContainer.style.width="100%",this.videoContainer.style.height="100%",this.videoContainer.style.maxWidth="none",this.videoContainer.style.borderRadius="0",this.videoContainer.style.margin="0",this.videoContainer.style.zIndex="0"):(this.videoContainer.style.position="relative",this.videoContainer.style.width="100%",this.videoContainer.style.maxWidth="260px",this.videoContainer.style.height="auto",this.videoContainer.style.aspectRatio="1/1",this.videoContainer.style.borderRadius="16px",this.videoContainer.style.marginBottom="16px")}}class U{constructor(t){o(this,"element");o(this,"messageContainer");o(this,"inputArea");o(this,"input");o(this,"sendBtn");o(this,"typingIndicator",null);this.onSend=t,this.element=document.createElement("div"),this.element.style.display="flex",this.element.style.flexDirection="column",this.element.style.flex="1",this.element.style.overflow="hidden",this.element.style.minHeight="0",this.messageContainer=document.createElement("div"),this.messageContainer.className="chat-messages",this.inputArea=document.createElement("div"),this.inputArea.className="chat-input-area",this.input=document.createElement("input"),this.input.className="chat-input",this.input.placeholder="Type a message...",this.input.addEventListener("keypress",i=>{i.key==="Enter"&&this.handleSend()}),this.sendBtn=document.createElement("button"),this.sendBtn.className="chat-send-btn",this.sendBtn.innerHTML=u.send,this.sendBtn.onclick=()=>this.handleSend(),this.inputArea.appendChild(this.input),this.inputArea.appendChild(this.sendBtn);const e=document.createElement("div");e.className="branding-footer",e.innerHTML="Technology Powered by <b>Vanira AI</b>",this.element.appendChild(this.messageContainer),this.element.appendChild(this.inputArea),this.element.appendChild(e)}getElement(){return this.element}formatTime(t=new Date){return t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}addMessage(t,e,i){const s=document.createElement("div");s.style.cssText=`
980
980
  display: flex;
981
981
  flex-direction: column;
982
982
  align-items: ${t==="user"?"flex-end":"flex-start"};
@@ -1017,7 +1017,7 @@ overflow: hidden;
1017
1017
  </div>
1018
1018
  <div class="voice-status-text">Tap to speak</div>
1019
1019
  <div class="voice-status-subtext">Start a conversation</div>
1020
- `;const e=this.element.querySelector(".central-orb-container");e&&(e.onclick=this.onClick)}getElement(){return this.element}}class O{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`
1020
+ `;const e=this.element.querySelector(".central-orb-container");e&&(e.onclick=this.onClick)}getElement(){return this.element}}class W{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`
1021
1021
  .welcome-chips-container {
1022
1022
  position: fixed;
1023
1023
  z-index: 9998;
@@ -1073,7 +1073,7 @@ overflow: hidden;
1073
1073
  transform: translateY(0);
1074
1074
  }
1075
1075
  }
1076
- `}}class U{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 j(()=>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 U{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 V{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 j(()=>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">${u.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 V{constructor(t,e,i,s="#6366f1",n="#a855f7",a){super(t,e,i,s,n,a),this.setupChat()}}class le extends U{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=`${u.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 V{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=`
1076
+ `}}class O{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 j(()=>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 O{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 U(e=>this.onSendMessage(e)),this.element.appendChild(this.chatWindow.getElement())}getElement(){return this.element}getChatWindow(){return this.chatWindow}}class V{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 U(e=>this.onSendMessage(e));const t=this.chatWindow.getElement();t.style.flex="1",this.element.appendChild(t),this.injectVoiceTrigger(),this.overlay=new j(()=>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">${u.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 V{constructor(t,e,i,s="#6366f1",n="#a855f7",a){super(t,e,i,s,n,a),this.setupChat()}}class le extends O{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=`${u.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 V{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=`
1077
1077
  <video
1078
1078
  src="https://www.simli.com/jenna.mp4"
1079
1079
  autoplay loop muted pip="false" playsinline
@@ -1082,15 +1082,15 @@ overflow: hidden;
1082
1082
  <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);">
1083
1083
  ${u.audioLines.replace('width="24"','width="12"').replace('height="24"','height="12"')}
1084
1084
  </div>
1085
- `;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,c=>{a&&a(c)},n,c=>{r&&c&&r(c)},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 I=class I 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,"pkKey","");o(this,"primaryColor","#6366f1");o(this,"secondaryColor","#4f46e5");o(this,"gradient",null);o(this,"positionType","fixed");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 S(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,c,A;const e=(l=this.sessionManager)==null?void 0:l.getSession();if(!e)return;const i=(A=(c=this.currentView)==null?void 0:c.getChatWindow)==null?void 0:A.call(c);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(!I.audioContext){const r=window.AudioContext||window.webkitAudioContext;if(!r)return;I.audioContext=new r}const i=I.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,c,A,d,g,w;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=(c=(l=this.currentView)==null?void 0:l.getChatWindow)==null?void 0:c.call(l);let n=e.text||e.response||e.content||e.message||"";if(!n&&!this.welcomeChipsData.length&&(n="Hey! how can I help you ?"),!n&&typeof e=="string"&&e.trim().startsWith("{"))try{const p=JSON.parse(e);n=p.text||p.response||p.content||p.message||"",((A=p.widget)==null?void 0:A.type)==="button_list"&&((d=p.widget.data)!=null&&d.buttons)&&(this.welcomeChipsData=p.widget.data.buttons)}catch{}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 p=(g=this.sessionManager)==null?void 0:g.getSession();(p==null?void 0:p.messages.some(x=>x.content===n&&x.role===i))||(n&&(s.addMessage(i,n),(w=this.sessionManager)==null||w.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 c=(i=this.sessionManager)==null?void 0:i.getSession();if(!e&&(c!=null&&c.prospectId)){this.prospectId=c.prospectId,this.chatId=c.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,p;(w=(g=this.currentView)==null?void 0:g.getChatWindow)==null||w.call(g).addMessage("assistant",d),(p=this.sessionManager)==null||p.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&&(this.handleWelcomePayload(A),A.chatId&&!this.chatId&&(this.chatId=A.chatId,this.eventSource||(this.eventSource=v.listenForAdminReplies(this.chatId,this.prospectId,d=>{var g,w,p;(w=(g=this.currentView)==null?void 0:g.getChatWindow)==null||w.call(g).addMessage("assistant",d),(p=this.sessionManager)==null||p.pushMessage("assistant",d),this.playMessageSound("receive")})))),(n=this.sessionManager)==null||n.saveIds(this.prospectId,this.chatId)}catch(c){console.error("[VaniraAI] Chat init failed",c);const A="Hey! how can I help you ?";(r=(a=this.currentView)==null?void 0:a.getChatWindow)==null||r.call(a).addMessage("assistant",A),(l=this.sessionManager)==null||l.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.pkKey=e.pkKey||e.pk_key||"",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.positionType=e.positionType||"fixed",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,this.pkKey||void 0),s=new G({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="",this.root.host&&(this.positionType==="fixed"?this.root.host.classList.add("vanira-portal"):this.root.host.classList.remove("vanira-portal"));const i=document.createElement("style");i.textContent=`@keyframes vanira-slide-up {
1085
+ `;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,c=>{a&&a(c)},n,c=>{r&&c&&r(c)},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 I=class I 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,"pkKey","");o(this,"chatInitialized",!1);o(this,"primaryColor","#6366f1");o(this,"secondaryColor","#4f46e5");o(this,"gradient",null);o(this,"positionType","fixed");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 S(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,c,A;const e=(l=this.sessionManager)==null?void 0:l.getSession();if(!e)return;const i=(A=(c=this.currentView)==null?void 0:c.getChatWindow)==null?void 0:A.call(c);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(!I.audioContext){const r=window.AudioContext||window.webkitAudioContext;if(!r)return;I.audioContext=new r}const i=I.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,c,A,d,g,w;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=(c=(l=this.currentView)==null?void 0:l.getChatWindow)==null?void 0:c.call(l);let n=e.text||e.response||e.content||e.message||"";if(!n&&!this.welcomeChipsData.length&&(n="Hey! how can I help you ?"),!n&&typeof e=="string"&&e.trim().startsWith("{"))try{const p=JSON.parse(e);n=p.text||p.response||p.content||p.message||"",((A=p.widget)==null?void 0:A.type)==="button_list"&&((d=p.widget.data)!=null&&d.buttons)&&(this.welcomeChipsData=p.widget.data.buttons)}catch{}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 p=(g=this.sessionManager)==null?void 0:g.getSession();(p==null?void 0:p.messages.some(b=>b.content===n&&b.role===i))||(n&&(s.addMessage(i,n),(w=this.sessionManager)==null||w.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&&!this.chatInitialized){this.chatInitialized=!0;try{v.setChatUrl(this.chatServerUrl);const c=(i=this.sessionManager)==null?void 0:i.getSession();if(!e&&(c!=null&&c.prospectId)){this.prospectId=c.prospectId,this.chatId=c.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,p;(w=(g=this.currentView)==null?void 0:g.getChatWindow)==null||w.call(g).addMessage("assistant",d),(p=this.sessionManager)==null||p.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&&(this.handleWelcomePayload(A),A.chatId&&!this.chatId&&(this.chatId=A.chatId,this.eventSource||(this.eventSource=v.listenForAdminReplies(this.chatId,this.prospectId,d=>{var g,w,p;(w=(g=this.currentView)==null?void 0:g.getChatWindow)==null||w.call(g).addMessage("assistant",d),(p=this.sessionManager)==null||p.pushMessage("assistant",d),this.playMessageSound("receive")})))),(n=this.sessionManager)==null||n.saveIds(this.prospectId,this.chatId)}catch(c){console.error("[VaniraAI] Chat init failed",c);const A="Hey! how can I help you ?";(r=(a=this.currentView)==null?void 0:a.getChatWindow)==null||r.call(a).addMessage("assistant",A),(l=this.sessionManager)==null||l.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.pkKey=e.pkKey||e.pk_key||"",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.positionType=e.positionType||"fixed",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,this.pkKey||void 0),s=new G({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="",this.root.host&&(this.positionType==="fixed"?this.root.host.classList.add("vanira-portal"):this.root.host.classList.remove("vanira-portal"));const i=document.createElement("style");i.textContent=`@keyframes vanira-slide-up {
1086
1086
  from { opacity:0; transform:translateY(16px); }
1087
1087
  to { opacity:1; transform:translateY(0); }
1088
1088
  }`,this.root.appendChild(i);const s=document.createElement("style");s.textContent=`
1089
1089
  ${ie}
1090
1090
  :host { ${te(this.primaryColor,this.secondaryColor)} }
1091
1091
  ${R.styles}
1092
- ${O.styles}
1092
+ ${W.styles}
1093
1093
  ${N.styles}
1094
1094
  ${this.gradient?`.widget-fab { background: ${this.gradient} !important; }`:""}
1095
- `,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 R(()=>this.togglePanel(),(c,A)=>{var d,g;(d=this.floatingWelcomeChips)==null||d.updateCoordinates(c,A,A>window.innerHeight/2),this.isPanelOpen&&((g=this.panel)==null||g.updatePosition({left:`${Math.max(20,Math.min(c-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"}))},(c,A)=>{localStorage.setItem(n,JSON.stringify({x:c,y:A}))}),this.floatingButton.setIcon(this.getFabIcon()),r?this.floatingButton.updateCoordinates(r.x,r.y):this.floatingButton.setPosition(this.getPosStyle()),this.floatingWelcomeChips=new O(c=>this.handleFloatingChipClick(c)),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.widgetMode.includes("chat")&&this.handleWelcomePayload(this.chatWelcomeMessage),this.initSessionManager()?this.widgetMode.includes("chat")&&this.initializeChatSession():this.showTabConflictBanner("conflict")}getFabIcon(){return this.widgetIcon&&T[this.widgetIcon]?T[this.widgetIcon]:this.widgetMode.includes("chat")?u.chat:u.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,c;const n=(c=(l=this.currentView)==null?void 0:l.getChatWindow)==null?void 0:c.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,c=>{var A,d,g;(d=(A=this.currentView)==null?void 0:A.getChatWindow)==null||d.call(A).addMessage("assistant",c),(g=this.sessionManager)==null||g.pushMessage("assistant",c),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 c=!1;await this.chatAdapter.sendMessage(e,this.agentId,this.prospectId,this.chatId,A=>{var d;c||(this.playMessageSound("receive"),c=!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;c||(this.playMessageSound("receive"),c=!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(c){i.setTyping(!1),console.error("[VaniraAI] Send message failed",c),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(I,"audioContext",null);let P=I;class de{static getProvider(t){return new P(t)}}class X extends HTMLElement{constructor(){super();o(this,"shadow");o(this,"provider",null);o(this,"widgetId","");o(this,"agentId","");o(this,"pkKey","");o(this,"serverUrl","https://inboxapi.travelr.club");o(this,"position","bottom-right");o(this,"primaryColor","#000000");o(this,"secondaryColor","#000000");o(this,"gradient",null);o(this,"positionType","fixed");this.shadow=this.attachShadow({mode:"open"})}static get observedAttributes(){return["widget-id","agent-id","position","primary-color","secondary-color","server-url","gradient","position-type","pk-key"]}connectedCallback(){console.log("[VaniraAI Widget] Initializing..."),this.readAttributes();const e={widgetId:this.widgetId,agentId:this.agentId,pkKey:this.pkKey,serverUrl:this.serverUrl,position:this.position,primaryColor:this.primaryColor,secondaryColor:this.secondaryColor,gradient:this.gradient,positionType:this.positionType};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.pkKey=this.getAttribute("pk-key")||"",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"),this.positionType=this.getAttribute("position-type")||"fixed"}async initializeExpandedConfig(){try{const e=await b.fetchWidgetConfig(this.widgetId,this.pkKey||void 0);this.provider&&await this.provider.initialize(e)}catch(e){console.error("[VaniraAI Widget] Config failed:",e)}}}customElements.get("vanira-convai")||customElements.define("vanira-convai",X),typeof window<"u"&&(window.VaniraConvAI=X,window.VaniraAI=G);const m=document.currentScript;if(m){const h=m.getAttribute("data-widget-id")||m.getAttribute("widget-id"),t=m.getAttribute("data-agent-id")||m.getAttribute("agent-id");if(h||t){const e=m.getAttribute("data-position")||"bottom-right",i=m.getAttribute("data-primary-color")||m.getAttribute("primary-color")||"#6366f1",s=m.getAttribute("data-secondary-color")||m.getAttribute("secondary-color"),n=m.getAttribute("data-gradient")||m.getAttribute("gradient"),a=m.getAttribute("data-server-url")||m.getAttribute("server-url"),r=m.getAttribute("data-pk-key")||m.getAttribute("pk-key"),l=document.createElement("vanira-convai");h&&l.setAttribute("widget-id",h),t&&l.setAttribute("agent-id",t),r&&l.setAttribute("pk-key",r),l.setAttribute("position",e),l.setAttribute("primary-color",i),s&&l.setAttribute("secondary-color",s),n&&l.setAttribute("gradient",n),a&&l.setAttribute("server-url",a),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>document.body.appendChild(l)):document.body.appendChild(l),l.addEventListener("vaniraai:tool_call",c=>{const A=c.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:d=>{console.log("[VaniraAI] sendResult called:",d)}})})}}})();
1095
+ `,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 R(()=>this.togglePanel(),(c,A)=>{var d,g;(d=this.floatingWelcomeChips)==null||d.updateCoordinates(c,A,A>window.innerHeight/2),this.isPanelOpen&&((g=this.panel)==null||g.updatePosition({left:`${Math.max(20,Math.min(c-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"}))},(c,A)=>{localStorage.setItem(n,JSON.stringify({x:c,y:A}))}),this.floatingButton.setIcon(this.getFabIcon()),r?this.floatingButton.updateCoordinates(r.x,r.y):this.floatingButton.setPosition(this.getPosStyle()),this.floatingWelcomeChips=new W(c=>this.handleFloatingChipClick(c)),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.widgetMode.includes("chat")&&this.handleWelcomePayload(this.chatWelcomeMessage),this.initSessionManager()?this.widgetMode.includes("chat")&&this.initializeChatSession():this.showTabConflictBanner("conflict")}getFabIcon(){return this.widgetIcon&&T[this.widgetIcon]?T[this.widgetIcon]:this.widgetMode.includes("chat")?u.chat:u.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,c;const n=(c=(l=this.currentView)==null?void 0:l.getChatWindow)==null?void 0:c.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,c=>{var A,d,g;(d=(A=this.currentView)==null?void 0:A.getChatWindow)==null||d.call(A).addMessage("assistant",c),(g=this.sessionManager)==null||g.pushMessage("assistant",c),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 c=!1;await this.chatAdapter.sendMessage(e,this.agentId,this.prospectId,this.chatId,A=>{var d;c||(this.playMessageSound("receive"),c=!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;c||(this.playMessageSound("receive"),c=!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(c){i.setTyping(!1),console.error("[VaniraAI] Send message failed",c),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(I,"audioContext",null);let P=I;class de{static getProvider(t){return new P(t)}}class X extends HTMLElement{constructor(){super();o(this,"shadow");o(this,"provider",null);o(this,"widgetId","");o(this,"agentId","");o(this,"pkKey","");o(this,"serverUrl","https://inboxapi.travelr.club");o(this,"position","bottom-right");o(this,"primaryColor","#000000");o(this,"secondaryColor","#000000");o(this,"gradient",null);o(this,"positionType","fixed");this.shadow=this.attachShadow({mode:"open"})}static get observedAttributes(){return["widget-id","agent-id","position","primary-color","secondary-color","server-url","gradient","position-type","pk-key"]}connectedCallback(){console.log("[VaniraAI Widget] Initializing..."),this.readAttributes();const e={widgetId:this.widgetId,agentId:this.agentId,pkKey:this.pkKey,serverUrl:this.serverUrl,position:this.position,primaryColor:this.primaryColor,secondaryColor:this.secondaryColor,gradient:this.gradient,positionType:this.positionType};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.pkKey=this.getAttribute("pk-key")||"",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"),this.positionType=this.getAttribute("position-type")||"fixed"}async initializeExpandedConfig(){try{const e=await x.fetchWidgetConfig(this.widgetId,this.pkKey||void 0);this.provider&&await this.provider.initialize(e)}catch(e){console.error("[VaniraAI Widget] Config failed:",e)}}}customElements.get("vanira-convai")||customElements.define("vanira-convai",X),typeof window<"u"&&(window.VaniraConvAI=X,window.VaniraAI=G);const m=document.currentScript;if(m){const h=m.getAttribute("data-widget-id")||m.getAttribute("widget-id"),t=m.getAttribute("data-agent-id")||m.getAttribute("agent-id");if(h||t){const e=m.getAttribute("data-position")||"bottom-right",i=m.getAttribute("data-primary-color")||m.getAttribute("primary-color")||"#6366f1",s=m.getAttribute("data-secondary-color")||m.getAttribute("secondary-color"),n=m.getAttribute("data-gradient")||m.getAttribute("gradient"),a=m.getAttribute("data-server-url")||m.getAttribute("server-url"),r=m.getAttribute("data-pk-key")||m.getAttribute("pk-key"),l=document.createElement("vanira-convai");h&&l.setAttribute("widget-id",h),t&&l.setAttribute("agent-id",t),r&&l.setAttribute("pk-key",r),l.setAttribute("position",e),l.setAttribute("primary-color",i),s&&l.setAttribute("secondary-color",s),n&&l.setAttribute("gradient",n),a&&l.setAttribute("server-url",a),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>document.body.appendChild(l)):document.body.appendChild(l),l.addEventListener("vaniraai:tool_call",c=>{const A=c.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:d=>{console.log("[VaniraAI] sendResult called:",d)}})})}}})();
1096
1096
  //# sourceMappingURL=vanira-sdk.js.map