token = api.AccessToken(os.getenv('LIVEKIT_API_KEY...
# ask-ai
l
token = api.AccessToken(os.getenv('LIVEKIT_API_KEY'), os.getenv('LIVEKIT_API_SECRET')) \ .with_identity("identity") \ .with_name("name") \ .with_metadata(metadata=json.dumps(metadata))\ .with_grants(api.VideoGrants( room_join=True, room=room_name)) \ modify the token to connect to room and communicate with particular participants
t
Thanks for reaching out, Rajadurai. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I’m responding to your request to “modify the token to connect to room and communicate with particular participants.” Quick answer: LiveKit tokens don’t provide a built‑in grant to allow or restrict communication with specific other participants inside a room. Tokens control room-level capabilities (join, publish, subscribe, hidden, etc.). To achieve targeted communication you’ll either change token grants (to allow/deny publishing or subscribing) or enforce per‑participant controls on the server after they join (mute tracks, remove participants, update permissions, or implement routing/dispatch logic). A few concrete options depending on what you mean by “communicate with particular participants” — pick the one that matches your use case and I’ll help with code: • Restrict sending (listen‑only): ◦ Issue the token with
can_publish=False
and
can_subscribe=True
. The participant can receive media but not send it. ◦ Example grant snippet:
Copy code
.with_grants(api.VideoGrants(
      room_join=True,
      room=room_name,
      can_publish=False,
      can_subscribe=True
    ))
• Allow sending but not receiving (publish-only): ◦ Set
can_publish=True
and
can_subscribe=False
. Useful for broadcast or data-only clients. • Hidden/observe without appearing: ◦ Use
hidden=True
to keep the participant out of participant lists while still subscribing.
Copy code
.with_grants(api.VideoGrants(
      room_join=True,
      room=room_name,
      can_publish=False,
      can_subscribe=True,
      hidden=True
    ))
• Fine‑grained control between specific participants (server‑side enforcement): ◦ Tokens can’t limit a participant to only subscribe to or publish to specific other participants. ◦ After participants join, your server can: ▪︎ Mute published tracks from specific participants, ▪︎ Remove or eject participants, ▪︎ Update participant metadata/roles and enforce routing logic in your application, ▪︎ Use agent/dispatch patterns to connect particular callers or agents to each other. ◦ If you want selective media routing (e.g., only Alice sees Bob), you’ll implement that server logic and use tokens to grant join/publish/subscribe broadly enough for the server to manage connections. Next steps — please tell me: 1. Do you want to prevent a client from sending audio/video, receiving audio/video, or both? 2. Do you need the client to be able to appear “hidden” in the participant list? 3. Or do you require true per‑participant selective communication (e.g., this user can only see/hear these specific users)? If so, describe the exact flow (who should see/hear whom, and whether server-side logic can enforce it). Once you tell me which option you want, I’ll provide the exact token code snippet and outline any server-side calls you’ll need. Sources: Server-side | livekit/livekit_composite | DeepWiki | Agent dispatch | LiveKit Documentation
l
In my three participants are there one agent local_participants when a particpant_b joins the room only remote particpants only communicate each other agent need to stop
t
Thanks — I’m responding to your goal: when participant_b joins a room with three participants (one agent + two local participants), you want the two remote/local participants to communicate with each other but have the agent’s communication stopped/blocked. A few quick clarifying questions so I can give the exact steps and code you need: 1. When you say “agent need to stop,” do you want the agent to: ◦ Be prevented from sending (publish) audio/video (listen-only), ◦ Be prevented from receiving audio/video (can't hear/see others), ◦ Be removed/ejected from the room entirely, or ◦ Remain in the room but be hidden (not visible in lists) while muted? 1. Should this change happen automatically the moment
participant_b
joins, or do you want a manual trigger (e.g., agent UI button or server decision)? 2. Are you able to run server-side logic when participants join (webhook or server event) to enforce rules, or do you need a pure token-only solution? ◦ Note: tokens cannot restrict a participant to only communicate with a subset of participants. Dynamic, per-participant blocking requires server-side actions after join. 1. Which SDK / language are you using on the client and server (JavaScript, Python, Go, etc.)? I’ll give code matching your stack. 2. Do you want audio/video only affected, or also data channels / screen share? Once you answer these, I’ll provide: • The simplest approach (token grant changes if appropriate), or • A server-side flow using participant updates (examples: mute participant’s published tracks, or call UpdateParticipant/remove) that runs when
participant_b
joins, plus code snippets for your SDK.
l
write python code for mute agent for publihsing tracks to reomte particpants and make sure the tracks between remote participants for communicating. use "participant_connected" node
t
Thanks — I’m responding to your request to provide Python code that mutes the agent’s published tracks when another participant connects (using the
participant_connected
event), while leaving communication between the remote participants intact. Below is an example using LiveKit’s Agents API objects shown in your earlier snippets. It listens for the
participant_connected
event and mutes the agent’s local published tracks when a new participant joins. Replace placeholders (STT/LLM/TTS/VAD, agent implementation) with your actual setup.
Copy code
import asyncio
from livekit.agents import JobContext, AgentSession, Participant
from livekit import rtc

async def mute_agent_tracks(agent_session: AgentSession):
    """
    Mute all local published tracks of the agent session.
    """
    local_participant = agent_session.room.local_participant
    if not local_participant:
        return

    for track_pub in local_participant.track_publications.values():
        # Only act on local track publications
        if isinstance(track_pub, rtc.LocalTrackPublication):
            # set_muted is async in example API
            await track_pub.set_muted(True)
            print(f"Muted track: {getattr(track_pub.track, 'name', '<unknown>')}")

async def on_participant_connected(agent_session: AgentSession, participant: Participant):
    """
    Callback for when a remote participant connects.
    Mute the agent's published tracks so agent stops sending media to others.
    """
    # Optionally ignore the agent's own connect events
    if participant.sid == agent_session.room.local_participant.sid:
        return

    print(f"Participant connected: {participant.identity} ({participant.sid})")
    await mute_agent_tracks(agent_session)

@server.rtc_session()
async def entrypoint(ctx: JobContext):
    """
    Agent entrypoint: start session, register handler, and connect.
    """
    # Create/configure AgentSession (replace ... with your config)
    session = AgentSession(
        stt=...,   # configure STT
        llm=...,   # configure LLM
        tts=...,   # configure TTS
        vad=...,   # configure VAD
    )

    # Register the participant_connected handler.
    # Use a lambda wrapper to pass the AgentSession instance into the callback.
    def _on_participant_connected(p):
        # schedule coroutine, do not block event loop
        asyncio.create_task(on_participant_connected(session, p))

    # Attach before connecting so early joins are captured
    ctx.room.on("participant_connected", _on_participant_connected)

    # Start the agent session and connect to room
    await session.start(agent=MyAgent(), room=ctx.room)   # replace MyAgent() with your agent
    await ctx.connect()

    # Keep the session running until shutdown
    await session.wait_until_stopped()
Key points and considerations: • Tokens cannot restrict which participants a client may subscribe to; you must mute the agent’s outgoing tracks server-side (as shown) to stop the agent from sending audio/video to everyone. • Muting only the agent’s published tracks leaves the other participants’ published tracks active, so they can continue to communicate with each other. • The handler checks and ignores the agent’s own participant connect event to avoid muting on self-connect. • If you need to unmute the agent later, call
await track_pub.set_muted(False)
for the relevant publications. • If you also need to block datachannels or other non-media paths, you’ll need additional application logic (e.g., close data channels or stop sending messages). If you tell me: • Which SDK/libraries versions you use (agent runtime/library versions), I can tailor any API calls exactly. • Whether you want the agent muted only when any new participant joins, or only when a specific participant identity joins, I’ll add that filter into the handler. Sources: Agent session | LiveKit Documentation | Job lifecycle | LiveKit Documentation | Building an Automated IVR Menu Caller | LiveKit Documentation