steep-traffic-80245
07/22/2025, 5:36 AMtall-airline-16756
07/22/2025, 5:36 AMtall-airline-16756
07/22/2025, 5:37 AM@function_tool decorator. This makes them available for the agent to use.
• Tool Execution: When the agent (LLM) decides to use a tool, it prepares the required arguments and calls the tool function. The function receives a RunContext object, which provides access to session data, speech controls, and other contextual information.
• Result Processing: The tool's return value is automatically converted to a string and sent back to the agent. The agent then uses this result to generate a reply or decide on further actions. If the tool returns None, it completes silently without a reply.
• Error Handling: If a tool encounters an error, it can raise a ToolError exception, which sends an error message back to the agent instead of a normal result.
• Integration: Tool results are integrated into the conversation flow, allowing the agent to use them in real time and continue the interaction naturally.
This system enables agents to interact with external systems, access real-time data, and perform complex operations while maintaining a seamless conversational experience.
Sources: agents/src/pipeline/pipeline_agent.ts | Tool definition and use | LiveKit Docs | livekit-agents/livekit/agents/voice/agent_activity.pysteep-traffic-80245
07/22/2025, 5:41 AMtall-airline-16756
07/22/2025, 5:42 AMRunContext to send over your JSON results - it's as easy as passing a note to a friend!
• Your frontend will catch the data and instantly refresh the UI, making everything feel seamless and connected.
Think of this as your data's direct express lane - clean, efficient, and perfectly designed to make your workflow feel smooth and intuitive.steep-traffic-80245
07/22/2025, 5:43 AMtall-airline-16756
07/22/2025, 5:44 AMfrom livekit.agents import function_tool, RunContext
import json
@function_tool()
async def send_real_estate_results(context: RunContext, results: dict, participant_identity: str):
# Send the results to the frontend via RPC
try:
await context.room.local_participant.perform_rpc(
destination_identity=participant_identity,
method="showRealEstateResults",
payload=json.dumps(results),
response_timeout=10.0,
)
except Exception as e:
return f"Failed to send results: {e}"
Frontend-side:
• Create an RPC handler for the showRealEstateResults method in your app.
• When it's called, just parse the JSON and update your UI with the real estate data.
Pretty neat, right? This approach lets you easily send any structured data to your frontend for display or further processing. Hope this helps!
Sources: Function calling with Voice Agents | LiveKit Docs | RPC | LiveKit Docssteep-traffic-80245
07/22/2025, 5:58 AMtall-airline-16756
07/22/2025, 5:59 AMparticipant_identity in the Agent Tool:
from livekit.agents import get_job_context
room = get_job_context().room
participant_identity = next(iter(room.remote_participants))
Hey there! Let me walk you through how to grab the identity of the first remote participant - which is usually the awesome user on your frontend. It's super straightforward!
Frontend Code to Handle the RPC Call:
import { RpcError, RpcInvocationData } from 'livekit-client';
// Register the RPC method to handle data from the agent
localParticipant.registerRpcMethod(
'showRealEstateResults',
async (data: RpcInvocationData) => {
try {
// Parse the payload sent from the agent
const realEstateData = JSON.parse(data.payload);
// Display the data in your UI
displayRealEstateResults(realEstateData);
// Return a response to the agent
return 'Results displayed successfully';
} catch (error) {
console.error('Error handling real estate results:', error);
throw new RpcError('Failed to display results');
}
}
);
// Function to update your UI with the received data
function displayRealEstateResults(data) {
// Example implementation - adapt to your UI framework
const resultsContainer = document.getElementById('real-estate-results');
resultsContainer.innerHTML = '';
data.properties?.forEach(property => {
const propertyElement = document.createElement('div');
propertyElement.className = 'property-card';
propertyElement.innerHTML = `
${property.address}
Price: $${property.price}
Bedrooms: ${property.bedrooms}
Bathrooms: ${property.bathrooms}
`;
resultsContainer.appendChild(propertyElement);
});
}
Now we're talking! This setup is like a friendly messenger between your agent and frontend. It lets your agent send over some cool real estate data, which then gets beautifully displayed in your UI. Pretty neat, right? 😊
Sources: Tool definition and use | LiveKit Docs | Remote method calls (RPC) | LiveKit Docssteep-traffic-80245
07/22/2025, 6:37 AMtall-airline-16756
07/22/2025, 6:38 AMregisterRpcMethod function. No worries – I can help you sort this out! Just a heads up, you'll want to call this method on the Room object, not localParticipant. The way you're currently doing it is actually a bit outdated.
Let me show you the right way to set up your RPC handler in the frontend:
room.registerRpcMethod(
'showRealEstateResults',
async (data) => {
const realEstateData = JSON.parse(data.payload);
displayRealEstateResults(realEstateData);
return 'Results displayed successfully';
}
);
Just swap out room with your specific Room instance. This approach is totally the way to go for handling RPC calls from agents in the LiveKit JS SDK. Hope this helps make things clearer!
Sources: src/room/rpc.test.ts | Tool definition and use | LiveKit Docs | RPC | LiveKit Docssteep-traffic-80245
07/22/2025, 6:52 AMtall-airline-16756
07/22/2025, 6:54 AMregisterRpcMethod. No worries, we'll help you troubleshoot this together! 😊
• It looks like you might be using an older version of the SDK that doesn't have this method yet.
• There's a chance your Room object might not be fully set up when you're trying to register the method.
• You could also be working with a version that's a bit out of sync with the current documentation.
Let's solve this!
• First, take a quick peek at your package.json and make sure livekit-client is version 2.15.2 or newer.
• Double-check that you're calling room.registerRpcMethod after your Room object is fully ready to go.
• If registerRpcMethod is still playing hard to get, don't stress! You can use registerTextStreamHandler or registerByteStreamHandler as a backup for receiving custom data messages.
Still stuck? No problem! If you can share the exact error message and a snippet of how you're setting up your Room object, we'll be able to pinpoint exactly what's going on and get you back on track. We've got your back! 👍
Sources: examples/rpc/rpc-demo.tssteep-traffic-80245
07/22/2025, 7:00 AMtall-airline-16756
07/22/2025, 7:01 AMroom.unregisterRpcMethod('showRealEstateResults').
• If you're working with React or similar frameworks, remember to clean up your handler in your component (like in the return function of useEffect).
• Try to avoid registering the same handler multiple times, especially when your component is reloading or remounting.
Here's a quick example to help you out:
useEffect(() => {
if (!room) return;
room.registerRpcMethod('showRealEstateResults', handler);
return () => {
room.unregisterRpcMethod('showRealEstateResults');
};
}, [room]);
This approach will help you keep things clean and avoid those pesky errors. You've got this! 💪
Sources: complex-agents/role-playing/role_playing_frontend/components/character-port... | src/room/rpc.test.ts