@vanira/sdk 0.0.86 → 0.0.87
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 +321 -103
- package/dist/headless/index.js +15129 -13880
- package/dist/index.d.ts +67 -1
- package/dist/platforms/browser.cjs +24 -8
- package/dist/platforms/browser.js +2110 -1986
- package/dist/platforms/react-native.cjs +17 -1
- package/dist/platforms/react-native.js +479 -355
- package/dist/vanira-sdk.es.js +9967 -8582
- package/dist/vanira-sdk.js +328 -110
- package/dist/vanira-sdk.umd.js +343 -114
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
class
|
|
1
|
+
var q = Object.defineProperty;
|
|
2
|
+
var X = (i, e, t) => e in i ? q(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
|
|
3
|
+
var l = (i, e, t) => X(i, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
class Z {
|
|
5
5
|
pause() {
|
|
6
6
|
}
|
|
7
7
|
cleanup() {
|
|
@@ -9,12 +9,12 @@ class z {
|
|
|
9
9
|
onEnded(e) {
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
class
|
|
12
|
+
class Q {
|
|
13
13
|
createRemotePlayer(e) {
|
|
14
|
-
return new
|
|
14
|
+
return new Z();
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
class
|
|
17
|
+
class F {
|
|
18
18
|
async getUserAudio(e) {
|
|
19
19
|
return navigator.mediaDevices.getUserMedia({
|
|
20
20
|
audio: e
|
|
@@ -24,7 +24,7 @@ class q {
|
|
|
24
24
|
e.getTracks().forEach((t) => t.stop());
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
class
|
|
27
|
+
class ee {
|
|
28
28
|
create(e) {
|
|
29
29
|
return new globalThis.RTCPeerConnection({
|
|
30
30
|
iceServers: e.iceServers,
|
|
@@ -32,24 +32,24 @@ class X {
|
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
class
|
|
35
|
+
class te {
|
|
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 = (n) => t.onError(n), e.onmessage = (n) => {
|
|
38
|
+
if (typeof n.data == "string") {
|
|
39
|
+
t.onMessage({ text: n.data });
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
|
-
if (
|
|
42
|
+
if (n.data instanceof ArrayBuffer) {
|
|
43
43
|
try {
|
|
44
|
-
const
|
|
45
|
-
(r == null ? void 0 : r.event) === "client_tool_call" && t.onMessage({ text:
|
|
44
|
+
const a = new TextDecoder().decode(n.data), r = JSON.parse(a);
|
|
45
|
+
(r == null ? void 0 : r.event) === "client_tool_call" && t.onMessage({ text: a });
|
|
46
46
|
} catch {
|
|
47
47
|
}
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
}, {
|
|
51
|
-
send(
|
|
52
|
-
e.readyState === "open" && e.send(
|
|
51
|
+
send(n) {
|
|
52
|
+
e.readyState === "open" && e.send(n);
|
|
53
53
|
},
|
|
54
54
|
isOpen() {
|
|
55
55
|
return e.readyState === "open";
|
|
@@ -60,7 +60,7 @@ class Z {
|
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
const
|
|
63
|
+
const ne = "https://api.vanira.io", c = {
|
|
64
64
|
Form: "vanira_form",
|
|
65
65
|
Calendar: "vanira_calendar",
|
|
66
66
|
Navigate: "vanira_navigate",
|
|
@@ -72,6 +72,7 @@ const Q = "https://api.vanira.io", c = {
|
|
|
72
72
|
SetDate: "vanira_set_date",
|
|
73
73
|
TypeText: "vanira_type_text",
|
|
74
74
|
WriteLatexText: "vanira_write_latex_text",
|
|
75
|
+
GeoGebra: "vanira_geogebra",
|
|
75
76
|
EraseText: "vanira_erase_text",
|
|
76
77
|
LiveVision: "vanira_live_vision",
|
|
77
78
|
CloseLiveCamera: "vanira_close_live_camera",
|
|
@@ -86,20 +87,20 @@ const Q = "https://api.vanira.io", c = {
|
|
|
86
87
|
KycDocumentCapture: "vanira_kyc_document_capture",
|
|
87
88
|
KycSelfieCapture: "vanira_kyc_selfie_capture",
|
|
88
89
|
KycSignatureCapture: "vanira_kyc_signature_capture"
|
|
89
|
-
},
|
|
90
|
-
function
|
|
91
|
-
return !!
|
|
90
|
+
}, ie = Object.values(c), ae = new Set(ie);
|
|
91
|
+
function K(i) {
|
|
92
|
+
return !!i && ae.has(i);
|
|
92
93
|
}
|
|
93
|
-
function
|
|
94
|
-
if (typeof
|
|
94
|
+
function J(i) {
|
|
95
|
+
if (typeof i == "string")
|
|
95
96
|
try {
|
|
96
|
-
return JSON.parse(
|
|
97
|
+
return JSON.parse(i);
|
|
97
98
|
} catch {
|
|
98
99
|
return {};
|
|
99
100
|
}
|
|
100
|
-
return
|
|
101
|
+
return i && typeof i == "object" ? i : {};
|
|
101
102
|
}
|
|
102
|
-
const
|
|
103
|
+
const $ = {
|
|
103
104
|
type_on_whiteboard: c.TypeText,
|
|
104
105
|
write_on_whiteboard: c.TypeText,
|
|
105
106
|
write_on_white_board: c.TypeText,
|
|
@@ -107,6 +108,9 @@ const N = {
|
|
|
107
108
|
write_latex_text: c.WriteLatexText,
|
|
108
109
|
write_latex_on_board: c.WriteLatexText,
|
|
109
110
|
latex_on_whiteboard: c.WriteLatexText,
|
|
111
|
+
show_geogebra: c.GeoGebra,
|
|
112
|
+
geogebra_diagram: c.GeoGebra,
|
|
113
|
+
geogebra: c.GeoGebra,
|
|
110
114
|
erase_text: c.EraseText,
|
|
111
115
|
dom_erase: c.EraseText,
|
|
112
116
|
open_live_camera: c.LiveVision,
|
|
@@ -142,74 +146,84 @@ const N = {
|
|
|
142
146
|
kyc_signature_capture: c.KycSignatureCapture,
|
|
143
147
|
capture_kyc_signature: c.KycSignatureCapture,
|
|
144
148
|
signature_capture: c.KycSignatureCapture
|
|
145
|
-
},
|
|
149
|
+
}, j = {
|
|
146
150
|
vanira_tab_screenshot: c.ScreenVision,
|
|
147
151
|
vanira_document_capture: c.KycDocumentCapture,
|
|
148
152
|
vanira_selfie_capture: c.KycSelfieCapture,
|
|
149
153
|
vanira_signature_capture: c.KycSignatureCapture,
|
|
150
154
|
vanira_kyc_signature: c.KycSignatureCapture
|
|
151
155
|
};
|
|
152
|
-
function
|
|
153
|
-
const t =
|
|
156
|
+
function re(i, e) {
|
|
157
|
+
const t = i.commands ?? (e == null ? void 0 : e.commands) ?? i.construction ?? (e == null ? void 0 : e.construction) ?? i.geogebra_commands ?? (e == null ? void 0 : e.geogebra_commands) ?? i.script ?? (e == null ? void 0 : e.script);
|
|
158
|
+
return Array.isArray(t) ? t.some((n) => String(n).trim().length > 0) : typeof t == "string" && t.trim().length > 0;
|
|
159
|
+
}
|
|
160
|
+
function se(i, e) {
|
|
161
|
+
const t = i.material_id ?? (e == null ? void 0 : e.material_id) ?? i.materialId ?? (e == null ? void 0 : e.materialId);
|
|
162
|
+
return typeof t == "string" && t.trim().length > 0;
|
|
163
|
+
}
|
|
164
|
+
function oe(i, e) {
|
|
165
|
+
const t = i.latex_text ?? (e == null ? void 0 : e.latex_text);
|
|
154
166
|
return typeof t == "string" && t.trim().length > 0;
|
|
155
167
|
}
|
|
156
|
-
function
|
|
157
|
-
const t =
|
|
168
|
+
function G(i, e) {
|
|
169
|
+
const t = i.text_to_type ?? (e == null ? void 0 : e.text_to_type) ?? i.text ?? (e == null ? void 0 : e.text) ?? i.value ?? (e == null ? void 0 : e.value);
|
|
158
170
|
return typeof t == "string" && t.trim().length > 0;
|
|
159
171
|
}
|
|
160
|
-
function
|
|
161
|
-
const t =
|
|
162
|
-
return Array.isArray(t) ? t.length > 0 : typeof t == "string" ? t.split(",").map((
|
|
172
|
+
function ce(i, e) {
|
|
173
|
+
const t = i.fields ?? (e == null ? void 0 : e.fields);
|
|
174
|
+
return Array.isArray(t) ? t.length > 0 : typeof t == "string" ? t.split(",").map((n) => n.trim()).filter(Boolean).length > 0 : !1;
|
|
163
175
|
}
|
|
164
|
-
function
|
|
165
|
-
const t =
|
|
176
|
+
function le(i, e) {
|
|
177
|
+
const t = i == null ? void 0 : i.preset_id;
|
|
166
178
|
if (typeof t == "string") {
|
|
167
|
-
if (
|
|
168
|
-
const r =
|
|
179
|
+
if (K(t)) return t;
|
|
180
|
+
const r = j[t];
|
|
169
181
|
if (r) return r;
|
|
170
182
|
}
|
|
171
|
-
const
|
|
172
|
-
if (typeof
|
|
173
|
-
if (
|
|
174
|
-
const r =
|
|
183
|
+
const a = J(e).preset_id;
|
|
184
|
+
if (typeof a == "string") {
|
|
185
|
+
if (K(a)) return a;
|
|
186
|
+
const r = j[a];
|
|
175
187
|
if (r) return r;
|
|
176
188
|
}
|
|
177
189
|
}
|
|
178
|
-
function
|
|
179
|
-
const
|
|
180
|
-
let
|
|
181
|
-
if (
|
|
190
|
+
function de(i, e, t) {
|
|
191
|
+
const n = J(e);
|
|
192
|
+
let a = le(i, n);
|
|
193
|
+
if (a === c.Form && G(n, i) && !ce(n, i))
|
|
182
194
|
return c.TypeText;
|
|
183
|
-
if (
|
|
195
|
+
if (a) return a;
|
|
184
196
|
const r = String(t ?? "").trim().toLowerCase();
|
|
185
|
-
if (r &&
|
|
186
|
-
return
|
|
187
|
-
if (
|
|
197
|
+
if (r && $[r])
|
|
198
|
+
return $[r];
|
|
199
|
+
if (re(n, i) || se(n, i))
|
|
200
|
+
return c.GeoGebra;
|
|
201
|
+
if (oe(n, i))
|
|
188
202
|
return c.WriteLatexText;
|
|
189
|
-
if (
|
|
203
|
+
if (G(n, i))
|
|
190
204
|
return c.TypeText;
|
|
191
205
|
}
|
|
192
|
-
const
|
|
193
|
-
function
|
|
194
|
-
return `vanira_latest_call_id_${
|
|
206
|
+
const I = "vanira_latest_call_id", k = "vanira_prospect_id";
|
|
207
|
+
function T(i) {
|
|
208
|
+
return `vanira_latest_call_id_${i}`;
|
|
195
209
|
}
|
|
196
|
-
function
|
|
197
|
-
return `vanira_prospect_id_${
|
|
210
|
+
function b(i) {
|
|
211
|
+
return `vanira_prospect_id_${i}`;
|
|
198
212
|
}
|
|
199
|
-
function
|
|
200
|
-
return `vanira_call_meta_${
|
|
213
|
+
function z(i) {
|
|
214
|
+
return `vanira_call_meta_${i}`;
|
|
201
215
|
}
|
|
202
|
-
function
|
|
203
|
-
if (!
|
|
216
|
+
function S(i, e) {
|
|
217
|
+
if (!i) return null;
|
|
204
218
|
try {
|
|
205
|
-
return
|
|
219
|
+
return i.getItem(e);
|
|
206
220
|
} catch {
|
|
207
221
|
return null;
|
|
208
222
|
}
|
|
209
223
|
}
|
|
210
|
-
function
|
|
211
|
-
if (typeof window > "u" || !
|
|
212
|
-
const e = [], t =
|
|
224
|
+
function W(i) {
|
|
225
|
+
if (typeof window > "u" || !i) return null;
|
|
226
|
+
const e = [], t = S(window.localStorage, z(i));
|
|
213
227
|
if (t)
|
|
214
228
|
try {
|
|
215
229
|
const h = JSON.parse(t);
|
|
@@ -220,139 +234,197 @@ function B(a) {
|
|
|
220
234
|
});
|
|
221
235
|
} catch {
|
|
222
236
|
}
|
|
223
|
-
const
|
|
237
|
+
const n = (h, s, u) => {
|
|
224
238
|
h && e.push({
|
|
225
239
|
callId: h,
|
|
226
240
|
prospectId: s || void 0,
|
|
227
241
|
updatedAt: u
|
|
228
242
|
});
|
|
229
|
-
},
|
|
230
|
-
return
|
|
231
|
-
|
|
232
|
-
|
|
243
|
+
}, a = S(window.localStorage, b(i)), r = S(window.sessionStorage, b(i)), o = S(window.localStorage, k);
|
|
244
|
+
return n(
|
|
245
|
+
S(window.localStorage, T(i)),
|
|
246
|
+
a || o,
|
|
233
247
|
2
|
|
234
|
-
),
|
|
235
|
-
|
|
248
|
+
), n(
|
|
249
|
+
S(window.sessionStorage, T(i)),
|
|
236
250
|
r || o,
|
|
237
251
|
1
|
|
238
|
-
),
|
|
252
|
+
), n(S(window.localStorage, I), o, 0), n(S(window.sessionStorage, I), o, 0), e.length ? (e.sort((h, s) => s.updatedAt - h.updatedAt), e[0]) : null;
|
|
239
253
|
}
|
|
240
|
-
function
|
|
241
|
-
var
|
|
242
|
-
if (typeof window > "u" || !
|
|
243
|
-
const
|
|
254
|
+
function he(i, e, t) {
|
|
255
|
+
var a, r, o, h, s, u, p, d, _;
|
|
256
|
+
if (typeof window > "u" || !i || !e) return;
|
|
257
|
+
const n = {
|
|
244
258
|
callId: e,
|
|
245
259
|
prospectId: t,
|
|
246
260
|
updatedAt: Date.now()
|
|
247
261
|
};
|
|
248
262
|
try {
|
|
249
|
-
(
|
|
263
|
+
(a = window.localStorage) == null || a.setItem(z(i), JSON.stringify(n)), (r = window.localStorage) == null || r.setItem(T(i), e), (o = window.sessionStorage) == null || o.setItem(T(i), e), t && ((h = window.localStorage) == null || h.setItem(b(i), t), (s = window.sessionStorage) == null || s.setItem(b(i), t)), (u = window.localStorage) == null || u.setItem(I, e), (p = window.sessionStorage) == null || p.setItem(I, e), t && ((d = window.localStorage) == null || d.setItem(k, t), (_ = window.sessionStorage) == null || _.setItem(k, t));
|
|
250
264
|
} catch {
|
|
251
265
|
}
|
|
252
266
|
}
|
|
253
|
-
const
|
|
267
|
+
const ue = /* @__PURE__ */ new Set([
|
|
254
268
|
"client_tool_call",
|
|
255
269
|
"clearAudio",
|
|
256
270
|
"client_tool_cancel"
|
|
257
271
|
]);
|
|
258
|
-
function
|
|
259
|
-
if (!
|
|
260
|
-
const e =
|
|
261
|
-
return typeof e == "string" &&
|
|
272
|
+
function pe(i) {
|
|
273
|
+
if (!i || typeof i != "object") return !1;
|
|
274
|
+
const e = i.event;
|
|
275
|
+
return typeof e == "string" && ue.has(e);
|
|
262
276
|
}
|
|
263
|
-
const
|
|
264
|
-
function E(
|
|
265
|
-
return (
|
|
277
|
+
const x = 16 * 1024, _e = 256 * 1024;
|
|
278
|
+
function E(i, e) {
|
|
279
|
+
return (i == null ? void 0 : i.readyState) === "open" && (e == null ? void 0 : e.readyState) === "open";
|
|
266
280
|
}
|
|
267
|
-
function
|
|
281
|
+
function me(i, e) {
|
|
268
282
|
return {
|
|
269
|
-
control: (
|
|
283
|
+
control: (i == null ? void 0 : i.readyState) ?? "missing",
|
|
270
284
|
mediaBytes: (e == null ? void 0 : e.readyState) ?? "missing"
|
|
271
285
|
};
|
|
272
286
|
}
|
|
273
|
-
async function
|
|
274
|
-
if (E(
|
|
287
|
+
async function fe(i, e, t = 8e3) {
|
|
288
|
+
if (E(i, e))
|
|
275
289
|
return !0;
|
|
276
|
-
const
|
|
277
|
-
for (; Date.now() <
|
|
278
|
-
if (E(
|
|
290
|
+
const n = Date.now() + t;
|
|
291
|
+
for (; Date.now() < n; ) {
|
|
292
|
+
if (E(i, e))
|
|
279
293
|
return !0;
|
|
280
|
-
await new Promise((
|
|
294
|
+
await new Promise((a) => setTimeout(a, 50));
|
|
281
295
|
}
|
|
282
|
-
return E(
|
|
296
|
+
return E(i, e);
|
|
283
297
|
}
|
|
284
|
-
async function
|
|
285
|
-
for (;
|
|
298
|
+
async function H(i) {
|
|
299
|
+
for (; i.bufferedAmount > _e; )
|
|
286
300
|
await new Promise((e) => setTimeout(e, 10));
|
|
287
301
|
}
|
|
288
|
-
async function
|
|
302
|
+
async function ye(i) {
|
|
289
303
|
const {
|
|
290
304
|
bytes: e,
|
|
291
305
|
filename: t,
|
|
292
|
-
contentType:
|
|
293
|
-
reason:
|
|
306
|
+
contentType: n,
|
|
307
|
+
reason: a,
|
|
294
308
|
message: r,
|
|
295
309
|
callId: o,
|
|
296
310
|
mediaBytesChannel: h,
|
|
297
311
|
sendControlEvent: s,
|
|
298
312
|
uploadId: u = crypto.randomUUID(),
|
|
299
313
|
uploadKind: p = "media"
|
|
300
|
-
} =
|
|
314
|
+
} = i, d = e.byteLength, _ = d === 0 ? 0 : Math.ceil(d / x);
|
|
301
315
|
s("client_media_upload_start", {
|
|
302
316
|
data: {
|
|
303
317
|
upload_id: u,
|
|
304
318
|
call_id: o,
|
|
305
|
-
reason:
|
|
319
|
+
reason: a,
|
|
306
320
|
message: r,
|
|
307
321
|
filename: t,
|
|
308
|
-
content_type:
|
|
309
|
-
size:
|
|
322
|
+
content_type: n,
|
|
323
|
+
size: d,
|
|
310
324
|
chunk_count: _,
|
|
311
325
|
upload_kind: p
|
|
312
326
|
}
|
|
313
327
|
});
|
|
314
328
|
const m = new Uint8Array(e);
|
|
315
|
-
for (let f = 0; f <
|
|
316
|
-
await
|
|
317
|
-
const
|
|
318
|
-
h.send(m.subarray(f,
|
|
329
|
+
for (let f = 0; f < d; f += x) {
|
|
330
|
+
await H(h);
|
|
331
|
+
const w = Math.min(f + x, d);
|
|
332
|
+
h.send(m.subarray(f, w));
|
|
319
333
|
}
|
|
320
|
-
return await
|
|
334
|
+
return await H(h), s("client_media_upload_complete", {
|
|
321
335
|
data: {
|
|
322
336
|
upload_id: u,
|
|
323
337
|
call_id: o,
|
|
324
|
-
reason:
|
|
338
|
+
reason: a,
|
|
325
339
|
message: r,
|
|
326
340
|
chunk_count: _,
|
|
327
341
|
upload_kind: p
|
|
328
342
|
}
|
|
329
|
-
}), { media_id: u, url: "", content_type:
|
|
343
|
+
}), { media_id: u, url: "", content_type: n };
|
|
330
344
|
}
|
|
331
|
-
async function
|
|
332
|
-
return typeof
|
|
345
|
+
async function Se(i) {
|
|
346
|
+
return typeof i.arrayBuffer == "function" ? i.arrayBuffer() : new Response(i).arrayBuffer();
|
|
333
347
|
}
|
|
334
|
-
|
|
348
|
+
const we = 15e3, R = "vanira-connect-stall-prompt";
|
|
349
|
+
let v = null;
|
|
350
|
+
function ge(i = we) {
|
|
351
|
+
typeof window > "u" || (g(!1), v = setTimeout(() => {
|
|
352
|
+
v = null, ve(), window.dispatchEvent(new CustomEvent("vanira:connect-stall"));
|
|
353
|
+
}, i));
|
|
354
|
+
}
|
|
355
|
+
function g(i = !0) {
|
|
356
|
+
v !== null && (clearTimeout(v), v = null), i && P();
|
|
357
|
+
}
|
|
358
|
+
function P() {
|
|
359
|
+
var i;
|
|
360
|
+
typeof document > "u" || (i = document.getElementById(R)) == null || i.remove();
|
|
361
|
+
}
|
|
362
|
+
function ve() {
|
|
363
|
+
var t, n;
|
|
364
|
+
if (typeof document > "u" || document.getElementById(R)) return;
|
|
365
|
+
const i = document.createElement("div");
|
|
366
|
+
i.id = R, i.setAttribute("role", "alertdialog"), i.setAttribute("aria-modal", "true"), i.setAttribute("aria-labelledby", "vanira-stall-title"), i.style.cssText = [
|
|
367
|
+
"position:fixed",
|
|
368
|
+
"inset:0",
|
|
369
|
+
"z-index:2147483646",
|
|
370
|
+
"display:flex",
|
|
371
|
+
"align-items:center",
|
|
372
|
+
"justify-content:center",
|
|
373
|
+
"padding:24px",
|
|
374
|
+
"background:rgba(0,0,0,0.55)",
|
|
375
|
+
"font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif"
|
|
376
|
+
].join(";");
|
|
377
|
+
const e = document.createElement("div");
|
|
378
|
+
e.style.cssText = [
|
|
379
|
+
"max-width:400px",
|
|
380
|
+
"width:100%",
|
|
381
|
+
"padding:24px",
|
|
382
|
+
"border-radius:16px",
|
|
383
|
+
"background:#fff",
|
|
384
|
+
"box-shadow:0 20px 60px rgba(0,0,0,0.25)",
|
|
385
|
+
"color:#111"
|
|
386
|
+
].join(";"), e.innerHTML = `
|
|
387
|
+
<h2 id="vanira-stall-title" style="margin:0 0 12px;font-size:18px;font-weight:600">Browser is blocking the connection</h2>
|
|
388
|
+
<p style="margin:0 0 20px;font-size:14px;line-height:1.5;color:#444">
|
|
389
|
+
The call is still connecting. Please <strong>hard refresh</strong> your browser to reconnect.
|
|
390
|
+
</p>
|
|
391
|
+
<div style="display:flex;gap:12px;flex-wrap:wrap">
|
|
392
|
+
<button type="button" id="vanira-stall-refresh" style="flex:1;min-width:140px;padding:10px 16px;border:none;border-radius:8px;background:#111;color:#fff;font-size:14px;font-weight:600;cursor:pointer">
|
|
393
|
+
Hard refresh
|
|
394
|
+
</button>
|
|
395
|
+
<button type="button" id="vanira-stall-dismiss" style="flex:1;min-width:100px;padding:10px 16px;border:1px solid #ddd;border-radius:8px;background:#fff;color:#333;font-size:14px;cursor:pointer">
|
|
396
|
+
Dismiss
|
|
397
|
+
</button>
|
|
398
|
+
</div>
|
|
399
|
+
<p style="margin:12px 0 0;font-size:12px;color:#888">
|
|
400
|
+
Tip: Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac)
|
|
401
|
+
</p>
|
|
402
|
+
`, i.appendChild(e), document.body.appendChild(i), (t = e.querySelector("#vanira-stall-refresh")) == null || t.addEventListener("click", () => {
|
|
403
|
+
P(), window.location.reload();
|
|
404
|
+
}), (n = e.querySelector("#vanira-stall-dismiss")) == null || n.addEventListener("click", () => P());
|
|
405
|
+
}
|
|
406
|
+
function Ce(i) {
|
|
335
407
|
return null;
|
|
336
408
|
}
|
|
337
|
-
function
|
|
409
|
+
function C() {
|
|
338
410
|
return typeof window > "u" ? "/" : `${window.location.pathname}${window.location.search}${window.location.hash}` || "/";
|
|
339
411
|
}
|
|
340
|
-
class
|
|
412
|
+
class Ie {
|
|
341
413
|
constructor(e) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
414
|
+
l(this, "active", !1);
|
|
415
|
+
l(this, "initialSent", !1);
|
|
416
|
+
l(this, "lastRoute", "");
|
|
417
|
+
l(this, "sendContext");
|
|
418
|
+
l(this, "isReady");
|
|
419
|
+
l(this, "cleanupFns", []);
|
|
420
|
+
l(this, "initialRetryTimer", null);
|
|
421
|
+
l(this, "routePollTimer", null);
|
|
422
|
+
l(this, "originalPushState", null);
|
|
423
|
+
l(this, "originalReplaceState", null);
|
|
352
424
|
this.sendContext = e.sendContext, this.isReady = e.isReady ?? (() => !0);
|
|
353
425
|
}
|
|
354
426
|
start() {
|
|
355
|
-
typeof window > "u" || this.active || (this.active = !0, this.initialSent = !1, this.lastRoute =
|
|
427
|
+
typeof window > "u" || this.active || (this.active = !0, this.initialSent = !1, this.lastRoute = C(), this.attachListeners(), this.scheduleInitialContextSend());
|
|
356
428
|
}
|
|
357
429
|
stop() {
|
|
358
430
|
if (!(!this.active && this.cleanupFns.length === 0)) {
|
|
@@ -384,11 +456,11 @@ class _e {
|
|
|
384
456
|
attachListeners() {
|
|
385
457
|
const e = (r, o = 0) => {
|
|
386
458
|
const h = () => {
|
|
387
|
-
const s =
|
|
459
|
+
const s = C();
|
|
388
460
|
s !== this.lastRoute && this.handleRouteChange(s, r);
|
|
389
461
|
};
|
|
390
462
|
o > 0 ? window.setTimeout(h, o) : queueMicrotask(h);
|
|
391
|
-
}, t = () => e("popstate"),
|
|
463
|
+
}, t = () => e("popstate"), n = () => e("hashchange"), a = (r) => {
|
|
392
464
|
const o = r.detail;
|
|
393
465
|
if ((o == null ? void 0 : o.initiated_by) === "agent") {
|
|
394
466
|
e("vanira_navigate_agent", 120);
|
|
@@ -396,41 +468,41 @@ class _e {
|
|
|
396
468
|
}
|
|
397
469
|
e("vanira_navigate", 120);
|
|
398
470
|
};
|
|
399
|
-
window.addEventListener("popstate", t), window.addEventListener("hashchange",
|
|
471
|
+
window.addEventListener("popstate", t), window.addEventListener("hashchange", n), window.addEventListener("vanira:navigate", a), this.cleanupFns.push(
|
|
400
472
|
() => window.removeEventListener("popstate", t),
|
|
401
|
-
() => window.removeEventListener("hashchange",
|
|
402
|
-
() => window.removeEventListener("vanira:navigate",
|
|
473
|
+
() => window.removeEventListener("hashchange", n),
|
|
474
|
+
() => window.removeEventListener("vanira:navigate", a)
|
|
403
475
|
), this.originalPushState = history.pushState.bind(history), this.originalReplaceState = history.replaceState.bind(history), history.pushState = (...r) => {
|
|
404
476
|
this.originalPushState(...r), e("pushState");
|
|
405
477
|
}, history.replaceState = (...r) => {
|
|
406
478
|
this.originalReplaceState(...r), e("replaceState");
|
|
407
479
|
}, this.routePollTimer = window.setInterval(() => {
|
|
408
480
|
if (!this.active) return;
|
|
409
|
-
const r =
|
|
481
|
+
const r = C();
|
|
410
482
|
r !== this.lastRoute && this.handleRouteChange(r, "location_poll");
|
|
411
483
|
}, 1e3);
|
|
412
484
|
}
|
|
413
485
|
handleRouteChange(e, t) {
|
|
414
486
|
if (!this.active) return;
|
|
415
|
-
const
|
|
416
|
-
if (
|
|
487
|
+
const n = this.lastRoute;
|
|
488
|
+
if (n === e) return;
|
|
417
489
|
if (this.lastRoute = e, !this.initialSent) {
|
|
418
490
|
this.scheduleInitialContextSend();
|
|
419
491
|
return;
|
|
420
492
|
}
|
|
421
|
-
!this.isReady() ||
|
|
493
|
+
!this.isReady() || Ce() || this.sendRouteContext("route_changed", n, t, "user");
|
|
422
494
|
}
|
|
423
|
-
sendRouteContext(e, t,
|
|
424
|
-
const r =
|
|
495
|
+
sendRouteContext(e, t, n, a = "user") {
|
|
496
|
+
const r = C();
|
|
425
497
|
this.lastRoute = r;
|
|
426
498
|
const o = {
|
|
427
499
|
ui_state: "page_navigation",
|
|
428
|
-
navigation_led_by:
|
|
500
|
+
navigation_led_by: a,
|
|
429
501
|
current_route: r,
|
|
430
502
|
current_page: r,
|
|
431
503
|
user_action: e === "call_started" ? "call_started_on_page" : "user_navigated"
|
|
432
504
|
};
|
|
433
|
-
e === "call_started" ? o.message = `User started the call while viewing ${r}.` : (o.previous_route = t ?? "", o.message = `User navigated from ${t || "(unknown)"} to ${r}.`,
|
|
505
|
+
e === "call_started" ? o.message = `User started the call while viewing ${r}.` : (o.previous_route = t ?? "", o.message = `User navigated from ${t || "(unknown)"} to ${r}.`, n && (o.navigation_source = n));
|
|
434
506
|
try {
|
|
435
507
|
this.sendContext(o);
|
|
436
508
|
} catch {
|
|
@@ -439,62 +511,67 @@ class _e {
|
|
|
439
511
|
}
|
|
440
512
|
const y = class y {
|
|
441
513
|
constructor(e) {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
514
|
+
l(this, "serverUrl");
|
|
515
|
+
l(this, "agentId");
|
|
516
|
+
l(this, "callId");
|
|
517
|
+
l(this, "prospectId");
|
|
518
|
+
l(this, "apiKey");
|
|
519
|
+
l(this, "backendUrl");
|
|
520
|
+
l(this, "token");
|
|
521
|
+
l(this, "prospectName");
|
|
522
|
+
l(this, "extraDetails");
|
|
523
|
+
l(this, "onConnected");
|
|
524
|
+
l(this, "onDisconnected");
|
|
525
|
+
l(this, "onError");
|
|
526
|
+
l(this, "onTranscription");
|
|
527
|
+
l(this, "onLocalStream");
|
|
454
528
|
// @ts-ignore
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
529
|
+
l(this, "onRemoteTrack");
|
|
530
|
+
l(this, "onClientToolCall");
|
|
531
|
+
l(this, "onSessionStarted");
|
|
532
|
+
l(this, "sessionStartedEmitted", !1);
|
|
533
|
+
l(this, "pc", null);
|
|
534
|
+
l(this, "dataChannel", null);
|
|
535
|
+
l(this, "mediaBytesChannel", null);
|
|
536
|
+
l(this, "audioElement", null);
|
|
537
|
+
l(this, "localStream", null);
|
|
538
|
+
l(this, "micMuted", !1);
|
|
539
|
+
l(this, "connected", !1);
|
|
540
|
+
l(this, "appliedRemoteCandidates", /* @__PURE__ */ new Set());
|
|
541
|
+
l(this, "remoteDescSet", !1);
|
|
542
|
+
l(this, "pendingServerIce", []);
|
|
543
|
+
l(this, "icePollStop", !1);
|
|
544
|
+
l(this, "iceServers");
|
|
545
|
+
l(this, "callSessionLoaded", !1);
|
|
546
|
+
l(this, "connectGeneration", 0);
|
|
547
|
+
l(this, "runtime");
|
|
548
|
+
l(this, "sessionBehavior");
|
|
549
|
+
l(this, "routeTracker", null);
|
|
550
|
+
l(this, "_status", "idle");
|
|
551
|
+
l(this, "listeners", /* @__PURE__ */ new Map());
|
|
476
552
|
/** Live vision config — auto-starts camera on connect when scope is full_call. */
|
|
477
|
-
|
|
478
|
-
|
|
553
|
+
l(this, "liveVision");
|
|
554
|
+
l(this, "liveVisionAutoStarted", !1);
|
|
555
|
+
l(this, "connectStallTimeoutMs");
|
|
479
556
|
if (!e.agentId) throw new Error("agentId is required");
|
|
480
|
-
const t = !!(e.apiKey || e.token),
|
|
557
|
+
const t = !!(e.apiKey || e.token), n = !!(e.serverUrl && e.callId), a = y.normalizeIceServers(
|
|
481
558
|
e.iceServers
|
|
482
559
|
);
|
|
483
|
-
if (!t && !
|
|
560
|
+
if (!t && !n)
|
|
484
561
|
throw new Error(
|
|
485
562
|
"apiKey or token is required — or pass serverUrl and callId from a prior POST /calls/create"
|
|
486
563
|
);
|
|
487
|
-
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 ||
|
|
564
|
+
this.agentId = e.agentId, this.sessionBehavior = e.sessionBehavior, this.serverUrl = (e.serverUrl || "").replace(/\/$/, ""), this.apiKey = e.apiKey, this.token = e.token, this.prospectName = e.prospectName, this.extraDetails = e.extraDetails, this.backendUrl = (e.backendUrl || ne).replace(/\/$/, ""), a.length && (this.iceServers = a), n && (this.callSessionLoaded = !0);
|
|
488
565
|
const r = typeof window < "u";
|
|
489
566
|
this.prospectId = e.prospectId;
|
|
490
567
|
const o = e.sessionBehavior === "continue";
|
|
491
568
|
if (o && r && !e.callId) {
|
|
492
|
-
const s =
|
|
569
|
+
const s = W(this.agentId);
|
|
493
570
|
s && (e.callId || (this.callId = s.callId), !this.prospectId && s.prospectId && (this.prospectId = s.prospectId));
|
|
494
571
|
}
|
|
495
572
|
if (!this.prospectId && r)
|
|
496
573
|
try {
|
|
497
|
-
const s =
|
|
574
|
+
const s = W(this.agentId);
|
|
498
575
|
this.prospectId = (s == null ? void 0 : s.prospectId) || window.sessionStorage && window.sessionStorage.getItem("vanira_prospect_id") || window.localStorage && window.localStorage.getItem("vanira_prospect_id") || void 0;
|
|
499
576
|
} catch {
|
|
500
577
|
}
|
|
@@ -502,27 +579,27 @@ const y = class y {
|
|
|
502
579
|
const h = e.onSessionStarted;
|
|
503
580
|
this.onSessionStarted = (s) => {
|
|
504
581
|
h == null || h(s), this.emit("session_started", s);
|
|
505
|
-
}, this.liveVision = e.liveVision, this.onConnected = () => {
|
|
582
|
+
}, this.liveVision = e.liveVision, this.connectStallTimeoutMs = e.connectStallTimeoutMs ?? 15e3, this.onConnected = () => {
|
|
506
583
|
var s;
|
|
507
|
-
this._status = "connected", (s = e.onConnected) == null || s.call(e), this.emit("connected"), this.maybeAutoStartLiveCamera();
|
|
584
|
+
g(), this._status = "connected", (s = e.onConnected) == null || s.call(e), this.emit("connected"), this.maybeAutoStartLiveCamera();
|
|
508
585
|
}, this.onDisconnected = () => {
|
|
509
586
|
var s;
|
|
510
|
-
this._status = "disconnected", (s = e.onDisconnected) == null || s.call(e), this.emit("disconnected");
|
|
587
|
+
g(), this._status = "disconnected", (s = e.onDisconnected) == null || s.call(e), this.emit("disconnected");
|
|
511
588
|
}, this.onError = (s) => {
|
|
512
589
|
var p;
|
|
513
|
-
this._status = "error";
|
|
590
|
+
g(), this._status = "error";
|
|
514
591
|
const u = typeof s == "string" ? s : (s == null ? void 0 : s.message) || "Connection error";
|
|
515
592
|
(p = e.onError) == null || p.call(e, s), this.emit("error", u);
|
|
516
|
-
}, this.onTranscription = (s, u) => {
|
|
517
|
-
var
|
|
518
|
-
(
|
|
593
|
+
}, this.onTranscription = (s, u, p) => {
|
|
594
|
+
var d;
|
|
595
|
+
(d = e.onTranscription) == null || d.call(e, s, u), this.emit("transcription", { text: s, isFinal: u, role: p });
|
|
519
596
|
}, this.onLocalStream = e.onLocalStream || (() => {
|
|
520
597
|
}), this.onRemoteTrack = (s, u) => {
|
|
521
598
|
var p;
|
|
522
599
|
(p = e.onRemoteTrack) == null || p.call(e, s, u), this.emit("track", { track: s, stream: u });
|
|
523
600
|
}, this.onClientToolCall = (s) => {
|
|
524
|
-
var
|
|
525
|
-
(
|
|
601
|
+
var d;
|
|
602
|
+
(d = e.onClientToolCall) == null || d.call(e, s);
|
|
526
603
|
const u = (s == null ? void 0 : s.data) || s, p = {
|
|
527
604
|
name: String(u.name || u.tool_name || ""),
|
|
528
605
|
arguments: u.arguments || u.args || {},
|
|
@@ -531,7 +608,7 @@ const y = class y {
|
|
|
531
608
|
client_fields: u.client_fields || {}
|
|
532
609
|
};
|
|
533
610
|
p.name && p.tool_call_id && this.emit("tool_call", p);
|
|
534
|
-
}, this.runtime = e.runtime, typeof window < "u" && e.trackRouteContext !== !1 && (this.routeTracker = new
|
|
611
|
+
}, this.runtime = e.runtime, typeof window < "u" && e.trackRouteContext !== !1 && (this.routeTracker = new Ie({
|
|
535
612
|
sendContext: (s) => this.sendContextUpdate(s),
|
|
536
613
|
isReady: () => {
|
|
537
614
|
var s;
|
|
@@ -557,7 +634,7 @@ const y = class y {
|
|
|
557
634
|
*/
|
|
558
635
|
async connect() {
|
|
559
636
|
var t;
|
|
560
|
-
this._status = "connecting";
|
|
637
|
+
this._status = "connecting", this.connectStallTimeoutMs > 0 && ge(this.connectStallTimeoutMs);
|
|
561
638
|
const e = ++this.connectGeneration;
|
|
562
639
|
if (await this.loadCallSession(), !this.isConnectCancelled(e)) {
|
|
563
640
|
if (!this.serverUrl)
|
|
@@ -570,15 +647,15 @@ const y = class y {
|
|
|
570
647
|
} catch {
|
|
571
648
|
}
|
|
572
649
|
try {
|
|
573
|
-
this.appliedRemoteCandidates.clear(), this.stopRemoteIcePolling();
|
|
574
|
-
const
|
|
650
|
+
this.appliedRemoteCandidates.clear(), this.remoteDescSet = !1, this.pendingServerIce = [], this.icePollStop = !1, this.stopRemoteIcePolling();
|
|
651
|
+
const n = this.getIceServers();
|
|
575
652
|
this.pc = new RTCPeerConnection({
|
|
576
|
-
iceServers:
|
|
653
|
+
iceServers: n,
|
|
577
654
|
iceTransportPolicy: "all"
|
|
578
655
|
});
|
|
579
|
-
let
|
|
656
|
+
let a;
|
|
580
657
|
try {
|
|
581
|
-
|
|
658
|
+
a = await navigator.mediaDevices.getUserMedia({
|
|
582
659
|
audio: {
|
|
583
660
|
echoCancellation: !0,
|
|
584
661
|
noiseSuppression: !0,
|
|
@@ -587,78 +664,73 @@ const y = class y {
|
|
|
587
664
|
channelCount: 1
|
|
588
665
|
}
|
|
589
666
|
});
|
|
590
|
-
} catch (
|
|
591
|
-
if (
|
|
667
|
+
} catch (d) {
|
|
668
|
+
if (d.name === "NotAllowedError" || d.name === "PermissionDeniedError" || (t = d.message) != null && t.includes("Permission denied")) {
|
|
592
669
|
const _ = navigator.userAgent, m = /iPad|iPhone|iPod/.test(_) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
|
|
593
670
|
let f = "Microphone access denied. Please allow microphone access in your browser settings.";
|
|
594
671
|
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).");
|
|
595
|
-
const
|
|
596
|
-
throw
|
|
672
|
+
const w = new Error(f);
|
|
673
|
+
throw w.name = d.name, w;
|
|
597
674
|
}
|
|
598
|
-
throw
|
|
675
|
+
throw d;
|
|
599
676
|
}
|
|
600
677
|
if (this.isConnectCancelled(e)) {
|
|
601
|
-
|
|
678
|
+
a.getTracks().forEach((d) => d.stop());
|
|
602
679
|
return;
|
|
603
680
|
}
|
|
604
|
-
if (this.localStream =
|
|
605
|
-
|
|
681
|
+
if (this.localStream = a, !this.pc || this.isConnectCancelled(e)) {
|
|
682
|
+
a.getTracks().forEach((d) => d.stop());
|
|
606
683
|
return;
|
|
607
684
|
}
|
|
608
|
-
if (this.onLocalStream(
|
|
685
|
+
if (this.onLocalStream(a), a.getTracks().forEach((d) => {
|
|
609
686
|
var _;
|
|
610
|
-
(_ = this.pc) == null || _.addTrack(
|
|
687
|
+
(_ = this.pc) == null || _.addTrack(d, a);
|
|
611
688
|
}), !this.pc)
|
|
612
689
|
throw new Error("RTCPeerConnection was closed unexpectedly");
|
|
613
690
|
this.dataChannel = this.pc.createDataChannel("control"), this.dataChannel.onopen = () => {
|
|
614
|
-
var
|
|
615
|
-
(
|
|
616
|
-
}, this.dataChannel.onmessage = (
|
|
617
|
-
if (typeof
|
|
691
|
+
var d;
|
|
692
|
+
(d = this.routeTracker) == null || d.onChannelReady();
|
|
693
|
+
}, this.dataChannel.onmessage = (d) => {
|
|
694
|
+
if (typeof d.data == "string")
|
|
618
695
|
try {
|
|
619
|
-
this.handleControlEvent(JSON.parse(
|
|
696
|
+
this.handleControlEvent(JSON.parse(d.data));
|
|
620
697
|
} catch {
|
|
621
698
|
}
|
|
622
|
-
else if (
|
|
699
|
+
else if (d.data instanceof ArrayBuffer)
|
|
623
700
|
try {
|
|
624
|
-
const _ = new TextDecoder().decode(
|
|
701
|
+
const _ = new TextDecoder().decode(d.data);
|
|
625
702
|
try {
|
|
626
703
|
const m = JSON.parse(_);
|
|
627
|
-
|
|
704
|
+
pe(m) && this.handleControlEvent(m);
|
|
628
705
|
} catch {
|
|
629
706
|
}
|
|
630
707
|
} catch {
|
|
631
708
|
}
|
|
632
|
-
else
|
|
709
|
+
else d.data instanceof Blob && d.data.text().then((_) => {
|
|
633
710
|
try {
|
|
634
711
|
this.handleControlEvent(JSON.parse(_));
|
|
635
712
|
} catch {
|
|
636
713
|
}
|
|
637
714
|
});
|
|
638
|
-
}, this.dataChannel.onerror = (
|
|
715
|
+
}, this.dataChannel.onerror = (d) => {
|
|
639
716
|
}, this.mediaBytesChannel = this.pc.createDataChannel("media-bytes", { ordered: !0 }), this.mediaBytesChannel.binaryType = "arraybuffer", this.mediaBytesChannel.onopen = () => {
|
|
640
|
-
}, this.mediaBytesChannel.onerror = (
|
|
641
|
-
}, this.pc.ontrack = (
|
|
642
|
-
const _ =
|
|
717
|
+
}, this.mediaBytesChannel.onerror = (d) => {
|
|
718
|
+
}, this.pc.ontrack = (d) => {
|
|
719
|
+
const _ = d.track, m = d.streams[0];
|
|
643
720
|
_.kind === "audio" ? (this.audioElement = new Audio(), this.audioElement.srcObject = m, this.audioElement.play().catch((f) => {
|
|
644
721
|
}), this.audioElement.onended = () => {
|
|
645
722
|
this.sendEvent("playedStream"), typeof window < "u" && window.dispatchEvent(new CustomEvent("vanira:agent-playback-ended"));
|
|
646
723
|
}, this.onRemoteTrack(_, m)) : _.kind === "video" && this.onRemoteTrack(_, m);
|
|
647
724
|
};
|
|
648
725
|
const r = () => {
|
|
649
|
-
var m, f,
|
|
650
|
-
const
|
|
651
|
-
((
|
|
726
|
+
var m, f, w, U, L, M, D, O, N, V, B;
|
|
727
|
+
const d = ((m = this.pc) == null ? void 0 : m.connectionState) === "connected" || ((f = this.pc) == null ? void 0 : f.iceConnectionState) === "connected" || ((w = this.pc) == null ? void 0 : w.iceConnectionState) === "completed", _ = ((U = this.pc) == null ? void 0 : U.connectionState) === "failed" || ((L = this.pc) == null ? void 0 : L.iceConnectionState) === "failed" || ((M = this.pc) == null ? void 0 : M.connectionState) === "closed" || ((D = this.pc) == null ? void 0 : D.iceConnectionState) === "closed" || ((O = this.pc) == null ? void 0 : O.connectionState) === "disconnected" || ((N = this.pc) == null ? void 0 : N.iceConnectionState) === "disconnected";
|
|
728
|
+
((V = this.pc) == null ? void 0 : V.connectionState) === "connected" && this.stopRemoteIcePolling(), d && !this.connected ? (this.connected = !0, (B = this.routeTracker) == null || B.start(), this.onConnected()) : _ && this.connected && (this.connected = !1, this.liveVisionAutoStarted = !1, this.onDisconnected());
|
|
652
729
|
};
|
|
653
730
|
this.pc.onconnectionstatechange = r, this.pc.oniceconnectionstatechange = r;
|
|
654
731
|
const o = this.getIceTrickleUrl();
|
|
655
|
-
this.pc.onicecandidate = (
|
|
656
|
-
|
|
657
|
-
method: "POST",
|
|
658
|
-
headers: { "Content-Type": "application/json" },
|
|
659
|
-
body: JSON.stringify({ candidate: l.candidate.toJSON() })
|
|
660
|
-
}).catch((_) => {
|
|
661
|
-
});
|
|
732
|
+
this.pc.onicecandidate = (d) => {
|
|
733
|
+
d.candidate && this.sendRemoteIceCandidate(d.candidate, o);
|
|
662
734
|
};
|
|
663
735
|
const h = await this.pc.createOffer();
|
|
664
736
|
if (this.isConnectCancelled(e) || (await this.pc.setLocalDescription(h), this.isConnectCancelled(e))) return;
|
|
@@ -673,32 +745,32 @@ const y = class y {
|
|
|
673
745
|
});
|
|
674
746
|
if (this.isConnectCancelled(e)) return;
|
|
675
747
|
if (!u.ok) {
|
|
676
|
-
const
|
|
677
|
-
throw new Error(
|
|
748
|
+
const d = await u.json();
|
|
749
|
+
throw new Error(d.error || `HTTP ${u.status}`);
|
|
678
750
|
}
|
|
679
751
|
const { answer: p } = await u.json();
|
|
680
|
-
if (this.isConnectCancelled(e) || !this.pc || (await this.pc.setRemoteDescription(p), this.isConnectCancelled(e))) return;
|
|
752
|
+
if (this.isConnectCancelled(e) || !this.pc || (await this.pc.setRemoteDescription(p), this.isConnectCancelled(e)) || (this.remoteDescSet = !0, await this.flushPendingServerIce(), this.isConnectCancelled(e))) return;
|
|
681
753
|
this.startRemoteIcePolling(o);
|
|
682
|
-
} catch (
|
|
754
|
+
} catch (n) {
|
|
683
755
|
if (this.isConnectCancelled(e)) return;
|
|
684
|
-
throw this.disconnect(), this.onError(
|
|
756
|
+
throw this.disconnect(), this.onError(n.message || n), n;
|
|
685
757
|
}
|
|
686
758
|
}
|
|
687
759
|
}
|
|
688
760
|
createCallCacheKey(e, t) {
|
|
689
|
-
const
|
|
761
|
+
const n = this.apiKey ? `key:${this.apiKey.slice(0, 16)}` : `token:${(this.token || "").slice(-16)}`;
|
|
690
762
|
return [
|
|
691
763
|
this.backendUrl,
|
|
692
764
|
this.agentId,
|
|
693
765
|
e,
|
|
694
766
|
t || "",
|
|
695
767
|
this.prospectId || "",
|
|
696
|
-
|
|
768
|
+
n
|
|
697
769
|
].join("|");
|
|
698
770
|
}
|
|
699
|
-
async postCreateCall(e, t,
|
|
771
|
+
async postCreateCall(e, t, n) {
|
|
700
772
|
var h, s, u;
|
|
701
|
-
const
|
|
773
|
+
const a = await fetch(`${this.backendUrl}/calls/create`, {
|
|
702
774
|
method: "POST",
|
|
703
775
|
headers: e,
|
|
704
776
|
body: JSON.stringify({
|
|
@@ -707,14 +779,16 @@ const y = class y {
|
|
|
707
779
|
mode: t,
|
|
708
780
|
...(s = this.runtime) != null && s.runtimeName ? { runtime: this.runtime.runtimeName } : {},
|
|
709
781
|
prospect_id: this.prospectId,
|
|
710
|
-
...
|
|
782
|
+
...this.prospectName ? { prospect_name: this.prospectName } : {},
|
|
783
|
+
...this.extraDetails && Object.keys(this.extraDetails).length ? { extra_details: this.extraDetails } : {},
|
|
784
|
+
...n ? { call_id: n } : {}
|
|
711
785
|
})
|
|
712
786
|
});
|
|
713
|
-
if (!
|
|
714
|
-
const p = await
|
|
715
|
-
throw new Error(`[VaniraClient] createCall failed (${
|
|
787
|
+
if (!a.ok) {
|
|
788
|
+
const p = await a.json().catch(() => ({}));
|
|
789
|
+
throw new Error(`[VaniraClient] createCall failed (${a.status}): ${((u = p == null ? void 0 : p.detail) == null ? void 0 : u.message) || (p == null ? void 0 : p.message) || a.statusText}`);
|
|
716
790
|
}
|
|
717
|
-
const r = await
|
|
791
|
+
const r = await a.json();
|
|
718
792
|
if (!r.call_id || !r.worker_url)
|
|
719
793
|
throw new Error("[VaniraClient] /calls/create response missing call_id or worker_url");
|
|
720
794
|
const o = y.normalizeIceServers(r.ice_servers);
|
|
@@ -728,7 +802,7 @@ const y = class y {
|
|
|
728
802
|
};
|
|
729
803
|
}
|
|
730
804
|
applyCreateCallSession(e) {
|
|
731
|
-
if (this.callId = e.callId, this.prospectId = e.prospectId || this.prospectId, this.serverUrl = e.serverUrl, this.iceServers = e.iceServers, this.callSessionLoaded = !0,
|
|
805
|
+
if (this.callId = e.callId, this.prospectId = e.prospectId || this.prospectId, this.serverUrl = e.serverUrl, this.iceServers = e.iceServers, this.callSessionLoaded = !0, he(this.agentId, this.callId || "", this.prospectId), this.onSessionStarted && this.prospectId && this.callId && !this.sessionStartedEmitted)
|
|
732
806
|
try {
|
|
733
807
|
this.onSessionStarted({ prospectId: this.prospectId, callId: this.callId, serverUrl: this.serverUrl }), this.sessionStartedEmitted = !0;
|
|
734
808
|
} catch {
|
|
@@ -744,10 +818,10 @@ const y = class y {
|
|
|
744
818
|
throw new Error("[VaniraClient] apiKey or token is required to create a call session");
|
|
745
819
|
const e = { "Content-Type": "application/json" };
|
|
746
820
|
this.apiKey ? e["X-API-Key"] = this.apiKey : this.token && (e.Authorization = this.token.startsWith("Bearer ") ? this.token : `Bearer ${this.token}`);
|
|
747
|
-
const t = this.sessionBehavior === "continue" ? this.callId : void 0,
|
|
748
|
-
let r = y.inflightCreates.get(
|
|
749
|
-
r || (r = this.postCreateCall(e,
|
|
750
|
-
y.inflightCreates.get(
|
|
821
|
+
const t = this.sessionBehavior === "continue" ? this.callId : void 0, n = this.sessionBehavior === "continue" ? "continue" : "new", a = this.createCallCacheKey(n, t);
|
|
822
|
+
let r = y.inflightCreates.get(a);
|
|
823
|
+
r || (r = this.postCreateCall(e, n, t), y.inflightCreates.set(a, r), r.finally(() => {
|
|
824
|
+
y.inflightCreates.get(a) === r && y.inflightCreates.delete(a);
|
|
751
825
|
}));
|
|
752
826
|
const o = await r;
|
|
753
827
|
this.applyCreateCallSession(o);
|
|
@@ -760,10 +834,10 @@ const y = class y {
|
|
|
760
834
|
static normalizeIceServers(e) {
|
|
761
835
|
if (!Array.isArray(e)) return [];
|
|
762
836
|
const t = [];
|
|
763
|
-
for (const
|
|
764
|
-
const
|
|
837
|
+
for (const n of e) {
|
|
838
|
+
const a = n == null ? void 0 : n.urls, r = Array.isArray(a) ? a.filter(Boolean) : typeof a == "string" && a.trim() ? [a.trim()] : [];
|
|
765
839
|
if (!r.length) continue;
|
|
766
|
-
const o = { urls: r.length === 1 ? r[0] : r }, h =
|
|
840
|
+
const o = { urls: r.length === 1 ? r[0] : r }, h = n.username, s = n.credential;
|
|
767
841
|
h && (o.username = h), s && (o.credential = s), t.push(o);
|
|
768
842
|
}
|
|
769
843
|
return t;
|
|
@@ -789,52 +863,92 @@ const y = class y {
|
|
|
789
863
|
return `${this.getWorkerOrigin()}/webrtc/ice?agent_id=${this.agentId}&call_id=${this.callId}`;
|
|
790
864
|
}
|
|
791
865
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
866
|
+
async sendRemoteIceCandidate(e, t) {
|
|
867
|
+
try {
|
|
868
|
+
const n = await fetch(t, {
|
|
869
|
+
method: "POST",
|
|
870
|
+
headers: { "Content-Type": "application/json" },
|
|
871
|
+
body: JSON.stringify({ candidate: e.toJSON() })
|
|
872
|
+
});
|
|
873
|
+
if (n.ok) {
|
|
874
|
+
const a = await n.json();
|
|
875
|
+
await this.applyServerIceCandidates(a.candidates);
|
|
797
876
|
}
|
|
798
|
-
|
|
799
|
-
|
|
877
|
+
} catch {
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
/** Queue server ICE until setRemoteDescription(answer), then apply. */
|
|
881
|
+
async applyServerIceCandidates(e) {
|
|
882
|
+
if (!(!this.pc || !(e != null && e.length))) {
|
|
883
|
+
if (!this.remoteDescSet) {
|
|
884
|
+
this.pendingServerIce.push(...e);
|
|
800
885
|
return;
|
|
801
886
|
}
|
|
802
|
-
|
|
803
|
-
const
|
|
804
|
-
if (!
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
this.appliedRemoteCandidates.add(r);
|
|
810
|
-
try {
|
|
811
|
-
await this.pc.addIceCandidate(n);
|
|
812
|
-
} catch {
|
|
813
|
-
}
|
|
887
|
+
for (const t of e) {
|
|
888
|
+
const n = JSON.stringify(t);
|
|
889
|
+
if (!this.appliedRemoteCandidates.has(n)) {
|
|
890
|
+
this.appliedRemoteCandidates.add(n);
|
|
891
|
+
try {
|
|
892
|
+
await this.pc.addIceCandidate(t);
|
|
893
|
+
} catch {
|
|
814
894
|
}
|
|
815
895
|
}
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
async flushPendingServerIce() {
|
|
900
|
+
if (!this.pc || !this.remoteDescSet || this.pendingServerIce.length === 0) return;
|
|
901
|
+
const e = this.pendingServerIce;
|
|
902
|
+
this.pendingServerIce = [];
|
|
903
|
+
for (const t of e) {
|
|
904
|
+
const n = JSON.stringify(t);
|
|
905
|
+
if (!this.appliedRemoteCandidates.has(n)) {
|
|
906
|
+
this.appliedRemoteCandidates.add(n);
|
|
907
|
+
try {
|
|
908
|
+
await this.pc.addIceCandidate(t);
|
|
909
|
+
} catch {
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
startRemoteIcePolling(e) {
|
|
915
|
+
this.icePollStop = !1, this.pollServerIce(e);
|
|
916
|
+
}
|
|
917
|
+
async pollServerIce(e) {
|
|
918
|
+
var n;
|
|
919
|
+
const t = Date.now() + 15e3;
|
|
920
|
+
for (; !this.icePollStop && Date.now() < t; ) {
|
|
921
|
+
const a = (n = this.pc) == null ? void 0 : n.connectionState;
|
|
922
|
+
if (a === "connected" || a === "failed" || a === "closed") break;
|
|
923
|
+
try {
|
|
924
|
+
const r = await fetch(e, { method: "GET" });
|
|
925
|
+
if (r.ok) {
|
|
926
|
+
const o = await r.json();
|
|
927
|
+
if (await this.applyServerIceCandidates(o.candidates), o.done && (!o.candidates || o.candidates.length === 0)) break;
|
|
928
|
+
}
|
|
816
929
|
} catch {
|
|
817
930
|
}
|
|
818
|
-
|
|
931
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
932
|
+
}
|
|
819
933
|
}
|
|
820
934
|
stopRemoteIcePolling() {
|
|
821
|
-
this.
|
|
935
|
+
this.icePollStop = !0;
|
|
822
936
|
}
|
|
823
937
|
/**
|
|
824
938
|
* Send control event via DataChannel
|
|
825
939
|
*/
|
|
826
940
|
sendEvent(e, t = {}) {
|
|
827
|
-
var
|
|
828
|
-
if (((
|
|
829
|
-
const
|
|
830
|
-
this.dataChannel.send(JSON.stringify(
|
|
941
|
+
var n;
|
|
942
|
+
if (((n = this.dataChannel) == null ? void 0 : n.readyState) === "open") {
|
|
943
|
+
const a = { event: e, ...t };
|
|
944
|
+
this.dataChannel.send(JSON.stringify(a));
|
|
831
945
|
}
|
|
832
946
|
}
|
|
833
947
|
/** Wait for control DataChannel, then send (live vision lifecycle events). */
|
|
834
|
-
async sendEventWhenReady(e, t = {},
|
|
948
|
+
async sendEventWhenReady(e, t = {}, n = 1e4) {
|
|
835
949
|
var r;
|
|
836
|
-
const
|
|
837
|
-
for (; Date.now() <
|
|
950
|
+
const a = Date.now() + n;
|
|
951
|
+
for (; Date.now() < a; ) {
|
|
838
952
|
if (((r = this.dataChannel) == null ? void 0 : r.readyState) === "open")
|
|
839
953
|
return this.sendEvent(e, t), !0;
|
|
840
954
|
await new Promise((o) => setTimeout(o, 50));
|
|
@@ -877,26 +991,36 @@ const y = class y {
|
|
|
877
991
|
var t;
|
|
878
992
|
switch (e.event) {
|
|
879
993
|
case "clearAudio":
|
|
994
|
+
this.dispatchBoardAbort(
|
|
995
|
+
"User interrupted while LaTeX was writing",
|
|
996
|
+
void 0,
|
|
997
|
+
c.WriteLatexText
|
|
998
|
+
);
|
|
880
999
|
break;
|
|
881
1000
|
case "transcription":
|
|
882
|
-
|
|
1001
|
+
{
|
|
1002
|
+
const n = e.data && typeof e.data == "object" ? e.data : {}, a = String(e.text ?? n.text ?? "").trim(), r = e.isFinal ?? e.is_final ?? n.isFinal ?? n.is_final, o = r === void 0 ? !0 : r === !0 || r === "true", h = String(
|
|
1003
|
+
e.role ?? e.speaker ?? n.role ?? n.speaker ?? ""
|
|
1004
|
+
).trim() || void 0;
|
|
1005
|
+
a && this.onTranscription(a, o, h);
|
|
1006
|
+
}
|
|
883
1007
|
break;
|
|
884
1008
|
case "mark":
|
|
885
1009
|
break;
|
|
886
1010
|
case "client_tool_cancel": {
|
|
887
|
-
const
|
|
888
|
-
this.dispatchBoardAbort("Tool cancelled by server",
|
|
1011
|
+
const a = (e.data || e).tool_call_id || e.tool_call_id;
|
|
1012
|
+
this.dispatchBoardAbort("Tool cancelled by server", a);
|
|
889
1013
|
break;
|
|
890
1014
|
}
|
|
891
1015
|
case "client_tool_call": {
|
|
892
|
-
const
|
|
893
|
-
|
|
1016
|
+
const n = e.tool_call || e.data || e, a = (n == null ? void 0 : n.tool_call_id) || (n == null ? void 0 : n.call_id) || e.tool_call_id || "";
|
|
1017
|
+
a && ((t = this.dataChannel) == null ? void 0 : t.readyState) === "open" && this.dataChannel.send(JSON.stringify({
|
|
894
1018
|
event: "client_tool_ack",
|
|
895
|
-
data: { tool_call_id:
|
|
1019
|
+
data: { tool_call_id: a }
|
|
896
1020
|
}));
|
|
897
|
-
const r = (
|
|
1021
|
+
const r = (n == null ? void 0 : n.arguments) || (n == null ? void 0 : n.args) || {}, o = (n == null ? void 0 : n.client_fields) || {}, h = (n == null ? void 0 : n.name) || (n == null ? void 0 : n.tool_name) || "", s = de(o, r, h);
|
|
898
1022
|
if (h === "end_call") {
|
|
899
|
-
|
|
1023
|
+
a && this.sendToolResult(a, {
|
|
900
1024
|
status: "client_ack_end_call",
|
|
901
1025
|
message: "Ending call."
|
|
902
1026
|
}), window.setTimeout(() => this.disconnect(), 120);
|
|
@@ -904,11 +1028,11 @@ const y = class y {
|
|
|
904
1028
|
}
|
|
905
1029
|
if (s) {
|
|
906
1030
|
window.dispatchEvent(new CustomEvent("vanira:preset", {
|
|
907
|
-
detail: { toolCall:
|
|
908
|
-
})), this.onClientToolCall(
|
|
1031
|
+
detail: { toolCall: n, client: this }
|
|
1032
|
+
})), this.onClientToolCall(n);
|
|
909
1033
|
break;
|
|
910
1034
|
}
|
|
911
|
-
this.onClientToolCall(
|
|
1035
|
+
this.onClientToolCall(n);
|
|
912
1036
|
break;
|
|
913
1037
|
}
|
|
914
1038
|
}
|
|
@@ -918,7 +1042,7 @@ const y = class y {
|
|
|
918
1042
|
*/
|
|
919
1043
|
disconnect() {
|
|
920
1044
|
var e;
|
|
921
|
-
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) => {
|
|
1045
|
+
g(), this.connectGeneration++, this.stopRemoteIcePolling(), this.appliedRemoteCandidates.clear(), this.remoteDescSet = !1, this.pendingServerIce = [], this.audioElement && (this.audioElement.pause(), this.audioElement.srcObject = null), this.dataChannel && (this.dataChannel.close(), this.dataChannel = null), this.mediaBytesChannel && (this.mediaBytesChannel.close(), this.mediaBytesChannel = null), this.pc && (this.pc.getSenders().forEach((t) => {
|
|
922
1046
|
t.track && t.track.stop();
|
|
923
1047
|
}), this.pc.close(), this.pc = null), this.localStream && (this.localStream.getTracks().forEach((t) => {
|
|
924
1048
|
try {
|
|
@@ -932,12 +1056,12 @@ const y = class y {
|
|
|
932
1056
|
* Uses track.enabled (not pause) so audio resumes correctly when unmuted.
|
|
933
1057
|
*/
|
|
934
1058
|
setMicrophoneMuted(e) {
|
|
935
|
-
var t,
|
|
936
|
-
this.micMuted = e, (t = this.localStream) == null || t.getAudioTracks().forEach((
|
|
937
|
-
|
|
938
|
-
}), (
|
|
1059
|
+
var t, n;
|
|
1060
|
+
this.micMuted = e, (t = this.localStream) == null || t.getAudioTracks().forEach((a) => {
|
|
1061
|
+
a.enabled = !e;
|
|
1062
|
+
}), (n = this.pc) == null || n.getSenders().forEach((a) => {
|
|
939
1063
|
var r;
|
|
940
|
-
((r =
|
|
1064
|
+
((r = a.track) == null ? void 0 : r.kind) === "audio" && (a.track.enabled = !e);
|
|
941
1065
|
});
|
|
942
1066
|
}
|
|
943
1067
|
isMicrophoneMuted() {
|
|
@@ -950,9 +1074,9 @@ const y = class y {
|
|
|
950
1074
|
return e !== this.connectGeneration;
|
|
951
1075
|
}
|
|
952
1076
|
/** Notify WidgetPresetRenderer to cancel in-flight board animations */
|
|
953
|
-
dispatchBoardAbort(e, t) {
|
|
1077
|
+
dispatchBoardAbort(e, t, n) {
|
|
954
1078
|
typeof window > "u" || window.dispatchEvent(new CustomEvent("vanira:board_abort", {
|
|
955
|
-
detail: { reason: e, toolCallId: t }
|
|
1079
|
+
detail: { reason: e, toolCallId: t, presetId: n }
|
|
956
1080
|
}));
|
|
957
1081
|
}
|
|
958
1082
|
/**
|
|
@@ -967,7 +1091,7 @@ const y = class y {
|
|
|
967
1091
|
call_id: this.callId,
|
|
968
1092
|
data: { tool_call_id: e, result: t },
|
|
969
1093
|
result: t
|
|
970
|
-
});
|
|
1094
|
+
}), this.emit("tool_result", { toolCallId: e, result: t });
|
|
971
1095
|
}
|
|
972
1096
|
/**
|
|
973
1097
|
* Send an acknowledgement that the client received a tool call and rendered it.
|
|
@@ -1041,8 +1165,8 @@ const y = class y {
|
|
|
1041
1165
|
* @param reason Routing key for backend processing (default: 'general')
|
|
1042
1166
|
* @param message Optional user text message about the file
|
|
1043
1167
|
*/
|
|
1044
|
-
async uploadMedia(e, t = "general",
|
|
1045
|
-
return await
|
|
1168
|
+
async uploadMedia(e, t = "general", n = "") {
|
|
1169
|
+
return await fe(this.dataChannel, this.mediaBytesChannel) ? this._uploadMediaViaDataChannel(e, t, n) : (me(this.dataChannel, this.mediaBytesChannel), this._uploadMediaViaHTTP(e, t, n));
|
|
1046
1170
|
}
|
|
1047
1171
|
/**
|
|
1048
1172
|
* Upload a live vision / screen frame — HTTP only for now, never sends client_media_update.
|
|
@@ -1051,55 +1175,55 @@ const y = class y {
|
|
|
1051
1175
|
* Frames require a real media_url (server rejects empty). WebRTC upload returns url="" until
|
|
1052
1176
|
* the server adds client_media_upload_ready ack — use HTTP for frame JPEGs until then.
|
|
1053
1177
|
*/
|
|
1054
|
-
async uploadMediaFrame(e, t = "camera_capture",
|
|
1055
|
-
const
|
|
1178
|
+
async uploadMediaFrame(e, t = "camera_capture", n) {
|
|
1179
|
+
const a = n && !(e instanceof File) ? new File([e], n, { type: e.type || "image/jpeg" }) : e, { media_id: r, url: o, contentType: h } = await this._postMediaUpload(a, t, !0);
|
|
1056
1180
|
if (!r || !o)
|
|
1057
1181
|
throw new Error("Frame upload failed: server response missing media_id or url");
|
|
1058
1182
|
return { media_id: r, url: o, content_type: h };
|
|
1059
1183
|
}
|
|
1060
1184
|
/** WebRTC media-bytes path (control start/complete + binary chunks). */
|
|
1061
|
-
async _uploadBytesViaDataChannel(e, t,
|
|
1185
|
+
async _uploadBytesViaDataChannel(e, t, n, a, r) {
|
|
1062
1186
|
if (!this.callId || !this.mediaBytesChannel)
|
|
1063
1187
|
throw new Error("Upload failed: call not ready for WebRTC media upload.");
|
|
1064
|
-
const o = r || (e instanceof File ? e.name :
|
|
1065
|
-
return
|
|
1188
|
+
const o = r || (e instanceof File ? e.name : a === "frame" ? "frame.jpg" : "upload.bin"), h = e.type || (a === "frame" ? "image/jpeg" : "application/octet-stream"), s = await Se(e);
|
|
1189
|
+
return ye({
|
|
1066
1190
|
bytes: s,
|
|
1067
1191
|
filename: o,
|
|
1068
1192
|
contentType: h,
|
|
1069
1193
|
reason: t,
|
|
1070
|
-
message:
|
|
1194
|
+
message: n,
|
|
1071
1195
|
callId: this.callId,
|
|
1072
1196
|
mediaBytesChannel: this.mediaBytesChannel,
|
|
1073
1197
|
sendControlEvent: (u, p) => this.sendEvent(u, p),
|
|
1074
|
-
uploadKind:
|
|
1198
|
+
uploadKind: a
|
|
1075
1199
|
});
|
|
1076
1200
|
}
|
|
1077
|
-
async _uploadMediaViaDataChannel(e, t,
|
|
1078
|
-
const
|
|
1079
|
-
return { media_id:
|
|
1201
|
+
async _uploadMediaViaDataChannel(e, t, n) {
|
|
1202
|
+
const a = await this._uploadBytesViaDataChannel(e, t, n, "media");
|
|
1203
|
+
return { media_id: a.media_id, url: a.url };
|
|
1080
1204
|
}
|
|
1081
1205
|
/** HTTP fallback — original uploadMedia behavior (unchanged). */
|
|
1082
|
-
async _uploadMediaViaHTTP(e, t = "general",
|
|
1083
|
-
const { media_id:
|
|
1206
|
+
async _uploadMediaViaHTTP(e, t = "general", n = "") {
|
|
1207
|
+
const { media_id: a, url: r, contentType: o } = await this._postMediaUpload(e, t, !0);
|
|
1084
1208
|
return this.sendMediaUpdate({
|
|
1085
|
-
media_id:
|
|
1209
|
+
media_id: a,
|
|
1086
1210
|
media_url: r,
|
|
1087
1211
|
content_type: o,
|
|
1088
1212
|
reason: t,
|
|
1089
|
-
message:
|
|
1090
|
-
}), { media_id:
|
|
1213
|
+
message: n
|
|
1214
|
+
}), { media_id: a, url: r };
|
|
1091
1215
|
}
|
|
1092
|
-
async _postMediaUpload(e, t,
|
|
1216
|
+
async _postMediaUpload(e, t, n = !1) {
|
|
1093
1217
|
if (!this.serverUrl)
|
|
1094
1218
|
throw new Error("Upload failed: serverUrl is not set. Connect the VaniraClient first.");
|
|
1095
1219
|
if (!this.callId)
|
|
1096
1220
|
throw new Error("Upload failed: callId is missing.");
|
|
1097
|
-
const
|
|
1098
|
-
if (!
|
|
1221
|
+
const a = this.getWorkerOrigin();
|
|
1222
|
+
if (!a)
|
|
1099
1223
|
throw new Error(
|
|
1100
1224
|
"Upload failed: worker_url is not set. Connect the call before uploading media."
|
|
1101
1225
|
);
|
|
1102
|
-
const r = `${
|
|
1226
|
+
const r = `${a}/media/upload`, o = new FormData();
|
|
1103
1227
|
o.append("file", e), o.append("call_id", this.callId), o.append("reason", t);
|
|
1104
1228
|
const h = await fetch(r, {
|
|
1105
1229
|
method: "POST",
|
|
@@ -1113,10 +1237,10 @@ const y = class y {
|
|
|
1113
1237
|
}
|
|
1114
1238
|
throw new Error(`Upload failed: ${_}`);
|
|
1115
1239
|
}
|
|
1116
|
-
const s = await h.json(), u = s.media_id, p = s.url,
|
|
1240
|
+
const s = await h.json(), u = s.media_id, p = s.url, d = s.content_type || e.type;
|
|
1117
1241
|
if (!u || !p)
|
|
1118
1242
|
throw new Error("Upload failed: server response missing media_id or url");
|
|
1119
|
-
return
|
|
1243
|
+
return n ? { media_id: u, url: p, contentType: d } : { media_id: u, url: p, contentType: d };
|
|
1120
1244
|
}
|
|
1121
1245
|
// ─── Event emitter (replaces retired VaniraAI) ───────────────────────────
|
|
1122
1246
|
get status() {
|
|
@@ -1129,12 +1253,12 @@ const y = class y {
|
|
|
1129
1253
|
return this.listeners.has(e) || this.listeners.set(e, /* @__PURE__ */ new Set()), this.listeners.get(e).add(t), this;
|
|
1130
1254
|
}
|
|
1131
1255
|
off(e, t) {
|
|
1132
|
-
var
|
|
1133
|
-
return (
|
|
1256
|
+
var n;
|
|
1257
|
+
return (n = this.listeners.get(e)) == null || n.delete(t), this;
|
|
1134
1258
|
}
|
|
1135
1259
|
emit(e, t) {
|
|
1136
|
-
var
|
|
1137
|
-
(
|
|
1260
|
+
var n;
|
|
1261
|
+
(n = this.listeners.get(e)) == null || n.forEach((a) => a(t));
|
|
1138
1262
|
}
|
|
1139
1263
|
/** Alias for connect() — VaniraAI compatibility */
|
|
1140
1264
|
async start() {
|
|
@@ -1164,9 +1288,9 @@ const y = class y {
|
|
|
1164
1288
|
}
|
|
1165
1289
|
};
|
|
1166
1290
|
/** Dedupes concurrent POST /calls/create (e.g. React StrictMode double-mount). */
|
|
1167
|
-
|
|
1168
|
-
let
|
|
1169
|
-
const
|
|
1291
|
+
l(y, "inflightCreates", /* @__PURE__ */ new Map());
|
|
1292
|
+
let A = y;
|
|
1293
|
+
const Te = {
|
|
1170
1294
|
supportsAudioEndedEvent: !1,
|
|
1171
1295
|
supportsScreenShare: !1,
|
|
1172
1296
|
supportsDom: !1,
|
|
@@ -1174,40 +1298,40 @@ const me = {
|
|
|
1174
1298
|
supportsCustomElements: !1,
|
|
1175
1299
|
supportsLocalStorage: !1,
|
|
1176
1300
|
supportsBroadcastChannel: !1
|
|
1177
|
-
},
|
|
1301
|
+
}, be = {
|
|
1178
1302
|
name: "react-native",
|
|
1179
1303
|
callType: "web",
|
|
1180
1304
|
runtimeName: "react-native",
|
|
1181
1305
|
callIdPrefix: "rn_",
|
|
1182
|
-
capabilities:
|
|
1183
|
-
audio: new
|
|
1184
|
-
media: new
|
|
1185
|
-
peer: new
|
|
1186
|
-
dataChannel: new
|
|
1306
|
+
capabilities: Te,
|
|
1307
|
+
audio: new Q(),
|
|
1308
|
+
media: new F(),
|
|
1309
|
+
peer: new ee(),
|
|
1310
|
+
dataChannel: new te()
|
|
1187
1311
|
};
|
|
1188
|
-
function
|
|
1189
|
-
return new
|
|
1190
|
-
...
|
|
1191
|
-
runtime:
|
|
1312
|
+
function Y(i) {
|
|
1313
|
+
return new A({
|
|
1314
|
+
...i,
|
|
1315
|
+
runtime: be
|
|
1192
1316
|
});
|
|
1193
1317
|
}
|
|
1194
|
-
const
|
|
1195
|
-
function
|
|
1196
|
-
return
|
|
1318
|
+
const ke = Y;
|
|
1319
|
+
function xe(i) {
|
|
1320
|
+
return Y(i);
|
|
1197
1321
|
}
|
|
1198
|
-
const
|
|
1322
|
+
const Re = xe;
|
|
1199
1323
|
export {
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1324
|
+
Q as RNAudioAdapter,
|
|
1325
|
+
te as RNDataChannelAdapter,
|
|
1326
|
+
F as RNMediaAdapter,
|
|
1327
|
+
ee as RNPeerAdapter,
|
|
1328
|
+
A as VaniraAI,
|
|
1329
|
+
A as VaniraClient,
|
|
1330
|
+
A as WebRTCClient,
|
|
1331
|
+
ke as createReactNativeAI,
|
|
1332
|
+
Y as createReactNativeClient,
|
|
1333
|
+
Re as createVaniraAI,
|
|
1334
|
+
xe as createVaniraClient,
|
|
1335
|
+
Te as reactNativeCapabilities,
|
|
1336
|
+
be as reactNativeRuntime
|
|
1213
1337
|
};
|