Skip to content

Commit 3d0aaa7

Browse files
committed
feat(examples): add ElevenLabs realtime provider
1 parent c21c4be commit 3d0aaa7

5 files changed

Lines changed: 46 additions & 8 deletions

File tree

examples/ai-e2e-next/.env.local.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
# Then get your OpenAI API Key here: https://platform.openai.com/account/api-keys
33
OPENAI_API_KEY=xxxxxxx
44

5+
# Required for the ElevenLabs provider in the realtime example.
6+
# Create an agent at https://elevenlabs.io/app and copy its Agent ID.
7+
ELEVENLABS_API_KEY=xxxxxxx
8+
ELEVENLABS_AGENT_ID=xxxxxxx
9+
510
# You must first create an OpenAI Assistant here: https://platform.openai.com/assistants
611
# Then get your Assistant ID here: https://platform.openai.com/assistants
712
ASSISTANT_ID=xxxxxxx

examples/ai-e2e-next/app/api/realtime/[...path]/route.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { openai } from '@ai-sdk/openai';
22
import { google } from '@ai-sdk/google';
33
import { xai } from '@ai-sdk/xai';
4+
import { elevenLabs } from '@ai-sdk/elevenlabs';
45
import {
56
experimental_getRealtimeToolDefinitions as getRealtimeToolDefinitions,
67
gateway,
@@ -59,6 +60,10 @@ const providers: Record<
5960
factory: xai.experimental_realtime,
6061
model: 'grok-voice-latest',
6162
},
63+
elevenlabs: {
64+
factory: elevenLabs.experimental_realtime,
65+
model: process.env.ELEVENLABS_AGENT_ID ?? '',
66+
},
6267
gateway: {
6368
factory: gateway.experimental_realtime,
6469
model: 'openai/gpt-realtime-2',
@@ -87,6 +92,13 @@ export async function POST(
8792
: await getRealtimeToolDefinitions({ tools });
8893

8994
const { factory, model } = providerConfig;
95+
if (!model) {
96+
return Response.json(
97+
{ error: `Missing model configuration for provider: ${provider}` },
98+
{ status: 400 },
99+
);
100+
}
101+
90102
const tokenResult = await factory.getToken({
91103
model,
92104
sessionConfig:

examples/ai-e2e-next/app/realtime/page.tsx

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { experimental_useRealtime } from '@ai-sdk/react';
44
import { openai } from '@ai-sdk/openai';
55
import { google } from '@ai-sdk/google';
66
import { xai } from '@ai-sdk/xai';
7+
import { elevenLabs } from '@ai-sdk/elevenlabs';
78
import { useState, useRef, useEffect, useMemo } from 'react';
89

9-
type Provider = 'openai' | 'google' | 'xai';
10+
type Provider = 'openai' | 'google' | 'xai' | 'elevenlabs';
1011

1112
type VoiceOption = { id: string; label: string };
1213

@@ -23,6 +24,7 @@ const PROVIDER_CONFIG: Record<
2324
createModel: (
2425
modelId: string,
2526
) => ReturnType<typeof openai.experimental_realtime>;
27+
usesAgentConfiguration?: boolean;
2628
sessionConfigOverrides?: Record<string, unknown>;
2729
}
2830
> = {
@@ -59,6 +61,17 @@ const PROVIDER_CONFIG: Record<
5961
staticVoices: toVoiceOptions(['ara', 'eve', 'leo', 'rex', 'sal']),
6062
createModel: modelId => xai.experimental_realtime(modelId),
6163
},
64+
elevenlabs: {
65+
label: 'ElevenLabs',
66+
defaultModel: 'configured-agent',
67+
staticVoices: [],
68+
createModel: modelId => elevenLabs.experimental_realtime(modelId),
69+
usesAgentConfiguration: true,
70+
sessionConfigOverrides: {
71+
inputAudioFormat: { type: 'audio/pcm', rate: 16000 },
72+
outputAudioFormat: { type: 'audio/pcm', rate: 16000 },
73+
},
74+
},
6275
};
6376

6477
export default function RealtimePage() {
@@ -132,7 +145,7 @@ export default function RealtimePage() {
132145
style={selectStyle}
133146
>
134147
{currentVoices.length === 0 ? (
135-
<option>No voices available</option>
148+
<option>Agent default</option>
136149
) : (
137150
currentVoices.map(v => (
138151
<option key={v.id} value={v.id}>
@@ -185,12 +198,16 @@ function RealtimeChat({
185198

186199
const sessionConfig = useMemo(
187200
() => ({
188-
instructions:
189-
'You are a helpful assistant. Be concise. ' +
190-
'You have access to tools for weather and dice rolling.',
191-
inputAudioTranscription: {},
192-
voice,
193-
turnDetection: { type: 'server-vad' as const },
201+
...(config.usesAgentConfiguration
202+
? {}
203+
: {
204+
instructions:
205+
'You are a helpful assistant. Be concise. ' +
206+
'You have access to tools for weather and dice rolling.',
207+
inputAudioTranscription: {},
208+
...(voice ? { voice } : {}),
209+
turnDetection: { type: 'server-vad' as const },
210+
}),
194211
...config.sessionConfigOverrides,
195212
}),
196213
[voice, config],

examples/ai-e2e-next/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"@ai-sdk/azure": "workspace:*",
1515
"@ai-sdk/cohere": "workspace:*",
1616
"@ai-sdk/deepseek": "workspace:*",
17+
"@ai-sdk/elevenlabs": "workspace:*",
1718
"@ai-sdk/fireworks": "workspace:*",
1819
"@ai-sdk/google": "workspace:*",
1920
"@ai-sdk/google-vertex": "workspace:*",

pnpm-lock.yaml

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

0 commit comments

Comments
 (0)