@vanira/sdk 0.0.83 → 0.0.85
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/dist/headless/index.cjs +471 -158
- package/dist/headless/index.d.ts +3 -0
- package/dist/headless/index.js +42995 -4006
- package/dist/index.d.ts +43 -0
- package/dist/platforms/browser.cjs +41 -3
- package/dist/platforms/browser.d.ts +3 -0
- package/dist/platforms/browser.js +21285 -689
- package/dist/platforms/react-native.cjs +1 -1
- package/dist/platforms/react-native.js +397 -387
- package/dist/vanira-sdk.es.js +46595 -7590
- package/dist/vanira-sdk.js +491 -221
- package/dist/vanira-sdk.umd.js +525 -212
- package/package.json +6 -5
- package/dist/chunks/html2canvas.js +0 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
class
|
|
1
|
+
var H = Object.defineProperty;
|
|
2
|
+
var G = (a, e, t) => e in a ? H(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
|
|
3
|
+
var l = (a, e, t) => G(a, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
class z {
|
|
5
5
|
pause() {
|
|
6
6
|
}
|
|
7
7
|
cleanup() {
|
|
@@ -9,12 +9,12 @@ class H {
|
|
|
9
9
|
onEnded(e) {
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
class
|
|
12
|
+
class Y {
|
|
13
13
|
createRemotePlayer(e) {
|
|
14
|
-
return new
|
|
14
|
+
return new z();
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
class
|
|
17
|
+
class q {
|
|
18
18
|
async getUserAudio(e) {
|
|
19
19
|
return navigator.mediaDevices.getUserMedia({
|
|
20
20
|
audio: e
|
|
@@ -24,7 +24,7 @@ class Y {
|
|
|
24
24
|
e.getTracks().forEach((t) => t.stop());
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
class
|
|
27
|
+
class X {
|
|
28
28
|
create(e) {
|
|
29
29
|
return new globalThis.RTCPeerConnection({
|
|
30
30
|
iceServers: e.iceServers,
|
|
@@ -32,24 +32,24 @@ class q {
|
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
class
|
|
35
|
+
class Z {
|
|
36
36
|
bind(e, t) {
|
|
37
|
-
return e.onopen = () => t.onOpen(), e.onerror = (
|
|
38
|
-
if (typeof
|
|
39
|
-
t.onMessage({ text:
|
|
37
|
+
return e.onopen = () => t.onOpen(), e.onerror = (i) => t.onError(i), e.onmessage = (i) => {
|
|
38
|
+
if (typeof i.data == "string") {
|
|
39
|
+
t.onMessage({ text: i.data });
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
|
-
if (
|
|
42
|
+
if (i.data instanceof ArrayBuffer) {
|
|
43
43
|
try {
|
|
44
|
-
const
|
|
45
|
-
(s == null ? void 0 : s.event) === "client_tool_call" && t.onMessage({ text:
|
|
44
|
+
const n = new TextDecoder().decode(i.data), s = JSON.parse(n);
|
|
45
|
+
(s == null ? void 0 : s.event) === "client_tool_call" && t.onMessage({ text: n });
|
|
46
46
|
} catch {
|
|
47
47
|
}
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
}, {
|
|
51
|
-
send(
|
|
52
|
-
e.readyState === "open" && e.send(
|
|
51
|
+
send(i) {
|
|
52
|
+
e.readyState === "open" && e.send(i);
|
|
53
53
|
},
|
|
54
54
|
isOpen() {
|
|
55
55
|
return e.readyState === "open";
|
|
@@ -60,7 +60,7 @@ class F {
|
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
const
|
|
63
|
+
const Q = "https://api.vanira.io", u = {
|
|
64
64
|
Form: "vanira_form",
|
|
65
65
|
Calendar: "vanira_calendar",
|
|
66
66
|
Navigate: "vanira_navigate",
|
|
@@ -71,42 +71,23 @@ const X = "https://api.vanira.io", h = {
|
|
|
71
71
|
SelectOption: "vanira_select_option",
|
|
72
72
|
SetDate: "vanira_set_date",
|
|
73
73
|
TypeText: "vanira_type_text",
|
|
74
|
+
WriteLatexText: "vanira_write_latex_text",
|
|
74
75
|
EraseText: "vanira_erase_text",
|
|
75
|
-
Draw: "vanira_draw",
|
|
76
|
-
EraseDraw: "vanira_erase_draw",
|
|
77
76
|
LiveVision: "vanira_live_vision",
|
|
78
77
|
CloseLiveCamera: "vanira_close_live_camera",
|
|
79
78
|
LiveScreen: "vanira_live_screen",
|
|
80
79
|
CloseLiveScreen: "vanira_close_live_screen",
|
|
81
80
|
ClipRegion: "vanira_clip_region",
|
|
82
|
-
|
|
83
|
-
ScreenInk: "vanira_screen_ink",
|
|
84
|
-
ScreenCursor: "vanira_screen_cursor",
|
|
85
|
-
ScreenClick: "vanira_screen_click",
|
|
86
|
-
ClearScreenOverlay: "vanira_clear_screen_overlay",
|
|
87
|
-
PageScan: "vanira_page_scan",
|
|
81
|
+
ScreenVision: "vanira_screen_vision",
|
|
88
82
|
PointAt: "vanira_point_at",
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
83
|
+
DrawOnScreen: "vanira_draw_on_screen",
|
|
84
|
+
ClearScreenDraw: "vanira_clear_screen_draw",
|
|
85
|
+
HighlightOnScreen: "vanira_highlight_on_screen"
|
|
86
|
+
}, F = Object.values(u), ee = new Set(F);
|
|
87
|
+
function V(a) {
|
|
88
|
+
return !!a && ee.has(a);
|
|
94
89
|
}
|
|
95
|
-
|
|
96
|
-
h.ScreenInk,
|
|
97
|
-
h.ScreenCursor,
|
|
98
|
-
h.ScreenClick,
|
|
99
|
-
h.ClearScreenOverlay,
|
|
100
|
-
h.PointAt,
|
|
101
|
-
h.OutlineTargets,
|
|
102
|
-
h.ClearGuide
|
|
103
|
-
]);
|
|
104
|
-
[
|
|
105
|
-
...ee,
|
|
106
|
-
h.PageScan,
|
|
107
|
-
h.TabScreenshot
|
|
108
|
-
];
|
|
109
|
-
function K(a) {
|
|
90
|
+
function j(a) {
|
|
110
91
|
if (typeof a == "string")
|
|
111
92
|
try {
|
|
112
93
|
return JSON.parse(a);
|
|
@@ -115,72 +96,89 @@ function K(a) {
|
|
|
115
96
|
}
|
|
116
97
|
return a && typeof a == "object" ? a : {};
|
|
117
98
|
}
|
|
118
|
-
const
|
|
119
|
-
type_on_whiteboard:
|
|
120
|
-
write_on_whiteboard:
|
|
121
|
-
write_on_white_board:
|
|
122
|
-
dom_typing_simulation:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
tab_screenshot:
|
|
138
|
-
capture_tab:
|
|
139
|
-
capture_tab_screenshot:
|
|
140
|
-
screenshot_tab:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
99
|
+
const N = {
|
|
100
|
+
type_on_whiteboard: u.TypeText,
|
|
101
|
+
write_on_whiteboard: u.TypeText,
|
|
102
|
+
write_on_white_board: u.TypeText,
|
|
103
|
+
dom_typing_simulation: u.TypeText,
|
|
104
|
+
write_latex_text: u.WriteLatexText,
|
|
105
|
+
write_latex_on_board: u.WriteLatexText,
|
|
106
|
+
latex_on_whiteboard: u.WriteLatexText,
|
|
107
|
+
erase_text: u.EraseText,
|
|
108
|
+
dom_erase: u.EraseText,
|
|
109
|
+
open_live_camera: u.LiveVision,
|
|
110
|
+
live_vision: u.LiveVision,
|
|
111
|
+
close_live_camera: u.CloseLiveCamera,
|
|
112
|
+
stop_live_camera: u.CloseLiveCamera,
|
|
113
|
+
open_live_screen: u.LiveScreen,
|
|
114
|
+
close_live_screen: u.CloseLiveScreen,
|
|
115
|
+
screen_vision: u.ScreenVision,
|
|
116
|
+
capture_screen_vision: u.ScreenVision,
|
|
117
|
+
capture_screen: u.ScreenVision,
|
|
118
|
+
tab_screenshot: u.ScreenVision,
|
|
119
|
+
capture_tab: u.ScreenVision,
|
|
120
|
+
capture_tab_screenshot: u.ScreenVision,
|
|
121
|
+
screenshot_tab: u.ScreenVision,
|
|
122
|
+
point_at: u.PointAt,
|
|
123
|
+
point_at_screen: u.PointAt,
|
|
124
|
+
draw_on_screen: u.DrawOnScreen,
|
|
125
|
+
screen_draw: u.DrawOnScreen,
|
|
126
|
+
clear_screen_draw: u.ClearScreenDraw,
|
|
127
|
+
clear_screen_annotations: u.ClearScreenDraw,
|
|
128
|
+
highlight_on_screen: u.HighlightOnScreen,
|
|
129
|
+
highlight_element_on_screen: u.HighlightOnScreen,
|
|
130
|
+
highlight_screen_element: u.HighlightOnScreen
|
|
131
|
+
}, B = {
|
|
132
|
+
vanira_tab_screenshot: u.ScreenVision
|
|
147
133
|
};
|
|
148
|
-
function
|
|
134
|
+
function te(a, e) {
|
|
135
|
+
const t = a.latex_text ?? (e == null ? void 0 : e.latex_text);
|
|
136
|
+
return typeof t == "string" && t.trim().length > 0;
|
|
137
|
+
}
|
|
138
|
+
function D(a, e) {
|
|
149
139
|
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);
|
|
150
140
|
return typeof t == "string" && t.trim().length > 0;
|
|
151
141
|
}
|
|
152
|
-
function
|
|
142
|
+
function ie(a, e) {
|
|
153
143
|
const t = a.fields ?? (e == null ? void 0 : e.fields);
|
|
154
|
-
return Array.isArray(t) ? t.length > 0 : typeof t == "string" ? t.split(",").map((
|
|
144
|
+
return Array.isArray(t) ? t.length > 0 : typeof t == "string" ? t.split(",").map((i) => i.trim()).filter(Boolean).length > 0 : !1;
|
|
155
145
|
}
|
|
156
146
|
function ne(a, e) {
|
|
157
147
|
const t = a == null ? void 0 : a.preset_id;
|
|
158
|
-
if (typeof t == "string"
|
|
159
|
-
return t;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
148
|
+
if (typeof t == "string") {
|
|
149
|
+
if (V(t)) return t;
|
|
150
|
+
const s = B[t];
|
|
151
|
+
if (s) return s;
|
|
152
|
+
}
|
|
153
|
+
const n = j(e).preset_id;
|
|
154
|
+
if (typeof n == "string") {
|
|
155
|
+
if (V(n)) return n;
|
|
156
|
+
const s = B[n];
|
|
157
|
+
if (s) return s;
|
|
158
|
+
}
|
|
163
159
|
}
|
|
164
|
-
function
|
|
165
|
-
const
|
|
166
|
-
let
|
|
167
|
-
if (
|
|
168
|
-
return
|
|
169
|
-
if (
|
|
160
|
+
function ae(a, e, t) {
|
|
161
|
+
const i = j(e);
|
|
162
|
+
let n = ne(a, i);
|
|
163
|
+
if (n === u.Form && D(i, a) && !ie(i, a))
|
|
164
|
+
return u.TypeText;
|
|
165
|
+
if (n) return n;
|
|
170
166
|
const s = String(t ?? "").trim().toLowerCase();
|
|
171
|
-
if (s &&
|
|
172
|
-
return
|
|
173
|
-
if (
|
|
174
|
-
return
|
|
167
|
+
if (s && N[s])
|
|
168
|
+
return N[s];
|
|
169
|
+
if (te(i, a))
|
|
170
|
+
return u.WriteLatexText;
|
|
171
|
+
if (D(i, a))
|
|
172
|
+
return u.TypeText;
|
|
175
173
|
}
|
|
176
|
-
const g = "vanira_latest_call_id",
|
|
174
|
+
const g = "vanira_latest_call_id", R = "vanira_prospect_id";
|
|
177
175
|
function C(a) {
|
|
178
176
|
return `vanira_latest_call_id_${a}`;
|
|
179
177
|
}
|
|
180
178
|
function I(a) {
|
|
181
179
|
return `vanira_prospect_id_${a}`;
|
|
182
180
|
}
|
|
183
|
-
function
|
|
181
|
+
function W(a) {
|
|
184
182
|
return `vanira_call_meta_${a}`;
|
|
185
183
|
}
|
|
186
184
|
function S(a, e) {
|
|
@@ -191,148 +189,148 @@ function S(a, e) {
|
|
|
191
189
|
return null;
|
|
192
190
|
}
|
|
193
191
|
}
|
|
194
|
-
function
|
|
192
|
+
function $(a) {
|
|
195
193
|
if (typeof window > "u" || !a) return null;
|
|
196
|
-
const e = [], t = S(window.localStorage,
|
|
194
|
+
const e = [], t = S(window.localStorage, W(a));
|
|
197
195
|
if (t)
|
|
198
196
|
try {
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
callId:
|
|
202
|
-
prospectId:
|
|
203
|
-
updatedAt:
|
|
197
|
+
const d = JSON.parse(t);
|
|
198
|
+
d != null && d.callId && e.push({
|
|
199
|
+
callId: d.callId,
|
|
200
|
+
prospectId: d.prospectId,
|
|
201
|
+
updatedAt: d.updatedAt || 0
|
|
204
202
|
});
|
|
205
203
|
} catch {
|
|
206
204
|
}
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
callId:
|
|
205
|
+
const i = (d, r, h) => {
|
|
206
|
+
d && e.push({
|
|
207
|
+
callId: d,
|
|
210
208
|
prospectId: r || void 0,
|
|
211
|
-
updatedAt:
|
|
209
|
+
updatedAt: h
|
|
212
210
|
});
|
|
213
|
-
},
|
|
214
|
-
return
|
|
211
|
+
}, n = S(window.localStorage, I(a)), s = S(window.sessionStorage, I(a)), o = S(window.localStorage, R);
|
|
212
|
+
return i(
|
|
215
213
|
S(window.localStorage, C(a)),
|
|
216
|
-
|
|
214
|
+
n || o,
|
|
217
215
|
2
|
|
218
|
-
),
|
|
216
|
+
), i(
|
|
219
217
|
S(window.sessionStorage, C(a)),
|
|
220
218
|
s || o,
|
|
221
219
|
1
|
|
222
|
-
),
|
|
220
|
+
), i(S(window.localStorage, g), o, 0), i(S(window.sessionStorage, g), o, 0), e.length ? (e.sort((d, r) => r.updatedAt - d.updatedAt), e[0]) : null;
|
|
223
221
|
}
|
|
224
|
-
function
|
|
225
|
-
var
|
|
222
|
+
function se(a, e, t) {
|
|
223
|
+
var n, s, o, d, r, h, p, c, _;
|
|
226
224
|
if (typeof window > "u" || !a || !e) return;
|
|
227
|
-
const
|
|
225
|
+
const i = {
|
|
228
226
|
callId: e,
|
|
229
227
|
prospectId: t,
|
|
230
228
|
updatedAt: Date.now()
|
|
231
229
|
};
|
|
232
230
|
try {
|
|
233
|
-
(
|
|
231
|
+
(n = window.localStorage) == null || n.setItem(W(a), JSON.stringify(i)), (s = window.localStorage) == null || s.setItem(C(a), e), (o = window.sessionStorage) == null || o.setItem(C(a), e), t && ((d = window.localStorage) == null || d.setItem(I(a), t), (r = window.sessionStorage) == null || r.setItem(I(a), t)), (h = window.localStorage) == null || h.setItem(g, e), (p = window.sessionStorage) == null || p.setItem(g, e), t && ((c = window.localStorage) == null || c.setItem(R, t), (_ = window.sessionStorage) == null || _.setItem(R, t));
|
|
234
232
|
} catch {
|
|
235
233
|
}
|
|
236
234
|
}
|
|
237
|
-
const
|
|
235
|
+
const re = /* @__PURE__ */ new Set([
|
|
238
236
|
"client_tool_call",
|
|
239
237
|
"clearAudio",
|
|
240
238
|
"client_tool_cancel"
|
|
241
239
|
]);
|
|
242
|
-
function
|
|
240
|
+
function oe(a) {
|
|
243
241
|
if (!a || typeof a != "object") return !1;
|
|
244
242
|
const e = a.event;
|
|
245
|
-
return typeof e == "string" &&
|
|
243
|
+
return typeof e == "string" && re.has(e);
|
|
246
244
|
}
|
|
247
|
-
const T = 16 * 1024,
|
|
245
|
+
const T = 16 * 1024, ce = 256 * 1024;
|
|
248
246
|
function E(a, e) {
|
|
249
247
|
return (a == null ? void 0 : a.readyState) === "open" && (e == null ? void 0 : e.readyState) === "open";
|
|
250
248
|
}
|
|
251
|
-
function
|
|
249
|
+
function le(a, e) {
|
|
252
250
|
return {
|
|
253
251
|
control: (a == null ? void 0 : a.readyState) ?? "missing",
|
|
254
252
|
mediaBytes: (e == null ? void 0 : e.readyState) ?? "missing"
|
|
255
253
|
};
|
|
256
254
|
}
|
|
257
|
-
async function
|
|
255
|
+
async function de(a, e, t = 8e3) {
|
|
258
256
|
if (E(a, e))
|
|
259
257
|
return !0;
|
|
260
|
-
const
|
|
261
|
-
for (; Date.now() <
|
|
258
|
+
const i = Date.now() + t;
|
|
259
|
+
for (; Date.now() < i; ) {
|
|
262
260
|
if (E(a, e))
|
|
263
261
|
return !0;
|
|
264
|
-
await new Promise((
|
|
262
|
+
await new Promise((n) => setTimeout(n, 50));
|
|
265
263
|
}
|
|
266
264
|
return E(a, e);
|
|
267
265
|
}
|
|
268
|
-
async function
|
|
269
|
-
for (; a.bufferedAmount >
|
|
266
|
+
async function K(a) {
|
|
267
|
+
for (; a.bufferedAmount > ce; )
|
|
270
268
|
await new Promise((e) => setTimeout(e, 10));
|
|
271
269
|
}
|
|
272
|
-
async function
|
|
270
|
+
async function he(a) {
|
|
273
271
|
const {
|
|
274
272
|
bytes: e,
|
|
275
273
|
filename: t,
|
|
276
|
-
contentType:
|
|
277
|
-
reason:
|
|
274
|
+
contentType: i,
|
|
275
|
+
reason: n,
|
|
278
276
|
message: s,
|
|
279
277
|
callId: o,
|
|
280
|
-
mediaBytesChannel:
|
|
278
|
+
mediaBytesChannel: d,
|
|
281
279
|
sendControlEvent: r,
|
|
282
|
-
uploadId:
|
|
280
|
+
uploadId: h = crypto.randomUUID(),
|
|
283
281
|
uploadKind: p = "media"
|
|
284
|
-
} = a,
|
|
282
|
+
} = a, c = e.byteLength, _ = c === 0 ? 0 : Math.ceil(c / T);
|
|
285
283
|
r("client_media_upload_start", {
|
|
286
284
|
data: {
|
|
287
|
-
upload_id:
|
|
285
|
+
upload_id: h,
|
|
288
286
|
call_id: o,
|
|
289
|
-
reason:
|
|
287
|
+
reason: n,
|
|
290
288
|
message: s,
|
|
291
289
|
filename: t,
|
|
292
|
-
content_type:
|
|
293
|
-
size:
|
|
290
|
+
content_type: i,
|
|
291
|
+
size: c,
|
|
294
292
|
chunk_count: _,
|
|
295
293
|
upload_kind: p
|
|
296
294
|
}
|
|
297
295
|
});
|
|
298
296
|
const m = new Uint8Array(e);
|
|
299
|
-
for (let f = 0; f <
|
|
300
|
-
await
|
|
301
|
-
const v = Math.min(f + T,
|
|
302
|
-
|
|
297
|
+
for (let f = 0; f < c; f += T) {
|
|
298
|
+
await K(d);
|
|
299
|
+
const v = Math.min(f + T, c);
|
|
300
|
+
d.send(m.subarray(f, v));
|
|
303
301
|
}
|
|
304
|
-
return await
|
|
302
|
+
return await K(d), r("client_media_upload_complete", {
|
|
305
303
|
data: {
|
|
306
|
-
upload_id:
|
|
304
|
+
upload_id: h,
|
|
307
305
|
call_id: o,
|
|
308
|
-
reason:
|
|
306
|
+
reason: n,
|
|
309
307
|
message: s,
|
|
310
308
|
chunk_count: _,
|
|
311
309
|
upload_kind: p
|
|
312
310
|
}
|
|
313
|
-
}), { media_id:
|
|
311
|
+
}), { media_id: h, url: "", content_type: i };
|
|
314
312
|
}
|
|
315
|
-
async function
|
|
313
|
+
async function ue(a) {
|
|
316
314
|
return typeof a.arrayBuffer == "function" ? a.arrayBuffer() : new Response(a).arrayBuffer();
|
|
317
315
|
}
|
|
318
|
-
function
|
|
316
|
+
function pe(a) {
|
|
319
317
|
return null;
|
|
320
318
|
}
|
|
321
319
|
function y() {
|
|
322
320
|
return typeof window > "u" ? "/" : `${window.location.pathname}${window.location.search}${window.location.hash}` || "/";
|
|
323
321
|
}
|
|
324
|
-
class
|
|
322
|
+
class _e {
|
|
325
323
|
constructor(e) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
324
|
+
l(this, "active", !1);
|
|
325
|
+
l(this, "initialSent", !1);
|
|
326
|
+
l(this, "lastRoute", "");
|
|
327
|
+
l(this, "sendContext");
|
|
328
|
+
l(this, "isReady");
|
|
329
|
+
l(this, "cleanupFns", []);
|
|
330
|
+
l(this, "initialRetryTimer", null);
|
|
331
|
+
l(this, "routePollTimer", null);
|
|
332
|
+
l(this, "originalPushState", null);
|
|
333
|
+
l(this, "originalReplaceState", null);
|
|
336
334
|
this.sendContext = e.sendContext, this.isReady = e.isReady ?? (() => !0);
|
|
337
335
|
}
|
|
338
336
|
start() {
|
|
@@ -367,12 +365,12 @@ class pe {
|
|
|
367
365
|
}
|
|
368
366
|
attachListeners() {
|
|
369
367
|
const e = (s, o = 0) => {
|
|
370
|
-
const
|
|
368
|
+
const d = () => {
|
|
371
369
|
const r = y();
|
|
372
370
|
r !== this.lastRoute && this.handleRouteChange(r, s);
|
|
373
371
|
};
|
|
374
|
-
o > 0 ? window.setTimeout(
|
|
375
|
-
}, t = () => e("popstate"),
|
|
372
|
+
o > 0 ? window.setTimeout(d, o) : queueMicrotask(d);
|
|
373
|
+
}, t = () => e("popstate"), i = () => e("hashchange"), n = (s) => {
|
|
376
374
|
const o = s.detail;
|
|
377
375
|
if ((o == null ? void 0 : o.initiated_by) === "agent") {
|
|
378
376
|
e("vanira_navigate_agent", 120);
|
|
@@ -380,10 +378,10 @@ class pe {
|
|
|
380
378
|
}
|
|
381
379
|
e("vanira_navigate", 120);
|
|
382
380
|
};
|
|
383
|
-
window.addEventListener("popstate", t), window.addEventListener("hashchange",
|
|
381
|
+
window.addEventListener("popstate", t), window.addEventListener("hashchange", i), window.addEventListener("vanira:navigate", n), this.cleanupFns.push(
|
|
384
382
|
() => window.removeEventListener("popstate", t),
|
|
385
|
-
() => window.removeEventListener("hashchange",
|
|
386
|
-
() => window.removeEventListener("vanira:navigate",
|
|
383
|
+
() => window.removeEventListener("hashchange", i),
|
|
384
|
+
() => window.removeEventListener("vanira:navigate", n)
|
|
387
385
|
), this.originalPushState = history.pushState.bind(history), this.originalReplaceState = history.replaceState.bind(history), history.pushState = (...s) => {
|
|
388
386
|
this.originalPushState(...s), e("pushState");
|
|
389
387
|
}, history.replaceState = (...s) => {
|
|
@@ -396,25 +394,25 @@ class pe {
|
|
|
396
394
|
}
|
|
397
395
|
handleRouteChange(e, t) {
|
|
398
396
|
if (!this.active) return;
|
|
399
|
-
const
|
|
400
|
-
if (
|
|
397
|
+
const i = this.lastRoute;
|
|
398
|
+
if (i === e) return;
|
|
401
399
|
if (this.lastRoute = e, !this.initialSent) {
|
|
402
400
|
this.scheduleInitialContextSend();
|
|
403
401
|
return;
|
|
404
402
|
}
|
|
405
|
-
!this.isReady() ||
|
|
403
|
+
!this.isReady() || pe() || this.sendRouteContext("route_changed", i, t, "user");
|
|
406
404
|
}
|
|
407
|
-
sendRouteContext(e, t,
|
|
405
|
+
sendRouteContext(e, t, i, n = "user") {
|
|
408
406
|
const s = y();
|
|
409
407
|
this.lastRoute = s;
|
|
410
408
|
const o = {
|
|
411
409
|
ui_state: "page_navigation",
|
|
412
|
-
navigation_led_by:
|
|
410
|
+
navigation_led_by: n,
|
|
413
411
|
current_route: s,
|
|
414
412
|
current_page: s,
|
|
415
413
|
user_action: e === "call_started" ? "call_started_on_page" : "user_navigated"
|
|
416
414
|
};
|
|
417
|
-
e === "call_started" ? o.message = `User started the call while viewing ${s}.` : (o.previous_route = t ?? "", o.message = `User navigated from ${t || "(unknown)"} to ${s}.`,
|
|
415
|
+
e === "call_started" ? o.message = `User started the call while viewing ${s}.` : (o.previous_route = t ?? "", o.message = `User navigated from ${t || "(unknown)"} to ${s}.`, i && (o.navigation_source = i));
|
|
418
416
|
try {
|
|
419
417
|
this.sendContext(o);
|
|
420
418
|
} catch {
|
|
@@ -423,69 +421,69 @@ class pe {
|
|
|
423
421
|
}
|
|
424
422
|
const w = class w {
|
|
425
423
|
constructor(e) {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
424
|
+
l(this, "serverUrl");
|
|
425
|
+
l(this, "agentId");
|
|
426
|
+
l(this, "callId");
|
|
427
|
+
l(this, "prospectId");
|
|
428
|
+
l(this, "apiKey");
|
|
429
|
+
l(this, "backendUrl");
|
|
430
|
+
l(this, "token");
|
|
431
|
+
l(this, "onConnected");
|
|
432
|
+
l(this, "onDisconnected");
|
|
433
|
+
l(this, "onError");
|
|
434
|
+
l(this, "onTranscription");
|
|
435
|
+
l(this, "onLocalStream");
|
|
438
436
|
// @ts-ignore
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
437
|
+
l(this, "onRemoteTrack");
|
|
438
|
+
l(this, "onClientToolCall");
|
|
439
|
+
l(this, "onSessionStarted");
|
|
440
|
+
l(this, "sessionStartedEmitted", !1);
|
|
441
|
+
l(this, "pc", null);
|
|
442
|
+
l(this, "dataChannel", null);
|
|
443
|
+
l(this, "mediaBytesChannel", null);
|
|
444
|
+
l(this, "audioElement", null);
|
|
445
|
+
l(this, "localStream", null);
|
|
446
|
+
l(this, "micMuted", !1);
|
|
447
|
+
l(this, "connected", !1);
|
|
448
|
+
l(this, "icePollInterval", null);
|
|
449
|
+
l(this, "appliedRemoteCandidates", /* @__PURE__ */ new Set());
|
|
450
|
+
l(this, "iceServers");
|
|
451
|
+
l(this, "callSessionLoaded", !1);
|
|
452
|
+
l(this, "connectGeneration", 0);
|
|
453
|
+
l(this, "runtime");
|
|
454
|
+
l(this, "sessionBehavior");
|
|
455
|
+
l(this, "routeTracker", null);
|
|
456
|
+
l(this, "_status", "idle");
|
|
457
|
+
l(this, "listeners", /* @__PURE__ */ new Map());
|
|
460
458
|
/** Live vision config — auto-starts camera on connect when scope is full_call. */
|
|
461
|
-
|
|
462
|
-
|
|
459
|
+
l(this, "liveVision");
|
|
460
|
+
l(this, "liveVisionAutoStarted", !1);
|
|
463
461
|
if (!e.agentId) throw new Error("agentId is required");
|
|
464
|
-
const t = !!(e.apiKey || e.token),
|
|
462
|
+
const t = !!(e.apiKey || e.token), i = !!(e.serverUrl && e.callId), n = w.normalizeIceServers(
|
|
465
463
|
e.iceServers
|
|
466
464
|
);
|
|
467
|
-
if (!t && !
|
|
465
|
+
if (!t && !i)
|
|
468
466
|
throw new Error(
|
|
469
467
|
"apiKey or token is required — or pass serverUrl and callId from a prior POST /calls/create"
|
|
470
468
|
);
|
|
471
|
-
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 ||
|
|
469
|
+
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 || Q).replace(/\/$/, ""), n.length && (this.iceServers = n), i && (this.callSessionLoaded = !0);
|
|
472
470
|
const s = typeof window < "u";
|
|
473
471
|
this.prospectId = e.prospectId;
|
|
474
472
|
const o = e.sessionBehavior === "continue";
|
|
475
473
|
if (o && s && !e.callId) {
|
|
476
|
-
const r =
|
|
474
|
+
const r = $(this.agentId);
|
|
477
475
|
r && (e.callId || (this.callId = r.callId), !this.prospectId && r.prospectId && (this.prospectId = r.prospectId));
|
|
478
476
|
}
|
|
479
477
|
if (!this.prospectId && s)
|
|
480
478
|
try {
|
|
481
|
-
const r =
|
|
479
|
+
const r = $(this.agentId);
|
|
482
480
|
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;
|
|
483
481
|
} catch {
|
|
484
482
|
}
|
|
485
483
|
e.callId ? this.callId = e.callId : o || (this.callId = void 0);
|
|
486
|
-
const
|
|
484
|
+
const d = e.onSessionStarted;
|
|
487
485
|
this.onSessionStarted = (r) => {
|
|
488
|
-
|
|
486
|
+
d == null || d(r), this.emit("session_started", r);
|
|
489
487
|
}, this.liveVision = e.liveVision, this.onConnected = () => {
|
|
490
488
|
var r;
|
|
491
489
|
this._status = "connected", (r = e.onConnected) == null || r.call(e), this.emit("connected"), this.maybeAutoStartLiveCamera();
|
|
@@ -495,27 +493,27 @@ const w = class w {
|
|
|
495
493
|
}, this.onError = (r) => {
|
|
496
494
|
var p;
|
|
497
495
|
this._status = "error";
|
|
498
|
-
const
|
|
499
|
-
(p = e.onError) == null || p.call(e, r), this.emit("error",
|
|
500
|
-
}, this.onTranscription = (r,
|
|
496
|
+
const h = typeof r == "string" ? r : (r == null ? void 0 : r.message) || "Connection error";
|
|
497
|
+
(p = e.onError) == null || p.call(e, r), this.emit("error", h);
|
|
498
|
+
}, this.onTranscription = (r, h) => {
|
|
501
499
|
var p;
|
|
502
|
-
(p = e.onTranscription) == null || p.call(e, r,
|
|
500
|
+
(p = e.onTranscription) == null || p.call(e, r, h), this.emit("transcription", { text: r, isFinal: h });
|
|
503
501
|
}, this.onLocalStream = e.onLocalStream || (() => {
|
|
504
|
-
}), this.onRemoteTrack = (r,
|
|
502
|
+
}), this.onRemoteTrack = (r, h) => {
|
|
505
503
|
var p;
|
|
506
|
-
(p = e.onRemoteTrack) == null || p.call(e, r,
|
|
504
|
+
(p = e.onRemoteTrack) == null || p.call(e, r, h), this.emit("track", { track: r, stream: h });
|
|
507
505
|
}, this.onClientToolCall = (r) => {
|
|
508
|
-
var
|
|
509
|
-
(
|
|
510
|
-
const
|
|
511
|
-
name: String(
|
|
512
|
-
arguments:
|
|
513
|
-
tool_call_id: String(
|
|
514
|
-
execution_mode:
|
|
515
|
-
client_fields:
|
|
506
|
+
var c;
|
|
507
|
+
(c = e.onClientToolCall) == null || c.call(e, r);
|
|
508
|
+
const h = (r == null ? void 0 : r.data) || r, p = {
|
|
509
|
+
name: String(h.name || h.tool_name || ""),
|
|
510
|
+
arguments: h.arguments || h.args || {},
|
|
511
|
+
tool_call_id: String(h.tool_call_id || h.call_id || ""),
|
|
512
|
+
execution_mode: h.execution_mode === "blocking" ? "blocking" : "fire_and_forget",
|
|
513
|
+
client_fields: h.client_fields || {}
|
|
516
514
|
};
|
|
517
515
|
p.name && p.tool_call_id && this.emit("tool_call", p);
|
|
518
|
-
}, this.runtime = e.runtime, typeof window < "u" && e.trackRouteContext !== !1 && (this.routeTracker = new
|
|
516
|
+
}, this.runtime = e.runtime, typeof window < "u" && e.trackRouteContext !== !1 && (this.routeTracker = new _e({
|
|
519
517
|
sendContext: (r) => this.sendContextUpdate(r),
|
|
520
518
|
isReady: () => {
|
|
521
519
|
var r;
|
|
@@ -555,14 +553,14 @@ const w = class w {
|
|
|
555
553
|
}
|
|
556
554
|
try {
|
|
557
555
|
this.appliedRemoteCandidates.clear(), this.stopRemoteIcePolling();
|
|
558
|
-
const
|
|
556
|
+
const i = this.getIceServers();
|
|
559
557
|
this.pc = new RTCPeerConnection({
|
|
560
|
-
iceServers:
|
|
558
|
+
iceServers: i,
|
|
561
559
|
iceTransportPolicy: "all"
|
|
562
560
|
});
|
|
563
|
-
let
|
|
561
|
+
let n;
|
|
564
562
|
try {
|
|
565
|
-
|
|
563
|
+
n = await navigator.mediaDevices.getUserMedia({
|
|
566
564
|
audio: {
|
|
567
565
|
echoCancellation: !0,
|
|
568
566
|
noiseSuppression: !0,
|
|
@@ -571,82 +569,82 @@ const w = class w {
|
|
|
571
569
|
channelCount: 1
|
|
572
570
|
}
|
|
573
571
|
});
|
|
574
|
-
} catch (
|
|
575
|
-
if (
|
|
572
|
+
} catch (c) {
|
|
573
|
+
if (c.name === "NotAllowedError" || c.name === "PermissionDeniedError" || (t = c.message) != null && t.includes("Permission denied")) {
|
|
576
574
|
const _ = navigator.userAgent, m = /iPad|iPhone|iPod/.test(_) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
|
|
577
575
|
let f = "Microphone access denied. Please allow microphone access in your browser settings.";
|
|
578
576
|
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).");
|
|
579
577
|
const v = new Error(f);
|
|
580
|
-
throw v.name =
|
|
578
|
+
throw v.name = c.name, v;
|
|
581
579
|
}
|
|
582
|
-
throw
|
|
580
|
+
throw c;
|
|
583
581
|
}
|
|
584
582
|
if (this.isConnectCancelled(e)) {
|
|
585
|
-
|
|
583
|
+
n.getTracks().forEach((c) => c.stop());
|
|
586
584
|
return;
|
|
587
585
|
}
|
|
588
|
-
if (this.localStream =
|
|
589
|
-
|
|
586
|
+
if (this.localStream = n, !this.pc || this.isConnectCancelled(e)) {
|
|
587
|
+
n.getTracks().forEach((c) => c.stop());
|
|
590
588
|
return;
|
|
591
589
|
}
|
|
592
|
-
if (this.onLocalStream(
|
|
590
|
+
if (this.onLocalStream(n), n.getTracks().forEach((c) => {
|
|
593
591
|
var _;
|
|
594
|
-
(_ = this.pc) == null || _.addTrack(
|
|
592
|
+
(_ = this.pc) == null || _.addTrack(c, n);
|
|
595
593
|
}), !this.pc)
|
|
596
594
|
throw new Error("RTCPeerConnection was closed unexpectedly");
|
|
597
595
|
this.dataChannel = this.pc.createDataChannel("control"), this.dataChannel.onopen = () => {
|
|
598
|
-
var
|
|
599
|
-
(
|
|
600
|
-
}, this.dataChannel.onmessage = (
|
|
601
|
-
if (typeof
|
|
596
|
+
var c;
|
|
597
|
+
(c = this.routeTracker) == null || c.onChannelReady();
|
|
598
|
+
}, this.dataChannel.onmessage = (c) => {
|
|
599
|
+
if (typeof c.data == "string")
|
|
602
600
|
try {
|
|
603
|
-
this.handleControlEvent(JSON.parse(
|
|
601
|
+
this.handleControlEvent(JSON.parse(c.data));
|
|
604
602
|
} catch {
|
|
605
603
|
}
|
|
606
|
-
else if (
|
|
604
|
+
else if (c.data instanceof ArrayBuffer)
|
|
607
605
|
try {
|
|
608
|
-
const _ = new TextDecoder().decode(
|
|
606
|
+
const _ = new TextDecoder().decode(c.data);
|
|
609
607
|
try {
|
|
610
608
|
const m = JSON.parse(_);
|
|
611
|
-
|
|
609
|
+
oe(m) && this.handleControlEvent(m);
|
|
612
610
|
} catch {
|
|
613
611
|
}
|
|
614
612
|
} catch {
|
|
615
613
|
}
|
|
616
|
-
else
|
|
614
|
+
else c.data instanceof Blob && c.data.text().then((_) => {
|
|
617
615
|
try {
|
|
618
616
|
this.handleControlEvent(JSON.parse(_));
|
|
619
617
|
} catch {
|
|
620
618
|
}
|
|
621
619
|
});
|
|
622
|
-
}, this.dataChannel.onerror = (
|
|
620
|
+
}, this.dataChannel.onerror = (c) => {
|
|
623
621
|
}, this.mediaBytesChannel = this.pc.createDataChannel("media-bytes", { ordered: !0 }), this.mediaBytesChannel.binaryType = "arraybuffer", this.mediaBytesChannel.onopen = () => {
|
|
624
|
-
}, this.mediaBytesChannel.onerror = (
|
|
625
|
-
}, this.pc.ontrack = (
|
|
626
|
-
const _ =
|
|
622
|
+
}, this.mediaBytesChannel.onerror = (c) => {
|
|
623
|
+
}, this.pc.ontrack = (c) => {
|
|
624
|
+
const _ = c.track, m = c.streams[0];
|
|
627
625
|
_.kind === "audio" ? (this.audioElement = new Audio(), this.audioElement.srcObject = m, this.audioElement.play().catch((f) => {
|
|
628
626
|
}), this.audioElement.onended = () => {
|
|
629
627
|
this.sendEvent("playedStream"), typeof window < "u" && window.dispatchEvent(new CustomEvent("vanira:agent-playback-ended"));
|
|
630
628
|
}, this.onRemoteTrack(_, m)) : _.kind === "video" && this.onRemoteTrack(_, m);
|
|
631
629
|
};
|
|
632
630
|
const s = () => {
|
|
633
|
-
var m, f, v, b,
|
|
634
|
-
const
|
|
635
|
-
((M = this.pc) == null ? void 0 : M.connectionState) === "connected" && this.stopRemoteIcePolling(),
|
|
631
|
+
var m, f, v, b, x, A, P, U, L, M, O;
|
|
632
|
+
const c = ((m = this.pc) == null ? void 0 : m.connectionState) === "connected" || ((f = this.pc) == null ? void 0 : f.iceConnectionState) === "connected" || ((v = this.pc) == null ? void 0 : v.iceConnectionState) === "completed", _ = ((b = this.pc) == null ? void 0 : b.connectionState) === "failed" || ((x = this.pc) == null ? void 0 : x.iceConnectionState) === "failed" || ((A = this.pc) == null ? void 0 : A.connectionState) === "closed" || ((P = this.pc) == null ? void 0 : P.iceConnectionState) === "closed" || ((U = this.pc) == null ? void 0 : U.connectionState) === "disconnected" || ((L = this.pc) == null ? void 0 : L.iceConnectionState) === "disconnected";
|
|
633
|
+
((M = this.pc) == null ? void 0 : M.connectionState) === "connected" && this.stopRemoteIcePolling(), c && !this.connected ? (this.connected = !0, (O = this.routeTracker) == null || O.start(), this.onConnected()) : _ && this.connected && (this.connected = !1, this.liveVisionAutoStarted = !1, this.onDisconnected());
|
|
636
634
|
};
|
|
637
635
|
this.pc.onconnectionstatechange = s, this.pc.oniceconnectionstatechange = s;
|
|
638
636
|
const o = this.getIceTrickleUrl();
|
|
639
|
-
this.pc.onicecandidate = (
|
|
640
|
-
|
|
637
|
+
this.pc.onicecandidate = (c) => {
|
|
638
|
+
c.candidate && fetch(o, {
|
|
641
639
|
method: "POST",
|
|
642
640
|
headers: { "Content-Type": "application/json" },
|
|
643
|
-
body: JSON.stringify({ candidate:
|
|
641
|
+
body: JSON.stringify({ candidate: c.candidate.toJSON() })
|
|
644
642
|
}).catch((_) => {
|
|
645
643
|
});
|
|
646
644
|
};
|
|
647
|
-
const
|
|
648
|
-
if (this.isConnectCancelled(e) || (await this.pc.setLocalDescription(
|
|
649
|
-
const r = this.serverUrl.includes("?") ? this.serverUrl : `${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`,
|
|
645
|
+
const d = await this.pc.createOffer();
|
|
646
|
+
if (this.isConnectCancelled(e) || (await this.pc.setLocalDescription(d), this.isConnectCancelled(e))) return;
|
|
647
|
+
const r = this.serverUrl.includes("?") ? this.serverUrl : `${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`, h = await fetch(r, {
|
|
650
648
|
method: "POST",
|
|
651
649
|
headers: { "Content-Type": "application/json" },
|
|
652
650
|
body: JSON.stringify({
|
|
@@ -656,49 +654,49 @@ const w = class w {
|
|
|
656
654
|
})
|
|
657
655
|
});
|
|
658
656
|
if (this.isConnectCancelled(e)) return;
|
|
659
|
-
if (!
|
|
660
|
-
const
|
|
661
|
-
throw new Error(
|
|
657
|
+
if (!h.ok) {
|
|
658
|
+
const c = await h.json();
|
|
659
|
+
throw new Error(c.error || `HTTP ${h.status}`);
|
|
662
660
|
}
|
|
663
|
-
const { answer: p } = await
|
|
661
|
+
const { answer: p } = await h.json();
|
|
664
662
|
if (this.isConnectCancelled(e) || !this.pc || (await this.pc.setRemoteDescription(p), this.isConnectCancelled(e))) return;
|
|
665
663
|
this.startRemoteIcePolling(o);
|
|
666
|
-
} catch (
|
|
664
|
+
} catch (i) {
|
|
667
665
|
if (this.isConnectCancelled(e)) return;
|
|
668
|
-
throw this.disconnect(), this.onError(
|
|
666
|
+
throw this.disconnect(), this.onError(i.message || i), i;
|
|
669
667
|
}
|
|
670
668
|
}
|
|
671
669
|
}
|
|
672
670
|
createCallCacheKey(e, t) {
|
|
673
|
-
const
|
|
671
|
+
const i = this.apiKey ? `key:${this.apiKey.slice(0, 16)}` : `token:${(this.token || "").slice(-16)}`;
|
|
674
672
|
return [
|
|
675
673
|
this.backendUrl,
|
|
676
674
|
this.agentId,
|
|
677
675
|
e,
|
|
678
676
|
t || "",
|
|
679
677
|
this.prospectId || "",
|
|
680
|
-
|
|
678
|
+
i
|
|
681
679
|
].join("|");
|
|
682
680
|
}
|
|
683
|
-
async postCreateCall(e, t,
|
|
684
|
-
var
|
|
685
|
-
const
|
|
681
|
+
async postCreateCall(e, t, i) {
|
|
682
|
+
var d, r, h;
|
|
683
|
+
const n = await fetch(`${this.backendUrl}/calls/create`, {
|
|
686
684
|
method: "POST",
|
|
687
685
|
headers: e,
|
|
688
686
|
body: JSON.stringify({
|
|
689
687
|
agent_id: this.agentId,
|
|
690
|
-
type: ((
|
|
688
|
+
type: ((d = this.runtime) == null ? void 0 : d.callType) || "web",
|
|
691
689
|
mode: t,
|
|
692
690
|
...(r = this.runtime) != null && r.runtimeName ? { runtime: this.runtime.runtimeName } : {},
|
|
693
691
|
prospect_id: this.prospectId,
|
|
694
|
-
...
|
|
692
|
+
...i ? { call_id: i } : {}
|
|
695
693
|
})
|
|
696
694
|
});
|
|
697
|
-
if (!
|
|
698
|
-
const p = await
|
|
699
|
-
throw new Error(`[VaniraClient] createCall failed (${
|
|
695
|
+
if (!n.ok) {
|
|
696
|
+
const p = await n.json().catch(() => ({}));
|
|
697
|
+
throw new Error(`[VaniraClient] createCall failed (${n.status}): ${((h = p == null ? void 0 : p.detail) == null ? void 0 : h.message) || (p == null ? void 0 : p.message) || n.statusText}`);
|
|
700
698
|
}
|
|
701
|
-
const s = await
|
|
699
|
+
const s = await n.json();
|
|
702
700
|
if (!s.call_id || !s.worker_url)
|
|
703
701
|
throw new Error("[VaniraClient] /calls/create response missing call_id or worker_url");
|
|
704
702
|
const o = w.normalizeIceServers(s.ice_servers);
|
|
@@ -712,7 +710,7 @@ const w = class w {
|
|
|
712
710
|
};
|
|
713
711
|
}
|
|
714
712
|
applyCreateCallSession(e) {
|
|
715
|
-
if (this.callId = e.callId, this.prospectId = e.prospectId || this.prospectId, this.serverUrl = e.serverUrl, this.iceServers = e.iceServers, this.callSessionLoaded = !0,
|
|
713
|
+
if (this.callId = e.callId, this.prospectId = e.prospectId || this.prospectId, this.serverUrl = e.serverUrl, this.iceServers = e.iceServers, this.callSessionLoaded = !0, se(this.agentId, this.callId || "", this.prospectId), this.onSessionStarted && this.prospectId && this.callId && !this.sessionStartedEmitted)
|
|
716
714
|
try {
|
|
717
715
|
this.onSessionStarted({ prospectId: this.prospectId, callId: this.callId, serverUrl: this.serverUrl }), this.sessionStartedEmitted = !0;
|
|
718
716
|
} catch {
|
|
@@ -728,10 +726,10 @@ const w = class w {
|
|
|
728
726
|
throw new Error("[VaniraClient] apiKey or token is required to create a call session");
|
|
729
727
|
const e = { "Content-Type": "application/json" };
|
|
730
728
|
this.apiKey ? e["X-API-Key"] = this.apiKey : this.token && (e.Authorization = this.token.startsWith("Bearer ") ? this.token : `Bearer ${this.token}`);
|
|
731
|
-
const t = this.sessionBehavior === "continue" ? this.callId : void 0,
|
|
732
|
-
let s = w.inflightCreates.get(
|
|
733
|
-
s || (s = this.postCreateCall(e,
|
|
734
|
-
w.inflightCreates.get(
|
|
729
|
+
const t = this.sessionBehavior === "continue" ? this.callId : void 0, i = this.sessionBehavior === "continue" ? "continue" : "new", n = this.createCallCacheKey(i, t);
|
|
730
|
+
let s = w.inflightCreates.get(n);
|
|
731
|
+
s || (s = this.postCreateCall(e, i, t), w.inflightCreates.set(n, s), s.finally(() => {
|
|
732
|
+
w.inflightCreates.get(n) === s && w.inflightCreates.delete(n);
|
|
735
733
|
}));
|
|
736
734
|
const o = await s;
|
|
737
735
|
this.applyCreateCallSession(o);
|
|
@@ -744,11 +742,11 @@ const w = class w {
|
|
|
744
742
|
static normalizeIceServers(e) {
|
|
745
743
|
if (!Array.isArray(e)) return [];
|
|
746
744
|
const t = [];
|
|
747
|
-
for (const
|
|
748
|
-
const
|
|
745
|
+
for (const i of e) {
|
|
746
|
+
const n = i == null ? void 0 : i.urls, s = Array.isArray(n) ? n.filter(Boolean) : typeof n == "string" && n.trim() ? [n.trim()] : [];
|
|
749
747
|
if (!s.length) continue;
|
|
750
|
-
const o = { urls: s.length === 1 ? s[0] : s },
|
|
751
|
-
|
|
748
|
+
const o = { urls: s.length === 1 ? s[0] : s }, d = i.username, r = i.credential;
|
|
749
|
+
d && (o.username = d), r && (o.credential = r), t.push(o);
|
|
752
750
|
}
|
|
753
751
|
return t;
|
|
754
752
|
}
|
|
@@ -786,13 +784,13 @@ const w = class w {
|
|
|
786
784
|
try {
|
|
787
785
|
const t = await fetch(e);
|
|
788
786
|
if (!t.ok) return;
|
|
789
|
-
const { candidates:
|
|
790
|
-
for (const
|
|
791
|
-
const s = JSON.stringify(
|
|
787
|
+
const { candidates: i } = await t.json();
|
|
788
|
+
for (const n of i || []) {
|
|
789
|
+
const s = JSON.stringify(n);
|
|
792
790
|
if (!this.appliedRemoteCandidates.has(s)) {
|
|
793
791
|
this.appliedRemoteCandidates.add(s);
|
|
794
792
|
try {
|
|
795
|
-
await this.pc.addIceCandidate(
|
|
793
|
+
await this.pc.addIceCandidate(n);
|
|
796
794
|
} catch {
|
|
797
795
|
}
|
|
798
796
|
}
|
|
@@ -808,17 +806,17 @@ const w = class w {
|
|
|
808
806
|
* Send control event via DataChannel
|
|
809
807
|
*/
|
|
810
808
|
sendEvent(e, t = {}) {
|
|
811
|
-
var
|
|
812
|
-
if (((
|
|
813
|
-
const
|
|
814
|
-
this.dataChannel.send(JSON.stringify(
|
|
809
|
+
var i;
|
|
810
|
+
if (((i = this.dataChannel) == null ? void 0 : i.readyState) === "open") {
|
|
811
|
+
const n = { event: e, ...t };
|
|
812
|
+
this.dataChannel.send(JSON.stringify(n));
|
|
815
813
|
}
|
|
816
814
|
}
|
|
817
815
|
/** Wait for control DataChannel, then send (live vision lifecycle events). */
|
|
818
|
-
async sendEventWhenReady(e, t = {},
|
|
816
|
+
async sendEventWhenReady(e, t = {}, i = 1e4) {
|
|
819
817
|
var s;
|
|
820
|
-
const
|
|
821
|
-
for (; Date.now() <
|
|
818
|
+
const n = Date.now() + i;
|
|
819
|
+
for (; Date.now() < n; ) {
|
|
822
820
|
if (((s = this.dataChannel) == null ? void 0 : s.readyState) === "open")
|
|
823
821
|
return this.sendEvent(e, t), !0;
|
|
824
822
|
await new Promise((o) => setTimeout(o, 50));
|
|
@@ -836,7 +834,7 @@ const w = class w {
|
|
|
836
834
|
name: "open_live_camera",
|
|
837
835
|
tool_call_id: `lv_${crypto.randomUUID()}`,
|
|
838
836
|
execution_mode: "fire_and_forget",
|
|
839
|
-
client_fields: { preset_id:
|
|
837
|
+
client_fields: { preset_id: u.LiveVision },
|
|
840
838
|
arguments: {
|
|
841
839
|
mode: "live",
|
|
842
840
|
scope: t,
|
|
@@ -868,19 +866,19 @@ const w = class w {
|
|
|
868
866
|
case "mark":
|
|
869
867
|
break;
|
|
870
868
|
case "client_tool_cancel": {
|
|
871
|
-
const
|
|
872
|
-
this.dispatchBoardAbort("Tool cancelled by server",
|
|
869
|
+
const n = (e.data || e).tool_call_id || e.tool_call_id;
|
|
870
|
+
this.dispatchBoardAbort("Tool cancelled by server", n);
|
|
873
871
|
break;
|
|
874
872
|
}
|
|
875
873
|
case "client_tool_call": {
|
|
876
|
-
const
|
|
877
|
-
|
|
874
|
+
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 || "";
|
|
875
|
+
n && ((t = this.dataChannel) == null ? void 0 : t.readyState) === "open" && this.dataChannel.send(JSON.stringify({
|
|
878
876
|
event: "client_tool_ack",
|
|
879
|
-
data: { tool_call_id:
|
|
877
|
+
data: { tool_call_id: n }
|
|
880
878
|
}));
|
|
881
|
-
const s = (
|
|
882
|
-
if (
|
|
883
|
-
|
|
879
|
+
const s = (i == null ? void 0 : i.arguments) || (i == null ? void 0 : i.args) || {}, o = (i == null ? void 0 : i.client_fields) || {}, d = (i == null ? void 0 : i.name) || (i == null ? void 0 : i.tool_name) || "", r = ae(o, s, d);
|
|
880
|
+
if (d === "end_call") {
|
|
881
|
+
n && this.sendToolResult(n, {
|
|
884
882
|
status: "client_ack_end_call",
|
|
885
883
|
message: "Ending call."
|
|
886
884
|
}), window.setTimeout(() => this.disconnect(), 120);
|
|
@@ -888,11 +886,11 @@ const w = class w {
|
|
|
888
886
|
}
|
|
889
887
|
if (r) {
|
|
890
888
|
window.dispatchEvent(new CustomEvent("vanira:preset", {
|
|
891
|
-
detail: { toolCall:
|
|
892
|
-
})), this.onClientToolCall(
|
|
889
|
+
detail: { toolCall: i, client: this }
|
|
890
|
+
})), this.onClientToolCall(i);
|
|
893
891
|
break;
|
|
894
892
|
}
|
|
895
|
-
this.onClientToolCall(
|
|
893
|
+
this.onClientToolCall(i);
|
|
896
894
|
break;
|
|
897
895
|
}
|
|
898
896
|
}
|
|
@@ -916,12 +914,12 @@ const w = class w {
|
|
|
916
914
|
* Uses track.enabled (not pause) so audio resumes correctly when unmuted.
|
|
917
915
|
*/
|
|
918
916
|
setMicrophoneMuted(e) {
|
|
919
|
-
var t,
|
|
920
|
-
this.micMuted = e, (t = this.localStream) == null || t.getAudioTracks().forEach((
|
|
921
|
-
|
|
922
|
-
}), (
|
|
917
|
+
var t, i;
|
|
918
|
+
this.micMuted = e, (t = this.localStream) == null || t.getAudioTracks().forEach((n) => {
|
|
919
|
+
n.enabled = !e;
|
|
920
|
+
}), (i = this.pc) == null || i.getSenders().forEach((n) => {
|
|
923
921
|
var s;
|
|
924
|
-
((s =
|
|
922
|
+
((s = n.track) == null ? void 0 : s.kind) === "audio" && (n.track.enabled = !e);
|
|
925
923
|
});
|
|
926
924
|
}
|
|
927
925
|
isMicrophoneMuted() {
|
|
@@ -991,6 +989,25 @@ const w = class w {
|
|
|
991
989
|
triggerActionInterrupt() {
|
|
992
990
|
this.sendEvent("action_interrupt");
|
|
993
991
|
}
|
|
992
|
+
/**
|
|
993
|
+
* Notify the server that uploaded media should enter the AI vision context (process_media).
|
|
994
|
+
* Send after client_tool_result for blocking presets that also upload a snapshot.
|
|
995
|
+
*/
|
|
996
|
+
sendMediaUpdate(e) {
|
|
997
|
+
if (!this.dataChannel || this.dataChannel.readyState !== "open")
|
|
998
|
+
return !1;
|
|
999
|
+
const t = {
|
|
1000
|
+
event: "client_media_update",
|
|
1001
|
+
data: {
|
|
1002
|
+
media_id: e.media_id,
|
|
1003
|
+
media_url: e.media_url,
|
|
1004
|
+
content_type: e.content_type,
|
|
1005
|
+
reason: e.reason,
|
|
1006
|
+
message: e.message ?? ""
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
return this.dataChannel.send(JSON.stringify(t)), !0;
|
|
1010
|
+
}
|
|
994
1011
|
/**
|
|
995
1012
|
* Upload file to media server without notifying the AI (no client_media_update).
|
|
996
1013
|
* Use for blocking presets — result goes in client_tool_result only.
|
|
@@ -1006,8 +1023,8 @@ const w = class w {
|
|
|
1006
1023
|
* @param reason Routing key for backend processing (default: 'general')
|
|
1007
1024
|
* @param message Optional user text message about the file
|
|
1008
1025
|
*/
|
|
1009
|
-
async uploadMedia(e, t = "general",
|
|
1010
|
-
return await
|
|
1026
|
+
async uploadMedia(e, t = "general", i = "") {
|
|
1027
|
+
return await de(this.dataChannel, this.mediaBytesChannel) ? this._uploadMediaViaDataChannel(e, t, i) : (le(this.dataChannel, this.mediaBytesChannel), this._uploadMediaViaHTTP(e, t, i));
|
|
1011
1028
|
}
|
|
1012
1029
|
/**
|
|
1013
1030
|
* Upload a live vision / screen frame — HTTP only for now, never sends client_media_update.
|
|
@@ -1016,79 +1033,72 @@ const w = class w {
|
|
|
1016
1033
|
* Frames require a real media_url (server rejects empty). WebRTC upload returns url="" until
|
|
1017
1034
|
* the server adds client_media_upload_ready ack — use HTTP for frame JPEGs until then.
|
|
1018
1035
|
*/
|
|
1019
|
-
async uploadMediaFrame(e, t = "camera_capture",
|
|
1020
|
-
const
|
|
1036
|
+
async uploadMediaFrame(e, t = "camera_capture", i) {
|
|
1037
|
+
const n = i && !(e instanceof File) ? new File([e], i, { type: e.type || "image/jpeg" }) : e, { media_id: s, url: o, contentType: d } = await this._postMediaUpload(n, t, !0);
|
|
1021
1038
|
if (!s || !o)
|
|
1022
1039
|
throw new Error("Frame upload failed: server response missing media_id or url");
|
|
1023
|
-
return { media_id: s, url: o, content_type:
|
|
1040
|
+
return { media_id: s, url: o, content_type: d };
|
|
1024
1041
|
}
|
|
1025
1042
|
/** WebRTC media-bytes path (control start/complete + binary chunks). */
|
|
1026
|
-
async _uploadBytesViaDataChannel(e, t,
|
|
1043
|
+
async _uploadBytesViaDataChannel(e, t, i, n, s) {
|
|
1027
1044
|
if (!this.callId || !this.mediaBytesChannel)
|
|
1028
1045
|
throw new Error("Upload failed: call not ready for WebRTC media upload.");
|
|
1029
|
-
const o = s || (e instanceof File ? e.name :
|
|
1030
|
-
return
|
|
1046
|
+
const o = s || (e instanceof File ? e.name : n === "frame" ? "frame.jpg" : "upload.bin"), d = e.type || (n === "frame" ? "image/jpeg" : "application/octet-stream"), r = await ue(e);
|
|
1047
|
+
return he({
|
|
1031
1048
|
bytes: r,
|
|
1032
1049
|
filename: o,
|
|
1033
|
-
contentType:
|
|
1050
|
+
contentType: d,
|
|
1034
1051
|
reason: t,
|
|
1035
|
-
message:
|
|
1052
|
+
message: i,
|
|
1036
1053
|
callId: this.callId,
|
|
1037
1054
|
mediaBytesChannel: this.mediaBytesChannel,
|
|
1038
|
-
sendControlEvent: (
|
|
1039
|
-
uploadKind:
|
|
1055
|
+
sendControlEvent: (h, p) => this.sendEvent(h, p),
|
|
1056
|
+
uploadKind: n
|
|
1040
1057
|
});
|
|
1041
1058
|
}
|
|
1042
|
-
async _uploadMediaViaDataChannel(e, t,
|
|
1043
|
-
const
|
|
1044
|
-
return { media_id:
|
|
1059
|
+
async _uploadMediaViaDataChannel(e, t, i) {
|
|
1060
|
+
const n = await this._uploadBytesViaDataChannel(e, t, i, "media");
|
|
1061
|
+
return { media_id: n.media_id, url: n.url };
|
|
1045
1062
|
}
|
|
1046
1063
|
/** HTTP fallback — original uploadMedia behavior (unchanged). */
|
|
1047
|
-
async _uploadMediaViaHTTP(e, t = "general",
|
|
1048
|
-
const { media_id:
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
reason: t,
|
|
1057
|
-
message: n
|
|
1058
|
-
}
|
|
1059
|
-
};
|
|
1060
|
-
this.dataChannel.send(JSON.stringify(c));
|
|
1061
|
-
}
|
|
1062
|
-
return { media_id: i, url: s };
|
|
1064
|
+
async _uploadMediaViaHTTP(e, t = "general", i = "") {
|
|
1065
|
+
const { media_id: n, url: s, contentType: o } = await this._postMediaUpload(e, t, !0);
|
|
1066
|
+
return this.sendMediaUpdate({
|
|
1067
|
+
media_id: n,
|
|
1068
|
+
media_url: s,
|
|
1069
|
+
content_type: o,
|
|
1070
|
+
reason: t,
|
|
1071
|
+
message: i
|
|
1072
|
+
}), { media_id: n, url: s };
|
|
1063
1073
|
}
|
|
1064
|
-
async _postMediaUpload(e, t,
|
|
1074
|
+
async _postMediaUpload(e, t, i = !1) {
|
|
1065
1075
|
if (!this.serverUrl)
|
|
1066
1076
|
throw new Error("Upload failed: serverUrl is not set. Connect the VaniraClient first.");
|
|
1067
1077
|
if (!this.callId)
|
|
1068
1078
|
throw new Error("Upload failed: callId is missing.");
|
|
1069
|
-
const
|
|
1070
|
-
if (!
|
|
1079
|
+
const n = this.getWorkerOrigin();
|
|
1080
|
+
if (!n)
|
|
1071
1081
|
throw new Error(
|
|
1072
1082
|
"Upload failed: worker_url is not set. Connect the call before uploading media."
|
|
1073
1083
|
);
|
|
1074
|
-
const s = `${
|
|
1084
|
+
const s = `${n}/media/upload`, o = new FormData();
|
|
1075
1085
|
o.append("file", e), o.append("call_id", this.callId), o.append("reason", t);
|
|
1076
|
-
const
|
|
1086
|
+
const d = await fetch(s, {
|
|
1077
1087
|
method: "POST",
|
|
1078
1088
|
body: o
|
|
1079
1089
|
});
|
|
1080
|
-
if (!
|
|
1081
|
-
let _ = `HTTP ${
|
|
1090
|
+
if (!d.ok) {
|
|
1091
|
+
let _ = `HTTP ${d.status}`;
|
|
1082
1092
|
try {
|
|
1083
|
-
_ = (await
|
|
1093
|
+
_ = (await d.json()).error || _;
|
|
1084
1094
|
} catch {
|
|
1085
1095
|
}
|
|
1086
1096
|
throw new Error(`Upload failed: ${_}`);
|
|
1087
1097
|
}
|
|
1088
|
-
const r = await
|
|
1089
|
-
if (!
|
|
1098
|
+
const r = await d.json(), h = r.media_id, p = r.url, c = r.content_type || e.type;
|
|
1099
|
+
if (!h || !p)
|
|
1090
1100
|
throw new Error("Upload failed: server response missing media_id or url");
|
|
1091
|
-
return
|
|
1101
|
+
return i ? { media_id: h, url: p, contentType: c } : { media_id: h, url: p, contentType: c };
|
|
1092
1102
|
}
|
|
1093
1103
|
// ─── Event emitter (replaces retired VaniraAI) ───────────────────────────
|
|
1094
1104
|
get status() {
|
|
@@ -1101,12 +1111,12 @@ const w = class w {
|
|
|
1101
1111
|
return this.listeners.has(e) || this.listeners.set(e, /* @__PURE__ */ new Set()), this.listeners.get(e).add(t), this;
|
|
1102
1112
|
}
|
|
1103
1113
|
off(e, t) {
|
|
1104
|
-
var
|
|
1105
|
-
return (
|
|
1114
|
+
var i;
|
|
1115
|
+
return (i = this.listeners.get(e)) == null || i.delete(t), this;
|
|
1106
1116
|
}
|
|
1107
1117
|
emit(e, t) {
|
|
1108
|
-
var
|
|
1109
|
-
(
|
|
1118
|
+
var i;
|
|
1119
|
+
(i = this.listeners.get(e)) == null || i.forEach((n) => n(t));
|
|
1110
1120
|
}
|
|
1111
1121
|
/** Alias for connect() — VaniraAI compatibility */
|
|
1112
1122
|
async start() {
|
|
@@ -1136,9 +1146,9 @@ const w = class w {
|
|
|
1136
1146
|
}
|
|
1137
1147
|
};
|
|
1138
1148
|
/** Dedupes concurrent POST /calls/create (e.g. React StrictMode double-mount). */
|
|
1139
|
-
|
|
1140
|
-
let
|
|
1141
|
-
const
|
|
1149
|
+
l(w, "inflightCreates", /* @__PURE__ */ new Map());
|
|
1150
|
+
let k = w;
|
|
1151
|
+
const me = {
|
|
1142
1152
|
supportsAudioEndedEvent: !1,
|
|
1143
1153
|
supportsScreenShare: !1,
|
|
1144
1154
|
supportsDom: !1,
|
|
@@ -1146,40 +1156,40 @@ const _e = {
|
|
|
1146
1156
|
supportsCustomElements: !1,
|
|
1147
1157
|
supportsLocalStorage: !1,
|
|
1148
1158
|
supportsBroadcastChannel: !1
|
|
1149
|
-
},
|
|
1159
|
+
}, fe = {
|
|
1150
1160
|
name: "react-native",
|
|
1151
1161
|
callType: "web",
|
|
1152
1162
|
runtimeName: "react-native",
|
|
1153
1163
|
callIdPrefix: "rn_",
|
|
1154
|
-
capabilities:
|
|
1155
|
-
audio: new
|
|
1156
|
-
media: new
|
|
1157
|
-
peer: new
|
|
1158
|
-
dataChannel: new
|
|
1164
|
+
capabilities: me,
|
|
1165
|
+
audio: new Y(),
|
|
1166
|
+
media: new q(),
|
|
1167
|
+
peer: new X(),
|
|
1168
|
+
dataChannel: new Z()
|
|
1159
1169
|
};
|
|
1160
1170
|
function J(a) {
|
|
1161
|
-
return new
|
|
1171
|
+
return new k({
|
|
1162
1172
|
...a,
|
|
1163
|
-
runtime:
|
|
1173
|
+
runtime: fe
|
|
1164
1174
|
});
|
|
1165
1175
|
}
|
|
1166
|
-
const
|
|
1167
|
-
function
|
|
1176
|
+
const ve = J;
|
|
1177
|
+
function we(a) {
|
|
1168
1178
|
return J(a);
|
|
1169
1179
|
}
|
|
1170
|
-
const
|
|
1180
|
+
const ye = we;
|
|
1171
1181
|
export {
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1182
|
+
Y as RNAudioAdapter,
|
|
1183
|
+
Z as RNDataChannelAdapter,
|
|
1184
|
+
q as RNMediaAdapter,
|
|
1185
|
+
X as RNPeerAdapter,
|
|
1186
|
+
k as VaniraAI,
|
|
1187
|
+
k as VaniraClient,
|
|
1188
|
+
k as WebRTCClient,
|
|
1189
|
+
ve as createReactNativeAI,
|
|
1180
1190
|
J as createReactNativeClient,
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1191
|
+
ye as createVaniraAI,
|
|
1192
|
+
we as createVaniraClient,
|
|
1193
|
+
me as reactNativeCapabilities,
|
|
1194
|
+
fe as reactNativeRuntime
|
|
1185
1195
|
};
|