Skip to content

Commit 0e62be0

Browse files
Update Node starter to LiveKit Agents 1.5 (#54)
* Adopt @livekit/agents 1.5.0 (pre-release) Bump @livekit/agents to the 0.0.0-next-20260624041820 pre-release (next dist-tag) to validate against the upcoming 1.5.0 release. Pinned exactly for reproducible validation; to be repinned to stable 1.5.0 on release. Update the commented-out tools example in agent.ts to the 1.5.0 flat-array tool syntax with a required `name` (llm.tool({ name, ... }) in a `tools: [...]` array), and note that voice.Agent.create({...}) is now available as an alternative to subclassing voice.Agent. Co-authored-by: Cursor <cursoragent@cursor.com> * save 1.5.0 template * Update main.ts * Update agent.ts * ci: stop tracking pnpm-lock.yaml and pnpm-workspace.yaml check-template-files fails when pnpm-lock.yaml is tracked, and these files (absent on main) altered CI's install so prettier wasn't resolved. Untrack them to align with main. Co-authored-by: Cursor <cursoragent@cursor.com> * Update LiveKit Agents to stable 1.5 Co-authored-by: Cursor <cursoragent@cursor.com> * Remove incomplete AsyncToolset example Co-authored-by: Cursor <cursoragent@cursor.com> * Update starter dependency ranges Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent dd89b48 commit 0e62be0

4 files changed

Lines changed: 48 additions & 48 deletions

File tree

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@
3030
"vitest": "^4.1.4"
3131
},
3232
"dependencies": {
33-
"@livekit/agents": "^1.4.7",
33+
"@livekit/agents": "^1.5.0",
3434
"@livekit/plugins-ai-coustics": "^0.2.14",
35+
"@livekit/rtc-node": "^0.13.31",
3536
"dotenv": "^17.4.1",
36-
"zod": "^3.25.76"
37+
"zod": "^4.4.3"
3738
}
3839
}

src/agent.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { dedent, inference, initializeLogger, voice } from '@livekit/agents';
22
import dotenv from 'dotenv';
33
import { afterEach, beforeEach, describe, it } from 'vitest';
4-
import { Agent } from './agent.ts';
4+
import { createAgent } from './agent.ts';
55

66
dotenv.config({ path: '.env.local' });
77

