agents
agents copied to clipboard
JobRequest- req.room.metadata is null in livekit-agents==0.8.9 and 0.8.10 on self hosted cluster.
For LiveKit agent plugin versions livekit-agents==0.8.8, we get room metadata in
async def request_fnc(req: JobRequest) -> None:
in req.room.metadata as value what we set while creating room, but in version 0.8.9 and 0.8.10 room metadata is empty.This is creating issue as we decide whether to accept or reject job by an worker based on metadata.
For debugging this further we setup another Kubernetes cluster with latest version of LiveKit server(1.7.2) and on that we faced same issue, but when we try same agent with a cloud url we are getting data for req.room.metadata in that case in request_fnc function.All this works fine upto version 0.8.8, and after that it works fine only against cloud deployments.
While debugging further we noticed that when worker registers against self hosted LiveKit server we get—
{"message": "registered worker", "level": "INFO", "id": "AW_RUiaBy8tZiJG", "server_info": "version: "1.7.2"\nprotocol: 14\nnode_id: "ND_YoMMvbptFrzu"\nagent_protocol: 1\n", "timestamp": "2024-09-06T13:38:17.174800+00:00"}
And on cloud we get- {"message": "registered worker", "level": "INFO", "id": "AW_9WpsyqqF9Zjp", "server_info": "edition: Cloud\nversion: "1.7.2"\nprotocol: 15\nregion: "India"\nnode_id: "NC_DBLR1A_auoA9TfuCnyV"\n", "timestamp": "2024-09-06T09:19:44.927947+00:00”}
Is it due to protocol difference 14 and 15?
I am facing the same issue. Did you find a solution to this?
Actually it was an issue on my end.
My approach where metadata is correctly passed to the agent request_func:
- NextJS App (UI + Server)
- LiveKit Agent (Python) -> this is where request_func is called
In the NextJS App I create an API to 'createRoom'. This API. creates a room, sets the metadata and generates a token for the user:
Example route.ts
import { RoomServiceClient, AccessToken } from 'livekit-server-sdk';
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const apiKey = process.env.LIVEKIT_API_KEY;
const apiSecret = process.env.LIVEKIT_API_SECRET;
const wsUrl = process.env.LIVEKIT_WS_URL;
if (!apiKey || !apiSecret || !wsUrl) {
console.error('LiveKit environment variables are not set');
return NextResponse.json({ error: 'Server misconfigured' }, { status: 500 });
}
const roomService = new RoomServiceClient(wsUrl, apiKey, apiSecret);
try {
const roomId = crypto.randomUUID()
const room = await roomService.createRoom({
name: roomId,
metadata: JSON.stringify({ type: 'chat' }),
});
// Create an access token
const at = new AccessToken(apiKey, apiSecret, {
identity: 'user_id',
ttl: '10m', // Token expires after 10 minutes
});
at.addGrant({ roomJoin: true, room: roomId });
const token = await at.toJwt();
return NextResponse.json({ room, token });
} catch (error) {
console.error('Error creating room and token:', error);
return NextResponse.json({ error: 'Failed to create room and token' }, { status: 500 });
}
}
Now I consume this client side like this:
'use client'
import { LiveKitRoom } from '@livekit/components-react'
import { Room } from 'livekit-client'
import { useEffect, useState } from 'react'
export interface LKRoomProps {
token: string
url: string
children: React.ReactNode
}
export function LKRoom({ token, url, children }: LKRoomProps) {
const [room, setRoom] = useState<Room | null>(null);
useEffect(() => {
const setupRoom = async () => {
const response = await fetch('/api/create-room', { method: 'POST' });
const data = await response.json();
const newRoom = new Room();
await newRoom.connect(url, data['token']);
setRoom(newRoom);
}
setupRoom();
}, [url, token]);
if (!room) return null;
return (
<LiveKitRoom serverUrl={url} token={token} connect={true} room={room}>
{children}
</LiveKitRoom>
);
}
I have same issues is there any update on this ?
same issue. meta data always nil. livekit-agents==0.10.2
2024-10-28 17:43:35,485 - INFO voice-agent - connecting to room test-room22222, rtc.Room(sid=unknown, name=test-room22222, metadata=, connection_state=1) {"pid": 87126, "job_id": "AJ_DNYdmSAqkeU8"}
As a workaround I tried to set metadata to participant and it works:
token = (
api.AccessToken(self.livekit_api_key, self.livekit_api_secret)
.with_identity(identity)
.with_name(room_name)
.with_grants(
api.VideoGrants(
room_join=True,
room=room_name,
room_record=True,
)
)
.with_metadata(metadata_str)
.to_jwt()
)
This is still happening in Feb of 2024 -- would love to fix this ASAP.
I have a usecase where I won't have a user joining the room
@firattamurlc and then, how do you access and give this metadata to the agent under JobContext?
@firattamurlc How do you read the metadata? Can't access the metadata in the room metadata, the participant metadata or in the jobcontext...
I also ran into this issue with reading room metadata.
In my case, the problem was that the metadata is not immediately available before connecting to the room. The fix was to call:
await ctx.connect()
before trying to read ctx.room.metadata.
After connecting, the metadata is accessible as expected.
Here’s a simplified example of how I handled it:
# Create room with metadata
room = await lkapi.room.create_room(
api.CreateRoomRequest(
name=room_name,
empty_timeout=empty_timeout,
max_participants=max_participants,
metadata=metadata_json, # 📌 关键:存储 metadata
)
)
# Agent entrypoint
async def entrypoint(ctx: JobContext):
try:
await ctx.connect()
if not ctx.room.metadata:
raise ValueError("房间 metadata 为空,无法加载配置")
# Use ctx.room.metadata here
config = json.loads(ctx.room.metadata)
...
except Exception as e:
logger.error(f"加载房间配置失败: {e}")
After adding await ctx.connect(), everything worked correctly.
thanks for sharing the solution @xiesiyang !