import { useState, useEffect, useRef } from 'react' export default function Robot() { const [message, setMessage] = useState(''); const [listening, setListening] = useState(false); const [conversation, setConversation] = useState<{"role": "user" | "assistant", "content": string}[]>([]) const conversationRef = useRef(null); const [conversationIndex, setConversationIndex] = useState(0); const sendMessage = async () => { try { const response = await fetch("http://localhost:8000/message", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ message }), }); const data = await response.json(); console.log(data); } catch (error) { console.error("Error sending message: ", error); } }; useEffect(() => { const eventSource = new EventSource("http://localhost:8000/sse"); eventSource.onmessage = (event) => { try { const data = JSON.parse(event.data); if ("voice_active" in data) setListening(data.voice_active); if ("speech" in data) setConversation(conversation => [...conversation, {"role": "user", "content": data.speech}]); if ("llm_response" in data) setConversation(conversation => [...conversation, {"role": "assistant", "content": data.llm_response}]); } catch { console.log("Unparsable SSE message:", event.data); } }; return () => { eventSource.close(); }; }, [conversationIndex]); useEffect(() => { if (!conversationRef || !conversationRef.current) return; conversationRef.current.scrollTop = conversationRef.current.scrollHeight; }, [conversation]); return ( <>

Robot interaction

Force robot speech

setMessage(e.target.value)} onKeyDown={(e) => e.key === "Enter" && sendMessage().then(() => setMessage(""))} placeholder="Enter a message" />

Conversation

Listening {listening ? "🟢" : "🔴"}

{conversation.map((item, i) => (

{item["content"]}

))}
); }