@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.
@@ -1,7 +1,7 @@
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 d = (a, e, t) => G(a, typeof e != "symbol" ? e + "" : e, t);
4
- class z {
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 Y {
12
+ class Q {
13
13
  createRemotePlayer(e) {
14
- return new z();
14
+ return new Z();
15
15
  }
16
16
  }
17
- class q {
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 X {
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 Z {
35
+ class te {
36
36
  bind(e, t) {
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 });
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 (i.data instanceof ArrayBuffer) {
42
+ if (n.data instanceof ArrayBuffer) {
43
43
  try {
44
- const n = new TextDecoder().decode(i.data), r = JSON.parse(n);
45
- (r == null ? void 0 : r.event) === "client_tool_call" && t.onMessage({ text: n });
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(i) {
52
- e.readyState === "open" && e.send(i);
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 Q = "https://api.vanira.io", c = {
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
- }, F = Object.values(c), ee = new Set(F);
90
- function V(a) {
91
- return !!a && ee.has(a);
90
+ }, ie = Object.values(c), ae = new Set(ie);
91
+ function K(i) {
92
+ return !!i && ae.has(i);
92
93
  }
93
- function j(a) {
94
- if (typeof a == "string")
94
+ function J(i) {
95
+ if (typeof i == "string")
95
96
  try {
96
- return JSON.parse(a);
97
+ return JSON.parse(i);
97
98
  } catch {
98
99
  return {};
99
100
  }
100
- return a && typeof a == "object" ? a : {};
101
+ return i && typeof i == "object" ? i : {};
101
102
  }
102
- const N = {
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
- }, D = {
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 te(a, e) {
153
- const t = a.latex_text ?? (e == null ? void 0 : e.latex_text);
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 K(a, e) {
157
- 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);
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 ie(a, e) {
161
- const t = a.fields ?? (e == null ? void 0 : e.fields);
162
- return Array.isArray(t) ? t.length > 0 : typeof t == "string" ? t.split(",").map((i) => i.trim()).filter(Boolean).length > 0 : !1;
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 ne(a, e) {
165
- const t = a == null ? void 0 : a.preset_id;
176
+ function le(i, e) {
177
+ const t = i == null ? void 0 : i.preset_id;
166
178
  if (typeof t == "string") {
167
- if (V(t)) return t;
168
- const r = D[t];
179
+ if (K(t)) return t;
180
+ const r = j[t];
169
181
  if (r) return r;
170
182
  }
171
- const n = j(e).preset_id;
172
- if (typeof n == "string") {
173
- if (V(n)) return n;
174
- const r = D[n];
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 ae(a, e, t) {
179
- const i = j(e);
180
- let n = ne(a, i);
181
- if (n === c.Form && K(i, a) && !ie(i, a))
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 (n) return n;
195
+ if (a) return a;
184
196
  const r = String(t ?? "").trim().toLowerCase();
185
- if (r && N[r])
186
- return N[r];
187
- if (te(i, a))
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 (K(i, a))
203
+ if (G(n, i))
190
204
  return c.TypeText;
191
205
  }
192
- const g = "vanira_latest_call_id", k = "vanira_prospect_id";
193
- function C(a) {
194
- return `vanira_latest_call_id_${a}`;
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 I(a) {
197
- return `vanira_prospect_id_${a}`;
210
+ function b(i) {
211
+ return `vanira_prospect_id_${i}`;
198
212
  }
199
- function W(a) {
200
- return `vanira_call_meta_${a}`;
213
+ function z(i) {
214
+ return `vanira_call_meta_${i}`;
201
215
  }
202
- function w(a, e) {
203
- if (!a) return null;
216
+ function S(i, e) {
217
+ if (!i) return null;
204
218
  try {
205
- return a.getItem(e);
219
+ return i.getItem(e);
206
220
  } catch {
207
221
  return null;
208
222
  }
209
223
  }
210
- function B(a) {
211
- if (typeof window > "u" || !a) return null;
212
- const e = [], t = w(window.localStorage, W(a));
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 i = (h, s, u) => {
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
- }, n = w(window.localStorage, I(a)), r = w(window.sessionStorage, I(a)), o = w(window.localStorage, k);
230
- return i(
231
- w(window.localStorage, C(a)),
232
- n || o,
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
- ), i(
235
- w(window.sessionStorage, C(a)),
248
+ ), n(
249
+ S(window.sessionStorage, T(i)),
236
250
  r || o,
237
251
  1
238
- ), i(w(window.localStorage, g), o, 0), i(w(window.sessionStorage, g), o, 0), e.length ? (e.sort((h, s) => s.updatedAt - h.updatedAt), e[0]) : null;
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 re(a, e, t) {
241
- var n, r, o, h, s, u, p, l, _;
242
- if (typeof window > "u" || !a || !e) return;
243
- const i = {
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
- (n = window.localStorage) == null || n.setItem(W(a), JSON.stringify(i)), (r = window.localStorage) == null || r.setItem(C(a), e), (o = window.sessionStorage) == null || o.setItem(C(a), e), t && ((h = window.localStorage) == null || h.setItem(I(a), t), (s = window.sessionStorage) == null || s.setItem(I(a), t)), (u = window.localStorage) == null || u.setItem(g, e), (p = window.sessionStorage) == null || p.setItem(g, e), t && ((l = window.localStorage) == null || l.setItem(k, t), (_ = window.sessionStorage) == null || _.setItem(k, t));
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 se = /* @__PURE__ */ new Set([
267
+ const ue = /* @__PURE__ */ new Set([
254
268
  "client_tool_call",
255
269
  "clearAudio",
256
270
  "client_tool_cancel"
257
271
  ]);
258
- function oe(a) {
259
- if (!a || typeof a != "object") return !1;
260
- const e = a.event;
261
- return typeof e == "string" && se.has(e);
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 T = 16 * 1024, ce = 256 * 1024;
264
- function E(a, e) {
265
- return (a == null ? void 0 : a.readyState) === "open" && (e == null ? void 0 : e.readyState) === "open";
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 le(a, e) {
281
+ function me(i, e) {
268
282
  return {
269
- control: (a == null ? void 0 : a.readyState) ?? "missing",
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 de(a, e, t = 8e3) {
274
- if (E(a, e))
287
+ async function fe(i, e, t = 8e3) {
288
+ if (E(i, e))
275
289
  return !0;
276
- const i = Date.now() + t;
277
- for (; Date.now() < i; ) {
278
- if (E(a, 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((n) => setTimeout(n, 50));
294
+ await new Promise((a) => setTimeout(a, 50));
281
295
  }
282
- return E(a, e);
296
+ return E(i, e);
283
297
  }
284
- async function $(a) {
285
- for (; a.bufferedAmount > ce; )
298
+ async function H(i) {
299
+ for (; i.bufferedAmount > _e; )
286
300
  await new Promise((e) => setTimeout(e, 10));
287
301
  }
288
- async function he(a) {
302
+ async function ye(i) {
289
303
  const {
290
304
  bytes: e,
291
305
  filename: t,
292
- contentType: i,
293
- reason: n,
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
- } = a, l = e.byteLength, _ = l === 0 ? 0 : Math.ceil(l / T);
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: n,
319
+ reason: a,
306
320
  message: r,
307
321
  filename: t,
308
- content_type: i,
309
- size: l,
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 < l; f += T) {
316
- await $(h);
317
- const S = Math.min(f + T, l);
318
- h.send(m.subarray(f, S));
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 $(h), s("client_media_upload_complete", {
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: n,
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: i };
343
+ }), { media_id: u, url: "", content_type: n };
330
344
  }
331
- async function ue(a) {
332
- return typeof a.arrayBuffer == "function" ? a.arrayBuffer() : new Response(a).arrayBuffer();
345
+ async function Se(i) {
346
+ return typeof i.arrayBuffer == "function" ? i.arrayBuffer() : new Response(i).arrayBuffer();
333
347
  }
334
- function pe(a) {
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 v() {
409
+ function C() {
338
410
  return typeof window > "u" ? "/" : `${window.location.pathname}${window.location.search}${window.location.hash}` || "/";
339
411
  }
340
- class _e {
412
+ class Ie {
341
413
  constructor(e) {
342
- d(this, "active", !1);
343
- d(this, "initialSent", !1);
344
- d(this, "lastRoute", "");
345
- d(this, "sendContext");
346
- d(this, "isReady");
347
- d(this, "cleanupFns", []);
348
- d(this, "initialRetryTimer", null);
349
- d(this, "routePollTimer", null);
350
- d(this, "originalPushState", null);
351
- d(this, "originalReplaceState", null);
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 = v(), this.attachListeners(), this.scheduleInitialContextSend());
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 = v();
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"), i = () => e("hashchange"), n = (r) => {
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", i), window.addEventListener("vanira:navigate", n), this.cleanupFns.push(
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", i),
402
- () => window.removeEventListener("vanira:navigate", n)
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 = v();
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 i = this.lastRoute;
416
- if (i === e) return;
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() || pe() || this.sendRouteContext("route_changed", i, t, "user");
493
+ !this.isReady() || Ce() || this.sendRouteContext("route_changed", n, t, "user");
422
494
  }
423
- sendRouteContext(e, t, i, n = "user") {
424
- const r = v();
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: n,
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}.`, i && (o.navigation_source = i));
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
- d(this, "serverUrl");
443
- d(this, "agentId");
444
- d(this, "callId");
445
- d(this, "prospectId");
446
- d(this, "apiKey");
447
- d(this, "backendUrl");
448
- d(this, "token");
449
- d(this, "onConnected");
450
- d(this, "onDisconnected");
451
- d(this, "onError");
452
- d(this, "onTranscription");
453
- d(this, "onLocalStream");
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
- d(this, "onRemoteTrack");
456
- d(this, "onClientToolCall");
457
- d(this, "onSessionStarted");
458
- d(this, "sessionStartedEmitted", !1);
459
- d(this, "pc", null);
460
- d(this, "dataChannel", null);
461
- d(this, "mediaBytesChannel", null);
462
- d(this, "audioElement", null);
463
- d(this, "localStream", null);
464
- d(this, "micMuted", !1);
465
- d(this, "connected", !1);
466
- d(this, "icePollInterval", null);
467
- d(this, "appliedRemoteCandidates", /* @__PURE__ */ new Set());
468
- d(this, "iceServers");
469
- d(this, "callSessionLoaded", !1);
470
- d(this, "connectGeneration", 0);
471
- d(this, "runtime");
472
- d(this, "sessionBehavior");
473
- d(this, "routeTracker", null);
474
- d(this, "_status", "idle");
475
- d(this, "listeners", /* @__PURE__ */ new Map());
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
- d(this, "liveVision");
478
- d(this, "liveVisionAutoStarted", !1);
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), i = !!(e.serverUrl && e.callId), n = y.normalizeIceServers(
557
+ const t = !!(e.apiKey || e.token), n = !!(e.serverUrl && e.callId), a = y.normalizeIceServers(
481
558
  e.iceServers
482
559
  );
483
- if (!t && !i)
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 || Q).replace(/\/$/, ""), n.length && (this.iceServers = n), i && (this.callSessionLoaded = !0);
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 = B(this.agentId);
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 = B(this.agentId);
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 p;
518
- (p = e.onTranscription) == null || p.call(e, s, u), this.emit("transcription", { text: s, isFinal: u });
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 l;
525
- (l = e.onClientToolCall) == null || l.call(e, s);
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 _e({
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 i = this.getIceServers();
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: i,
653
+ iceServers: n,
577
654
  iceTransportPolicy: "all"
578
655
  });
579
- let n;
656
+ let a;
580
657
  try {
581
- n = await navigator.mediaDevices.getUserMedia({
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 (l) {
591
- if (l.name === "NotAllowedError" || l.name === "PermissionDeniedError" || (t = l.message) != null && t.includes("Permission denied")) {
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 S = new Error(f);
596
- throw S.name = l.name, S;
672
+ const w = new Error(f);
673
+ throw w.name = d.name, w;
597
674
  }
598
- throw l;
675
+ throw d;
599
676
  }
600
677
  if (this.isConnectCancelled(e)) {
601
- n.getTracks().forEach((l) => l.stop());
678
+ a.getTracks().forEach((d) => d.stop());
602
679
  return;
603
680
  }
604
- if (this.localStream = n, !this.pc || this.isConnectCancelled(e)) {
605
- n.getTracks().forEach((l) => l.stop());
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(n), n.getTracks().forEach((l) => {
685
+ if (this.onLocalStream(a), a.getTracks().forEach((d) => {
609
686
  var _;
610
- (_ = this.pc) == null || _.addTrack(l, n);
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 l;
615
- (l = this.routeTracker) == null || l.onChannelReady();
616
- }, this.dataChannel.onmessage = (l) => {
617
- if (typeof l.data == "string")
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(l.data));
696
+ this.handleControlEvent(JSON.parse(d.data));
620
697
  } catch {
621
698
  }
622
- else if (l.data instanceof ArrayBuffer)
699
+ else if (d.data instanceof ArrayBuffer)
623
700
  try {
624
- const _ = new TextDecoder().decode(l.data);
701
+ const _ = new TextDecoder().decode(d.data);
625
702
  try {
626
703
  const m = JSON.parse(_);
627
- oe(m) && this.handleControlEvent(m);
704
+ pe(m) && this.handleControlEvent(m);
628
705
  } catch {
629
706
  }
630
707
  } catch {
631
708
  }
632
- else l.data instanceof Blob && l.data.text().then((_) => {
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 = (l) => {
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 = (l) => {
641
- }, this.pc.ontrack = (l) => {
642
- const _ = l.track, m = l.streams[0];
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, S, b, x, A, P, U, L, M, O;
650
- const l = ((m = this.pc) == null ? void 0 : m.connectionState) === "connected" || ((f = this.pc) == null ? void 0 : f.iceConnectionState) === "connected" || ((S = this.pc) == null ? void 0 : S.iceConnectionState) === "completed", _ = ((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";
651
- ((M = this.pc) == null ? void 0 : M.connectionState) === "connected" && this.stopRemoteIcePolling(), l && !this.connected ? (this.connected = !0, (O = this.routeTracker) == null || O.start(), this.onConnected()) : _ && this.connected && (this.connected = !1, this.liveVisionAutoStarted = !1, this.onDisconnected());
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 = (l) => {
656
- l.candidate && fetch(o, {
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 l = await u.json();
677
- throw new Error(l.error || `HTTP ${u.status}`);
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 (i) {
754
+ } catch (n) {
683
755
  if (this.isConnectCancelled(e)) return;
684
- throw this.disconnect(), this.onError(i.message || i), i;
756
+ throw this.disconnect(), this.onError(n.message || n), n;
685
757
  }
686
758
  }
687
759
  }
688
760
  createCallCacheKey(e, t) {
689
- const i = this.apiKey ? `key:${this.apiKey.slice(0, 16)}` : `token:${(this.token || "").slice(-16)}`;
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
- i
768
+ n
697
769
  ].join("|");
698
770
  }
699
- async postCreateCall(e, t, i) {
771
+ async postCreateCall(e, t, n) {
700
772
  var h, s, u;
701
- const n = await fetch(`${this.backendUrl}/calls/create`, {
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
- ...i ? { call_id: i } : {}
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 (!n.ok) {
714
- const p = await n.json().catch(() => ({}));
715
- throw new Error(`[VaniraClient] createCall failed (${n.status}): ${((u = p == null ? void 0 : p.detail) == null ? void 0 : u.message) || (p == null ? void 0 : p.message) || n.statusText}`);
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 n.json();
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, re(this.agentId, this.callId || "", this.prospectId), this.onSessionStarted && this.prospectId && this.callId && !this.sessionStartedEmitted)
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, i = this.sessionBehavior === "continue" ? "continue" : "new", n = this.createCallCacheKey(i, t);
748
- let r = y.inflightCreates.get(n);
749
- r || (r = this.postCreateCall(e, i, t), y.inflightCreates.set(n, r), r.finally(() => {
750
- y.inflightCreates.get(n) === r && y.inflightCreates.delete(n);
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 i of e) {
764
- const n = i == null ? void 0 : i.urls, r = Array.isArray(n) ? n.filter(Boolean) : typeof n == "string" && n.trim() ? [n.trim()] : [];
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 = i.username, s = i.credential;
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
- startRemoteIcePolling(e) {
793
- this.stopRemoteIcePolling(), this.icePollInterval = setInterval(async () => {
794
- if (!this.pc) {
795
- this.stopRemoteIcePolling();
796
- return;
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
- if (this.pc.connectionState === "connected") {
799
- this.stopRemoteIcePolling();
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
- try {
803
- const t = await fetch(e);
804
- if (!t.ok) return;
805
- const { candidates: i } = await t.json();
806
- for (const n of i || []) {
807
- const r = JSON.stringify(n);
808
- if (!this.appliedRemoteCandidates.has(r)) {
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
- }, 150);
931
+ await new Promise((r) => setTimeout(r, 150));
932
+ }
819
933
  }
820
934
  stopRemoteIcePolling() {
821
- this.icePollInterval !== null && (clearInterval(this.icePollInterval), this.icePollInterval = null);
935
+ this.icePollStop = !0;
822
936
  }
823
937
  /**
824
938
  * Send control event via DataChannel
825
939
  */
826
940
  sendEvent(e, t = {}) {
827
- var i;
828
- if (((i = this.dataChannel) == null ? void 0 : i.readyState) === "open") {
829
- const n = { event: e, ...t };
830
- this.dataChannel.send(JSON.stringify(n));
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 = {}, i = 1e4) {
948
+ async sendEventWhenReady(e, t = {}, n = 1e4) {
835
949
  var r;
836
- const n = Date.now() + i;
837
- for (; Date.now() < n; ) {
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
- this.onTranscription(e.text, e.isFinal);
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 n = (e.data || e).tool_call_id || e.tool_call_id;
888
- this.dispatchBoardAbort("Tool cancelled by server", n);
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 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 || "";
893
- n && ((t = this.dataChannel) == null ? void 0 : t.readyState) === "open" && this.dataChannel.send(JSON.stringify({
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: n }
1019
+ data: { tool_call_id: a }
896
1020
  }));
897
- const r = (i == null ? void 0 : i.arguments) || (i == null ? void 0 : i.args) || {}, o = (i == null ? void 0 : i.client_fields) || {}, h = (i == null ? void 0 : i.name) || (i == null ? void 0 : i.tool_name) || "", s = ae(o, r, h);
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
- n && this.sendToolResult(n, {
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: i, client: this }
908
- })), this.onClientToolCall(i);
1031
+ detail: { toolCall: n, client: this }
1032
+ })), this.onClientToolCall(n);
909
1033
  break;
910
1034
  }
911
- this.onClientToolCall(i);
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, i;
936
- this.micMuted = e, (t = this.localStream) == null || t.getAudioTracks().forEach((n) => {
937
- n.enabled = !e;
938
- }), (i = this.pc) == null || i.getSenders().forEach((n) => {
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 = n.track) == null ? void 0 : r.kind) === "audio" && (n.track.enabled = !e);
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", i = "") {
1045
- return await de(this.dataChannel, this.mediaBytesChannel) ? this._uploadMediaViaDataChannel(e, t, i) : (le(this.dataChannel, this.mediaBytesChannel), this._uploadMediaViaHTTP(e, t, i));
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", i) {
1055
- const n = i && !(e instanceof File) ? new File([e], i, { type: e.type || "image/jpeg" }) : e, { media_id: r, url: o, contentType: h } = await this._postMediaUpload(n, t, !0);
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, i, n, r) {
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 : n === "frame" ? "frame.jpg" : "upload.bin"), h = e.type || (n === "frame" ? "image/jpeg" : "application/octet-stream"), s = await ue(e);
1065
- return he({
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: i,
1194
+ message: n,
1071
1195
  callId: this.callId,
1072
1196
  mediaBytesChannel: this.mediaBytesChannel,
1073
1197
  sendControlEvent: (u, p) => this.sendEvent(u, p),
1074
- uploadKind: n
1198
+ uploadKind: a
1075
1199
  });
1076
1200
  }
1077
- async _uploadMediaViaDataChannel(e, t, i) {
1078
- const n = await this._uploadBytesViaDataChannel(e, t, i, "media");
1079
- return { media_id: n.media_id, url: n.url };
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", i = "") {
1083
- const { media_id: n, url: r, contentType: o } = await this._postMediaUpload(e, t, !0);
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: n,
1209
+ media_id: a,
1086
1210
  media_url: r,
1087
1211
  content_type: o,
1088
1212
  reason: t,
1089
- message: i
1090
- }), { media_id: n, url: r };
1213
+ message: n
1214
+ }), { media_id: a, url: r };
1091
1215
  }
1092
- async _postMediaUpload(e, t, i = !1) {
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 n = this.getWorkerOrigin();
1098
- if (!n)
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 = `${n}/media/upload`, o = new FormData();
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, l = s.content_type || e.type;
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 i ? { media_id: u, url: p, contentType: l } : { media_id: u, url: p, contentType: l };
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 i;
1133
- return (i = this.listeners.get(e)) == null || i.delete(t), this;
1256
+ var n;
1257
+ return (n = this.listeners.get(e)) == null || n.delete(t), this;
1134
1258
  }
1135
1259
  emit(e, t) {
1136
- var i;
1137
- (i = this.listeners.get(e)) == null || i.forEach((n) => n(t));
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
- d(y, "inflightCreates", /* @__PURE__ */ new Map());
1168
- let R = y;
1169
- const me = {
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
- }, fe = {
1301
+ }, be = {
1178
1302
  name: "react-native",
1179
1303
  callType: "web",
1180
1304
  runtimeName: "react-native",
1181
1305
  callIdPrefix: "rn_",
1182
- capabilities: me,
1183
- audio: new Y(),
1184
- media: new q(),
1185
- peer: new X(),
1186
- dataChannel: new Z()
1306
+ capabilities: Te,
1307
+ audio: new Q(),
1308
+ media: new F(),
1309
+ peer: new ee(),
1310
+ dataChannel: new te()
1187
1311
  };
1188
- function J(a) {
1189
- return new R({
1190
- ...a,
1191
- runtime: fe
1312
+ function Y(i) {
1313
+ return new A({
1314
+ ...i,
1315
+ runtime: be
1192
1316
  });
1193
1317
  }
1194
- const Se = J;
1195
- function ye(a) {
1196
- return J(a);
1318
+ const ke = Y;
1319
+ function xe(i) {
1320
+ return Y(i);
1197
1321
  }
1198
- const ve = ye;
1322
+ const Re = xe;
1199
1323
  export {
1200
- Y as RNAudioAdapter,
1201
- Z as RNDataChannelAdapter,
1202
- q as RNMediaAdapter,
1203
- X as RNPeerAdapter,
1204
- R as VaniraAI,
1205
- R as VaniraClient,
1206
- R as WebRTCClient,
1207
- Se as createReactNativeAI,
1208
- J as createReactNativeClient,
1209
- ve as createVaniraAI,
1210
- ye as createVaniraClient,
1211
- me as reactNativeCapabilities,
1212
- fe as reactNativeRuntime
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
  };