@streamoji/avatar-widget 0.2.6 → 0.2.7
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/avatar-widget.cjs +4 -4
- package/dist/avatar-widget.cjs.map +1 -1
- package/dist/avatar-widget.js +156 -154
- package/dist/avatar-widget.js.map +1 -1
- package/dist/avatar-widget.umd.js +10 -10
- package/dist/avatar-widget.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/avatar-widget.js
CHANGED
|
@@ -15,38 +15,38 @@ const lt = "https://ai.streamoji.com", B = (...f) => {
|
|
|
15
15
|
if (!T) return;
|
|
16
16
|
let V, E = null;
|
|
17
17
|
f && (f.fftSize = 128, E = new Uint8Array(f.frequencyBinCount));
|
|
18
|
-
const
|
|
19
|
-
V = requestAnimationFrame(
|
|
20
|
-
const ae = g.width,
|
|
21
|
-
if (ae === 0 ||
|
|
22
|
-
const U =
|
|
23
|
-
T.clearRect(0, 0, ae,
|
|
18
|
+
const te = () => {
|
|
19
|
+
V = requestAnimationFrame(te), (g.width !== g.offsetWidth || g.height !== g.offsetHeight) && (g.width = g.offsetWidth, g.height = g.offsetHeight);
|
|
20
|
+
const ae = g.width, I = g.height;
|
|
21
|
+
if (ae === 0 || I === 0) return;
|
|
22
|
+
const U = I / 2;
|
|
23
|
+
T.clearRect(0, 0, ae, I), T.fillStyle = "#1e293b";
|
|
24
24
|
const _ = 2, m = _ + 2, Y = ae * 0.95, $ = Math.floor(Y / m);
|
|
25
25
|
(!w.current || w.current.length !== $) && (w.current = new Float32Array($).fill(2));
|
|
26
26
|
const pe = $ * m, k = (ae - pe) / 2;
|
|
27
27
|
f && E && f.getByteFrequencyData(E);
|
|
28
28
|
const He = E ? E.length : 0, q = Math.floor(He * 0.7) / $, ge = new Float32Array($);
|
|
29
|
-
for (let
|
|
30
|
-
let
|
|
29
|
+
for (let M = 0; M < $; M++) {
|
|
30
|
+
let O = 0;
|
|
31
31
|
if (E && q > 0) {
|
|
32
|
-
const be = Math.floor(
|
|
32
|
+
const be = Math.floor(M * q), L = Math.floor((M + 1) * q);
|
|
33
33
|
for (let v = be; v < L; v++) {
|
|
34
34
|
const y = E[v] || 0;
|
|
35
|
-
y >
|
|
35
|
+
y > O && (O = y);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
const W =
|
|
40
|
-
ge[
|
|
38
|
+
O < 10 && (O = 0);
|
|
39
|
+
const W = O / 255, D = O > 0 ? Math.max(2, Math.pow(W, 1.4) * I * 0.25) : 2;
|
|
40
|
+
ge[M] = D;
|
|
41
41
|
}
|
|
42
|
-
for (let
|
|
43
|
-
const
|
|
44
|
-
w.current[
|
|
45
|
-
const be = k +
|
|
46
|
-
T.beginPath(), T.roundRect ? T.roundRect(be, L, _,
|
|
42
|
+
for (let M = 0; M < $; M++) {
|
|
43
|
+
const O = $ - 1 - M, W = Math.max(ge[M], ge[O]), D = w.current[M] + (W - w.current[M]) * 0.3;
|
|
44
|
+
w.current[M] = D;
|
|
45
|
+
const be = k + M * m, L = U - D / 2;
|
|
46
|
+
T.beginPath(), T.roundRect ? T.roundRect(be, L, _, D, 4) : T.fillRect(be, L, _, D), T.fill();
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
|
-
return
|
|
49
|
+
return te(), () => {
|
|
50
50
|
cancelAnimationFrame(V);
|
|
51
51
|
};
|
|
52
52
|
}, [f]), /* @__PURE__ */ l(
|
|
@@ -512,9 +512,9 @@ const wn = Kt(
|
|
|
512
512
|
responseAudioStartTimeRef: T,
|
|
513
513
|
adjustments: V,
|
|
514
514
|
mood: E,
|
|
515
|
-
expression:
|
|
515
|
+
expression: te,
|
|
516
516
|
agentResponse: ae,
|
|
517
|
-
isSpeaking:
|
|
517
|
+
isSpeaking: I,
|
|
518
518
|
nextStartTimeRef: U,
|
|
519
519
|
stopPlayback: _,
|
|
520
520
|
setIsSpeaking: ce,
|
|
@@ -526,10 +526,10 @@ const wn = Kt(
|
|
|
526
526
|
const { scene: k } = ct(f), xe = ct(pe === "female" ? cn : an), q = dt(
|
|
527
527
|
() => xe.flatMap((d) => d.animations),
|
|
528
528
|
[xe]
|
|
529
|
-
), ge = ct(un),
|
|
529
|
+
), ge = ct(un), M = dt(
|
|
530
530
|
() => ge.flatMap((d) => d.animations),
|
|
531
531
|
[ge]
|
|
532
|
-
),
|
|
532
|
+
), O = c(null), W = c(null), D = c(null), be = c([]), [L] = b(() => new Ve.AnimationMixer(k)), v = c({}), y = c(null), _e = c(0), Ie = c(!1), we = c(0), le = c(null);
|
|
533
533
|
P(() => {
|
|
534
534
|
if (!(!q || !k)) {
|
|
535
535
|
if (q.forEach((d, u) => {
|
|
@@ -538,7 +538,7 @@ const wn = Kt(
|
|
|
538
538
|
const r = L.clipAction(d, k);
|
|
539
539
|
r.name = i, r.setLoop(Ve.LoopOnce, 1), r.clampWhenFinished = !0, v.current[i] = r;
|
|
540
540
|
}
|
|
541
|
-
}),
|
|
541
|
+
}), M.forEach((d, u) => {
|
|
542
542
|
const i = `talk_${u}`;
|
|
543
543
|
if (!v.current[i]) {
|
|
544
544
|
const r = L.clipAction(d, k);
|
|
@@ -552,7 +552,7 @@ const wn = Kt(
|
|
|
552
552
|
L.stopAllAction(), v.current = {}, y.current = null;
|
|
553
553
|
};
|
|
554
554
|
}
|
|
555
|
-
}, [q,
|
|
555
|
+
}, [q, M, k, L]);
|
|
556
556
|
const ve = c("");
|
|
557
557
|
P(() => {
|
|
558
558
|
if (!m || !k || m === ve.current) return;
|
|
@@ -561,7 +561,7 @@ const wn = Kt(
|
|
|
561
561
|
(u) => {
|
|
562
562
|
if (u.animations && u.animations.length > 0) {
|
|
563
563
|
const i = u.animations[0], r = L.clipAction(i, k);
|
|
564
|
-
if (r.name = `EXPR_${m}`, r.setLoop(Ve.LoopOnce, 1), r.clampWhenFinished = !0, v.current[`EXPR_${m}`] = r,
|
|
564
|
+
if (r.name = `EXPR_${m}`, r.setLoop(Ve.LoopOnce, 1), r.clampWhenFinished = !0, v.current[`EXPR_${m}`] = r, I && le.current === m) {
|
|
565
565
|
const h = y.current;
|
|
566
566
|
r.reset().fadeIn(0.3).play(), h && h !== r && h.crossFadeTo(r, 0.3, !0), y.current = r, le.current = null;
|
|
567
567
|
}
|
|
@@ -572,14 +572,14 @@ const wn = Kt(
|
|
|
572
572
|
console.error(`[ANIMATION] Failed to load ${m}`, u);
|
|
573
573
|
}
|
|
574
574
|
);
|
|
575
|
-
}, [m, k, L,
|
|
575
|
+
}, [m, k, L, I]), P(() => {
|
|
576
576
|
const d = (u) => {
|
|
577
577
|
const i = u.action, r = i.name || "";
|
|
578
578
|
if (r.startsWith("idle_")) {
|
|
579
579
|
const G = (parseInt(r.split("_")[1]) + 1) % q.length, Q = v.current[`idle_${G}`];
|
|
580
580
|
Q && (Q.reset().fadeIn(0.5).play(), i.crossFadeTo(Q, 0.5, !0), y.current = Q);
|
|
581
581
|
} else if (r.startsWith("EXPR_")) {
|
|
582
|
-
if (
|
|
582
|
+
if (I) {
|
|
583
583
|
const h = v.current.talk_0;
|
|
584
584
|
h && (h.reset().fadeIn(0.5).play(), i.crossFadeTo(h, 0.5, !0), y.current = h);
|
|
585
585
|
} else {
|
|
@@ -588,8 +588,8 @@ const wn = Kt(
|
|
|
588
588
|
}
|
|
589
589
|
Y && Y();
|
|
590
590
|
} else if (r.startsWith("talk_"))
|
|
591
|
-
if (
|
|
592
|
-
const G = (parseInt(r.split("_")[1]) + 1) %
|
|
591
|
+
if (I && !$) {
|
|
592
|
+
const G = (parseInt(r.split("_")[1]) + 1) % M.length, Q = v.current[`talk_${G}`];
|
|
593
593
|
Q && (Q.reset().fadeIn(0.3).play(), i.crossFadeTo(Q, 0.3, !0), y.current = Q);
|
|
594
594
|
} else {
|
|
595
595
|
const h = v.current.idle_0;
|
|
@@ -600,12 +600,12 @@ const wn = Kt(
|
|
|
600
600
|
}, [
|
|
601
601
|
L,
|
|
602
602
|
q,
|
|
603
|
+
M,
|
|
603
604
|
I,
|
|
604
|
-
N,
|
|
605
605
|
$,
|
|
606
606
|
Y
|
|
607
607
|
]), P(() => {
|
|
608
|
-
if (
|
|
608
|
+
if (I && k) {
|
|
609
609
|
const d = y.current, u = d?.name || "";
|
|
610
610
|
if (u.startsWith("idle_") || u.startsWith("talk_") || u === "") {
|
|
611
611
|
const i = le.current;
|
|
@@ -621,19 +621,19 @@ const wn = Kt(
|
|
|
621
621
|
r && (r.reset().fadeIn(0.5).play(), d && d.crossFadeTo(r, 0.5, !0), y.current = r);
|
|
622
622
|
}
|
|
623
623
|
}
|
|
624
|
-
} else if (!
|
|
624
|
+
} else if (!I && k) {
|
|
625
625
|
const d = y.current, u = d?.name || "";
|
|
626
626
|
if (u.startsWith("talk_") || u.startsWith("EXPR_")) {
|
|
627
627
|
const i = v.current.idle_0;
|
|
628
628
|
i && (i.reset().fadeIn(0.5).play(), d && d.crossFadeTo(i, 0.5, !0), y.current = i);
|
|
629
629
|
}
|
|
630
630
|
}
|
|
631
|
-
}, [
|
|
631
|
+
}, [I, k, m]), P(() => {
|
|
632
632
|
if (!k) return;
|
|
633
633
|
k.traverse((i) => {
|
|
634
634
|
if (i.isMesh && i.morphTargetDictionary) {
|
|
635
635
|
const r = i.name.toLowerCase();
|
|
636
|
-
(r.includes("head") || r.includes("avatar")) && (W.current = i, B(`[ANIMATION] Found head mesh: ${i.name}`)), r.includes("teeth") && (
|
|
636
|
+
(r.includes("head") || r.includes("avatar")) && (W.current = i, B(`[ANIMATION] Found head mesh: ${i.name}`)), r.includes("teeth") && (D.current = i, B(`[ANIMATION] Found teeth mesh: ${i.name}`));
|
|
637
637
|
}
|
|
638
638
|
});
|
|
639
639
|
const d = W.current?.morphTargetDictionary;
|
|
@@ -653,53 +653,55 @@ const wn = Kt(
|
|
|
653
653
|
if (r)
|
|
654
654
|
for (const h in r.mix) {
|
|
655
655
|
const G = r.mix[h] * u;
|
|
656
|
-
z(W.current, h, G), z(
|
|
656
|
+
z(W.current, h, G), z(D.current, h, G);
|
|
657
657
|
}
|
|
658
658
|
}, ke = (d) => {
|
|
659
659
|
const u = Xe[d] ?? Xe.neutral;
|
|
660
660
|
for (const i in u)
|
|
661
|
-
z(W.current, i, u[i]), z(
|
|
661
|
+
z(W.current, i, u[i]), z(D.current, i, u[i]);
|
|
662
662
|
};
|
|
663
663
|
return Yt((d, u) => {
|
|
664
664
|
const i = Math.pow(0.88, 60 * u);
|
|
665
|
-
Mt(W.current, i), Mt(
|
|
665
|
+
Mt(W.current, i), Mt(D.current, i), ke(E);
|
|
666
666
|
const r = d.clock.elapsedTime;
|
|
667
667
|
let h = 0;
|
|
668
668
|
if (Math.floor(r) % 5 === 0 && Math.floor((r - u) % 5) !== 0) {
|
|
669
|
-
let
|
|
670
|
-
k.traverse((
|
|
671
|
-
|
|
669
|
+
let j = null;
|
|
670
|
+
k.traverse((X) => {
|
|
671
|
+
X.name.toLowerCase().includes("hips") && (j = X);
|
|
672
672
|
});
|
|
673
|
-
const ye =
|
|
673
|
+
const ye = j ? `Hips Y: ${j.position.y.toFixed(4)}` : "Hips not found";
|
|
674
674
|
B(`[ANIMATION] Mixer Time: ${L.time.toFixed(2)}, ${ye}`);
|
|
675
675
|
}
|
|
676
676
|
if (L.update(u), r > _e.current && !Ie.current && (Ie.current = !0, we.current = r), Ie.current) {
|
|
677
|
-
const ye = (r - we.current) /
|
|
678
|
-
if (ye >= 1)
|
|
679
|
-
Ie.current = !1
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
677
|
+
const j = I ? 0.2 : 0.3, ye = (r - we.current) / j;
|
|
678
|
+
if (ye >= 1) {
|
|
679
|
+
Ie.current = !1;
|
|
680
|
+
const X = I ? 1 : 2.5;
|
|
681
|
+
_e.current = r + X;
|
|
682
|
+
} else {
|
|
683
|
+
const X = ye < 0.5 ? ye * 2 : (1 - ye) * 2;
|
|
684
|
+
z(W.current, "eyeBlinkLeft", X), z(W.current, "eyeBlinkRight", X), z(D.current, "eyeBlinkLeft", X), z(D.current, "eyeBlinkRight", X), h = X * hn.browInnerUp;
|
|
683
685
|
}
|
|
684
686
|
}
|
|
685
|
-
const G = Xe[E] ?? Xe.neutral, Q = G.browInnerUp ?? 0, Ke = G.browOuterUpLeft ?? 0, $e = G.browOuterUpRight ?? 0, Ue = r * mn, Re = ut * Math.sin(Ue),
|
|
686
|
-
if (z(W.current, "browInnerUp", Me), z(
|
|
687
|
-
const
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
687
|
+
const G = Xe[E] ?? Xe.neutral, Q = G.browInnerUp ?? 0, Ke = G.browOuterUpLeft ?? 0, $e = G.browOuterUpRight ?? 0, Ue = r * mn, Re = ut * Math.sin(Ue), Z = ut * 0.7 * Math.sin(Ue + 0.7), je = ut * 0.7 * Math.sin(Ue + 1.3), ne = (j) => Math.max(0, Math.min(1, j)), Ae = ne(Q + Re), Le = ne(Ke + Z), Be = ne($e + je), Me = ne(Ae + h);
|
|
688
|
+
if (z(W.current, "browInnerUp", Me), z(D.current, "browInnerUp", Me), z(W.current, "browOuterUpLeft", Le), z(D.current, "browOuterUpLeft", Le), z(W.current, "browOuterUpRight", Be), z(D.current, "browOuterUpRight", Be), O.current) {
|
|
689
|
+
const j = A.current ? 0 : V.rotation[1];
|
|
690
|
+
O.current.rotation.y = Ve.MathUtils.lerp(
|
|
691
|
+
O.current.rotation.y,
|
|
692
|
+
j,
|
|
691
693
|
0.1
|
|
692
|
-
),
|
|
694
|
+
), O.current.position.set(...V.position), O.current.scale.setScalar(V.scale), O.current.rotation.x = V.rotation[0], O.current.rotation.z = V.rotation[2];
|
|
693
695
|
}
|
|
694
696
|
if (A.current && g.current) {
|
|
695
|
-
const
|
|
696
|
-
for (let
|
|
697
|
-
const re = w.current[
|
|
697
|
+
const j = g.current.currentTime, De = (j - T.current) * 1e3 - -150;
|
|
698
|
+
for (let ee = 0; ee < w.current.length; ee++) {
|
|
699
|
+
const re = w.current[ee];
|
|
698
700
|
De >= re.vtime && De < re.vtime + re.vduration && Ne(re.viseme, re.weight ?? 1);
|
|
699
701
|
}
|
|
700
|
-
|
|
702
|
+
j > U.current + 0.5 && (_(), ce(!1));
|
|
701
703
|
}
|
|
702
|
-
}), /* @__PURE__ */ l("group", { ref:
|
|
704
|
+
}), /* @__PURE__ */ l("group", { ref: O, children: /* @__PURE__ */ l("primitive", { object: k }) });
|
|
703
705
|
}
|
|
704
706
|
);
|
|
705
707
|
function vn(f) {
|
|
@@ -711,24 +713,24 @@ const yn = ({
|
|
|
711
713
|
onNavigationRequested: w,
|
|
712
714
|
avatarGender: g
|
|
713
715
|
} = {}) => {
|
|
714
|
-
const T = f ?? A ?? "", V = on(T || void 0), [E,
|
|
716
|
+
const T = f ?? A ?? "", V = on(T || void 0), [E, te] = b(""), [ae, I] = b(""), [U, _] = b("Ready"), [ce, m] = b(!1), [Y, $] = b(!1), [pe, k] = b([]), [He, xe] = b(""), q = c(null), [ge, M] = b(
|
|
715
717
|
() => typeof window < "u" ? window.matchMedia("(max-width: 480px)").matches : !1
|
|
716
718
|
);
|
|
717
719
|
P(() => {
|
|
718
|
-
const e = window.matchMedia("(max-width: 480px)"), t = () =>
|
|
720
|
+
const e = window.matchMedia("(max-width: 480px)"), t = () => M(e.matches);
|
|
719
721
|
return e.addEventListener("change", t), () => e.removeEventListener("change", t);
|
|
720
722
|
}, []);
|
|
721
|
-
const
|
|
723
|
+
const O = ge ? 80 : 600, W = c(!1), D = c([]), be = c(0), L = c(!1), v = c([]), y = c(null), _e = c([]);
|
|
722
724
|
c([]);
|
|
723
725
|
const Ie = c([]), we = c(0), le = c(0), ve = c(0), Ne = c(0), ke = c(!1), [d, u] = b(
|
|
724
726
|
null
|
|
725
|
-
), i = c(null), [r, h] = b("neutral"), [G, Q] = b(""), [Ke, $e] = b(""), [Ue, Re] = b("Chat with us"), [
|
|
727
|
+
), i = c(null), [r, h] = b("neutral"), [G, Q] = b(""), [Ke, $e] = b(""), [Ue, Re] = b("Chat with us"), [Z, je] = b(
|
|
726
728
|
null
|
|
727
|
-
), [
|
|
728
|
-
|
|
729
|
-
const [ye,
|
|
729
|
+
), [ne, Ae] = b("hidden"), [Le, Be] = b(""), Me = c(null), j = c(ne);
|
|
730
|
+
j.current = ne;
|
|
731
|
+
const [ye, X] = b(null), De = c(null), ee = c(null), [re, ft] = b(!1), ht = c(null), [ue, Je] = b("hidden"), [mt, Dt] = b(""), Ze = c(ue);
|
|
730
732
|
Ze.current = ue;
|
|
731
|
-
const he = c(""), Ce = c(!1), Oe = c(""), pt = c(Date.now()), et = c([]), Pe = c(!1), [tt, We] = b(!1), [gt, bt] = b(!1), Se = c(null), Fe = dt(() => re ? "Try again" : U === "Busy" ? "Busy" : U === "Thinking..." || U === "Processing Voice..." ? U :
|
|
733
|
+
const he = c(""), Ce = c(!1), Oe = c(""), pt = c(Date.now()), et = c([]), Pe = c(!1), [tt, We] = b(!1), [gt, bt] = b(!1), Se = c(null), Fe = dt(() => re ? "Try again" : U === "Busy" ? "Busy" : U === "Thinking..." || U === "Processing Voice..." ? U : Z != null && Z !== "" && Z !== "none" && Z !== "<none>" ? `Enter ${vn(Z)}` : ue !== "hidden" || !gt ? null : It, [U, Z, re, ue, gt]), _t = !re && U !== "Busy" && U !== "Thinking..." && U !== "Processing Voice..." && (Z == null || Z === "" || Z === "none" || Z === "<none>");
|
|
732
734
|
P(() => {
|
|
733
735
|
if (ue !== "hidden" || !_t) {
|
|
734
736
|
bt(!1), Se.current != null && (clearTimeout(Se.current), Se.current = null);
|
|
@@ -742,7 +744,7 @@ const yn = ({
|
|
|
742
744
|
}, [ue, _t]);
|
|
743
745
|
const qe = Fe != null && Fe !== "";
|
|
744
746
|
P(() => {
|
|
745
|
-
const e =
|
|
747
|
+
const e = j.current;
|
|
746
748
|
if (!(e === "exiting" || e === "entering")) {
|
|
747
749
|
if (e === "hidden") {
|
|
748
750
|
qe && (Be(Fe ?? ""), Ae("entering"));
|
|
@@ -753,17 +755,17 @@ const yn = ({
|
|
|
753
755
|
}, [
|
|
754
756
|
qe,
|
|
755
757
|
Fe,
|
|
756
|
-
|
|
758
|
+
ne,
|
|
757
759
|
Le
|
|
758
760
|
]), P(() => {
|
|
759
761
|
if (U !== "Busy") {
|
|
760
|
-
|
|
762
|
+
ee.current != null && (clearTimeout(ee.current), ee.current = null);
|
|
761
763
|
return;
|
|
762
764
|
}
|
|
763
|
-
return
|
|
764
|
-
|
|
765
|
+
return ee.current = setTimeout(() => {
|
|
766
|
+
ee.current = null, _("Ready"), ft(!0);
|
|
765
767
|
}, 12e3), () => {
|
|
766
|
-
|
|
768
|
+
ee.current != null && (clearTimeout(ee.current), ee.current = null);
|
|
767
769
|
};
|
|
768
770
|
}, [U]), P(() => {
|
|
769
771
|
if (!re) return;
|
|
@@ -771,7 +773,7 @@ const yn = ({
|
|
|
771
773
|
return () => clearTimeout(e);
|
|
772
774
|
}, [re]);
|
|
773
775
|
const Ct = Qe(() => {
|
|
774
|
-
const e =
|
|
776
|
+
const e = j.current;
|
|
775
777
|
if (e === "exiting") {
|
|
776
778
|
Ae("hidden");
|
|
777
779
|
const t = Me.current;
|
|
@@ -820,7 +822,7 @@ const yn = ({
|
|
|
820
822
|
}, Nt = Qe(() => {
|
|
821
823
|
}, []), wt = (e) => {
|
|
822
824
|
if (Ce.current)
|
|
823
|
-
e === "§" ? Ce.current = !1 : (Oe.current += e,
|
|
825
|
+
e === "§" ? Ce.current = !1 : (Oe.current += e, I((t) => t + e));
|
|
824
826
|
else if (e === "§") {
|
|
825
827
|
Ce.current = !0;
|
|
826
828
|
return;
|
|
@@ -866,7 +868,7 @@ const yn = ({
|
|
|
866
868
|
})();
|
|
867
869
|
}, []), P(() => {
|
|
868
870
|
const e = () => {
|
|
869
|
-
pt.current = Date.now(), Pe.current && (Pe.current = !1, We(!1), k([]), xe(""),
|
|
871
|
+
pt.current = Date.now(), Pe.current && (Pe.current = !1, We(!1), k([]), xe(""), I(""), $(!1));
|
|
870
872
|
};
|
|
871
873
|
window.addEventListener("mousemove", e), window.addEventListener("keydown", e), window.addEventListener("mousedown", e), window.addEventListener("touchstart", e);
|
|
872
874
|
const t = setInterval(async () => {
|
|
@@ -934,12 +936,12 @@ const yn = ({
|
|
|
934
936
|
), me = c(null), Te = c(
|
|
935
937
|
null
|
|
936
938
|
), ze = Qe((e = !1) => {
|
|
937
|
-
e && (ke.current = !0, m(!1), _("Ready")), v.current = [],
|
|
939
|
+
e && (ke.current = !0, m(!1), _("Ready")), v.current = [], D.current = [], L.current = !1, $(!1), we.current = 0, le.current = 0, ve.current = 0, _e.current.forEach((t) => {
|
|
938
940
|
try {
|
|
939
941
|
t.stop();
|
|
940
942
|
} catch {
|
|
941
943
|
}
|
|
942
|
-
}), De.current && (clearTimeout(De.current), De.current = null),
|
|
944
|
+
}), De.current && (clearTimeout(De.current), De.current = null), X(null), $e(""), _e.current = [];
|
|
943
945
|
}, []), Wt = async () => {
|
|
944
946
|
try {
|
|
945
947
|
const e = await navigator.mediaDevices.getUserMedia({ audio: !0 }), t = window.AudioContext || window.webkitAudioContext, s = new t(), o = s.createMediaStreamSource(e), n = s.createAnalyser();
|
|
@@ -991,18 +993,18 @@ const yn = ({
|
|
|
991
993
|
const $t = (e) => {
|
|
992
994
|
const t = e.numberOfChannels, s = e.length * t * 2 + 44, o = new ArrayBuffer(s), n = new DataView(o);
|
|
993
995
|
let a = 0;
|
|
994
|
-
const p = (
|
|
995
|
-
n.setUint16(a,
|
|
996
|
-
}, R = (
|
|
997
|
-
n.setUint32(a,
|
|
996
|
+
const p = (F) => {
|
|
997
|
+
n.setUint16(a, F, !0), a += 2;
|
|
998
|
+
}, R = (F) => {
|
|
999
|
+
n.setUint32(a, F, !0), a += 4;
|
|
998
1000
|
};
|
|
999
1001
|
R(1179011410), R(s - 8), R(1163280727), R(544501094), R(16), p(1), p(t), R(e.sampleRate), R(e.sampleRate * 2 * t), p(t * 2), p(16), R(1635017060), R(s - a - 4);
|
|
1000
1002
|
const S = [];
|
|
1001
|
-
for (let
|
|
1003
|
+
for (let F = 0; F < t; F++) S.push(e.getChannelData(F));
|
|
1002
1004
|
let x = 0;
|
|
1003
1005
|
for (; a < s; ) {
|
|
1004
|
-
for (let
|
|
1005
|
-
let H = Math.max(-1, Math.min(1, S[
|
|
1006
|
+
for (let F = 0; F < t; F++) {
|
|
1007
|
+
let H = Math.max(-1, Math.min(1, S[F][x]));
|
|
1006
1008
|
H = H < 0 ? H * 32768 : H * 32767, n.setInt16(a, H, !0), a += 2;
|
|
1007
1009
|
}
|
|
1008
1010
|
x++;
|
|
@@ -1011,7 +1013,7 @@ const yn = ({
|
|
|
1011
1013
|
}, ot = async (e, t, s = !1) => {
|
|
1012
1014
|
if (!ke.current) {
|
|
1013
1015
|
if (W.current) {
|
|
1014
|
-
|
|
1016
|
+
D.current.push({
|
|
1015
1017
|
audio: e,
|
|
1016
1018
|
visemes: t,
|
|
1017
1019
|
isNewSegment: s
|
|
@@ -1023,46 +1025,46 @@ const yn = ({
|
|
|
1023
1025
|
const o = window.AudioContext || window.webkitAudioContext, n = y.current ?? new o();
|
|
1024
1026
|
n.state === "suspended" && await n.resume(), y.current = n;
|
|
1025
1027
|
const a = window.atob(e), p = new Uint8Array(a.length);
|
|
1026
|
-
for (let
|
|
1027
|
-
p[
|
|
1028
|
+
for (let N = 0; N < a.length; N++)
|
|
1029
|
+
p[N] = a.charCodeAt(N);
|
|
1028
1030
|
const R = await n.decodeAudioData(p.buffer.slice(0));
|
|
1029
1031
|
ve.current += R.duration;
|
|
1030
1032
|
const S = n.currentTime;
|
|
1031
1033
|
let x = le.current;
|
|
1032
|
-
const
|
|
1034
|
+
const F = !L.current;
|
|
1033
1035
|
x < S && (x = S + 0.1), le.current = x + R.duration;
|
|
1034
1036
|
const H = n.createBufferSource();
|
|
1035
1037
|
H.buffer = R;
|
|
1036
|
-
let
|
|
1037
|
-
if ((!
|
|
1038
|
-
_e.current = _e.current.filter((
|
|
1038
|
+
let J = xt;
|
|
1039
|
+
if ((!J || J.context !== n) && (J = n.createAnalyser(), J.fftSize = 64, J.connect(n.destination), Bt(J)), H.connect(J), _e.current.push(H), ke.current) {
|
|
1040
|
+
_e.current = _e.current.filter((N) => N !== H);
|
|
1039
1041
|
return;
|
|
1040
1042
|
}
|
|
1041
|
-
if (
|
|
1043
|
+
if (F) {
|
|
1042
1044
|
L.current = !0, $(!0), B(
|
|
1043
1045
|
`[AUDIO] setIsSpeaking(true) - First chunk starting at ${x.toFixed(
|
|
1044
1046
|
3
|
|
1045
1047
|
)}`
|
|
1046
1048
|
), we.current = x;
|
|
1047
|
-
const
|
|
1048
|
-
be.current = performance.now() +
|
|
1049
|
+
const N = (x - S) * 1e3;
|
|
1050
|
+
be.current = performance.now() + N, B(
|
|
1049
1051
|
`[AUDIO] Response started. Initial startTime: ${x.toFixed(
|
|
1050
1052
|
3
|
|
1051
1053
|
)}, CT: ${S.toFixed(3)}`
|
|
1052
1054
|
);
|
|
1053
1055
|
}
|
|
1054
1056
|
H.start(x);
|
|
1055
|
-
const
|
|
1056
|
-
s && (Ne.current =
|
|
1057
|
-
`[AUDIO] New segment detected at +${
|
|
1057
|
+
const K = (x - we.current) * 1e3;
|
|
1058
|
+
s && (Ne.current = K, B(
|
|
1059
|
+
`[AUDIO] New segment detected at +${K.toFixed(
|
|
1058
1060
|
0
|
|
1059
1061
|
)}ms. Resetting segment offset.`
|
|
1060
|
-
)), t.forEach((
|
|
1061
|
-
const
|
|
1062
|
-
if (
|
|
1063
|
-
const ie = bn(
|
|
1062
|
+
)), t.forEach((N, se) => {
|
|
1063
|
+
const C = N.symbol ?? "";
|
|
1064
|
+
if (C) {
|
|
1065
|
+
const ie = bn(C), fe = Math.round(N.start * 1e3), Ee = Math.round((N.duration ?? 0) * 1e3), At = Ne.current + fe;
|
|
1064
1066
|
se < 3 && B(
|
|
1065
|
-
`[AUDIO] Viseme "${
|
|
1067
|
+
`[AUDIO] Viseme "${C}": segment_relative=${fe}ms, segment_offset=${Ne.current.toFixed(
|
|
1066
1068
|
0
|
|
1067
1069
|
)}ms => vtime=${At}ms`
|
|
1068
1070
|
), ie.forEach((Lt) => {
|
|
@@ -1076,19 +1078,19 @@ const yn = ({
|
|
|
1076
1078
|
}
|
|
1077
1079
|
}), _("Speaking...");
|
|
1078
1080
|
} finally {
|
|
1079
|
-
if (W.current = !1,
|
|
1080
|
-
const o =
|
|
1081
|
+
if (W.current = !1, D.current.length > 0) {
|
|
1082
|
+
const o = D.current.shift();
|
|
1081
1083
|
o && ot(o.audio, o.visemes, o.isNewSegment);
|
|
1082
1084
|
}
|
|
1083
1085
|
}
|
|
1084
1086
|
}
|
|
1085
1087
|
}, jt = async (e) => {
|
|
1086
1088
|
try {
|
|
1087
|
-
m(!0), We(!1), Oe.current = "",
|
|
1089
|
+
m(!0), We(!1), Oe.current = "", I(""), _("Processing Voice...");
|
|
1088
1090
|
const t = await e.arrayBuffer(), o = await new (window.AudioContext || window.webkitAudioContext)().decodeAudioData(t), n = $t(o), a = new FileReader();
|
|
1089
1091
|
a.readAsDataURL(n), a.onloadend = async () => {
|
|
1090
1092
|
const p = a.result.split(",")[1];
|
|
1091
|
-
ze(),
|
|
1093
|
+
ze(), te(""), he.current = "", Ce.current = !1;
|
|
1092
1094
|
const R = `${lt}/stt?token=${encodeURIComponent(
|
|
1093
1095
|
T
|
|
1094
1096
|
)}`, S = await fetch(R, {
|
|
@@ -1101,53 +1103,53 @@ const yn = ({
|
|
|
1101
1103
|
});
|
|
1102
1104
|
if (S.status === 429) {
|
|
1103
1105
|
try {
|
|
1104
|
-
const se = await S.text(),
|
|
1105
|
-
B("[STT] 429 agent at capacity:",
|
|
1106
|
+
const se = await S.text(), C = JSON.parse(se);
|
|
1107
|
+
B("[STT] 429 agent at capacity:", C?.detail);
|
|
1106
1108
|
} catch {
|
|
1107
1109
|
}
|
|
1108
|
-
|
|
1110
|
+
te(""), _("Busy"), m(!1);
|
|
1109
1111
|
return;
|
|
1110
1112
|
}
|
|
1111
1113
|
if (!S.ok) {
|
|
1112
1114
|
const se = await S.text();
|
|
1113
|
-
let
|
|
1115
|
+
let C = "STT Failed";
|
|
1114
1116
|
try {
|
|
1115
|
-
|
|
1117
|
+
C = JSON.parse(se).error || C;
|
|
1116
1118
|
} catch {
|
|
1117
|
-
se && (
|
|
1119
|
+
se && (C = se.slice(0, 200));
|
|
1118
1120
|
}
|
|
1119
|
-
throw new Error(
|
|
1121
|
+
throw new Error(C);
|
|
1120
1122
|
}
|
|
1121
1123
|
const x = S.body;
|
|
1122
1124
|
if (B("this is body" + x), !x) {
|
|
1123
1125
|
_("STT Failed"), m(!1);
|
|
1124
1126
|
return;
|
|
1125
1127
|
}
|
|
1126
|
-
const
|
|
1128
|
+
const F = x.getReader();
|
|
1127
1129
|
ke.current = !1;
|
|
1128
1130
|
const H = new TextDecoder();
|
|
1129
|
-
let
|
|
1130
|
-
const
|
|
1131
|
+
let J = "", K = !1;
|
|
1132
|
+
const N = async (se, C) => {
|
|
1131
1133
|
switch (se) {
|
|
1132
1134
|
case "transcript":
|
|
1133
|
-
|
|
1135
|
+
C.transcript != null && te(String(C.transcript));
|
|
1134
1136
|
break;
|
|
1135
1137
|
case "text": {
|
|
1136
|
-
const ie =
|
|
1138
|
+
const ie = C.delta ?? C.text ?? "";
|
|
1137
1139
|
ie && wt(ie);
|
|
1138
1140
|
break;
|
|
1139
1141
|
}
|
|
1140
1142
|
case "audio": {
|
|
1141
|
-
const ie =
|
|
1143
|
+
const ie = C.chunk, fe = C.visemes ?? [], Ee = !!C.is_new_segment;
|
|
1142
1144
|
ie && await ot(ie, fe, Ee);
|
|
1143
1145
|
break;
|
|
1144
1146
|
}
|
|
1145
1147
|
case "done": {
|
|
1146
|
-
|
|
1148
|
+
K = !0, _("Ready"), m(!1);
|
|
1147
1149
|
break;
|
|
1148
1150
|
}
|
|
1149
1151
|
case "error": {
|
|
1150
|
-
|
|
1152
|
+
K = !0, _("STT Failed"), m(!1);
|
|
1151
1153
|
break;
|
|
1152
1154
|
}
|
|
1153
1155
|
default:
|
|
@@ -1155,22 +1157,22 @@ const yn = ({
|
|
|
1155
1157
|
}
|
|
1156
1158
|
};
|
|
1157
1159
|
for (; ; ) {
|
|
1158
|
-
const { done: se, value:
|
|
1159
|
-
|
|
1160
|
-
const ie =
|
|
1160
|
+
const { done: se, value: C } = await F.read();
|
|
1161
|
+
C && (J += H.decode(C, { stream: !0 }));
|
|
1162
|
+
const ie = J.split(`
|
|
1161
1163
|
|
|
1162
1164
|
`);
|
|
1163
|
-
|
|
1165
|
+
J = ie.pop() ?? "";
|
|
1164
1166
|
for (const fe of ie) {
|
|
1165
1167
|
const Ee = Ye(fe);
|
|
1166
|
-
Ee && await
|
|
1168
|
+
Ee && await N(Ee.event, Ee.data);
|
|
1167
1169
|
}
|
|
1168
1170
|
if (se) {
|
|
1169
|
-
if (
|
|
1170
|
-
const fe = Ye(
|
|
1171
|
-
fe && await
|
|
1171
|
+
if (J.trim()) {
|
|
1172
|
+
const fe = Ye(J.trim());
|
|
1173
|
+
fe && await N(fe.event, fe.data);
|
|
1172
1174
|
}
|
|
1173
|
-
|
|
1175
|
+
K || (_("Ready"), m(!1));
|
|
1174
1176
|
break;
|
|
1175
1177
|
}
|
|
1176
1178
|
}
|
|
@@ -1179,7 +1181,7 @@ const yn = ({
|
|
|
1179
1181
|
console.error("Audio Submission Error:", t), _("STT Failed"), m(!1);
|
|
1180
1182
|
}
|
|
1181
1183
|
}, Jt = async (e) => {
|
|
1182
|
-
e && e.preventDefault(), We(!1), Oe.current = "",
|
|
1184
|
+
e && e.preventDefault(), We(!1), Oe.current = "", I(""), !(!E || ce) && await qt(E);
|
|
1183
1185
|
}, Ye = (e) => {
|
|
1184
1186
|
const t = e.split(/\r?\n/);
|
|
1185
1187
|
let s = "", o = "";
|
|
@@ -1215,12 +1217,12 @@ const yn = ({
|
|
|
1215
1217
|
{ role: "user", content: E || "..." },
|
|
1216
1218
|
{ role: "assistant", content: o }
|
|
1217
1219
|
];
|
|
1218
|
-
Ut(n), Ie.current = [...v.current], _("Ready"), m(!1),
|
|
1220
|
+
Ut(n), Ie.current = [...v.current], _("Ready"), m(!1), te("");
|
|
1219
1221
|
break;
|
|
1220
1222
|
}
|
|
1221
1223
|
case "error": {
|
|
1222
1224
|
const s = t.message ?? "Unknown error";
|
|
1223
|
-
Oe.current = s,
|
|
1225
|
+
Oe.current = s, I(s), _("Agent Failed"), m(!1);
|
|
1224
1226
|
break;
|
|
1225
1227
|
}
|
|
1226
1228
|
}
|
|
@@ -1251,11 +1253,11 @@ const yn = ({
|
|
|
1251
1253
|
});
|
|
1252
1254
|
if (a.status === 429) {
|
|
1253
1255
|
try {
|
|
1254
|
-
const
|
|
1255
|
-
B("[CHAT] 429 agent at capacity:",
|
|
1256
|
+
const F = await a.json();
|
|
1257
|
+
B("[CHAT] 429 agent at capacity:", F?.detail);
|
|
1256
1258
|
} catch {
|
|
1257
1259
|
}
|
|
1258
|
-
|
|
1260
|
+
te(""), _("Busy"), m(!1);
|
|
1259
1261
|
return;
|
|
1260
1262
|
}
|
|
1261
1263
|
if (!a.ok)
|
|
@@ -1270,25 +1272,25 @@ const yn = ({
|
|
|
1270
1272
|
const S = new TextDecoder();
|
|
1271
1273
|
let x = "";
|
|
1272
1274
|
for (; ; ) {
|
|
1273
|
-
const { done:
|
|
1275
|
+
const { done: F, value: H } = await R.read();
|
|
1274
1276
|
B(
|
|
1275
|
-
`[SSE] Chunk received. done=${
|
|
1277
|
+
`[SSE] Chunk received. done=${F}, length=${H?.length || 0}`
|
|
1276
1278
|
), H && (x += S.decode(H, { stream: !0 }));
|
|
1277
|
-
const
|
|
1279
|
+
const J = x.split(`
|
|
1278
1280
|
|
|
1279
1281
|
`);
|
|
1280
|
-
x =
|
|
1281
|
-
for (const
|
|
1282
|
-
B(`[SSE] Processing block: ${
|
|
1283
|
-
const
|
|
1284
|
-
|
|
1282
|
+
x = J.pop() ?? "";
|
|
1283
|
+
for (const K of J) {
|
|
1284
|
+
B(`[SSE] Processing block: ${K.slice(0, 50)}...`);
|
|
1285
|
+
const N = Ye(K);
|
|
1286
|
+
N && (B(`[SSE] Event: ${N.event}`), kt(N.event, N.data));
|
|
1285
1287
|
}
|
|
1286
|
-
if (
|
|
1288
|
+
if (F) {
|
|
1287
1289
|
if (B("[SSE] Stream finished"), x.trim()) {
|
|
1288
|
-
const
|
|
1289
|
-
|
|
1290
|
+
const K = Ye(x.trim());
|
|
1291
|
+
K && kt(K.event, K.data);
|
|
1290
1292
|
}
|
|
1291
|
-
_("Ready"), m(!1),
|
|
1293
|
+
_("Ready"), m(!1), te("");
|
|
1292
1294
|
break;
|
|
1293
1295
|
}
|
|
1294
1296
|
}
|
|
@@ -1312,10 +1314,10 @@ const yn = ({
|
|
|
1312
1314
|
e && (e.scrollTop = e.scrollHeight);
|
|
1313
1315
|
}, [mt]), /* @__PURE__ */ oe("div", { className: "avatar-widget-container", children: [
|
|
1314
1316
|
/* @__PURE__ */ oe("div", { className: "avatar-input-area", children: [
|
|
1315
|
-
|
|
1317
|
+
ne !== "hidden" ? /* @__PURE__ */ l(
|
|
1316
1318
|
"div",
|
|
1317
1319
|
{
|
|
1318
|
-
className: `avatar-thinking-tab${
|
|
1320
|
+
className: `avatar-thinking-tab${ne === "exiting" ? " avatar-thinking-tab--exiting" : ne === "entering" ? " avatar-thinking-tab--entering" : ""}`,
|
|
1319
1321
|
onAnimationEnd: Ct,
|
|
1320
1322
|
children: Le === It ? /* @__PURE__ */ l(
|
|
1321
1323
|
"a",
|
|
@@ -1477,7 +1479,7 @@ const yn = ({
|
|
|
1477
1479
|
id: "avatar-text-input",
|
|
1478
1480
|
type: "text",
|
|
1479
1481
|
value: E,
|
|
1480
|
-
onChange: (e) =>
|
|
1482
|
+
onChange: (e) => te(e.target.value),
|
|
1481
1483
|
placeholder: U === "Busy" ? "Assisting another user" : He || "Ask me anything",
|
|
1482
1484
|
disabled: ce || U === "Busy",
|
|
1483
1485
|
autoComplete: "off",
|
|
@@ -1595,7 +1597,7 @@ const yn = ({
|
|
|
1595
1597
|
"div",
|
|
1596
1598
|
{
|
|
1597
1599
|
className: "avatar-canvas-layer",
|
|
1598
|
-
style: { width:
|
|
1600
|
+
style: { width: O, height: O },
|
|
1599
1601
|
children: /* @__PURE__ */ oe(
|
|
1600
1602
|
Qt,
|
|
1601
1603
|
{
|