happy-fall-6105
03/18/2026, 11:49 AMtall-airline-16756
03/18/2026, 11:49 AMtall-airline-16756
03/18/2026, 11:50 AMshutdown_process_timeout option in the agent server options.
Would you like the exact config path or an example of setting shutdown_process_timeout for your setup?
Sources: Job lifecycle | LiveKit Documentation, with interactive elementshappy-fall-6105
03/18/2026, 11:51 AMtall-airline-16756
03/18/2026, 11:51 AMagent_server:
# time in seconds the server will wait for shutdown callbacks to finish
shutdown_process_timeout: 30
Programmatic example (server startup)
// pseudocode / Node-style example
const options = {
// other agent options...
shutdown_process_timeout: 30 // seconds
};
const server = createAgentServer(options);
server.start();
Notes:
• The value is in seconds.
• The default is 10 seconds; set a larger value only if your shutdown hooks need more time.
• Keep shutdown hooks fast and idempotent so the process can terminate reliably.
If you tell me which runtime or config file you’re using (e.g., Docker Compose, systemd unit, Golang binary flags), I can provide a tailored example for that environment.
, with interactive elementshappy-fall-6105
03/18/2026, 11:58 AMtall-airline-16756
03/18/2026, 11:58 AMconfig.yaml with lk agent create to change room parameters when deploying to LiveKit Cloud.
You cannot use a config.yaml file to modify room-level parameters during an lk agent create deployment. There’s no support for passing room configuration that way.
What you can do instead:
• Include room configuration in the access token using the RoomConfiguration object (this supports fields like max_participants and agent dispatch rules via RoomAgentDispatch).
• Use environment variables or the livekit.toml for agent/server-level configuration when deploying agents (these do not change room parameters).
• Set room parameters programmatically at runtime via the SDKs or server APIs when creating or updating rooms.
If you tell me which room parameters you want to change (for example: max participants, metadata, agent dispatch rules) and how you create rooms (via SDK, server API, or token-based creation), I can show the exact code or token fields to set those values.
Sources: examples/drive-thru | livekit/livekit_composite | DeepWiki | server-sdk-kotlin | livekit/livekit_composite | DeepWiki, with interactive elementshappy-fall-6105
03/18/2026, 12:00 PMtall-airline-16756
03/18/2026, 12:00 PMdeparture_timeout. I’m responding to that specifically and how to set it when using LiveKit Cloud.
Short answer:
• You cannot set departure_timeout via a config.yaml passed to lk agent create.
• Set departure_timeout when creating the room through the Server SDK or the Room creation API (it's a field on the CreateRoomRequest).
Examples — set departure_timeout when creating a room
1) Python (async example)
from livekit import api
lk_api = api.LiveKitAPI(
url="https://your-instance.livekit.cloud",
api_key="your-api-key",
api_secret="your-api-secret",
)
# create room with departure_timeout (seconds)
resp = await lk_api.room.create_room(
api.CreateRoomRequest(
name="my-room",
max_participants=10,
departure_timeout=60 # keep room open 60s after last participant leaves
)
)
2) Node.js (pseudocode / typical pattern)
const lk = new LiveKitAPI({ url: 'https://your-instance.livekit.cloud', apiKey: 'key', apiSecret: 'secret' });
await lk.rooms.createRoom({
name: 'my-room',
max_participants: 10,
departure_timeout: 60 // seconds
});
Notes and best practices
• departure_timeout is measured in seconds and controls how long the room remains open after the last participant disconnects.
• This is a room creation parameter (CreateRoomRequest). It’s not part of agent-level config or agent deployment files.
• If you create rooms via tokens or programmatically from your app server, include departure_timeout there.
• If you tell me how you currently create rooms (Server SDK, REST API, token-based flow), I can give a precise code sample for that environment. Sources: Server-side | livekit/livekit_composite | DeepWiki | Python SDKs | livekit/livekit_composite | DeepWiki | Job lifecycle | LiveKit Documentation, with interactive elementshappy-fall-6105
03/19/2026, 1:21 PMtall-airline-16756
03/19/2026, 1:21 PMdepartureTimeout to the LiveKit Meet frontend call stops the agent backend from producing logs (but the connection works when you omit it). Let’s narrow down what’s happening and get you a working setup.
Quick checklist and likely causes
• Parameter name/casing: The room creation API expects departure_timeout (snake_case) at the server/SDK level. Frontend helpers may use camelCase, but sometimes that field isn’t accepted from the client for security reasons. If the frontend call forwards this directly to the server SDK, it may be ignored or rejected.
• Where the room is created: For LiveKit Cloud, rooms should normally be created from a trusted server (Server SDK or Room creation API) rather than from an untrusted client. If the Meet frontend is calling an internal API that attempts to create rooms with departureTimeout, that call may be blocked or not reach the agent.
• Metadata: There are no mandatory fields required in metadata — it’s a free-form string. Invalid or very large metadata could cause issues, but that’s uncommon.
• Silent failures: If the agent backend shows no logs when you include the field, the create-room request may not be reaching the agent (client validation, proxy/edge rejecting it, or the request failing earlier).
Next steps — please provide a couple quick details so I can pinpoint the problem
1. How are you calling roomService.createRoom in detail? Is this function on your frontend directly calling the LiveKit REST/SDK, or is it hitting your app server which then calls LiveKit Server SDK?
2. Which exact SDK/method are you using? (e.g., LiveKit Meet frontend library, livekit-js, or a custom wrapper). Paste the minimal code snippet if possible.
3. What exact field name are you sending? You showed departureTimeout — can you confirm that’s the literal key sent to the API?
4. Do you see any HTTP error responses in the browser devtools network tab when you include the field? Any status code or response body?
5. Which LiveKit backend are you using — LiveKit Cloud (hosted) or self-hosted agent? You mentioned agent deployed on LiveKit Cloud; confirm that.
6. Do you have any agent logs at all when you attempt the create? If not, is there any other service (your app server) that logs the create-room request and response?
Immediate workaround you can try
• Create the room from your trusted server using the Server SDK and set departure_timeout (snake_case) there. Then generate tokens for clients to join that pre-created room. This avoids client-side room creation issues entirely.
Example (server-side, Node-like)
// server-side: use Server SDK to create room
await livekitApi.rooms.createRoom({
name: 'my-room',
departure_timeout: 120, // seconds, snake_case
metadata: metadataString,
});
What I can do next
• If you share how the create call is routed (frontend -> app server -> LiveKit) and the exact request shape, I’ll point out the exact field name and show a minimal working example for your stack.
• If you prefer, paste the browser network request (headers + payload) when departureTimeout is included and I’ll inspect for mismatched fields or errors.
You’re close — once I know how the create call is sent (client vs server) and the exact request payload, I’ll give a precise fix.
, with interactive elementshappy-fall-6105
03/19/2026, 1:25 PM${participantName}__${randomParticipantPostfix},
name: participantName,
metadata: metadataString,
},
roomName,
);
// Return connection details
const data: ConnectionDetails = {
serverUrl: livekitServerUrl,
roomName: roomName,
participantToken: participantToken,
participantName: participantName,
};
return new NextResponse(JSON.stringify(data), {
headers: {
'Content-Type': 'application/json',
'Set-Cookie': ${COOKIE_KEY}=${randomParticipantPostfix}; Path=/; HttpOnly; SameSite=Strict; Secure; Expires=${getCookieExpirationTime()},
},
});
function createParticipantToken(userInfo: AccessTokenOptions, roomName: string) {
const at = new AccessToken(API_KEY, API_SECRET, userInfo);
at.ttl = '5m';
const grant: VideoGrant = {
room: roomName,
roomJoin: true,
canPublish: true,
canPublishData: true,
canSubscribe: true,
};
at.addGrant(grant);
if (AGENT_NAME) {
at.roomConfig = new RoomConfiguration({
agents: [new RoomAgentDispatch({ agentName: AGENT_NAME })],
});
}
return at.toJwt();
}tall-airline-16756
03/19/2026, 1:26 PMroomService.createRoom with departureTimeout and then issues a participant token. Good detail; that helps narrow this down.
Two likely issues and how to check/fix them 1) Field name / casing mismatch
• The Server API expects departure_timeout (snake_case) on the CreateRoom request. Your code sends departureTimeout (camelCase). That can cause the field to be ignored or the request to be rejected depending on the client implementation.
• Fix: send departure_timeout when calling the server SDK or use the SDK’s CreateRoomRequest/typed object rather than a plain object.
Example (Node-style, using snake_case):
await roomService.createRoom({
name: roomName,
departure_timeout: 120,
metadata: metadataString,
});
Or, if the SDK provides a CreateRoomRequest class, construct that class and set departure_timeout on it.
2) Room creation should happen on the trusted server and is best done via the Server SDK (which you are doing) — but confirm the SDK method you’re calling actually maps fields properly
• Verify which RoomServiceClient you’re using and whether it expects camelCase or snake_case in the payload. If you’re passing a plain JS object and the client serializes to the API directly, mismatch will occur.
• Check the response from createRoom. Right now you return connection details without showing the createRoom response; the create call may be returning an error or validation failure that you’re not logging.
Debugging steps to find the root cause
1. Log the createRoom response and any caught errors.
◦ Wrap the call in try/catch and console.log the result and error (status/message/body).
1. Inspect network or SDK logs:
◦ If createRoom fails, your agent might not receive anything — that explains the missing agent logs. A failed/invalid request will often return an HTTP error to your server.
1. Confirm agent behavior:
◦ Without departureTimeout, agent logs appear — so compare the successful vs failing request payloads.
1. Try creating the room server-side with snake_case explicitly (and minimal fields) to confirm:
try {
const resp = await roomService.createRoom({
name: roomName,
departure_timeout: 120,
metadata: metadataString,
});
console.log('createRoom response', resp);
} catch (err) {
console.error('createRoom error', err);
}
1. Verify token generation and roomConfig:
◦ Your token code sets at.roomConfig when AGENT_NAME is present. That’s fine. Note: roomConfig in the token is separate from CreateRoomRequest; ensure you aren’t relying on the token to set departure_timeout.
About metadata
• metadata is a free-form string. There are no mandatory fields required. Large or malformed strings could cause issues but that’s uncommon. Metadata isn’t the cause unless it contains something that triggers validation in your path.
Immediate workaround
• Create the room first server-side with departure_timeout (snake_case). If that succeeds, return tokens and join clients to the pre-created room. This avoids depending on the frontend to pass create-room options.
If the above doesn’t fix it, please share:
• The exact RoomServiceClient library/package name and version you’re using.
• The error or response from the createRoom call (paste the console output from the try/catch).
• Logs from your server (the handler for /api/connection-details) showing the request payload and any error stacks.
I’ll walk through the next steps once I can see the createRoom response or the client library info.
, with interactive elementshappy-fall-6105
03/23/2026, 10:01 AMtall-airline-16756
03/23/2026, 10:01 AMdepartureTimeout, metadata, and agents succeeds, but the lk agent logs stop showing anything. Let’s walk through the likely reasons and focused debugging steps so we can find the root cause.
Key things to check and why logs disappear
• Silent or early failures: If the create-room request is rejected by the LiveKit control plane (validation error, bad payload shape, or permission problem), the agent never receives a job to run — so the agent will not produce logs. A successful createRoom call on your server doesn't guarantee the agent was dispatched; you must confirm the create call actually triggered the agent dispatch.
• Field naming and payload shape: The Server API expects snake_case fields (e.g., departure_timeout). Some SDK wrappers accept camelCase and map it, others do not. If the SDK you use accepts agents but not the exact typed objects you constructed, the request may be malformed in a way that still returns success but does not dispatch an agent.
• Agent dispatch rules: When you set agents on the CreateRoomRequest, agent dispatch happens based on those dispatch rules. If the specified agent name is incorrect or not available, the room might be created without an agent assignment or with a dispatch that never reaches a running agent instance — leading to no agent logs.
• Token roomConfig vs CreateRoomRequest: You are both creating the room with agents and adding roomConfig to the token via at.roomConfig. These are separate. If they conflict the effective dispatch may differ from what you expect.
• Agent selection / scaling behavior of LiveKit Cloud: If your dispatch request targets a specific agent name that isn’t registered/online, the cloud controller may delay or fail to schedule that agent instance — again no logs on the agent.
Concrete checks and quick debugging steps
1. Inspect the createRoom response
◦ Wrap the call in try/catch and log the full response and any error.
◦ Show the response body (it should include the room object and any agent dispatch info).
Example:
try {
const resp = await roomService.createRoom({...});
console.log('createRoom ok:', resp);
} catch (err) {
console.error('createRoom error:', err);
}
1. Confirm the request payload shape sent to LiveKit
◦ Print the object you pass into createRoom just before sending it.
◦ Ensure you are using snake_case if the SDK requires it:
▪︎ use departure_timeout not departureTimeout if the SDK expects API fields.
▪︎ agents should be an array of RoomAgentDispatch objects — verify the SDK’s typed constructor is used or that the plain object matches required shape.
1. Check agent dispatch result in the create response
◦ The response may include dispatch or room metadata showing which agent (if any) was assigned. If no agent assigned, the agent won’t have logs.
◦ If the response indicates a pending dispatch or an error, that explains no logs.
1. Verify the agent name and availability
◦ Ensure AGENT_NAME is exactly the name the agent registered with, and that the agent is running and registered in the LiveKit Cloud before creating the room.
◦ If you target a named agent that is not online, the Cloud may not start it automatically depending on configuration.
1. Compare behavior without agents
◦ Create a room without the agents field (which you said works and shows logs). Compare the returned room object and any dispatch info to the one that does not produce logs. This will show what changed in dispatching.
1. Avoid conflicting settings between token and CreateRoomRequest
◦ Prefer setting agent dispatch via one place: either the CreateRoomRequest’s agents or the token’s roomConfig, not both. Conflicts can lead to unexpected dispatch behavior.
1. Check size/format of metadata
◦ Metadata is free-form. Extremely large metadata could cause the request to be truncated/ignored, but that’s uncommon. Still, test with a short simple metadata string to rule it out.
Immediate troubleshooting actions for you to run
1. Re-run createRoom while logging the full response and any error.
2. If the response shows success, paste the returned JSON for the created room (sensitive keys redacted). I’ll inspect the agent dispatch fields.
3. Try creating the room with explicit snake_case keys:
await roomService.createRoom({
name: roomName,
departure_timeout: 120,
metadata: metadataString,
agents: AGENT_NAME ? [ new RoomAgentDispatch({ agentName: AGENT_NAME }) ] : undefined,
});
1. Try creating the room without agents but with departure_timeout to see if agent logs appear; then add agents back and compare responses.
If you share these three things I’ll pinpoint the problem quickly:
• The createRoom response JSON when you include agents.
• The exact agent name you set in AGENT_NAME.
• Which library/package and version you use for RoomServiceClient (so I can confirm expected field names).
You’re very close — once I can see the createRoom response and the agent name, I’ll tell you why the agent logs stop and how to make sure your room gets dispatched to the agent so logs appear.
, with interactive elementshappy-fall-6105
03/23/2026, 10:05 AMtall-airline-16756
03/23/2026, 10:05 AMLOG_LEVEL, RUST_LOG, or a server option), increase it to info or debug and restart the agent. Then reproduce the create-room action and watch logs.
◦ Example: set LOG_LEVEL=debug (or equivalent) and restart.
1. Confirm log output sink
◦ Verify the agent writes to stdout/stderr. If it writes to a file, confirm the file path and permissions. If your platform captures stdout only, file logs won’t appear there.
◦ If using Kubernetes, run:
▪︎ kubectl get pods then kubectl logs <agent-pod-name> -f to stream logs live.
1. Reproduce with a simple action while streaming logs
◦ Stream logs (e.g., kubectl logs -f or Cloud Console live tail) and then immediately trigger join/create from your frontend. Note timestamps and whether any new output appears.
1. Look for subtle log entries
◦ Some agents only log on specific events (error, warnings, lifecycle events). Search for terms like agent, dispatch, session, join, or timestamps around your test join to see quieter messages.
1. Ensure your agent instance is the one handling the room
◦ If the Cloud control plane dispatches to another agent instance, you might be watching logs for the wrong agent. Confirm which agent registered for that room (agent name/ID) and tail that instance’s logs.
If you want, I can help further — please share:
• How you’re currently viewing logs (Cloud Console, kubectl, systemd, file path).
• The agent name/ID you set (so we can confirm which instance to inspect).
• Any environment variables or flags you use to start the agent (especially anything related to logging).
If you prefer, try this quick test and paste results:
1. Increase logging to debug (env var or startup flag).
2. Stream the agent logs live.
3. Trigger a new join/create for the room and paste any new log lines (redact secrets).
I’ll help interpret the output and give the exact config tweak to make logging reliable.
, with interactive elementshappy-fall-6105
03/24/2026, 8:34 AMtall-airline-16756
03/24/2026, 8:34 AMhappy-fall-6105
03/24/2026, 11:33 AMtall-airline-16756
03/24/2026, 11:33 AMhappy-fall-6105
03/24/2026, 1:07 PMtall-airline-16756
03/24/2026, 1:07 PMon_participant_connected.
Short answer
• New participants’ audio is delivered to the agent automatically by default. The agent subscribes to published microphone tracks when participants publish them, so you don’t strictly need to add a manual login in on_participant_connected for audio to reach the agent.
When you might still use on_participant_connected
• If you want custom behavior when someone joins, handle the event:
◦ Explicitly subscribe or unsubscribe the agent to that participant’s tracks.
◦ Apply per-participant rules (e.g., block this user from the agent, route only specific users).
◦ Send a welcome data message or trigger agent-side setup for that participant.
• If your agent is configured to target a single participant (e.g., RoomIO with a specific participant), then you will need to handle selection logic when participants connect so the agent knows which identity to focus on.
• If you implemented a button to prevent a user’s audio from reaching the agent (subscription toggle), you may need to update subscription state on participant connect/reconnect to maintain that setting.
Practical notes
• Default auto-subscribe behavior: When a participant publishes audio, agents will receive it unless subscription rules or explicit agent-side logic prevent it.
• Use on_participant_connected when you need to enforce custom subscription rules, maintain per-user mute-for-agent state, or initialize participant-specific processing (transcription, diarization, etc.).
• For robustness, if you rely on subscription toggles, ensure reconnects and new publishes re-apply the intended subscription state (you can re-apply in the participant-connected handler).
If you’d like, tell me which behavior you want by default (agent hears everyone, agent hears selected users, or agent hears everyone but only responds on wake-word) and whether you’ve implemented the agent-side subscription toggle. I can then provide a short code example showing how to use on_participant_connected to set or re-apply subscription rules.
, with interactive elements