@vanira/sdk 0.0.86 → 0.0.88

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 +1,17 @@
1
- "use strict";var Q=Object.defineProperty;var F=(a,e,t)=>e in a?Q(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var d=(a,e,t)=>F(a,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class ee{pause(){}cleanup(){}onEnded(e){}}class W{createRemotePlayer(e){return new ee}}class J{async getUserAudio(e){return navigator.mediaDevices.getUserMedia({audio:e})}stopStream(e){e.getTracks().forEach(t=>t.stop())}}class H{create(e){return new globalThis.RTCPeerConnection({iceServers:e.iceServers,iceTransportPolicy:e.iceTransportPolicy??"all"})}}class G{bind(e,t){return e.onopen=()=>t.onOpen(),e.onerror=i=>t.onError(i),e.onmessage=i=>{if(typeof i.data=="string"){t.onMessage({text:i.data});return}if(i.data instanceof ArrayBuffer){try{const n=new TextDecoder().decode(i.data),r=JSON.parse(n);(r==null?void 0:r.event)==="client_tool_call"&&t.onMessage({text:n})}catch{}return}},{send(i){e.readyState==="open"&&e.send(i)},isOpen(){return e.readyState==="open"},close(){e.close()}}}}const te="https://api.vanira.io",c={Form:"vanira_form",Calendar:"vanira_calendar",Navigate:"vanira_navigate",Upload:"vanira_upload",Camera:"vanira_camera",HighlightElement:"vanira_highlight_element",ClickElement:"vanira_click_element",SelectOption:"vanira_select_option",SetDate:"vanira_set_date",TypeText:"vanira_type_text",WriteLatexText:"vanira_write_latex_text",EraseText:"vanira_erase_text",LiveVision:"vanira_live_vision",CloseLiveCamera:"vanira_close_live_camera",LiveScreen:"vanira_live_screen",CloseLiveScreen:"vanira_close_live_screen",ClipRegion:"vanira_clip_region",ScreenVision:"vanira_screen_vision",PointAt:"vanira_point_at",DrawOnScreen:"vanira_draw_on_screen",ClearScreenDraw:"vanira_clear_screen_draw",HighlightOnScreen:"vanira_highlight_on_screen",KycDocumentCapture:"vanira_kyc_document_capture",KycSelfieCapture:"vanira_kyc_selfie_capture",KycSignatureCapture:"vanira_kyc_signature_capture"},ie=Object.values(c),ne=new Set(ie);function V(a){return!!a&&ne.has(a)}function z(a){if(typeof a=="string")try{return JSON.parse(a)}catch{return{}}return a&&typeof a=="object"?a:{}}const D={type_on_whiteboard:c.TypeText,write_on_whiteboard:c.TypeText,write_on_white_board:c.TypeText,dom_typing_simulation:c.TypeText,write_latex_text:c.WriteLatexText,write_latex_on_board:c.WriteLatexText,latex_on_whiteboard:c.WriteLatexText,erase_text:c.EraseText,dom_erase:c.EraseText,open_live_camera:c.LiveVision,live_vision:c.LiveVision,close_live_camera:c.CloseLiveCamera,stop_live_camera:c.CloseLiveCamera,open_live_screen:c.LiveScreen,close_live_screen:c.CloseLiveScreen,screen_vision:c.ScreenVision,capture_screen_vision:c.ScreenVision,capture_screen:c.ScreenVision,tab_screenshot:c.ScreenVision,capture_tab:c.ScreenVision,capture_tab_screenshot:c.ScreenVision,screenshot_tab:c.ScreenVision,point_at:c.PointAt,point_at_screen:c.PointAt,draw_on_screen:c.DrawOnScreen,screen_draw:c.DrawOnScreen,clear_screen_draw:c.ClearScreenDraw,clear_screen_annotations:c.ClearScreenDraw,highlight_on_screen:c.HighlightOnScreen,highlight_element_on_screen:c.HighlightOnScreen,highlight_screen_element:c.HighlightOnScreen,kyc_document_capture:c.KycDocumentCapture,capture_id_document:c.KycDocumentCapture,document_capture:c.KycDocumentCapture,capture_kyc_document:c.KycDocumentCapture,kyc_selfie_capture:c.KycSelfieCapture,capture_selfie:c.KycSelfieCapture,selfie_capture:c.KycSelfieCapture,capture_kyc_selfie:c.KycSelfieCapture,kyc_signature_capture:c.KycSignatureCapture,capture_kyc_signature:c.KycSignatureCapture,signature_capture:c.KycSignatureCapture},K={vanira_tab_screenshot:c.ScreenVision,vanira_document_capture:c.KycDocumentCapture,vanira_selfie_capture:c.KycSelfieCapture,vanira_signature_capture:c.KycSignatureCapture,vanira_kyc_signature:c.KycSignatureCapture};function ae(a,e){const t=a.latex_text??(e==null?void 0:e.latex_text);return typeof t=="string"&&t.trim().length>0}function B(a,e){const t=a.text_to_type??(e==null?void 0:e.text_to_type)??a.text??(e==null?void 0:e.text)??a.value??(e==null?void 0:e.value);return typeof t=="string"&&t.trim().length>0}function re(a,e){const t=a.fields??(e==null?void 0:e.fields);return Array.isArray(t)?t.length>0:typeof t=="string"?t.split(",").map(i=>i.trim()).filter(Boolean).length>0:!1}function se(a,e){const t=a==null?void 0:a.preset_id;if(typeof t=="string"){if(V(t))return t;const r=K[t];if(r)return r}const n=z(e).preset_id;if(typeof n=="string"){if(V(n))return n;const r=K[n];if(r)return r}}function oe(a,e,t){const i=z(e);let n=se(a,i);if(n===c.Form&&B(i,a)&&!re(i,a))return c.TypeText;if(n)return n;const r=String(t??"").trim().toLowerCase();if(r&&D[r])return D[r];if(ae(i,a))return c.WriteLatexText;if(B(i,a))return c.TypeText}const C="vanira_latest_call_id",R="vanira_prospect_id";function I(a){return`vanira_latest_call_id_${a}`}function T(a){return`vanira_prospect_id_${a}`}function Y(a){return`vanira_call_meta_${a}`}function S(a,e){if(!a)return null;try{return a.getItem(e)}catch{return null}}function $(a){if(typeof window>"u"||!a)return null;const e=[],t=S(window.localStorage,Y(a));if(t)try{const h=JSON.parse(t);h!=null&&h.callId&&e.push({callId:h.callId,prospectId:h.prospectId,updatedAt:h.updatedAt||0})}catch{}const i=(h,s,u)=>{h&&e.push({callId:h,prospectId:s||void 0,updatedAt:u})},n=S(window.localStorage,T(a)),r=S(window.sessionStorage,T(a)),o=S(window.localStorage,R);return i(S(window.localStorage,I(a)),n||o,2),i(S(window.sessionStorage,I(a)),r||o,1),i(S(window.localStorage,C),o,0),i(S(window.sessionStorage,C),o,0),e.length?(e.sort((h,s)=>s.updatedAt-h.updatedAt),e[0]):null}function ce(a,e,t){var n,r,o,h,s,u,p,l,_;if(typeof window>"u"||!a||!e)return;const i={callId:e,prospectId:t,updatedAt:Date.now()};try{(n=window.localStorage)==null||n.setItem(Y(a),JSON.stringify(i)),(r=window.localStorage)==null||r.setItem(I(a),e),(o=window.sessionStorage)==null||o.setItem(I(a),e),t&&((h=window.localStorage)==null||h.setItem(T(a),t),(s=window.sessionStorage)==null||s.setItem(T(a),t)),(u=window.localStorage)==null||u.setItem(C,e),(p=window.sessionStorage)==null||p.setItem(C,e),t&&((l=window.localStorage)==null||l.setItem(R,t),(_=window.sessionStorage)==null||_.setItem(R,t))}catch{}}const le=new Set(["client_tool_call","clearAudio","client_tool_cancel"]);function de(a){if(!a||typeof a!="object")return!1;const e=a.event;return typeof e=="string"&&le.has(e)}const E=16*1024,he=256*1024;function k(a,e){return(a==null?void 0:a.readyState)==="open"&&(e==null?void 0:e.readyState)==="open"}function ue(a,e){return{control:(a==null?void 0:a.readyState)??"missing",mediaBytes:(e==null?void 0:e.readyState)??"missing"}}async function pe(a,e,t=8e3){if(k(a,e))return!0;const i=Date.now()+t;for(;Date.now()<i;){if(k(a,e))return!0;await new Promise(n=>setTimeout(n,50))}return k(a,e)}async function j(a){for(;a.bufferedAmount>he;)await new Promise(e=>setTimeout(e,10))}async function _e(a){const{bytes:e,filename:t,contentType:i,reason:n,message:r,callId:o,mediaBytesChannel:h,sendControlEvent:s,uploadId:u=crypto.randomUUID(),uploadKind:p="media"}=a,l=e.byteLength,_=l===0?0:Math.ceil(l/E);s("client_media_upload_start",{data:{upload_id:u,call_id:o,reason:n,message:r,filename:t,content_type:i,size:l,chunk_count:_,upload_kind:p}});const m=new Uint8Array(e);for(let f=0;f<l;f+=E){await j(h);const w=Math.min(f+E,l);h.send(m.subarray(f,w))}return await j(h),s("client_media_upload_complete",{data:{upload_id:u,call_id:o,reason:n,message:r,chunk_count:_,upload_kind:p}}),{media_id:u,url:"",content_type:i}}async function me(a){return typeof a.arrayBuffer=="function"?a.arrayBuffer():new Response(a).arrayBuffer()}function fe(a){return null}function g(){return typeof window>"u"?"/":`${window.location.pathname}${window.location.search}${window.location.hash}`||"/"}class ye{constructor(e){d(this,"active",!1);d(this,"initialSent",!1);d(this,"lastRoute","");d(this,"sendContext");d(this,"isReady");d(this,"cleanupFns",[]);d(this,"initialRetryTimer",null);d(this,"routePollTimer",null);d(this,"originalPushState",null);d(this,"originalReplaceState",null);this.sendContext=e.sendContext,this.isReady=e.isReady??(()=>!0)}start(){typeof window>"u"||this.active||(this.active=!0,this.initialSent=!1,this.lastRoute=g(),this.attachListeners(),this.scheduleInitialContextSend())}stop(){if(!(!this.active&&this.cleanupFns.length===0)){this.active=!1,this.initialSent=!1,this.initialRetryTimer!==null&&(clearTimeout(this.initialRetryTimer),this.initialRetryTimer=null),this.routePollTimer!==null&&(clearInterval(this.routePollTimer),this.routePollTimer=null);for(const e of this.cleanupFns)try{e()}catch{}this.cleanupFns.length=0,this.originalPushState&&(history.pushState=this.originalPushState,this.originalPushState=null),this.originalReplaceState&&(history.replaceState=this.originalReplaceState,this.originalReplaceState=null)}}onChannelReady(){this.scheduleInitialContextSend()}scheduleInitialContextSend(e=0){if(!(!this.active||this.initialSent)){if(this.isReady()){this.sendRouteContext("call_started"),this.initialSent=!0;return}e>=30||(this.initialRetryTimer=window.setTimeout(()=>this.scheduleInitialContextSend(e+1),100))}}attachListeners(){const e=(r,o=0)=>{const h=()=>{const s=g();s!==this.lastRoute&&this.handleRouteChange(s,r)};o>0?window.setTimeout(h,o):queueMicrotask(h)},t=()=>e("popstate"),i=()=>e("hashchange"),n=r=>{const o=r.detail;if((o==null?void 0:o.initiated_by)==="agent"){e("vanira_navigate_agent",120);return}e("vanira_navigate",120)};window.addEventListener("popstate",t),window.addEventListener("hashchange",i),window.addEventListener("vanira:navigate",n),this.cleanupFns.push(()=>window.removeEventListener("popstate",t),()=>window.removeEventListener("hashchange",i),()=>window.removeEventListener("vanira:navigate",n)),this.originalPushState=history.pushState.bind(history),this.originalReplaceState=history.replaceState.bind(history),history.pushState=(...r)=>{this.originalPushState(...r),e("pushState")},history.replaceState=(...r)=>{this.originalReplaceState(...r),e("replaceState")},this.routePollTimer=window.setInterval(()=>{if(!this.active)return;const r=g();r!==this.lastRoute&&this.handleRouteChange(r,"location_poll")},1e3)}handleRouteChange(e,t){if(!this.active)return;const i=this.lastRoute;if(i===e)return;if(this.lastRoute=e,!this.initialSent){this.scheduleInitialContextSend();return}!this.isReady()||fe()||this.sendRouteContext("route_changed",i,t,"user")}sendRouteContext(e,t,i,n="user"){const r=g();this.lastRoute=r;const o={ui_state:"page_navigation",navigation_led_by:n,current_route:r,current_page:r,user_action:e==="call_started"?"call_started_on_page":"user_navigated"};e==="call_started"?o.message=`User started the call while viewing ${r}.`:(o.previous_route=t??"",o.message=`User navigated from ${t||"(unknown)"} to ${r}.`,i&&(o.navigation_source=i));try{this.sendContext(o)}catch{}}}const y=class y{constructor(e){d(this,"serverUrl");d(this,"agentId");d(this,"callId");d(this,"prospectId");d(this,"apiKey");d(this,"backendUrl");d(this,"token");d(this,"onConnected");d(this,"onDisconnected");d(this,"onError");d(this,"onTranscription");d(this,"onLocalStream");d(this,"onRemoteTrack");d(this,"onClientToolCall");d(this,"onSessionStarted");d(this,"sessionStartedEmitted",!1);d(this,"pc",null);d(this,"dataChannel",null);d(this,"mediaBytesChannel",null);d(this,"audioElement",null);d(this,"localStream",null);d(this,"micMuted",!1);d(this,"connected",!1);d(this,"icePollInterval",null);d(this,"appliedRemoteCandidates",new Set);d(this,"iceServers");d(this,"callSessionLoaded",!1);d(this,"connectGeneration",0);d(this,"runtime");d(this,"sessionBehavior");d(this,"routeTracker",null);d(this,"_status","idle");d(this,"listeners",new Map);d(this,"liveVision");d(this,"liveVisionAutoStarted",!1);if(!e.agentId)throw new Error("agentId is required");const t=!!(e.apiKey||e.token),i=!!(e.serverUrl&&e.callId),n=y.normalizeIceServers(e.iceServers);if(!t&&!i)throw new Error("apiKey or token is required — or pass serverUrl and callId from a prior POST /calls/create");this.agentId=e.agentId,this.sessionBehavior=e.sessionBehavior,this.serverUrl=(e.serverUrl||"").replace(/\/$/,""),this.apiKey=e.apiKey,this.token=e.token,this.backendUrl=(e.backendUrl||te).replace(/\/$/,""),n.length&&(this.iceServers=n),i&&(this.callSessionLoaded=!0);const r=typeof window<"u";this.prospectId=e.prospectId;const o=e.sessionBehavior==="continue";if(o&&r&&!e.callId){const s=$(this.agentId);s&&(e.callId||(this.callId=s.callId),!this.prospectId&&s.prospectId&&(this.prospectId=s.prospectId))}if(!this.prospectId&&r)try{const s=$(this.agentId);this.prospectId=(s==null?void 0:s.prospectId)||window.sessionStorage&&window.sessionStorage.getItem("vanira_prospect_id")||window.localStorage&&window.localStorage.getItem("vanira_prospect_id")||void 0}catch{}e.callId?this.callId=e.callId:o||(this.callId=void 0);const h=e.onSessionStarted;this.onSessionStarted=s=>{h==null||h(s),this.emit("session_started",s)},this.liveVision=e.liveVision,this.onConnected=()=>{var s;this._status="connected",(s=e.onConnected)==null||s.call(e),this.emit("connected"),this.maybeAutoStartLiveCamera()},this.onDisconnected=()=>{var s;this._status="disconnected",(s=e.onDisconnected)==null||s.call(e),this.emit("disconnected")},this.onError=s=>{var p;this._status="error";const u=typeof s=="string"?s:(s==null?void 0:s.message)||"Connection error";(p=e.onError)==null||p.call(e,s),this.emit("error",u)},this.onTranscription=(s,u)=>{var p;(p=e.onTranscription)==null||p.call(e,s,u),this.emit("transcription",{text:s,isFinal:u})},this.onLocalStream=e.onLocalStream||(()=>{}),this.onRemoteTrack=(s,u)=>{var p;(p=e.onRemoteTrack)==null||p.call(e,s,u),this.emit("track",{track:s,stream:u})},this.onClientToolCall=s=>{var l;(l=e.onClientToolCall)==null||l.call(e,s);const u=(s==null?void 0:s.data)||s,p={name:String(u.name||u.tool_name||""),arguments:u.arguments||u.args||{},tool_call_id:String(u.tool_call_id||u.call_id||""),execution_mode:u.execution_mode==="blocking"?"blocking":"fire_and_forget",client_fields:u.client_fields||{}};p.name&&p.tool_call_id&&this.emit("tool_call",p)},this.runtime=e.runtime,typeof window<"u"&&e.trackRouteContext!==!1&&(this.routeTracker=new ye({sendContext:s=>this.sendContextUpdate(s),isReady:()=>{var s;return((s=this.dataChannel)==null?void 0:s.readyState)==="open"}}))}async createCall(){return this.connect()}async connect(){var t;this._status="connecting";const e=++this.connectGeneration;if(await this.loadCallSession(),!this.isConnectCancelled(e)){if(!this.serverUrl)throw new Error("[VaniraClient] worker_url missing from /calls/create");if(!this.callId)throw new Error("[VaniraClient] call_id missing — must come from POST /calls/create");if(this.onSessionStarted&&this.prospectId&&this.callId&&!this.sessionStartedEmitted)try{this.onSessionStarted({prospectId:this.prospectId,callId:this.callId,serverUrl:this.serverUrl}),this.sessionStartedEmitted=!0}catch{}try{this.appliedRemoteCandidates.clear(),this.stopRemoteIcePolling();const i=this.getIceServers();this.pc=new RTCPeerConnection({iceServers:i,iceTransportPolicy:"all"});let n;try{n=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,sampleRate:{ideal:16e3},channelCount:1}})}catch(l){if(l.name==="NotAllowedError"||l.name==="PermissionDeniedError"||(t=l.message)!=null&&t.includes("Permission denied")){const _=navigator.userAgent,m=/iPad|iPhone|iPod/.test(_)||navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1;let f="Microphone access denied. Please allow microphone access in your browser settings.";m&&(_.includes("CriOS")?f="Microphone access blocked. Please enable it in iOS Settings > Chrome > Microphone, then reload the page.":_.includes("FxiOS")?f="Microphone access blocked. Please enable it in iOS Settings > Firefox > Microphone, then reload the page.":f="Microphone access blocked. Please enable it in iOS Settings > Safari > Microphone (or tap 'aA' > Website Settings > Allow Microphone).");const w=new Error(f);throw w.name=l.name,w}throw l}if(this.isConnectCancelled(e)){n.getTracks().forEach(l=>l.stop());return}if(this.localStream=n,!this.pc||this.isConnectCancelled(e)){n.getTracks().forEach(l=>l.stop());return}if(this.onLocalStream(n),n.getTracks().forEach(l=>{var _;(_=this.pc)==null||_.addTrack(l,n)}),!this.pc)throw new Error("RTCPeerConnection was closed unexpectedly");this.dataChannel=this.pc.createDataChannel("control"),this.dataChannel.onopen=()=>{var l;(l=this.routeTracker)==null||l.onChannelReady()},this.dataChannel.onmessage=l=>{if(typeof l.data=="string")try{this.handleControlEvent(JSON.parse(l.data))}catch{}else if(l.data instanceof ArrayBuffer)try{const _=new TextDecoder().decode(l.data);try{const m=JSON.parse(_);de(m)&&this.handleControlEvent(m)}catch{}}catch{}else l.data instanceof Blob&&l.data.text().then(_=>{try{this.handleControlEvent(JSON.parse(_))}catch{}})},this.dataChannel.onerror=l=>{},this.mediaBytesChannel=this.pc.createDataChannel("media-bytes",{ordered:!0}),this.mediaBytesChannel.binaryType="arraybuffer",this.mediaBytesChannel.onopen=()=>{},this.mediaBytesChannel.onerror=l=>{},this.pc.ontrack=l=>{const _=l.track,m=l.streams[0];_.kind==="audio"?(this.audioElement=new Audio,this.audioElement.srcObject=m,this.audioElement.play().catch(f=>{}),this.audioElement.onended=()=>{this.sendEvent("playedStream"),typeof window<"u"&&window.dispatchEvent(new CustomEvent("vanira:agent-playback-ended"))},this.onRemoteTrack(_,m)):_.kind==="video"&&this.onRemoteTrack(_,m)};const r=()=>{var m,f,w,A,x,P,U,L,M,O,N;const l=((m=this.pc)==null?void 0:m.connectionState)==="connected"||((f=this.pc)==null?void 0:f.iceConnectionState)==="connected"||((w=this.pc)==null?void 0:w.iceConnectionState)==="completed",_=((A=this.pc)==null?void 0:A.connectionState)==="failed"||((x=this.pc)==null?void 0:x.iceConnectionState)==="failed"||((P=this.pc)==null?void 0:P.connectionState)==="closed"||((U=this.pc)==null?void 0:U.iceConnectionState)==="closed"||((L=this.pc)==null?void 0:L.connectionState)==="disconnected"||((M=this.pc)==null?void 0:M.iceConnectionState)==="disconnected";((O=this.pc)==null?void 0:O.connectionState)==="connected"&&this.stopRemoteIcePolling(),l&&!this.connected?(this.connected=!0,(N=this.routeTracker)==null||N.start(),this.onConnected()):_&&this.connected&&(this.connected=!1,this.liveVisionAutoStarted=!1,this.onDisconnected())};this.pc.onconnectionstatechange=r,this.pc.oniceconnectionstatechange=r;const o=this.getIceTrickleUrl();this.pc.onicecandidate=l=>{l.candidate&&fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({candidate:l.candidate.toJSON()})}).catch(_=>{})};const h=await this.pc.createOffer();if(this.isConnectCancelled(e)||(await this.pc.setLocalDescription(h),this.isConnectCancelled(e)))return;const s=this.serverUrl.includes("?")?this.serverUrl:`${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`,u=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({offer:this.pc.localDescription,agentId:this.agentId,callId:this.callId})});if(this.isConnectCancelled(e))return;if(!u.ok){const l=await u.json();throw new Error(l.error||`HTTP ${u.status}`)}const{answer:p}=await u.json();if(this.isConnectCancelled(e)||!this.pc||(await this.pc.setRemoteDescription(p),this.isConnectCancelled(e)))return;this.startRemoteIcePolling(o)}catch(i){if(this.isConnectCancelled(e))return;throw this.disconnect(),this.onError(i.message||i),i}}}createCallCacheKey(e,t){const i=this.apiKey?`key:${this.apiKey.slice(0,16)}`:`token:${(this.token||"").slice(-16)}`;return[this.backendUrl,this.agentId,e,t||"",this.prospectId||"",i].join("|")}async postCreateCall(e,t,i){var h,s,u;const n=await fetch(`${this.backendUrl}/calls/create`,{method:"POST",headers:e,body:JSON.stringify({agent_id:this.agentId,type:((h=this.runtime)==null?void 0:h.callType)||"web",mode:t,...(s=this.runtime)!=null&&s.runtimeName?{runtime:this.runtime.runtimeName}:{},prospect_id:this.prospectId,...i?{call_id:i}:{}})});if(!n.ok){const p=await n.json().catch(()=>({}));throw new Error(`[VaniraClient] createCall failed (${n.status}): ${((u=p==null?void 0:p.detail)==null?void 0:u.message)||(p==null?void 0:p.message)||n.statusText}`)}const r=await n.json();if(!r.call_id||!r.worker_url)throw new Error("[VaniraClient] /calls/create response missing call_id or worker_url");const o=y.normalizeIceServers(r.ice_servers);if(!o.length)throw new Error("[VaniraClient] /calls/create response missing ice_servers");return{callId:r.call_id,prospectId:r.prospect_id||this.prospectId,serverUrl:r.worker_url.replace(/\/$/,""),iceServers:o}}applyCreateCallSession(e){if(this.callId=e.callId,this.prospectId=e.prospectId||this.prospectId,this.serverUrl=e.serverUrl,this.iceServers=e.iceServers,this.callSessionLoaded=!0,ce(this.agentId,this.callId||"",this.prospectId),this.onSessionStarted&&this.prospectId&&this.callId&&!this.sessionStartedEmitted)try{this.onSessionStarted({prospectId:this.prospectId,callId:this.callId,serverUrl:this.serverUrl}),this.sessionStartedEmitted=!0}catch{}}async loadCallSession(){if(this.callSessionLoaded)return;if(this.serverUrl&&this.callId){this.callSessionLoaded=!0;return}if(!this.apiKey&&!this.token)throw new Error("[VaniraClient] apiKey or token is required to create a call session");const e={"Content-Type":"application/json"};this.apiKey?e["X-API-Key"]=this.apiKey:this.token&&(e.Authorization=this.token.startsWith("Bearer ")?this.token:`Bearer ${this.token}`);const t=this.sessionBehavior==="continue"?this.callId:void 0,i=this.sessionBehavior==="continue"?"continue":"new",n=this.createCallCacheKey(i,t);let r=y.inflightCreates.get(n);r||(r=this.postCreateCall(e,i,t),y.inflightCreates.set(n,r),r.finally(()=>{y.inflightCreates.get(n)===r&&y.inflightCreates.delete(n)}));const o=await r;this.applyCreateCallSession(o)}getIceServers(){var e;if((e=this.iceServers)!=null&&e.length)return this.iceServers;throw new Error("[VaniraClient] ice_servers missing — pass iceServers from POST /calls/create")}static normalizeIceServers(e){if(!Array.isArray(e))return[];const t=[];for(const i of e){const n=i==null?void 0:i.urls,r=Array.isArray(n)?n.filter(Boolean):typeof n=="string"&&n.trim()?[n.trim()]:[];if(!r.length)continue;const o={urls:r.length===1?r[0]:r},h=i.username,s=i.credential;h&&(o.username=h),s&&(o.credential=s),t.push(o)}return t}getWorkerOrigin(){var e;if(!((e=this.serverUrl)!=null&&e.trim()))return"";try{return new URL(this.serverUrl).origin}catch{return this.serverUrl.replace(/\/webrtc.*$/,"").replace(/\/$/,"")}}getIceTrickleUrl(){try{const e=new URL(this.serverUrl);return e.pathname.endsWith("/webrtc")?e.pathname=`${e.pathname}/ice`:e.pathname="/webrtc/ice",e.toString()}catch{return`${this.getWorkerOrigin()}/webrtc/ice?agent_id=${this.agentId}&call_id=${this.callId}`}}startRemoteIcePolling(e){this.stopRemoteIcePolling(),this.icePollInterval=setInterval(async()=>{if(!this.pc){this.stopRemoteIcePolling();return}if(this.pc.connectionState==="connected"){this.stopRemoteIcePolling();return}try{const t=await fetch(e);if(!t.ok)return;const{candidates:i}=await t.json();for(const n of i||[]){const r=JSON.stringify(n);if(!this.appliedRemoteCandidates.has(r)){this.appliedRemoteCandidates.add(r);try{await this.pc.addIceCandidate(n)}catch{}}}}catch{}},150)}stopRemoteIcePolling(){this.icePollInterval!==null&&(clearInterval(this.icePollInterval),this.icePollInterval=null)}sendEvent(e,t={}){var i;if(((i=this.dataChannel)==null?void 0:i.readyState)==="open"){const n={event:e,...t};this.dataChannel.send(JSON.stringify(n))}}async sendEventWhenReady(e,t={},i=1e4){var r;const n=Date.now()+i;for(;Date.now()<n;){if(((r=this.dataChannel)==null?void 0:r.readyState)==="open")return this.sendEvent(e,t),!0;await new Promise(o=>setTimeout(o,50))}return!1}startLiveCamera(e={}){const t={...this.liveVision,...e};this.emit("tool_call",this.buildOpenLiveCameraToolCall(t))}buildOpenLiveCameraToolCall(e={}){const t=e.scope??"until_call_end";return{name:"open_live_camera",tool_call_id:`lv_${crypto.randomUUID()}`,execution_mode:"fire_and_forget",client_fields:{preset_id:c.LiveVision},arguments:{mode:"live",scope:t,target_fps:e.target_fps??1,max_fps:e.max_fps??3,max_width:e.max_width??640,reason:e.reason??"camera_capture",facing_mode:e.facing_mode??"environment",show_preview:e.show_preview??!0,...t==="timed"&&e.duration_sec?{duration_sec:e.duration_sec}:{}}}}maybeAutoStartLiveCamera(){const e=this.liveVision;!(e!=null&&e.enabled)||e.scope!=="full_call"||this.liveVisionAutoStarted||(this.liveVisionAutoStarted=!0,this.emit("tool_call",this.buildOpenLiveCameraToolCall(e)))}handleControlEvent(e){var t;switch(e.event){case"clearAudio":break;case"transcription":this.onTranscription(e.text,e.isFinal);break;case"mark":break;case"client_tool_cancel":{const n=(e.data||e).tool_call_id||e.tool_call_id;this.dispatchBoardAbort("Tool cancelled by server",n);break}case"client_tool_call":{const i=e.tool_call||e.data||e,n=(i==null?void 0:i.tool_call_id)||(i==null?void 0:i.call_id)||e.tool_call_id||"";n&&((t=this.dataChannel)==null?void 0:t.readyState)==="open"&&this.dataChannel.send(JSON.stringify({event:"client_tool_ack",data:{tool_call_id:n}}));const r=(i==null?void 0:i.arguments)||(i==null?void 0:i.args)||{},o=(i==null?void 0:i.client_fields)||{},h=(i==null?void 0:i.name)||(i==null?void 0:i.tool_name)||"",s=oe(o,r,h);if(h==="end_call"){n&&this.sendToolResult(n,{status:"client_ack_end_call",message:"Ending call."}),window.setTimeout(()=>this.disconnect(),120);break}if(s){window.dispatchEvent(new CustomEvent("vanira:preset",{detail:{toolCall:i,client:this}})),this.onClientToolCall(i);break}this.onClientToolCall(i);break}}}disconnect(){var e;this.connectGeneration++,this.stopRemoteIcePolling(),this.appliedRemoteCandidates.clear(),this.audioElement&&(this.audioElement.pause(),this.audioElement.srcObject=null),this.dataChannel&&(this.dataChannel.close(),this.dataChannel=null),this.mediaBytesChannel&&(this.mediaBytesChannel.close(),this.mediaBytesChannel=null),this.pc&&(this.pc.getSenders().forEach(t=>{t.track&&t.track.stop()}),this.pc.close(),this.pc=null),this.localStream&&(this.localStream.getTracks().forEach(t=>{try{t.stop()}catch{}}),this.localStream=null),this.connected=!1,(e=this.routeTracker)==null||e.stop(),this.callSessionLoaded=!1,this.sessionStartedEmitted=!1,this.serverUrl="",this.callId=void 0,this.micMuted=!1,this.iceServers=void 0,this.onDisconnected()}setMicrophoneMuted(e){var t,i;this.micMuted=e,(t=this.localStream)==null||t.getAudioTracks().forEach(n=>{n.enabled=!e}),(i=this.pc)==null||i.getSenders().forEach(n=>{var r;((r=n.track)==null?void 0:r.kind)==="audio"&&(n.track.enabled=!e)})}isMicrophoneMuted(){return this.micMuted}toggleMicrophoneMuted(){return this.setMicrophoneMuted(!this.micMuted),this.micMuted}isConnectCancelled(e){return e!==this.connectGeneration}dispatchBoardAbort(e,t){typeof window>"u"||window.dispatchEvent(new CustomEvent("vanira:board_abort",{detail:{reason:e,toolCallId:t}}))}sendToolResult(e,t){this.callId,this.sendEvent("client_tool_result",{call_id:this.callId,data:{tool_call_id:e,result:t},result:t})}sendToolAck(e){var t;((t=this.dataChannel)==null?void 0:t.readyState)==="open"&&this.dataChannel.send(JSON.stringify({event:"client_tool_ack",data:{tool_call_id:e}}))}sendContextUpdate(e){this.sendEvent("client_context_update",{data:{context:e}})}sendActionTrigger(e,t={}){this.sendEvent("client_action_trigger",{data:{action_name:e,data:t}})}triggerActionInterrupt(){this.sendEvent("action_interrupt")}sendMediaUpdate(e){if(!this.dataChannel||this.dataChannel.readyState!=="open")return!1;const t={event:"client_media_update",data:{media_id:e.media_id,media_url:e.media_url,content_type:e.content_type,reason:e.reason,message:e.message??""}};return this.dataChannel.send(JSON.stringify(t)),!0}async uploadMediaForToolResult(e,t="general"){return this._postMediaUpload(e,t)}async uploadMedia(e,t="general",i=""){return await pe(this.dataChannel,this.mediaBytesChannel)?this._uploadMediaViaDataChannel(e,t,i):(ue(this.dataChannel,this.mediaBytesChannel),this._uploadMediaViaHTTP(e,t,i))}async uploadMediaFrame(e,t="camera_capture",i){const n=i&&!(e instanceof File)?new File([e],i,{type:e.type||"image/jpeg"}):e,{media_id:r,url:o,contentType:h}=await this._postMediaUpload(n,t,!0);if(!r||!o)throw new Error("Frame upload failed: server response missing media_id or url");return{media_id:r,url:o,content_type:h}}async _uploadBytesViaDataChannel(e,t,i,n,r){if(!this.callId||!this.mediaBytesChannel)throw new Error("Upload failed: call not ready for WebRTC media upload.");const o=r||(e instanceof File?e.name:n==="frame"?"frame.jpg":"upload.bin"),h=e.type||(n==="frame"?"image/jpeg":"application/octet-stream"),s=await me(e);return _e({bytes:s,filename:o,contentType:h,reason:t,message:i,callId:this.callId,mediaBytesChannel:this.mediaBytesChannel,sendControlEvent:(u,p)=>this.sendEvent(u,p),uploadKind:n})}async _uploadMediaViaDataChannel(e,t,i){const n=await this._uploadBytesViaDataChannel(e,t,i,"media");return{media_id:n.media_id,url:n.url}}async _uploadMediaViaHTTP(e,t="general",i=""){const{media_id:n,url:r,contentType:o}=await this._postMediaUpload(e,t,!0);return this.sendMediaUpdate({media_id:n,media_url:r,content_type:o,reason:t,message:i}),{media_id:n,url:r}}async _postMediaUpload(e,t,i=!1){if(!this.serverUrl)throw new Error("Upload failed: serverUrl is not set. Connect the VaniraClient first.");if(!this.callId)throw new Error("Upload failed: callId is missing.");const n=this.getWorkerOrigin();if(!n)throw new Error("Upload failed: worker_url is not set. Connect the call before uploading media.");const r=`${n}/media/upload`,o=new FormData;o.append("file",e),o.append("call_id",this.callId),o.append("reason",t);const h=await fetch(r,{method:"POST",body:o});if(!h.ok){let _=`HTTP ${h.status}`;try{_=(await h.json()).error||_}catch{}throw new Error(`Upload failed: ${_}`)}const s=await h.json(),u=s.media_id,p=s.url,l=s.content_type||e.type;if(!u||!p)throw new Error("Upload failed: server response missing media_id or url");return i?{media_id:u,url:p,contentType:l}:{media_id:u,url:p,contentType:l}}get status(){return this._status}get isConnected(){return this._status==="connected"}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),this}off(e,t){var i;return(i=this.listeners.get(e))==null||i.delete(t),this}emit(e,t){var i;(i=this.listeners.get(e))==null||i.forEach(n=>n(t))}async start(){return await this.connect(),{callId:this.callId||"",prospectId:this.prospectId||"",serverUrl:this.serverUrl||""}}stop(){this.disconnect(),this._status="disconnected"}sendToolError(e,t){this.sendToolResult(e,{status:"error",error:t})}updateContext(e){this.sendContextUpdate(e)}triggerInterrupt(e,t={}){this.triggerActionInterrupt(),this.sendActionTrigger(e,t)}interruptAudioOnly(){this.triggerActionInterrupt()}};d(y,"inflightCreates",new Map);let v=y;const q={supportsAudioEndedEvent:!1,supportsScreenShare:!1,supportsDom:!1,supportsHtmlAudio:!1,supportsCustomElements:!1,supportsLocalStorage:!1,supportsBroadcastChannel:!1},X={name:"react-native",callType:"web",runtimeName:"react-native",callIdPrefix:"rn_",capabilities:q,audio:new W,media:new J,peer:new H,dataChannel:new G};function b(a){return new v({...a,runtime:X})}const Se=b;function Z(a){return b(a)}const we=Z;exports.RNAudioAdapter=W;exports.RNDataChannelAdapter=G;exports.RNMediaAdapter=J;exports.RNPeerAdapter=H;exports.VaniraAI=v;exports.VaniraClient=v;exports.WebRTCClient=v;exports.createReactNativeAI=Se;exports.createReactNativeClient=b;exports.createVaniraAI=we;exports.createVaniraClient=Z;exports.reactNativeCapabilities=q;exports.reactNativeRuntime=X;
1
+ "use strict";var ae=Object.defineProperty;var ie=(i,e,t)=>e in i?ae(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var d=(i,e,t)=>ie(i,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class ne{pause(){}cleanup(){}onEnded(e){}}class z{createRemotePlayer(e){return new ne}}class Y{async getUserAudio(e){return navigator.mediaDevices.getUserMedia({audio:e})}stopStream(e){e.getTracks().forEach(t=>t.stop())}}class q{create(e){return new globalThis.RTCPeerConnection({iceServers:e.iceServers,iceTransportPolicy:e.iceTransportPolicy??"all"})}}class X{bind(e,t){return e.onopen=()=>t.onOpen(),e.onerror=a=>t.onError(a),e.onmessage=a=>{if(typeof a.data=="string"){t.onMessage({text:a.data});return}if(a.data instanceof ArrayBuffer){try{const n=new TextDecoder().decode(a.data),r=JSON.parse(n);(r==null?void 0:r.event)==="client_tool_call"&&t.onMessage({text:n})}catch{}return}},{send(a){e.readyState==="open"&&e.send(a)},isOpen(){return e.readyState==="open"},close(){e.close()}}}}const re="https://api.vanira.io",c={Form:"vanira_form",Calendar:"vanira_calendar",Navigate:"vanira_navigate",Upload:"vanira_upload",Camera:"vanira_camera",HighlightElement:"vanira_highlight_element",ClickElement:"vanira_click_element",SelectOption:"vanira_select_option",SetDate:"vanira_set_date",TypeText:"vanira_type_text",WriteLatexText:"vanira_write_latex_text",GeoGebra:"vanira_geogebra",EraseText:"vanira_erase_text",LiveVision:"vanira_live_vision",CloseLiveCamera:"vanira_close_live_camera",LiveScreen:"vanira_live_screen",CloseLiveScreen:"vanira_close_live_screen",ClipRegion:"vanira_clip_region",ScreenVision:"vanira_screen_vision",PointAt:"vanira_point_at",DrawOnScreen:"vanira_draw_on_screen",ClearScreenDraw:"vanira_clear_screen_draw",HighlightOnScreen:"vanira_highlight_on_screen",KycDocumentCapture:"vanira_kyc_document_capture",KycSelfieCapture:"vanira_kyc_selfie_capture",KycSignatureCapture:"vanira_kyc_signature_capture"},se=Object.values(c),oe=new Set(se);function $(i){return!!i&&oe.has(i)}function Z(i){if(typeof i=="string")try{return JSON.parse(i)}catch{return{}}return i&&typeof i=="object"?i:{}}const j={type_on_whiteboard:c.TypeText,write_on_whiteboard:c.TypeText,write_on_white_board:c.TypeText,dom_typing_simulation:c.TypeText,write_latex_text:c.WriteLatexText,write_latex_on_board:c.WriteLatexText,latex_on_whiteboard:c.WriteLatexText,show_geogebra:c.GeoGebra,geogebra_diagram:c.GeoGebra,geogebra:c.GeoGebra,erase_text:c.EraseText,dom_erase:c.EraseText,open_live_camera:c.LiveVision,live_vision:c.LiveVision,close_live_camera:c.CloseLiveCamera,stop_live_camera:c.CloseLiveCamera,open_live_screen:c.LiveScreen,close_live_screen:c.CloseLiveScreen,screen_vision:c.ScreenVision,capture_screen_vision:c.ScreenVision,capture_screen:c.ScreenVision,tab_screenshot:c.ScreenVision,capture_tab:c.ScreenVision,capture_tab_screenshot:c.ScreenVision,screenshot_tab:c.ScreenVision,point_at:c.PointAt,point_at_screen:c.PointAt,draw_on_screen:c.DrawOnScreen,screen_draw:c.DrawOnScreen,clear_screen_draw:c.ClearScreenDraw,clear_screen_annotations:c.ClearScreenDraw,highlight_on_screen:c.HighlightOnScreen,highlight_element_on_screen:c.HighlightOnScreen,highlight_screen_element:c.HighlightOnScreen,kyc_document_capture:c.KycDocumentCapture,capture_id_document:c.KycDocumentCapture,document_capture:c.KycDocumentCapture,capture_kyc_document:c.KycDocumentCapture,kyc_selfie_capture:c.KycSelfieCapture,capture_selfie:c.KycSelfieCapture,selfie_capture:c.KycSelfieCapture,capture_kyc_selfie:c.KycSelfieCapture,kyc_signature_capture:c.KycSignatureCapture,capture_kyc_signature:c.KycSignatureCapture,signature_capture:c.KycSignatureCapture},G={vanira_tab_screenshot:c.ScreenVision,vanira_document_capture:c.KycDocumentCapture,vanira_selfie_capture:c.KycSelfieCapture,vanira_signature_capture:c.KycSignatureCapture,vanira_kyc_signature:c.KycSignatureCapture};function ce(i,e){const t=i.commands??(e==null?void 0:e.commands)??i.construction??(e==null?void 0:e.construction)??i.geogebra_commands??(e==null?void 0:e.geogebra_commands)??i.script??(e==null?void 0:e.script);return Array.isArray(t)?t.some(a=>String(a).trim().length>0):typeof t=="string"&&t.trim().length>0}function le(i,e){const t=i.material_id??(e==null?void 0:e.material_id)??i.materialId??(e==null?void 0:e.materialId);return typeof t=="string"&&t.trim().length>0}function de(i,e){const t=i.latex_text??(e==null?void 0:e.latex_text);return typeof t=="string"&&t.trim().length>0}function W(i,e){const t=i.text_to_type??(e==null?void 0:e.text_to_type)??i.text??(e==null?void 0:e.text)??i.value??(e==null?void 0:e.value);return typeof t=="string"&&t.trim().length>0}function he(i,e){const t=i.fields??(e==null?void 0:e.fields);return Array.isArray(t)?t.length>0:typeof t=="string"?t.split(",").map(a=>a.trim()).filter(Boolean).length>0:!1}function ue(i,e){const t=i==null?void 0:i.preset_id;if(typeof t=="string"){if($(t))return t;const r=G[t];if(r)return r}const n=Z(e).preset_id;if(typeof n=="string"){if($(n))return n;const r=G[n];if(r)return r}}function pe(i,e,t){const a=Z(e);let n=ue(i,a);if(n===c.Form&&W(a,i)&&!he(a,i))return c.TypeText;if(n)return n;const r=String(t??"").trim().toLowerCase();if(r&&j[r])return j[r];if(ce(a,i)||le(a,i))return c.GeoGebra;if(de(a,i))return c.WriteLatexText;if(W(a,i))return c.TypeText}const T="vanira_latest_call_id",R="vanira_prospect_id";function b(i){return`vanira_latest_call_id_${i}`}function x(i){return`vanira_prospect_id_${i}`}function Q(i){return`vanira_call_meta_${i}`}function S(i,e){if(!i)return null;try{return i.getItem(e)}catch{return null}}function H(i){if(typeof window>"u"||!i)return null;const e=[],t=S(window.localStorage,Q(i));if(t)try{const h=JSON.parse(t);h!=null&&h.callId&&e.push({callId:h.callId,prospectId:h.prospectId,updatedAt:h.updatedAt||0})}catch{}const a=(h,_,s)=>{h&&e.push({callId:h,prospectId:_||void 0,updatedAt:s})},n=S(window.localStorage,x(i)),r=S(window.sessionStorage,x(i)),o=S(window.localStorage,R);return a(S(window.localStorage,b(i)),n||o,2),a(S(window.sessionStorage,b(i)),r||o,1),a(S(window.localStorage,T),o,0),a(S(window.sessionStorage,T),o,0),e.length?(e.sort((h,_)=>_.updatedAt-h.updatedAt),e[0]):null}function _e(i,e,t){var n,r,o,h,_,s,u,l,p;if(typeof window>"u"||!i||!e)return;const a={callId:e,prospectId:t,updatedAt:Date.now()};try{(n=window.localStorage)==null||n.setItem(Q(i),JSON.stringify(a)),(r=window.localStorage)==null||r.setItem(b(i),e),(o=window.sessionStorage)==null||o.setItem(b(i),e),t&&((h=window.localStorage)==null||h.setItem(x(i),t),(_=window.sessionStorage)==null||_.setItem(x(i),t)),(s=window.localStorage)==null||s.setItem(T,e),(u=window.sessionStorage)==null||u.setItem(T,e),t&&((l=window.localStorage)==null||l.setItem(R,t),(p=window.sessionStorage)==null||p.setItem(R,t))}catch{}}const me=new Set(["client_tool_call","clearAudio","client_tool_cancel"]);function fe(i){if(!i||typeof i!="object")return!1;const e=i.event;return typeof e=="string"&&me.has(e)}const E=16*1024,ye=256*1024;function k(i,e){return(i==null?void 0:i.readyState)==="open"&&(e==null?void 0:e.readyState)==="open"}function Se(i,e){return{control:(i==null?void 0:i.readyState)??"missing",mediaBytes:(e==null?void 0:e.readyState)??"missing"}}async function we(i,e,t=8e3){if(k(i,e))return!0;const a=Date.now()+t;for(;Date.now()<a;){if(k(i,e))return!0;await new Promise(n=>setTimeout(n,50))}return k(i,e)}async function J(i){for(;i.bufferedAmount>ye;)await new Promise(e=>setTimeout(e,10))}async function ge(i){const{bytes:e,filename:t,contentType:a,reason:n,message:r,callId:o,mediaBytesChannel:h,sendControlEvent:_,uploadId:s=crypto.randomUUID(),uploadKind:u="media"}=i,l=e.byteLength,p=l===0?0:Math.ceil(l/E);_("client_media_upload_start",{data:{upload_id:s,call_id:o,reason:n,message:r,filename:t,content_type:a,size:l,chunk_count:p,upload_kind:u}});const m=new Uint8Array(e);for(let f=0;f<l;f+=E){await J(h);const w=Math.min(f+E,l);h.send(m.subarray(f,w))}return await J(h),_("client_media_upload_complete",{data:{upload_id:s,call_id:o,reason:n,message:r,chunk_count:p,upload_kind:u}}),{media_id:s,url:"",content_type:a}}async function ve(i){return typeof i.arrayBuffer=="function"?i.arrayBuffer():new Response(i).arrayBuffer()}const Ce=15e3,A="vanira-connect-stall-prompt";let C=null;function Ie(i=Ce){typeof window>"u"||(v(!1),C=setTimeout(()=>{C=null,Te(),window.dispatchEvent(new CustomEvent("vanira:connect-stall"))},i))}function v(i=!0){C!==null&&(clearTimeout(C),C=null),i&&P()}function P(){var i;typeof document>"u"||(i=document.getElementById(A))==null||i.remove()}function Te(){var t,a;if(typeof document>"u"||document.getElementById(A))return;const i=document.createElement("div");i.id=A,i.setAttribute("role","alertdialog"),i.setAttribute("aria-modal","true"),i.setAttribute("aria-labelledby","vanira-stall-title"),i.style.cssText=["position:fixed","inset:0","z-index:2147483646","display:flex","align-items:center","justify-content:center","padding:24px","background:rgba(0,0,0,0.55)","font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif"].join(";");const e=document.createElement("div");e.style.cssText=["max-width:400px","width:100%","padding:24px","border-radius:16px","background:#fff","box-shadow:0 20px 60px rgba(0,0,0,0.25)","color:#111"].join(";"),e.innerHTML=`
2
+ <h2 id="vanira-stall-title" style="margin:0 0 12px;font-size:18px;font-weight:600">Browser is blocking the connection</h2>
3
+ <p style="margin:0 0 20px;font-size:14px;line-height:1.5;color:#444">
4
+ The call is still connecting. Please <strong>hard refresh</strong> your browser to reconnect.
5
+ </p>
6
+ <div style="display:flex;gap:12px;flex-wrap:wrap">
7
+ <button type="button" id="vanira-stall-refresh" style="flex:1;min-width:140px;padding:10px 16px;border:none;border-radius:8px;background:#111;color:#fff;font-size:14px;font-weight:600;cursor:pointer">
8
+ Hard refresh
9
+ </button>
10
+ <button type="button" id="vanira-stall-dismiss" style="flex:1;min-width:100px;padding:10px 16px;border:1px solid #ddd;border-radius:8px;background:#fff;color:#333;font-size:14px;cursor:pointer">
11
+ Dismiss
12
+ </button>
13
+ </div>
14
+ <p style="margin:12px 0 0;font-size:12px;color:#888">
15
+ Tip: Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac)
16
+ </p>
17
+ `,i.appendChild(e),document.body.appendChild(i),(t=e.querySelector("#vanira-stall-refresh"))==null||t.addEventListener("click",()=>{P(),window.location.reload()}),(a=e.querySelector("#vanira-stall-dismiss"))==null||a.addEventListener("click",()=>P())}function be(i){return null}function I(){return typeof window>"u"?"/":`${window.location.pathname}${window.location.search}${window.location.hash}`||"/"}class xe{constructor(e){d(this,"active",!1);d(this,"initialSent",!1);d(this,"lastRoute","");d(this,"sendContext");d(this,"isReady");d(this,"cleanupFns",[]);d(this,"initialRetryTimer",null);d(this,"routePollTimer",null);d(this,"originalPushState",null);d(this,"originalReplaceState",null);this.sendContext=e.sendContext,this.isReady=e.isReady??(()=>!0)}start(){typeof window>"u"||this.active||(this.active=!0,this.initialSent=!1,this.lastRoute=I(),this.attachListeners(),this.scheduleInitialContextSend())}stop(){if(!(!this.active&&this.cleanupFns.length===0)){this.active=!1,this.initialSent=!1,this.initialRetryTimer!==null&&(clearTimeout(this.initialRetryTimer),this.initialRetryTimer=null),this.routePollTimer!==null&&(clearInterval(this.routePollTimer),this.routePollTimer=null);for(const e of this.cleanupFns)try{e()}catch{}this.cleanupFns.length=0,this.originalPushState&&(history.pushState=this.originalPushState,this.originalPushState=null),this.originalReplaceState&&(history.replaceState=this.originalReplaceState,this.originalReplaceState=null)}}onChannelReady(){this.scheduleInitialContextSend()}scheduleInitialContextSend(e=0){if(!(!this.active||this.initialSent)){if(this.isReady()){this.sendRouteContext("call_started"),this.initialSent=!0;return}e>=30||(this.initialRetryTimer=window.setTimeout(()=>this.scheduleInitialContextSend(e+1),100))}}attachListeners(){const e=(r,o=0)=>{const h=()=>{const _=I();_!==this.lastRoute&&this.handleRouteChange(_,r)};o>0?window.setTimeout(h,o):queueMicrotask(h)},t=()=>e("popstate"),a=()=>e("hashchange"),n=r=>{const o=r.detail;if((o==null?void 0:o.initiated_by)==="agent"){e("vanira_navigate_agent",120);return}e("vanira_navigate",120)};window.addEventListener("popstate",t),window.addEventListener("hashchange",a),window.addEventListener("vanira:navigate",n),this.cleanupFns.push(()=>window.removeEventListener("popstate",t),()=>window.removeEventListener("hashchange",a),()=>window.removeEventListener("vanira:navigate",n)),this.originalPushState=history.pushState.bind(history),this.originalReplaceState=history.replaceState.bind(history),history.pushState=(...r)=>{this.originalPushState(...r),e("pushState")},history.replaceState=(...r)=>{this.originalReplaceState(...r),e("replaceState")},this.routePollTimer=window.setInterval(()=>{if(!this.active)return;const r=I();r!==this.lastRoute&&this.handleRouteChange(r,"location_poll")},1e3)}handleRouteChange(e,t){if(!this.active)return;const a=this.lastRoute;if(a===e)return;if(this.lastRoute=e,!this.initialSent){this.scheduleInitialContextSend();return}!this.isReady()||be()||this.sendRouteContext("route_changed",a,t,"user")}sendRouteContext(e,t,a,n="user"){const r=I();this.lastRoute=r;const o={ui_state:"page_navigation",navigation_led_by:n,current_route:r,current_page:r,user_action:e==="call_started"?"call_started_on_page":"user_navigated"};e==="call_started"?o.message=`User started the call while viewing ${r}.`:(o.previous_route=t??"",o.message=`User navigated from ${t||"(unknown)"} to ${r}.`,a&&(o.navigation_source=a));try{this.sendContext(o)}catch{}}}const y=class y{constructor(e){d(this,"serverUrl");d(this,"agentId");d(this,"callId");d(this,"prospectId");d(this,"apiKey");d(this,"backendUrl");d(this,"token");d(this,"prospectName");d(this,"welcomeMessage");d(this,"extraDetails");d(this,"onConnected");d(this,"onDisconnected");d(this,"onError");d(this,"onTranscription");d(this,"onLocalStream");d(this,"onRemoteTrack");d(this,"onClientToolCall");d(this,"onSessionStarted");d(this,"sessionStartedEmitted",!1);d(this,"pc",null);d(this,"dataChannel",null);d(this,"mediaBytesChannel",null);d(this,"audioElement",null);d(this,"localStream",null);d(this,"micMuted",!1);d(this,"connected",!1);d(this,"appliedRemoteCandidates",new Set);d(this,"remoteDescSet",!1);d(this,"pendingServerIce",[]);d(this,"icePollStop",!1);d(this,"iceServers");d(this,"callSessionLoaded",!1);d(this,"connectGeneration",0);d(this,"runtime");d(this,"sessionBehavior");d(this,"routeTracker",null);d(this,"_status","idle");d(this,"listeners",new Map);d(this,"liveVision");d(this,"liveVisionAutoStarted",!1);d(this,"connectStallTimeoutMs");var _;if(!e.agentId)throw new Error("agentId is required");const t=!!(e.apiKey||e.token),a=!!(e.serverUrl&&e.callId),n=y.normalizeIceServers(e.iceServers);if(!t&&!a)throw new Error("apiKey or token is required — or pass serverUrl and callId from a prior POST /calls/create");this.agentId=e.agentId,this.sessionBehavior=e.sessionBehavior,this.serverUrl=(e.serverUrl||"").replace(/\/$/,""),this.apiKey=e.apiKey,this.token=e.token,this.prospectName=e.prospectName,this.welcomeMessage=((_=e.welcomeMessage)==null?void 0:_.trim())||void 0,this.extraDetails=e.extraDetails,this.backendUrl=(e.backendUrl||re).replace(/\/$/,""),n.length&&(this.iceServers=n),a&&(this.callSessionLoaded=!0);const r=typeof window<"u";this.prospectId=e.prospectId;const o=e.sessionBehavior==="continue";if(o&&r&&!e.callId){const s=H(this.agentId);s&&(e.callId||(this.callId=s.callId),!this.prospectId&&s.prospectId&&(this.prospectId=s.prospectId))}if(!this.prospectId&&r)try{const s=H(this.agentId);this.prospectId=(s==null?void 0:s.prospectId)||window.sessionStorage&&window.sessionStorage.getItem("vanira_prospect_id")||window.localStorage&&window.localStorage.getItem("vanira_prospect_id")||void 0}catch{}e.callId?this.callId=e.callId:o||(this.callId=void 0);const h=e.onSessionStarted;this.onSessionStarted=s=>{h==null||h(s),this.emit("session_started",s)},this.liveVision=e.liveVision,this.connectStallTimeoutMs=e.connectStallTimeoutMs??15e3,this.onConnected=()=>{var s;v(),this._status="connected",(s=e.onConnected)==null||s.call(e),this.emit("connected"),this.maybeAutoStartLiveCamera()},this.onDisconnected=()=>{var s;v(),this._status="disconnected",(s=e.onDisconnected)==null||s.call(e),this.emit("disconnected")},this.onError=s=>{var l;v(),this._status="error";const u=typeof s=="string"?s:(s==null?void 0:s.message)||"Connection error";(l=e.onError)==null||l.call(e,s),this.emit("error",u)},this.onTranscription=(s,u,l)=>{var p;(p=e.onTranscription)==null||p.call(e,s,u),this.emit("transcription",{text:s,isFinal:u,role:l})},this.onLocalStream=e.onLocalStream||(()=>{}),this.onRemoteTrack=(s,u)=>{var l;(l=e.onRemoteTrack)==null||l.call(e,s,u),this.emit("track",{track:s,stream:u})},this.onClientToolCall=s=>{var p;(p=e.onClientToolCall)==null||p.call(e,s);const u=(s==null?void 0:s.data)||s,l={name:String(u.name||u.tool_name||""),arguments:u.arguments||u.args||{},tool_call_id:String(u.tool_call_id||u.call_id||""),execution_mode:u.execution_mode==="blocking"?"blocking":"fire_and_forget",client_fields:u.client_fields||{}};l.name&&l.tool_call_id&&this.emit("tool_call",l)},this.runtime=e.runtime,typeof window<"u"&&e.trackRouteContext!==!1&&(this.routeTracker=new xe({sendContext:s=>this.sendContextUpdate(s),isReady:()=>{var s;return((s=this.dataChannel)==null?void 0:s.readyState)==="open"}}))}async createCall(){return this.connect()}async connect(){var t;this._status="connecting",this.connectStallTimeoutMs>0&&Ie(this.connectStallTimeoutMs);const e=++this.connectGeneration;if(await this.loadCallSession(),!this.isConnectCancelled(e)){if(!this.serverUrl)throw new Error("[VaniraClient] worker_url missing from /calls/create");if(!this.callId)throw new Error("[VaniraClient] call_id missing — must come from POST /calls/create");if(this.onSessionStarted&&this.prospectId&&this.callId&&!this.sessionStartedEmitted)try{this.onSessionStarted({prospectId:this.prospectId,callId:this.callId,serverUrl:this.serverUrl}),this.sessionStartedEmitted=!0}catch{}try{this.appliedRemoteCandidates.clear(),this.remoteDescSet=!1,this.pendingServerIce=[],this.icePollStop=!1,this.stopRemoteIcePolling();const a=this.getIceServers();this.pc=new RTCPeerConnection({iceServers:a,iceTransportPolicy:"all"});let n;try{n=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,sampleRate:{ideal:16e3},channelCount:1}})}catch(l){if(l.name==="NotAllowedError"||l.name==="PermissionDeniedError"||(t=l.message)!=null&&t.includes("Permission denied")){const p=navigator.userAgent,m=/iPad|iPhone|iPod/.test(p)||navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1;let f="Microphone access denied. Please allow microphone access in your browser settings.";m&&(p.includes("CriOS")?f="Microphone access blocked. Please enable it in iOS Settings > Chrome > Microphone, then reload the page.":p.includes("FxiOS")?f="Microphone access blocked. Please enable it in iOS Settings > Firefox > Microphone, then reload the page.":f="Microphone access blocked. Please enable it in iOS Settings > Safari > Microphone (or tap 'aA' > Website Settings > Allow Microphone).");const w=new Error(f);throw w.name=l.name,w}throw l}if(this.isConnectCancelled(e)){n.getTracks().forEach(l=>l.stop());return}if(this.localStream=n,!this.pc||this.isConnectCancelled(e)){n.getTracks().forEach(l=>l.stop());return}if(this.onLocalStream(n),n.getTracks().forEach(l=>{var p;(p=this.pc)==null||p.addTrack(l,n)}),!this.pc)throw new Error("RTCPeerConnection was closed unexpectedly");this.dataChannel=this.pc.createDataChannel("control"),this.dataChannel.onopen=()=>{var l;(l=this.routeTracker)==null||l.onChannelReady()},this.dataChannel.onmessage=l=>{if(typeof l.data=="string")try{this.handleControlEvent(JSON.parse(l.data))}catch{}else if(l.data instanceof ArrayBuffer)try{const p=new TextDecoder().decode(l.data);try{const m=JSON.parse(p);fe(m)&&this.handleControlEvent(m)}catch{}}catch{}else l.data instanceof Blob&&l.data.text().then(p=>{try{this.handleControlEvent(JSON.parse(p))}catch{}})},this.dataChannel.onerror=l=>{},this.mediaBytesChannel=this.pc.createDataChannel("media-bytes",{ordered:!0}),this.mediaBytesChannel.binaryType="arraybuffer",this.mediaBytesChannel.onopen=()=>{},this.mediaBytesChannel.onerror=l=>{},this.pc.ontrack=l=>{const p=l.track,m=l.streams[0];p.kind==="audio"?(this.audioElement=new Audio,this.audioElement.srcObject=m,this.audioElement.play().catch(f=>{}),this.audioElement.onended=()=>{this.sendEvent("playedStream"),typeof window<"u"&&window.dispatchEvent(new CustomEvent("vanira:agent-playback-ended"))},this.onRemoteTrack(p,m)):p.kind==="video"&&this.onRemoteTrack(p,m)};const r=()=>{var m,f,w,M,L,D,O,N,V,B,K;const l=((m=this.pc)==null?void 0:m.connectionState)==="connected"||((f=this.pc)==null?void 0:f.iceConnectionState)==="connected"||((w=this.pc)==null?void 0:w.iceConnectionState)==="completed",p=((M=this.pc)==null?void 0:M.connectionState)==="failed"||((L=this.pc)==null?void 0:L.iceConnectionState)==="failed"||((D=this.pc)==null?void 0:D.connectionState)==="closed"||((O=this.pc)==null?void 0:O.iceConnectionState)==="closed"||((N=this.pc)==null?void 0:N.connectionState)==="disconnected"||((V=this.pc)==null?void 0:V.iceConnectionState)==="disconnected";((B=this.pc)==null?void 0:B.connectionState)==="connected"&&this.stopRemoteIcePolling(),l&&!this.connected?(this.connected=!0,(K=this.routeTracker)==null||K.start(),this.onConnected()):p&&this.connected&&(this.connected=!1,this.liveVisionAutoStarted=!1,this.onDisconnected())};this.pc.onconnectionstatechange=r,this.pc.oniceconnectionstatechange=r;const o=this.getIceTrickleUrl();this.pc.onicecandidate=l=>{l.candidate&&this.sendRemoteIceCandidate(l.candidate,o)};const h=await this.pc.createOffer();if(this.isConnectCancelled(e)||(await this.pc.setLocalDescription(h),this.isConnectCancelled(e)))return;const _=this.serverUrl.includes("?")?this.serverUrl:`${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`,s=await fetch(_,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({offer:this.pc.localDescription,agentId:this.agentId,callId:this.callId})});if(this.isConnectCancelled(e))return;if(!s.ok){const l=await s.json();throw new Error(l.error||`HTTP ${s.status}`)}const{answer:u}=await s.json();if(this.isConnectCancelled(e)||!this.pc||(await this.pc.setRemoteDescription(u),this.isConnectCancelled(e))||(this.remoteDescSet=!0,await this.flushPendingServerIce(),this.isConnectCancelled(e)))return;this.startRemoteIcePolling(o)}catch(a){if(this.isConnectCancelled(e))return;throw this.disconnect(),this.onError(a.message||a),a}}}createCallCacheKey(e,t){const a=this.apiKey?`key:${this.apiKey.slice(0,16)}`:`token:${(this.token||"").slice(-16)}`;return[this.backendUrl,this.agentId,e,t||"",this.prospectId||"",a].join("|")}async postCreateCall(e,t,a){var h,_,s;const n=await fetch(`${this.backendUrl}/calls/create`,{method:"POST",headers:e,body:JSON.stringify({agent_id:this.agentId,type:((h=this.runtime)==null?void 0:h.callType)||"web",mode:t,...(_=this.runtime)!=null&&_.runtimeName?{runtime:this.runtime.runtimeName}:{},prospect_id:this.prospectId,...this.prospectName?{prospect_name:this.prospectName}:{},...this.welcomeMessage?{welcome_message:this.welcomeMessage}:{},...this.extraDetails&&Object.keys(this.extraDetails).length?{extra_details:this.extraDetails}:{},...a?{call_id:a}:{}})});if(!n.ok){const u=await n.json().catch(()=>({}));throw new Error(`[VaniraClient] createCall failed (${n.status}): ${((s=u==null?void 0:u.detail)==null?void 0:s.message)||(u==null?void 0:u.message)||n.statusText}`)}const r=await n.json();if(!r.call_id||!r.worker_url)throw new Error("[VaniraClient] /calls/create response missing call_id or worker_url");const o=y.normalizeIceServers(r.ice_servers);if(!o.length)throw new Error("[VaniraClient] /calls/create response missing ice_servers");return{callId:r.call_id,prospectId:r.prospect_id||this.prospectId,serverUrl:r.worker_url.replace(/\/$/,""),iceServers:o}}applyCreateCallSession(e){if(this.callId=e.callId,this.prospectId=e.prospectId||this.prospectId,this.serverUrl=e.serverUrl,this.iceServers=e.iceServers,this.callSessionLoaded=!0,_e(this.agentId,this.callId||"",this.prospectId),this.onSessionStarted&&this.prospectId&&this.callId&&!this.sessionStartedEmitted)try{this.onSessionStarted({prospectId:this.prospectId,callId:this.callId,serverUrl:this.serverUrl}),this.sessionStartedEmitted=!0}catch{}}async loadCallSession(){if(this.callSessionLoaded)return;if(this.serverUrl&&this.callId){this.callSessionLoaded=!0;return}if(!this.apiKey&&!this.token)throw new Error("[VaniraClient] apiKey or token is required to create a call session");const e={"Content-Type":"application/json"};this.apiKey?e["X-API-Key"]=this.apiKey:this.token&&(e.Authorization=this.token.startsWith("Bearer ")?this.token:`Bearer ${this.token}`);const t=this.sessionBehavior==="continue"?this.callId:void 0,a=this.sessionBehavior==="continue"?"continue":"new",n=this.createCallCacheKey(a,t);let r=y.inflightCreates.get(n);r||(r=this.postCreateCall(e,a,t),y.inflightCreates.set(n,r),r.finally(()=>{y.inflightCreates.get(n)===r&&y.inflightCreates.delete(n)}));const o=await r;this.applyCreateCallSession(o)}getIceServers(){var e;if((e=this.iceServers)!=null&&e.length)return this.iceServers;throw new Error("[VaniraClient] ice_servers missing — pass iceServers from POST /calls/create")}static normalizeIceServers(e){if(!Array.isArray(e))return[];const t=[];for(const a of e){const n=a==null?void 0:a.urls,r=Array.isArray(n)?n.filter(Boolean):typeof n=="string"&&n.trim()?[n.trim()]:[];if(!r.length)continue;const o={urls:r.length===1?r[0]:r},h=a.username,_=a.credential;h&&(o.username=h),_&&(o.credential=_),t.push(o)}return t}getWorkerOrigin(){var e;if(!((e=this.serverUrl)!=null&&e.trim()))return"";try{return new URL(this.serverUrl).origin}catch{return this.serverUrl.replace(/\/webrtc.*$/,"").replace(/\/$/,"")}}getIceTrickleUrl(){try{const e=new URL(this.serverUrl);return e.pathname.endsWith("/webrtc")?e.pathname=`${e.pathname}/ice`:e.pathname="/webrtc/ice",e.toString()}catch{return`${this.getWorkerOrigin()}/webrtc/ice?agent_id=${this.agentId}&call_id=${this.callId}`}}async sendRemoteIceCandidate(e,t){try{const a=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({candidate:e.toJSON()})});if(a.ok){const n=await a.json();await this.applyServerIceCandidates(n.candidates)}}catch{}}async applyServerIceCandidates(e){if(!(!this.pc||!(e!=null&&e.length))){if(!this.remoteDescSet){this.pendingServerIce.push(...e);return}for(const t of e){const a=JSON.stringify(t);if(!this.appliedRemoteCandidates.has(a)){this.appliedRemoteCandidates.add(a);try{await this.pc.addIceCandidate(t)}catch{}}}}}async flushPendingServerIce(){if(!this.pc||!this.remoteDescSet||this.pendingServerIce.length===0)return;const e=this.pendingServerIce;this.pendingServerIce=[];for(const t of e){const a=JSON.stringify(t);if(!this.appliedRemoteCandidates.has(a)){this.appliedRemoteCandidates.add(a);try{await this.pc.addIceCandidate(t)}catch{}}}}startRemoteIcePolling(e){this.icePollStop=!1,this.pollServerIce(e)}async pollServerIce(e){var a;const t=Date.now()+15e3;for(;!this.icePollStop&&Date.now()<t;){const n=(a=this.pc)==null?void 0:a.connectionState;if(n==="connected"||n==="failed"||n==="closed")break;try{const r=await fetch(e,{method:"GET"});if(r.ok){const o=await r.json();if(await this.applyServerIceCandidates(o.candidates),o.done&&(!o.candidates||o.candidates.length===0))break}}catch{}await new Promise(r=>setTimeout(r,150))}}stopRemoteIcePolling(){this.icePollStop=!0}sendEvent(e,t={}){var a;if(((a=this.dataChannel)==null?void 0:a.readyState)==="open"){const n={event:e,...t};this.dataChannel.send(JSON.stringify(n))}}async sendEventWhenReady(e,t={},a=1e4){var r;const n=Date.now()+a;for(;Date.now()<n;){if(((r=this.dataChannel)==null?void 0:r.readyState)==="open")return this.sendEvent(e,t),!0;await new Promise(o=>setTimeout(o,50))}return!1}startLiveCamera(e={}){const t={...this.liveVision,...e};this.emit("tool_call",this.buildOpenLiveCameraToolCall(t))}buildOpenLiveCameraToolCall(e={}){const t=e.scope??"until_call_end";return{name:"open_live_camera",tool_call_id:`lv_${crypto.randomUUID()}`,execution_mode:"fire_and_forget",client_fields:{preset_id:c.LiveVision},arguments:{mode:"live",scope:t,target_fps:e.target_fps??1,max_fps:e.max_fps??3,max_width:e.max_width??640,reason:e.reason??"camera_capture",facing_mode:e.facing_mode??"environment",show_preview:e.show_preview??!0,...t==="timed"&&e.duration_sec?{duration_sec:e.duration_sec}:{}}}}maybeAutoStartLiveCamera(){const e=this.liveVision;!(e!=null&&e.enabled)||e.scope!=="full_call"||this.liveVisionAutoStarted||(this.liveVisionAutoStarted=!0,this.emit("tool_call",this.buildOpenLiveCameraToolCall(e)))}handleControlEvent(e){var t;switch(e.event){case"clearAudio":this.dispatchBoardAbort("User interrupted while LaTeX was writing",void 0,c.WriteLatexText);break;case"transcription":{const a=e.data&&typeof e.data=="object"?e.data:{},n=String(e.text??a.text??"").trim(),r=e.isFinal??e.is_final??a.isFinal??a.is_final,o=r===void 0?!0:r===!0||r==="true",h=String(e.role??e.speaker??a.role??a.speaker??"").trim()||void 0;n&&this.onTranscription(n,o,h)}break;case"mark":break;case"client_tool_cancel":{const n=(e.data||e).tool_call_id||e.tool_call_id;this.dispatchBoardAbort("Tool cancelled by server",n);break}case"client_tool_call":{const a=e.tool_call||e.data||e,n=(a==null?void 0:a.tool_call_id)||(a==null?void 0:a.call_id)||e.tool_call_id||"";n&&((t=this.dataChannel)==null?void 0:t.readyState)==="open"&&this.dataChannel.send(JSON.stringify({event:"client_tool_ack",data:{tool_call_id:n}}));const r=(a==null?void 0:a.arguments)||(a==null?void 0:a.args)||{},o=(a==null?void 0:a.client_fields)||{},h=(a==null?void 0:a.name)||(a==null?void 0:a.tool_name)||"",_=pe(o,r,h);if(h==="end_call"){n&&this.sendToolResult(n,{status:"client_ack_end_call",message:"Ending call."}),window.setTimeout(()=>this.disconnect(),120);break}if(_){window.dispatchEvent(new CustomEvent("vanira:preset",{detail:{toolCall:a,client:this}})),this.onClientToolCall(a);break}this.onClientToolCall(a);break}}}disconnect(){var e;v(),this.connectGeneration++,this.stopRemoteIcePolling(),this.appliedRemoteCandidates.clear(),this.remoteDescSet=!1,this.pendingServerIce=[],this.audioElement&&(this.audioElement.pause(),this.audioElement.srcObject=null),this.dataChannel&&(this.dataChannel.close(),this.dataChannel=null),this.mediaBytesChannel&&(this.mediaBytesChannel.close(),this.mediaBytesChannel=null),this.pc&&(this.pc.getSenders().forEach(t=>{t.track&&t.track.stop()}),this.pc.close(),this.pc=null),this.localStream&&(this.localStream.getTracks().forEach(t=>{try{t.stop()}catch{}}),this.localStream=null),this.connected=!1,(e=this.routeTracker)==null||e.stop(),this.callSessionLoaded=!1,this.sessionStartedEmitted=!1,this.serverUrl="",this.callId=void 0,this.micMuted=!1,this.iceServers=void 0,this.onDisconnected()}setMicrophoneMuted(e){var t,a;this.micMuted=e,(t=this.localStream)==null||t.getAudioTracks().forEach(n=>{n.enabled=!e}),(a=this.pc)==null||a.getSenders().forEach(n=>{var r;((r=n.track)==null?void 0:r.kind)==="audio"&&(n.track.enabled=!e)})}isMicrophoneMuted(){return this.micMuted}toggleMicrophoneMuted(){return this.setMicrophoneMuted(!this.micMuted),this.micMuted}isConnectCancelled(e){return e!==this.connectGeneration}dispatchBoardAbort(e,t,a){typeof window>"u"||window.dispatchEvent(new CustomEvent("vanira:board_abort",{detail:{reason:e,toolCallId:t,presetId:a}}))}sendToolResult(e,t){this.callId,this.sendEvent("client_tool_result",{call_id:this.callId,data:{tool_call_id:e,result:t},result:t}),this.emit("tool_result",{toolCallId:e,result:t})}sendToolAck(e){var t;((t=this.dataChannel)==null?void 0:t.readyState)==="open"&&this.dataChannel.send(JSON.stringify({event:"client_tool_ack",data:{tool_call_id:e}}))}sendContextUpdate(e){this.sendEvent("client_context_update",{data:{context:e}})}sendActionTrigger(e,t={}){this.sendEvent("client_action_trigger",{data:{action_name:e,data:t}})}triggerActionInterrupt(){this.sendEvent("action_interrupt")}sendMediaUpdate(e){if(!this.dataChannel||this.dataChannel.readyState!=="open")return!1;const t={event:"client_media_update",data:{media_id:e.media_id,media_url:e.media_url,content_type:e.content_type,reason:e.reason,message:e.message??""}};return this.dataChannel.send(JSON.stringify(t)),!0}async uploadMediaForToolResult(e,t="general"){return this._postMediaUpload(e,t)}async uploadMedia(e,t="general",a=""){return await we(this.dataChannel,this.mediaBytesChannel)?this._uploadMediaViaDataChannel(e,t,a):(Se(this.dataChannel,this.mediaBytesChannel),this._uploadMediaViaHTTP(e,t,a))}async uploadMediaFrame(e,t="camera_capture",a){const n=a&&!(e instanceof File)?new File([e],a,{type:e.type||"image/jpeg"}):e,{media_id:r,url:o,contentType:h}=await this._postMediaUpload(n,t,!0);if(!r||!o)throw new Error("Frame upload failed: server response missing media_id or url");return{media_id:r,url:o,content_type:h}}async _uploadBytesViaDataChannel(e,t,a,n,r){if(!this.callId||!this.mediaBytesChannel)throw new Error("Upload failed: call not ready for WebRTC media upload.");const o=r||(e instanceof File?e.name:n==="frame"?"frame.jpg":"upload.bin"),h=e.type||(n==="frame"?"image/jpeg":"application/octet-stream"),_=await ve(e);return ge({bytes:_,filename:o,contentType:h,reason:t,message:a,callId:this.callId,mediaBytesChannel:this.mediaBytesChannel,sendControlEvent:(s,u)=>this.sendEvent(s,u),uploadKind:n})}async _uploadMediaViaDataChannel(e,t,a){const n=await this._uploadBytesViaDataChannel(e,t,a,"media");return{media_id:n.media_id,url:n.url}}async _uploadMediaViaHTTP(e,t="general",a=""){const{media_id:n,url:r,contentType:o}=await this._postMediaUpload(e,t,!0);return this.sendMediaUpdate({media_id:n,media_url:r,content_type:o,reason:t,message:a}),{media_id:n,url:r}}async _postMediaUpload(e,t,a=!1){if(!this.serverUrl)throw new Error("Upload failed: serverUrl is not set. Connect the VaniraClient first.");if(!this.callId)throw new Error("Upload failed: callId is missing.");const n=this.getWorkerOrigin();if(!n)throw new Error("Upload failed: worker_url is not set. Connect the call before uploading media.");const r=`${n}/media/upload`,o=new FormData;o.append("file",e),o.append("call_id",this.callId),o.append("reason",t);const h=await fetch(r,{method:"POST",body:o});if(!h.ok){let p=`HTTP ${h.status}`;try{p=(await h.json()).error||p}catch{}throw new Error(`Upload failed: ${p}`)}const _=await h.json(),s=_.media_id,u=_.url,l=_.content_type||e.type;if(!s||!u)throw new Error("Upload failed: server response missing media_id or url");return a?{media_id:s,url:u,contentType:l}:{media_id:s,url:u,contentType:l}}get status(){return this._status}get isConnected(){return this._status==="connected"}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),this}off(e,t){var a;return(a=this.listeners.get(e))==null||a.delete(t),this}emit(e,t){var a;(a=this.listeners.get(e))==null||a.forEach(n=>n(t))}async start(){return await this.connect(),{callId:this.callId||"",prospectId:this.prospectId||"",serverUrl:this.serverUrl||""}}stop(){this.disconnect(),this._status="disconnected"}sendToolError(e,t){this.sendToolResult(e,{status:"error",error:t})}updateContext(e){this.sendContextUpdate(e)}triggerInterrupt(e,t={}){this.triggerActionInterrupt(),this.sendActionTrigger(e,t)}interruptAudioOnly(){this.triggerActionInterrupt()}};d(y,"inflightCreates",new Map);let g=y;const F={supportsAudioEndedEvent:!1,supportsScreenShare:!1,supportsDom:!1,supportsHtmlAudio:!1,supportsCustomElements:!1,supportsLocalStorage:!1,supportsBroadcastChannel:!1},ee={name:"react-native",callType:"web",runtimeName:"react-native",callIdPrefix:"rn_",capabilities:F,audio:new z,media:new Y,peer:new q,dataChannel:new X};function U(i){return new g({...i,runtime:ee})}const Ee=U;function te(i){return U(i)}const ke=te;exports.RNAudioAdapter=z;exports.RNDataChannelAdapter=X;exports.RNMediaAdapter=Y;exports.RNPeerAdapter=q;exports.VaniraAI=g;exports.VaniraClient=g;exports.WebRTCClient=g;exports.createReactNativeAI=Ee;exports.createReactNativeClient=U;exports.createVaniraAI=ke;exports.createVaniraClient=te;exports.reactNativeCapabilities=F;exports.reactNativeRuntime=ee;