@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
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
|
|
3
|
+
export const VANIRA_API_BASE_URL: string;
|
|
4
|
+
|
|
5
|
+
export type VaniraClientStatus =
|
|
6
|
+
| 'idle'
|
|
7
|
+
| 'connecting'
|
|
8
|
+
| 'connected'
|
|
9
|
+
| 'disconnected'
|
|
10
|
+
| 'error';
|
|
11
|
+
|
|
12
|
+
export interface VaniraClientConfig {
|
|
13
|
+
agentId: string;
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
token?: string;
|
|
16
|
+
backendUrl?: string;
|
|
17
|
+
serverUrl?: string;
|
|
18
|
+
callId?: string;
|
|
19
|
+
iceServers?: RTCIceServer[];
|
|
20
|
+
prospectId?: string;
|
|
21
|
+
sessionBehavior?: 'continue' | 'new';
|
|
22
|
+
runtime?: unknown;
|
|
23
|
+
liveVision?: Record<string, unknown>;
|
|
24
|
+
onSessionStarted?: (payload: {
|
|
25
|
+
prospectId: string;
|
|
26
|
+
callId: string;
|
|
27
|
+
serverUrl: string;
|
|
28
|
+
}) => void;
|
|
29
|
+
onConnected?: () => void;
|
|
30
|
+
onDisconnected?: () => void;
|
|
31
|
+
onError?: (error: unknown) => void;
|
|
32
|
+
onTranscription?: (text: string, isFinal: boolean) => void;
|
|
33
|
+
onClientToolCall?: (toolCall: unknown) => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ClientToolCall {
|
|
37
|
+
name: string;
|
|
38
|
+
arguments: Record<string, unknown>;
|
|
39
|
+
tool_call_id: string;
|
|
40
|
+
execution_mode: 'blocking' | 'fire_and_forget';
|
|
41
|
+
client_fields?: Record<string, unknown>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface TranscriptionEvent {
|
|
45
|
+
text: string;
|
|
46
|
+
isFinal: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export class VaniraClient {
|
|
50
|
+
constructor(config: VaniraClientConfig);
|
|
51
|
+
readonly status: VaniraClientStatus;
|
|
52
|
+
readonly isConnected: boolean;
|
|
53
|
+
readonly serverUrl: string | undefined;
|
|
54
|
+
readonly callId: string | undefined;
|
|
55
|
+
readonly prospectId: string | undefined;
|
|
56
|
+
on(event: 'connected', callback: () => void): this;
|
|
57
|
+
on(event: 'disconnected', callback: () => void): this;
|
|
58
|
+
on(event: 'error', callback: (message: string) => void): this;
|
|
59
|
+
on(event: 'transcription', callback: (payload: TranscriptionEvent) => void): this;
|
|
60
|
+
on(
|
|
61
|
+
event: 'preset',
|
|
62
|
+
callback: (payload: {toolCall: unknown; client: unknown}) => void,
|
|
63
|
+
): this;
|
|
64
|
+
on(event: 'tool_call', callback: (payload: ClientToolCall) => void): this;
|
|
65
|
+
off(event: string, callback: (...args: unknown[]) => void): this;
|
|
66
|
+
start(): Promise<{callId: string; prospectId: string; serverUrl: string}>;
|
|
67
|
+
stop(): void;
|
|
68
|
+
setMicrophoneMuted(muted: boolean): void;
|
|
69
|
+
isMicrophoneMuted(): boolean;
|
|
70
|
+
sendToolResult(toolCallId: string, result: Record<string, unknown>): void;
|
|
71
|
+
sendToolError(toolCallId: string, error: string): void;
|
|
72
|
+
updateContext(context: Record<string, unknown>): void;
|
|
73
|
+
triggerInterrupt(actionName: string, data?: Record<string, unknown>): void;
|
|
74
|
+
interruptAudioOnly(): void;
|
|
75
|
+
sendActionTrigger(actionName: string, data?: Record<string, unknown>): void;
|
|
76
|
+
sendEvent(event: string, data?: Record<string, unknown>): void;
|
|
77
|
+
uploadMedia(
|
|
78
|
+
file: Blob | File,
|
|
79
|
+
reason?: string,
|
|
80
|
+
message?: string,
|
|
81
|
+
): Promise<{media_id: string; url: string; content_type?: string}>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const WebRTCClient: typeof VaniraClient;
|
|
85
|
+
export const VaniraAI: typeof VaniraClient;
|
|
86
|
+
export type WebRTCClientConfig = VaniraClientConfig;
|
|
87
|
+
export type VaniraAIConfig = VaniraClientConfig;
|
|
88
|
+
export type VaniraAIStatus = VaniraClientStatus;
|
|
89
|
+
|
|
90
|
+
export interface StoredCallSession {
|
|
91
|
+
callId: string;
|
|
92
|
+
prospectId?: string;
|
|
93
|
+
updatedAt: number;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function hasContinueSession(storage: unknown, agentId: string): boolean;
|
|
97
|
+
export function loadContinueSession(
|
|
98
|
+
storage: unknown,
|
|
99
|
+
agentId: string,
|
|
100
|
+
): StoredCallSession | null;
|
|
101
|
+
export function saveCallSession(
|
|
102
|
+
storage: unknown,
|
|
103
|
+
agentId: string,
|
|
104
|
+
callId: string,
|
|
105
|
+
prospectId?: string,
|
|
106
|
+
): void;
|
|
107
|
+
|
|
108
|
+
export class SessionManager {
|
|
109
|
+
constructor(storage?: unknown);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export class RouteContextTracker {
|
|
113
|
+
constructor(client: VaniraClient, route: string);
|
|
114
|
+
start(): void;
|
|
115
|
+
stop(): void;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function getCurrentPageRoute(): string;
|
|
119
|
+
export function markAgentNavigation(route: string): void;
|
|
120
|
+
export function normalizePageRoute(route: string): string;
|
|
121
|
+
|
|
122
|
+
export function createBrowserClient(config: VaniraClientConfig): VaniraClient;
|
|
123
|
+
export const createBrowserAI: typeof createBrowserClient;
|
|
124
|
+
export const browserRuntime: Record<string, unknown>;
|
|
125
|
+
export const browserCapabilities: Record<string, boolean>;
|
|
126
|
+
|
|
127
|
+
export class VaniraWidget {
|
|
128
|
+
constructor(config: Record<string, unknown>);
|
|
129
|
+
mount(target?: HTMLElement | string): void;
|
|
130
|
+
unmount(): void;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export type VaniraCallBoxStatus = VaniraClientStatus;
|
|
134
|
+
export type VaniraCustomToolCall = ClientToolCall;
|
|
135
|
+
|
|
136
|
+
export type VaniraCallBoxProps = Record<string, unknown>;
|
|
137
|
+
export function VaniraCallBox(props: VaniraCallBoxProps): React.JSX.Element;
|
|
138
|
+
export function VaniraCallBoxChrome(props: Record<string, unknown>): React.JSX.Element;
|
|
139
|
+
|
|
140
|
+
export interface PresetRendererHandle {
|
|
141
|
+
enqueueToolCall: (toolCall: unknown) => void;
|
|
142
|
+
clearQueue: () => void;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface PresetRendererProps {
|
|
146
|
+
client: VaniraClient | null;
|
|
147
|
+
toolCall?: unknown | null;
|
|
148
|
+
onCustomTool?: (toolCall: unknown) => void;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const PresetRenderer: React.ForwardRefExoticComponent<
|
|
152
|
+
PresetRendererProps & React.RefAttributes<PresetRendererHandle>
|
|
153
|
+
>;
|
|
154
|
+
|
|
155
|
+
export const VaniraPresetId: Record<string, string>;
|
|
156
|
+
export const VANIRA_PRESET_IDS: readonly string[];
|
|
157
|
+
export function isVaniraPresetId(id: string): boolean;
|
|
158
|
+
export function extractPresetId(toolCall: unknown): string | undefined;
|
|
159
|
+
export function resolvePresetIdForToolCall(
|
|
160
|
+
clientFields?: Record<string, unknown> | null,
|
|
161
|
+
args?: Record<string, unknown> | null,
|
|
162
|
+
toolName?: string,
|
|
163
|
+
): string | undefined;
|
|
164
|
+
|
|
165
|
+
export const BrowserAudioAdapter: unknown;
|
|
166
|
+
export const BrowserMediaAdapter: unknown;
|
|
167
|
+
export const BrowserPeerAdapter: unknown;
|
|
168
|
+
export const BrowserDataChannelAdapter: unknown;
|
|
169
|
+
|
|
170
|
+
export class ConfigService {}
|
|
171
|
+
export class ChatService {}
|
|
172
|
+
|
|
173
|
+
export function refreshVaniraDebug(): void;
|
|
174
|
+
export function isVaniraDebug(): boolean;
|
|
175
|
+
export function devLog(...args: unknown[]): void;
|
|
176
|
+
export function devWarn(...args: unknown[]): void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";var le=Object.defineProperty;var de=(s,e,t)=>e in s?le(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var l=(s,e,t)=>de(s,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class he{constructor(e){l(this,"el");this.el=new Audio,this.el.srcObject=e,this.el.play().catch(t=>{})}pause(){}cleanup(){this.el.pause(),this.el.srcObject=null}onEnded(e){this.el.onended=e}}class X{createRemotePlayer(e){return new he(e)}}class Z{async getUserAudio(e){return navigator.mediaDevices.getUserMedia({audio:e})}stopStream(e){e.getTracks().forEach(t=>t.stop())}}class Q{create(e){return new RTCPeerConnection({iceServers:e.iceServers,iceTransportPolicy:e.iceTransportPolicy??"all"})}}const ue=new Set(["client_tool_call","clearAudio","client_tool_cancel"]);function ee(s){if(!s||typeof s!="object")return!1;const e=s.event;return typeof e=="string"&&ue.has(e)}class te{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),i=JSON.parse(n);ee(i)&&t.onMessage({text:n})}catch{}return}a.data instanceof Blob&&a.data.text().then(n=>{t.onMessage({text:n})}).catch(n=>{})},{send(a){e.readyState==="open"&&e.send(a)},isOpen(){return e.readyState==="open"},close(){e.close()}}}}const j="https://api.vanira.io",p={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"},pe=Object.values(p),_e=new Set(pe);function W(s){return!!s&&_e.has(s)}const fe=new Set([p.ScreenInk,p.ScreenCursor,p.ScreenClick,p.ClearScreenOverlay,p.PointAt,p.OutlineTargets,p.ClearGuide]);[...fe,p.PageScan,p.TabScreenshot];function ae(s){if(typeof s=="string")try{return JSON.parse(s)}catch{return{}}return s&&typeof s=="object"?s:{}}const G={type_on_whiteboard:p.TypeText,write_on_whiteboard:p.TypeText,write_on_white_board:p.TypeText,dom_typing_simulation:p.TypeText,erase_text:p.EraseText,dom_erase:p.EraseText,draw_on_board:p.Draw,erase_drawing_board:p.EraseDraw,open_live_camera:p.LiveVision,live_vision:p.LiveVision,close_live_camera:p.CloseLiveCamera,stop_live_camera:p.CloseLiveCamera,open_live_screen:p.LiveScreen,close_live_screen:p.CloseLiveScreen,screen_ink:p.ScreenInk,screen_cursor:p.ScreenCursor,screen_click:p.ScreenClick,clear_screen_overlay:p.ClearScreenOverlay,tab_screenshot:p.TabScreenshot,capture_tab:p.TabScreenshot,capture_tab_screenshot:p.TabScreenshot,screenshot_tab:p.TabScreenshot,page_scan:p.PageScan,scan_page:p.PageScan,point_at:p.PointAt,outline_targets:p.OutlineTargets,outline_elements:p.OutlineTargets,clear_guide:p.ClearGuide};function z(s,e){const t=s.text_to_type??(e==null?void 0:e.text_to_type)??s.text??(e==null?void 0:e.text)??s.value??(e==null?void 0:e.value);return typeof t=="string"&&t.trim().length>0}function me(s,e){const t=s.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 we(s,e){const t=s==null?void 0:s.preset_id;if(typeof t=="string"&&W(t))return t;const n=ae(e).preset_id;if(typeof n=="string"&&W(n))return n}function Se(s,e,t){const a=ae(e);let n=we(s,a);if(n===p.Form&&z(a,s)&&!me(a,s))return p.TypeText;if(n)return n;const i=String(t??"").trim().toLowerCase();if(i&&G[i])return G[i];if(z(a,s))return p.TypeText}const M="vanira_latest_call_id",N="vanira_prospect_id";function x(s){return`vanira_latest_call_id_${s}`}function L(s){return`vanira_prospect_id_${s}`}function ne(s){return`vanira_call_meta_${s}`}function C(s,e){if(!s)return null;try{return s.getItem(e)}catch{return null}}function Y(s){if(typeof window>"u"||!s)return null;const e=[],t=C(window.localStorage,ne(s));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 a=(c,r,h)=>{c&&e.push({callId:c,prospectId:r||void 0,updatedAt:h})},n=C(window.localStorage,L(s)),i=C(window.sessionStorage,L(s)),o=C(window.localStorage,N);return a(C(window.localStorage,x(s)),n||o,2),a(C(window.sessionStorage,x(s)),i||o,1),a(C(window.localStorage,M),o,0),a(C(window.sessionStorage,M),o,0),e.length?(e.sort((c,r)=>r.updatedAt-c.updatedAt),e[0]):null}function ye(s,e,t){var n,i,o,c,r,h,u,d,_;if(typeof window>"u"||!s||!e)return;const a={callId:e,prospectId:t,updatedAt:Date.now()};try{(n=window.localStorage)==null||n.setItem(ne(s),JSON.stringify(a)),(i=window.localStorage)==null||i.setItem(x(s),e),(o=window.sessionStorage)==null||o.setItem(x(s),e),t&&((c=window.localStorage)==null||c.setItem(L(s),t),(r=window.sessionStorage)==null||r.setItem(L(s),t)),(h=window.localStorage)==null||h.setItem(M,e),(u=window.sessionStorage)==null||u.setItem(M,e),t&&((d=window.localStorage)==null||d.setItem(N,t),(_=window.sessionStorage)==null||_.setItem(N,t))}catch{}}const $=16*1024,ve=256*1024;function D(s,e){return(s==null?void 0:s.readyState)==="open"&&(e==null?void 0:e.readyState)==="open"}function ge(s,e){return{control:(s==null?void 0:s.readyState)??"missing",mediaBytes:(e==null?void 0:e.readyState)??"missing"}}async function Ce(s,e,t=8e3){if(D(s,e))return!0;const a=Date.now()+t;for(;Date.now()<a;){if(D(s,e))return!0;await new Promise(n=>setTimeout(n,50))}return D(s,e)}async function q(s){for(;s.bufferedAmount>ve;)await new Promise(e=>setTimeout(e,10))}async function Ie(s){const{bytes:e,filename:t,contentType:a,reason:n,message:i,callId:o,mediaBytesChannel:c,sendControlEvent:r,uploadId:h=crypto.randomUUID(),uploadKind:u="media"}=s,d=e.byteLength,_=d===0?0:Math.ceil(d/$);r("client_media_upload_start",{data:{upload_id:h,call_id:o,reason:n,message:i,filename:t,content_type:a,size:d,chunk_count:_,upload_kind:u}});const f=new Uint8Array(e);for(let m=0;m<d;m+=$){await q(c);const S=Math.min(m+$,d);c.send(f.subarray(m,S))}return await q(c),r("client_media_upload_complete",{data:{upload_id:h,call_id:o,reason:n,message:i,chunk_count:_,upload_kind:u}}),{media_id:h,url:"",content_type:a}}async function be(s){return typeof s.arrayBuffer=="function"?s.arrayBuffer():new Response(s).arrayBuffer()}function Te(s){return null}function U(){return typeof window>"u"?"/":`${window.location.pathname}${window.location.search}${window.location.hash}`||"/"}class Ee{constructor(e){l(this,"active",!1);l(this,"initialSent",!1);l(this,"lastRoute","");l(this,"sendContext");l(this,"isReady");l(this,"cleanupFns",[]);l(this,"initialRetryTimer",null);l(this,"routePollTimer",null);l(this,"originalPushState",null);l(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=U(),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=(i,o=0)=>{const c=()=>{const r=U();r!==this.lastRoute&&this.handleRouteChange(r,i)};o>0?window.setTimeout(c,o):queueMicrotask(c)},t=()=>e("popstate"),a=()=>e("hashchange"),n=i=>{const o=i.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=(...i)=>{this.originalPushState(...i),e("pushState")},history.replaceState=(...i)=>{this.originalReplaceState(...i),e("replaceState")},this.routePollTimer=window.setInterval(()=>{if(!this.active)return;const i=U();i!==this.lastRoute&&this.handleRouteChange(i,"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()||Te()||this.sendRouteContext("route_changed",a,t,"user")}sendRouteContext(e,t,a,n="user"){const i=U();this.lastRoute=i;const o={ui_state:"page_navigation",navigation_led_by:n,current_route:i,current_page:i,user_action:e==="call_started"?"call_started_on_page":"user_navigated"};e==="call_started"?o.message=`User started the call while viewing ${i}.`:(o.previous_route=t??"",o.message=`User navigated from ${t||"(unknown)"} to ${i}.`,a&&(o.navigation_source=a));try{this.sendContext(o)}catch{}}}const y=class y{constructor(e){l(this,"serverUrl");l(this,"agentId");l(this,"callId");l(this,"prospectId");l(this,"apiKey");l(this,"backendUrl");l(this,"token");l(this,"onConnected");l(this,"onDisconnected");l(this,"onError");l(this,"onTranscription");l(this,"onLocalStream");l(this,"onRemoteTrack");l(this,"onClientToolCall");l(this,"onSessionStarted");l(this,"sessionStartedEmitted",!1);l(this,"pc",null);l(this,"dataChannel",null);l(this,"mediaBytesChannel",null);l(this,"audioElement",null);l(this,"localStream",null);l(this,"micMuted",!1);l(this,"connected",!1);l(this,"icePollInterval",null);l(this,"appliedRemoteCandidates",new Set);l(this,"iceServers");l(this,"callSessionLoaded",!1);l(this,"connectGeneration",0);l(this,"runtime");l(this,"sessionBehavior");l(this,"routeTracker",null);l(this,"_status","idle");l(this,"listeners",new Map);l(this,"liveVision");l(this,"liveVisionAutoStarted",!1);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.backendUrl=(e.backendUrl||j).replace(/\/$/,""),n.length&&(this.iceServers=n),a&&(this.callSessionLoaded=!0);const i=typeof window<"u";this.prospectId=e.prospectId;const o=e.sessionBehavior==="continue";if(o&&i&&!e.callId){const r=Y(this.agentId);r&&(e.callId||(this.callId=r.callId),!this.prospectId&&r.prospectId&&(this.prospectId=r.prospectId))}if(!this.prospectId&&i)try{const r=Y(this.agentId);this.prospectId=(r==null?void 0:r.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=r=>{c==null||c(r),this.emit("session_started",r)},this.liveVision=e.liveVision,this.onConnected=()=>{var r;this._status="connected",(r=e.onConnected)==null||r.call(e),this.emit("connected"),this.maybeAutoStartLiveCamera()},this.onDisconnected=()=>{var r;this._status="disconnected",(r=e.onDisconnected)==null||r.call(e),this.emit("disconnected")},this.onError=r=>{var u;this._status="error";const h=typeof r=="string"?r:(r==null?void 0:r.message)||"Connection error";(u=e.onError)==null||u.call(e,r),this.emit("error",h)},this.onTranscription=(r,h)=>{var u;(u=e.onTranscription)==null||u.call(e,r,h),this.emit("transcription",{text:r,isFinal:h})},this.onLocalStream=e.onLocalStream||(()=>{}),this.onRemoteTrack=(r,h)=>{var u;(u=e.onRemoteTrack)==null||u.call(e,r,h),this.emit("track",{track:r,stream:h})},this.onClientToolCall=r=>{var d;(d=e.onClientToolCall)==null||d.call(e,r);const h=(r==null?void 0:r.data)||r,u={name:String(h.name||h.tool_name||""),arguments:h.arguments||h.args||{},tool_call_id:String(h.tool_call_id||h.call_id||""),execution_mode:h.execution_mode==="blocking"?"blocking":"fire_and_forget",client_fields:h.client_fields||{}};u.name&&u.tool_call_id&&this.emit("tool_call",u)},this.runtime=e.runtime,typeof window<"u"&&e.trackRouteContext!==!1&&(this.routeTracker=new Ee({sendContext:r=>this.sendContextUpdate(r),isReady:()=>{var r;return((r=this.dataChannel)==null?void 0:r.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 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(d){if(d.name==="NotAllowedError"||d.name==="PermissionDeniedError"||(t=d.message)!=null&&t.includes("Permission denied")){const _=navigator.userAgent,f=/iPad|iPhone|iPod/.test(_)||navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1;let m="Microphone access denied. Please allow microphone access in your browser settings.";f&&(_.includes("CriOS")?m="Microphone access blocked. Please enable it in iOS Settings > Chrome > Microphone, then reload the page.":_.includes("FxiOS")?m="Microphone access blocked. Please enable it in iOS Settings > Firefox > Microphone, then reload the page.":m="Microphone access blocked. Please enable it in iOS Settings > Safari > Microphone (or tap 'aA' > Website Settings > Allow Microphone).");const S=new Error(m);throw S.name=d.name,S}throw d}if(this.isConnectCancelled(e)){n.getTracks().forEach(d=>d.stop());return}if(this.localStream=n,!this.pc||this.isConnectCancelled(e)){n.getTracks().forEach(d=>d.stop());return}if(this.onLocalStream(n),n.getTracks().forEach(d=>{var _;(_=this.pc)==null||_.addTrack(d,n)}),!this.pc)throw new Error("RTCPeerConnection was closed unexpectedly");this.dataChannel=this.pc.createDataChannel("control"),this.dataChannel.onopen=()=>{var d;(d=this.routeTracker)==null||d.onChannelReady()},this.dataChannel.onmessage=d=>{if(typeof d.data=="string")try{this.handleControlEvent(JSON.parse(d.data))}catch{}else if(d.data instanceof ArrayBuffer)try{const _=new TextDecoder().decode(d.data);try{const f=JSON.parse(_);ee(f)&&this.handleControlEvent(f)}catch{}}catch{}else d.data instanceof Blob&&d.data.text().then(_=>{try{this.handleControlEvent(JSON.parse(_))}catch{}})},this.dataChannel.onerror=d=>{},this.mediaBytesChannel=this.pc.createDataChannel("media-bytes",{ordered:!0}),this.mediaBytesChannel.binaryType="arraybuffer",this.mediaBytesChannel.onopen=()=>{},this.mediaBytesChannel.onerror=d=>{},this.pc.ontrack=d=>{const _=d.track,f=d.streams[0];_.kind==="audio"?(this.audioElement=new Audio,this.audioElement.srcObject=f,this.audioElement.play().catch(m=>{}),this.audioElement.onended=()=>{this.sendEvent("playedStream"),typeof window<"u"&&window.dispatchEvent(new CustomEvent("vanira:agent-playback-ended"))},this.onRemoteTrack(_,f)):_.kind==="video"&&this.onRemoteTrack(_,f)};const i=()=>{var f,m,S,E,k,P,A,I,v,g,O;const d=((f=this.pc)==null?void 0:f.connectionState)==="connected"||((m=this.pc)==null?void 0:m.iceConnectionState)==="connected"||((S=this.pc)==null?void 0:S.iceConnectionState)==="completed",_=((E=this.pc)==null?void 0:E.connectionState)==="failed"||((k=this.pc)==null?void 0:k.iceConnectionState)==="failed"||((P=this.pc)==null?void 0:P.connectionState)==="closed"||((A=this.pc)==null?void 0:A.iceConnectionState)==="closed"||((I=this.pc)==null?void 0:I.connectionState)==="disconnected"||((v=this.pc)==null?void 0:v.iceConnectionState)==="disconnected";((g=this.pc)==null?void 0:g.connectionState)==="connected"&&this.stopRemoteIcePolling(),d&&!this.connected?(this.connected=!0,(O=this.routeTracker)==null||O.start(),this.onConnected()):_&&this.connected&&(this.connected=!1,this.liveVisionAutoStarted=!1,this.onDisconnected())};this.pc.onconnectionstatechange=i,this.pc.oniceconnectionstatechange=i;const o=this.getIceTrickleUrl();this.pc.onicecandidate=d=>{d.candidate&&fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({candidate:d.candidate.toJSON()})}).catch(_=>{})};const c=await this.pc.createOffer();if(this.isConnectCancelled(e)||(await this.pc.setLocalDescription(c),this.isConnectCancelled(e)))return;const r=this.serverUrl.includes("?")?this.serverUrl:`${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`,h=await fetch(r,{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(!h.ok){const d=await h.json();throw new Error(d.error||`HTTP ${h.status}`)}const{answer:u}=await h.json();if(this.isConnectCancelled(e)||!this.pc||(await this.pc.setRemoteDescription(u),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 c,r,h;const n=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,...(r=this.runtime)!=null&&r.runtimeName?{runtime:this.runtime.runtimeName}:{},prospect_id:this.prospectId,...a?{call_id:a}:{}})});if(!n.ok){const u=await n.json().catch(()=>({}));throw new Error(`[VaniraClient] createCall failed (${n.status}): ${((h=u==null?void 0:u.detail)==null?void 0:h.message)||(u==null?void 0:u.message)||n.statusText}`)}const i=await n.json();if(!i.call_id||!i.worker_url)throw new Error("[VaniraClient] /calls/create response missing call_id or worker_url");const o=y.normalizeIceServers(i.ice_servers);if(!o.length)throw new Error("[VaniraClient] /calls/create response missing ice_servers");return{callId:i.call_id,prospectId:i.prospect_id||this.prospectId,serverUrl:i.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,ye(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 i=y.inflightCreates.get(n);i||(i=this.postCreateCall(e,a,t),y.inflightCreates.set(n,i),i.finally(()=>{y.inflightCreates.get(n)===i&&y.inflightCreates.delete(n)}));const o=await i;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,i=Array.isArray(n)?n.filter(Boolean):typeof n=="string"&&n.trim()?[n.trim()]:[];if(!i.length)continue;const o={urls:i.length===1?i[0]:i},c=a.username,r=a.credential;c&&(o.username=c),r&&(o.credential=r),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:a}=await t.json();for(const n of a||[]){const i=JSON.stringify(n);if(!this.appliedRemoteCandidates.has(i)){this.appliedRemoteCandidates.add(i);try{await this.pc.addIceCandidate(n)}catch{}}}}catch{}},150)}stopRemoteIcePolling(){this.icePollInterval!==null&&(clearInterval(this.icePollInterval),this.icePollInterval=null)}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 i;const n=Date.now()+a;for(;Date.now()<n;){if(((i=this.dataChannel)==null?void 0:i.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:p.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 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 i=(a==null?void 0:a.arguments)||(a==null?void 0:a.args)||{},o=(a==null?void 0:a.client_fields)||{},c=(a==null?void 0:a.name)||(a==null?void 0:a.tool_name)||"",r=Se(o,i,c);if(c==="end_call"){n&&this.sendToolResult(n,{status:"client_ack_end_call",message:"Ending call."}),window.setTimeout(()=>this.disconnect(),120);break}if(r){window.dispatchEvent(new CustomEvent("vanira:preset",{detail:{toolCall:a,client:this}})),this.onClientToolCall(a);break}this.onClientToolCall(a);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,a;this.micMuted=e,(t=this.localStream)==null||t.getAudioTracks().forEach(n=>{n.enabled=!e}),(a=this.pc)==null||a.getSenders().forEach(n=>{var i;((i=n.track)==null?void 0:i.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")}async uploadMediaForToolResult(e,t="general"){return this._postMediaUpload(e,t)}async uploadMedia(e,t="general",a=""){return await Ce(this.dataChannel,this.mediaBytesChannel)?this._uploadMediaViaDataChannel(e,t,a):(ge(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:i,url:o,contentType:c}=await this._postMediaUpload(n,t,!0);if(!i||!o)throw new Error("Frame upload failed: server response missing media_id or url");return{media_id:i,url:o,content_type:c}}async _uploadBytesViaDataChannel(e,t,a,n,i){if(!this.callId||!this.mediaBytesChannel)throw new Error("Upload failed: call not ready for WebRTC media upload.");const o=i||(e instanceof File?e.name:n==="frame"?"frame.jpg":"upload.bin"),c=e.type||(n==="frame"?"image/jpeg":"application/octet-stream"),r=await be(e);return Ie({bytes:r,filename:o,contentType:c,reason:t,message:a,callId:this.callId,mediaBytesChannel:this.mediaBytesChannel,sendControlEvent:(h,u)=>this.sendEvent(h,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:i,contentType:o}=await this._postMediaUpload(e,t,!0);if(this.dataChannel&&this.dataChannel.readyState==="open"){const c={event:"client_media_update",data:{media_id:n,media_url:i,content_type:o,reason:t,message:a}};this.dataChannel.send(JSON.stringify(c))}return{media_id:n,url:i}}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 i=`${n}/media/upload`,o=new FormData;o.append("file",e),o.append("call_id",this.callId),o.append("reason",t);const c=await fetch(i,{method:"POST",body:o});if(!c.ok){let _=`HTTP ${c.status}`;try{_=(await c.json()).error||_}catch{}throw new Error(`Upload failed: ${_}`)}const r=await c.json(),h=r.media_id,u=r.url,d=r.content_type||e.type;if(!h||!u)throw new Error("Upload failed: server response missing media_id or url");return a?{media_id:h,url:u,contentType:d}:{media_id:h,url:u,contentType:d}}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()}};l(y,"inflightCreates",new Map);let T=y;var F;const ie={supportsAudioEndedEvent:!0,supportsScreenShare:typeof navigator<"u"&&typeof((F=navigator.mediaDevices)==null?void 0:F.getDisplayMedia)=="function",supportsDom:typeof document<"u",supportsHtmlAudio:typeof Audio<"u",supportsCustomElements:typeof customElements<"u",supportsLocalStorage:typeof localStorage<"u",supportsBroadcastChannel:typeof BroadcastChannel<"u"},se={name:"browser",callType:"web",runtimeName:"browser",callIdPrefix:"web_",capabilities:ie,audio:new X,media:new Z,peer:new Q,dataChannel:new te};function re(s){return new T({...s,runtime:se})}const ke=re,b=class b{constructor(e){l(this,"tabId");l(this,"sessionKey");l(this,"channelName");l(this,"channel",null);l(this,"heartbeatTimer",null);l(this,"listeners",new Map);const t=e.replace(/[^a-z0-9_-]/gi,"_");this.sessionKey=`vaniraai_session_${t}`,this.channelName=`vaniraai_channel_${t}`,this.tabId=this._getOrCreateTabId(),this._setupChannel()}getTabId(){return this.tabId}claimSession(){const e=this._loadSession();if(e){const n=Date.now()-e.lastActive,i=e.tabId===this.tabId,o=n>b.HEARTBEAT_TIMEOUT_MS;if(i)return this._startHeartbeat(),this._emit("session_restored"),!0;if(!o)return this._emit("tab_conflict"),!1}const t=e?{...e,tabId:this.tabId,lastActive:Date.now()}:{tabId:this.tabId,prospectId:"",chatId:null,conversationId:null,messages:[],lastActive:Date.now()};this._saveSession(t),this._startHeartbeat(),this._broadcast({type:"took_over",tabId:this.tabId});const a=!!(e!=null&&e.prospectId);return this._emit(a?"session_restored":"session_claimed"),!0}forceClaimSession(){const e=this._loadSession(),t=e?{...e,tabId:this.tabId,lastActive:Date.now()}:{tabId:this.tabId,prospectId:"",chatId:null,conversationId:null,messages:[],lastActive:Date.now()};this._saveSession(t),this._startHeartbeat(),this._broadcast({type:"took_over",tabId:this.tabId}),this._emit("session_claimed")}saveIds(e,t,a){const n=this._loadSession()??this._blankSession();this._saveSession({...n,prospectId:e,chatId:t,conversationId:a??n.conversationId??null,tabId:this.tabId,lastActive:Date.now()})}pushMessage(e,t){const a=this._loadSession()??this._blankSession();a.messages.push({role:e,content:t,timestamp:Date.now()}),a.messages.length>100&&(a.messages=a.messages.slice(-100)),this._saveSession({...a,tabId:this.tabId,lastActive:Date.now()})}updateLastAssistantMessage(e){const t=this._loadSession()??this._blankSession(),a=t.messages;let n=!1;for(let i=a.length-1;i>=0;i--)if(a[i].role==="assistant"&&a[i].content===""){a[i].content=e,n=!0;break}if(!n){for(let i=a.length-1;i>=0;i--)if(a[i].role==="assistant"){a[i].content=e,n=!0;break}}n||a.push({role:"assistant",content:e,timestamp:Date.now()}),this._saveSession({...t,tabId:this.tabId,lastActive:Date.now()})}getSession(){return this._loadSession()}clearSession(){localStorage.removeItem(this.sessionKey),this._broadcast({type:"session_cleared",tabId:this.tabId}),this._emit("session_cleared")}clearChatKeepProspect(){const e=this._loadSession();e&&this._saveSession({...e,chatId:null,conversationId:null,messages:[],lastActive:Date.now()})}destroy(){this._stopHeartbeat(),this.channel&&(this.channel.close(),this.channel=null)}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}_getOrCreateTabId(){let e=sessionStorage.getItem("vaniraai_tab_id");return e||(e=`tab_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,sessionStorage.setItem("vaniraai_tab_id",e)),e}_setupChannel(){typeof BroadcastChannel>"u"||(this.channel=new BroadcastChannel(this.channelName),this.channel.onmessage=e=>{const t=e.data;t.tabId!==this.tabId&&(t.type==="took_over"&&(this._stopHeartbeat(),this._emit("tab_took_over")),t.type,t.type==="session_cleared"&&this._emit("session_cleared"))})}_broadcast(e){var t;(t=this.channel)==null||t.postMessage(e)}_startHeartbeat(){this._stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{const e=this._loadSession();e&&e.tabId===this.tabId&&(this._saveSession({...e,lastActive:Date.now()}),this._broadcast({type:"heartbeat",tabId:this.tabId}))},b.HEARTBEAT_INTERVAL_MS)}_stopHeartbeat(){this.heartbeatTimer!==null&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}_loadSession(){try{const e=localStorage.getItem(this.sessionKey);return e?JSON.parse(e):null}catch{return null}}_saveSession(e){try{localStorage.setItem(this.sessionKey,JSON.stringify(e))}catch{}}_blankSession(){return{tabId:this.tabId,prospectId:"",chatId:null,conversationId:null,messages:[],lastActive:Date.now()}}_emit(e){var t;(t=this.listeners.get(e))==null||t.forEach(a=>a())}};l(b,"HEARTBEAT_INTERVAL_MS",5e3),l(b,"HEARTBEAT_TIMEOUT_MS",15e3);let V=b;class Ae{static async fetchWidgetConfig(e,t){var n;const a={"Content-Type":"application/json"};t&&(a["X-API-Key"]=t);try{const i=await fetch(`${j}/assistant/widget/${e}/config`,{method:"GET",headers:a});if(!i.ok)throw new Error(`Widget config fetch failed: HTTP ${i.status}`);const o=await i.json();return(n=o.agent)!=null&&n.client&&(o.client=o.agent.client),o}catch(i){throw i}}}let R="https://inboxapi.vanira.io";const Re="https://coredb.travelr.club/v1/graphql";class Pe{static setChatUrl(e){R=e}static async createChatProspect(e){var a,n;const t=`
|
|
2
|
+
mutation CreateChatProspect($prospectGroupId: uuid!, $name: String!) {
|
|
3
|
+
insert_prospects_one(object: {prospect_group_id: $prospectGroupId, name: $name, source: WEBSITE_WIDGET}) {
|
|
4
|
+
id
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
`;try{const o=await(await fetch(Re,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:t,variables:{prospectGroupId:e,name:`Widget Guest ${new Date().toLocaleString()}`}})})).json();return o.errors?`anon_${Date.now()}_${Math.random().toString(36).substr(2,9)}`:((n=(a=o.data)==null?void 0:a.insert_prospects_one)==null?void 0:n.id)||`anon_${Date.now()}`}catch{return`anon_${Date.now()}`}}static async fetchWelcomeMessage(e,t,a,n){try{const i={"Content-Type":"application/json"},o=await fetch(`${R}/widget/chat`,{method:"POST",headers:i,body:JSON.stringify({agent_id:e,...a?{widget_id:a}:{},message:"",prospect_id:t,stream:!1})});if(!o.ok)throw new Error("Failed to fetch welcome message");const c=await o.json();let r=c.response||"Hey! how can I help you ?",h;const u=c.chat_id||c.inbox_id,d=c.conversation_id||null;return c.widget&&(h=c.widget),{role:"assistant",content:r,widget:h,chatId:u,conversationId:d}}catch{return{role:"assistant",content:"Hey! how can I help you ?"}}}static async sendChatMessage(e,t,a,n,i,o,c,r,h){var u,d,_,f;try{const m={"Content-Type":"application/json"},S={agent_id:e,message:a,prospect_id:t,stream:!0};n&&(S.inbox_id=n),r&&(S.widget_id=r);const E=await fetch(`${R}/widget/chat`,{method:"POST",headers:m,body:JSON.stringify(S)});if(!E.ok)throw new Error("Chat request failed");const k=(u=E.body)==null?void 0:u.getReader(),P=new TextDecoder;if(!k)throw new Error("No reader");let A="",I="",v=null,g=null;for(;;){const{done:O,value:oe}=await k.read();if(O)break;I+=P.decode(oe,{stream:!0});const H=I.split(`
|
|
8
|
+
`);I=H.pop()||"";for(const ce of H){const B=ce.trim();if(B&&B.startsWith("data: ")){const K=B.slice(6);if(K==="[DONE]"){c(v,g);return}try{const w=JSON.parse(K);if(w.type==="metadata"){(w.chat_id||w.inbox_id)&&(v=w.chat_id||w.inbox_id),w.conversation_id&&(g=w.conversation_id);continue}const J=(f=(_=(d=w.choices)==null?void 0:d[0])==null?void 0:_.delta)==null?void 0:f.content;J&&(A+=J,i(A)),w.widget&&o(w.widget),w.chat_id&&!v&&(v=w.chat_id),w.conversation_id&&!g&&(g=w.conversation_id)}catch{}}}}c(v,g)}catch{i("Sorry, I encountered an error. Please try again."),c(null,null)}}static listenForAdminReplies(e,t,a){const n=`${R}/inbox/stream?inbox_id=${e}&sender=${encodeURIComponent(t)}`;let i=null,o=0,c=!1;const r=()=>{c||(i=new EventSource(n),i.onopen=()=>{o=0},i.onmessage=h=>{try{const u=JSON.parse(h.data),d=u.direction==="outgoing",_=!!u.content,f=u.source!=="ai";d&&_&&f&&a(u.content)}catch{}},i.onerror=h=>{if(i&&(i.close(),i=null),c)return;const u=Math.min(2e3*Math.pow(2,o),3e4);o++,setTimeout(r,u)})};return r(),{close:()=>{c=!0,i&&(i.close(),i=null)}}}static async createCall(e,t,a,n,i){try{const o={"Content-Type":"application/json"};i&&(o["X-API-Key"]=i);const c=await fetch(`${j}/calls/create`,{method:"POST",headers:o,body:JSON.stringify({agent_id:e,prospect_id:a||void 0,type:"web"})}),r=await c.json();if(!c.ok)throw new Error(`[VaniraAI] Call creation failed HTTP ${c.status}`);if(!r.worker_url)throw new Error("[VaniraAI] Worker URL missing from response. Call cannot proceed.");return{callId:r.call_id||r.id||`web_${Date.now()}`,workerUrl:r.worker_url}}catch(o){throw o}}static async resolveConversation(e){try{if(!(await fetch(`${R}/inbox/conversations/resolve`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({conversation_id:e})})).ok)throw new Error("Failed to resolve conversation")}catch(t){throw t}}}exports.BrowserAudioAdapter=X;exports.BrowserDataChannelAdapter=te;exports.BrowserMediaAdapter=Z;exports.BrowserPeerAdapter=Q;exports.ChatService=Pe;exports.ConfigService=Ae;exports.SessionManager=V;exports.VaniraAI=T;exports.VaniraClient=T;exports.WebRTCClient=T;exports.browserCapabilities=ie;exports.browserRuntime=se;exports.createBrowserAI=ke;exports.createBrowserClient=re;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
VaniraClientConfig,
|
|
3
|
+
VaniraClientStatus,
|
|
4
|
+
ClientToolCall,
|
|
5
|
+
TranscriptionEvent,
|
|
6
|
+
WebRTCClientConfig,
|
|
7
|
+
VaniraAIConfig,
|
|
8
|
+
VaniraAIStatus,
|
|
9
|
+
} from '../index';
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
VaniraClient,
|
|
13
|
+
WebRTCClient,
|
|
14
|
+
VaniraAI,
|
|
15
|
+
createBrowserClient,
|
|
16
|
+
createBrowserAI,
|
|
17
|
+
browserRuntime,
|
|
18
|
+
browserCapabilities,
|
|
19
|
+
SessionManager,
|
|
20
|
+
ConfigService,
|
|
21
|
+
ChatService,
|
|
22
|
+
BrowserAudioAdapter,
|
|
23
|
+
BrowserMediaAdapter,
|
|
24
|
+
BrowserPeerAdapter,
|
|
25
|
+
BrowserDataChannelAdapter,
|
|
26
|
+
} from '../index';
|