@oshara/voice-sdk 0.1.0

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.
Files changed (61) hide show
  1. package/README.md +198 -0
  2. package/dist/appearance-CNWT8x1G.cjs +2 -0
  3. package/dist/appearance-CNWT8x1G.cjs.map +1 -0
  4. package/dist/appearance-i6QBkpCk.js +650 -0
  5. package/dist/appearance-i6QBkpCk.js.map +1 -0
  6. package/dist/consent-CK9VXNPa.js +54 -0
  7. package/dist/consent-CK9VXNPa.js.map +1 -0
  8. package/dist/consent-D7QNSkQD.cjs +2 -0
  9. package/dist/consent-D7QNSkQD.cjs.map +1 -0
  10. package/dist/core/analytics.d.ts +30 -0
  11. package/dist/core/appearance.d.ts +113 -0
  12. package/dist/core/audioSettings.d.ts +69 -0
  13. package/dist/core/consent.d.ts +17 -0
  14. package/dist/core/createVoiceAgent.d.ts +79 -0
  15. package/dist/core/events.d.ts +103 -0
  16. package/dist/core/formController.d.ts +28 -0
  17. package/dist/core/forms.d.ts +235 -0
  18. package/dist/core/index.d.ts +29 -0
  19. package/dist/core/prevContext.d.ts +26 -0
  20. package/dist/core/transport.d.ts +30 -0
  21. package/dist/core/types.d.ts +49 -0
  22. package/dist/core/voice.d.ts +79 -0
  23. package/dist/createVoiceAgent-BM3HODS6.js +1058 -0
  24. package/dist/createVoiceAgent-BM3HODS6.js.map +1 -0
  25. package/dist/createVoiceAgent-CJWxWzz6.cjs +4 -0
  26. package/dist/createVoiceAgent-CJWxWzz6.cjs.map +1 -0
  27. package/dist/index.cjs +2 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.js +44 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/react/index.d.ts +60 -0
  32. package/dist/react.cjs +2 -0
  33. package/dist/react.cjs.map +1 -0
  34. package/dist/react.js +115 -0
  35. package/dist/react.js.map +1 -0
  36. package/dist/styles.css +1838 -0
  37. package/dist/ui/index.d.ts +21 -0
  38. package/dist/ui/ui.d.ts +165 -0
  39. package/dist/ui.cjs +284 -0
  40. package/dist/ui.cjs.map +1 -0
  41. package/dist/ui.js +1153 -0
  42. package/dist/ui.js.map +1 -0
  43. package/package.json +67 -0
  44. package/src/core/analytics.ts +111 -0
  45. package/src/core/appearance.ts +464 -0
  46. package/src/core/audioSettings.ts +180 -0
  47. package/src/core/consent.ts +78 -0
  48. package/src/core/createVoiceAgent.ts +280 -0
  49. package/src/core/events.ts +120 -0
  50. package/src/core/formController.ts +317 -0
  51. package/src/core/forms.ts +861 -0
  52. package/src/core/index.ts +121 -0
  53. package/src/core/prevContext.ts +153 -0
  54. package/src/core/transport.ts +118 -0
  55. package/src/core/types.ts +66 -0
  56. package/src/core/voice.ts +1179 -0
  57. package/src/react/index.ts +238 -0
  58. package/src/ui/index.ts +507 -0
  59. package/src/ui/styles.css +1838 -0
  60. package/src/ui/ui.ts +1672 -0
  61. package/src/vite-env.d.ts +10 -0
