i am interested in having my front end work as fol...
# ask-ai
e
i am interested in having my front end work as follows during a user conversation with a livekit agent: 1. there is a big green circle on the page, which will contain messages and pulse as follows: 2. when the user is speaking, i want the circle to say "Listening" 3. when the user is done speaking, i want the circle to say "Thinking" and pulse 4. once the ai starts speaking again, i want the circle to say "AI Speaking" and pulse 5. when the AI is done speaking i want it stop pulsing and say "Waiting for Response" 6. when the AI starts speaking, again, i want the circle to say "AI speaking" and pulse i am using VAD + the Multilingual model for turn detection (and it's working perfectly right now). how would you recommend i implement it so that the front end works as i've described?
t
Thanks for reaching out, Jason. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
I'd love to help you out! Could you please let me know which frontend framework or technologies you're using (like React, Angular, or just plain JavaScript)? This way, I can provide the best guidance tailored just for your needs.
e
javascript
t
I'm glad you're looking to implement this functionality in JavaScript! Here's a friendly step-by-step guide to help you through the process: 1. Backend Setup: You'll want to use the LiveKit Multilingual Turn Detector along with Silero VAD for turn detection. Setting up your backend to send real-time End-of-Utterance (EOU) probability updates to the frontend via Remote Procedure Calls (RPC) will be key. 2. Frontend Integration: On the frontend side, you can register an RPC handler in your JavaScript to receive these updates. Here's a simple example to get you started:
Copy code
room.localParticipant.rpc.on('received', async (request) => {
  if (request.method === 'client.eou_update') {
    const payload = JSON.parse(request.payload);
    const eouPercentage = payload.percentage;

    // Update UI dynamically
    document.getElementById('status-circle').textContent = `${eouPercentage.toFixed(1)}%`;
    updateCircleState(eouPercentage); // Custom function to handle animations
  }
});
1. UI Updates: Using the EOU percentage you receive, you can update the circle's text and animations dynamically. Here's a helpful example:
Copy code
function updateCircleState(eouPercentage) {
  const circle = document.getElementById('status-circle');
  if (eouPercentage > 80) {
    circle.textContent = 'Thinking';
    circle.classList.add('pulse');
  } else {
    circle.textContent = 'Listening';
    circle.classList.remove('pulse');
  }
}
This method will help your frontend reflect the conversation state in real-time smoothly. If you have any questions or would like me to walk you through any part in more detail, please don’t hesitate to ask. I’m here to help! Sources: Building the all-in-one platform for voice AI agents | Building the all-in-one platform for voice AI agents | livekit-plugins/livekit-plugins-turn-detector/README.md | Turn detection and interruptions | LiveKit Docs | complex-agents/turn-taking/agent.py
e
when you say "setting up your backend to send realtime EOU ....", do you mean the agent code?
t
Absolutely! When I mention "setting up your backend to send real-time EOU updates," I’m specifically talking about the agent code. What you’d do is configure the agent to use the LiveKit Multilingual Turn Detector and Silero VAD for detecting turns. Then, the agent code will send End-of-Utterance (EOU) probability updates to the frontend through Remote Procedure Calls (RPC). If you’d like, I’d be happy to walk you through the details on how to adjust the agent code for this—just let me know!
e
i'm already using the multilingual turn detector and silero vad. however, please look at this thread between myself and cursor. OpenAI Call Triggering: Looking at the agent code, the OpenAI calls are triggered by LiveKit's built-in turn detection system: • Line 544: turn_detection=MultilingualModel() - Uses LiveKit's multilingual turn detector • Line 547: vad=ctx.proc.userdata["vad"] - Uses VAD (Voice Activity Detection) • Lines 552-553: min_endpointing_delay=1.0, max_endpointing_delay=5.0 - Controls when turns end So the current system uses LiveKit's built-in turn detection (not EOU percentages) to determine when the user finishes speaking and trigger OpenAI calls. Questions for you: 1. Should I create new functions for the EOU-based button states, or modify the existing approach? 2. Agent changes: Since the agent already has turn detection working, should I add RPC message sending to the existing turn detection events, or do you want to ask LiveKit first about the best approach? The current system is working with LiveKit's turn detection, so we might be able to hook into those existing events rather than implementing a separate EOU percentage system. my question is whether we can hook into the existing events to inform the button states rather than implementing a separate EOU percentage system.
t
Thanks for reaching out! I wanted to share that LiveKit doesn’t have built-in turn detection events that automatically update the frontend UI. Instead, the recommended approach is to use the EOU (End-of-Utterance) percentage system. Here’s a friendly overview of how this works: 1. You’d use the existing turn detection tools like the Multilingual Turn Detector and Silero VAD within your agent code. 2. Then, you can add custom Remote Procedure Calls (RPC) to send EOU probability updates from your agent to the frontend after each turn is detected. 3. On the frontend side, you’d register an RPC handler to receive these updates and update the UI dynamically. It’s important to note that while LiveKit uses signals like
on_start_of_speech
and
on_end_of_speech
internally for agent decisions, these aren’t automatically sent to the frontend unless you forward them explicitly through RPC or data channels. If you’d like, I’m here to help guide you through setting up this custom EOU percentage system, just like in the LiveKit examples. Feel free to ask anytime! Sources: Improving voice AI's turn detection with transformers | livekit-agents/livekit/agents/voice/agent_activity.py | complex-agents/turn-taking/agent.py
e
Subject: RPC Handler Not Working - 'LocalParticipant' object has no attribute 'rpc' Hi LiveKit team, I'm trying to implement real-time EOU (End-of-Utterance) updates from my agent to the frontend using RPC, but I'm getting errors. Here's my setup: Agent Side (Python):
Copy code
python
async def send_eou_update(eou_percentage):
    try:
        payload = json.dumps({"type": "eou_update", "percentage": eou_percentage})
        await ctx.room.local_participant.rpc("client.eou_update", payload)
        print(f":bar_chart: Sent EOU update: {eou_percentage:.1f}%", flush=True)
    except Exception as e:
        print(f":x: Failed to send EOU RPC: {e}", flush=True)
Frontend Side (JavaScript):
Copy code
javascript
function setupRPCHandler() {
    if (livekitInterviewer && livekitInterviewer.room) {
        livekitInterviewer.room.localParticipant.rpc.on('received', async (request) => {
            if (request.method === 'client.eou_update') {
                const payload = JSON.parse(request.payload);
                const eouPercentage = payload.percentage;
                updateButtonFromEOU(eouPercentage);
            }
        });
    }
}
Error I'm getting:
Copy code
:x: Failed to send EOU RPC: 'LocalParticipant' object has no attribute 'rpc'
Questions: 1. What's the correct way to send RPC messages from the agent to the frontend? 2. What's the correct way to set up the RPC handler on the frontend? 3. Are there any specific LiveKit SDK versions or configurations needed for RPC to work? My setup: - LiveKit Agent SDK (Python) - LiveKit Client SDK (JavaScript) - Local development environment Thanks for your help!
t
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!