Use voiceAssistant components (#98)
This commit is contained in:
@@ -12,28 +12,22 @@ import {
|
||||
PlaygroundTabbedTile,
|
||||
PlaygroundTile,
|
||||
} from "@/components/playground/PlaygroundTile";
|
||||
import { AgentMultibandAudioVisualizer } from "@/components/visualization/AgentMultibandAudioVisualizer";
|
||||
import { useConfig } from "@/hooks/useConfig";
|
||||
import { useMultibandTrackVolume } from "@/hooks/useTrackVolume";
|
||||
import { TranscriptionTile } from "@/transcriptions/TranscriptionTile";
|
||||
import {
|
||||
TrackReferenceOrPlaceholder,
|
||||
BarVisualizer,
|
||||
VideoTrack,
|
||||
useConnectionState,
|
||||
useDataChannel,
|
||||
useLocalParticipant,
|
||||
useRemoteParticipants,
|
||||
useRoomInfo,
|
||||
useTracks,
|
||||
useVoiceAssistant,
|
||||
} from "@livekit/components-react";
|
||||
import {
|
||||
ConnectionState,
|
||||
LocalParticipant,
|
||||
RoomEvent,
|
||||
Track,
|
||||
} from "livekit-client";
|
||||
import { ConnectionState, LocalParticipant, Track } from "livekit-client";
|
||||
import { QRCodeSVG } from "qrcode.react";
|
||||
import { ReactNode, useCallback, useEffect, useMemo, useState } from "react";
|
||||
import tailwindTheme from "../../lib/tailwindTheme.preval";
|
||||
|
||||
export interface PlaygroundMeta {
|
||||
name: string;
|
||||
@@ -55,15 +49,10 @@ export default function Playground({
|
||||
}: PlaygroundProps) {
|
||||
const { config, setUserSettings } = useConfig();
|
||||
const { name } = useRoomInfo();
|
||||
const [messages, setMessages] = useState<ChatMessageType[]>([]);
|
||||
const [transcripts, setTranscripts] = useState<ChatMessageType[]>([]);
|
||||
const { localParticipant } = useLocalParticipant();
|
||||
|
||||
const participants = useRemoteParticipants({
|
||||
updateOnlyOn: [RoomEvent.ParticipantMetadataChanged],
|
||||
});
|
||||
const agentParticipant = participants.find((p) => p.isAgent);
|
||||
const isAgentConnected = agentParticipant !== undefined;
|
||||
const voiceAssistant = useVoiceAssistant();
|
||||
|
||||
const roomState = useConnectionState();
|
||||
const tracks = useTracks();
|
||||
@@ -75,32 +64,12 @@ export default function Playground({
|
||||
}
|
||||
}, [config, localParticipant, roomState]);
|
||||
|
||||
let agentAudioTrack: TrackReferenceOrPlaceholder | undefined;
|
||||
const aat = tracks.find(
|
||||
(trackRef) =>
|
||||
trackRef.publication.kind === Track.Kind.Audio &&
|
||||
trackRef.participant.isAgent
|
||||
);
|
||||
if (aat) {
|
||||
agentAudioTrack = aat;
|
||||
} else if (agentParticipant) {
|
||||
agentAudioTrack = {
|
||||
participant: agentParticipant,
|
||||
source: Track.Source.Microphone,
|
||||
};
|
||||
}
|
||||
|
||||
const agentVideoTrack = tracks.find(
|
||||
(trackRef) =>
|
||||
trackRef.publication.kind === Track.Kind.Video &&
|
||||
trackRef.participant.isAgent
|
||||
);
|
||||
|
||||
const subscribedVolumes = useMultibandTrackVolume(
|
||||
agentAudioTrack?.publication?.track,
|
||||
5
|
||||
);
|
||||
|
||||
const localTracks = tracks.filter(
|
||||
({ participant }) => participant instanceof LocalParticipant
|
||||
);
|
||||
@@ -111,11 +80,6 @@ export default function Playground({
|
||||
({ source }) => source === Track.Source.Microphone
|
||||
);
|
||||
|
||||
const localMultibandVolume = useMultibandTrackVolume(
|
||||
localMicTrack?.publication.track,
|
||||
20
|
||||
);
|
||||
|
||||
const onDataReceived = useCallback(
|
||||
(msg: any) => {
|
||||
if (msg.topic === "transcription") {
|
||||
@@ -181,6 +145,18 @@ export default function Playground({
|
||||
);
|
||||
}, [agentVideoTrack, config, roomState]);
|
||||
|
||||
useEffect(() => {
|
||||
document.body.style.setProperty(
|
||||
"--lk-theme-color",
|
||||
// @ts-ignore
|
||||
tailwindTheme.colors[config.settings.theme_color]["500"]
|
||||
);
|
||||
document.body.style.setProperty(
|
||||
"--lk-drop-shadow",
|
||||
`var(--lk-theme-color) 0px 0px 18px`
|
||||
);
|
||||
}, [config.settings.theme_color]);
|
||||
|
||||
const audioTileContent = useMemo(() => {
|
||||
const disconnectedContent = (
|
||||
<div className="flex flex-col items-center justify-center gap-2 text-gray-700 text-center w-full">
|
||||
@@ -195,19 +171,15 @@ export default function Playground({
|
||||
</div>
|
||||
);
|
||||
|
||||
// TODO: keep it in the speaking state until we come up with a better protocol for agent states
|
||||
const visualizerContent = (
|
||||
<div className="flex items-center justify-center w-full">
|
||||
<AgentMultibandAudioVisualizer
|
||||
state="speaking"
|
||||
barWidth={30}
|
||||
minBarHeight={30}
|
||||
maxBarHeight={150}
|
||||
accentColor={config.settings.theme_color}
|
||||
accentShade={500}
|
||||
frequencies={subscribedVolumes}
|
||||
borderRadius={12}
|
||||
gap={16}
|
||||
<div
|
||||
className={`flex items-center justify-center w-full h-48 [--lk-va-bar-width:30px] [--lk-va-bar-gap:20px] [--lk-fg:var(--lk-theme-color)]`}
|
||||
>
|
||||
<BarVisualizer
|
||||
state={voiceAssistant.state}
|
||||
trackRef={voiceAssistant.audioTrack}
|
||||
barCount={5}
|
||||
options={{ minHeight: 20 }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -216,29 +188,29 @@ export default function Playground({
|
||||
return disconnectedContent;
|
||||
}
|
||||
|
||||
if (!agentAudioTrack) {
|
||||
if (!voiceAssistant.audioTrack) {
|
||||
return waitingContent;
|
||||
}
|
||||
|
||||
return visualizerContent;
|
||||
}, [
|
||||
agentAudioTrack,
|
||||
voiceAssistant.audioTrack,
|
||||
config.settings.theme_color,
|
||||
subscribedVolumes,
|
||||
roomState,
|
||||
voiceAssistant.state,
|
||||
]);
|
||||
|
||||
const chatTileContent = useMemo(() => {
|
||||
if (agentAudioTrack) {
|
||||
if (voiceAssistant.audioTrack) {
|
||||
return (
|
||||
<TranscriptionTile
|
||||
agentAudioTrack={agentAudioTrack}
|
||||
agentAudioTrack={voiceAssistant.audioTrack}
|
||||
accentColor={config.settings.theme_color}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <></>;
|
||||
}, [config.settings.theme_color, agentAudioTrack]);
|
||||
}, [config.settings.theme_color, voiceAssistant.audioTrack]);
|
||||
|
||||
const settingsTileContent = useMemo(() => {
|
||||
return (
|
||||
@@ -284,7 +256,7 @@ export default function Playground({
|
||||
<NameValueRow
|
||||
name="Agent connected"
|
||||
value={
|
||||
isAgentConnected ? (
|
||||
voiceAssistant.agent ? (
|
||||
"TRUE"
|
||||
) : roomState === ConnectionState.Connected ? (
|
||||
<LoadingSVG diameter={12} strokeWidth={2} />
|
||||
@@ -293,7 +265,7 @@ export default function Playground({
|
||||
)
|
||||
}
|
||||
valueColor={
|
||||
isAgentConnected
|
||||
voiceAssistant.agent
|
||||
? `${config.settings.theme_color}-500`
|
||||
: "gray-500"
|
||||
}
|
||||
@@ -318,7 +290,7 @@ export default function Playground({
|
||||
title="Microphone"
|
||||
deviceSelectorKind="audioinput"
|
||||
>
|
||||
<AudioInputTile frequencies={localMultibandVolume} />
|
||||
<AudioInputTile trackRef={localMicTrack} />
|
||||
</ConfigurationPanelItem>
|
||||
)}
|
||||
<div className="w-full">
|
||||
@@ -350,12 +322,11 @@ export default function Playground({
|
||||
localParticipant,
|
||||
name,
|
||||
roomState,
|
||||
isAgentConnected,
|
||||
localVideoTrack,
|
||||
localMicTrack,
|
||||
localMultibandVolume,
|
||||
themeColors,
|
||||
setUserSettings,
|
||||
voiceAssistant.agent,
|
||||
]);
|
||||
|
||||
let mobileTabs: PlaygroundTab[] = [];
|
||||
|
||||
Reference in New Issue
Block a user