import { Room, RoomEvent } from "livekit-client";
const CORE_SERVICE_BASE_URL = "https://live.convai.com";
const API_KEY = "<X-Api-Key>";
const CHARACTER_ID = "<your character_id>";
async function startVoiceSessionAndWatchMetrics() {
// 1) Call /connect with debug enabled
const connectResp = await fetch(`${CORE_SERVICE_BASE_URL}/connect`, {
method: "POST",
headers: {
"x-api-key": API_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
character_id: CHARACTER_ID,
debug: true,
}),
});
if (!connectResp.ok) {
throw new Error(`/connect failed: ${connectResp.status}`);
}
const connectData = await connectResp.json();
const { room_url, token, session_id } = connectData;
// 2) Join the WebRTC room using room_url + token
const room = new Room();
room.on(RoomEvent.Connected, () => {
console.log("Connected to room");
});
room.on(RoomEvent.DataReceived, (payload) => {
// LiveKit data payload is bytes -> decode -> parse JSON
let msg;
try {
const text = new TextDecoder().decode(payload);
msg = JSON.parse(text);
} catch {
return;
}
// 3) Filter only RTVI metrics messages
if (msg?.label !== "rtvi-ai") return;
if (msg?.type !== "metrics") return;
const ttfb = msg?.data?.ttfb ?? [];
const processing = msg?.data?.processing ?? [];
const custom = msg?.data?.custom ?? [];
console.log("RTVI metrics", { ttfb, processing, custom });
});
room.on(RoomEvent.Disconnected, () => {
console.log("Disconnected from room");
});
await room.connect(room_url, token);
// Return objects so caller can disconnect/cleanup later
return { room, session_id };
}
// Example usage:
startVoiceSessionAndWatchMetrics().catch(console.error);