Loading...
Loading...
Build LiveKit Agent backends in TypeScript or JavaScript. Use this skill when creating voice AI agents, voice assistants, or any realtime AI application using LiveKit's Node.js Agents SDK (@livekit/agents-js). Covers AgentSession, Agent class, function tools with zod, STT/LLM/TTS models, turn detection, and realtime models.
npx skill4agent add codestackr/livekit-skills agents-tsdocs_searchget_pagesget_changelogcode_searchget_python_agent_examplepnpm add @livekit/agents@1.x \
@livekit/agents-plugin-silero@1.x \
@livekit/agents-plugin-livekit@1.x \
@livekit/noise-cancellation-node@0.x \
dotenv.env.locallk app env -w.env.localLIVEKIT_API_KEY=your_api_key
LIVEKIT_API_SECRET=your_api_secret
LIVEKIT_URL=wss://your-project.livekit.cloudimport {
type JobContext,
type JobProcess,
WorkerOptions,
cli,
defineAgent,
voice,
} from '@livekit/agents';
import * as livekit from '@livekit/agents-plugin-livekit';
import * as silero from '@livekit/agents-plugin-silero';
import { BackgroundVoiceCancellation } from '@livekit/noise-cancellation-node';
import { fileURLToPath } from 'node:url';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });
export default defineAgent({
prewarm: async (proc: JobProcess) => {
proc.userData.vad = await silero.VAD.load();
},
entry: async (ctx: JobContext) => {
const vad = ctx.proc.userData.vad! as silero.VAD;
const assistant = new voice.Agent({
instructions: `You are a helpful voice AI assistant.
Keep responses concise, 1-3 sentences. No markdown or emojis.`,
});
const session = new voice.AgentSession({
vad,
stt: "assemblyai/universal-streaming:en",
llm: "openai/gpt-4.1-mini",
tts: "cartesia/sonic-3:9626c31c-bec5-4cca-baa8-f8ba9e84c8bc",
turnDetection: new livekit.turnDetector.MultilingualModel(),
});
await session.start({
agent: assistant,
room: ctx.room,
inputOptions: {
// For standard web/mobile participants use BackgroundVoiceCancellation()
// For telephony/SIP applications use TelephonyBackgroundVoiceCancellation()
noiseCancellation: BackgroundVoiceCancellation(),
},
});
await ctx.connect();
const handle = session.generateReply({
instructions: 'Greet the user and offer your assistance.',
});
await handle.waitForPlayout();
},
});
cli.runApp(new WorkerOptions({ agent: fileURLToPath(import.meta.url) }));import {
type JobContext,
WorkerOptions,
cli,
defineAgent,
voice,
} from '@livekit/agents';
import * as openai from '@livekit/agents-plugin-openai';
import { BackgroundVoiceCancellation } from '@livekit/noise-cancellation-node';
import { fileURLToPath } from 'node:url';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });
export default defineAgent({
entry: async (ctx: JobContext) => {
const assistant = new voice.Agent({
instructions: 'You are a helpful voice AI assistant.',
});
const session = new voice.AgentSession({
llm: new openai.realtime.RealtimeModel({
voice: 'coral',
}),
});
await session.start({
agent: assistant,
room: ctx.room,
inputOptions: {
// For standard web/mobile participants use BackgroundVoiceCancellation()
// For telephony/SIP applications use TelephonyBackgroundVoiceCancellation()
noiseCancellation: BackgroundVoiceCancellation(),
},
});
await ctx.connect();
const handle = session.generateReply({
instructions: 'Greet the user and offer your assistance.',
});
await handle.waitForPlayout();
},
});
cli.runApp(new WorkerOptions({ agent: fileURLToPath(import.meta.url) }));import { defineAgent, type JobContext, type JobProcess } from '@livekit/agents';
export default defineAgent({
// Optional: Preload models before jobs start
prewarm: async (proc: JobProcess) => {
proc.userData.vad = await silero.VAD.load();
},
// Required: Main entry point for each job
entry: async (ctx: JobContext) => {
// Your agent logic here
},
});voice.Agentimport { voice, llm } from '@livekit/agents';
import { z } from 'zod';
// Option 1: Direct instantiation
const assistant = new voice.Agent({
instructions: 'Your system prompt here',
tools: {
getWeather: llm.tool({
description: 'Get the current weather for a location',
parameters: z.object({
location: z.string().describe('The city name'),
}),
execute: async ({ location }) => {
return `The weather in ${location} is sunny and 72°F`;
},
}),
},
});
// Option 2: Class extension (recommended for complex agents)
class Assistant extends voice.Agent {
constructor() {
super({
instructions: 'Your system prompt here',
tools: {
getWeather: llm.tool({
description: 'Get the current weather for a location',
parameters: z.object({
location: z.string().describe('The city name'),
}),
execute: async ({ location }) => {
return `The weather in ${location} is sunny and 72°F`;
},
}),
},
});
}
}const session = new voice.AgentSession({
stt: "assemblyai/universal-streaming:en",
llm: "openai/gpt-4.1-mini",
tts: "cartesia/sonic-3:voice_id",
vad: await silero.VAD.load(),
turnDetection: new livekit.turnDetector.MultilingualModel(),
});session.start({ agent, room })session.say(text)session.generateReply({ instructions })session.interrupt()session.updateAgent(newAgent)package.json{
"scripts": {
"dev": "tsx agent.ts dev",
"build": "tsc",
"start": "node agent.js start",
"download-files": "tsc && node agent.js download-files"
}
}# Development mode with auto-reload
pnpm dev
# Production mode
pnpm build && pnpm start
# Download required model files
pnpm download-files"assemblyai/universal-streaming:en""deepgram/nova-3:en""cartesia/ink""openai/gpt-4.1-mini""openai/gpt-4.1""openai/gpt-5""gemini/gemini-3-flash""cartesia/sonic-3:{voice_id}""elevenlabs/eleven_turbo_v2_5:{voice_id}""deepgram/aura:{voice}"@livekit/agents # Core framework
@livekit/agents-plugin-openai # OpenAI (LLM, STT, TTS, Realtime)
@livekit/agents-plugin-deepgram # Deepgram (STT, TTS)
@livekit/agents-plugin-elevenlabs # ElevenLabs (TTS)
@livekit/agents-plugin-silero # Silero (VAD)
@livekit/agents-plugin-livekit # Turn detector
@livekit/agents-plugin-gemini # Google Gemini
@livekit/agents-plugin-groq # Groq
@livekit/noise-cancellation-node # Noise cancellationprewarmBackgroundVoiceCancellation()TelephonyBackgroundVoiceCancellation()waitForPlayout()lk app env -w