@vanira/sdk 0.0.85 → 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 +386 -88
- package/dist/headless/index.js +16448 -14351
- package/dist/index.d.ts +67 -1
- package/dist/platforms/browser.cjs +24 -8
- package/dist/platforms/browser.js +2226 -2084
- package/dist/platforms/react-native.cjs +17 -1
- package/dist/platforms/react-native.js +585 -443
- package/dist/vanira-sdk.es.js +11270 -9037
- package/dist/vanira-sdk.js +403 -105
- package/dist/vanira-sdk.umd.js +414 -105
- package/package.json +4 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var l = (
|
|
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
|
-
(
|
|
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", u = {
|
|
|
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",
|
|
@@ -82,244 +83,333 @@ const Q = "https://api.vanira.io", u = {
|
|
|
82
83
|
PointAt: "vanira_point_at",
|
|
83
84
|
DrawOnScreen: "vanira_draw_on_screen",
|
|
84
85
|
ClearScreenDraw: "vanira_clear_screen_draw",
|
|
85
|
-
HighlightOnScreen: "vanira_highlight_on_screen"
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
HighlightOnScreen: "vanira_highlight_on_screen",
|
|
87
|
+
KycDocumentCapture: "vanira_kyc_document_capture",
|
|
88
|
+
KycSelfieCapture: "vanira_kyc_selfie_capture",
|
|
89
|
+
KycSignatureCapture: "vanira_kyc_signature_capture"
|
|
90
|
+
}, ie = Object.values(c), ae = new Set(ie);
|
|
91
|
+
function K(i) {
|
|
92
|
+
return !!i && ae.has(i);
|
|
89
93
|
}
|
|
90
|
-
function
|
|
91
|
-
if (typeof
|
|
94
|
+
function J(i) {
|
|
95
|
+
if (typeof i == "string")
|
|
92
96
|
try {
|
|
93
|
-
return JSON.parse(
|
|
97
|
+
return JSON.parse(i);
|
|
94
98
|
} catch {
|
|
95
99
|
return {};
|
|
96
100
|
}
|
|
97
|
-
return
|
|
101
|
+
return i && typeof i == "object" ? i : {};
|
|
98
102
|
}
|
|
99
|
-
const
|
|
100
|
-
type_on_whiteboard:
|
|
101
|
-
write_on_whiteboard:
|
|
102
|
-
write_on_white_board:
|
|
103
|
-
dom_typing_simulation:
|
|
104
|
-
write_latex_text:
|
|
105
|
-
write_latex_on_board:
|
|
106
|
-
latex_on_whiteboard:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
103
|
+
const $ = {
|
|
104
|
+
type_on_whiteboard: c.TypeText,
|
|
105
|
+
write_on_whiteboard: c.TypeText,
|
|
106
|
+
write_on_white_board: c.TypeText,
|
|
107
|
+
dom_typing_simulation: c.TypeText,
|
|
108
|
+
write_latex_text: c.WriteLatexText,
|
|
109
|
+
write_latex_on_board: c.WriteLatexText,
|
|
110
|
+
latex_on_whiteboard: c.WriteLatexText,
|
|
111
|
+
show_geogebra: c.GeoGebra,
|
|
112
|
+
geogebra_diagram: c.GeoGebra,
|
|
113
|
+
geogebra: c.GeoGebra,
|
|
114
|
+
erase_text: c.EraseText,
|
|
115
|
+
dom_erase: c.EraseText,
|
|
116
|
+
open_live_camera: c.LiveVision,
|
|
117
|
+
live_vision: c.LiveVision,
|
|
118
|
+
close_live_camera: c.CloseLiveCamera,
|
|
119
|
+
stop_live_camera: c.CloseLiveCamera,
|
|
120
|
+
open_live_screen: c.LiveScreen,
|
|
121
|
+
close_live_screen: c.CloseLiveScreen,
|
|
122
|
+
screen_vision: c.ScreenVision,
|
|
123
|
+
capture_screen_vision: c.ScreenVision,
|
|
124
|
+
capture_screen: c.ScreenVision,
|
|
125
|
+
tab_screenshot: c.ScreenVision,
|
|
126
|
+
capture_tab: c.ScreenVision,
|
|
127
|
+
capture_tab_screenshot: c.ScreenVision,
|
|
128
|
+
screenshot_tab: c.ScreenVision,
|
|
129
|
+
point_at: c.PointAt,
|
|
130
|
+
point_at_screen: c.PointAt,
|
|
131
|
+
draw_on_screen: c.DrawOnScreen,
|
|
132
|
+
screen_draw: c.DrawOnScreen,
|
|
133
|
+
clear_screen_draw: c.ClearScreenDraw,
|
|
134
|
+
clear_screen_annotations: c.ClearScreenDraw,
|
|
135
|
+
highlight_on_screen: c.HighlightOnScreen,
|
|
136
|
+
highlight_element_on_screen: c.HighlightOnScreen,
|
|
137
|
+
highlight_screen_element: c.HighlightOnScreen,
|
|
138
|
+
kyc_document_capture: c.KycDocumentCapture,
|
|
139
|
+
capture_id_document: c.KycDocumentCapture,
|
|
140
|
+
document_capture: c.KycDocumentCapture,
|
|
141
|
+
capture_kyc_document: c.KycDocumentCapture,
|
|
142
|
+
kyc_selfie_capture: c.KycSelfieCapture,
|
|
143
|
+
capture_selfie: c.KycSelfieCapture,
|
|
144
|
+
selfie_capture: c.KycSelfieCapture,
|
|
145
|
+
capture_kyc_selfie: c.KycSelfieCapture,
|
|
146
|
+
kyc_signature_capture: c.KycSignatureCapture,
|
|
147
|
+
capture_kyc_signature: c.KycSignatureCapture,
|
|
148
|
+
signature_capture: c.KycSignatureCapture
|
|
149
|
+
}, j = {
|
|
150
|
+
vanira_tab_screenshot: c.ScreenVision,
|
|
151
|
+
vanira_document_capture: c.KycDocumentCapture,
|
|
152
|
+
vanira_selfie_capture: c.KycSelfieCapture,
|
|
153
|
+
vanira_signature_capture: c.KycSignatureCapture,
|
|
154
|
+
vanira_kyc_signature: c.KycSignatureCapture
|
|
133
155
|
};
|
|
134
|
-
function
|
|
135
|
-
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);
|
|
136
162
|
return typeof t == "string" && t.trim().length > 0;
|
|
137
163
|
}
|
|
138
|
-
function
|
|
139
|
-
const t =
|
|
164
|
+
function oe(i, e) {
|
|
165
|
+
const t = i.latex_text ?? (e == null ? void 0 : e.latex_text);
|
|
140
166
|
return typeof t == "string" && t.trim().length > 0;
|
|
141
167
|
}
|
|
142
|
-
function
|
|
143
|
-
const t =
|
|
144
|
-
return
|
|
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);
|
|
170
|
+
return typeof t == "string" && t.trim().length > 0;
|
|
171
|
+
}
|
|
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;
|
|
145
175
|
}
|
|
146
|
-
function
|
|
147
|
-
const t =
|
|
176
|
+
function le(i, e) {
|
|
177
|
+
const t = i == null ? void 0 : i.preset_id;
|
|
148
178
|
if (typeof t == "string") {
|
|
149
|
-
if (
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
179
|
+
if (K(t)) return t;
|
|
180
|
+
const r = j[t];
|
|
181
|
+
if (r) return r;
|
|
152
182
|
}
|
|
153
|
-
const
|
|
154
|
-
if (typeof
|
|
155
|
-
if (
|
|
156
|
-
const
|
|
157
|
-
if (
|
|
183
|
+
const a = J(e).preset_id;
|
|
184
|
+
if (typeof a == "string") {
|
|
185
|
+
if (K(a)) return a;
|
|
186
|
+
const r = j[a];
|
|
187
|
+
if (r) return r;
|
|
158
188
|
}
|
|
159
189
|
}
|
|
160
|
-
function
|
|
161
|
-
const
|
|
162
|
-
let
|
|
163
|
-
if (
|
|
164
|
-
return
|
|
165
|
-
if (
|
|
166
|
-
const
|
|
167
|
-
if (
|
|
168
|
-
return
|
|
169
|
-
if (
|
|
170
|
-
return
|
|
171
|
-
if (
|
|
172
|
-
return
|
|
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))
|
|
194
|
+
return c.TypeText;
|
|
195
|
+
if (a) return a;
|
|
196
|
+
const r = String(t ?? "").trim().toLowerCase();
|
|
197
|
+
if (r && $[r])
|
|
198
|
+
return $[r];
|
|
199
|
+
if (re(n, i) || se(n, i))
|
|
200
|
+
return c.GeoGebra;
|
|
201
|
+
if (oe(n, i))
|
|
202
|
+
return c.WriteLatexText;
|
|
203
|
+
if (G(n, i))
|
|
204
|
+
return c.TypeText;
|
|
173
205
|
}
|
|
174
|
-
const
|
|
175
|
-
function
|
|
176
|
-
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}`;
|
|
177
209
|
}
|
|
178
|
-
function
|
|
179
|
-
return `vanira_prospect_id_${
|
|
210
|
+
function b(i) {
|
|
211
|
+
return `vanira_prospect_id_${i}`;
|
|
180
212
|
}
|
|
181
|
-
function
|
|
182
|
-
return `vanira_call_meta_${
|
|
213
|
+
function z(i) {
|
|
214
|
+
return `vanira_call_meta_${i}`;
|
|
183
215
|
}
|
|
184
|
-
function S(
|
|
185
|
-
if (!
|
|
216
|
+
function S(i, e) {
|
|
217
|
+
if (!i) return null;
|
|
186
218
|
try {
|
|
187
|
-
return
|
|
219
|
+
return i.getItem(e);
|
|
188
220
|
} catch {
|
|
189
221
|
return null;
|
|
190
222
|
}
|
|
191
223
|
}
|
|
192
|
-
function
|
|
193
|
-
if (typeof window > "u" || !
|
|
194
|
-
const e = [], t = S(window.localStorage,
|
|
224
|
+
function W(i) {
|
|
225
|
+
if (typeof window > "u" || !i) return null;
|
|
226
|
+
const e = [], t = S(window.localStorage, z(i));
|
|
195
227
|
if (t)
|
|
196
228
|
try {
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
callId:
|
|
200
|
-
prospectId:
|
|
201
|
-
updatedAt:
|
|
229
|
+
const h = JSON.parse(t);
|
|
230
|
+
h != null && h.callId && e.push({
|
|
231
|
+
callId: h.callId,
|
|
232
|
+
prospectId: h.prospectId,
|
|
233
|
+
updatedAt: h.updatedAt || 0
|
|
202
234
|
});
|
|
203
235
|
} catch {
|
|
204
236
|
}
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
callId:
|
|
208
|
-
prospectId:
|
|
209
|
-
updatedAt:
|
|
237
|
+
const n = (h, s, u) => {
|
|
238
|
+
h && e.push({
|
|
239
|
+
callId: h,
|
|
240
|
+
prospectId: s || void 0,
|
|
241
|
+
updatedAt: u
|
|
210
242
|
});
|
|
211
|
-
},
|
|
212
|
-
return
|
|
213
|
-
S(window.localStorage,
|
|
214
|
-
|
|
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,
|
|
215
247
|
2
|
|
216
|
-
),
|
|
217
|
-
S(window.sessionStorage,
|
|
218
|
-
|
|
248
|
+
), n(
|
|
249
|
+
S(window.sessionStorage, T(i)),
|
|
250
|
+
r || o,
|
|
219
251
|
1
|
|
220
|
-
),
|
|
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;
|
|
221
253
|
}
|
|
222
|
-
function
|
|
223
|
-
var
|
|
224
|
-
if (typeof window > "u" || !
|
|
225
|
-
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 = {
|
|
226
258
|
callId: e,
|
|
227
259
|
prospectId: t,
|
|
228
260
|
updatedAt: Date.now()
|
|
229
261
|
};
|
|
230
262
|
try {
|
|
231
|
-
(
|
|
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));
|
|
232
264
|
} catch {
|
|
233
265
|
}
|
|
234
266
|
}
|
|
235
|
-
const
|
|
267
|
+
const ue = /* @__PURE__ */ new Set([
|
|
236
268
|
"client_tool_call",
|
|
237
269
|
"clearAudio",
|
|
238
270
|
"client_tool_cancel"
|
|
239
271
|
]);
|
|
240
|
-
function
|
|
241
|
-
if (!
|
|
242
|
-
const e =
|
|
243
|
-
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);
|
|
244
276
|
}
|
|
245
|
-
const
|
|
246
|
-
function E(
|
|
247
|
-
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";
|
|
248
280
|
}
|
|
249
|
-
function
|
|
281
|
+
function me(i, e) {
|
|
250
282
|
return {
|
|
251
|
-
control: (
|
|
283
|
+
control: (i == null ? void 0 : i.readyState) ?? "missing",
|
|
252
284
|
mediaBytes: (e == null ? void 0 : e.readyState) ?? "missing"
|
|
253
285
|
};
|
|
254
286
|
}
|
|
255
|
-
async function
|
|
256
|
-
if (E(
|
|
287
|
+
async function fe(i, e, t = 8e3) {
|
|
288
|
+
if (E(i, e))
|
|
257
289
|
return !0;
|
|
258
|
-
const
|
|
259
|
-
for (; Date.now() <
|
|
260
|
-
if (E(
|
|
290
|
+
const n = Date.now() + t;
|
|
291
|
+
for (; Date.now() < n; ) {
|
|
292
|
+
if (E(i, e))
|
|
261
293
|
return !0;
|
|
262
|
-
await new Promise((
|
|
294
|
+
await new Promise((a) => setTimeout(a, 50));
|
|
263
295
|
}
|
|
264
|
-
return E(
|
|
296
|
+
return E(i, e);
|
|
265
297
|
}
|
|
266
|
-
async function
|
|
267
|
-
for (;
|
|
298
|
+
async function H(i) {
|
|
299
|
+
for (; i.bufferedAmount > _e; )
|
|
268
300
|
await new Promise((e) => setTimeout(e, 10));
|
|
269
301
|
}
|
|
270
|
-
async function
|
|
302
|
+
async function ye(i) {
|
|
271
303
|
const {
|
|
272
304
|
bytes: e,
|
|
273
305
|
filename: t,
|
|
274
|
-
contentType:
|
|
275
|
-
reason:
|
|
276
|
-
message:
|
|
306
|
+
contentType: n,
|
|
307
|
+
reason: a,
|
|
308
|
+
message: r,
|
|
277
309
|
callId: o,
|
|
278
|
-
mediaBytesChannel:
|
|
279
|
-
sendControlEvent:
|
|
280
|
-
uploadId:
|
|
310
|
+
mediaBytesChannel: h,
|
|
311
|
+
sendControlEvent: s,
|
|
312
|
+
uploadId: u = crypto.randomUUID(),
|
|
281
313
|
uploadKind: p = "media"
|
|
282
|
-
} =
|
|
283
|
-
|
|
314
|
+
} = i, d = e.byteLength, _ = d === 0 ? 0 : Math.ceil(d / x);
|
|
315
|
+
s("client_media_upload_start", {
|
|
284
316
|
data: {
|
|
285
|
-
upload_id:
|
|
317
|
+
upload_id: u,
|
|
286
318
|
call_id: o,
|
|
287
|
-
reason:
|
|
288
|
-
message:
|
|
319
|
+
reason: a,
|
|
320
|
+
message: r,
|
|
289
321
|
filename: t,
|
|
290
|
-
content_type:
|
|
291
|
-
size:
|
|
322
|
+
content_type: n,
|
|
323
|
+
size: d,
|
|
292
324
|
chunk_count: _,
|
|
293
325
|
upload_kind: p
|
|
294
326
|
}
|
|
295
327
|
});
|
|
296
328
|
const m = new Uint8Array(e);
|
|
297
|
-
for (let f = 0; f <
|
|
298
|
-
await
|
|
299
|
-
const
|
|
300
|
-
|
|
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));
|
|
301
333
|
}
|
|
302
|
-
return await
|
|
334
|
+
return await H(h), s("client_media_upload_complete", {
|
|
303
335
|
data: {
|
|
304
|
-
upload_id:
|
|
336
|
+
upload_id: u,
|
|
305
337
|
call_id: o,
|
|
306
|
-
reason:
|
|
307
|
-
message:
|
|
338
|
+
reason: a,
|
|
339
|
+
message: r,
|
|
308
340
|
chunk_count: _,
|
|
309
341
|
upload_kind: p
|
|
310
342
|
}
|
|
311
|
-
}), { media_id:
|
|
343
|
+
}), { media_id: u, url: "", content_type: n };
|
|
344
|
+
}
|
|
345
|
+
async function Se(i) {
|
|
346
|
+
return typeof i.arrayBuffer == "function" ? i.arrayBuffer() : new Response(i).arrayBuffer();
|
|
312
347
|
}
|
|
313
|
-
|
|
314
|
-
|
|
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));
|
|
315
354
|
}
|
|
316
|
-
function
|
|
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) {
|
|
317
407
|
return null;
|
|
318
408
|
}
|
|
319
|
-
function
|
|
409
|
+
function C() {
|
|
320
410
|
return typeof window > "u" ? "/" : `${window.location.pathname}${window.location.search}${window.location.hash}` || "/";
|
|
321
411
|
}
|
|
322
|
-
class
|
|
412
|
+
class Ie {
|
|
323
413
|
constructor(e) {
|
|
324
414
|
l(this, "active", !1);
|
|
325
415
|
l(this, "initialSent", !1);
|
|
@@ -334,7 +424,7 @@ class _e {
|
|
|
334
424
|
this.sendContext = e.sendContext, this.isReady = e.isReady ?? (() => !0);
|
|
335
425
|
}
|
|
336
426
|
start() {
|
|
337
|
-
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());
|
|
338
428
|
}
|
|
339
429
|
stop() {
|
|
340
430
|
if (!(!this.active && this.cleanupFns.length === 0)) {
|
|
@@ -364,62 +454,62 @@ class _e {
|
|
|
364
454
|
}
|
|
365
455
|
}
|
|
366
456
|
attachListeners() {
|
|
367
|
-
const e = (
|
|
368
|
-
const
|
|
369
|
-
const
|
|
370
|
-
|
|
457
|
+
const e = (r, o = 0) => {
|
|
458
|
+
const h = () => {
|
|
459
|
+
const s = C();
|
|
460
|
+
s !== this.lastRoute && this.handleRouteChange(s, r);
|
|
371
461
|
};
|
|
372
|
-
o > 0 ? window.setTimeout(
|
|
373
|
-
}, t = () => e("popstate"),
|
|
374
|
-
const o =
|
|
462
|
+
o > 0 ? window.setTimeout(h, o) : queueMicrotask(h);
|
|
463
|
+
}, t = () => e("popstate"), n = () => e("hashchange"), a = (r) => {
|
|
464
|
+
const o = r.detail;
|
|
375
465
|
if ((o == null ? void 0 : o.initiated_by) === "agent") {
|
|
376
466
|
e("vanira_navigate_agent", 120);
|
|
377
467
|
return;
|
|
378
468
|
}
|
|
379
469
|
e("vanira_navigate", 120);
|
|
380
470
|
};
|
|
381
|
-
window.addEventListener("popstate", t), window.addEventListener("hashchange",
|
|
471
|
+
window.addEventListener("popstate", t), window.addEventListener("hashchange", n), window.addEventListener("vanira:navigate", a), this.cleanupFns.push(
|
|
382
472
|
() => window.removeEventListener("popstate", t),
|
|
383
|
-
() => window.removeEventListener("hashchange",
|
|
384
|
-
() => window.removeEventListener("vanira:navigate",
|
|
385
|
-
), this.originalPushState = history.pushState.bind(history), this.originalReplaceState = history.replaceState.bind(history), history.pushState = (...
|
|
386
|
-
this.originalPushState(...
|
|
387
|
-
}, history.replaceState = (...
|
|
388
|
-
this.originalReplaceState(...
|
|
473
|
+
() => window.removeEventListener("hashchange", n),
|
|
474
|
+
() => window.removeEventListener("vanira:navigate", a)
|
|
475
|
+
), this.originalPushState = history.pushState.bind(history), this.originalReplaceState = history.replaceState.bind(history), history.pushState = (...r) => {
|
|
476
|
+
this.originalPushState(...r), e("pushState");
|
|
477
|
+
}, history.replaceState = (...r) => {
|
|
478
|
+
this.originalReplaceState(...r), e("replaceState");
|
|
389
479
|
}, this.routePollTimer = window.setInterval(() => {
|
|
390
480
|
if (!this.active) return;
|
|
391
|
-
const
|
|
392
|
-
|
|
481
|
+
const r = C();
|
|
482
|
+
r !== this.lastRoute && this.handleRouteChange(r, "location_poll");
|
|
393
483
|
}, 1e3);
|
|
394
484
|
}
|
|
395
485
|
handleRouteChange(e, t) {
|
|
396
486
|
if (!this.active) return;
|
|
397
|
-
const
|
|
398
|
-
if (
|
|
487
|
+
const n = this.lastRoute;
|
|
488
|
+
if (n === e) return;
|
|
399
489
|
if (this.lastRoute = e, !this.initialSent) {
|
|
400
490
|
this.scheduleInitialContextSend();
|
|
401
491
|
return;
|
|
402
492
|
}
|
|
403
|
-
!this.isReady() ||
|
|
493
|
+
!this.isReady() || Ce() || this.sendRouteContext("route_changed", n, t, "user");
|
|
404
494
|
}
|
|
405
|
-
sendRouteContext(e, t,
|
|
406
|
-
const
|
|
407
|
-
this.lastRoute =
|
|
495
|
+
sendRouteContext(e, t, n, a = "user") {
|
|
496
|
+
const r = C();
|
|
497
|
+
this.lastRoute = r;
|
|
408
498
|
const o = {
|
|
409
499
|
ui_state: "page_navigation",
|
|
410
|
-
navigation_led_by:
|
|
411
|
-
current_route:
|
|
412
|
-
current_page:
|
|
500
|
+
navigation_led_by: a,
|
|
501
|
+
current_route: r,
|
|
502
|
+
current_page: r,
|
|
413
503
|
user_action: e === "call_started" ? "call_started_on_page" : "user_navigated"
|
|
414
504
|
};
|
|
415
|
-
e === "call_started" ? o.message = `User started the call while viewing ${
|
|
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));
|
|
416
506
|
try {
|
|
417
507
|
this.sendContext(o);
|
|
418
508
|
} catch {
|
|
419
509
|
}
|
|
420
510
|
}
|
|
421
511
|
}
|
|
422
|
-
const
|
|
512
|
+
const y = class y {
|
|
423
513
|
constructor(e) {
|
|
424
514
|
l(this, "serverUrl");
|
|
425
515
|
l(this, "agentId");
|
|
@@ -428,6 +518,8 @@ const w = class w {
|
|
|
428
518
|
l(this, "apiKey");
|
|
429
519
|
l(this, "backendUrl");
|
|
430
520
|
l(this, "token");
|
|
521
|
+
l(this, "prospectName");
|
|
522
|
+
l(this, "extraDetails");
|
|
431
523
|
l(this, "onConnected");
|
|
432
524
|
l(this, "onDisconnected");
|
|
433
525
|
l(this, "onError");
|
|
@@ -445,8 +537,10 @@ const w = class w {
|
|
|
445
537
|
l(this, "localStream", null);
|
|
446
538
|
l(this, "micMuted", !1);
|
|
447
539
|
l(this, "connected", !1);
|
|
448
|
-
l(this, "icePollInterval", null);
|
|
449
540
|
l(this, "appliedRemoteCandidates", /* @__PURE__ */ new Set());
|
|
541
|
+
l(this, "remoteDescSet", !1);
|
|
542
|
+
l(this, "pendingServerIce", []);
|
|
543
|
+
l(this, "icePollStop", !1);
|
|
450
544
|
l(this, "iceServers");
|
|
451
545
|
l(this, "callSessionLoaded", !1);
|
|
452
546
|
l(this, "connectGeneration", 0);
|
|
@@ -458,66 +552,67 @@ const w = class w {
|
|
|
458
552
|
/** Live vision config — auto-starts camera on connect when scope is full_call. */
|
|
459
553
|
l(this, "liveVision");
|
|
460
554
|
l(this, "liveVisionAutoStarted", !1);
|
|
555
|
+
l(this, "connectStallTimeoutMs");
|
|
461
556
|
if (!e.agentId) throw new Error("agentId is required");
|
|
462
|
-
const t = !!(e.apiKey || e.token),
|
|
557
|
+
const t = !!(e.apiKey || e.token), n = !!(e.serverUrl && e.callId), a = y.normalizeIceServers(
|
|
463
558
|
e.iceServers
|
|
464
559
|
);
|
|
465
|
-
if (!t && !
|
|
560
|
+
if (!t && !n)
|
|
466
561
|
throw new Error(
|
|
467
562
|
"apiKey or token is required — or pass serverUrl and callId from a prior POST /calls/create"
|
|
468
563
|
);
|
|
469
|
-
this.agentId = e.agentId, this.sessionBehavior = e.sessionBehavior, this.serverUrl = (e.serverUrl || "").replace(/\/$/, ""), this.apiKey = e.apiKey, this.token = e.token, this.backendUrl = (e.backendUrl ||
|
|
470
|
-
const
|
|
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);
|
|
565
|
+
const r = typeof window < "u";
|
|
471
566
|
this.prospectId = e.prospectId;
|
|
472
567
|
const o = e.sessionBehavior === "continue";
|
|
473
|
-
if (o &&
|
|
474
|
-
const
|
|
475
|
-
|
|
568
|
+
if (o && r && !e.callId) {
|
|
569
|
+
const s = W(this.agentId);
|
|
570
|
+
s && (e.callId || (this.callId = s.callId), !this.prospectId && s.prospectId && (this.prospectId = s.prospectId));
|
|
476
571
|
}
|
|
477
|
-
if (!this.prospectId &&
|
|
572
|
+
if (!this.prospectId && r)
|
|
478
573
|
try {
|
|
479
|
-
const
|
|
480
|
-
this.prospectId = (
|
|
574
|
+
const s = W(this.agentId);
|
|
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;
|
|
481
576
|
} catch {
|
|
482
577
|
}
|
|
483
578
|
e.callId ? this.callId = e.callId : o || (this.callId = void 0);
|
|
484
|
-
const
|
|
485
|
-
this.onSessionStarted = (
|
|
486
|
-
|
|
487
|
-
}, this.liveVision = e.liveVision, this.onConnected = () => {
|
|
488
|
-
var
|
|
489
|
-
this._status = "connected", (
|
|
579
|
+
const h = e.onSessionStarted;
|
|
580
|
+
this.onSessionStarted = (s) => {
|
|
581
|
+
h == null || h(s), this.emit("session_started", s);
|
|
582
|
+
}, this.liveVision = e.liveVision, this.connectStallTimeoutMs = e.connectStallTimeoutMs ?? 15e3, this.onConnected = () => {
|
|
583
|
+
var s;
|
|
584
|
+
g(), this._status = "connected", (s = e.onConnected) == null || s.call(e), this.emit("connected"), this.maybeAutoStartLiveCamera();
|
|
490
585
|
}, this.onDisconnected = () => {
|
|
491
|
-
var
|
|
492
|
-
this._status = "disconnected", (
|
|
493
|
-
}, this.onError = (
|
|
494
|
-
var p;
|
|
495
|
-
this._status = "error";
|
|
496
|
-
const h = typeof r == "string" ? r : (r == null ? void 0 : r.message) || "Connection error";
|
|
497
|
-
(p = e.onError) == null || p.call(e, r), this.emit("error", h);
|
|
498
|
-
}, this.onTranscription = (r, h) => {
|
|
586
|
+
var s;
|
|
587
|
+
g(), this._status = "disconnected", (s = e.onDisconnected) == null || s.call(e), this.emit("disconnected");
|
|
588
|
+
}, this.onError = (s) => {
|
|
499
589
|
var p;
|
|
500
|
-
(
|
|
590
|
+
g(), this._status = "error";
|
|
591
|
+
const u = typeof s == "string" ? s : (s == null ? void 0 : s.message) || "Connection error";
|
|
592
|
+
(p = e.onError) == null || p.call(e, s), this.emit("error", 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 });
|
|
501
596
|
}, this.onLocalStream = e.onLocalStream || (() => {
|
|
502
|
-
}), this.onRemoteTrack = (
|
|
597
|
+
}), this.onRemoteTrack = (s, u) => {
|
|
503
598
|
var p;
|
|
504
|
-
(p = e.onRemoteTrack) == null || p.call(e,
|
|
505
|
-
}, this.onClientToolCall = (
|
|
506
|
-
var
|
|
507
|
-
(
|
|
508
|
-
const
|
|
509
|
-
name: String(
|
|
510
|
-
arguments:
|
|
511
|
-
tool_call_id: String(
|
|
512
|
-
execution_mode:
|
|
513
|
-
client_fields:
|
|
599
|
+
(p = e.onRemoteTrack) == null || p.call(e, s, u), this.emit("track", { track: s, stream: u });
|
|
600
|
+
}, this.onClientToolCall = (s) => {
|
|
601
|
+
var d;
|
|
602
|
+
(d = e.onClientToolCall) == null || d.call(e, s);
|
|
603
|
+
const u = (s == null ? void 0 : s.data) || s, p = {
|
|
604
|
+
name: String(u.name || u.tool_name || ""),
|
|
605
|
+
arguments: u.arguments || u.args || {},
|
|
606
|
+
tool_call_id: String(u.tool_call_id || u.call_id || ""),
|
|
607
|
+
execution_mode: u.execution_mode === "blocking" ? "blocking" : "fire_and_forget",
|
|
608
|
+
client_fields: u.client_fields || {}
|
|
514
609
|
};
|
|
515
610
|
p.name && p.tool_call_id && this.emit("tool_call", p);
|
|
516
|
-
}, this.runtime = e.runtime, typeof window < "u" && e.trackRouteContext !== !1 && (this.routeTracker = new
|
|
517
|
-
sendContext: (
|
|
611
|
+
}, this.runtime = e.runtime, typeof window < "u" && e.trackRouteContext !== !1 && (this.routeTracker = new Ie({
|
|
612
|
+
sendContext: (s) => this.sendContextUpdate(s),
|
|
518
613
|
isReady: () => {
|
|
519
|
-
var
|
|
520
|
-
return ((
|
|
614
|
+
var s;
|
|
615
|
+
return ((s = this.dataChannel) == null ? void 0 : s.readyState) === "open";
|
|
521
616
|
}
|
|
522
617
|
}));
|
|
523
618
|
}
|
|
@@ -539,7 +634,7 @@ const w = class w {
|
|
|
539
634
|
*/
|
|
540
635
|
async connect() {
|
|
541
636
|
var t;
|
|
542
|
-
this._status = "connecting";
|
|
637
|
+
this._status = "connecting", this.connectStallTimeoutMs > 0 && ge(this.connectStallTimeoutMs);
|
|
543
638
|
const e = ++this.connectGeneration;
|
|
544
639
|
if (await this.loadCallSession(), !this.isConnectCancelled(e)) {
|
|
545
640
|
if (!this.serverUrl)
|
|
@@ -552,15 +647,15 @@ const w = class w {
|
|
|
552
647
|
} catch {
|
|
553
648
|
}
|
|
554
649
|
try {
|
|
555
|
-
this.appliedRemoteCandidates.clear(), this.stopRemoteIcePolling();
|
|
556
|
-
const
|
|
650
|
+
this.appliedRemoteCandidates.clear(), this.remoteDescSet = !1, this.pendingServerIce = [], this.icePollStop = !1, this.stopRemoteIcePolling();
|
|
651
|
+
const n = this.getIceServers();
|
|
557
652
|
this.pc = new RTCPeerConnection({
|
|
558
|
-
iceServers:
|
|
653
|
+
iceServers: n,
|
|
559
654
|
iceTransportPolicy: "all"
|
|
560
655
|
});
|
|
561
|
-
let
|
|
656
|
+
let a;
|
|
562
657
|
try {
|
|
563
|
-
|
|
658
|
+
a = await navigator.mediaDevices.getUserMedia({
|
|
564
659
|
audio: {
|
|
565
660
|
echoCancellation: !0,
|
|
566
661
|
noiseSuppression: !0,
|
|
@@ -569,82 +664,77 @@ const w = class w {
|
|
|
569
664
|
channelCount: 1
|
|
570
665
|
}
|
|
571
666
|
});
|
|
572
|
-
} catch (
|
|
573
|
-
if (
|
|
667
|
+
} catch (d) {
|
|
668
|
+
if (d.name === "NotAllowedError" || d.name === "PermissionDeniedError" || (t = d.message) != null && t.includes("Permission denied")) {
|
|
574
669
|
const _ = navigator.userAgent, m = /iPad|iPhone|iPod/.test(_) || navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
|
|
575
670
|
let f = "Microphone access denied. Please allow microphone access in your browser settings.";
|
|
576
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).");
|
|
577
|
-
const
|
|
578
|
-
throw
|
|
672
|
+
const w = new Error(f);
|
|
673
|
+
throw w.name = d.name, w;
|
|
579
674
|
}
|
|
580
|
-
throw
|
|
675
|
+
throw d;
|
|
581
676
|
}
|
|
582
677
|
if (this.isConnectCancelled(e)) {
|
|
583
|
-
|
|
678
|
+
a.getTracks().forEach((d) => d.stop());
|
|
584
679
|
return;
|
|
585
680
|
}
|
|
586
|
-
if (this.localStream =
|
|
587
|
-
|
|
681
|
+
if (this.localStream = a, !this.pc || this.isConnectCancelled(e)) {
|
|
682
|
+
a.getTracks().forEach((d) => d.stop());
|
|
588
683
|
return;
|
|
589
684
|
}
|
|
590
|
-
if (this.onLocalStream(
|
|
685
|
+
if (this.onLocalStream(a), a.getTracks().forEach((d) => {
|
|
591
686
|
var _;
|
|
592
|
-
(_ = this.pc) == null || _.addTrack(
|
|
687
|
+
(_ = this.pc) == null || _.addTrack(d, a);
|
|
593
688
|
}), !this.pc)
|
|
594
689
|
throw new Error("RTCPeerConnection was closed unexpectedly");
|
|
595
690
|
this.dataChannel = this.pc.createDataChannel("control"), this.dataChannel.onopen = () => {
|
|
596
|
-
var
|
|
597
|
-
(
|
|
598
|
-
}, this.dataChannel.onmessage = (
|
|
599
|
-
if (typeof
|
|
691
|
+
var d;
|
|
692
|
+
(d = this.routeTracker) == null || d.onChannelReady();
|
|
693
|
+
}, this.dataChannel.onmessage = (d) => {
|
|
694
|
+
if (typeof d.data == "string")
|
|
600
695
|
try {
|
|
601
|
-
this.handleControlEvent(JSON.parse(
|
|
696
|
+
this.handleControlEvent(JSON.parse(d.data));
|
|
602
697
|
} catch {
|
|
603
698
|
}
|
|
604
|
-
else if (
|
|
699
|
+
else if (d.data instanceof ArrayBuffer)
|
|
605
700
|
try {
|
|
606
|
-
const _ = new TextDecoder().decode(
|
|
701
|
+
const _ = new TextDecoder().decode(d.data);
|
|
607
702
|
try {
|
|
608
703
|
const m = JSON.parse(_);
|
|
609
|
-
|
|
704
|
+
pe(m) && this.handleControlEvent(m);
|
|
610
705
|
} catch {
|
|
611
706
|
}
|
|
612
707
|
} catch {
|
|
613
708
|
}
|
|
614
|
-
else
|
|
709
|
+
else d.data instanceof Blob && d.data.text().then((_) => {
|
|
615
710
|
try {
|
|
616
711
|
this.handleControlEvent(JSON.parse(_));
|
|
617
712
|
} catch {
|
|
618
713
|
}
|
|
619
714
|
});
|
|
620
|
-
}, this.dataChannel.onerror = (
|
|
715
|
+
}, this.dataChannel.onerror = (d) => {
|
|
621
716
|
}, this.mediaBytesChannel = this.pc.createDataChannel("media-bytes", { ordered: !0 }), this.mediaBytesChannel.binaryType = "arraybuffer", this.mediaBytesChannel.onopen = () => {
|
|
622
|
-
}, this.mediaBytesChannel.onerror = (
|
|
623
|
-
}, this.pc.ontrack = (
|
|
624
|
-
const _ =
|
|
717
|
+
}, this.mediaBytesChannel.onerror = (d) => {
|
|
718
|
+
}, this.pc.ontrack = (d) => {
|
|
719
|
+
const _ = d.track, m = d.streams[0];
|
|
625
720
|
_.kind === "audio" ? (this.audioElement = new Audio(), this.audioElement.srcObject = m, this.audioElement.play().catch((f) => {
|
|
626
721
|
}), this.audioElement.onended = () => {
|
|
627
722
|
this.sendEvent("playedStream"), typeof window < "u" && window.dispatchEvent(new CustomEvent("vanira:agent-playback-ended"));
|
|
628
723
|
}, this.onRemoteTrack(_, m)) : _.kind === "video" && this.onRemoteTrack(_, m);
|
|
629
724
|
};
|
|
630
|
-
const
|
|
631
|
-
var m, f,
|
|
632
|
-
const
|
|
633
|
-
((
|
|
725
|
+
const r = () => {
|
|
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());
|
|
634
729
|
};
|
|
635
|
-
this.pc.onconnectionstatechange =
|
|
730
|
+
this.pc.onconnectionstatechange = r, this.pc.oniceconnectionstatechange = r;
|
|
636
731
|
const o = this.getIceTrickleUrl();
|
|
637
|
-
this.pc.onicecandidate = (
|
|
638
|
-
|
|
639
|
-
method: "POST",
|
|
640
|
-
headers: { "Content-Type": "application/json" },
|
|
641
|
-
body: JSON.stringify({ candidate: c.candidate.toJSON() })
|
|
642
|
-
}).catch((_) => {
|
|
643
|
-
});
|
|
732
|
+
this.pc.onicecandidate = (d) => {
|
|
733
|
+
d.candidate && this.sendRemoteIceCandidate(d.candidate, o);
|
|
644
734
|
};
|
|
645
|
-
const
|
|
646
|
-
if (this.isConnectCancelled(e) || (await this.pc.setLocalDescription(
|
|
647
|
-
const
|
|
735
|
+
const h = await this.pc.createOffer();
|
|
736
|
+
if (this.isConnectCancelled(e) || (await this.pc.setLocalDescription(h), this.isConnectCancelled(e))) return;
|
|
737
|
+
const s = this.serverUrl.includes("?") ? this.serverUrl : `${this.serverUrl}/webrtc?agent=${this.agentId}_${this.callId}`, u = await fetch(s, {
|
|
648
738
|
method: "POST",
|
|
649
739
|
headers: { "Content-Type": "application/json" },
|
|
650
740
|
body: JSON.stringify({
|
|
@@ -654,63 +744,65 @@ const w = class w {
|
|
|
654
744
|
})
|
|
655
745
|
});
|
|
656
746
|
if (this.isConnectCancelled(e)) return;
|
|
657
|
-
if (!
|
|
658
|
-
const
|
|
659
|
-
throw new Error(
|
|
747
|
+
if (!u.ok) {
|
|
748
|
+
const d = await u.json();
|
|
749
|
+
throw new Error(d.error || `HTTP ${u.status}`);
|
|
660
750
|
}
|
|
661
|
-
const { answer: p } = await
|
|
662
|
-
if (this.isConnectCancelled(e) || !this.pc || (await this.pc.setRemoteDescription(p), this.isConnectCancelled(e))) return;
|
|
751
|
+
const { answer: p } = await u.json();
|
|
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;
|
|
663
753
|
this.startRemoteIcePolling(o);
|
|
664
|
-
} catch (
|
|
754
|
+
} catch (n) {
|
|
665
755
|
if (this.isConnectCancelled(e)) return;
|
|
666
|
-
throw this.disconnect(), this.onError(
|
|
756
|
+
throw this.disconnect(), this.onError(n.message || n), n;
|
|
667
757
|
}
|
|
668
758
|
}
|
|
669
759
|
}
|
|
670
760
|
createCallCacheKey(e, t) {
|
|
671
|
-
const
|
|
761
|
+
const n = this.apiKey ? `key:${this.apiKey.slice(0, 16)}` : `token:${(this.token || "").slice(-16)}`;
|
|
672
762
|
return [
|
|
673
763
|
this.backendUrl,
|
|
674
764
|
this.agentId,
|
|
675
765
|
e,
|
|
676
766
|
t || "",
|
|
677
767
|
this.prospectId || "",
|
|
678
|
-
|
|
768
|
+
n
|
|
679
769
|
].join("|");
|
|
680
770
|
}
|
|
681
|
-
async postCreateCall(e, t,
|
|
682
|
-
var
|
|
683
|
-
const
|
|
771
|
+
async postCreateCall(e, t, n) {
|
|
772
|
+
var h, s, u;
|
|
773
|
+
const a = await fetch(`${this.backendUrl}/calls/create`, {
|
|
684
774
|
method: "POST",
|
|
685
775
|
headers: e,
|
|
686
776
|
body: JSON.stringify({
|
|
687
777
|
agent_id: this.agentId,
|
|
688
|
-
type: ((
|
|
778
|
+
type: ((h = this.runtime) == null ? void 0 : h.callType) || "web",
|
|
689
779
|
mode: t,
|
|
690
|
-
...(
|
|
780
|
+
...(s = this.runtime) != null && s.runtimeName ? { runtime: this.runtime.runtimeName } : {},
|
|
691
781
|
prospect_id: this.prospectId,
|
|
692
|
-
...
|
|
782
|
+
...this.prospectName ? { prospect_name: this.prospectName } : {},
|
|
783
|
+
...this.extraDetails && Object.keys(this.extraDetails).length ? { extra_details: this.extraDetails } : {},
|
|
784
|
+
...n ? { call_id: n } : {}
|
|
693
785
|
})
|
|
694
786
|
});
|
|
695
|
-
if (!
|
|
696
|
-
const p = await
|
|
697
|
-
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}`);
|
|
698
790
|
}
|
|
699
|
-
const
|
|
700
|
-
if (!
|
|
791
|
+
const r = await a.json();
|
|
792
|
+
if (!r.call_id || !r.worker_url)
|
|
701
793
|
throw new Error("[VaniraClient] /calls/create response missing call_id or worker_url");
|
|
702
|
-
const o =
|
|
794
|
+
const o = y.normalizeIceServers(r.ice_servers);
|
|
703
795
|
if (!o.length)
|
|
704
796
|
throw new Error("[VaniraClient] /calls/create response missing ice_servers");
|
|
705
797
|
return {
|
|
706
|
-
callId:
|
|
707
|
-
prospectId:
|
|
708
|
-
serverUrl:
|
|
798
|
+
callId: r.call_id,
|
|
799
|
+
prospectId: r.prospect_id || this.prospectId,
|
|
800
|
+
serverUrl: r.worker_url.replace(/\/$/, ""),
|
|
709
801
|
iceServers: o
|
|
710
802
|
};
|
|
711
803
|
}
|
|
712
804
|
applyCreateCallSession(e) {
|
|
713
|
-
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)
|
|
714
806
|
try {
|
|
715
807
|
this.onSessionStarted({ prospectId: this.prospectId, callId: this.callId, serverUrl: this.serverUrl }), this.sessionStartedEmitted = !0;
|
|
716
808
|
} catch {
|
|
@@ -726,12 +818,12 @@ const w = class w {
|
|
|
726
818
|
throw new Error("[VaniraClient] apiKey or token is required to create a call session");
|
|
727
819
|
const e = { "Content-Type": "application/json" };
|
|
728
820
|
this.apiKey ? e["X-API-Key"] = this.apiKey : this.token && (e.Authorization = this.token.startsWith("Bearer ") ? this.token : `Bearer ${this.token}`);
|
|
729
|
-
const t = this.sessionBehavior === "continue" ? this.callId : void 0,
|
|
730
|
-
let
|
|
731
|
-
|
|
732
|
-
|
|
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);
|
|
733
825
|
}));
|
|
734
|
-
const o = await
|
|
826
|
+
const o = await r;
|
|
735
827
|
this.applyCreateCallSession(o);
|
|
736
828
|
}
|
|
737
829
|
getIceServers() {
|
|
@@ -742,11 +834,11 @@ const w = class w {
|
|
|
742
834
|
static normalizeIceServers(e) {
|
|
743
835
|
if (!Array.isArray(e)) return [];
|
|
744
836
|
const t = [];
|
|
745
|
-
for (const
|
|
746
|
-
const
|
|
747
|
-
if (!
|
|
748
|
-
const o = { urls:
|
|
749
|
-
|
|
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()] : [];
|
|
839
|
+
if (!r.length) continue;
|
|
840
|
+
const o = { urls: r.length === 1 ? r[0] : r }, h = n.username, s = n.credential;
|
|
841
|
+
h && (o.username = h), s && (o.credential = s), t.push(o);
|
|
750
842
|
}
|
|
751
843
|
return t;
|
|
752
844
|
}
|
|
@@ -771,53 +863,93 @@ const w = class w {
|
|
|
771
863
|
return `${this.getWorkerOrigin()}/webrtc/ice?agent_id=${this.agentId}&call_id=${this.callId}`;
|
|
772
864
|
}
|
|
773
865
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
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);
|
|
779
876
|
}
|
|
780
|
-
|
|
781
|
-
|
|
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);
|
|
782
885
|
return;
|
|
783
886
|
}
|
|
784
|
-
|
|
785
|
-
const
|
|
786
|
-
if (!
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
this.appliedRemoteCandidates.add(s);
|
|
792
|
-
try {
|
|
793
|
-
await this.pc.addIceCandidate(n);
|
|
794
|
-
} catch {
|
|
795
|
-
}
|
|
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 {
|
|
796
894
|
}
|
|
797
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
|
+
}
|
|
798
929
|
} catch {
|
|
799
930
|
}
|
|
800
|
-
|
|
931
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
932
|
+
}
|
|
801
933
|
}
|
|
802
934
|
stopRemoteIcePolling() {
|
|
803
|
-
this.
|
|
935
|
+
this.icePollStop = !0;
|
|
804
936
|
}
|
|
805
937
|
/**
|
|
806
938
|
* Send control event via DataChannel
|
|
807
939
|
*/
|
|
808
940
|
sendEvent(e, t = {}) {
|
|
809
|
-
var
|
|
810
|
-
if (((
|
|
811
|
-
const
|
|
812
|
-
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));
|
|
813
945
|
}
|
|
814
946
|
}
|
|
815
947
|
/** Wait for control DataChannel, then send (live vision lifecycle events). */
|
|
816
|
-
async sendEventWhenReady(e, t = {},
|
|
817
|
-
var
|
|
818
|
-
const
|
|
819
|
-
for (; Date.now() <
|
|
820
|
-
if (((
|
|
948
|
+
async sendEventWhenReady(e, t = {}, n = 1e4) {
|
|
949
|
+
var r;
|
|
950
|
+
const a = Date.now() + n;
|
|
951
|
+
for (; Date.now() < a; ) {
|
|
952
|
+
if (((r = this.dataChannel) == null ? void 0 : r.readyState) === "open")
|
|
821
953
|
return this.sendEvent(e, t), !0;
|
|
822
954
|
await new Promise((o) => setTimeout(o, 50));
|
|
823
955
|
}
|
|
@@ -834,7 +966,7 @@ const w = class w {
|
|
|
834
966
|
name: "open_live_camera",
|
|
835
967
|
tool_call_id: `lv_${crypto.randomUUID()}`,
|
|
836
968
|
execution_mode: "fire_and_forget",
|
|
837
|
-
client_fields: { preset_id:
|
|
969
|
+
client_fields: { preset_id: c.LiveVision },
|
|
838
970
|
arguments: {
|
|
839
971
|
mode: "live",
|
|
840
972
|
scope: t,
|
|
@@ -859,38 +991,48 @@ const w = class w {
|
|
|
859
991
|
var t;
|
|
860
992
|
switch (e.event) {
|
|
861
993
|
case "clearAudio":
|
|
994
|
+
this.dispatchBoardAbort(
|
|
995
|
+
"User interrupted while LaTeX was writing",
|
|
996
|
+
void 0,
|
|
997
|
+
c.WriteLatexText
|
|
998
|
+
);
|
|
862
999
|
break;
|
|
863
1000
|
case "transcription":
|
|
864
|
-
|
|
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
|
+
}
|
|
865
1007
|
break;
|
|
866
1008
|
case "mark":
|
|
867
1009
|
break;
|
|
868
1010
|
case "client_tool_cancel": {
|
|
869
|
-
const
|
|
870
|
-
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);
|
|
871
1013
|
break;
|
|
872
1014
|
}
|
|
873
1015
|
case "client_tool_call": {
|
|
874
|
-
const
|
|
875
|
-
|
|
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({
|
|
876
1018
|
event: "client_tool_ack",
|
|
877
|
-
data: { tool_call_id:
|
|
1019
|
+
data: { tool_call_id: a }
|
|
878
1020
|
}));
|
|
879
|
-
const
|
|
880
|
-
if (
|
|
881
|
-
|
|
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);
|
|
1022
|
+
if (h === "end_call") {
|
|
1023
|
+
a && this.sendToolResult(a, {
|
|
882
1024
|
status: "client_ack_end_call",
|
|
883
1025
|
message: "Ending call."
|
|
884
1026
|
}), window.setTimeout(() => this.disconnect(), 120);
|
|
885
1027
|
break;
|
|
886
1028
|
}
|
|
887
|
-
if (
|
|
1029
|
+
if (s) {
|
|
888
1030
|
window.dispatchEvent(new CustomEvent("vanira:preset", {
|
|
889
|
-
detail: { toolCall:
|
|
890
|
-
})), this.onClientToolCall(
|
|
1031
|
+
detail: { toolCall: n, client: this }
|
|
1032
|
+
})), this.onClientToolCall(n);
|
|
891
1033
|
break;
|
|
892
1034
|
}
|
|
893
|
-
this.onClientToolCall(
|
|
1035
|
+
this.onClientToolCall(n);
|
|
894
1036
|
break;
|
|
895
1037
|
}
|
|
896
1038
|
}
|
|
@@ -900,7 +1042,7 @@ const w = class w {
|
|
|
900
1042
|
*/
|
|
901
1043
|
disconnect() {
|
|
902
1044
|
var e;
|
|
903
|
-
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) => {
|
|
904
1046
|
t.track && t.track.stop();
|
|
905
1047
|
}), this.pc.close(), this.pc = null), this.localStream && (this.localStream.getTracks().forEach((t) => {
|
|
906
1048
|
try {
|
|
@@ -914,12 +1056,12 @@ const w = class w {
|
|
|
914
1056
|
* Uses track.enabled (not pause) so audio resumes correctly when unmuted.
|
|
915
1057
|
*/
|
|
916
1058
|
setMicrophoneMuted(e) {
|
|
917
|
-
var t,
|
|
918
|
-
this.micMuted = e, (t = this.localStream) == null || t.getAudioTracks().forEach((
|
|
919
|
-
|
|
920
|
-
}), (
|
|
921
|
-
var
|
|
922
|
-
((
|
|
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) => {
|
|
1063
|
+
var r;
|
|
1064
|
+
((r = a.track) == null ? void 0 : r.kind) === "audio" && (a.track.enabled = !e);
|
|
923
1065
|
});
|
|
924
1066
|
}
|
|
925
1067
|
isMicrophoneMuted() {
|
|
@@ -932,9 +1074,9 @@ const w = class w {
|
|
|
932
1074
|
return e !== this.connectGeneration;
|
|
933
1075
|
}
|
|
934
1076
|
/** Notify WidgetPresetRenderer to cancel in-flight board animations */
|
|
935
|
-
dispatchBoardAbort(e, t) {
|
|
1077
|
+
dispatchBoardAbort(e, t, n) {
|
|
936
1078
|
typeof window > "u" || window.dispatchEvent(new CustomEvent("vanira:board_abort", {
|
|
937
|
-
detail: { reason: e, toolCallId: t }
|
|
1079
|
+
detail: { reason: e, toolCallId: t, presetId: n }
|
|
938
1080
|
}));
|
|
939
1081
|
}
|
|
940
1082
|
/**
|
|
@@ -949,7 +1091,7 @@ const w = class w {
|
|
|
949
1091
|
call_id: this.callId,
|
|
950
1092
|
data: { tool_call_id: e, result: t },
|
|
951
1093
|
result: t
|
|
952
|
-
});
|
|
1094
|
+
}), this.emit("tool_result", { toolCallId: e, result: t });
|
|
953
1095
|
}
|
|
954
1096
|
/**
|
|
955
1097
|
* Send an acknowledgement that the client received a tool call and rendered it.
|
|
@@ -1023,8 +1165,8 @@ const w = class w {
|
|
|
1023
1165
|
* @param reason Routing key for backend processing (default: 'general')
|
|
1024
1166
|
* @param message Optional user text message about the file
|
|
1025
1167
|
*/
|
|
1026
|
-
async uploadMedia(e, t = "general",
|
|
1027
|
-
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));
|
|
1028
1170
|
}
|
|
1029
1171
|
/**
|
|
1030
1172
|
* Upload a live vision / screen frame — HTTP only for now, never sends client_media_update.
|
|
@@ -1033,72 +1175,72 @@ const w = class w {
|
|
|
1033
1175
|
* Frames require a real media_url (server rejects empty). WebRTC upload returns url="" until
|
|
1034
1176
|
* the server adds client_media_upload_ready ack — use HTTP for frame JPEGs until then.
|
|
1035
1177
|
*/
|
|
1036
|
-
async uploadMediaFrame(e, t = "camera_capture",
|
|
1037
|
-
const
|
|
1038
|
-
if (!
|
|
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);
|
|
1180
|
+
if (!r || !o)
|
|
1039
1181
|
throw new Error("Frame upload failed: server response missing media_id or url");
|
|
1040
|
-
return { media_id:
|
|
1182
|
+
return { media_id: r, url: o, content_type: h };
|
|
1041
1183
|
}
|
|
1042
1184
|
/** WebRTC media-bytes path (control start/complete + binary chunks). */
|
|
1043
|
-
async _uploadBytesViaDataChannel(e, t,
|
|
1185
|
+
async _uploadBytesViaDataChannel(e, t, n, a, r) {
|
|
1044
1186
|
if (!this.callId || !this.mediaBytesChannel)
|
|
1045
1187
|
throw new Error("Upload failed: call not ready for WebRTC media upload.");
|
|
1046
|
-
const o =
|
|
1047
|
-
return
|
|
1048
|
-
bytes:
|
|
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({
|
|
1190
|
+
bytes: s,
|
|
1049
1191
|
filename: o,
|
|
1050
|
-
contentType:
|
|
1192
|
+
contentType: h,
|
|
1051
1193
|
reason: t,
|
|
1052
|
-
message:
|
|
1194
|
+
message: n,
|
|
1053
1195
|
callId: this.callId,
|
|
1054
1196
|
mediaBytesChannel: this.mediaBytesChannel,
|
|
1055
|
-
sendControlEvent: (
|
|
1056
|
-
uploadKind:
|
|
1197
|
+
sendControlEvent: (u, p) => this.sendEvent(u, p),
|
|
1198
|
+
uploadKind: a
|
|
1057
1199
|
});
|
|
1058
1200
|
}
|
|
1059
|
-
async _uploadMediaViaDataChannel(e, t,
|
|
1060
|
-
const
|
|
1061
|
-
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 };
|
|
1062
1204
|
}
|
|
1063
1205
|
/** HTTP fallback — original uploadMedia behavior (unchanged). */
|
|
1064
|
-
async _uploadMediaViaHTTP(e, t = "general",
|
|
1065
|
-
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);
|
|
1066
1208
|
return this.sendMediaUpdate({
|
|
1067
|
-
media_id:
|
|
1068
|
-
media_url:
|
|
1209
|
+
media_id: a,
|
|
1210
|
+
media_url: r,
|
|
1069
1211
|
content_type: o,
|
|
1070
1212
|
reason: t,
|
|
1071
|
-
message:
|
|
1072
|
-
}), { media_id:
|
|
1213
|
+
message: n
|
|
1214
|
+
}), { media_id: a, url: r };
|
|
1073
1215
|
}
|
|
1074
|
-
async _postMediaUpload(e, t,
|
|
1216
|
+
async _postMediaUpload(e, t, n = !1) {
|
|
1075
1217
|
if (!this.serverUrl)
|
|
1076
1218
|
throw new Error("Upload failed: serverUrl is not set. Connect the VaniraClient first.");
|
|
1077
1219
|
if (!this.callId)
|
|
1078
1220
|
throw new Error("Upload failed: callId is missing.");
|
|
1079
|
-
const
|
|
1080
|
-
if (!
|
|
1221
|
+
const a = this.getWorkerOrigin();
|
|
1222
|
+
if (!a)
|
|
1081
1223
|
throw new Error(
|
|
1082
1224
|
"Upload failed: worker_url is not set. Connect the call before uploading media."
|
|
1083
1225
|
);
|
|
1084
|
-
const
|
|
1226
|
+
const r = `${a}/media/upload`, o = new FormData();
|
|
1085
1227
|
o.append("file", e), o.append("call_id", this.callId), o.append("reason", t);
|
|
1086
|
-
const
|
|
1228
|
+
const h = await fetch(r, {
|
|
1087
1229
|
method: "POST",
|
|
1088
1230
|
body: o
|
|
1089
1231
|
});
|
|
1090
|
-
if (!
|
|
1091
|
-
let _ = `HTTP ${
|
|
1232
|
+
if (!h.ok) {
|
|
1233
|
+
let _ = `HTTP ${h.status}`;
|
|
1092
1234
|
try {
|
|
1093
|
-
_ = (await
|
|
1235
|
+
_ = (await h.json()).error || _;
|
|
1094
1236
|
} catch {
|
|
1095
1237
|
}
|
|
1096
1238
|
throw new Error(`Upload failed: ${_}`);
|
|
1097
1239
|
}
|
|
1098
|
-
const
|
|
1099
|
-
if (!
|
|
1240
|
+
const s = await h.json(), u = s.media_id, p = s.url, d = s.content_type || e.type;
|
|
1241
|
+
if (!u || !p)
|
|
1100
1242
|
throw new Error("Upload failed: server response missing media_id or url");
|
|
1101
|
-
return
|
|
1243
|
+
return n ? { media_id: u, url: p, contentType: d } : { media_id: u, url: p, contentType: d };
|
|
1102
1244
|
}
|
|
1103
1245
|
// ─── Event emitter (replaces retired VaniraAI) ───────────────────────────
|
|
1104
1246
|
get status() {
|
|
@@ -1111,12 +1253,12 @@ const w = class w {
|
|
|
1111
1253
|
return this.listeners.has(e) || this.listeners.set(e, /* @__PURE__ */ new Set()), this.listeners.get(e).add(t), this;
|
|
1112
1254
|
}
|
|
1113
1255
|
off(e, t) {
|
|
1114
|
-
var
|
|
1115
|
-
return (
|
|
1256
|
+
var n;
|
|
1257
|
+
return (n = this.listeners.get(e)) == null || n.delete(t), this;
|
|
1116
1258
|
}
|
|
1117
1259
|
emit(e, t) {
|
|
1118
|
-
var
|
|
1119
|
-
(
|
|
1260
|
+
var n;
|
|
1261
|
+
(n = this.listeners.get(e)) == null || n.forEach((a) => a(t));
|
|
1120
1262
|
}
|
|
1121
1263
|
/** Alias for connect() — VaniraAI compatibility */
|
|
1122
1264
|
async start() {
|
|
@@ -1146,9 +1288,9 @@ const w = class w {
|
|
|
1146
1288
|
}
|
|
1147
1289
|
};
|
|
1148
1290
|
/** Dedupes concurrent POST /calls/create (e.g. React StrictMode double-mount). */
|
|
1149
|
-
l(
|
|
1150
|
-
let
|
|
1151
|
-
const
|
|
1291
|
+
l(y, "inflightCreates", /* @__PURE__ */ new Map());
|
|
1292
|
+
let A = y;
|
|
1293
|
+
const Te = {
|
|
1152
1294
|
supportsAudioEndedEvent: !1,
|
|
1153
1295
|
supportsScreenShare: !1,
|
|
1154
1296
|
supportsDom: !1,
|
|
@@ -1156,40 +1298,40 @@ const me = {
|
|
|
1156
1298
|
supportsCustomElements: !1,
|
|
1157
1299
|
supportsLocalStorage: !1,
|
|
1158
1300
|
supportsBroadcastChannel: !1
|
|
1159
|
-
},
|
|
1301
|
+
}, be = {
|
|
1160
1302
|
name: "react-native",
|
|
1161
1303
|
callType: "web",
|
|
1162
1304
|
runtimeName: "react-native",
|
|
1163
1305
|
callIdPrefix: "rn_",
|
|
1164
|
-
capabilities:
|
|
1165
|
-
audio: new
|
|
1166
|
-
media: new
|
|
1167
|
-
peer: new
|
|
1168
|
-
dataChannel: new
|
|
1306
|
+
capabilities: Te,
|
|
1307
|
+
audio: new Q(),
|
|
1308
|
+
media: new F(),
|
|
1309
|
+
peer: new ee(),
|
|
1310
|
+
dataChannel: new te()
|
|
1169
1311
|
};
|
|
1170
|
-
function
|
|
1171
|
-
return new
|
|
1172
|
-
...
|
|
1173
|
-
runtime:
|
|
1312
|
+
function Y(i) {
|
|
1313
|
+
return new A({
|
|
1314
|
+
...i,
|
|
1315
|
+
runtime: be
|
|
1174
1316
|
});
|
|
1175
1317
|
}
|
|
1176
|
-
const
|
|
1177
|
-
function
|
|
1178
|
-
return
|
|
1318
|
+
const ke = Y;
|
|
1319
|
+
function xe(i) {
|
|
1320
|
+
return Y(i);
|
|
1179
1321
|
}
|
|
1180
|
-
const
|
|
1322
|
+
const Re = xe;
|
|
1181
1323
|
export {
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
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
|
|
1195
1337
|
};
|