I'm running into an error trying to audit via valu...
# ask-ai
e
I'm running into an error trying to audit via values returned from Room. can you explain to me the key difference between getting the Room name / sid from RoomInfo vs the direct methods? I note that the method returned on sid() is async?
t
Thanks for reaching out, Arthur. 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 why you’re seeing different behavior when auditing room name/SID from
RoomInfo
vs the client
Room
, and why
sid()
is async. •
RoomInfo
is server-provided metadata (e.g., from ListRooms, CreateRoom, or webhooks). It includes
sid
and
name
as plain fields and is available synchronously because it’s returned in the server response. • The client
Room
is a live, stateful object created when you connect. Its full server-side metadata (including the
sid
) arrives only after the join/ signaling response is received. Because that data isn’t available immediately on instantiation,
sid()
is async and resolves once the server’s join response has been processed. Practical guidance: • For auditing or logging where you need immediate, reliable `sid`/`name`, use
RoomInfo
from server APIs or your server-side records. • If you must use the client
Room
, wait for the connection/join to complete (or await
room.sid()
), then read the values to avoid race conditions. If you can share whether you’re using server-side APIs or the client SDK (and which SDK/language), I can give a short example for how to safely read the SID for auditing. Sources: Connecting to LiveKit | LiveKit docs | Managing rooms | LiveKit docs | client-sdk-js | livekit/livekit_composite | DeepWiki
e
To provide more context, we use a server create room job to also dispatch an agent - we want to ensure that the agent's logs include the right room sid and name. If this is how we init our workflows is it a guarantee that RoomInfo on the agents side will have the right sid and name?
t
Thanks — I’m responding to your question about whether the agent’s RoomInfo (populated from your server create-room job) will reliably contain the correct room SID and name for logging. Yes. If your server creates the room and sends the agent the RoomInfo produced by that create-room API (or includes the room’s sid and name in the job payload), the agent will have the correct, server-assigned
sid
and
name
synchronously for logging. RoomInfo is server-provided metadata and contains the final `sid`/`name` values, so using it in your agent’s job ensures consistent audit fields without waiting on client-side signaling. Practical suggestions to avoid issues: • Include the
sid
and
name
explicitly in the job payload you dispatch to the agent (derived from the CreateRoom response). • Log those values from the job payload immediately (don’t rely on the agent’s client-side
Room
object until it’s connected). • If you must use the agent’s
Room
SDK instance later, await
room.sid()
or the join completion before reading `sid`/`name` to avoid race conditions. If you want, tell me which server API or SDK you’re using and I’ll provide the exact payload/field names to include in the job.
e
Just for my knowledge, in what use case would we use room.sid() - when does an agent not know the sid() at init time?
t
Good question — responding to your ask about when to use
room.sid()
and why an agent might not know the SID at init time. When to use
room.sid()
(async) • When the client-side
Room
instance was created before the server’s join response arrives.
room.sid()
waits for that server-provided metadata, so use it when you need the SID after connecting. • When your agent joins a room using only a token/URL and does not receive server-created metadata separately. The SID is learned from the join/signaling flow, not at instantiation. • When code runs immediately after creating the
Room
object (e.g., in connection setup handlers) and you must avoid race conditions — awaiting
room.sid()
ensures the value is available. When an agent does NOT know the SID at init time • The agent was started with only a join token or connection URL and no server-side payload containing the room’s `sid`/`name`. • The
Room
object is constructed before the signaling
JoinResponse
is processed (common if you create the Room and then immediately run logic that reads the SID). • Transient reconnection flows where the local object exists but the fresh server state hasn’t arrived yet. Practical patterns • If your server creates the room and you dispatch the agent with the CreateRoom response (including `sid`/`name`), log from that payload immediately — no need for
room.sid()
. • If the agent only has a token/URL, await
room.sid()
or wait for the join/connected event before auditing/logging the SID. • Combine both: include
sid
in job payloads when possible; fall back to
await room.sid()
if the payload lacks it. If you tell me whether your agents currently receive the CreateRoom response in their job payload or only a token/URL, I can suggest the simplest change to ensure reliable logging.
e
If I want to store this data in agent context a long with other metadata I retrieve from my server at instantiation time - how would I do this? Would I store it as a Key on my TestAgent(Agent)?
t
Thanks — responding to your question about how to store room SID/name and other server metadata in the agent context at instantiation time. Short answer: yes — store the room metadata on the agent session context. You can put it as attributes on your TestAgent instance, but the recommended pattern is to attach structured data to
AgentSession.userdata
(or an equivalent session-scoped object) so it’s type-safe and accessible across tools/handlers. Recommended approach (concise): • Include
sid
and
name
in the job payload dispatched to the agent (derived from your CreateRoom response). • Build a small dataclass or dict that contains room info + other server metadata. • Pass that object into
AgentSession.userdata
before calling
session.start()
/
ctx.connect()
. • Access it from the agent via
self.session.userdata
(or keep copies on the agent instance if preferred). Minimal example (conceptual):
Copy code
@dataclass
class SessionContext:
    room_name: str
    room_sid: str
    user_profile: dict
    custom_config: dict

