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