dazzling-truck-32153
12/28/2025, 11:44 PMtall-airline-16756
12/28/2025, 11:44 PMtall-airline-16756
12/28/2025, 11:44 PMegress_ended webhook: it fires when the recording finishes and includes the file location so you can start downloads or post-processing immediately.
If you tell me which output (S3, GCS, or a streaming destination) you’re using and whether you’re seeing longer delays, I can help diagnose further.
Sources: server-sdk-js | livekit/livekit_composite | DeepWikidazzling-truck-32153
12/28/2025, 11:46 PMtall-airline-16756
12/28/2025, 11:46 PMegress_ended webhook?dazzling-truck-32153
12/31/2025, 3:49 AMtall-airline-16756
12/31/2025, 3:49 AMParticipantKind.AGENT) and can receive live audio, video, and data from users, run STT/LLM/TTS and vision models, then publish synthesized audio (and optionally video/avatars) back into the room. They support real-time multimodal interactions and common use cases like assistants, translators, NPCs, and meeting note-takers.
If you want, tell me:
• Which language/runtime you prefer (Node.js or Python)
• Whether you need vision (camera) processing or audio-only
• If you want a prebuilt integration (e.g., OpenAI, Deepgram, ElevenLabs) or a custom model
I can then point you to the right quickstart and a minimal example to get started.
Sources: Agents (Python) | livekit/livekit_composite | DeepWiki | Vision | LiveKit docs | LiveKit Docs | An open source stack for real-time multimodal AIdazzling-truck-32153
12/31/2025, 3:53 AMtall-airline-16756
12/31/2025, 3:53 AMParticipantKind.AGENT) from Node.js. The agent can subscribe to a single participant’s tracks, run STT/LLM/TTS, and publish synthesized audio back to the room.
• Targeting one participant: Subscribe only to that participant’s audio/video tracks (identify them by participant SID or identity) so the agent listens and responds to just that person.
• Camera processing: Supported — you can capture video frames from the participant’s video track and send them to vision models (e.g., Gemini Live / OpenAI Realtime) for analysis, then use results in the agent’s responses.
• Avatars: Optional. You can publish a video track (avatar output) from the agent instead of or in addition to audio if you want visual presence.
• Prebuilt integrations: Use plugins for STT, TTS, and VAD (Deepgram, ElevenLabs, Silero, etc.) to simplify setup, or wire your own model endpoints.
• Where to start: Use the Node.js Agent quickstart / Agent Builder to prototype an AgentSession that:
a. Joins the room as an agent.
b. Subscribes to the chosen participant’s tracks.
c. Streams audio/video into your STT/vision/LLM pipeline.
d. Converts responses to audio (TTS) and publishes back to the room.
If you’d like, I can:
• Provide a minimal Node.js example showing how to join as an agent and subscribe to one participant.
• Show sample code for extracting video frames and sending them to a vision model.
• Recommend plugins for STT/TTS based on your preferred providers.
Which would you like next, and which STT/LLM/TTS providers do you plan to use (or do you want recommendations)?dazzling-truck-32153
12/31/2025, 3:56 AMtall-airline-16756
12/31/2025, 3:56 AM// agent.js
import { LivekitServer, RoomServiceClient, Participant } from "livekit-server-sdk";
import { Deepgram } from "@deepgram/sdk";
import fetch from "node-fetch";
import WebSocket from "ws";
import fs from "fs";
import { spawn } from "child_process"; // for local audio handling if needed
// CONFIG - fill these
const LIVEKIT_API_KEY = process.env.LIVEKIT_API_KEY;
const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET;
const LIVEKIT_URL = process.env.LIVEKIT_URL; // e.g., <wss://cloud.livekit.io>
const ROOM_NAME = "test-room";
const AGENT_IDENTITY = "ai-agent-node";
const TARGET_PARTICIPANT_IDENTITY = "user-to-respond-to";
const DEEPGRAM_API_KEY = process.env.DG_API_KEY;
const GROQ_API_KEY = process.env.GROQ_API_KEY;
const TTS_API_KEY = process.env.TTS_API_KEY; // ElevenLabs or other
// Initialize SDK clients
const lg = new LivekitServer(LIVEKIT_API_KEY, LIVEKIT_API_SECRET, { url: LIVEKIT_URL });
const deepgram = new Deepgram(DEEPGRAM_API_KEY);
// 1) Create an ephemeral token so the agent can join (server-side)
async function createAgentToken() {
const at = lg.joinToken(ROOM_NAME, { name: AGENT_IDENTITY, participantType: "agent" });
return at.toJwt();
}
// 2) Connect as a participant (we'll use WebRTC-less approach conceptually)
// In practice use a WebRTC client to publish an output audio track. For simplicity, this example shows
// server flow for receiving audio via LiveKit egress or subscribing; actual media plumbing requires a WebRTC endpoint.
// Simplified flow: subscribe to the participant's audio via LiveKit WebSocket Events or use Track Egress.
// Here we demonstrate using Deepgram's streaming via WebSocket with PCM chunks you provide.
// Helper: send transcript to Groq Moonshot
async function askGroq(prompt) {
const res = await fetch("<https://api.groq.ai/v1/streams>", {
method: "POST",
headers: {
"Authorization": `Bearer ${GROQ_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "moonshot",
input: prompt,
}),
});
const data = await res.json();
// adjust based on Groq streaming/response shape
return data.output || data.text || JSON.stringify(data);
}
// Helper: TTS (ElevenLabs example)
async function ttsGenerate(text) {
const res = await fetch("<https://api.elevenlabs.io/v1/text-to-speech/YOUR_VOICE_ID>", {
method: "POST",
headers: {
"xi-api-key": TTS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ text }),
});
const arrayBuffer = await res.arrayBuffer();
fs.writeFileSync("response.wav", Buffer.from(arrayBuffer));
return "response.wav";
}
// Main orchestration (conceptual)
async function runAgent() {
// 1. Create token and instruct your client to join as agent (or create a WebRTC client here)
const token = await createAgentToken();
console.log("Agent token (use to join room as agent):", token);
// 2. Subscribe to track(s) of target participant
// In a full implementation, your agent's client subscribes to the participant's audio track and receives PCM frames.
// For demo: assume you receive chunks of audio (PCM or opus) that you forward to Deepgram.
// Example: using Deepgram live websocket (conceptual)
const dgSocketUrl = `<wss://api.deepgram.com/v1/listen?encoding=linear16&sample_rate=16000`;>
const ws = new WebSocket(dgSocketUrl, {
headers: { Authorization: `Token ${DEEPGRAM_API_KEY}` },
});
ws.on("open", () => {
console.log("Deepgram WS open — stream audio here");
// send audio bytes as you receive them from the participant's track
});
ws.on("message", async (msg) => {
const parsed = JSON.parse(msg.toString());
if (parsed.channel && parsed.channel.alternatives) {
const transcript = parsed.channel.alternatives[0].transcript;
console.log("Transcript:", transcript);
// send transcript to Groq for response
const reply = await askGroq(transcript);
console.log("Groq reply:", reply);
// generate TTS audio
const wavPath = await ttsGenerate(reply);
// publish wavPath as audio track into LiveKit room (requires a WebRTC or track-publish flow)
// For example, use a local headless WebRTC client to publish `response.wav` as the agent's audio track.
// Implementation of publishing is environment-specific; use a browser RTCPeerConnection or a server-side
// WebRTC implementation to push audio into LiveKit.
}
});
ws.on("close", () => console.log("Deepgram WS closed"));
}
runAgent().catch(console.error);
Notes and next steps
• Media plumbing: The example shows orchestration. To actually hear the agent in the room you must publish a microphone-like audio track from the agent. That requires a WebRTC client (browser or server-side) to create and publish an audio track (e.g., play generated WAV into an AudioWorklet or use a server WebRTC library to push PCM to a track).
• Subscribing to a single participant: identify them by identity or SID and subscribe to their tracks in your agent client; only forward that audio to Deepgram.
• Camera processing: subscribe to the participant's video track, grab frames (e.g., via a MediaStream in a browser agent or using server-side frame extractor if using a headless WebRTC client), then send frames to Groq vision or your chosen model.
• Avatars: if you want an avatar video, publish a video track from the agent. That can be an MJPEG or generated frames streamed via a WebRTC video track.
• Plugins: use Deepgram for STT (streaming), Groq Moonshot for LLM replies, and ElevenLabs (or another TTS) for audio synthesis as shown.
If you want, I can:
• Provide a more complete example showing how to publish the generated audio into LiveKit (browser-based agent or server WebRTC example).
• Show code to extract video frames and send them to Groq vision.
Which of those would you like next?