# create session with userdata
session = AgentSession[SessionContext](userdata=SessionContext(...))
await session.start(agent=TestAgent(), room=ctx.room)
# inside agent: use self.session.userdata.room_sid
Why
userdata
is preferred: • Keeps agent logic stateless while providing session-scoped state. • Easier to share with tools, handoffs, and structured logging. • Avoids race conditions because you populate it from the server-created RoomInfo before connecting. If you prefer storing directly on the agent instance, that’s fine for simple cases—just initialize those attributes from the same SessionContext before
session.start()
. If you want, tell me which language/SDK you’re using and I’ll give a short concrete snippet matching your stack. Sources: Job lifecycle | LiveKit docs | External data and RAG | LiveKit docs | Agents and handoffs | LiveKit docs | Building Multi-Agent Architectures with LiveKit Agents
e
If I am doing transfers to other agents - is this persisted in session?
t
Responding to your question about whether metadata persists when transferring to other agents. Yes — session-level data persists across agent transfers. The active
AgentSession
(including
session.room.name
,
session.room.sid
,
session.history
, and
session.userdata
) continues running and is shared with the new agent, so room identifiers and any userdata you store remain available after a handoff. Recommended steps to ensure persistence: • Put room SID/name and any server metadata into
AgentSession.userdata
(or a session-scoped dataclass) at instantiation. • When creating the new agent, reuse the same
AgentSession
(the handoff flow does this automatically). • If you need conversation continuity, pass the prior agent’s chat context (
chat_ctx
) into the new agent. If you want, tell me which SDK/language you’re using and I’ll give a tiny code snippet matching your stack. Sources: Agents and handoffs | LiveKit docs | Tool definition and use | LiveKit docs
e
So just to clarify, my tool calls all get ctx: RunContext - and to access this it is ctx.session.userdata[KEY] correct?
t
Yes — that’s correct. In a tool (where you receive a
RunContext
as
ctx
), access session-scoped metadata via
ctx.session.userdata
. Depending on how you stored it: • If
userdata
is a dict:
ctx.session.userdata["key"]
• If
userdata
is a dataclass/object:
ctx.session.userdata.key
Quick example:
Copy code
# dict style
value = ctx.session.userdata["room_sid"]

# dataclass style
value = ctx.session.userdata.room_sid
This
userdata
is persisted for the lifetime of the
AgentSession
and is available across agent transfers.
e
The room name is set but the room_sid was not available - why would this be the case? Instead of using room sid is there a room ID that I can use instead that is always there?
t
Thanks — I’m responding to why
room.name
can be present while
room.sid
is missing, and whether there’s an alternative always-present ID. Why
room.sid
may be missing while
room.name
exists • Timing:
room.name
can be provided in job payloads or from your server-created RoomInfo immediately. The
room.sid
on the client
Room
object becomes available only after the server’s join/signaling response is processed, so reading
room.sid
too early yields nothing. • Payload difference: If your dispatch/job includes
room.name
but does not include the CreateRoom response (or explicitly the
sid
), the agent will see the name from the payload but not the sid. • Token-only join: If an agent is started with only a token/URL and no server metadata, the SID must be learned from the join flow (so it’s async). Is there an alternative ID that’s always available? • There is no separate guaranteed persistent identifier other than the server-assigned room SID.
room.sid
is the canonical unique ID. •
room.name
is not guaranteed unique or immutable, so it’s not a reliable substitute for audit/logging. Practical fixes to ensure you always have an SID • Include the
sid
in the job payload you dispatch to the agent (take it from the CreateRoom response) and store it in
session.userdata
at instantiation. • If you must rely on the client
Room
, wait for the join/connected event or
await room.sid()
before logging or persisting the value. • Use both: prefer
session.userdata["room_sid"]
populated by your server; fall back to
await room.sid()
only if userdata lacks it. If you tell me whether your agent currently receives CreateRoom’s response in the job payload or only a token/URL, I’ll suggest the minimal change to guarantee the SID is available.