@zeroweight/react 0.2.30 → 0.2.31
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.
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { useMemo as be, useRef as
|
|
1
|
+
import { useMemo as be, useRef as x, useState as S, useCallback as b, useEffect as g } from "react";
|
|
2
2
|
import { ZeroWeightRenderer as Se, ActionQueue as xe, VoiceActivityDetector as ke } from "@zeroweight/renderer";
|
|
3
|
-
import { jsxs as k, jsx as r, Fragment as
|
|
4
|
-
import { useVoiceAssistant as we, useLocalParticipant as Ae, useIsSpeaking as Te, useDataChannel as Ie, RoomAudioRenderer as Re, LiveKitRoom as
|
|
3
|
+
import { jsxs as k, jsx as r, Fragment as U } from "react/jsx-runtime";
|
|
4
|
+
import { useVoiceAssistant as we, useLocalParticipant as Ae, useIsSpeaking as Te, useDataChannel as Ie, RoomAudioRenderer as Re, LiveKitRoom as Ce } from "@livekit/components-react";
|
|
5
5
|
import "@livekit/components-styles";
|
|
6
|
-
import { Loader2 as
|
|
7
|
-
const ze = 3e4, Pe = 120, Fe = "wss://prod-project-pazuyq69.livekit.cloud",
|
|
8
|
-
function Ue(
|
|
6
|
+
import { Loader2 as Q, MicOff as Me, Mic as Ee, Power as Le, Activity as De } from "lucide-react";
|
|
7
|
+
const ze = 3e4, Pe = 120, Fe = "wss://prod-project-pazuyq69.livekit.cloud", te = "https://api.zeroweight.ai";
|
|
8
|
+
function Ue(m) {
|
|
9
9
|
const {
|
|
10
10
|
avatarId: a,
|
|
11
11
|
apiKey: n = null,
|
|
@@ -13,166 +13,166 @@ function Ue(v) {
|
|
|
13
13
|
turnOffMicWhenAISpeaking: d = !0,
|
|
14
14
|
livekitUrl: w = Fe,
|
|
15
15
|
sessionDuration: p = Pe,
|
|
16
|
-
inactivityTimeout:
|
|
17
|
-
} =
|
|
16
|
+
inactivityTimeout: A = ze
|
|
17
|
+
} = m, T = w, C = be(() => {
|
|
18
18
|
if (u) return u;
|
|
19
|
-
const
|
|
19
|
+
const t = n ? { "X-ZW-Api-Key": n } : void 0;
|
|
20
20
|
return {
|
|
21
21
|
getBundle: async (f) => {
|
|
22
|
-
const
|
|
23
|
-
`${
|
|
22
|
+
const I = await fetch(
|
|
23
|
+
`${te}/avatars/bundle/${encodeURIComponent(
|
|
24
24
|
f
|
|
25
25
|
)}`,
|
|
26
|
-
{ headers:
|
|
26
|
+
{ headers: t }
|
|
27
27
|
);
|
|
28
|
-
if (!
|
|
28
|
+
if (!I.ok)
|
|
29
29
|
throw new Error(
|
|
30
|
-
`Failed to fetch avatar bundle (${
|
|
30
|
+
`Failed to fetch avatar bundle (${I.status} ${I.statusText})`
|
|
31
31
|
);
|
|
32
|
-
return
|
|
32
|
+
return I.json();
|
|
33
33
|
},
|
|
34
34
|
getLiveKitToken: async (f) => {
|
|
35
|
-
const
|
|
35
|
+
const I = new URLSearchParams({
|
|
36
36
|
avatar_id: f,
|
|
37
37
|
name: "anonymuous"
|
|
38
|
-
}),
|
|
39
|
-
`${
|
|
40
|
-
{ headers:
|
|
38
|
+
}), l = await fetch(
|
|
39
|
+
`${te}/livekit/token?${I.toString()}`,
|
|
40
|
+
{ headers: t }
|
|
41
41
|
);
|
|
42
|
-
if (!
|
|
42
|
+
if (!l.ok)
|
|
43
43
|
throw new Error(
|
|
44
|
-
`Failed to fetch LiveKit token (${
|
|
44
|
+
`Failed to fetch LiveKit token (${l.status} ${l.statusText})`
|
|
45
45
|
);
|
|
46
|
-
return
|
|
46
|
+
return l.json();
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
|
-
}, [u, n]), s =
|
|
49
|
+
}, [u, n]), s = x(null), v = x(null), i = x(null), y = x(null), [h, M] = S("idle"), [o, D] = S(null), [e, c] = S(
|
|
50
50
|
/* @__PURE__ */ new Set(["listening"])
|
|
51
|
-
), [
|
|
51
|
+
), [_, z] = S({
|
|
52
52
|
listening: { kind: "looped" },
|
|
53
53
|
speaking: { kind: "looped" }
|
|
54
|
-
}), [
|
|
55
|
-
}), [oe,
|
|
56
|
-
const
|
|
57
|
-
if (!
|
|
58
|
-
let f =
|
|
59
|
-
return f || (f = document.createElement("canvas"), f.style.width = "100%", f.style.height = "100%", f.style.display = "block",
|
|
54
|
+
}), [P, j] = S(!1), [ie, q] = S(null), [$, O] = S(!1), [K, J] = S(!1), [ae, W] = S(p), E = x(null), N = x(() => {
|
|
55
|
+
}), [oe, Z] = S(!1), [se, X] = S(0.8), L = x(null), V = h === "ready", Y = b(() => {
|
|
56
|
+
const t = s.current;
|
|
57
|
+
if (!t) return null;
|
|
58
|
+
let f = t.querySelector("canvas");
|
|
59
|
+
return f || (f = document.createElement("canvas"), f.style.width = "100%", f.style.height = "100%", f.style.display = "block", t.appendChild(f)), v.current = f, f;
|
|
60
60
|
}, []);
|
|
61
|
-
|
|
62
|
-
let
|
|
61
|
+
g(() => {
|
|
62
|
+
let t = !1;
|
|
63
63
|
return (async () => {
|
|
64
|
-
const
|
|
65
|
-
if (!
|
|
66
|
-
const
|
|
67
|
-
i.current =
|
|
68
|
-
const
|
|
69
|
-
|
|
64
|
+
const I = Y();
|
|
65
|
+
if (!I) return;
|
|
66
|
+
const l = new Se();
|
|
67
|
+
i.current = l;
|
|
68
|
+
const H = new xe((R, F) => {
|
|
69
|
+
l.play(R, F);
|
|
70
70
|
});
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}),
|
|
74
|
-
|
|
75
|
-
}),
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
return
|
|
71
|
+
y.current = H, l.on("stateChanged", (R) => {
|
|
72
|
+
t || M(R);
|
|
73
|
+
}), l.on("dimensions", (R, F) => {
|
|
74
|
+
t || D({ width: R, height: F });
|
|
75
|
+
}), l.on("actionLoaded", (R) => {
|
|
76
|
+
t || c((F) => {
|
|
77
|
+
const ee = new Set(F);
|
|
78
|
+
return ee.add(R), ee;
|
|
79
79
|
});
|
|
80
|
-
}),
|
|
81
|
-
|
|
82
|
-
}),
|
|
83
|
-
|
|
80
|
+
}), l.on("allActionsLoaded", () => {
|
|
81
|
+
t || j(!1);
|
|
82
|
+
}), l.on("ready", () => {
|
|
83
|
+
t || (z(l.getActionMetadata()), H.setActionMetadata(l.getActionMetadata()));
|
|
84
84
|
});
|
|
85
85
|
try {
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
} catch (
|
|
91
|
-
console.error("[useAvatarSession] Init failed:",
|
|
86
|
+
j(!0);
|
|
87
|
+
const R = await C.getBundle(a);
|
|
88
|
+
if (t || (await l.init(I, { payload: R.payload }), t)) return;
|
|
89
|
+
z(l.getActionMetadata()), H.setActionMetadata(l.getActionMetadata());
|
|
90
|
+
} catch (R) {
|
|
91
|
+
console.error("[useAvatarSession] Init failed:", R);
|
|
92
92
|
}
|
|
93
93
|
})(), () => {
|
|
94
|
-
|
|
94
|
+
t = !0, i.current?.destroy(), i.current = null, y.current = null;
|
|
95
95
|
};
|
|
96
|
-
}, [a,
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}, [
|
|
101
|
-
const ce =
|
|
102
|
-
if (!(
|
|
96
|
+
}, [a, Y, C]);
|
|
97
|
+
const G = x(!1);
|
|
98
|
+
g(() => {
|
|
99
|
+
V && i.current && e.has("wave_hand") && !G.current && (i.current.play("wave_hand", "listening"), G.current = !0);
|
|
100
|
+
}, [V, e]);
|
|
101
|
+
const ce = b(async () => {
|
|
102
|
+
if (!($ || K)) {
|
|
103
103
|
O(!0);
|
|
104
104
|
try {
|
|
105
105
|
await navigator.mediaDevices.getUserMedia({ audio: !0 });
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
} catch (
|
|
109
|
-
console.error("[useAvatarSession] Failed to connect:",
|
|
106
|
+
const t = await C.getLiveKitToken(a);
|
|
107
|
+
q(t.token);
|
|
108
|
+
} catch (t) {
|
|
109
|
+
console.error("[useAvatarSession] Failed to connect:", t), O(!1);
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
}, [K,
|
|
113
|
-
E.current && (clearInterval(E.current), E.current = null),
|
|
112
|
+
}, [$, K, a, C]), B = b(() => {
|
|
113
|
+
E.current && (clearInterval(E.current), E.current = null), W(p), L.current && (clearTimeout(L.current), L.current = null), q(null), J(!1), O(!1), y.current?.forceListening();
|
|
114
114
|
}, [p]);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}, [
|
|
118
|
-
const le =
|
|
119
|
-
|
|
120
|
-
}, []), ue =
|
|
121
|
-
E.current && clearInterval(E.current),
|
|
122
|
-
|
|
115
|
+
g(() => {
|
|
116
|
+
N.current = B;
|
|
117
|
+
}, [B]);
|
|
118
|
+
const le = b(() => {
|
|
119
|
+
J(!0), O(!1);
|
|
120
|
+
}, []), ue = b(() => {
|
|
121
|
+
E.current && clearInterval(E.current), W(p), E.current = setInterval(() => {
|
|
122
|
+
W((t) => t <= 1 ? (clearInterval(E.current), E.current = null, setTimeout(() => N.current(), 0), 0) : t - 1);
|
|
123
123
|
}, 1e3);
|
|
124
|
-
}, [p]), de =
|
|
125
|
-
const f = Math.floor(
|
|
126
|
-
return `${f}:${
|
|
124
|
+
}, [p]), de = b((t) => {
|
|
125
|
+
const f = Math.floor(t / 60).toString().padStart(2, "0"), I = (t % 60).toString().padStart(2, "0");
|
|
126
|
+
return `${f}:${I}`;
|
|
127
127
|
}, []);
|
|
128
|
-
|
|
128
|
+
g(() => () => {
|
|
129
129
|
E.current && clearInterval(E.current);
|
|
130
130
|
}, []);
|
|
131
|
-
const pe =
|
|
132
|
-
(
|
|
133
|
-
if (!
|
|
134
|
-
|
|
131
|
+
const pe = b(
|
|
132
|
+
(t) => {
|
|
133
|
+
if (!t) {
|
|
134
|
+
L.current && (clearTimeout(L.current), L.current = null);
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
},
|
|
137
|
+
L.current || (L.current = setTimeout(() => {
|
|
138
|
+
L.current = null, N.current();
|
|
139
|
+
}, A));
|
|
140
140
|
},
|
|
141
|
-
[
|
|
142
|
-
), fe =
|
|
143
|
-
|
|
144
|
-
}, []), ge =
|
|
145
|
-
|
|
146
|
-
}, []), he =
|
|
147
|
-
|
|
148
|
-
}, []), me =
|
|
149
|
-
|
|
150
|
-
}, []), ve =
|
|
141
|
+
[A]
|
|
142
|
+
), fe = b(() => {
|
|
143
|
+
Z((t) => !t);
|
|
144
|
+
}, []), ge = b((t) => {
|
|
145
|
+
Z(t);
|
|
146
|
+
}, []), he = b((t) => {
|
|
147
|
+
X(t);
|
|
148
|
+
}, []), me = b(() => {
|
|
149
|
+
X((t) => t > 0 ? 0 : 1);
|
|
150
|
+
}, []), ve = b(() => {
|
|
151
151
|
i.current?.interrupt();
|
|
152
|
-
}, []), ye =
|
|
153
|
-
i.current?.play(
|
|
152
|
+
}, []), ye = b((t) => {
|
|
153
|
+
i.current?.play(t, "listening");
|
|
154
154
|
}, []);
|
|
155
155
|
return {
|
|
156
156
|
containerRef: s,
|
|
157
157
|
renderer: i.current,
|
|
158
|
-
actionQueue:
|
|
159
|
-
rendererState:
|
|
158
|
+
actionQueue: y.current,
|
|
159
|
+
rendererState: h,
|
|
160
160
|
avatarDimensions: o,
|
|
161
|
-
loadedActions:
|
|
162
|
-
actionMetadata:
|
|
163
|
-
isLoadingActions:
|
|
164
|
-
isEngineReady:
|
|
165
|
-
token:
|
|
166
|
-
isConnecting:
|
|
167
|
-
isConnected:
|
|
168
|
-
livekitUrl:
|
|
161
|
+
loadedActions: e,
|
|
162
|
+
actionMetadata: _,
|
|
163
|
+
isLoadingActions: P,
|
|
164
|
+
isEngineReady: V,
|
|
165
|
+
token: ie,
|
|
166
|
+
isConnecting: $,
|
|
167
|
+
isConnected: K,
|
|
168
|
+
livekitUrl: T,
|
|
169
169
|
timeRemaining: ae,
|
|
170
170
|
formatTime: de,
|
|
171
171
|
micMuted: oe,
|
|
172
172
|
volume: se,
|
|
173
173
|
turnOffMicWhenAISpeaking: d,
|
|
174
174
|
connect: ce,
|
|
175
|
-
disconnect:
|
|
175
|
+
disconnect: B,
|
|
176
176
|
toggleMic: fe,
|
|
177
177
|
setMicMuted: ge,
|
|
178
178
|
setVolume: he,
|
|
@@ -185,7 +185,7 @@ function Ue(v) {
|
|
|
185
185
|
};
|
|
186
186
|
}
|
|
187
187
|
const _e = ({
|
|
188
|
-
session:
|
|
188
|
+
session: m,
|
|
189
189
|
style: a,
|
|
190
190
|
loadingContent: n
|
|
191
191
|
}) => /* @__PURE__ */ k(
|
|
@@ -218,14 +218,14 @@ const _e = ({
|
|
|
218
218
|
/* @__PURE__ */ r(
|
|
219
219
|
"div",
|
|
220
220
|
{
|
|
221
|
-
ref:
|
|
221
|
+
ref: m.containerRef,
|
|
222
222
|
style: {
|
|
223
223
|
position: "relative",
|
|
224
224
|
width: "100%",
|
|
225
225
|
height: "100%",
|
|
226
226
|
transition: "all 0.5s ease-in-out"
|
|
227
227
|
},
|
|
228
|
-
children: !
|
|
228
|
+
children: !m.isEngineReady && /* @__PURE__ */ r(
|
|
229
229
|
"div",
|
|
230
230
|
{
|
|
231
231
|
style: {
|
|
@@ -249,7 +249,7 @@ const _e = ({
|
|
|
249
249
|
},
|
|
250
250
|
children: [
|
|
251
251
|
/* @__PURE__ */ r(
|
|
252
|
-
|
|
252
|
+
Q,
|
|
253
253
|
{
|
|
254
254
|
style: {
|
|
255
255
|
width: 40,
|
|
@@ -282,7 +282,7 @@ const _e = ({
|
|
|
282
282
|
)
|
|
283
283
|
]
|
|
284
284
|
}
|
|
285
|
-
),
|
|
285
|
+
), ne = {
|
|
286
286
|
flexShrink: 0,
|
|
287
287
|
borderRadius: 9999,
|
|
288
288
|
padding: 16,
|
|
@@ -292,7 +292,7 @@ const _e = ({
|
|
|
292
292
|
display: "inline-flex",
|
|
293
293
|
alignItems: "center",
|
|
294
294
|
justifyContent: "center"
|
|
295
|
-
},
|
|
295
|
+
}, re = {
|
|
296
296
|
position: "relative",
|
|
297
297
|
display: "inline-flex",
|
|
298
298
|
alignItems: "center",
|
|
@@ -308,7 +308,7 @@ const _e = ({
|
|
|
308
308
|
border: "none",
|
|
309
309
|
cursor: "pointer"
|
|
310
310
|
}, je = ({
|
|
311
|
-
session:
|
|
311
|
+
session: m,
|
|
312
312
|
style: a
|
|
313
313
|
}) => {
|
|
314
314
|
const {
|
|
@@ -317,31 +317,31 @@ const _e = ({
|
|
|
317
317
|
isConnected: d,
|
|
318
318
|
isConnecting: w,
|
|
319
319
|
isEngineReady: p,
|
|
320
|
-
loadedActions:
|
|
321
|
-
connect:
|
|
322
|
-
disconnect:
|
|
323
|
-
} =
|
|
324
|
-
...
|
|
320
|
+
loadedActions: A,
|
|
321
|
+
connect: T,
|
|
322
|
+
disconnect: C
|
|
323
|
+
} = m, [s, v] = S(!1), [i, y] = S(!1), h = p && A.has("listening") && A.has("speaking"), M = n ? {
|
|
324
|
+
...ne,
|
|
325
325
|
background: "rgba(239,68,68,0.1)",
|
|
326
326
|
color: "#f87171",
|
|
327
327
|
boxShadow: "inset 0 0 0 1px rgba(239,68,68,0.3)",
|
|
328
328
|
...s ? { background: "rgba(239,68,68,0.2)" } : {}
|
|
329
329
|
} : {
|
|
330
|
-
...
|
|
330
|
+
...ne,
|
|
331
331
|
background: s ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.4)",
|
|
332
332
|
color: "#fff",
|
|
333
333
|
boxShadow: "inset 0 0 0 1px rgba(255,255,255,0.1)"
|
|
334
334
|
}, o = d ? {
|
|
335
|
-
...
|
|
335
|
+
...re,
|
|
336
336
|
background: i ? "rgba(239,68,68,0.22)" : "rgba(239,68,68,0.14)",
|
|
337
337
|
boxShadow: "inset 0 0 0 1px rgba(239,68,68,0.5), 0 0 20px rgba(239,68,68,0.2)"
|
|
338
338
|
} : {
|
|
339
|
-
...
|
|
339
|
+
...re,
|
|
340
340
|
background: "linear-gradient(to right, #7c3aed, #db2777, #f97316)",
|
|
341
341
|
boxShadow: "0 0 30px rgba(236,72,153,0.3)",
|
|
342
342
|
opacity: i ? 0.9 : 1
|
|
343
343
|
};
|
|
344
|
-
return (w || !
|
|
344
|
+
return (w || !h) && (o.opacity = 0.5, o.cursor = "not-allowed"), /* @__PURE__ */ k(
|
|
345
345
|
"div",
|
|
346
346
|
{
|
|
347
347
|
style: {
|
|
@@ -379,32 +379,32 @@ const _e = ({
|
|
|
379
379
|
{
|
|
380
380
|
type: "button",
|
|
381
381
|
onClick: u,
|
|
382
|
-
onMouseEnter: () =>
|
|
383
|
-
onMouseLeave: () =>
|
|
384
|
-
style:
|
|
382
|
+
onMouseEnter: () => v(!0),
|
|
383
|
+
onMouseLeave: () => v(!1),
|
|
384
|
+
style: M,
|
|
385
385
|
title: n ? "Unmute mic" : "Mute mic",
|
|
386
|
-
children: n ? /* @__PURE__ */ r(
|
|
386
|
+
children: n ? /* @__PURE__ */ r(Me, { size: 24 }) : /* @__PURE__ */ r(Ee, { size: 24 })
|
|
387
387
|
}
|
|
388
388
|
),
|
|
389
389
|
/* @__PURE__ */ r(
|
|
390
390
|
"button",
|
|
391
391
|
{
|
|
392
392
|
type: "button",
|
|
393
|
-
onClick: d ?
|
|
394
|
-
onMouseEnter: () =>
|
|
395
|
-
onMouseLeave: () =>
|
|
396
|
-
disabled: !d && (w || !
|
|
393
|
+
onClick: d ? C : T,
|
|
394
|
+
onMouseEnter: () => y(!0),
|
|
395
|
+
onMouseLeave: () => y(!1),
|
|
396
|
+
disabled: !d && (w || !h),
|
|
397
397
|
style: o,
|
|
398
|
-
children: w ? /* @__PURE__ */ k(
|
|
399
|
-
/* @__PURE__ */ r(
|
|
398
|
+
children: w ? /* @__PURE__ */ k(U, { children: [
|
|
399
|
+
/* @__PURE__ */ r(Q, { size: 20, style: { animation: "zwr-spin 1s linear infinite" } }),
|
|
400
400
|
/* @__PURE__ */ r("span", { children: "Connecting..." })
|
|
401
|
-
] }) : !d && !
|
|
402
|
-
/* @__PURE__ */ r(
|
|
401
|
+
] }) : !d && !h ? /* @__PURE__ */ k(U, { children: [
|
|
402
|
+
/* @__PURE__ */ r(Q, { size: 20, style: { animation: "zwr-spin 1s linear infinite" } }),
|
|
403
403
|
/* @__PURE__ */ r("span", { children: "Loading Avatar..." })
|
|
404
|
-
] }) : d ? /* @__PURE__ */ k(
|
|
404
|
+
] }) : d ? /* @__PURE__ */ k(U, { children: [
|
|
405
405
|
/* @__PURE__ */ r(Le, { size: 20 }),
|
|
406
406
|
/* @__PURE__ */ r("span", { children: "End Session" })
|
|
407
|
-
] }) : /* @__PURE__ */ k(
|
|
407
|
+
] }) : /* @__PURE__ */ k(U, { children: [
|
|
408
408
|
/* @__PURE__ */ r(De, { size: 20 }),
|
|
409
409
|
/* @__PURE__ */ r("span", { children: "Start Session" })
|
|
410
410
|
] })
|
|
@@ -417,9 +417,9 @@ const _e = ({
|
|
|
417
417
|
}
|
|
418
418
|
);
|
|
419
419
|
}, Oe = ({
|
|
420
|
-
session:
|
|
420
|
+
session: m
|
|
421
421
|
}) => {
|
|
422
|
-
const { isConnected: a, timeRemaining: n, formatTime: u } =
|
|
422
|
+
const { isConnected: a, timeRemaining: n, formatTime: u } = m, d = a && n <= 30, w = a && n > 30 && n <= 60, p = {
|
|
423
423
|
display: "flex",
|
|
424
424
|
alignItems: "center",
|
|
425
425
|
gap: 8,
|
|
@@ -444,7 +444,7 @@ const _e = ({
|
|
|
444
444
|
boxShadow: "0 4px 12px rgba(0,0,0,0.3)"
|
|
445
445
|
}
|
|
446
446
|
};
|
|
447
|
-
return /* @__PURE__ */ k(
|
|
447
|
+
return /* @__PURE__ */ k(U, { children: [
|
|
448
448
|
/* @__PURE__ */ r("style", { children: `
|
|
449
449
|
@keyframes zwr-pulse {
|
|
450
450
|
0%, 100% { opacity: 1; }
|
|
@@ -484,110 +484,118 @@ const _e = ({
|
|
|
484
484
|
] })
|
|
485
485
|
] });
|
|
486
486
|
}, $e = ({
|
|
487
|
-
session:
|
|
487
|
+
session: m
|
|
488
488
|
}) => {
|
|
489
|
-
const { renderer: a, actionQueue: n, micMuted: u, volume: d, setInactivityActive: w, loadedActions: p } =
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
}, [p]),
|
|
493
|
-
const
|
|
494
|
-
if (!a || !
|
|
495
|
-
const
|
|
496
|
-
return a.onOneshotComplete((
|
|
497
|
-
const P =
|
|
489
|
+
const { renderer: a, actionQueue: n, micMuted: u, volume: d, setInactivityActive: w, loadedActions: p } = m, { turnOffMicWhenAISpeaking: A, setMicMuted: T } = m, C = x(!1), { state: s, audioTrack: v } = we(), i = Ae(), y = Te(i.localParticipant), h = x(null), M = x(p);
|
|
490
|
+
g(() => {
|
|
491
|
+
M.current = p;
|
|
492
|
+
}, [p]), g(() => {
|
|
493
|
+
const e = i.localParticipant;
|
|
494
|
+
if (!a || !e) return;
|
|
495
|
+
const c = new TextEncoder();
|
|
496
|
+
return a.onOneshotComplete((z) => {
|
|
497
|
+
const P = c.encode(
|
|
498
498
|
JSON.stringify({
|
|
499
499
|
type: "ACTION_FINISHED",
|
|
500
|
-
action:
|
|
500
|
+
action: z
|
|
501
501
|
})
|
|
502
502
|
);
|
|
503
|
-
|
|
503
|
+
e.publishData(P, {
|
|
504
504
|
reliable: !0
|
|
505
|
-
}).catch((
|
|
506
|
-
console.error("[LiveKitAvatarProvider] Failed to publish action completion:",
|
|
505
|
+
}).catch((j) => {
|
|
506
|
+
console.error("[LiveKitAvatarProvider] Failed to publish action completion:", j);
|
|
507
507
|
});
|
|
508
508
|
});
|
|
509
|
-
}, [a, i.localParticipant]),
|
|
509
|
+
}, [a, i.localParticipant]), g(() => {
|
|
510
510
|
if (!n) return;
|
|
511
|
-
const
|
|
511
|
+
const e = new ke({
|
|
512
512
|
threshold: 8e-3,
|
|
513
513
|
analyseIntervalMs: 30,
|
|
514
514
|
speechStartFrames: 1,
|
|
515
515
|
speechPauseFrames: 30,
|
|
516
516
|
turnEndFrames: 50
|
|
517
517
|
});
|
|
518
|
-
return
|
|
518
|
+
return h.current = e, e.on("speechStart", () => {
|
|
519
519
|
n.setTurnActive(!0), n.setSpeechState("speaking");
|
|
520
|
-
}),
|
|
520
|
+
}), e.on("turnEnd", () => {
|
|
521
521
|
n.setTurnActive(!1);
|
|
522
522
|
}), () => {
|
|
523
|
-
|
|
523
|
+
e.stop(), h.current = null;
|
|
524
524
|
};
|
|
525
|
-
}, [n]),
|
|
526
|
-
const
|
|
527
|
-
if (
|
|
528
|
-
if (
|
|
529
|
-
const
|
|
530
|
-
|
|
525
|
+
}, [n]), g(() => {
|
|
526
|
+
const e = h.current;
|
|
527
|
+
if (e)
|
|
528
|
+
if (v?.publication?.track) {
|
|
529
|
+
const c = v.publication.track.mediaStreamTrack;
|
|
530
|
+
c && e.start(c);
|
|
531
531
|
} else
|
|
532
|
-
|
|
533
|
-
}, [
|
|
534
|
-
const o =
|
|
535
|
-
return
|
|
532
|
+
e.stop();
|
|
533
|
+
}, [v?.publication?.track]);
|
|
534
|
+
const o = x(null), D = x(!1);
|
|
535
|
+
return g(() => {
|
|
536
536
|
if (!n) return;
|
|
537
|
-
const
|
|
538
|
-
|
|
539
|
-
o.current = null,
|
|
537
|
+
const e = s;
|
|
538
|
+
e === "speaking" ? (o.current && (clearTimeout(o.current), o.current = null), n.setTurnActive(!0), n.setSpeechState("speaking")) : e === "listening" || e === "idle" ? (o.current && (clearTimeout(o.current), o.current = null), h.current?.endTurn(), n.setTurnActive(!1)) : e === "thinking" && (o.current || (o.current = setTimeout(() => {
|
|
539
|
+
o.current = null, h.current?.endTurn(), n.setTurnActive(!1);
|
|
540
540
|
}, 500)));
|
|
541
|
-
}, [s, n]),
|
|
542
|
-
const
|
|
543
|
-
if (!
|
|
544
|
-
|
|
541
|
+
}, [s, n]), g(() => {
|
|
542
|
+
const e = s === "speaking";
|
|
543
|
+
if (!A) {
|
|
544
|
+
D.current = e;
|
|
545
545
|
return;
|
|
546
546
|
}
|
|
547
|
-
const
|
|
548
|
-
!
|
|
549
|
-
}, [u,
|
|
547
|
+
const c = D.current;
|
|
548
|
+
!c && e ? u || T(!0) : c && !e && u && T(!1), D.current = e;
|
|
549
|
+
}, [u, T, s, A]), g(() => {
|
|
550
|
+
if (!A || !n) return;
|
|
551
|
+
const e = (c) => {
|
|
552
|
+
c || T(!1);
|
|
553
|
+
};
|
|
554
|
+
return n.on("turnChanged", e), () => {
|
|
555
|
+
n.off("turnChanged", e);
|
|
556
|
+
};
|
|
557
|
+
}, [n, T, A]), g(() => () => {
|
|
550
558
|
o.current && clearTimeout(o.current);
|
|
551
|
-
}, []), Ie((
|
|
559
|
+
}, []), Ie((e) => {
|
|
552
560
|
try {
|
|
553
|
-
const
|
|
554
|
-
if (
|
|
555
|
-
const P =
|
|
556
|
-
if (!
|
|
561
|
+
const _ = new TextDecoder().decode(e.payload), z = JSON.parse(_);
|
|
562
|
+
if (z.type === "AVATAR_UPDATE") {
|
|
563
|
+
const P = z.action;
|
|
564
|
+
if (!M.current.has(P))
|
|
557
565
|
return;
|
|
558
566
|
n?.dispatch(P);
|
|
559
567
|
}
|
|
560
|
-
} catch (
|
|
561
|
-
console.error("[LiveKitAvatarProvider] Failed to parse data message:",
|
|
568
|
+
} catch (c) {
|
|
569
|
+
console.error("[LiveKitAvatarProvider] Failed to parse data message:", c);
|
|
562
570
|
}
|
|
563
|
-
}),
|
|
564
|
-
w(!(s === "speaking") && !
|
|
565
|
-
}, [
|
|
571
|
+
}), g(() => {
|
|
572
|
+
w(!(s === "speaking") && !y);
|
|
573
|
+
}, [y, w, s]), g(() => {
|
|
566
574
|
if (!n) return;
|
|
567
|
-
const
|
|
568
|
-
(!
|
|
569
|
-
}, [
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
console.error("[LiveKitAvatarProvider] Failed to set mic state:",
|
|
575
|
+
const e = !!v;
|
|
576
|
+
(!e || s === "disconnected") && (h.current?.endTurn(), n.forceListening()), C.current = e;
|
|
577
|
+
}, [v, s, n]), g(() => {
|
|
578
|
+
const e = i.localParticipant;
|
|
579
|
+
e && e.setMicrophoneEnabled(!u).catch((c) => {
|
|
580
|
+
console.error("[LiveKitAvatarProvider] Failed to set mic state:", c);
|
|
573
581
|
});
|
|
574
582
|
}, [u, i.localParticipant]), /* @__PURE__ */ r("div", { style: { position: "absolute", bottom: 80, left: 8, right: 8, display: "flex", flexDirection: "column", gap: 8 }, children: /* @__PURE__ */ r(Re, { volume: d }) });
|
|
575
583
|
}, Qe = ({
|
|
576
|
-
avatarId:
|
|
584
|
+
avatarId: m,
|
|
577
585
|
apiKey: a,
|
|
578
586
|
api: n,
|
|
579
587
|
turnOffMicWhenAISpeaking: u,
|
|
580
588
|
livekitUrl: d,
|
|
581
589
|
sessionDuration: w,
|
|
582
590
|
inactivityTimeout: p,
|
|
583
|
-
style:
|
|
584
|
-
className:
|
|
585
|
-
loadingContent:
|
|
591
|
+
style: A,
|
|
592
|
+
className: T,
|
|
593
|
+
loadingContent: C,
|
|
586
594
|
customControls: s,
|
|
587
|
-
customStatusBadge:
|
|
595
|
+
customStatusBadge: v
|
|
588
596
|
}) => {
|
|
589
597
|
const i = Ue({
|
|
590
|
-
avatarId:
|
|
598
|
+
avatarId: m,
|
|
591
599
|
apiKey: a,
|
|
592
600
|
api: n,
|
|
593
601
|
turnOffMicWhenAISpeaking: u,
|
|
@@ -595,16 +603,16 @@ const _e = ({
|
|
|
595
603
|
sessionDuration: w,
|
|
596
604
|
inactivityTimeout: p
|
|
597
605
|
}), {
|
|
598
|
-
token:
|
|
599
|
-
isConnected:
|
|
600
|
-
avatarDimensions:
|
|
606
|
+
token: y,
|
|
607
|
+
isConnected: h,
|
|
608
|
+
avatarDimensions: M,
|
|
601
609
|
disconnect: o,
|
|
602
|
-
startSessionTimer:
|
|
610
|
+
startSessionTimer: D
|
|
603
611
|
} = i;
|
|
604
612
|
return /* @__PURE__ */ k(
|
|
605
613
|
"section",
|
|
606
614
|
{
|
|
607
|
-
className:
|
|
615
|
+
className: T,
|
|
608
616
|
style: {
|
|
609
617
|
position: "relative",
|
|
610
618
|
display: "flex",
|
|
@@ -618,11 +626,11 @@ const _e = ({
|
|
|
618
626
|
height: "80vh",
|
|
619
627
|
width: "auto",
|
|
620
628
|
maxWidth: "100%",
|
|
621
|
-
aspectRatio:
|
|
622
|
-
...
|
|
629
|
+
aspectRatio: M ? `${M.width} / ${M.height}` : "3 / 4",
|
|
630
|
+
...A
|
|
623
631
|
},
|
|
624
632
|
children: [
|
|
625
|
-
/* @__PURE__ */ r(_e, { session: i, loadingContent:
|
|
633
|
+
/* @__PURE__ */ r(_e, { session: i, loadingContent: C }),
|
|
626
634
|
/* @__PURE__ */ k(
|
|
627
635
|
"div",
|
|
628
636
|
{
|
|
@@ -647,7 +655,7 @@ const _e = ({
|
|
|
647
655
|
justifyContent: "space-between"
|
|
648
656
|
},
|
|
649
657
|
children: [
|
|
650
|
-
|
|
658
|
+
v ? v(i) : /* @__PURE__ */ r(Oe, { session: i }),
|
|
651
659
|
/* @__PURE__ */ r("div", {})
|
|
652
660
|
]
|
|
653
661
|
}
|
|
@@ -656,16 +664,16 @@ const _e = ({
|
|
|
656
664
|
]
|
|
657
665
|
}
|
|
658
666
|
),
|
|
659
|
-
/* @__PURE__ */ r("div", { style: { display: "none" }, children:
|
|
660
|
-
|
|
667
|
+
/* @__PURE__ */ r("div", { style: { display: "none" }, children: y && d && /* @__PURE__ */ r(
|
|
668
|
+
Ce,
|
|
661
669
|
{
|
|
662
670
|
serverUrl: d,
|
|
663
|
-
token:
|
|
671
|
+
token: y,
|
|
664
672
|
connect: !0,
|
|
665
673
|
video: !1,
|
|
666
674
|
audio: !0,
|
|
667
675
|
onConnected: () => {
|
|
668
|
-
i.markConnected(),
|
|
676
|
+
i.markConnected(), D();
|
|
669
677
|
},
|
|
670
678
|
onDisconnected: o,
|
|
671
679
|
children: /* @__PURE__ */ r($e, { session: i })
|