Add attributes inspector and explicit dispatch support (#144)

This commit is contained in:
Ben Cherry
2025-05-29 15:26:04 -07:00
committed by GitHub
parent 5eddfa935c
commit 0218a5a002
30 changed files with 1208 additions and 692 deletions

View File

@@ -2,21 +2,36 @@ import { NextApiRequest, NextApiResponse } from "next";
import { generateRandomAlphanumeric } from "@/lib/util";
import { AccessToken } from "livekit-server-sdk";
import { RoomAgentDispatch, RoomConfiguration } from "@livekit/protocol";
import type { AccessTokenOptions, VideoGrant } from "livekit-server-sdk";
import { TokenResult } from "../../lib/types";
const apiKey = process.env.LIVEKIT_API_KEY;
const apiSecret = process.env.LIVEKIT_API_SECRET;
const createToken = (userInfo: AccessTokenOptions, grant: VideoGrant) => {
const createToken = (
userInfo: AccessTokenOptions,
grant: VideoGrant,
agentName?: string,
) => {
const at = new AccessToken(apiKey, apiSecret, userInfo);
at.addGrant(grant);
if (agentName) {
at.roomConfig = new RoomConfiguration({
agents: [
new RoomAgentDispatch({
agentName: agentName,
metadata: '{"user_id": "12345"}',
}),
],
});
}
return at.toJwt();
};
export default async function handleToken(
req: NextApiRequest,
res: NextApiResponse
res: NextApiResponse,
) {
try {
if (req.method !== "POST") {
@@ -32,34 +47,47 @@ export default async function handleToken(
const {
roomName: roomNameFromBody,
participantName,
participantName: participantNameFromBody,
participantId: participantIdFromBody,
metadata: metadataFromBody,
attributes: attributesFromBody,
agentName: agentNameFromBody,
} = req.body;
// Get room name from query params or generate random one
const roomName = roomNameFromBody as string ||
const roomName =
(roomNameFromBody as string) ||
`room-${generateRandomAlphanumeric(4)}-${generateRandomAlphanumeric(4)}`;
// Get participant name from query params or generate random one
const identity = participantIdFromBody as string ||
const identity =
(participantIdFromBody as string) ||
`identity-${generateRandomAlphanumeric(4)}`;
// Get agent name from query params or use none (automatic dispatch)
const agentName = (agentNameFromBody as string) || undefined;
// Get metadata and attributes from query params
const metadata = metadataFromBody as string | undefined;
const attributesStr = attributesFromBody as string | undefined;
const attributes = attributesStr || {};
const participantName = participantNameFromBody || identity;
const grant: VideoGrant = {
room: roomName,
roomJoin: true,
canPublish: true,
canPublishData: true,
canSubscribe: true,
canUpdateOwnMetadata: true,
};
const token = await createToken({ identity, metadata, attributes, name: participantName }, grant);
const token = await createToken(
{ identity, metadata, attributes, name: participantName },
grant,
agentName,
);
const result: TokenResult = {
identity,
accessToken: token,
@@ -70,4 +98,4 @@ export default async function handleToken(
res.statusMessage = (e as Error).message;
res.status(500).end();
}
}
}

View File

@@ -12,7 +12,11 @@ import { PlaygroundConnect } from "@/components/PlaygroundConnect";
import Playground from "@/components/playground/Playground";
import { PlaygroundToast, ToastType } from "@/components/toast/PlaygroundToast";
import { ConfigProvider, useConfig } from "@/hooks/useConfig";
import { ConnectionMode, ConnectionProvider, useConnection } from "@/hooks/useConnection";
import {
ConnectionMode,
ConnectionProvider,
useConnection,
} from "@/hooks/useConnection";
import { useMemo } from "react";
import { ToastProvider, useToast } from "@/components/toast/ToasterProvider";
@@ -44,26 +48,26 @@ export default function Home() {
export function HomeInner() {
const { shouldConnect, wsUrl, token, mode, connect, disconnect } =
useConnection();
const {config} = useConfig();
const { config } = useConfig();
const { toastMessage, setToastMessage } = useToast();
const handleConnect = useCallback(
async (c: boolean, mode: ConnectionMode) => {
c ? connect(mode) : disconnect();
},
[connect, disconnect]
[connect, disconnect],
);
const showPG = useMemo(() => {
if (process.env.NEXT_PUBLIC_LIVEKIT_URL) {
return true;
}
if(wsUrl) {
if (wsUrl) {
return true;
}
return false;
}, [wsUrl])
}, [wsUrl]);
return (
<>
@@ -129,4 +133,4 @@ export function HomeInner() {
</main>
</>
);
}
}