@@ -0,0 +1,1058 @@
1
+ var Re = Object.defineProperty;
2
+ var Oe = (e, n, r) => n in e ? Re(e, n, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[n] = r;
3
+ var ie = (e, n, r) => Oe(e, typeof n != "symbol" ? n + "" : n, r);
4
+ import { j as pe, i as Ne, t as Z, c as $e, d as Ke, v as je, s as Ve, k as Je, b as Ge, h as He, m as qe, e as ze, D as We, f as Xe } from "./appearance-i6QBkpCk.js";
5
+ import { Room as Be, RoomEvent as C, ConnectionState as me, Track as we, AudioPresets as Ye, LocalAudioTrack as Qe } from "livekit-client";
6
+ const he = "voiceAgent.visitor", ge = /* @__PURE__ */ new Set();
7
+ function Ze() {
8
+ try {
9
+ const e = localStorage.getItem(he);
10
+ if (e) return e;
11
+ const n = ve();
12
+ return localStorage.setItem(he, n), n;
13
+ } catch {
14
+ return ve();
15
+ }
16
+ }
17
+ function ve() {
18
+ try {
19
+ if (typeof crypto < "u" && crypto.randomUUID)
20
+ return crypto.randomUUID();
21
+ } catch {
22
+ }
23
+ return `v-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
24
+ }
25
+ function et(e, n, r = {}) {
26
+ var m, g;
27
+ if (!e.agentSlug || e.disabled || ge.has(n)) return;
28
+ ge.add(n);
29
+ const a = `${e.apiUrl}/api/agents/${encodeURIComponent(
30
+ e.agentSlug
31
+ )}/events/`, i = JSON.stringify({
32
+ event_type: n,
33
+ visitor_id: Ze(),
34
+ origin_url: typeof window < "u" && ((m = window.location) == null ? void 0 : m.href) || "",
35
+ metadata: r
36
+ }), c = { "Content-Type": "application/json" };
37
+ (g = e.apiKey) != null && g.trim() && (c["x-api-key"] = e.apiKey.trim());
38
+ const A = e.fetch ?? (typeof globalThis.fetch == "function" ? globalThis.fetch.bind(globalThis) : null);
39
+ if (A)
40
+ try {
41
+ A(a, {
42
+ method: "POST",
43
+ headers: c,
44
+ body: i,
45
+ keepalive: !0
46
+ }).catch(() => {
47
+ });
48
+ } catch {
49
+ }
50
+ }
51
+ const X = {
52
+ echoCancellation: !0,
53
+ noiseSuppression: !0,
54
+ // Off by default: AGC boosts the trailing tail of an utterance, which
55
+ // confuses the agent's contextual turn detector ("user is still
56
+ // talking softly") and delays preemptive LLM generation. Users can
57
+ // toggle this on per-call from the audio settings drawer if they're
58
+ // soft-spoken and the agent isn't hearing them.
59
+ autoGainControl: !1,
60
+ voiceIsolation: !0,
61
+ noiseFilter: "deepfilter",
62
+ deepFilterStrength: 40,
63
+ micDeviceId: "",
64
+ speakerDeviceId: "",
65
+ outputVolume: 85,
66
+ headphonesMode: !0,
67
+ transcriptionEnabled: !1,
68
+ textInputEnabled: !1
69
+ }, tt = "voice-agent:audio-prefs:";
70
+ function ke(e) {
71
+ return `${tt}${e || "default"}`;
72
+ }
73
+ function Ae(e) {
74
+ try {
75
+ const n = window.localStorage.getItem(ke(e));
76
+ if (!n) return { ...X };
77
+ const r = JSON.parse(n);
78
+ return !r || typeof r != "object" ? { ...X } : { ...X, ...Te(r) };
79
+ } catch {
80
+ return { ...X };
81
+ }
82
+ }
83
+ function nt(e, n) {
84
+ try {
85
+ window.localStorage.setItem(
86
+ ke(e),
87
+ JSON.stringify(Te(n))
88
+ );
89
+ } catch {
90
+ }
91
+ }
92
+ function Te(e) {
93
+ const n = {};
94
+ return typeof e.echoCancellation == "boolean" && (n.echoCancellation = e.echoCancellation), typeof e.noiseSuppression == "boolean" && (n.noiseSuppression = e.noiseSuppression), typeof e.autoGainControl == "boolean" && (n.autoGainControl = e.autoGainControl), typeof e.voiceIsolation == "boolean" && (n.voiceIsolation = e.voiceIsolation), e.noiseFilter === "off" || e.noiseFilter === "krisp" || e.noiseFilter === "deepfilter" ? n.noiseFilter = e.noiseFilter : typeof e.krispEnabled == "boolean" && (n.noiseFilter = e.krispEnabled ? "krisp" : "off"), typeof e.deepFilterStrength == "number" && Number.isFinite(e.deepFilterStrength) && (n.deepFilterStrength = Math.max(0, Math.min(100, e.deepFilterStrength))), typeof e.micDeviceId == "string" && (n.micDeviceId = e.micDeviceId), typeof e.speakerDeviceId == "string" && (n.speakerDeviceId = e.speakerDeviceId), typeof e.outputVolume == "number" && Number.isFinite(e.outputVolume) && (n.outputVolume = Math.max(0, Math.min(100, e.outputVolume))), typeof e.headphonesMode == "boolean" && (n.headphonesMode = e.headphonesMode), typeof e.transcriptionEnabled == "boolean" && (n.transcriptionEnabled = e.transcriptionEnabled), typeof e.textInputEnabled == "boolean" && (n.textInputEnabled = e.textInputEnabled), n;
95
+ }
96
+ async function it() {
97
+ var a;
98
+ if (!((a = navigator.mediaDevices) != null && a.enumerateDevices))
99
+ return { inputs: [], outputs: [] };
100
+ const e = await navigator.mediaDevices.enumerateDevices(), n = e.filter((i) => i.kind === "audioinput"), r = e.filter((i) => i.kind === "audiooutput");
101
+ return { inputs: n, outputs: r };
102
+ }
103
+ function ot() {
104
+ var a, i;
105
+ const e = typeof HTMLAudioElement < "u" ? HTMLAudioElement.prototype : null, n = !!(e && typeof e.setSinkId == "function");
106
+ let r = !1;
107
+ try {
108
+ const c = (i = (a = navigator.mediaDevices) == null ? void 0 : a.getSupportedConstraints) == null ? void 0 : i.call(a);
109
+ r = !!(c != null && c.voiceIsolation);
110
+ } catch {
111
+ r = !1;
112
+ }
113
+ return { setSinkIdSupported: n, voiceIsolationSupported: r };
114
+ }
115
+ class rt {
116
+ constructor() {
117
+ ie(this, "listeners", /* @__PURE__ */ new Map());
118
+ ie(this, "emit", (n, r) => {
119
+ const a = this.listeners.get(n);
120
+ if (a)
121
+ for (const i of Array.from(a))
122
+ try {
123
+ i(r);
124
+ } catch (c) {
125
+ console.error(`[voice-agent] listener for "${String(n)}" threw`, c);
126
+ }
127
+ });
128
+ }
129
+ on(n, r) {
130
+ let a = this.listeners.get(n);
131
+ return a || (a = /* @__PURE__ */ new Set(), this.listeners.set(n, a)), a.add(r), () => this.off(n, r);
132
+ }
133
+ off(n, r) {
134
+ var a;
135
+ (a = this.listeners.get(n)) == null || a.delete(r);
136
+ }
137
+ clear() {
138
+ this.listeners.clear();
139
+ }
140
+ }
141
+ function st(e, n) {
142
+ const r = e.steps;
143
+ if (!(r != null && r.length)) return -1;
144
+ for (let a = 0; a < r.length; a++)
145
+ if (r[a].fields.some((c) => c.name && n.has(c.name))) return a;
146
+ return -1;
147
+ }
148
+ function at(e) {
149
+ const { emit: n, voice: r, apiUrl: a, agentSlug: i, apiKey: c, fetch: A } = e;
150
+ let m = null, g = {}, u = 0, v = null;
151
+ const o = (d) => {
152
+ if (!m) return null;
153
+ const k = m;
154
+ return {
155
+ type: "form_state",
156
+ form_id: k.id,
157
+ is_open: d,
158
+ step_index: u,
159
+ total_steps: Z(k),
160
+ values: { ...g },
161
+ // Ship the field schema (incl. select/radio/checkbox options) so the
162
+ // agent can register enum-constrained voice-fill tools even when the
163
+ // session token has no appearance.forms entry for this form.
164
+ fields: Ge(k)
165
+ };
166
+ }, D = (d) => {
167
+ if (v !== null && (clearTimeout(v), v = null), !r.isActive()) return;
168
+ const k = d ? o(!0) : {
169
+ type: "form_state",
170
+ form_id: "",
171
+ is_open: !1,
172
+ step_index: 0,
173
+ total_steps: 0,
174
+ values: {},
175
+ fields: []
176
+ };
177
+ k && r.publishData(k, "form.state");
178
+ }, T = () => {
179
+ v !== null && clearTimeout(v), v = setTimeout(() => {
180
+ v = null, D(m !== null);
181
+ }, 250);
182
+ }, F = () => {
183
+ n("form:update", { values: { ...g }, stepIndex: u });
184
+ }, S = () => {
185
+ v !== null && (clearTimeout(v), v = null);
186
+ const d = m !== null;
187
+ m = null, g = {}, u = 0, n("form:close", {}), d && D(!1);
188
+ }, w = (d, k) => {
189
+ m = d, u = 0, g = pe(Ne(d), k ?? null), n("form:show", {
190
+ definition: d,
191
+ draft: { ...g },
192
+ stepIndex: u,
193
+ inCall: r.isActive(),
194
+ transcriptionEnabled: r.isActive() && r.getAudioState().prefs.transcriptionEnabled
195
+ }), D(!0);
196
+ }, U = (d) => {
197
+ m && (g = pe(g, d), F(), D(!0));
198
+ }, y = (d) => {
199
+ m && (Object.assign(g, d), T());
200
+ }, N = (d) => {
201
+ if (!m) return;
202
+ const k = Z(m), x = Math.max(0, Math.min(d, k - 1));
203
+ x !== u && (u = x, F(), D(!0));
204
+ }, E = () => {
205
+ !m || u === 0 || N(u - 1);
206
+ }, $ = async () => {
207
+ if (!m) return;
208
+ const d = m, k = Z(d), x = u >= k - 1, L = x ? $e(d) : Ke(d, u), G = je(L, g);
209
+ if (G.length) {
210
+ if (x && Z(d) > 1) {
211
+ const _ = st(
212
+ d,
213
+ new Set(G.map((M) => M.name))
214
+ );
215
+ _ >= 0 && _ !== u && (u = _, F());
216
+ }
217
+ n("form:validation", { errors: G }), r.isActive() && r.publishData(
218
+ {
219
+ type: "form_submit_failed",
220
+ form_id: d.id,
221
+ text: `(System: the "${d.title}" form was NOT submitted — these fields need attention: ${G.map((_) => `${_.label} (${_.message})`).join(", ")}. Ask the visitor to correct them and do not say it was submitted.)`
222
+ },
223
+ "voice.user_text"
224
+ );
225
+ return;
226
+ }
227
+ if (!x) {
228
+ u += 1, F(), D(!0);
229
+ return;
230
+ }
231
+ n("form:submitting", {});
232
+ try {
233
+ await Ve({
234
+ definition: d,
235
+ values: g,
236
+ apiUrl: a,
237
+ slug: i,
238
+ sessionId: r.sessionId(),
239
+ apiKey: c,
240
+ fetch: A
241
+ });
242
+ const _ = d.success_message ?? "Submitted. We'll be in touch shortly.";
243
+ n("form:submitted", {
244
+ formId: d.id,
245
+ values: { ...g },
246
+ successMessage: _
247
+ }), r.isActive() && r.publishData(
248
+ {
249
+ type: d.confirmation_type ?? `${d.id}_submitted`,
250
+ form_id: d.id,
251
+ text: Je(d, g),
252
+ form: { ...g }
253
+ },
254
+ d.confirmation_topic ?? "voice.user_text"
255
+ ), setTimeout(() => {
256
+ m === d && S();
257
+ }, 1500);
258
+ } catch (_) {
259
+ const M = _ instanceof Error ? _.message : "We couldn't send your request right now. Please try again.";
260
+ n("form:error", { message: M }), r.isActive() && r.publishData(
261
+ {
262
+ type: "form_submit_failed",
263
+ form_id: d.id,
264
+ text: `(System: the "${d.title}" form submission failed: ${M} Tell the visitor it didn't go through and offer to try again.)`
265
+ },
266
+ "voice.user_text"
267
+ );
268
+ }
269
+ };
270
+ return {
271
+ open: w,
272
+ merge: U,
273
+ close: S,
274
+ updateValues: y,
275
+ current: () => (m == null ? void 0 : m.id) ?? null,
276
+ getActive: () => m ? { definition: m, values: { ...g }, stepIndex: u } : null,
277
+ step: (d) => {
278
+ m && (d === "next" ? N(u + 1) : d === "back" ? E() : typeof d == "number" && N(d));
279
+ },
280
+ submit: () => {
281
+ $();
282
+ }
283
+ };
284
+ }
285
+ function lt(e, n = {}) {
286
+ var i;
287
+ const r = { ...n }, a = (i = e.apiKey) == null ? void 0 : i.trim();
288
+ return a && (r["x-api-key"] = a), r;
289
+ }
290
+ function ct(e) {
291
+ if (e) return e;
292
+ if (typeof globalThis.fetch == "function")
293
+ return globalThis.fetch.bind(globalThis);
294
+ throw new Error(
295
+ "[voice-agent] No global fetch available. Pass `fetch` in the SDK config (Node < 18)."
296
+ );
297
+ }
298
+ function ut(e) {
299
+ e && e.trim().startsWith("sk_") && typeof window < "u" && console.warn(
300
+ "[voice-agent] A secret API key (sk_…) was provided in a browser context — it is visible to anyone who views the page. For public embeds omit `apiKey` and rely on origin allow-listing; reserve `apiKey` for server-side/Node usage."
301
+ );
302
+ }
303
+ async function dt(e) {
304
+ var A;
305
+ const n = ct(e.fetch), r = e.originUrl ?? (typeof window < "u" && ((A = window.location) == null ? void 0 : A.href) || ""), a = await n(`${e.apiUrl}/api/agents/agent-session/`, {
306
+ method: "POST",
307
+ headers: lt(e, { "Content-Type": "application/json" }),
308
+ body: JSON.stringify({
309
+ agent: e.agentSlug,
310
+ origin_url: r,
311
+ language: e.language,
312
+ ...e.extra ?? {}
313
+ })
314
+ });
315
+ let i;
316
+ try {
317
+ i = await a.json();
318
+ } catch {
319
+ throw new Error(`session request failed (${a.status}): non-JSON response`);
320
+ }
321
+ if (!a.ok || (i == null ? void 0 : i.success) === !1) {
322
+ const m = (i == null ? void 0 : i.message) || `HTTP ${a.status}`;
323
+ throw new Error(`session request failed: ${m}`);
324
+ }
325
+ const c = (i == null ? void 0 : i.data) ?? i;
326
+ if (!(c != null && c.livekit_url) || !(c != null && c.token))
327
+ throw new Error(
328
+ `session response missing livekit_url/token (got keys: ${Object.keys(
329
+ c || {}
330
+ ).join(",")})`
331
+ );
332
+ return c;
333
+ }
334
+ const ft = "https://esm.sh/deepfilternet3-noise-filter@1.2.1", pt = "voiceAgent.prevContext", mt = 4e3, ht = 500, Fe = 1500, gt = 14 * 24 * 60 * 60 * 1e3;
335
+ function oe(e) {
336
+ return `${pt}.${e}`;
337
+ }
338
+ function re() {
339
+ try {
340
+ return window.localStorage;
341
+ } catch {
342
+ return null;
343
+ }
344
+ }
345
+ function vt(e) {
346
+ if (!e) return null;
347
+ const n = re();
348
+ if (!n) return null;
349
+ let r = null;
350
+ try {
351
+ r = n.getItem(oe(e));
352
+ } catch {
353
+ return null;
354
+ }
355
+ if (!r) return null;
356
+ let a;
357
+ try {
358
+ a = JSON.parse(r);
359
+ } catch {
360
+ return null;
361
+ }
362
+ if (!a || typeof a != "object") return null;
363
+ const i = a, c = typeof i.savedAt == "number" ? i.savedAt : 0;
364
+ if (!c || Date.now() - c > gt)
365
+ return _e(e), null;
366
+ const A = [];
367
+ if (Array.isArray(i.turns))
368
+ for (const g of i.turns) {
369
+ if (!g || typeof g != "object") continue;
370
+ const u = g.role, v = g.text;
371
+ if (u !== "user" && u !== "agent" || typeof v != "string") continue;
372
+ const o = v.trim();
373
+ o && A.push({ role: u, text: o });
374
+ }
375
+ const m = typeof i.summary == "string" ? i.summary.trim().slice(0, Fe) : "";
376
+ return !A.length && !m ? null : { savedAt: c, turns: A, summary: m };
377
+ }
378
+ function yt(e, n, r) {
379
+ if (!e) return;
380
+ const a = re();
381
+ if (!a) return;
382
+ const i = [];
383
+ for (const u of n) {
384
+ const v = (u.text || "").trim().slice(0, ht);
385
+ v && i.push({ role: u.role, text: v });
386
+ }
387
+ const c = i.slice(-30);
388
+ let A = c.reduce((u, v) => u + v.text.length, 0);
389
+ for (; c.length > 1 && A > mt; ) {
390
+ const u = c.shift();
391
+ u && (A -= u.text.length);
392
+ }
393
+ const m = (r || "").trim().slice(0, Fe);
394
+ if (!c.length && !m) {
395
+ _e(e);
396
+ return;
397
+ }
398
+ const g = {
399
+ savedAt: Date.now(),
400
+ turns: c,
401
+ summary: m
402
+ };
403
+ try {
404
+ a.setItem(oe(e), JSON.stringify(g));
405
+ } catch {
406
+ }
407
+ }
408
+ function _e(e) {
409
+ if (!e) return;
410
+ const n = re();
411
+ if (n)
412
+ try {
413
+ n.removeItem(oe(e));
414
+ } catch {
415
+ }
416
+ }
417
+ function bt(e) {
418
+ const n = (e.summary || "").trim();
419
+ return n ? `User profile from previous session:
420
+ ${n}` : e.turns.map(
421
+ (a) => a.role === "user" ? `User: ${a.text}` : `Assistant: ${a.text}`
422
+ ).join(`
423
+ `);
424
+ }
425
+ function St(e) {
426
+ const {
427
+ fetchSession: n,
428
+ agentSlug: r,
429
+ getAppearance: a,
430
+ emit: i,
431
+ deepFilter: c = {},
432
+ persistPrefs: A = !0
433
+ } = e, m = c.moduleUrl && c.moduleUrl.trim() || ft, g = c.cdnUrl && c.cdnUrl.trim() ? c.cdnUrl.trim() : void 0, u = c.wasmUrl && c.wasmUrl.trim() ? c.wasmUrl.trim() : void 0, v = c.onnxUrl && c.onnxUrl.trim() ? c.onnxUrl.trim() : void 0;
434
+ let o = null, D = null, T = null, F = !1, S = !1, w = null;
435
+ const U = 200;
436
+ let y = e.initialPrefs ? { ...e.initialPrefs } : Ae(r);
437
+ const N = () => {
438
+ A && nt(r, y);
439
+ };
440
+ let E = "off", $ = !1, d = !1, k = !1, x = "", L = null;
441
+ const G = 150, _ = () => {
442
+ let s;
443
+ $ ? s = "speaking" : k ? s = "thinking" : d ? s = "listening" : s = "idle", i("state", {
444
+ orb: s,
445
+ statusLabel: s === "thinking" && x || null
446
+ });
447
+ }, M = () => {
448
+ L !== null && (window.clearTimeout(L), L = null);
449
+ }, se = (s) => {
450
+ M(), k = !0, x = s || "", _();
451
+ }, ae = () => {
452
+ !k || L !== null || (L = window.setTimeout(() => {
453
+ L = null, k = !1, x = "", _();
454
+ }, G));
455
+ };
456
+ let K = null, B = null, Y = null;
457
+ const H = /* @__PURE__ */ new Map();
458
+ let R = !1, j = null, V = "", J = null;
459
+ const le = (s) => {
460
+ H.size === 0 && !(s && s.trim()) || yt(
461
+ r,
462
+ Array.from(H.values()),
463
+ s ?? V
464
+ );
465
+ }, Ie = (s, t, f, h) => {
466
+ const b = (f || "").trim();
467
+ if (!b) return;
468
+ const l = `${s}:${t}`;
469
+ h ? H.set(l, { role: s, text: b }) : H.has(l) && H.set(l, { role: s, text: b });
470
+ }, Q = () => {
471
+ B = null, Y !== null && (window.clearInterval(Y), Y = null), i("call:timer", { remainingMs: null });
472
+ }, De = () => {
473
+ M(), $ = !1, d = !1, k = !1, x = "", i("state", { orb: "idle", statusLabel: null }), i("controls", { canStart: !0, canMute: !1, canEnd: !1 }), i("mute", { muted: !1 }), F = !1, S = !1, w !== null && (window.clearTimeout(w), w = null), Q(), T && (T.remove(), T = null), E = "off", K = null;
474
+ }, xe = async (s) => {
475
+ const f = new Promise((l) => {
476
+ J = l;
477
+ });
478
+ try {
479
+ await s.localParticipant.publishData(
480
+ new TextEncoder().encode(JSON.stringify({ type: "request_summary" })),
481
+ { reliable: !0, topic: "voice.request_summary" }
482
+ );
483
+ } catch (l) {
484
+ return console.warn("[voice-agent] Failed to publish summary request:", l), J = null, V;
485
+ }
486
+ const h = new Promise(
487
+ (l) => window.setTimeout(() => l(""), 2500)
488
+ ), b = await Promise.race([f, h]);
489
+ return J = null, b || V;
490
+ }, q = async (s = !1) => {
491
+ Q(), j && (window.removeEventListener("beforeunload", j), window.removeEventListener("pagehide", j), j = null);
492
+ let t = V;
493
+ if (o && !s) {
494
+ i("call:status", { status: "Saving…" });
495
+ try {
496
+ t = await xe(o);
497
+ } catch {
498
+ t = V;
499
+ }
500
+ }
501
+ try {
502
+ o && await o.disconnect();
503
+ } finally {
504
+ o = null, D = null;
505
+ try {
506
+ le(t);
507
+ } catch {
508
+ }
509
+ De(), i("connection", { phase: "disconnected" });
510
+ }
511
+ }, ce = async (s) => {
512
+ if (R) return;
513
+ const t = vt(r);
514
+ if (!t) {
515
+ R = !0;
516
+ return;
517
+ }
518
+ const f = bt(t);
519
+ if (!f) {
520
+ R = !0;
521
+ return;
522
+ }
523
+ const h = JSON.stringify({
524
+ type: "previous_context",
525
+ text: f,
526
+ saved_at: new Date(t.savedAt).toISOString()
527
+ });
528
+ try {
529
+ await s.localParticipant.publishData(
530
+ new TextEncoder().encode(h),
531
+ {
532
+ reliable: !0,
533
+ topic: "voice.previous_context"
534
+ }
535
+ ), R = !0;
536
+ } catch (b) {
537
+ console.warn("[voice-agent] Failed to publish previous context:", b);
538
+ }
539
+ }, Ce = () => {
540
+ Q();
541
+ const s = a().max_call_seconds;
542
+ !Number.isFinite(s) || s <= 0 || (B = Date.now() + s * 1e3, i("call:timer", { remainingMs: s * 1e3 }), Y = window.setInterval(() => {
543
+ if (B === null) return;
544
+ const t = B - Date.now();
545
+ if (t <= 0) {
546
+ i("call:timer", { remainingMs: 0 }), Q(), i("call:status", { status: a().labels.call_ended }), q();
547
+ return;
548
+ }
549
+ i("call:timer", { remainingMs: t });
550
+ }, 500));
551
+ }, Ee = async () => {
552
+ i("controls", { canStart: !1, canMute: !1, canEnd: !1 }), i("transcript:clear", {}), H.clear(), R = !1, V = "", J = null, i("connection", { phase: "connecting" }), i("state", { orb: "connecting", statusLabel: null }), i("call:status", { status: a().labels.connecting });
553
+ let s;
554
+ try {
555
+ s = await n(), D = s.session_id;
556
+ } catch (t) {
557
+ i("call:status", { status: `Error: ${t.message}` }), i("error", { scope: "session", error: t }), i("controls", { canStart: !0, canMute: !1, canEnd: !1 }), i("connection", { phase: "failed", error: t.message });
558
+ return;
559
+ }
560
+ o = new Be({
561
+ adaptiveStream: !0,
562
+ dynacast: !0,
563
+ webAudioMix: !1
564
+ }), o.on(C.ConnectionStateChanged, (t) => {
565
+ t === me.Connected && (i("call:status", { status: "Connected" }), i("connection", { phase: "connected" })), t === me.Disconnected && i("call:status", { status: "Disconnected" });
566
+ }), o.on(C.AudioPlaybackStatusChanged, () => {
567
+ o != null && o.canPlaybackAudio || console.warn("[voice-agent] Audio playback blocked by browser — call room.startAudio() after a user gesture");
568
+ }), o.on(
569
+ C.TrackSubscribed,
570
+ (t, f, h) => {
571
+ t.kind === we.Kind.Audio && (T = t.attach(), T.autoplay = !0, T.setAttribute("playsinline", ""), T.style.display = "none", T.volume = Math.max(0, Math.min(1, y.outputVolume / 100)), document.body.appendChild(T), be(T, y.speakerDeviceId));
572
+ }
573
+ ), o.on(C.ActiveSpeakersChanged, (t) => {
574
+ const f = o == null ? void 0 : o.localParticipant.identity;
575
+ $ = t.some((h) => h.identity !== f), d = t.some((h) => h.identity === f), ($ || d) && (M(), k = !1, x = ""), _(), ue($);
576
+ }), o.on(
577
+ C.TranscriptionReceived,
578
+ (t, f) => {
579
+ const b = (f == null ? void 0 : f.identity) === (o == null ? void 0 : o.localParticipant.identity) ? "user" : "agent";
580
+ for (const l of t)
581
+ i("transcript", {
582
+ role: b,
583
+ segmentId: l.id,
584
+ text: l.text,
585
+ isFinal: l.final
586
+ }), Ie(b, l.id, l.text, l.final);
587
+ }
588
+ ), o.on(C.ParticipantConnected, (t) => {
589
+ !o || R || window.setTimeout(() => {
590
+ !o || R || ce(o);
591
+ }, 750);
592
+ }), o.on(
593
+ C.DataReceived,
594
+ (t, f, h, b) => {
595
+ if (b === "voice.session_summary")
596
+ try {
597
+ const l = new TextDecoder().decode(t);
598
+ if (!l) return;
599
+ let p;
600
+ try {
601
+ p = JSON.parse(l);
602
+ } catch {
603
+ p = null;
604
+ }
605
+ const I = p && typeof p == "object" && typeof p.text == "string" ? (p.text || "").trim() : l.trim();
606
+ if (!I) return;
607
+ if (V = I, J) {
608
+ const P = J;
609
+ J = null, P(I);
610
+ }
611
+ } catch (l) {
612
+ console.warn("[voice-agent] Failed to handle session summary:", l);
613
+ }
614
+ }
615
+ ), o.on(
616
+ C.DataReceived,
617
+ (t, f, h, b) => {
618
+ b === "voice.end_call" && q(!0);
619
+ }
620
+ ), o.on(
621
+ C.DataReceived,
622
+ (t, f, h, b) => {
623
+ if (b === "voice.agent_status")
624
+ try {
625
+ const l = new TextDecoder().decode(t), p = l ? JSON.parse(l) : null;
626
+ if (!p || typeof p != "object") return;
627
+ const I = String(p.state || ""), P = String(p.label || "");
628
+ I === "thinking" ? se(P) : ae();
629
+ } catch (l) {
630
+ console.debug("[voice-agent] bad agent_status payload", l);
631
+ }
632
+ }
633
+ ), o.on(
634
+ C.ParticipantAttributesChanged,
635
+ (t, f) => {
636
+ if ((f == null ? void 0 : f.identity) === (o == null ? void 0 : o.localParticipant.identity)) return;
637
+ const h = t == null ? void 0 : t["lk.agent.state"];
638
+ typeof h == "string" && (h === "thinking" ? k || se("") : h === "speaking" ? (M(), k = !1, x = "", _()) : (h === "listening" || h === "idle") && ae());
639
+ }
640
+ ), o.on(C.DataReceived, (t, f, h, b) => {
641
+ try {
642
+ const l = new TextDecoder().decode(t), p = l ? JSON.parse(l) : null;
643
+ i("data", { data: p, topic: b });
644
+ } catch (l) {
645
+ console.debug("[voice-agent] non-JSON data message ignored", l);
646
+ }
647
+ }), o.on(C.Disconnected, () => {
648
+ q();
649
+ }), o.on(
650
+ C.ParticipantDisconnected,
651
+ (t) => {
652
+ o && o.remoteParticipants.size === 0 && q(!0);
653
+ }
654
+ );
655
+ try {
656
+ if (await o.connect(s.livekit_url, s.token), await o.localParticipant.setMicrophoneEnabled(
657
+ !0,
658
+ ye(y),
659
+ {
660
+ // Opus "speech" preset — narrower band optimized for voice.
661
+ audioPreset: Ye.speech,
662
+ // DTX intentionally OFF: it skips frames during silence, which
663
+ // disrupts the steady cadence that the agent's contextual turn
664
+ // detector + Silero VAD rely on to time end-of-turn. With DTX
665
+ // on, preemptive LLM generation fires noticeably later.
666
+ dtx: !1,
667
+ // RED intentionally OFF: redundancy adds decode jitter without
668
+ // a clear win on the typical low-loss WiFi/wired path. Re-enable
669
+ // if you observe audible packet-loss artifacts.
670
+ red: !1
671
+ }
672
+ ), y.micDeviceId)
673
+ try {
674
+ await o.switchActiveDevice("audioinput", y.micDeviceId);
675
+ } catch (t) {
676
+ console.warn("[voice-agent] saved mic device unavailable:", t);
677
+ }
678
+ await ee(y.noiseFilter), Ue(), i("state", { orb: "listening", statusLabel: null }), i("call:status", { status: a().labels.listening }), i("controls", { canStart: !0, canMute: !0, canEnd: !0 }), Ce(), o.remoteParticipants.size > 0 && window.setTimeout(() => {
679
+ !o || R || ce(o);
680
+ }, 750), j = () => le(), window.addEventListener("beforeunload", j), window.addEventListener("pagehide", j);
681
+ } catch (t) {
682
+ i("call:status", { status: `Connect failed: ${t.message}` }), i("error", { scope: "connect", error: t }), await q();
683
+ }
684
+ }, ue = (s) => {
685
+ var t, f;
686
+ if (!o || F || y.headphonesMode) {
687
+ de(), S && (S = !1, (t = O(o)) == null || t.unmute());
688
+ return;
689
+ }
690
+ if (s) {
691
+ if (S || w !== null) return;
692
+ w = window.setTimeout(() => {
693
+ if (w = null, !o || F || S || y.headphonesMode) return;
694
+ const h = O(o);
695
+ h && (S = !0, h.mute());
696
+ }, U);
697
+ } else {
698
+ if (w !== null && (window.clearTimeout(w), w = null), !S) return;
699
+ S = !1, (f = O(o)) == null || f.unmute();
700
+ }
701
+ }, de = () => {
702
+ w !== null && (window.clearTimeout(w), w = null);
703
+ }, Pe = async () => {
704
+ if (!o) return F;
705
+ F = !F, de(), S = !1;
706
+ const s = O(o);
707
+ return s ? F ? await s.mute() : await s.unmute() : await o.localParticipant.setMicrophoneEnabled(!F), i("mute", { muted: F }), i("call:status", {
708
+ status: F ? a().labels.muted : a().labels.listening
709
+ }), F;
710
+ }, Me = async (s, t) => {
711
+ if (o)
712
+ try {
713
+ await o.localParticipant.publishData(
714
+ new TextEncoder().encode(JSON.stringify(s)),
715
+ { reliable: !0, topic: t }
716
+ );
717
+ } catch (f) {
718
+ console.warn("[voice-agent] failed to publish data:", f);
719
+ }
720
+ }, ee = async (s) => {
721
+ const t = o ? O(o) : null;
722
+ if (!t) {
723
+ E = s === "off" ? "off" : "failed", K = null;
724
+ return;
725
+ }
726
+ try {
727
+ await t.stopProcessor();
728
+ } catch {
729
+ }
730
+ if (K = null, s === "off") {
731
+ E = "off";
732
+ return;
733
+ }
734
+ if (s === "krisp") {
735
+ E = await Se(t);
736
+ return;
737
+ }
738
+ if (s === "deepfilter")
739
+ try {
740
+ const b = (await import(m)).DeepFilterNoiseFilterProcessor;
741
+ if (typeof b != "function")
742
+ throw new Error("DeepFilterNoiseFilterProcessor export missing");
743
+ const l = {};
744
+ g && (l.cdnUrl = g);
745
+ const p = new b({
746
+ noiseReductionLevel: y.deepFilterStrength,
747
+ assetConfig: Object.keys(l).length > 0 ? l : void 0
748
+ }), I = u, P = v, z = I || P ? globalThis.fetch.bind(globalThis) : null;
749
+ if (z) {
750
+ const Le = (W, ne) => {
751
+ const fe = typeof W == "string" ? W : W instanceof URL ? W.href : W.url;
752
+ return I && /\/df_bg\.wasm(?:$|[?#])/.test(fe) ? z(I, ne) : P && /\/DeepFilterNet3_onnx\.tar\.gz(?:$|[?#])/.test(fe) ? z(P, ne) : z(W, ne);
753
+ };
754
+ globalThis.fetch = Le;
755
+ }
756
+ try {
757
+ await t.setProcessor(
758
+ p
759
+ );
760
+ } finally {
761
+ z && (globalThis.fetch = z);
762
+ }
763
+ K = p, E = "active", console.info(
764
+ "[voice-agent] DeepFilterNet3 noise filter attached (strength=" + y.deepFilterStrength + ")"
765
+ );
766
+ } catch (f) {
767
+ console.warn(
768
+ "[voice-agent] DeepFilterNet3 unavailable, falling back to Krisp:",
769
+ f
770
+ ), E = "unsupported", await Se(t) === "active" && (E = "active");
771
+ }
772
+ }, Ue = () => {
773
+ i("audio", te());
774
+ }, te = () => {
775
+ var f;
776
+ const s = o ? O(o) : null, t = (f = s == null ? void 0 : s.mediaStreamTrack) == null ? void 0 : f.getSettings();
777
+ return {
778
+ prefs: { ...y },
779
+ applied: {
780
+ echoCancellation: t == null ? void 0 : t.echoCancellation,
781
+ noiseSuppression: t == null ? void 0 : t.noiseSuppression,
782
+ autoGainControl: t == null ? void 0 : t.autoGainControl,
783
+ voiceIsolation: t == null ? void 0 : t.voiceIsolation,
784
+ sampleRate: t == null ? void 0 : t.sampleRate,
785
+ channelCount: t == null ? void 0 : t.channelCount,
786
+ deviceId: t == null ? void 0 : t.deviceId
787
+ },
788
+ noiseFilter: {
789
+ engine: y.noiseFilter,
790
+ status: E
791
+ }
792
+ };
793
+ };
794
+ return {
795
+ start: Ee,
796
+ end: q,
797
+ toggleMute: Pe,
798
+ isActive: () => o !== null,
799
+ sessionId: () => D,
800
+ publishData: Me,
801
+ updateAudioSettings: async (s) => {
802
+ const t = { ...y, ...s }, f = o ? O(o) : null, h = [
803
+ "echoCancellation",
804
+ "noiseSuppression",
805
+ "autoGainControl",
806
+ "voiceIsolation"
807
+ ], b = {};
808
+ for (const p of h)
809
+ p in s && s[p] !== y[p] && (b[p] = t[p]);
810
+ if (f && Object.keys(b).length > 0)
811
+ try {
812
+ await f.mediaStreamTrack.applyConstraints(b);
813
+ } catch (p) {
814
+ console.warn(
815
+ "[voice-agent] applyConstraints rejected, falling back to restartTrack:",
816
+ p
817
+ );
818
+ try {
819
+ await f.restartTrack(ye(t));
820
+ } catch (I) {
821
+ console.warn("[voice-agent] restartTrack failed:", I);
822
+ }
823
+ }
824
+ if ("noiseFilter" in s && s.noiseFilter !== y.noiseFilter && (y = { ...y, noiseFilter: t.noiseFilter }, await ee(t.noiseFilter)), "deepFilterStrength" in s && s.deepFilterStrength !== y.deepFilterStrength && t.noiseFilter === "deepfilter")
825
+ if (y = { ...y, deepFilterStrength: t.deepFilterStrength }, K && typeof K.setSuppressionLevel == "function")
826
+ try {
827
+ K.setSuppressionLevel(t.deepFilterStrength);
828
+ } catch (p) {
829
+ console.warn("[voice-agent] DeepFilter setSuppressionLevel failed:", p);
830
+ }
831
+ else
832
+ await ee("deepfilter");
833
+ if ("micDeviceId" in s && s.micDeviceId !== y.micDeviceId && o)
834
+ try {
835
+ await o.switchActiveDevice("audioinput", t.micDeviceId || "default");
836
+ } catch (p) {
837
+ console.warn("[voice-agent] failed to switch mic device:", p);
838
+ }
839
+ "speakerDeviceId" in s && s.speakerDeviceId !== y.speakerDeviceId && T && await be(T, t.speakerDeviceId), "outputVolume" in s && T && (T.volume = Math.max(0, Math.min(1, t.outputVolume / 100))), "headphonesMode" in s && s.headphonesMode !== y.headphonesMode && ue(!1), y = t, N();
840
+ const l = te();
841
+ return i("audio", l), l;
842
+ },
843
+ getAudioState: te,
844
+ getAudioStats: async () => {
845
+ if (!o) return null;
846
+ const s = [], t = O(o);
847
+ if (t)
848
+ try {
849
+ const h = await t.getRTCStatsReport();
850
+ h && s.push(h);
851
+ } catch {
852
+ }
853
+ for (const h of o.remoteParticipants.values())
854
+ for (const b of h.audioTrackPublications.values()) {
855
+ const l = b.track;
856
+ if (l)
857
+ try {
858
+ const p = await l.getRTCStatsReport();
859
+ p && s.push(p);
860
+ } catch {
861
+ }
862
+ }
863
+ const f = {
864
+ outboundAudioLevel: 0,
865
+ inboundAudioLevel: 0,
866
+ packetsLost: 0,
867
+ jitter: 0,
868
+ roundTripTime: 0
869
+ };
870
+ for (const h of s)
871
+ h.forEach((b) => {
872
+ const l = b;
873
+ if (l.type === "outbound-rtp" && l.kind === "audio") {
874
+ const p = l.audioLevel;
875
+ typeof p == "number" && (f.outboundAudioLevel = p);
876
+ }
877
+ if (l.type === "inbound-rtp" && l.kind === "audio") {
878
+ const p = l.audioLevel;
879
+ typeof p == "number" && (f.inboundAudioLevel = p);
880
+ const I = l.packetsLost;
881
+ typeof I == "number" && (f.packetsLost = I);
882
+ const P = l.jitter;
883
+ typeof P == "number" && (f.jitter = P * 1e3);
884
+ }
885
+ if (l.type === "candidate-pair" && (l.selected === !0 || l.nominated === !0)) {
886
+ const p = l.currentRoundTripTime;
887
+ typeof p == "number" && (f.roundTripTime = p * 1e3);
888
+ }
889
+ });
890
+ return f;
891
+ }
892
+ };
893
+ }
894
+ function ye(e) {
895
+ return {
896
+ echoCancellation: e.echoCancellation,
897
+ noiseSuppression: e.noiseSuppression,
898
+ autoGainControl: e.autoGainControl,
899
+ voiceIsolation: e.voiceIsolation,
900
+ channelCount: 1,
901
+ sampleRate: 48e3,
902
+ deviceId: e.micDeviceId ? { ideal: e.micDeviceId } : void 0
903
+ };
904
+ }
905
+ function O(e) {
906
+ if (!e) return null;
907
+ const n = e.localParticipant.getTrackPublication(we.Source.Microphone), r = n == null ? void 0 : n.audioTrack;
908
+ return r instanceof Qe ? r : null;
909
+ }
910
+ async function be(e, n) {
911
+ const r = e.setSinkId;
912
+ if (typeof r == "function")
913
+ try {
914
+ await r.call(e, n || "");
915
+ } catch (a) {
916
+ console.warn("[voice-agent] setSinkId failed:", a);
917
+ }
918
+ }
919
+ async function Se(e) {
920
+ const { KrispNoiseFilter: n, isKrispNoiseFilterSupported: r } = await import("@livekit/krisp-noise-filter");
921
+ if (!r())
922
+ return console.warn(
923
+ "[voice-agent] Krisp noise filter NOT supported in this browser — relying on browser noiseSuppression only"
924
+ ), "unsupported";
925
+ try {
926
+ return await e.setProcessor(n()), console.info("[voice-agent] Krisp noise filter attached"), "active";
927
+ } catch (a) {
928
+ return console.warn("[voice-agent] Failed to attach Krisp noise filter:", a), "failed";
929
+ }
930
+ }
931
+ const wt = "https://api.oshara.ai";
932
+ function It(e) {
933
+ e.agentSlug || console.error("[voice-agent] agentSlug is required"), ut(e.apiKey);
934
+ const n = e.apiUrl ?? wt, r = e.persistAudioPrefs ?? !0;
935
+ let a = e.language ?? "en";
936
+ const i = new rt(), c = i.emit, A = {
937
+ ...X,
938
+ ...r ? Ae(e.agentSlug) : {},
939
+ ...e.audio ?? {}
940
+ };
941
+ let m = We;
942
+ const g = () => m, u = St({
943
+ fetchSession: () => dt({
944
+ apiUrl: n,
945
+ agentSlug: e.agentSlug,
946
+ language: a,
947
+ apiKey: e.apiKey,
948
+ fetch: e.fetch
949
+ }),
950
+ agentSlug: e.agentSlug,
951
+ getAppearance: g,
952
+ emit: c,
953
+ deepFilter: e.deepFilter,
954
+ initialPrefs: A,
955
+ persistPrefs: r
956
+ }), v = at({
957
+ emit: c,
958
+ voice: u,
959
+ apiUrl: n,
960
+ agentSlug: e.agentSlug,
961
+ apiKey: e.apiKey,
962
+ fetch: e.fetch
963
+ });
964
+ i.on("data", ({ data: S, topic: w }) => {
965
+ if (w === "voice.agent_handoff") {
966
+ const N = S && typeof S == "object" && typeof S.agent_name == "string" ? (S.agent_name || "").trim() : "";
967
+ c("agent:handoff", { agentName: N });
968
+ return;
969
+ }
970
+ if (He(w, S, v)) return;
971
+ const U = qe(w, S, g().forms);
972
+ if (!U) return;
973
+ const y = ze(S, U) ?? {};
974
+ v.current() === U.id ? v.merge(y) : v.open(U, y);
975
+ });
976
+ const o = (S, w = {}) => et(
977
+ {
978
+ apiUrl: n,
979
+ agentSlug: e.agentSlug,
980
+ apiKey: e.apiKey,
981
+ fetch: e.fetch,
982
+ disabled: e.disableAnalytics
983
+ },
984
+ S,
985
+ w
986
+ );
987
+ let D = !1;
988
+ const T = async () => (!D && (e.fetchAppearanceOnInit ?? !0) && (m = await Xe({
989
+ appearanceUrl: e.appearanceUrl ?? "",
990
+ apiUrl: n,
991
+ slug: e.agentSlug,
992
+ apiKey: e.apiKey,
993
+ fetch: e.fetch
994
+ })), D = !0, c("appearance", m), { appearance: m }), F = () => {
995
+ u.isActive() && u.end(), i.clear();
996
+ };
997
+ return {
998
+ agentSlug: e.agentSlug,
999
+ init: T,
1000
+ start: u.start,
1001
+ end: u.end,
1002
+ destroy: F,
1003
+ toggleMute: u.toggleMute,
1004
+ isActive: u.isActive,
1005
+ sessionId: u.sessionId,
1006
+ sendText: async (S) => {
1007
+ const w = (S || "").trim();
1008
+ !w || !u.isActive() || (c("transcript", {
1009
+ role: "user",
1010
+ segmentId: `typed-${Date.now()}`,
1011
+ text: w,
1012
+ isFinal: !0
1013
+ }), await u.publishData({ type: "user_text", text: w }, "voice.user_text"));
1014
+ },
1015
+ publishData: u.publishData,
1016
+ updateAudioSettings: u.updateAudioSettings,
1017
+ getAudioState: u.getAudioState,
1018
+ getAudioStats: u.getAudioStats,
1019
+ enumerateAudioDevices: it,
1020
+ getAudioCapabilities: ot,
1021
+ getActiveForm: v.getActive,
1022
+ updateFormValues: v.updateValues,
1023
+ stepForm: v.step,
1024
+ submitForm: v.submit,
1025
+ closeForm: v.close,
1026
+ openForm: v.open,
1027
+ getAppearance: g,
1028
+ setLanguage: (S) => {
1029
+ a = S || "en";
1030
+ },
1031
+ getLanguage: () => a,
1032
+ trackEvent: o,
1033
+ on: i.on.bind(i),
1034
+ off: i.off.bind(i)
1035
+ };
1036
+ }
1037
+ export {
1038
+ X as D,
1039
+ rt as E,
1040
+ ft as a,
1041
+ lt as b,
1042
+ _e as c,
1043
+ at as d,
1044
+ It as e,
1045
+ St as f,
1046
+ it as g,
1047
+ dt as h,
1048
+ bt as i,
1049
+ Ze as j,
1050
+ vt as k,
1051
+ Ae as l,
1052
+ yt as m,
1053
+ ot as p,
1054
+ nt as s,
1055
+ et as t,
1056
+ ut as w
1057
+ };
1058
+ //# sourceMappingURL=createVoiceAgent-BM3HODS6.js.map