@vanira/sdk 0.0.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -0
- package/dist/chunks/html2canvas.js +6 -0
- package/dist/headless/index.cjs +489 -0
- package/dist/headless/index.d.ts +30 -0
- package/dist/headless/index.js +6437 -0
- package/dist/index.d.ts +176 -0
- package/dist/platforms/browser.cjs +8 -0
- package/dist/platforms/browser.d.ts +26 -0
- package/dist/platforms/browser.js +1540 -0
- package/dist/platforms/react-native.cjs +1 -0
- package/dist/platforms/react-native.d.ts +6 -0
- package/dist/platforms/react-native.js +1185 -0
- package/dist/vanira-sdk.es.js +11475 -0
- package/dist/vanira-sdk.js +3031 -0
- package/dist/vanira-sdk.umd.js +3302 -0
- package/package.json +92 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var X=Object.defineProperty;var Z=(n,e,t)=>e in n?X(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var d=(n,e,t)=>Z(n,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class Q{pause(){}cleanup(){}onEnded(e){}}class j{createRemotePlayer(e){return new Q}}class J{async getUserAudio(e){return navigator.mediaDevices.getUserMedia({audio:e})}stopStream(e){e.getTracks().forEach(t=>t.stop())}}class G{create(e){return new globalThis.RTCPeerConnection({iceServers:e.iceServers,iceTransportPolicy:e.iceTransportPolicy??"all"})}}class W{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 a=new TextDecoder().decode(i.data),r=JSON.parse(a);(r==null?void 0:r.event)==="client_tool_call"&&t.onMessage({text:a})}catch{}return}},{send(i){e.readyState==="open"&&e.send(i)},isOpen(){return e.readyState==="open"},close(){e.close()}}}}const ee="https://api.vanira.io",h={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",EraseText:"vanira_erase_text",Draw:"vanira_draw",EraseDraw:"vanira_erase_draw",LiveVision:"vanira_live_vision",CloseLiveCamera:"vanira_close_live_camera",LiveScreen:"vanira_live_screen",CloseLiveScreen:"vanira_close_live_screen",ClipRegion:"vanira_clip_region",TabScreenshot:"vanira_tab_screenshot",ScreenInk:"vanira_screen_ink",ScreenCursor:"vanira_screen_cursor",ScreenClick:"vanira_screen_click",ClearScreenOverlay:"vanira_clear_screen_overlay",PageScan:"vanira_page_scan",PointAt:"vanira_point_at",OutlineTargets:"vanira_outline_targets",ClearGuide:"vanira_clear_guide"},te=Object.values(h),ie=new Set(te);function V(n){return!!n&&ie.has(n)}const ae=new Set([h.ScreenInk,h.ScreenCursor,h.ScreenClick,h.ClearScreenOverlay,h.PointAt,h.OutlineTargets,h.ClearGuide]);[...ae,h.PageScan,h.TabScreenshot];function H(n){if(typeof n=="string")try{return JSON.parse(n)}catch{return{}}return n&&typeof n=="object"?n:{}}const B={type_on_whiteboard:h.TypeText,write_on_whiteboard:h.TypeText,write_on_white_board:h.TypeText,dom_typing_simulation:h.TypeText,erase_text:h.EraseText,dom_erase:h.EraseText,draw_on_board:h.Draw,erase_drawing_board:h.EraseDraw,open_live_camera:h.LiveVision,live_vision:h.LiveVision,close_live_camera:h.CloseLiveCamera,stop_live_camera:h.CloseLiveCamera,open_live_screen:h.LiveScreen,close_live_screen:h.CloseLiveScreen,screen_ink:h.ScreenInk,screen_cursor:h.ScreenCursor,screen_click:h.ScreenClick,clear_screen_overlay:h.ClearScreenOverlay,tab_screenshot:h.TabScreenshot,capture_tab:h.TabScreenshot,capture_tab_screenshot:h.TabScreenshot,screenshot_tab:h.TabScreenshot,page_scan:h.PageScan,scan_page:h.PageScan,point_at:h.PointAt,outline_targets:h.OutlineTargets,outline_elements:h.OutlineTargets,clear_guide:h.ClearGuide};function D(n,e){const t=n.text_to_type??(e==null?void 0:e.text_to_type)??n.text??(e==null?void 0:e.text)??n.value??(e==null?void 0:e.value);return typeof t=="string"&&t.trim().length>0}function ne(n,e){const t=n.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 re(n,e){const t=n==null?void 0:n.preset_id;if(typeof t=="string"&&V(t))return t;const a=H(e).preset_id;if(typeof a=="string"&&V(a))return a}function se(n,e,t){const i=H(e);let a=re(n,i);if(a===h.Form&&D(i,n)&&!ne(i,n))return h.TypeText;if(a)return a;const r=String(t??"").trim().toLowerCase();if(r&&B[r])return B[r];if(D(i,n))return h.TypeText}const C="vanira_latest_call_id",k="vanira_prospect_id";function I(n){return`vanira_latest_call_id_${n}`}function T(n){return`vanira_prospect_id_${n}`}function z(n){return`vanira_call_meta_${n}`}function w(n,e){if(!n)return null;try{return n.getItem(e)}catch{return null}}function $(n){if(typeof window>"u"||!n)return null;const e=[],t=w(window.localStorage,z(n));if(t)try{const c=JSON.parse(t);c!=null&&c.callId&&e.push({callId:c.callId,prospectId:c.prospectId,updatedAt:c.updatedAt||0})}catch{}const i=(c,s,u)=>{c&&e.push({callId:c,prospectId:s||void 0,updatedAt:u})},a=w(window.localStorage,T(n)),r=w(window.sessionStorage,T(n)),o=w(window.localStorage,k);return i(w(window.localStorage,I(n)),a||o,2),i(w(window.sessionStorage,I(n)),r||o,1),i(w(window.localStorage,C),o,0),i(w(window.sessionStorage,C),o,0),e.length?(e.sort((c,s)=>s.updatedAt-c.updatedAt),e[0]):null}function oe(n,e,t){var a,r,o,c,s,u,p,l,_;if(typeof window>"u"||!n||!e)return;const i={callId:e,prospectId:t,updatedAt:Date.now()};try{(a=window.localStorage)==null||a.setItem(z(n),JSON.stringify(i)),(r=window.localStorage)==null||r.setItem(I(n),e),(o=window.sessionStorage)==null||o.setItem(I(n),e),t&&((c=window.localStorage)==null||c.setItem(T(n),t),(s=window.sessionStorage)==null||s.setItem(T(n),t)),(u=window.localStorage)==null||u.setItem(C,e),(p=window.sessionStorage)==null||p.setItem(C,e),t&&((l=window.localStorage)==null||l.setItem(k,t),(_=window.sessionStorage)==null||_.setItem(k,t))}catch{}}const ce=new Set(["client_tool_call","clearAudio","client_tool_cancel"]);function le(n){if(!n||typeof n!="object")return!1;const e=n.event;return typeof e=="string"&&ce.has(e)}const E=16*1024,de=256*1024;function R(n,e){return(n==null?void 0:n.readyState)==="open"&&(e==null?void 0:e.readyState)==="open"}function he(n,e){return{control:(n==null?void 0:n.readyState)??"missing",mediaBytes:(e==null?void 0:e.readyState)??"missing"}}async function ue(n,e,t=8e3){if(R(n,e))return!0;const i=Date.now()+t;for(;Date.now()<i;){if(R(n,e))return!0;await new Promise(a=>setTimeout(a,50))}return R(n,e)}async function K(n){for(;n.bufferedAmount>de;)await new Promise(e=>setTimeout(e,10))}async function pe(n){const{bytes:e,filename:t,contentType:i,reason:a,message:r,callId:o,mediaBytesChannel:c,sendControlEvent:s,uploadId:u=crypto.randomUUID(),uploadKind:p="media"}=n,l=e.byteLength,_=l===0?0:Math.ceil(l/E);s("client_media_upload_start",{data:{upload_id:u,call_id:o,reason:a,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 K(c);const S=Math.min(f+E,l);c.send(m.subarray(f,S))}return await K(c),s("client_media_upload_complete",{data:{upload_id:u,call_id:o,reason:a,message:r,chunk_count:_,upload_kind:p}}),{media_id:u,url:"",content_type:i}}async function _e(n){return typeof n.arrayBuffer=="function"?n.arrayBuffer():new Response(n).arrayBuffer()}function me(n){return null}function g(){return typeof window>"u"?"/":`${window.location.pathname}${window.location.search}${window.location.hash}`||"/"}class fe{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 c=()=>{const s=g();s!==this.lastRoute&&this.handleRouteChange(s,r)};o>0?window.setTimeout(c,o):queueMicrotask(c)},t=()=>e("popstate"),i=()=>e("hashchange"),a=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",a),this.cleanupFns.push(()=>window.removeEventListener("popstate",t),()=>window.removeEventListener("hashchange",i),()=>window.removeEventListener("vanira:navigate",a)),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()||me()||this.sendRouteContext("route_changed",i,t,"user")}sendRouteContext(e,t,i,a="user"){const r=g();this.lastRoute=r;const o={ui_state:"page_navigation",navigation_led_by:a,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 v=class v{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),a=v.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||ee).replace(/\/$/,""),a.length&&(this.iceServers=a),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 c=e.onSessionStarted;this.onSessionStarted=s=>{c==null||c(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 fe({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 a;try{a=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 S=new Error(f);throw S.name=l.name,S}throw l}if(this.isConnectCancelled(e)){a.getTracks().forEach(l=>l.stop());return}if(this.localStream=a,!this.pc||this.isConnectCancelled(e)){a.getTracks().forEach(l=>l.stop());return}if(this.onLocalStream(a),a.getTracks().forEach(l=>{var _;(_=this.pc)==null||_.addTrack(l,a)}),!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(_);le(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,S,P,A,U,x,M,O,L,N;const l=((m=this.pc)==null?void 0:m.connectionState)==="connected"||((f=this.pc)==null?void 0:f.iceConnectionState)==="connected"||((S=this.pc)==null?void 0:S.iceConnectionState)==="completed",_=((P=this.pc)==null?void 0:P.connectionState)==="failed"||((A=this.pc)==null?void 0:A.iceConnectionState)==="failed"||((U=this.pc)==null?void 0:U.connectionState)==="closed"||((x=this.pc)==null?void 0:x.iceConnectionState)==="closed"||((M=this.pc)==null?void 0:M.connectionState)==="disconnected"||((O=this.pc)==null?void 0:O.iceConnectionState)==="disconnected";((L=this.pc)==null?void 0:L.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 c=await this.pc.createOffer();if(this.isConnectCancelled(e)||(await this.pc.setLocalDescription(c),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 c,s,u;const a=await fetch(`${this.backendUrl}/calls/create`,{method:"POST",headers:e,body:JSON.stringify({agent_id:this.agentId,type:((c=this.runtime)==null?void 0:c.callType)||"web",mode:t,...(s=this.runtime)!=null&&s.runtimeName?{runtime:this.runtime.runtimeName}:{},prospect_id:this.prospectId,...i?{call_id:i}:{}})});if(!a.ok){const p=await a.json().catch(()=>({}));throw new Error(`[VaniraClient] createCall failed (${a.status}): ${((u=p==null?void 0:p.detail)==null?void 0:u.message)||(p==null?void 0:p.message)||a.statusText}`)}const r=await a.json();if(!r.call_id||!r.worker_url)throw new Error("[VaniraClient] /calls/create response missing call_id or worker_url");const o=v.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,oe(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",a=this.createCallCacheKey(i,t);let r=v.inflightCreates.get(a);r||(r=this.postCreateCall(e,i,t),v.inflightCreates.set(a,r),r.finally(()=>{v.inflightCreates.get(a)===r&&v.inflightCreates.delete(a)}));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 a=i==null?void 0:i.urls,r=Array.isArray(a)?a.filter(Boolean):typeof a=="string"&&a.trim()?[a.trim()]:[];if(!r.length)continue;const o={urls:r.length===1?r[0]:r},c=i.username,s=i.credential;c&&(o.username=c),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 a of i||[]){const r=JSON.stringify(a);if(!this.appliedRemoteCandidates.has(r)){this.appliedRemoteCandidates.add(r);try{await this.pc.addIceCandidate(a)}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 a={event:e,...t};this.dataChannel.send(JSON.stringify(a))}}async sendEventWhenReady(e,t={},i=1e4){var r;const a=Date.now()+i;for(;Date.now()<a;){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:h.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 a=(e.data||e).tool_call_id||e.tool_call_id;this.dispatchBoardAbort("Tool cancelled by server",a);break}case"client_tool_call":{const i=e.tool_call||e.data||e,a=(i==null?void 0:i.tool_call_id)||(i==null?void 0:i.call_id)||e.tool_call_id||"";a&&((t=this.dataChannel)==null?void 0:t.readyState)==="open"&&this.dataChannel.send(JSON.stringify({event:"client_tool_ack",data:{tool_call_id:a}}));const r=(i==null?void 0:i.arguments)||(i==null?void 0:i.args)||{},o=(i==null?void 0:i.client_fields)||{},c=(i==null?void 0:i.name)||(i==null?void 0:i.tool_name)||"",s=se(o,r,c);if(c==="end_call"){a&&this.sendToolResult(a,{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(a=>{a.enabled=!e}),(i=this.pc)==null||i.getSenders().forEach(a=>{var r;((r=a.track)==null?void 0:r.kind)==="audio"&&(a.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")}async uploadMediaForToolResult(e,t="general"){return this._postMediaUpload(e,t)}async uploadMedia(e,t="general",i=""){return await ue(this.dataChannel,this.mediaBytesChannel)?this._uploadMediaViaDataChannel(e,t,i):(he(this.dataChannel,this.mediaBytesChannel),this._uploadMediaViaHTTP(e,t,i))}async uploadMediaFrame(e,t="camera_capture",i){const a=i&&!(e instanceof File)?new File([e],i,{type:e.type||"image/jpeg"}):e,{media_id:r,url:o,contentType:c}=await this._postMediaUpload(a,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:c}}async _uploadBytesViaDataChannel(e,t,i,a,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:a==="frame"?"frame.jpg":"upload.bin"),c=e.type||(a==="frame"?"image/jpeg":"application/octet-stream"),s=await _e(e);return pe({bytes:s,filename:o,contentType:c,reason:t,message:i,callId:this.callId,mediaBytesChannel:this.mediaBytesChannel,sendControlEvent:(u,p)=>this.sendEvent(u,p),uploadKind:a})}async _uploadMediaViaDataChannel(e,t,i){const a=await this._uploadBytesViaDataChannel(e,t,i,"media");return{media_id:a.media_id,url:a.url}}async _uploadMediaViaHTTP(e,t="general",i=""){const{media_id:a,url:r,contentType:o}=await this._postMediaUpload(e,t,!0);if(this.dataChannel&&this.dataChannel.readyState==="open"){const c={event:"client_media_update",data:{media_id:a,media_url:r,content_type:o,reason:t,message:i}};this.dataChannel.send(JSON.stringify(c))}return{media_id:a,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 a=this.getWorkerOrigin();if(!a)throw new Error("Upload failed: worker_url is not set. Connect the call before uploading media.");const r=`${a}/media/upload`,o=new FormData;o.append("file",e),o.append("call_id",this.callId),o.append("reason",t);const c=await fetch(r,{method:"POST",body:o});if(!c.ok){let _=`HTTP ${c.status}`;try{_=(await c.json()).error||_}catch{}throw new Error(`Upload failed: ${_}`)}const s=await c.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(a=>a(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(v,"inflightCreates",new Map);let y=v;const Y={supportsAudioEndedEvent:!1,supportsScreenShare:!1,supportsDom:!1,supportsHtmlAudio:!1,supportsCustomElements:!1,supportsLocalStorage:!1,supportsBroadcastChannel:!1},q={name:"react-native",callType:"web",runtimeName:"react-native",callIdPrefix:"rn_",capabilities:Y,audio:new j,media:new J,peer:new G,dataChannel:new W};function b(n){return new y({...n,runtime:q})}const ve=b;function F(n){return b(n)}const we=F;exports.RNAudioAdapter=j;exports.RNDataChannelAdapter=W;exports.RNMediaAdapter=J;exports.RNPeerAdapter=G;exports.VaniraAI=y;exports.VaniraClient=y;exports.WebRTCClient=y;exports.createReactNativeAI=ve;exports.createReactNativeClient=b;exports.createVaniraAI=we;exports.createVaniraClient=F;exports.reactNativeCapabilities=Y;exports.reactNativeRuntime=q;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type {VaniraClientConfig, VaniraClientStatus, ClientToolCall} from '../index';
|
|
2
|
+
export {VaniraClient, WebRTCClient, VaniraAI} from '../index';
|
|
3
|
+
|
|
4
|
+
export const reactNativeRuntime: Record<string, unknown>;
|
|
5
|
+
export function createReactNativeClient(config: VaniraClientConfig): VaniraClient;
|
|
6
|
+
export function createReactNativeAI(config: VaniraClientConfig): VaniraClient;
|