"use client";
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
import {
VoiceOrb,
VoiceConnectButton,
VoiceMuteButton,
VoiceDisconnectButton,
deriveVoiceOrbState,
} from "@/components/assistant-ui/voice";
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
import {
AuiIf,
MessagePrimitive,
ThreadPrimitive,
useAuiState,
useVoiceState,
useVoiceVolume,
} from "@assistant-ui/react";
import { ArrowDownIcon } from "lucide-react";
import type { FC } from "react";
export const VoiceThread: FC = () => {
return (
s.thread.isEmpty}>
{() => }
);
};
const VoiceWelcome: FC = () => {
return (
Voice Conversation
Tap connect to start speaking
);
};
const ThreadScrollToBottom: FC = () => {
return (
);
};
const VoiceControlCenter: FC = () => {
return (
s.thread.voice == null || s.thread.voice.status.type === "ended"
}
>
s.thread.voice?.status.type === "starting"}>
Connecting...
s.thread.voice?.status.type === "running"}>
);
};
const BAR_WEIGHTS = [0.4, 0.65, 0.85, 1.0, 0.9, 0.75, 0.5];
const VoiceWaveform: FC = () => {
const voiceState = useVoiceState();
const state = deriveVoiceOrbState(voiceState);
const volume = useVoiceVolume();
const isActive = state === "listening" || state === "speaking";
return (
{BAR_WEIGHTS.map((weight, i) => {
const scale = isActive ? 0.1 + volume * 0.9 * weight : 0.1;
return (
);
})}
);
};
const ThreadMessage: FC = () => {
const role = useAuiState((s) => s.message.role);
if (role === "user") return ;
return ;
};
const AssistantMessage: FC = () => {
return (
{({ part }) => {
if (part.type === "text") return ;
return null;
}}
);
};
const UserMessage: FC = () => {
return (
);
};