with this configuration, is possible to have more ...
# ask-ai
a
with this configuration, is possible to have more than 10 agents dispatched to the same room?:
Copy code
// Configure room without automatic agent dispatch
    token.roomConfig = new RoomConfiguration({
      name: roomName,
      emptyTimeout: ROOM_EMPTY_TIMEOUT_SEC,
      departureTimeout: ROOM_DEPARTURE_TIMEOUT_SEC,
      maxParticipants: 4,
      minPlayoutDelay: ROOM_MIN_PLAYOUT_DELAY_MS,
      maxPlayoutDelay: ROOM_MAX_PLAYOUT_DELAY_MS,
      metadata: JSON.stringify({
        deviceId,
        userId,
      }),
      // No agents array - agents will be dispatched on-demand
    });
t
Thanks for reaching out, Sebastián. 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 question about whether this room config allows more than 10 agents to be dispatched to the same room. Short answer: yes. With no
agents
array in
roomConfig
and agents dispatched on-demand, there’s no built‑in 10‑agent limit — agents can be dispatched explicitly (AgentDispatchService, CLI, or agent participant tokens) and agent participants are distinct from regular participants. To confirm for your environment, please tell me: 1. Which product/version are you using (self‑hosted LiveKit, managed LiveKit, or a third‑party service/SDK)? 2. How are you dispatching agents in practice (AgentDispatchService/CLI, agent tokens, or automatic config)? 3. Are agents joining as
ParticipantKind.AGENT
in your code? 4. Any errors or logs you see when dispatch stops (e.g., after ~10 agents)? With those details I’ll verify whether anything in your setup could be enforcing a limit and suggest next steps. Sources: Agent dispatch | LiveKit docs | livekit/livekit_composite | DeepWiki
a
i want to prevent having multiple agents dispatched to the same room, aka, if agent is in room it should n't allow any additional agetns. also, whats maxParticipants for then?
t
Thanks — you're asking (1) how to prevent multiple agents from being dispatched to the same room so only one agent can be present, and (2) what
maxParticipants
controls. Short answer • Preventing multiple agents is not automatic — enforce it in your dispatch logic. •
maxParticipants
limits human/standard participants, not agents. How to enforce a single agent per room (options) • Explicit dispatch with server-side guard (recommended): before calling AgentDispatchService (or issuing an agent token), check room state in your backend (e.g., via room participant list or your own room record). Only dispatch if no participant with
ParticipantKind.AGENT
is present. • Dispatch via token at room creation: include a single
RoomAgentDispatch
in the room config embedded in the participant’s token so one agent is requested at join. Also ensure your server blocks any later dispatch calls for that room. • Single agent registration: register only one worker with a given
agent_name
. That prevents multiple distinct agents with the same name from being concurrently assigned, but you still must prevent additional dispatch calls. Practical checks to implement • Query the room participants (or maintain a backend flag) to detect any
AGENT
participant before dispatching. • On agent connect, mark the room as “agent-occupied”; clear it on agent disconnect/timeout. • Return a clear error when dispatch is attempted while the room is occupied, so callers know why the dispatch failed. About maxParticipants •
maxParticipants
caps standard (human/external/SIP) participants in the room. It does not apply to
AGENT
participants. Use application-level logic (above) to limit agents. If you want, tell me how you currently dispatch agents (API/CLI/token) and whether agents register with `agent_name`; I’ll give a short code snippet or sequence for the exact place to check/guard in your flow. Sources: Agent dispatch | LiveKit docs | Agents Framework | livekit/livekit_composite | DeepWiki
a
is that the most efficient way? now every manual dispatch, i have to: • check room exists by name • then check if agent participants exists in room • and then i can dispatch it
t
You're right to look for a simpler flow. Responding to your question about efficiency: yes—there's a more efficient approach than doing all three manual checks each time. Short answer • Do a direct dispatch call (AgentDispatchService or CLI / token-based dispatch). Dispatch requests are idempotent and the dispatch system will not create duplicate agent instances for the same dispatch rule. You do NOT need to manually check room existence or agent participants for correctness. • If you must enforce strict "only one agent ever" semantics for business logic or observability, add a lightweight server-side guard (atomic check-and-set) as an optimization — not the full three-step query. Recommended options (pick one) • Direct dispatch (recommended for simplicity): call AgentDispatchService.create_dispatch with
agent_name
and
room
. LiveKit will handle creating the room if needed and will avoid duplicate agent runs for the same dispatch. No pre-checks required. • Token-based single dispatch: embed a single
RoomAgentDispatch
in the participant token at room creation to request one agent at join. This prevents duplicates during the join flow. • Lightweight server-side guard (optional): maintain a small atomic flag or record (e.g., Redis SETNX or a DB transaction) per room that you set when dispatching and clear on agent disconnect. This prevents redundant dispatch calls for logging/metrics or to reduce API calls, but is not required for correctness. When to use the guard • Use it if you care about minimizing repeated API calls, consistent logging of who dispatched, or avoiding transient race attempts in your callers. Otherwise rely on direct dispatch idempotency. If you want, tell me which dispatch method you use (API, CLI, or token) and I’ll give a 3–5 line snippet showing the exact call or a small Redis pattern for the optional guard. Sources: Agent dispatch | LiveKit docs
a
but i have seen multiple agents dispatched to the same room
t
Thanks — I hear your frustration. You’ve seen multiple agents dispatched despite the recommended direct-dispatch approach. Let’s troubleshoot why that can happen and give a foolproof pattern to enforce one agent per room. Possible reasons you’re seeing duplicates • Race conditions: multiple callers issue dispatch requests for the same room concurrently before the system marks the room as having an agent. • Different dispatch rules/agent_names: requests with different
agent_name
or different dispatch metadata are treated as distinct and can start separate agents. • Worker registration: multiple agent workers registered under different names or without a single authoritative
agent_name
can result in more than one worker running for a room. • External/manual dispatch: someone or some process may be issuing additional dispatch calls (CLI, scheduled jobs, or retries). • Token + API overlap: a token-based dispatch at join plus a subsequent API dispatch can lead to two agents if both succeed. Foolproof patterns to enforce single-agent-per-room 1) Idempotent dispatch with a single authoritative
agent_name
• Always dispatch with the same
agent_name
. The dispatch system will treat repeated requests with identical agent_name+room as the same logical dispatch. • Avoid issuing dispatches using different names/metadata for the same agent role. 2) Server-side atomic guard (recommended for production) • Before calling create_dispatch, perform an atomic check-and-set on a fast store (Redis SETNX or DB row with transaction): set key
room:{roomName}:agent
=
agent_name
with short TTL. If SETNX fails, abort dispatch. • On agent connect, clear or extend the key; on agent disconnect, clear it. This prevents concurrent callers from issuing multiple dispatches. 3) Verify and dedupe after dispatch (safety net) • After create_dispatch returns, confirm the active dispatch record or check room participants for an
AGENT
. If multiple agents are present, programmatically stop extra dispatches (AgentDispatchService.delete) for duplicates. 4) Use token-based single dispatch for join flows (when applicable) • Embed one
RoomAgentDispatch
in the room token so only one agent is requested at creation. Don’t also call create_dispatch for the same room concurrently. Minimal implementation suggestion (Redis SETNX pattern) • SETNX room{room}agent <agent_name> EX 300 => success => call create_dispatch • If SETNX fails => another dispatch is in-flight/active => do not dispatch • On agent connected or on heartbeat, extend TTL; on disconnect, DEL the key. What I need from you to give an exact snippet • Which dispatch method are you using now? (AgentDispatchService API, CLI, or token-based) • Are you using
agent_name
consistently? • Do you have a fast store available (Redis) or do you prefer a DB transaction? Tell me those and I’ll give a 3–6 line code snippet for your stack (Redis or DB) or the exact API call pattern to prevent duplicates.
a
AgentDispatchService API yes always the same dispatch name
t
Thanks — you're using the AgentDispatchService API and the same
agent_name
. That helps. Short answer: add a cheap atomic guard around your dispatch call (Redis SETNX or a DB transactional flag) so concurrent callers can't create duplicate dispatches. Even with a single
agent_name
, race conditions or retries can still start multiple agents unless you serialize attempts. Recommended pattern (Redis SETNX — 3 steps) 1. Attempt to acquire lock: ◦ SETNX
room:{roomName}:agent
<agent_name>
EX 300 ◦ If SETNX fails -> another dispatch in-flight/active → abort. 1. Call AgentDispatchService.create_dispatch(...). 2. On agent connect, extend TTL or replace the key; on agent disconnect or stop, DEL the key. Minimal pseudo-JS (node-style):
Copy code
const key = `room:${roomName}:agent`;
const got = await redis.setnx(key, agentName);
if (!got) throw new Error('agent already dispatching');
await redis.expire(key, 300);
await agentDispatch.createDispatch({ agent_name: agentName, room: roomName });
// on agent connected: redis.expire(key, 3600)
// on disconnect: redis.del(key)
Notes and extras • Keep TTL short enough to recover from crashed dispatches but long enough to avoid races. • After create_dispatch, you can verify room participants and delete extras if you see duplicates as a safety net. • If you can’t use Redis, same idea with a DB row + transactional INSERT/unique constraint. If you want, I can give a 4–6 line example for your language (Python, Go, or JavaScript) or a recommended TTL value based on your agent startup time. Which language do you use?
a
and how to check agent dispatch status?
t
You're using AgentDispatchService and want to check dispatch status — here's the concise way to do that and how to use it in your guard. What to call • Use AgentDispatchService.list_dispatch (or ListDispatch) to get active dispatches for a room. • Use AgentDispatchService.get_dispatch (or GetDispatch) to fetch a specific dispatch by ID if needed. Typical flow 1. List dispatches for the room: ◦ If list is empty → no agent dispatched. ◦ If list contains one dispatch → agent present. ◦ If list contains >1 → duplicates exist (you can stop extras). 1. Optionally, after create_dispatch, call get_dispatch or list_dispatch to confirm the dispatch is active. Minimal pseudo-examples • Node/JS-like
Copy code
const dispatches = await lkApi.agentDispatch.listDispatch({ room: roomName });
if (dispatches.length === 0) {
  // safe to create_dispatch
}
• Python-like
Copy code
dispatches = await lkapi.agent_dispatch.list_dispatch(room=room_name)
if len(dispatches) == 0:
    # safe to create_dispatch
Combining with your atomic guard (recommended) • Acquire your Redis SETNX lock first. • Call list_dispatch(room) as a final check (optional) then call create_dispatch. • After create_dispatch returns, call list_dispatch/get_dispatch to confirm and clear/set your room key appropriately. If you want, tell me which SDK/language you prefer and I’ll give a 4–6 line concrete snippet for that stack. Sources: Agent dispatch | LiveKit docs
a
but can we confirm if a dispatch has actually been done?
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!