@@ -16,7 +16,7 @@ describe('agent evaluation', () => {
1616
beforeEach(async () => {
1717
judgeLlm = new inference.LLM({ model: 'openai/gpt-4.1-mini' });
1818
session = new voice.AgentSession();
19-
await session.start({ agent: new Agent() });
19+
await session.start({ agent: createAgent() });
2020
});
2121

2222
afterEach(async () => {

src/agent.ts

Lines changed: 41 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { dedent, inference, voice } from '@livekit/agents';
1+
import { Agent, dedent, inference } from '@livekit/agents';
22

3-
// Define a custom voice AI assistant by extending the base Agent class
4-
export class Agent extends voice.Agent {
5-
constructor() {
6-
super({
7-
instructions: dedent`
3+
// Build a custom voice AI assistant with the functional `Agent.create` API
4+
export function createAgent() {
5+
return Agent.create({
6+
instructions: dedent`
87
You are a friendly, reliable voice assistant that answers questions, explains topics, and completes tasks with available tools.
98
109
# Output rules
@@ -38,42 +37,42 @@ export class Agent extends voice.Agent {
3837
- Protect privacy and minimize sensitive data.
3938
`,
4039

41-
// A Large Language Model (LLM) is your agent's brain, processing user input and generating a response
42-
// See all available models at https://docs.livekit.io/agents/models/llm/
43-
llm: new inference.LLM({ model: 'google/gemma-4-31b-it' }),
40+
// A Large Language Model (LLM) is your agent's brain, processing user input and generating a response
41+
// See all available models at https://docs.livekit.io/agents/models/llm/
42+
llm: new inference.LLM({ model: 'google/gemma-4-31b-it' }),
4443

45-
// To use a realtime model instead of a voice pipeline, replace the LLM
46-
// with a RealtimeModel and remove the STT/TTS from the AgentSession
47-
// (Note: This is for the OpenAI Realtime API. For other providers, see https://docs.livekit.io/agents/models/realtime/)
48-
// 1. Install '@livekit/agents-plugin-openai'
49-
// 2. Set OPENAI_API_KEY in .env.local
50-
// 3. Add `import * as openai from '@livekit/agents-plugin-openai'` to the top of this file
51-
// 4. Replace the llm option with:
52-
// llm: new openai.realtime.RealtimeModel({ voice: 'marin' }),
44+
// To use a realtime model instead of a voice pipeline, replace the LLM
45+
// with a RealtimeModel and remove the STT/TTS from the AgentSession
46+
// (Note: This is for the OpenAI Realtime API. For other providers, see https://docs.livekit.io/agents/models/realtime/)
47+
// 1. Install '@livekit/agents-plugin-openai'
48+
// 2. Set OPENAI_API_KEY in .env.local
49+
// 3. Add `import * as openai from '@livekit/agents-plugin-openai'` to the top of this file
50+
// 4. Replace the llm option with:
51+
// llm: new openai.realtime.RealtimeModel({ voice: 'marin' }),
5352

54-
// To add tools, specify `tools` in the constructor.
55-
// Here's an example that adds a simple weather tool.
56-
// You also have to add `import { llm } from '@livekit/agents' and `import { z } from 'zod'` to the top of this file
57-
// tools: {
58-
// getWeather: llm.tool({
59-
// description: dedent`
60-
// Use this tool to look up current weather information in the given location.
61-
//
62-
// If the location is not supported by the weather service, the tool will indicate this.
63-
// You must tell the user the location's weather is unavailable.
64-
// `,
65-
// parameters: z.object({
66-
// location: z
67-
// .string()
68-
// .describe('The location to look up weather information for (e.g. city name)'),
69-
// }),
70-
// execute: async ({ location }) => {
71-
// console.log(`Looking up weather for ${location}`);
72-
//
73-
// return 'sunny with a temperature of 70 degrees.';
74-
// },
75-
// }),
76-
// },
77-
});
78-
}
53+
// To add tools, specify `tools` in the constructor.
54+
// Here's an example that adds a simple weather tool.
55+
// You also have to add `import { tool } from '@livekit/agents'` and `import { z } from 'zod'` to the top of this file
56+
// tools: [
57+
// tool({
58+
// name: 'getWeather',
59+
// description: dedent`
60+
// Use this tool to look up current weather information in the given location.
61+
//
62+
// If the location is not supported by the weather service, the tool will indicate this.
63+
// You must tell the user the location's weather is unavailable.
64+
// `,
65+
// parameters: z.object({
66+
// location: z
67+
// .string()
68+
// .describe('The location to look up weather information for (e.g. city name)'),
69+
// }),
70+
// execute: async ({ location }) => {
71+
// console.log(`Looking up weather for ${location}`);
72+
//
73+
// return 'sunny with a temperature of 70 degrees.';
74+
// },
75+
// }),
76+
// ],
77+
});
7978
}

src/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ServerOptions, cli, defineAgent, inference, voice } from '@livekit/agen
22
import { audioEnhancement } from '@livekit/plugins-ai-coustics';
33
import dotenv from 'dotenv';
44
import { fileURLToPath } from 'node:url';
5-
import { Agent } from './agent.ts';
5+
import { createAgent } from './agent.ts';
66

77
// Load environment variables from a local file.
88
// Make sure to set LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET
@@ -41,7 +41,7 @@ export default defineAgent({
4141

4242
// Start the session, which initializes the voice pipeline and warms up the models
4343
await session.start({
44-
agent: new Agent(),
44+
agent: createAgent(),
4545
room: ctx.room,
4646
inputOptions: {
4747
// ai-coustics QUAIL audio enhancement for noise cancellation

0 commit comments

Comments
 (0)