jolly-eve-3916
08/05/2025, 11:56 PMtall-airline-16756
08/05/2025, 11:56 PMtall-airline-16756
08/05/2025, 11:57 PMdestinationIdentity parameter in the performRpc method on the React Native client? If not, this might explain why the agent isn't receiving the call.
• Have you verified that the Python agent has fully joined the room before the RPC call is made? Timing issues could cause the agent to miss the call.
These details will help us pinpoint the issue and provide accurate guidance.jolly-eve-3916
08/06/2025, 12:08 AMtall-airline-16756
08/06/2025, 12:08 AMperformRpc call. Here’s a simple way to do it:
1. Log the Agent's Identity: Add a quick log in the Python agent to grab its identity when it connects:
<http://logger.info|logger.info>(f"Local participant identity: {ctx.room.local_participant.identity}")
2. Retrieve the Agent's Identity on the Client: Grab the agent’s identity from the room’s participant list like this:
const agent = room.participants.find(p => p.metadata === 'agent');
const agentIdentity = agent?.identity;
3. Update the RPC Call: Don’t forget to include the destinationIdentity in your performRpc method:
const result = await localParticipant.performRpc({
destinationIdentity: agentIdentity,
method: "start_turn",
payload: JSON.stringify({ participant_id: patientId }),
});
Following these steps should make sure your RPC call reaches the Python agent just right. If you hit any snags or want to chat more about it, just let me know—I’m here to help!jolly-eve-3916
08/06/2025, 12:15 AMtall-airline-16756
08/06/2025, 12:16 AMdestinationIdentity. Plus, I’ve included some troubleshooting tips to help you out:
1. Method Registration: Double-check that the RPC method name in your Python agent exactly matches the one the client is calling. For example:
@ctx.room.local_participant.register_rpc_method("start_turn")
2. Permissions: Make sure the token connecting the participants has all the necessary grants for RPC operations. Missing permissions can block the calls.
3. Participant State: Confirm your Python agent is still connected to the room when the RPC call happens. If it disconnects, the call won’t go through.
4. Payload Size: Keep the payload size under 15KiB—anything bigger might cause errors.
5. Response Timeout: Check that responseTimeout is long enough for your agent to process the request. If it takes too long, the call will time out.
6. Server-Side Debugging: While LiveKit Cloud doesn’t have a direct way to debug RPC routing on the server side, you can add detailed logging on both the client and agent to follow the call’s path.
Also, if you’re seeing the log message "Unable to verify RPC method registration," it might mean there’s a hiccup with how the methods are registered. Make sure you’re registering methods after the session starts, and that the names are unique and correctly set up.
If you want, feel free to share more details or error logs—I’m here to help you get this sorted!
Sources: livekit-rtc/livekit/rtc/rpc.pyjolly-eve-3916
08/06/2025, 12:34 AMtall-airline-16756
08/06/2025, 12:34 AMawait ctx.connect().
2. Register RPC Methods Right After Connecting: As soon as you’re connected, go ahead and register your RPC methods using ctx.room.local_participant.register_rpc_method(). This way, the methods are ready to go as soon as your agent joins.
3. Start the Session Once Registration is Done: After you’ve registered your RPC methods, you can start the session or move on to other tasks.
Here’s a quick example to show you how it all fits together:
async def entrypoint(ctx: JobContext):
await ctx.connect()
# Register RPC methods after connecting
@ctx.room.local_participant.register_rpc_method("ping")
async def ping(data: rtc.RpcInvocationData):
return {"pong": True}
# Start session
session = AgentSession(...)
await session.start(agent=assistant, room=ctx.room)
This way, the local participant is ready when you register your RPC methods, and you won’t run into that pesky "cannot access local participant before connecting" error. If anything’s unclear or you want more examples, just let me know—I’m happy to help!jolly-eve-3916
08/06/2025, 12:48 AMtall-airline-16756
08/06/2025, 12:48 AMroom.remoteParticipants is empty even though participants are connected, don’t worry—this can happen for a few reasons. Let’s walk through some common causes and how you can troubleshoot them:
1. Room Connection State: Make sure the room is fully connected before you check remoteParticipants. You can do this by checking room.connectionState. If the room isn’t connected yet, the list will naturally be empty.
2. Participant Event Listeners: Double-check that you’re listening for participant events like ParticipantConnected and ParticipantDisconnected. These events keep the remoteParticipants list updated as people join or leave.
3. State Delay: Sometimes there’s a tiny delay before remoteParticipants updates. You might want to add a short delay or poll the property a bit after confirming the room is connected.
4. SDK Version: It’s a good idea to be on the latest LiveKit SDK version, as older versions might handle remoteParticipants differently or have bugs.
Here’s a quick example to help you handle this smoothly:
// Make sure the room is connected
if (room.connectionState === ConnectionState.Connected) {
console.log("Remote participants:", room.remoteParticipants.values());
} else {
console.log("Room is not connected");
}
// Listen for participant connection events
room.on(RoomEvent.ParticipantConnected, (participant) => {
console.log("Participant connected:", participant.identity);
});
room.on(RoomEvent.ParticipantDisconnected, (participant) => {
console.log("Participant disconnected:", participant.identity);
});
Give these a try, and feel free to reach out if you want to chat more or need a hand with anything else!jolly-eve-3916
08/06/2025, 12:52 AMtall-airline-16756
08/06/2025, 12:52 AMCanPublish and CanPublishData permissions, since those are needed for RPC to work. Here’s an example:
from livekit import api
token = api.AccessToken() \
.with_identity("participant identity") \
.with_grants(
api.VideoGrants(
room_join=True,
room="your-room-name",
can_publish=True,
can_publish_data=True,
)
).to_jwt()
2. Verify RPC Method Registration: Double-check that the Python agent has properly registered the RPC methods using register_rpc_method. Like this:
@ctx.room.local_participant.register_rpc_method("start_turn")
async def start_turn(data: rtc.RpcInvocationData):
return {"status": "turn_started"}
3. Confirm Participant Connection: Make sure both the client and agent are connected to the same room, and that the agent shows up in the client’s remoteParticipants.
4. Enable Error Handling: It’s a good idea to add some error handling on the client side to catch any hiccups with the RPC call:
try {
const response = await localParticipant.performRpc({
destinationIdentity: agentIdentity,
method: "start_turn",
payload: JSON.stringify({ participant_id: patientId }),
});
console.log("RPC response:", response);
} catch (error) {
console.error("RPC call failed:", error);
}
If you give these steps a try and still run into trouble, just let me know—I’m here to help!jolly-eve-3916
08/06/2025, 1:03 AMtall-airline-16756
08/06/2025, 1:04 AM@ctx.room.local_participant.register_rpc_method("start_turn")
async def start_turn(data: rtc.RpcInvocationData):
<http://logger.info|logger.info>("========== PTT RPC CALLED: start_turn ==========")
return {"status": "turn_started"}
2. Review RPC Call Details: Confirm that the client is using the right destinationIdentity and method name. Also, check that the payload is formatted correctly and the responseTimeout is long enough.
3. Check Agent Permissions: Make sure the agent’s token has all the needed permissions like CanPublish and CanPublishData. Missing these can stop RPC from working.
4. Turn on Detailed Logging: Add logging on both sides to follow the RPC call’s journey. For example:
<http://logger.info|logger.info>(f"RPC call started: {method}")
try:
response = await room.local_participant.perform_rpc(
destination_identity='recipient-identity',
method=method,
payload=payload
)
<http://logger.info|logger.info>(f"RPC call completed successfully: {response}")
except Exception as e:
logger.error(f"RPC call failed: {e}")
5. Check Connection Status: Make sure your agent is fully connected to the room before sending RPC calls. You can watch connection events to confirm this.
6. Try It Out in the Playground: Use LiveKit’s playground environment to test your RPC setup. This can help you see if the issue is specific to your setup.
Give these a shot and let me know how it goes! If you need more help, I’m here for you.
Sources: livekit-rtc/livekit/rtc/_proto/rpc_pb2.py | rpc/rpc_agent.py | Voice AI quickstart | LiveKit Docs | examples/voice_agents/toggle_io.pyjolly-eve-3916
08/06/2025, 6:52 AMtall-airline-16756
08/06/2025, 6:52 AMAgentSession doesn’t directly impact how RPC handlers get called. RPC methods are set up and triggered at the participant level, so they work independently from the session's state or flow.
2. Should RPC handlers be registered at a different point?
It’s best to register RPC handlers right after the agent connects to the room, but before starting the AgentSession. This way, they’re all set and ready to handle any incoming calls.
3. Are additional permissions needed?
Make sure your token includes canPublish and canPublishData permissions—these are essential for RPC to work smoothly.
4. Could AgentSession block RPC messages?
No, the AgentSession won’t block or get in the way of RPC messages. It’s there to manage the interaction flow and state, but it doesn’t interfere with RPC operations.
To help you debug further, here are a few things to double-check:
• Make sure the RPC method name is exactly the same on both the client and the agent side.
• Confirm that the agent is fully connected before the client sends any RPC calls.
• Turn on detailed logging on both the client and agent to follow the RPC call’s path.
If you want, I’m here to help you dig deeper—just let me know!jolly-eve-3916
08/06/2025, 7:16 AMtall-airline-16756
08/06/2025, 7:17 AM@ctx.room.local_participant.register_rpc_method("ping")
async def ping(data: rtc.RpcInvocationData):
<http://logger.info|logger.info>("PING RPC CALLED!")
return {"pong": True}
2. Verify RPC Invocation: On the client side, confirm that your performRpc call uses the correct destinationIdentity and method name. Adding some error handling can help catch any issues:
try {
const result = await localParticipant.performRpc({
destinationIdentity: "agent-AJ_waqYo2bHt4QY",
method: "ping",
payload: "{}",
responseTimeout: 5000,
});
console.log("RPC response:", result);
} catch (error) {
console.error("RPC call failed:", error);
}
3. Turn on Detailed Logging: Adding logs on both the client and agent sides can help you trace what's happening with the RPC call. For example:
<http://logger.info|logger.info>("Registered RPC method: ping")
<http://logger.info|logger.info>("Received RPC call with payload: {data.payload}")
4. Check Connection Status: Make sure both participants are fully connected to the same room before sending RPC calls. It’s helpful to watch connection events to confirm everything’s good to go.
5. Review Permissions: Double-check that your token includes canPublish and canPublishData permissions, since these are needed for RPC to work smoothly.
6. Look Into Network Configuration: Sometimes network issues or firewall settings can block RPC messages. It’s worth making sure nothing is getting in the way.
If you’re still stuck, feel free to share:
• The code where you register the RPC method
• The code where you make the RPC call
• Any error messages or logs from both the client and agent
I’m here to help, so just let me know if you want to dig deeper!jolly-eve-3916
08/06/2025, 8:17 AMtall-airline-16756
08/06/2025, 8:18 AMRoomIO, AgentSession, and register RPC methods shouldn’t really affect how RPC works. Just make sure you register the RPC methods after your agent has fully connected to the room.
2. Turn Detection: Setting turn_detection="manual" won’t interfere with RPC functionality. This setting just controls when your agent knows to start and stop speaking.
3. Audio Disabled in RoomIO: Turning off audio in RoomIO won’t impact RPC either. RPC works independently from media streaming settings.
4. Verifying Handlers: To double-check that your RPC handlers are attached properly, you can log the registered handlers like this:
<http://logger.info|logger.info>(f"Registered RPC handlers: {ctx.room.local_participant._rpc_handlers.keys()}")
Your setup looks solid, and since the same RPC pattern works elsewhere, the hiccup might be about timing or a specific config. Here are a few things to keep an eye on:
• Make sure RPC methods get registered after your agent is fully connected to the room.
• Check that the destinationIdentity in the client exactly matches the agent’s identity.
• Confirm both participants are in the same room and fully connected when making the RPC call.
If you want, I’m here to help with any other questions or debugging tips!jolly-eve-3916
08/06/2025, 8:18 AMtall-airline-16756
08/06/2025, 8:19 AMRoomIO isn’t needed for the basic RPC features in LiveKit. You can register and call RPC methods right through the LiveKit client SDKs without touching RoomIO.
That said, if you’re working on an agent that deals with audio from certain participants or needs to handle more complex media routing, RoomIO becomes really important. It helps manage audio input/output, participant details, and events—basically everything you need for smooth voice agent interactions.
If your project doesn’t involve audio or media management, feel free to skip RoomIO and still enjoy all the RPC functionality. And hey, if you want me to explain anything more, just ask—I’m here to help!
Sources: Agents Core Architecture | livekit/livekit_composite | DeepWiki | How to set a fixed participant for agent audio processing | AI Agents Framework | livekit/livekit_composite | DeepWiki | Sources/LiveKit/Core/Room.swift | examples/voice_agents/push_to_talk.pyjolly-eve-3916
08/06/2025, 3:14 PMtall-airline-16756
08/06/2025, 3:14 PMrequest_fnc parameter in `WorkerOptions`—I hope this helps clear things up!
1. Is request_fnc required for RPC to work properly?
Nope, request_fnc isn’t required for RPC to function. There’s a default setup that automatically accepts all job requests, so RPC will still work even if you don’t define it yourself.
2. Does the agent need to accept() the job request with a specific identity for RPC routing to function?
Not really. The default request_fnc accepts all requests, which is enough for RPC routing to work smoothly. But if you want to add your own custom logic to filter or handle job requests, you can definitely create your own request_fnc.
3. Is there a default behavior when request_fnc is omitted that might prevent RPC from working?
The default is to accept all requests, so leaving out request_fnc shouldn’t stop RPC from working. If you’re running into issues, it’s probably due to something else—like the timing of RPC registration or how participants are connecting.
If anything’s still unclear or you want help troubleshooting further, just let me know—I’m here to help!
Sources: Worker options | LiveKit Docs | examples/voice_agents/push_to_talk.pyjolly-eve-3916
08/06/2025, 3:23 PMtall-airline-16756
08/06/2025, 3:23 PM_rpc_handlers).
◦ The method name in the client call doesn’t match the registered handler.
◦ The recipient participant isn’t found in the room (take a look at destinationIdentity).
◦ The handler takes too long to respond, causing a timeout.
◦ Network hiccups or unsupported protocol versions.
1. Agent Identity and Job Request:
◦ The client should use the agent’s participant identity (like agent-AJ_C4PTGfsda2JB) for destinationIdentity. Just a heads up, the identity set in handle_request is metadata and doesn’t impact RPC routing.
1. Room Connection Timing:
◦ The room doesn’t connect automatically—you’ll want to call ctx.connect() before registering any RPC methods.
◦ Make sure to register RPC methods after the room is connected but before starting the session.
1. Debugging RPC Flow:
◦ Try turning on detailed logging on both the client and agent to follow the RPC flow more closely.
◦ Keep an eye out for errors like RECIPIENT_NOT_FOUND or UNSUPPORTED_METHOD in the client logs.
1. AgentDispatchClient Usage:
◦ Use the participant identity (for example, agent-AJ_C4PTGfsda2JB) for destinationIdentity, not just the agent name.
◦ When you use the correct identity, AgentDispatchClient shouldn’t interfere with RPC routing.
If you want, I’m here to help with any other questions or if you need more debugging tips—just let me know!
Sources: src/room/Room.ts | RPC | LiveKit Docs | Remote method calls (RPC) | LiveKit Docsjolly-eve-3916
08/06/2025, 3:29 PM_rpc_handlers), but they're never invoked when the client calls performRpc. The client logs show RPC calls being made to the correct agent identity, but the handlers never execute.
## Environment
- livekit-agents version: 1.2.2
- Python version: 3.11
- Deployment: AWS ECS/Fargate
## Agent Code (agent-ptt.py)
python
_import_ asyncio
_import_ os
_import_ json
_import_ logging
_from_ datetime _import_ datetime
_from_ dotenv _import_ load_dotenv
_from_ typing _import_ Optional
_from_ livekit _import_ agents, rtc
_from_ livekit.agents _import_ Agent, AgentSession, JobContext, JobRequest, WorkerOptions, cli, llm
_from_ livekit.plugins _import_ deepgram, anthropic, silero
load_dotenv()
logging.basicConfig(_level_=<http://logging.INFO|logging.INFO>)
logger = logging.getLogger(__name__)
_# Global references for state management_
current_session = None
ptt_timeout_task: Optional[asyncio.Task] = None
class CoraPTTAssistant(Agent):
"""PTT-specific assistant with manual turn detection"""
def __init__(_self_, _chat_ctx_: llm.ChatContext = None):
super().__init__(
_chat_ctx_=chat_ctx _or_ llm.ChatContext(),
_llm_=anthropic.LLM(_model_="claude-sonnet-4-20250514"),
_instructions_="""You are Cora, """
)
async def entrypoint(_ctx_: JobContext):
"""PTT agent entrypoint - ONLY handles PTT mode"""
<http://logger.info|logger.info>(f"\n=== PTT AGENT ENTRYPOINT CALLED ===")
<http://logger.info|logger.info>(f"Room: {ctx.room.name}")
_# Connect to room FIRST (as per LiveKit support guidance)_
<http://logger.info|logger.info>("Connecting to room before RPC registration...")
_await_ ctx.connect()
<http://logger.info|logger.info>("Connected to room successfully")
_# Create PTT-only session with manual turn detection_
<http://logger.info|logger.info>("Creating PTT session with manual turn detection...")
session = AgentSession(
_stt_=deepgram.STT(
_model_="nova-3",
_interim_results_=False,
_punctuate_=True,
_smart_format_=True
),
_tts_=deepgram.TTS(_model_="aura-2-cora-en"),
_vad_=None, _# No VAD in PTT mode_
_turn_detection_="manual", _# CRITICAL: Manual mode for PTT_
)
_# Create the PTT assistant_
assistant = CoraPTTAssistant()
_# Store session globally for RPC handlers_
global current_session
current_session = session
_# Register RPC handlers AFTER room connection but BEFORE session.start()_
<http://logger.info|logger.info>("Registering RPC methods AFTER room connection but BEFORE session.start()...")
<http://logger.info|logger.info>(f"Current local participant: {ctx.room.local_participant}")
<http://logger.info|logger.info>(f"Current local participant identity: {ctx.room.local_participant.identity}")
<http://logger.info|logger.info>(f"\n=== IMPORTANT: Clients must use this exact identity for RPC destinationIdentity: '{ctx.room.local_participant.identity}' ===\n")
_# Add a test RPC call to verify methods are working_
@ctx.room.local_participant.register_rpc_method("ping")
async def ping(_data_: rtc.RpcInvocationData):
"""Simple test RPC method"""
_try_:
<http://logger.info|logger.info>("========================================")
<http://logger.info|logger.info>("PING RPC CALLED!")
<http://logger.info|logger.info>(f"Caller identity: {data.caller_identity}")
_return_ {"pong": True, "timestamp": datetime.now().isoformat()}
_except_ Exception _as_ e:
logger.error(f"Error in ping RPC handler: {e}")
_return_ {"error": str(e)}
@ctx.room.local_participant.register_rpc_method("start_turn")
async def start_turn(_data_: rtc.RpcInvocationData):
"""Called when user presses PTT button"""
_try_:
<http://logger.info|logger.info>(f"========== PTT RPC CALLED: start_turn ==========")
<http://logger.info|logger.info>(f"PTT: Starting turn from {data.caller_identity}")
_if_ current_session is None:
logger.error("ERROR: current_session is None!")
_return_ {"status": "error", "message": "Session not initialized"}
_# Stop any ongoing agent speech and clear pending audio_
current_session.interrupt()
current_session.clear_user_turn()
_# Enable audio input_
current_session.input.set_audio_enabled(True)
_return_ {"status": "turn_started"}
_except_ Exception _as_ e:
logger.error(f"Error in start_turn RPC handler: {e}")
_return_ {"status": "error", "message": str(e)}
@ctx.room.local_participant.register_rpc_method("end_turn")
async def end_turn(_data_: rtc.RpcInvocationData):
"""Called when user releases PTT button"""
_try_:
<http://logger.info|logger.info>("PTT RPC CALLED: end_turn")
_if_ current_session is None:
logger.error("ERROR: current_session is None!")
_return_ {"status": "error", "message": "Session not initialized"}
_# Disable audio input_
current_session.input.set_audio_enabled(False)
_# Commit the user turn to process collected audio_
current_session.commit_user_turn()
_return_ {"status": "turn_ended"}
_except_ Exception _as_ e:
logger.error(f"Error in end_turn RPC handler: {e}")
_return_ {"status": "error", "message": str(e)}
<http://logger.info|logger.info>("RPC handlers registered: start_turn, end_turn, ping")
_# Verify RPC registration_
_if_ hasattr(ctx.room.local_participant, '_rpc_handlers'):
<http://logger.info|logger.info>(f"Registered RPC handlers: {list(ctx.room.local_participant._rpc_handlers.keys())}")
_# Now start the session with the assistant_
<http://logger.info|logger.info>("\n=== STARTING PTT AGENT SESSION ===")
_await_ session.start(_agent_=assistant, _room_=ctx.room)
<http://logger.info|logger.info>("PTT AgentSession started")
_# Disable audio by default (after starting session)_
session.input.set_audio_enabled(False)
<http://logger.info|logger.info>("Audio input disabled by default")
_# Log final state_
<http://logger.info|logger.info>(f"PTT Agent fully initialized!")
<http://logger.info|logger.info>(f"Local participant identity: {ctx.room.local_participant.identity}")
async def handle_request(_request_: agents.JobRequest) -> None:
"""Handle incoming job requests for PTT mode"""
<http://logger.info|logger.info>(f"PTT agent received job request: {request}")
_await_ request.accept(
_identity_="ptt-agent",
_attributes_={"push-to-talk": "1"},
)
_if_ __name__ == "__main__":
cli.run_app(
WorkerOptions(
_entrypoint_fnc_=entrypoint,
_request_fnc_=handle_request,
_api_key_=os.getenv("LIVEKIT_API_KEY"),
_api_secret_=os.getenv("LIVEKIT_API_SECRET"),
_ws_url_=os.getenv("LIVEKIT_WS_URL"),
_agent_name_="cora-ptt-agent",
)
)
## Client Code (React Native)
typescript
_// When agent joins the room_
newRoom.on(RoomEvent.ParticipantConnected, async (_participant_) => {
console.log(`[PTT] Participant joined: ${participant.identity} (SID: ${participant.sid})`);
if (participant.identity !== patientId) {
console.log(`[PTT] Agent connected with identity: ${participant.identity}`);
_// Test RPC with a simple ping_
try {
const pingResult = await localParticipantRef.current?.performRpc({
destinationIdentity: participant.identity,
method: "ping",
payload: "{}",
responseTimeout: 3000,
});
console.log("[PTT] Ping RPC success! Result:", pingResult);
} catch (pingError) {
console.error("[PTT] Ping RPC failed:", pingError);
}
}
});
_// PTT button press_
const startRecording = async () => {
const agentParticipant = participants.find(_p_ => p.identity !== patientId);
console.log(`[PTT] Agent identity for RPC: '${agentParticipant.identity}'`);
const result = await localParticipantRef.current.performRpc({
destinationIdentity: agentParticipant.identity,
method: "start_turn",
payload: JSON.stringify({ participant_id: patientId }),
responseTimeout: 5000,
});
};
## Logs
### Agent Logs (AWS)
=== PTT AGENT ENTRYPOINT CALLED ===
Room: 636c2e4...-1733258767382
Connecting to room before RPC registration...
Connected to room successfully
Registering RPC methods AFTER room connection but BEFORE session.start()...
Current local participant: rtc.LocalParticipant(sid=PA_2pMLrPCBTAN9, identity=agent-AJ_C4PTGfsda2JB, name=)
Current local participant identity: agent-AJ_C4PTGfsda2JB
=== IMPORTANT: Clients must use this exact identity for RPC destinationIdentity: 'agent-AJ_C4PTGfsda2JB' ===
RPC handlers registered: start_turn, end_turn, ping
Registered RPC handlers: ['ping', 'start_turn', 'end_turn']
PTT Agent fully initialized!
Local participant identity: agent-AJ_C4PTGfsda2JB
### Client Logs
[PTT] Agent connected with identity: agent-AJ_C4PTGfsda2JB
[PTT] Testing RPC with ping...
[PTT] Ping target identity: 'agent-AJ_C4PTGfsda2JB'
[PTT] Ping RPC failed: Error
[PTT] Ping error details: {"code": 4, "message": "RPC timed out"}
[PTT] Agent identity for RPC: 'agent-AJ_C4PTGfsda2JB'
[PTT] Starting RPC call to agent-AJ_C4PTGfsda2JB with method: start_turn
[PTT] RPC start_turn failed: Error
[PTT] RPC error details: {"code": 4, "message": "RPC timed out"}
## Questions
1. Why are RPC handlers timing out? - The handlers are registered (confirmed in _rpc_handlers), but they're never invoked. The client gets timeout errors.
2. Is our registration order correct? - We're following your guidance: connect → register RPC → start session
3. Are we missing any configuration? - The agent uses agent_name="cora-ptt-agent" and the client uses the exact participant identity.
4. Could the global session reference be an issue? - We store the session globally so RPC handlers can access it.
5. Is there additional debugging we can enable? - To trace why the RPC isn't reaching the handler despite being registered.
The core issue: RPC handlers are registered but never execute, causing all RPC calls to timeout.tall-airline-16756
08/06/2025, 3:29 PMresponseTimeout set in performRpc(). By default, it’s 10 seconds, but you can tweak it for each call. If it takes longer, a timeout will happen.
2. Network Latency: Sometimes, slow network connections can eat up the time your handler has to respond. Keep an eye on your network and try to keep latency low between the client and agent.
3. Payload Size: Double-check that your request and response payloads are under the 15KiB limit. Bigger payloads can cause delays or errors.
4. Application Errors in Handler: If your handler runs into an unexpected error, it might not respond in time. Wrapping your code in try-except blocks can catch and log these errors, helping you spot issues quickly:
@ctx.room.local_participant.register_rpc_method("ping")
async def ping(data: rtc.RpcInvocationData):
try:
<http://logger.info|logger.info>("PING RPC CALLED!")
return {"pong": True, "timestamp": datetime.now().isoformat()}
except Exception as e:
logger.error(f"Error in ping RPC handler: {e}")
return {"error": str(e)}
1. Payload Format: Make sure your payload is formatted just right to avoid any parsing hiccups or delays in the handler.
2. Version Mismatch: Check that your server version supports the RPC features you’re using.
If you want to dig deeper, turning on detailed logging on both the client and agent can really help trace what’s going on with the RPC calls. And hey, if you need a hand or have more questions, just let me know—I’m here to help!jolly-eve-3916
08/06/2025, 4:19 PM[PTT] Agent identity for
RPC: '${agentParticipant.identity}');
// This logs: ptt-agent (not
agent-AJ_C4PTGfsda2JB)
Questions:
1. Why is participant.identity
returning "ptt-agent" (from
request.accept) instead of the
auto-generated identity like
"agent-AJ_C4PTGfsda2JB"?
2. Which identity should we use for
RPC destinationIdentity - the one from
request.accept or the auto-generated
one?
3. How can the client reliably
discover the correct identity for RPC
calls?
This identity mismatch appears to be
the root cause of our RPC timeout
issues.tall-airline-16756
08/06/2025, 4:19 PMparticipant.identity returning "ptt-agent" instead of the auto-generated identity?
Great question! The identity you set in request.accept (like "ptt-agent") actually takes precedence over the auto-generated one. This way, you can give the agent a custom, meaningful identity in the room that makes sense for your use case.
2. Which identity should we use for destinationIdentity?
You’ll want to use the identity from request.accept (such as "ptt-agent") for destinationIdentity. That’s the identity the agent uses in the room, and it’s what your client should target when making RPC calls.
3. How can the client reliably discover the correct identity for RPC calls?
The client can check the participant.identity property to find out the agent’s identity. Just make sure the client is aiming for the identity set in `request.accept`—that’s the one the agent is actually using in the room.
If anything’s still unclear or you want to dive deeper, just let me know—I’m here to help!
Sources: JobRequest | LiveKit Agentsjolly-eve-3916
08/06/2025, 4:23 PMtall-airline-16756
08/06/2025, 4:24 PMrequest.accept, here’s a simple way to do it:
1. Accept the Job Request: Use request.accept() and pass in the identity you want (like "ptt-agent"). This sets who you are for everything that follows.
2. Register RPC Handlers After Accepting: Make sure you register your RPC handlers only after you’ve set the identity with request.accept. For example:
await request.accept(identity="ptt-agent")
@ctx.room.local_participant.register_rpc_method("start_turn")
async def start_turn(data: rtc.RpcInvocationData):
# Here’s where you handle the RPC
pass
3. Pass Identity to Entrypoint: If your handlers are registered in the entrypoint, just pass the identity from handle_request over there. That way, everything stays consistent with the right identity.
If any of this feels unclear or you want me to walk you through it more, just let me know—I’m happy to help!jolly-eve-3916
08/06/2025, 4:51 PMtall-airline-16756
08/06/2025, 4:52 PMregister_rpc_method.
◦ The response timeout might be too short. Try increasing the responseTimeout in the client call to give the agent more time to respond.
◦ The agent might have disconnected or isn’t fully connected to the room. Make sure the agent stays connected during the RPC call.
◦ The payload size could be over the 15KiB limit. If so, try reducing the payload size.
◦ There might be network issues blocking the RPC call. Testing in a stable network environment can help.
1. Are additional permissions or configurations needed?
Make sure the token used by the agent includes canPublish and canPublishData permissions, as these are necessary for RPC to work properly.
2. Is there a way to enable more verbose RPC logging?
Yes! You can enable detailed logging on both the client and agent sides to better trace the RPC flow. For instance, log the destinationIdentity, method name, and payload on the client side, and log incoming RPC calls on the agent side. This usually helps pinpoint where the call might be getting dropped.
If you want, I’m here to help with any further questions or debugging steps you might need!gentle-rose-77238
08/15/2025, 10:29 PMtall-airline-16756
08/15/2025, 10:30 PMregister_rpc_method. Here’s a quick example:
@ctx.room.local_participant.register_rpc_method("ping")
async def ping(data: rtc.RpcInvocationData):
return {"pong": True}
2. Verify Participant Identity: It’s important that the client uses the correct destinationIdentity for the agent. This should match the identity set in request.accept or the auto-generated identity if none was specified.
3. Tweak the Response Timeout: Sometimes the agent just needs a bit more time to respond. Try increasing the responseTimeout in your client call like this:
const result = await localParticipant.performRpc({
destinationIdentity: "agent-identity",
method: "ping",
payload: "{}",
responseTimeout: 5000,
});
4. Check Permissions: Make sure the token your agent is using includes canPublish and canPublishData permissions so everything runs smoothly.
5. Turn on Detailed Logging: Adding logs on both the client and agent sides can really help track what’s going on. Log the destinationIdentity, method name, and payload on the client, and keep an eye on incoming RPC calls on the agent.
If you’re still stuck after trying these, just let me know! Sharing more about your setup—like the agent’s identity, which RPC method you’re calling, and any error messages or logs—will help me help you better.