Skip to content

Commit aed2da2

Browse files
feat: Add outbound example (#237)
1 parent ec0144f commit aed2da2

File tree

3 files changed

+80
-5
lines changed

3 files changed

+80
-5
lines changed

examples/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@livekit/agents-plugin-elevenlabs": "workspace:*",
2121
"@livekit/agents-plugin-openai": "workspace:*",
2222
"@livekit/agents-plugin-silero": "workspace:*",
23+
"livekit-server-sdk": "^2.9.2",
2324
"@livekit/rtc-node": "^0.12.1",
2425
"zod": "^3.23.8"
2526
},

examples/src/outbound.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
import {
5+
type JobContext,
6+
type JobProcess,
7+
WorkerOptions,
8+
cli,
9+
defineAgent,
10+
llm,
11+
pipeline,
12+
} from '@livekit/agents';
13+
import * as deepgram from '@livekit/agents-plugin-deepgram';
14+
import * as elevenlabs from '@livekit/agents-plugin-elevenlabs';
15+
import * as openai from '@livekit/agents-plugin-openai';
16+
import * as silero from '@livekit/agents-plugin-silero';
17+
import { SipClient } from 'livekit-server-sdk';
18+
import { fileURLToPath } from 'node:url';
19+
20+
export default defineAgent({
21+
prewarm: async (proc: JobProcess) => {
22+
proc.userData.vad = await silero.VAD.load();
23+
},
24+
entry: async (ctx: JobContext) => {
25+
const vad = ctx.proc.userData.vad! as silero.VAD;
26+
27+
await ctx.connect();
28+
29+
const sipClient = new SipClient(
30+
process.env.LIVEKIT_URL ?? '',
31+
process.env.LIVEKIT_API_KEY,
32+
process.env.LIVEKIT_API_SECRET,
33+
);
34+
35+
const trunkId = '...'; // create this with the CLI: https://docs.livekit.io/agents/quickstarts/outbound-calls/
36+
const phoneNumber = '...'; // read this from the metadata or hardcode it - e.g.: 'tel:+43.....'
37+
const roomName = ctx.room.name ?? '';
38+
const participantIdentity = 'Example participant identity';
39+
40+
const sipParticipantOptions = {
41+
participantIdentity,
42+
participantName: 'Example participant name',
43+
};
44+
45+
console.log('came here');
46+
await sipClient.createSipParticipant(trunkId, phoneNumber, roomName, sipParticipantOptions);
47+
48+
const participant = await ctx.waitForParticipant(participantIdentity);
49+
50+
const initialContext = new llm.ChatContext().append({
51+
role: llm.ChatRole.SYSTEM,
52+
text: 'You are a helpful assistant.',
53+
});
54+
55+
const agent = new pipeline.VoicePipelineAgent(
56+
vad,
57+
new deepgram.STT(),
58+
new openai.LLM(),
59+
new elevenlabs.TTS(),
60+
{
61+
chatCtx: initialContext,
62+
},
63+
);
64+
65+
agent.start(ctx.room, participant);
66+
67+
await agent.say('Hello - how can I help?', true);
68+
},
69+
});
70+
71+
cli.runApp(new WorkerOptions({ agent: fileURLToPath(import.meta.url) }));

pnpm-lock.yaml

Lines changed: 8 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)