avin-ai 0.2.4 → 0.2.6
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/avin-ai.es.js +247 -234
- package/dist/avin-ai.js +20 -20
- package/dist/avin-ai.umd.js +20 -20
- package/dist/index.d.ts +3 -1
- package/package.json +1 -1
package/dist/avin-ai.es.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
var W = Object.defineProperty;
|
|
2
2
|
var X = (l, t, e) => t in l ? W(l, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : l[t] = e;
|
|
3
|
-
var
|
|
3
|
+
var o = (l, t, e) => X(l, typeof t != "symbol" ? t + "" : t, e);
|
|
4
4
|
class b {
|
|
5
5
|
constructor(t) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
o(this, "serverUrl");
|
|
7
|
+
o(this, "agentId");
|
|
8
|
+
o(this, "callId");
|
|
9
|
+
o(this, "onConnected");
|
|
10
|
+
o(this, "onDisconnected");
|
|
11
|
+
o(this, "onError");
|
|
12
|
+
o(this, "onTranscription");
|
|
13
13
|
// @ts-ignore
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
o(this, "onRemoteTrack");
|
|
15
|
+
o(this, "onClientToolCall");
|
|
16
|
+
o(this, "pc", null);
|
|
17
|
+
o(this, "dataChannel", null);
|
|
18
|
+
o(this, "audioElement", null);
|
|
19
|
+
o(this, "connected", !1);
|
|
20
|
+
o(this, "iceServers");
|
|
21
|
+
o(this, "token");
|
|
22
22
|
if (!t.serverUrl) throw new Error("serverUrl is required");
|
|
23
23
|
if (!t.agentId) throw new Error("agentId is required");
|
|
24
24
|
this.serverUrl = t.serverUrl.replace(/\/$/, ""), this.agentId = t.agentId, this.callId = t.callId || this.generateCallId(), this.iceServers = t.iceServers, this.token = t.token, this.onConnected = t.onConnected || (() => {
|
|
@@ -86,12 +86,10 @@ class b {
|
|
|
86
86
|
const a = new TextDecoder().decode(r.data);
|
|
87
87
|
try {
|
|
88
88
|
const A = JSON.parse(a);
|
|
89
|
-
console.log("[OvinAI] Decoded JSON from binary
|
|
89
|
+
console.log("[OvinAI] Decoded JSON from binary:", A), A && typeof A == "object" && A.event && this.handleControlEvent(A);
|
|
90
90
|
} catch {
|
|
91
|
-
console.log("[OvinAI] Decoded String from binary:", a);
|
|
92
91
|
}
|
|
93
92
|
} catch {
|
|
94
|
-
console.log("[OvinAI] Received binary data:", r.data.byteLength, "bytes (not decodable)");
|
|
95
93
|
}
|
|
96
94
|
else r.data instanceof Blob && r.data.text().then((a) => {
|
|
97
95
|
try {
|
|
@@ -102,14 +100,14 @@ class b {
|
|
|
102
100
|
});
|
|
103
101
|
}, this.dataChannel.onerror = (r) => console.error("❌ [WebRTC] DataChannel error:", r), this.pc.ontrack = (r) => {
|
|
104
102
|
const a = r.track, A = r.streams[0];
|
|
105
|
-
console.log(`📥 [WebRTC] Received ${a.kind} track`), a.kind === "audio" ? (console.log("🔊 [WebRTC] Received audio track from server"), this.audioElement = new Audio(), this.audioElement.srcObject = A, this.audioElement.play().catch((
|
|
103
|
+
console.log(`📥 [WebRTC] Received ${a.kind} track`), a.kind === "audio" ? (console.log("🔊 [WebRTC] Received audio track from server"), this.audioElement = new Audio(), this.audioElement.srcObject = A, this.audioElement.play().catch((h) => console.warn("Audio autoplay blocked:", h)), this.audioElement.onended = () => {
|
|
106
104
|
this.sendEvent("playedStream"), console.log("✅ [WebRTC] TTS playback complete");
|
|
107
105
|
}) : a.kind === "video" && (console.log("📹 [WebRTC] Video track received"), this.onRemoteTrack(a, A));
|
|
108
106
|
};
|
|
109
107
|
const e = () => {
|
|
110
|
-
var A,
|
|
111
|
-
console.log("🔄 [WebRTC] State:", (A = this.pc) == null ? void 0 : A.connectionState, "| ICE:", (
|
|
112
|
-
const r = ((
|
|
108
|
+
var A, h, c, u, g, C, v, B, f, m, w;
|
|
109
|
+
console.log("🔄 [WebRTC] State:", (A = this.pc) == null ? void 0 : A.connectionState, "| ICE:", (h = this.pc) == null ? void 0 : h.iceConnectionState);
|
|
110
|
+
const r = ((c = this.pc) == null ? void 0 : c.connectionState) === "connected" || ((u = this.pc) == null ? void 0 : u.iceConnectionState) === "connected" || ((g = this.pc) == null ? void 0 : g.iceConnectionState) === "completed", a = ((C = this.pc) == null ? void 0 : C.connectionState) === "failed" || ((v = this.pc) == null ? void 0 : v.iceConnectionState) === "failed" || ((B = this.pc) == null ? void 0 : B.connectionState) === "closed" || ((f = this.pc) == null ? void 0 : f.iceConnectionState) === "closed" || ((m = this.pc) == null ? void 0 : m.connectionState) === "disconnected" || ((w = this.pc) == null ? void 0 : w.iceConnectionState) === "disconnected";
|
|
113
111
|
r && !this.connected ? (this.connected = !0, this.onConnected()) : a && this.connected && (this.connected = !1, this.onDisconnected());
|
|
114
112
|
};
|
|
115
113
|
this.pc.onconnectionstatechange = e, this.pc.oniceconnectionstatechange = e;
|
|
@@ -128,8 +126,8 @@ class b {
|
|
|
128
126
|
const r = await n.json();
|
|
129
127
|
throw new Error(r.error || `HTTP ${n.status}`);
|
|
130
128
|
}
|
|
131
|
-
const { answer:
|
|
132
|
-
console.log("📥 [WebRTC] Received answer from server"), await this.pc.setRemoteDescription(
|
|
129
|
+
const { answer: s } = await n.json();
|
|
130
|
+
console.log("📥 [WebRTC] Received answer from server"), await this.pc.setRemoteDescription(s), console.log("✅ [WebRTC] Connection established!");
|
|
133
131
|
} catch (t) {
|
|
134
132
|
throw console.error("❌ [WebRTC] Connection failed:", t), this.disconnect(), this.onError(t.message || t), t;
|
|
135
133
|
}
|
|
@@ -225,7 +223,7 @@ class b {
|
|
|
225
223
|
static async fetchIceServers(t, e = "https://coredb.travelr.club/v1/graphql") {
|
|
226
224
|
var i;
|
|
227
225
|
try {
|
|
228
|
-
const
|
|
226
|
+
const s = await fetch(e, {
|
|
229
227
|
method: "POST",
|
|
230
228
|
headers: {
|
|
231
229
|
"Content-Type": "application/json",
|
|
@@ -240,9 +238,9 @@ class b {
|
|
|
240
238
|
}
|
|
241
239
|
}` })
|
|
242
240
|
});
|
|
243
|
-
if (!
|
|
241
|
+
if (!s.ok)
|
|
244
242
|
throw new Error("Failed to fetch ICE servers");
|
|
245
|
-
return ((i = (await
|
|
243
|
+
return ((i = (await s.json()).data) == null ? void 0 : i.ice_servers) || [];
|
|
246
244
|
} catch (n) {
|
|
247
245
|
throw console.error("[WebRTC] Failed to fetch ICE servers:", n), n;
|
|
248
246
|
}
|
|
@@ -251,10 +249,10 @@ class b {
|
|
|
251
249
|
const F = { BASE_URL: "/", DEV: !1, MODE: "production", PROD: !0, SSR: !1 };
|
|
252
250
|
class V {
|
|
253
251
|
constructor(t) {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
252
|
+
o(this, "config");
|
|
253
|
+
o(this, "_status", "idle");
|
|
254
|
+
o(this, "client", null);
|
|
255
|
+
o(this, "listeners", /* @__PURE__ */ new Map());
|
|
258
256
|
if (!t.agentId) throw new Error("[AvinAI] agentId is required");
|
|
259
257
|
this.config = t;
|
|
260
258
|
}
|
|
@@ -440,7 +438,7 @@ class K {
|
|
|
440
438
|
if (!a)
|
|
441
439
|
throw new Error(`Widget configuration not found for ID: ${t}`);
|
|
442
440
|
if (a.client_id) {
|
|
443
|
-
const
|
|
441
|
+
const c = await (await fetch(k, {
|
|
444
442
|
method: "POST",
|
|
445
443
|
headers: { "Content-Type": "application/json" },
|
|
446
444
|
body: JSON.stringify({
|
|
@@ -454,17 +452,17 @@ class K {
|
|
|
454
452
|
variables: { id: a.client_id }
|
|
455
453
|
})
|
|
456
454
|
})).json();
|
|
457
|
-
(n =
|
|
455
|
+
(n = c.data) != null && n.client_by_pk && (a.client = c.data.client_by_pk);
|
|
458
456
|
}
|
|
459
457
|
return a;
|
|
460
|
-
} catch (
|
|
461
|
-
throw console.error("[AvinAI] Failed to fetch widget config:",
|
|
458
|
+
} catch (s) {
|
|
459
|
+
throw console.error("[AvinAI] Failed to fetch widget config:", s), s;
|
|
462
460
|
}
|
|
463
461
|
}
|
|
464
462
|
}
|
|
465
463
|
const P = "https://coredb.travelr.club/v1/graphql";
|
|
466
464
|
let x = "https://inboxapi.travelr.club";
|
|
467
|
-
class
|
|
465
|
+
class y {
|
|
468
466
|
static setChatUrl(t) {
|
|
469
467
|
x = t;
|
|
470
468
|
}
|
|
@@ -490,15 +488,15 @@ class C {
|
|
|
490
488
|
})
|
|
491
489
|
})).json();
|
|
492
490
|
return r.errors ? (console.warn("[AvinAI] Prospect creation failed, using anonymous ID", r.errors), `anon_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`) : ((n = (i = r.data) == null ? void 0 : i.insert_prospects_one) == null ? void 0 : n.id) || `anon_${Date.now()}`;
|
|
493
|
-
} catch (
|
|
494
|
-
return console.error("[AvinAI] Failed to create prospect:",
|
|
491
|
+
} catch (s) {
|
|
492
|
+
return console.error("[AvinAI] Failed to create prospect:", s), `anon_${Date.now()}`;
|
|
495
493
|
}
|
|
496
494
|
}
|
|
497
495
|
// Calls the new Go bridge /widget/chat endpoint with an empty message to initialize the session and get the Welcome config + inbox_id
|
|
498
496
|
static async fetchWelcomeMessage(t, e) {
|
|
499
497
|
var i, n;
|
|
500
498
|
try {
|
|
501
|
-
const
|
|
499
|
+
const s = await fetch(`${x}/widget/chat`, {
|
|
502
500
|
method: "POST",
|
|
503
501
|
headers: { "Content-Type": "application/json" },
|
|
504
502
|
body: JSON.stringify({
|
|
@@ -508,90 +506,102 @@ class C {
|
|
|
508
506
|
stream: !1
|
|
509
507
|
})
|
|
510
508
|
});
|
|
511
|
-
if (!
|
|
512
|
-
const r = await
|
|
509
|
+
if (!s.ok) throw new Error("Failed to fetch welcome message");
|
|
510
|
+
const r = await s.json();
|
|
513
511
|
let a = r.response || "Hello! How can I help you today?", A;
|
|
514
|
-
const
|
|
512
|
+
const h = r.chat_id || r.inbox_id;
|
|
515
513
|
if (r.widget) {
|
|
516
514
|
A = r.widget;
|
|
517
|
-
const
|
|
518
|
-
A.type === "carousel" && ((i = A.data) != null && i.cards) ?
|
|
515
|
+
const c = { text: a };
|
|
516
|
+
A.type === "carousel" && ((i = A.data) != null && i.cards) ? c.cards = A.data.cards : A.type === "button_list" && ((n = A.data) != null && n.buttons) && (c.buttons = A.data.buttons), a = JSON.stringify(c);
|
|
519
517
|
}
|
|
520
|
-
return { role: "assistant", content: a, widget: A, chatId:
|
|
521
|
-
} catch (
|
|
522
|
-
return console.error("[AvinAI] Failed to fetch welcome message:",
|
|
518
|
+
return { role: "assistant", content: a, widget: A, chatId: h };
|
|
519
|
+
} catch (s) {
|
|
520
|
+
return console.error("[AvinAI] Failed to fetch welcome message:", s), { role: "assistant", content: "Hello! How can I help you today?" };
|
|
523
521
|
}
|
|
524
522
|
}
|
|
525
|
-
static async sendChatMessage(t, e, i, n,
|
|
526
|
-
var A,
|
|
523
|
+
static async sendChatMessage(t, e, i, n, s, r, a) {
|
|
524
|
+
var A, h, c, u;
|
|
527
525
|
try {
|
|
528
|
-
const
|
|
526
|
+
const g = {
|
|
529
527
|
agent_id: t,
|
|
530
528
|
message: i,
|
|
531
529
|
prospect_id: e,
|
|
532
530
|
stream: !0
|
|
533
531
|
};
|
|
534
|
-
n && (
|
|
535
|
-
const
|
|
532
|
+
n && (g.inbox_id = n);
|
|
533
|
+
const C = await fetch(`${x}/widget/chat`, {
|
|
536
534
|
method: "POST",
|
|
537
535
|
headers: { "Content-Type": "application/json" },
|
|
538
|
-
body: JSON.stringify(
|
|
536
|
+
body: JSON.stringify(g)
|
|
539
537
|
});
|
|
540
|
-
if (!
|
|
541
|
-
const v = (A =
|
|
538
|
+
if (!C.ok) throw new Error("Chat request failed");
|
|
539
|
+
const v = (A = C.body) == null ? void 0 : A.getReader(), B = new TextDecoder();
|
|
542
540
|
if (!v) throw new Error("No reader");
|
|
543
|
-
let f = "",
|
|
541
|
+
let f = "", m = "", w = null;
|
|
544
542
|
for (; ; ) {
|
|
545
543
|
const { done: R, value: O } = await v.read();
|
|
546
544
|
if (R) break;
|
|
547
|
-
|
|
548
|
-
const Q =
|
|
545
|
+
m += B.decode(O, { stream: !0 });
|
|
546
|
+
const Q = m.split(`
|
|
549
547
|
`);
|
|
550
|
-
|
|
548
|
+
m = Q.pop() || "";
|
|
551
549
|
for (const U of Q) {
|
|
552
550
|
const I = U.trim();
|
|
553
551
|
if (I && I.startsWith("data: ")) {
|
|
554
552
|
const D = I.slice(6);
|
|
555
553
|
if (D === "[DONE]") {
|
|
556
|
-
a(
|
|
554
|
+
a(w);
|
|
557
555
|
return;
|
|
558
556
|
}
|
|
559
557
|
try {
|
|
560
|
-
const
|
|
561
|
-
if (
|
|
562
|
-
|
|
558
|
+
const p = JSON.parse(D);
|
|
559
|
+
if (p.type === "metadata" && p.chat_id) {
|
|
560
|
+
w = p.chat_id;
|
|
563
561
|
continue;
|
|
564
562
|
}
|
|
565
|
-
const M = (
|
|
566
|
-
M && (f += M,
|
|
563
|
+
const M = (u = (c = (h = p.choices) == null ? void 0 : h[0]) == null ? void 0 : c.delta) == null ? void 0 : u.content;
|
|
564
|
+
M && (f += M, s(f)), p.widget && r(p.widget), p.chat_id && !w && (w = p.chat_id);
|
|
567
565
|
} catch {
|
|
568
566
|
}
|
|
569
567
|
}
|
|
570
568
|
}
|
|
571
569
|
}
|
|
572
|
-
a(
|
|
573
|
-
} catch (
|
|
574
|
-
console.error("[AvinAI] Chat error:",
|
|
570
|
+
a(w);
|
|
571
|
+
} catch (g) {
|
|
572
|
+
console.error("[AvinAI] Chat error:", g), s("Sorry, I encountered an error. Please try again."), a(null);
|
|
575
573
|
}
|
|
576
574
|
}
|
|
577
575
|
static listenForAdminReplies(t, e, i) {
|
|
578
|
-
const n =
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
576
|
+
const n = `${x}/inbox/stream?inbox_id=${t}&sender=${encodeURIComponent(e)}`;
|
|
577
|
+
let s = null, r = 0, a = !1;
|
|
578
|
+
const A = () => {
|
|
579
|
+
a || (s = new EventSource(n), console.log(`[AvinAI] Subscribed to SSE EventSource at ${s.url}`), s.onopen = () => {
|
|
580
|
+
console.log("[AvinAI] SSE connection opened successfully."), r = 0;
|
|
581
|
+
}, s.onmessage = (h) => {
|
|
582
|
+
console.log("[AvinAI] 📡 Raw SSE Event triggered:", h.data);
|
|
583
|
+
try {
|
|
584
|
+
const c = JSON.parse(h.data);
|
|
585
|
+
console.log("[AvinAI] SSE stream JSON parsed:", c);
|
|
586
|
+
const u = c.direction === "outgoing", g = !!c.content, C = c.source !== "ai";
|
|
587
|
+
u && g && C && (console.log("[AvinAI] 🎯 Displaying admin message in chat UI:", c.content), i(c.content));
|
|
588
|
+
} catch (c) {
|
|
589
|
+
console.error("[AvinAI] SSE parse error", c);
|
|
590
|
+
}
|
|
591
|
+
}, s.onerror = (h) => {
|
|
592
|
+
if (console.error("[AvinAI] SSE connection error or disconnect", h), s && (s.close(), s = null), a) return;
|
|
593
|
+
const c = Math.min(2e3 * Math.pow(2, r), 3e4);
|
|
594
|
+
console.log(`[AvinAI] Reconnecting SSE in ${c}ms (Attempt ${r + 1})...`), r++, setTimeout(A, c);
|
|
595
|
+
});
|
|
596
|
+
};
|
|
597
|
+
return A(), {
|
|
598
|
+
close: () => {
|
|
599
|
+
a = !0, s && (s.close(), s = null, console.log("[AvinAI] SSE connection manually closed."));
|
|
588
600
|
}
|
|
589
|
-
}
|
|
590
|
-
console.error("[AvinAI] SSE connection error or disconnect", o);
|
|
591
|
-
}, n;
|
|
601
|
+
};
|
|
592
602
|
}
|
|
593
603
|
static async createCall(t, e, i) {
|
|
594
|
-
var
|
|
604
|
+
var s, r;
|
|
595
605
|
const n = `
|
|
596
606
|
mutation CreateCall($object: calls_insert_input!) {
|
|
597
607
|
insert_calls_one(object: $object) {
|
|
@@ -617,7 +627,7 @@ class C {
|
|
|
617
627
|
}
|
|
618
628
|
})
|
|
619
629
|
})).json();
|
|
620
|
-
return A.errors ? (console.warn("[AvinAI] Call creation failed", A.errors), `web_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`) : ((r = (
|
|
630
|
+
return A.errors ? (console.warn("[AvinAI] Call creation failed", A.errors), `web_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`) : ((r = (s = A.data) == null ? void 0 : s.insert_calls_one) == null ? void 0 : r.id) || `web_${Date.now()}`;
|
|
621
631
|
} catch (a) {
|
|
622
632
|
return console.error("[AvinAI] Failed to create call:", a), `web_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`;
|
|
623
633
|
}
|
|
@@ -625,8 +635,8 @@ class C {
|
|
|
625
635
|
}
|
|
626
636
|
class Z {
|
|
627
637
|
constructor(t) {
|
|
628
|
-
|
|
629
|
-
|
|
638
|
+
o(this, "config");
|
|
639
|
+
o(this, "root", null);
|
|
630
640
|
this.config = t;
|
|
631
641
|
}
|
|
632
642
|
async initialize(t) {
|
|
@@ -1187,7 +1197,7 @@ const T = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAA
|
|
|
1187
1197
|
border-radius: 0;
|
|
1188
1198
|
}
|
|
1189
1199
|
}
|
|
1190
|
-
`,
|
|
1200
|
+
`, d = {
|
|
1191
1201
|
phone: `
|
|
1192
1202
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1193
1203
|
<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>
|
|
@@ -1431,8 +1441,8 @@ const T = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAA
|
|
|
1431
1441
|
`
|
|
1432
1442
|
}, E = {
|
|
1433
1443
|
...z,
|
|
1434
|
-
default_chat:
|
|
1435
|
-
default_voice:
|
|
1444
|
+
default_chat: d.chat,
|
|
1445
|
+
default_voice: d.mic,
|
|
1436
1446
|
male: `<img src="${T}" style="width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block;" />`,
|
|
1437
1447
|
female: `<img src="${H}" style="width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block;" />`
|
|
1438
1448
|
};
|
|
@@ -1480,9 +1490,9 @@ overflow: hidden;
|
|
|
1480
1490
|
`;
|
|
1481
1491
|
});
|
|
1482
1492
|
class Y {
|
|
1483
|
-
constructor(t, e =
|
|
1484
|
-
|
|
1485
|
-
|
|
1493
|
+
constructor(t, e = d.chat) {
|
|
1494
|
+
o(this, "element");
|
|
1495
|
+
o(this, "iconContainer");
|
|
1486
1496
|
this.onClick = t, this.element = document.createElement("button"), this.element.className = "widget-fab", this.element.onclick = this.onClick, this.iconContainer = document.createElement("div"), this.iconContainer.style.display = "flex", this.iconContainer.style.alignItems = "center", this.iconContainer.style.justifyContent = "center", this.iconContainer.style.width = "100%", this.iconContainer.style.height = "100%", this.iconContainer.innerHTML = e, this.element.appendChild(this.iconContainer);
|
|
1487
1497
|
}
|
|
1488
1498
|
getElement() {
|
|
@@ -1530,18 +1540,18 @@ class Y {
|
|
|
1530
1540
|
`;
|
|
1531
1541
|
}
|
|
1532
1542
|
}
|
|
1533
|
-
class
|
|
1543
|
+
class S {
|
|
1534
1544
|
constructor(t, e = "Assistant") {
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1545
|
+
o(this, "element");
|
|
1546
|
+
o(this, "header");
|
|
1547
|
+
o(this, "titleElement");
|
|
1548
|
+
o(this, "contentArea");
|
|
1549
|
+
o(this, "maximizeBtn");
|
|
1550
|
+
o(this, "closeBtn");
|
|
1551
|
+
o(this, "isMaximized", !1);
|
|
1542
1552
|
this.onClose = t, this.title = e, this.element = document.createElement("div"), this.element.className = "widget-panel hidden", this.header = document.createElement("div"), this.header.className = "widget-header", this.titleElement = document.createElement("h3"), this.titleElement.className = "widget-title", this.titleElement.textContent = this.title;
|
|
1543
1553
|
const i = document.createElement("div");
|
|
1544
|
-
i.style.display = "flex", i.style.alignItems = "center", i.style.gap = "8px", this.maximizeBtn = document.createElement("button"), this.maximizeBtn.className = "close-btn", this.maximizeBtn.innerHTML =
|
|
1554
|
+
i.style.display = "flex", i.style.alignItems = "center", i.style.gap = "8px", this.maximizeBtn = document.createElement("button"), this.maximizeBtn.className = "close-btn", this.maximizeBtn.innerHTML = d.maximize2, this.maximizeBtn.onclick = () => this.toggleMaximize(), this.closeBtn = document.createElement("button"), this.closeBtn.className = "close-btn", this.closeBtn.innerHTML = d.close, this.closeBtn.onclick = this.onClose, i.appendChild(this.maximizeBtn), i.appendChild(this.closeBtn), this.header.appendChild(this.titleElement), this.header.appendChild(i), this.contentArea = document.createElement("div"), this.contentArea.className = "widget-body", this.contentArea.style.flex = "1", this.contentArea.style.display = "flex", this.contentArea.style.flexDirection = "column", this.contentArea.style.overflow = "hidden", this.contentArea.style.padding = "0", this.element.appendChild(this.header), this.element.appendChild(this.contentArea);
|
|
1545
1555
|
}
|
|
1546
1556
|
getElement() {
|
|
1547
1557
|
return this.element;
|
|
@@ -1562,7 +1572,7 @@ class G {
|
|
|
1562
1572
|
this.element.classList.add("hidden");
|
|
1563
1573
|
}
|
|
1564
1574
|
toggleMaximize() {
|
|
1565
|
-
this.isMaximized = !this.isMaximized, this.element.style.width = this.isMaximized ? "605px" : "380px", this.maximizeBtn.innerHTML = this.isMaximized ?
|
|
1575
|
+
this.isMaximized = !this.isMaximized, this.element.style.width = this.isMaximized ? "605px" : "380px", this.maximizeBtn.innerHTML = this.isMaximized ? d.minimize2 : d.maximize2;
|
|
1566
1576
|
}
|
|
1567
1577
|
static get styles() {
|
|
1568
1578
|
return `
|
|
@@ -1572,35 +1582,35 @@ class G {
|
|
|
1572
1582
|
}
|
|
1573
1583
|
class J {
|
|
1574
1584
|
constructor(t, e = "#6366f1", i = "#a855f7") {
|
|
1575
|
-
|
|
1585
|
+
o(this, "element");
|
|
1576
1586
|
// Layout Containers
|
|
1577
|
-
|
|
1578
|
-
|
|
1587
|
+
o(this, "contentContainer");
|
|
1588
|
+
o(this, "footerContainer");
|
|
1579
1589
|
// Voice Mode Elements
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1590
|
+
o(this, "waveContainer");
|
|
1591
|
+
o(this, "waveLayers", []);
|
|
1592
|
+
o(this, "connectingSpinner");
|
|
1583
1593
|
// Avatar Mode Elements
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1594
|
+
o(this, "videoContainer");
|
|
1595
|
+
o(this, "videoElement");
|
|
1596
|
+
o(this, "statusBadge");
|
|
1597
|
+
o(this, "prepareBadge");
|
|
1588
1598
|
// "AGENT IS ON THE WAY..."
|
|
1589
1599
|
// Common Elements
|
|
1590
|
-
|
|
1600
|
+
o(this, "statusText");
|
|
1591
1601
|
// For Voice Mode
|
|
1592
|
-
|
|
1602
|
+
o(this, "timerElement");
|
|
1593
1603
|
// For Voice Mode
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1604
|
+
o(this, "transcriptionElement");
|
|
1605
|
+
o(this, "hangupBtn");
|
|
1606
|
+
o(this, "startTime", null);
|
|
1607
|
+
o(this, "timerInterval", null);
|
|
1608
|
+
o(this, "isAvatarMode", !1);
|
|
1599
1609
|
this.onHangup = t, this.primaryColor = e, this.secondaryColor = i, this.element = document.createElement("div"), this.element.id = "voice-active-overlay", this.element.style.position = "absolute", this.element.style.top = "0", this.element.style.left = "0", this.element.style.width = "100%", this.element.style.height = "100%", this.element.style.background = "transparent", this.element.style.pointerEvents = "none", this.element.style.zIndex = "60", this.element.style.display = "none", this.element.style.flexDirection = "column", this.element.style.alignItems = "center", this.contentContainer = document.createElement("div"), this.contentContainer.style.flex = "1", this.contentContainer.style.display = "flex", this.contentContainer.style.flexDirection = "column", this.contentContainer.style.alignItems = "center", this.contentContainer.style.justifyContent = "center", this.contentContainer.style.width = "100%", this.contentContainer.style.padding = "20px", this.contentContainer.style.paddingBottom = "20px", this.videoContainer = document.createElement("div"), this.videoContainer.style.position = "relative", this.videoContainer.style.width = "100%", this.videoContainer.style.maxWidth = "300px", this.videoContainer.style.aspectRatio = "1/1", this.videoContainer.style.marginBottom = "16px", this.videoContainer.style.overflow = "hidden", this.videoContainer.style.borderRadius = "16px", this.videoContainer.style.boxShadow = "0 25px 50px -12px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(17, 24, 39, 0.05)", this.videoContainer.style.display = "none", this.videoContainer.style.pointerEvents = "auto", this.videoElement = document.createElement("video"), this.videoElement.style.width = "100%", this.videoElement.style.height = "100%", this.videoElement.style.objectFit = "cover", this.videoElement.style.backgroundColor = "transparent", this.videoElement.autoplay = !0, this.videoElement.playsInline = !0, this.videoElement.muted = !0, this.videoContainer.appendChild(this.videoElement), this.contentContainer.appendChild(this.videoContainer), this.waveContainer = document.createElement("div"), this.waveContainer.style.position = "relative", this.waveContainer.style.width = "200px", this.waveContainer.style.height = "200px", this.waveContainer.style.display = "flex", this.waveContainer.style.alignItems = "center", this.waveContainer.style.justifyContent = "center", this.waveContainer.style.marginBottom = "24px", this.waveContainer.style.pointerEvents = "auto", this.createWaveLayers(), this.contentContainer.appendChild(this.waveContainer), this.statusText = document.createElement("div"), this.statusText.className = "voice-status-text", this.statusText.style.fontSize = "18px", this.statusText.textContent = "Connecting...", this.contentContainer.appendChild(this.statusText), this.timerElement = document.createElement("div"), this.timerElement.className = "voice-status-subtext", this.timerElement.style.fontSize = "14px", this.timerElement.style.marginTop = "4px", this.contentContainer.appendChild(this.timerElement), this.statusBadge = document.createElement("div"), this.statusBadge.style.display = "none", this.statusBadge.style.alignItems = "center", this.statusBadge.style.gap = "8px", this.statusBadge.style.padding = "6px 16px", this.statusBadge.style.backgroundColor = "#f0fdf4", this.statusBadge.style.borderRadius = "9999px", this.statusBadge.style.border = "1px solid #dcfce7", this.statusBadge.style.marginBottom = "8px", this.statusBadge.style.position = "relative", this.statusBadge.style.zIndex = "10";
|
|
1600
1610
|
const n = document.createElement("div");
|
|
1601
1611
|
n.style.width = "8px", n.style.height = "8px", n.style.borderRadius = "50%", n.style.backgroundColor = "#22c55e", n.style.boxShadow = "0 0 8px rgba(34,197,94,0.6)", n.style.animation = "pulse 2s infinite";
|
|
1602
|
-
const
|
|
1603
|
-
|
|
1612
|
+
const s = document.createElement("span");
|
|
1613
|
+
s.textContent = "CONNECTED", s.style.fontSize = "12px", s.style.fontWeight = "600", s.style.color = "#15803d", s.style.textTransform = "uppercase", s.style.letterSpacing = "0.05em", this.statusBadge.appendChild(n), this.statusBadge.appendChild(s), this.contentContainer.appendChild(this.statusBadge), this.prepareBadge = document.createElement("div"), this.prepareBadge.textContent = "AGENT IS ON THE WAY...", this.prepareBadge.style.display = "none", this.prepareBadge.style.fontSize = "12px", this.prepareBadge.style.fontWeight = "600", this.prepareBadge.style.color = "#a855f7", this.prepareBadge.style.textTransform = "uppercase", this.prepareBadge.style.letterSpacing = "0.05em", this.prepareBadge.style.animation = "pulse 1.5s infinite", this.prepareBadge.style.position = "relative", this.prepareBadge.style.zIndex = "10", this.contentContainer.appendChild(this.prepareBadge), this.transcriptionElement = document.createElement("div"), this.transcriptionElement.style.marginTop = "20px", this.transcriptionElement.style.padding = "0 24px", this.transcriptionElement.style.textAlign = "center", this.transcriptionElement.style.minHeight = "40px", this.transcriptionElement.style.maxHeight = "80px", this.transcriptionElement.style.overflowY = "auto", this.transcriptionElement.style.fontSize = "14px", this.transcriptionElement.style.color = "#4b5563", this.transcriptionElement.style.fontStyle = "italic", this.contentContainer.appendChild(this.transcriptionElement), this.element.appendChild(this.contentContainer), this.footerContainer = document.createElement("div"), this.footerContainer.style.position = "absolute", this.footerContainer.style.bottom = "16px", this.footerContainer.style.left = "0", this.footerContainer.style.width = "100%", this.footerContainer.style.display = "flex", this.footerContainer.style.justifyContent = "center", this.footerContainer.style.zIndex = "70", this.hangupBtn = document.createElement("button"), this.hangupBtn.className = "control-btn", this.hangupBtn.style.flex = "none", this.hangupBtn.style.width = "auto", this.hangupBtn.style.minWidth = "140px", this.hangupBtn.style.backgroundColor = "#ef4444", this.hangupBtn.style.color = "white", this.hangupBtn.style.borderRadius = "9999px", this.hangupBtn.style.padding = "10px 24px", this.hangupBtn.style.fontSize = "14px", this.hangupBtn.style.fontWeight = "500", this.hangupBtn.style.display = "flex", this.hangupBtn.style.alignItems = "center", this.hangupBtn.style.gap = "8px", this.hangupBtn.style.border = "none", this.hangupBtn.style.cursor = "pointer", this.hangupBtn.style.pointerEvents = "auto", this.hangupBtn.style.transition = "background-color 0.2s", this.hangupBtn.style.boxShadow = "0 4px 6px -1px rgba(0, 0, 0, 0.1)", this.hangupBtn.onmouseover = () => this.hangupBtn.style.backgroundColor = "#dc2626", this.hangupBtn.onmouseout = () => this.hangupBtn.style.backgroundColor = "#ef4444", this.hangupBtn.innerHTML = `${d.phone} End Call`;
|
|
1604
1614
|
const r = this.hangupBtn.querySelector("svg");
|
|
1605
1615
|
r && (r.style.transform = "rotate(135deg)", r.style.width = "16px", r.style.height = "16px"), this.hangupBtn.onclick = this.onHangup, this.footerContainer.appendChild(this.hangupBtn), this.element.appendChild(this.footerContainer);
|
|
1606
1616
|
}
|
|
@@ -1616,8 +1626,8 @@ class J {
|
|
|
1616
1626
|
i.className = "absolute rounded-full wave-2", i.style.width = "180px", i.style.height = "180px", i.style.background = `conic-gradient(from 60deg, ${this.secondaryColor}, #fcd34d, ${this.primaryColor}, ${this.secondaryColor})`, i.style.opacity = "0.8", i.style.animation = "wave-rotate-2 6s linear infinite", i.style.display = "none", this.waveLayers.push(i), this.waveContainer.appendChild(i);
|
|
1617
1627
|
const n = document.createElement("div");
|
|
1618
1628
|
n.className = "absolute rounded-full wave-3", n.style.width = "160px", n.style.height = "160px", n.style.background = `conic-gradient(from 120deg, #fcd34d, ${this.primaryColor}, ${this.secondaryColor}, #fcd34d)`, n.style.opacity = "0.9", n.style.animation = "wave-rotate-3 4s linear infinite", n.style.display = "none", this.waveLayers.push(n), this.waveContainer.appendChild(n);
|
|
1619
|
-
const
|
|
1620
|
-
|
|
1629
|
+
const s = document.createElement("div");
|
|
1630
|
+
s.className = "central-orb active", s.style.width = "56px", s.style.height = "56px", s.style.zIndex = "10", s.style.background = "#1f2937", s.style.borderRadius = "50%", s.style.display = "none", s.style.alignItems = "center", s.style.justifyContent = "center", s.style.color = "white", s.style.boxShadow = "0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)", s.innerHTML = d.phone, this.waveLayers.push(s), this.waveContainer.appendChild(s);
|
|
1621
1631
|
}
|
|
1622
1632
|
getElement() {
|
|
1623
1633
|
return this.element;
|
|
@@ -1676,15 +1686,15 @@ class J {
|
|
|
1676
1686
|
}
|
|
1677
1687
|
class L {
|
|
1678
1688
|
constructor(t) {
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1689
|
+
o(this, "element");
|
|
1690
|
+
o(this, "messageContainer");
|
|
1691
|
+
o(this, "inputArea");
|
|
1692
|
+
o(this, "input");
|
|
1693
|
+
o(this, "sendBtn");
|
|
1694
|
+
o(this, "typingIndicator", null);
|
|
1685
1695
|
this.onSend = t, this.element = document.createElement("div"), this.element.style.display = "flex", this.element.style.flexDirection = "column", this.element.style.flex = "1", this.element.style.overflow = "hidden", this.element.style.minHeight = "0", this.messageContainer = document.createElement("div"), this.messageContainer.className = "chat-messages", this.inputArea = document.createElement("div"), this.inputArea.className = "chat-input-area", this.input = document.createElement("input"), this.input.className = "chat-input", this.input.placeholder = "Type a message...", this.input.addEventListener("keypress", (e) => {
|
|
1686
1696
|
e.key === "Enter" && this.handleSend();
|
|
1687
|
-
}), this.sendBtn = document.createElement("button"), this.sendBtn.className = "chat-send-btn", this.sendBtn.innerHTML =
|
|
1697
|
+
}), this.sendBtn = document.createElement("button"), this.sendBtn.className = "chat-send-btn", this.sendBtn.innerHTML = d.send, this.sendBtn.onclick = () => this.handleSend(), this.inputArea.appendChild(this.input), this.inputArea.appendChild(this.sendBtn), this.element.appendChild(this.messageContainer), this.element.appendChild(this.inputArea);
|
|
1688
1698
|
}
|
|
1689
1699
|
getElement() {
|
|
1690
1700
|
return this.element;
|
|
@@ -1733,18 +1743,18 @@ class L {
|
|
|
1733
1743
|
}
|
|
1734
1744
|
class ee {
|
|
1735
1745
|
constructor(t) {
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1746
|
+
o(this, "element");
|
|
1747
|
+
o(this, "videoElement");
|
|
1748
|
+
o(this, "placeholderContainer");
|
|
1739
1749
|
this.element = document.createElement("div"), this.element.className = "avatar-container", this.element.style.position = "relative", this.element.style.width = "100%", this.element.style.height = "100%", this.element.style.background = "#ffffff", this.element.style.borderRadius = "16px", this.element.style.overflow = "hidden", this.placeholderContainer = document.createElement("div"), this.placeholderContainer.style.width = "100%", this.placeholderContainer.style.height = "100%", this.placeholderContainer.style.display = "flex", this.placeholderContainer.style.alignItems = "center", this.placeholderContainer.style.justifyContent = "center";
|
|
1740
1750
|
const e = t || "https://www.simli.com/jenna.mp4", i = e.endsWith(".mp4") || e.endsWith(".webm");
|
|
1741
1751
|
let n;
|
|
1742
1752
|
if (i) {
|
|
1743
|
-
const
|
|
1744
|
-
|
|
1753
|
+
const s = document.createElement("video");
|
|
1754
|
+
s.src = e, s.muted = !0, s.loop = !0, s.autoplay = !0, s.playsInline = !0, n = s;
|
|
1745
1755
|
} else {
|
|
1746
|
-
const
|
|
1747
|
-
|
|
1756
|
+
const s = document.createElement("img");
|
|
1757
|
+
s.src = e, n = s;
|
|
1748
1758
|
}
|
|
1749
1759
|
n.style.width = "140px", n.style.height = "140px", n.style.borderRadius = "50%", n.style.objectFit = "cover", n.style.backgroundColor = "#f3f4f6", this.placeholderContainer.appendChild(n), this.element.appendChild(this.placeholderContainer), this.videoElement = document.createElement("video"), this.videoElement.className = "avatar-video", this.videoElement.autoplay = !0, this.videoElement.playsInline = !0, this.videoElement.muted = !0, this.videoElement.style.display = "none", this.element.appendChild(this.videoElement);
|
|
1750
1760
|
}
|
|
@@ -1757,11 +1767,11 @@ class ee {
|
|
|
1757
1767
|
}
|
|
1758
1768
|
class te {
|
|
1759
1769
|
constructor(t) {
|
|
1760
|
-
|
|
1770
|
+
o(this, "element");
|
|
1761
1771
|
this.onClick = t, this.element = document.createElement("div"), this.element.className = "voice-mode-container", this.element.innerHTML = `
|
|
1762
1772
|
<div class="central-orb-container">
|
|
1763
1773
|
<div class="central-orb idle">
|
|
1764
|
-
${
|
|
1774
|
+
${d.audioLines}
|
|
1765
1775
|
</div>
|
|
1766
1776
|
<div class="central-orb-glow"></div>
|
|
1767
1777
|
</div>
|
|
@@ -1775,10 +1785,10 @@ class te {
|
|
|
1775
1785
|
return this.element;
|
|
1776
1786
|
}
|
|
1777
1787
|
}
|
|
1778
|
-
class
|
|
1788
|
+
class G {
|
|
1779
1789
|
constructor(t) {
|
|
1780
|
-
|
|
1781
|
-
|
|
1790
|
+
o(this, "element");
|
|
1791
|
+
o(this, "chips", []);
|
|
1782
1792
|
this.onChipClick = t, this.element = document.createElement("div"), this.element.className = "welcome-chips-container";
|
|
1783
1793
|
}
|
|
1784
1794
|
setChips(t) {
|
|
@@ -1861,12 +1871,12 @@ class S {
|
|
|
1861
1871
|
}
|
|
1862
1872
|
class j {
|
|
1863
1873
|
constructor(t, e, i = "#6366f1", n = "#a855f7") {
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1874
|
+
o(this, "element");
|
|
1875
|
+
o(this, "overlay");
|
|
1876
|
+
o(this, "onStartCall");
|
|
1877
|
+
o(this, "onHangup");
|
|
1878
|
+
o(this, "primaryColor");
|
|
1879
|
+
o(this, "secondaryColor");
|
|
1870
1880
|
this.onStartCall = t, this.onHangup = e, this.primaryColor = i, this.secondaryColor = n, this.element = document.createElement("div"), this.element.style.height = "100%", this.element.style.position = "relative";
|
|
1871
1881
|
}
|
|
1872
1882
|
initOverlay() {
|
|
@@ -1889,16 +1899,16 @@ class j {
|
|
|
1889
1899
|
}
|
|
1890
1900
|
}
|
|
1891
1901
|
class ie extends j {
|
|
1892
|
-
constructor(e, i, n = "#6366f1",
|
|
1893
|
-
super(e, i, n,
|
|
1894
|
-
|
|
1902
|
+
constructor(e, i, n = "#6366f1", s = "#a855f7") {
|
|
1903
|
+
super(e, i, n, s);
|
|
1904
|
+
o(this, "voiceOrb");
|
|
1895
1905
|
this.voiceOrb = new te(() => this.onStartCall()), this.element.appendChild(this.voiceOrb.getElement()), this.initOverlay();
|
|
1896
1906
|
}
|
|
1897
1907
|
}
|
|
1898
1908
|
class ne {
|
|
1899
1909
|
constructor(t) {
|
|
1900
|
-
|
|
1901
|
-
|
|
1910
|
+
o(this, "element");
|
|
1911
|
+
o(this, "chatWindow");
|
|
1902
1912
|
this.onSendMessage = t, this.element = document.createElement("div"), this.element.style.flex = "1", this.element.style.width = "100%", this.element.style.minHeight = "0", this.element.style.display = "flex", this.element.style.flexDirection = "column", this.chatWindow = new L((e) => this.onSendMessage(e)), this.element.appendChild(this.chatWindow.getElement());
|
|
1903
1913
|
}
|
|
1904
1914
|
getElement() {
|
|
@@ -1909,12 +1919,12 @@ class ne {
|
|
|
1909
1919
|
}
|
|
1910
1920
|
}
|
|
1911
1921
|
class N {
|
|
1912
|
-
constructor(t, e, i, n = "#6366f1",
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
this.onSendMessage = t, this.onStartCall = e, this.onHangup = i, this.primaryColor = n, this.secondaryColor =
|
|
1922
|
+
constructor(t, e, i, n = "#6366f1", s = "#a855f7") {
|
|
1923
|
+
o(this, "element");
|
|
1924
|
+
o(this, "chatWindow");
|
|
1925
|
+
o(this, "overlay");
|
|
1926
|
+
o(this, "voiceTrigger");
|
|
1927
|
+
this.onSendMessage = t, this.onStartCall = e, this.onHangup = i, this.primaryColor = n, this.secondaryColor = s, this.element = document.createElement("div"), this.element.style.flex = "1", this.element.style.display = "flex", this.element.style.flexDirection = "column", this.element.style.minHeight = "0", this.element.style.position = "relative";
|
|
1918
1928
|
}
|
|
1919
1929
|
setupChat() {
|
|
1920
1930
|
this.chatWindow = new L((e) => this.onSendMessage(e));
|
|
@@ -1923,7 +1933,7 @@ class N {
|
|
|
1923
1933
|
}
|
|
1924
1934
|
injectVoiceTrigger() {
|
|
1925
1935
|
const t = document.createElement("button");
|
|
1926
|
-
this.voiceTrigger = t, t.className = "voice-btn-simple", t.innerHTML = `<div class="voice-btn-icon">${
|
|
1936
|
+
this.voiceTrigger = t, t.className = "voice-btn-simple", t.innerHTML = `<div class="voice-btn-icon">${d.audioLines}</div>`, t.onclick = () => this.onStartCall();
|
|
1927
1937
|
const e = this.chatWindow.getElement().querySelector(".chat-input-area"), i = e == null ? void 0 : e.querySelector(".chat-send-btn");
|
|
1928
1938
|
e && i ? e.insertBefore(this.voiceTrigger, i) : console.warn("AvinSDK: Failed to inject voice trigger", { inputArea: e, sendBtn: i });
|
|
1929
1939
|
}
|
|
@@ -1947,21 +1957,21 @@ class N {
|
|
|
1947
1957
|
}
|
|
1948
1958
|
}
|
|
1949
1959
|
class se extends N {
|
|
1950
|
-
constructor(t, e, i, n = "#6366f1",
|
|
1951
|
-
super(t, e, i, n,
|
|
1960
|
+
constructor(t, e, i, n = "#6366f1", s = "#a855f7") {
|
|
1961
|
+
super(t, e, i, n, s), this.setupChat();
|
|
1952
1962
|
}
|
|
1953
1963
|
}
|
|
1954
1964
|
class oe extends j {
|
|
1955
|
-
constructor(e, i, n = "#6366f1",
|
|
1956
|
-
super(e, i, n,
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1965
|
+
constructor(e, i, n = "#6366f1", s = "#a855f7") {
|
|
1966
|
+
super(e, i, n, s);
|
|
1967
|
+
o(this, "avatarView");
|
|
1968
|
+
o(this, "startCallBtn");
|
|
1969
|
+
o(this, "controlsContainer");
|
|
1960
1970
|
this.element.style.display = "flex", this.element.style.flexDirection = "column", this.avatarView = new ee();
|
|
1961
1971
|
const r = this.avatarView.getElement();
|
|
1962
1972
|
r.style.width = "100%", r.style.maxWidth = "300px", r.style.aspectRatio = "1/1", r.style.borderRadius = "16px", r.style.overflow = "hidden", r.style.margin = "auto", r.style.position = "relative", this.element.appendChild(r), this.controlsContainer = document.createElement("div"), this.controlsContainer.className = "widget-body", this.controlsContainer.style.position = "absolute", this.controlsContainer.style.bottom = "20px", this.controlsContainer.style.width = "100%", this.controlsContainer.style.zIndex = "10";
|
|
1963
1973
|
const a = document.createElement("div");
|
|
1964
|
-
a.className = "controls", this.startCallBtn = document.createElement("button"), this.startCallBtn.className = "control-btn primary", this.startCallBtn.innerHTML = `${
|
|
1974
|
+
a.className = "controls", this.startCallBtn = document.createElement("button"), this.startCallBtn.className = "control-btn primary", this.startCallBtn.innerHTML = `${d.phone} <span>Start Call</span>`, this.startCallBtn.onclick = () => this.onStartCall(), a.appendChild(this.startCallBtn), this.controlsContainer.appendChild(a), this.element.appendChild(this.controlsContainer), this.initOverlay(), this.overlay.setMode("avatar");
|
|
1965
1975
|
}
|
|
1966
1976
|
getAvatarView() {
|
|
1967
1977
|
return this.avatarView;
|
|
@@ -1971,8 +1981,8 @@ class oe extends j {
|
|
|
1971
1981
|
}
|
|
1972
1982
|
}
|
|
1973
1983
|
class re extends N {
|
|
1974
|
-
constructor(t, e, i, n = "#6366f1",
|
|
1975
|
-
super(t, e, i, n,
|
|
1984
|
+
constructor(t, e, i, n = "#6366f1", s = "#a855f7") {
|
|
1985
|
+
super(t, e, i, n, s), this.setupChat(), this.overlay.setMode("avatar");
|
|
1976
1986
|
}
|
|
1977
1987
|
// Override to inject the unique Circular Video Button
|
|
1978
1988
|
injectVoiceTrigger() {
|
|
@@ -1984,13 +1994,13 @@ class re extends N {
|
|
|
1984
1994
|
style="width: 100%; height: 100%; object-fit: cover; border-radius: 50%;">
|
|
1985
1995
|
</video>
|
|
1986
1996
|
<div style="position: absolute; bottom: -2px; right: -2px; background: white; border-radius: 50%; padding: 2px; box-shadow: 0 1px 2px rgba(0,0,0,0.1);">
|
|
1987
|
-
${
|
|
1997
|
+
${d.audioLines.replace('width="24"', 'width="12"').replace('height="24"', 'height="12"')}
|
|
1988
1998
|
</div>
|
|
1989
1999
|
`;
|
|
1990
2000
|
const e = t.querySelector("div");
|
|
1991
2001
|
if (e) {
|
|
1992
|
-
const
|
|
1993
|
-
|
|
2002
|
+
const s = e.querySelector("svg");
|
|
2003
|
+
s && (s.style.width = "12px", s.style.height = "12px");
|
|
1994
2004
|
}
|
|
1995
2005
|
t.onclick = () => this.onStartCall();
|
|
1996
2006
|
const i = this.chatWindow.getElement().querySelector(".chat-input-area"), n = i == null ? void 0 : i.querySelector(".chat-send-btn");
|
|
@@ -1999,8 +2009,8 @@ class re extends N {
|
|
|
1999
2009
|
// No getAvatarView method anymore. AvinInternalProvider should check for capability or cast.
|
|
2000
2010
|
}
|
|
2001
2011
|
class ae {
|
|
2002
|
-
async sendMessage(t, e, i, n,
|
|
2003
|
-
return
|
|
2012
|
+
async sendMessage(t, e, i, n, s, r, a) {
|
|
2013
|
+
return y.sendChatMessage(
|
|
2004
2014
|
e,
|
|
2005
2015
|
i,
|
|
2006
2016
|
t,
|
|
@@ -2008,7 +2018,7 @@ class ae {
|
|
|
2008
2018
|
(A) => {
|
|
2009
2019
|
r && r(A);
|
|
2010
2020
|
},
|
|
2011
|
-
|
|
2021
|
+
s,
|
|
2012
2022
|
(A) => {
|
|
2013
2023
|
a && A && a(A);
|
|
2014
2024
|
}
|
|
@@ -2024,65 +2034,65 @@ class ae {
|
|
|
2024
2034
|
class Ae extends Z {
|
|
2025
2035
|
constructor(e) {
|
|
2026
2036
|
super(e);
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2037
|
+
o(this, "avinClient", null);
|
|
2038
|
+
o(this, "currentView", null);
|
|
2039
|
+
o(this, "isPanelOpen", !1);
|
|
2040
|
+
o(this, "callActive", !1);
|
|
2041
|
+
o(this, "eventSource", null);
|
|
2032
2042
|
// Components
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2043
|
+
o(this, "floatingButton", null);
|
|
2044
|
+
o(this, "floatingWelcomeChips", null);
|
|
2045
|
+
o(this, "panel", null);
|
|
2046
|
+
o(this, "welcomeChipsData", []);
|
|
2037
2047
|
// Chat Adapter
|
|
2038
|
-
|
|
2048
|
+
o(this, "chatAdapter");
|
|
2039
2049
|
// Config derived state
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2050
|
+
o(this, "widgetMode", "voice_only");
|
|
2051
|
+
o(this, "agentId", "");
|
|
2052
|
+
o(this, "prospectGroupId", "");
|
|
2053
|
+
o(this, "chatServerUrl", "");
|
|
2054
|
+
o(this, "mediaServerUrl", "");
|
|
2055
|
+
o(this, "prospectId", "");
|
|
2056
|
+
o(this, "chatId", null);
|
|
2047
2057
|
// Appearance (Defaults)
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2058
|
+
o(this, "primaryColor", "#6366f1");
|
|
2059
|
+
o(this, "secondaryColor", "#4f46e5");
|
|
2060
|
+
o(this, "gradient", null);
|
|
2061
|
+
o(this, "position", "bottom-right");
|
|
2062
|
+
o(this, "widgetIcon", null);
|
|
2053
2063
|
this.chatAdapter = new ae(), this.processConfig(e);
|
|
2054
2064
|
}
|
|
2055
2065
|
// Chat Logic
|
|
2056
2066
|
async initializeChatSession() {
|
|
2057
2067
|
var e, i, n;
|
|
2058
2068
|
try {
|
|
2059
|
-
|
|
2060
|
-
const
|
|
2061
|
-
if (
|
|
2069
|
+
y.setChatUrl(this.chatServerUrl), this.prospectGroupId ? this.prospectId = await y.createChatProspect(this.prospectGroupId) : this.prospectId = `anon_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
2070
|
+
const s = await y.fetchWelcomeMessage(this.agentId, this.prospectId);
|
|
2071
|
+
if (s && s.chatId && !this.chatId && (this.chatId = s.chatId, this.eventSource || (this.eventSource = y.listenForAdminReplies(this.chatId, this.prospectId, (r) => {
|
|
2062
2072
|
var a, A;
|
|
2063
2073
|
(A = (a = this.currentView) == null ? void 0 : a.getChatWindow) == null || A.call(a).addMessage("assistant", r);
|
|
2064
|
-
}))),
|
|
2074
|
+
}))), s && ((e = this.currentView) != null && e.getChatWindow)) {
|
|
2065
2075
|
const r = this.currentView.getChatWindow();
|
|
2066
|
-
if (r.clearMessages(),
|
|
2076
|
+
if (r.clearMessages(), s.widget)
|
|
2067
2077
|
try {
|
|
2068
|
-
const a = JSON.parse(
|
|
2069
|
-
r.addMessage(
|
|
2078
|
+
const a = JSON.parse(s.content);
|
|
2079
|
+
r.addMessage(s.role, a.text || ""), a.buttons && Array.isArray(a.buttons) && (r.addButtons(a.buttons), this.welcomeChipsData = a.buttons), this.updateWelcomeChipsVisibility();
|
|
2070
2080
|
} catch (a) {
|
|
2071
|
-
console.error("Failed to parse welcome widget content", a), r.addMessage(
|
|
2081
|
+
console.error("Failed to parse welcome widget content", a), r.addMessage(s.role, s.content);
|
|
2072
2082
|
}
|
|
2073
2083
|
else
|
|
2074
|
-
r.addMessage(
|
|
2084
|
+
r.addMessage(s.role, s.content);
|
|
2075
2085
|
}
|
|
2076
|
-
} catch (
|
|
2077
|
-
console.error("Chat init failed",
|
|
2086
|
+
} catch (s) {
|
|
2087
|
+
console.error("Chat init failed", s), (n = (i = this.currentView) == null ? void 0 : i.getChatWindow) == null || n.call(i).addMessage("assistant", "Hello! How can I help you today?");
|
|
2078
2088
|
}
|
|
2079
2089
|
}
|
|
2080
2090
|
async initialize(e) {
|
|
2081
2091
|
await super.initialize(e), this.processConfig(e), this.root && this.ui_renderer(this.root);
|
|
2082
2092
|
}
|
|
2083
2093
|
processConfig(e) {
|
|
2084
|
-
var i, n,
|
|
2085
|
-
if (this.agentId = e.agentId || e.agent_id || "", this.prospectGroupId = e.prospectGroupId || ((i = e.client) == null ? void 0 : i.base_prospect_group_id) || "", this.widgetMode = e.widgetMode || e.mode || "voice_only", this.primaryColor = e.primaryColor || "#6366f1", this.secondaryColor = e.secondaryColor || e.primaryColor || "#4f46e5", this.gradient = e.gradient || null, this.position = e.position || "bottom-right", this.widgetIcon = e.widgetIcon || e.icon || null, this.chatServerUrl = e.serverUrl || e.chatServerUrl || "https://inboxapi.travelr.club", (r = (
|
|
2094
|
+
var i, n, s, r;
|
|
2095
|
+
if (this.agentId = e.agentId || e.agent_id || "", this.prospectGroupId = e.prospectGroupId || ((i = e.client) == null ? void 0 : i.base_prospect_group_id) || "", this.widgetMode = e.widgetMode || e.mode || "voice_only", this.primaryColor = e.primaryColor || "#6366f1", this.secondaryColor = e.secondaryColor || e.primaryColor || "#4f46e5", this.gradient = e.gradient || null, this.position = e.position || "bottom-right", this.widgetIcon = e.widgetIcon || e.icon || null, this.chatServerUrl = e.serverUrl || e.chatServerUrl || "https://inboxapi.travelr.club", (r = (s = (n = e.agent) == null ? void 0 : n.tts_voice) == null ? void 0 : s.provider) != null && r.root_name) {
|
|
2086
2096
|
const a = e.agent.tts_voice.provider.root_name.toLowerCase();
|
|
2087
2097
|
this.mediaServerUrl = a === "premium" ? e.premiumMediaServerUrl || "https://godspeed.travelr.club" : e.mediaServerUrl || "https://in-godspeed.travelr.club";
|
|
2088
2098
|
} else
|
|
@@ -2092,7 +2102,7 @@ class Ae extends Z {
|
|
|
2092
2102
|
if (!(this.callActive || !this.agentId))
|
|
2093
2103
|
try {
|
|
2094
2104
|
this.callActive = !0, this.updateViewCallState(!0), this.updateViewStatus("connecting");
|
|
2095
|
-
const e = await
|
|
2105
|
+
const e = await y.createCall(
|
|
2096
2106
|
this.agentId,
|
|
2097
2107
|
this.prospectId || null,
|
|
2098
2108
|
this.widgetMode
|
|
@@ -2103,21 +2113,21 @@ class Ae extends Z {
|
|
|
2103
2113
|
});
|
|
2104
2114
|
i.on("connected", () => this.updateViewStatus("connected")).on("disconnected", () => this.end_call()).on("error", (n) => {
|
|
2105
2115
|
console.error("[AvinAI Widget] Call error:", n), this.updateViewStatus("error");
|
|
2106
|
-
}).on("transcription", ({ text: n, isFinal:
|
|
2116
|
+
}).on("transcription", ({ text: n, isFinal: s }) => {
|
|
2107
2117
|
var r, a;
|
|
2108
|
-
(a = (r = this.currentView) == null ? void 0 : r.setTranscription) == null || a.call(r, n,
|
|
2118
|
+
(a = (r = this.currentView) == null ? void 0 : r.setTranscription) == null || a.call(r, n, s);
|
|
2109
2119
|
}).on("track", ({ track: n }) => {
|
|
2110
|
-
var
|
|
2111
|
-
this.widgetMode.includes("avatar") && n.kind === "video" && ((
|
|
2120
|
+
var s;
|
|
2121
|
+
this.widgetMode.includes("avatar") && n.kind === "video" && ((s = this.currentView) != null && s.setVideoTrack) && this.currentView.setVideoTrack(n);
|
|
2112
2122
|
}).on("tool_call", (n) => {
|
|
2113
2123
|
var r, a;
|
|
2114
|
-
const
|
|
2124
|
+
const s = new CustomEvent("avinai:tool_call", {
|
|
2115
2125
|
detail: n,
|
|
2116
2126
|
bubbles: !0,
|
|
2117
2127
|
composed: !0
|
|
2118
2128
|
// crosses Shadow DOM boundary
|
|
2119
2129
|
});
|
|
2120
|
-
(a = (r = this.root) == null ? void 0 : r.host) == null || a.dispatchEvent(
|
|
2130
|
+
(a = (r = this.root) == null ? void 0 : r.host) == null || a.dispatchEvent(s), console.log("[AvinAI Widget] Tool call dispatched:", n.name, n.arguments), n.execution_mode;
|
|
2121
2131
|
}), this.avinClient = i, await i.start();
|
|
2122
2132
|
} catch (e) {
|
|
2123
2133
|
console.error("[AvinAI Widget] Call failed", e), this.updateViewStatus("error");
|
|
@@ -2141,13 +2151,13 @@ class Ae extends Z {
|
|
|
2141
2151
|
${$}
|
|
2142
2152
|
:host { ${q(this.primaryColor, this.secondaryColor)} }
|
|
2143
2153
|
${Y.styles}
|
|
2144
|
-
${S.styles}
|
|
2145
2154
|
${G.styles}
|
|
2155
|
+
${S.styles}
|
|
2146
2156
|
${this.gradient ? `.widget-fab { background: ${this.gradient} !important; }` : ""}
|
|
2147
|
-
`, this.root.appendChild(i), this.floatingButton = new Y(() => this.togglePanel()), this.floatingButton.setIcon(this.getFabIcon()), this.floatingButton.setPosition(this.getPosStyle()), this.floatingWelcomeChips = new
|
|
2157
|
+
`, this.root.appendChild(i), this.floatingButton = new Y(() => this.togglePanel()), this.floatingButton.setIcon(this.getFabIcon()), this.floatingButton.setPosition(this.getPosStyle()), this.floatingWelcomeChips = new G((n) => this.handleFloatingChipClick(n)), this.floatingWelcomeChips.setPosition(this.getPosStyle()), this.panel = new S(() => this.closePanel(), this.getPanelTitle()), this.root.appendChild(this.floatingWelcomeChips.getElement()), this.root.appendChild(this.floatingButton.getElement()), this.root.appendChild(this.panel.getElement()), this.setupPanelContent(), this.widgetMode.includes("chat") && this.initializeChatSession();
|
|
2148
2158
|
}
|
|
2149
2159
|
getFabIcon() {
|
|
2150
|
-
return this.widgetIcon && E[this.widgetIcon] ? E[this.widgetIcon] : this.widgetMode.includes("chat") ?
|
|
2160
|
+
return this.widgetIcon && E[this.widgetIcon] ? E[this.widgetIcon] : this.widgetMode.includes("chat") ? d.chat : d.audioLines;
|
|
2151
2161
|
}
|
|
2152
2162
|
getPanelTitle() {
|
|
2153
2163
|
let e = "Voice Assistant";
|
|
@@ -2203,11 +2213,14 @@ class Ae extends Z {
|
|
|
2203
2213
|
this.currentView && this.panel && this.panel.setContent(this.currentView.getElement());
|
|
2204
2214
|
}
|
|
2205
2215
|
async handleChatSend(e) {
|
|
2206
|
-
var n,
|
|
2216
|
+
var n, s;
|
|
2207
2217
|
if (!e) return;
|
|
2208
|
-
const i = (
|
|
2218
|
+
const i = (s = (n = this.currentView) == null ? void 0 : n.getChatWindow) == null ? void 0 : s.call(n);
|
|
2209
2219
|
if (i) {
|
|
2210
|
-
|
|
2220
|
+
this.chatId && !this.eventSource && (this.eventSource = y.listenForAdminReplies(this.chatId, this.prospectId, (r) => {
|
|
2221
|
+
var a, A;
|
|
2222
|
+
(A = (a = this.currentView) == null ? void 0 : a.getChatWindow) == null || A.call(a).addMessage("assistant", r);
|
|
2223
|
+
})), i.addMessage("user", e), i.setTyping(!0);
|
|
2211
2224
|
try {
|
|
2212
2225
|
await this.chatAdapter.sendMessage(
|
|
2213
2226
|
e,
|
|
@@ -2267,16 +2280,16 @@ class le {
|
|
|
2267
2280
|
class de extends HTMLElement {
|
|
2268
2281
|
constructor() {
|
|
2269
2282
|
super();
|
|
2270
|
-
|
|
2271
|
-
|
|
2283
|
+
o(this, "shadow");
|
|
2284
|
+
o(this, "provider", null);
|
|
2272
2285
|
// Config attributes
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2286
|
+
o(this, "widgetId", "");
|
|
2287
|
+
o(this, "agentId", "");
|
|
2288
|
+
o(this, "serverUrl", "https://inboxapi.travelr.club");
|
|
2289
|
+
o(this, "position", "bottom-right");
|
|
2290
|
+
o(this, "primaryColor", "#6366f1");
|
|
2291
|
+
o(this, "secondaryColor", "#4f46e5");
|
|
2292
|
+
o(this, "gradient", null);
|
|
2280
2293
|
this.shadow = this.attachShadow({ mode: "open" });
|
|
2281
2294
|
}
|
|
2282
2295
|
static get observedAttributes() {
|
|
@@ -2310,7 +2323,7 @@ class de extends HTMLElement {
|
|
|
2310
2323
|
export {
|
|
2311
2324
|
V as AvinAI,
|
|
2312
2325
|
de as AvinWidget,
|
|
2313
|
-
|
|
2326
|
+
y as ChatService,
|
|
2314
2327
|
K as ConfigService,
|
|
2315
2328
|
b as WebRTCClient
|
|
2316
2329
|
};
|