@assistant-ui/mcp-docs-server 0.1.25 → 0.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docs/organized/code-examples/waterfall.md +4 -4
- package/.docs/organized/code-examples/with-a2a.md +5 -5
- package/.docs/organized/code-examples/with-ag-ui.md +6 -6
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +7 -7
- package/.docs/organized/code-examples/with-artifacts.md +7 -7
- package/.docs/organized/code-examples/with-assistant-transport.md +5 -5
- package/.docs/organized/code-examples/with-chain-of-thought.md +7 -7
- package/.docs/organized/code-examples/with-cloud-standalone.md +8 -8
- package/.docs/organized/code-examples/with-cloud.md +7 -7
- package/.docs/organized/code-examples/with-custom-thread-list.md +7 -7
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +511 -0
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +10 -10
- package/.docs/organized/code-examples/with-expo.md +18 -18
- package/.docs/organized/code-examples/with-external-store.md +5 -5
- package/.docs/organized/code-examples/with-ffmpeg.md +220 -66
- package/.docs/organized/code-examples/with-google-adk.md +6 -6
- package/.docs/organized/code-examples/with-heat-graph.md +4 -4
- package/.docs/organized/code-examples/with-interactables.md +836 -0
- package/.docs/organized/code-examples/with-langgraph.md +6 -6
- package/.docs/organized/code-examples/with-livekit.md +591 -0
- package/.docs/organized/code-examples/with-parent-id-grouping.md +6 -6
- package/.docs/organized/code-examples/with-react-hook-form.md +8 -8
- package/.docs/organized/code-examples/with-react-ink.md +3 -3
- package/.docs/organized/code-examples/with-react-router.md +11 -11
- package/.docs/organized/code-examples/with-store.md +11 -6
- package/.docs/organized/code-examples/with-tanstack.md +8 -8
- package/.docs/organized/code-examples/with-tap-runtime.md +8 -8
- package/.docs/raw/blog/2026-03-launch-week/index.mdx +31 -0
- package/.docs/raw/docs/(docs)/cli.mdx +60 -0
- package/.docs/raw/docs/(docs)/copilots/model-context.mdx +9 -1
- package/.docs/raw/docs/(docs)/guides/attachments.mdx +65 -4
- package/.docs/raw/docs/(docs)/guides/interactables.mdx +354 -0
- package/.docs/raw/docs/(docs)/guides/message-timing.mdx +3 -3
- package/.docs/raw/docs/(docs)/guides/multi-agent.mdx +1 -0
- package/.docs/raw/docs/(docs)/guides/tool-ui.mdx +29 -0
- package/.docs/raw/docs/(docs)/guides/voice.mdx +333 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +128 -0
- package/.docs/raw/docs/(reference)/api-reference/primitives/message-part.mdx +23 -0
- package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +6 -0
- package/.docs/raw/docs/cloud/ai-sdk.mdx +81 -1
- package/.docs/raw/docs/ink/primitives.mdx +141 -0
- package/.docs/raw/docs/primitives/action-bar.mdx +351 -0
- package/.docs/raw/docs/primitives/assistant-modal.mdx +215 -0
- package/.docs/raw/docs/primitives/attachment.mdx +216 -0
- package/.docs/raw/docs/primitives/branch-picker.mdx +221 -0
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +311 -0
- package/.docs/raw/docs/primitives/composer.mdx +526 -0
- package/.docs/raw/docs/primitives/error.mdx +141 -0
- package/.docs/raw/docs/primitives/index.mdx +98 -0
- package/.docs/raw/docs/primitives/message.mdx +524 -0
- package/.docs/raw/docs/primitives/selection-toolbar.mdx +165 -0
- package/.docs/raw/docs/primitives/suggestion.mdx +242 -0
- package/.docs/raw/docs/primitives/thread-list.mdx +404 -0
- package/.docs/raw/docs/primitives/thread.mdx +482 -0
- package/.docs/raw/docs/runtimes/a2a/index.mdx +4 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +2 -2
- package/.docs/raw/docs/runtimes/assistant-transport.mdx +6 -2
- package/.docs/raw/docs/ui/context-display.mdx +2 -2
- package/.docs/raw/docs/ui/mention.mdx +168 -0
- package/.docs/raw/docs/ui/model-selector.mdx +1 -1
- package/.docs/raw/docs/ui/voice.mdx +172 -0
- package/package.json +3 -4
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
# Example: with-elevenlabs-conversational
|
|
2
|
+
|
|
3
|
+
## app/api/chat/route.ts
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import { openai } from "@ai-sdk/openai";
|
|
7
|
+
import { streamText, UIMessage, convertToModelMessages, stepCountIs } from "ai";
|
|
8
|
+
|
|
9
|
+
export const maxDuration = 30;
|
|
10
|
+
|
|
11
|
+
export async function POST(req: Request) {
|
|
12
|
+
const { messages }: { messages: UIMessage[] } = await req.json();
|
|
13
|
+
|
|
14
|
+
const result = streamText({
|
|
15
|
+
model: openai("gpt-4o"),
|
|
16
|
+
messages: await convertToModelMessages(messages),
|
|
17
|
+
stopWhen: stepCountIs(10),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return result.toUIMessageStreamResponse();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## app/globals.css
|
|
26
|
+
|
|
27
|
+
```css
|
|
28
|
+
@import "tailwindcss";
|
|
29
|
+
@import "tw-animate-css";
|
|
30
|
+
|
|
31
|
+
@source "../../../packages/ui/src";
|
|
32
|
+
|
|
33
|
+
@custom-variant dark (&:is(.dark *));
|
|
34
|
+
|
|
35
|
+
@theme inline {
|
|
36
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
37
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
38
|
+
--radius-lg: var(--radius);
|
|
39
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
40
|
+
--color-background: var(--background);
|
|
41
|
+
--color-foreground: var(--foreground);
|
|
42
|
+
--color-card: var(--card);
|
|
43
|
+
--color-card-foreground: var(--card-foreground);
|
|
44
|
+
--color-popover: var(--popover);
|
|
45
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
46
|
+
--color-primary: var(--primary);
|
|
47
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
48
|
+
--color-secondary: var(--secondary);
|
|
49
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
50
|
+
--color-muted: var(--muted);
|
|
51
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
52
|
+
--color-accent: var(--accent);
|
|
53
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
54
|
+
--color-destructive: var(--destructive);
|
|
55
|
+
--color-border: var(--border);
|
|
56
|
+
--color-input: var(--input);
|
|
57
|
+
--color-ring: var(--ring);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:root {
|
|
61
|
+
--radius: 0.625rem;
|
|
62
|
+
--background: oklch(1 0 0);
|
|
63
|
+
--foreground: oklch(0.141 0.005 285.823);
|
|
64
|
+
--primary: oklch(0.21 0.006 285.885);
|
|
65
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
66
|
+
--secondary: oklch(0.967 0.001 286.375);
|
|
67
|
+
--secondary-foreground: oklch(0.21 0.006 285.885);
|
|
68
|
+
--muted: oklch(0.967 0.001 286.375);
|
|
69
|
+
--muted-foreground: oklch(0.552 0.016 285.938);
|
|
70
|
+
--accent: oklch(0.967 0.001 286.375);
|
|
71
|
+
--accent-foreground: oklch(0.21 0.006 285.885);
|
|
72
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
73
|
+
--border: oklch(0.92 0.004 286.32);
|
|
74
|
+
--input: oklch(0.92 0.004 286.32);
|
|
75
|
+
--ring: oklch(0.705 0.015 286.067);
|
|
76
|
+
--card: oklch(1 0 0);
|
|
77
|
+
--card-foreground: oklch(0.141 0.005 285.823);
|
|
78
|
+
--popover: oklch(1 0 0);
|
|
79
|
+
--popover-foreground: oklch(0.141 0.005 285.823);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@layer base {
|
|
83
|
+
* {
|
|
84
|
+
@apply border-border outline-ring/50;
|
|
85
|
+
}
|
|
86
|
+
body {
|
|
87
|
+
@apply bg-background text-foreground;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## app/layout.tsx
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import type { Metadata } from "next";
|
|
97
|
+
import "./globals.css";
|
|
98
|
+
|
|
99
|
+
export const metadata: Metadata = {
|
|
100
|
+
title: "ElevenLabs Conversational AI Example",
|
|
101
|
+
description:
|
|
102
|
+
"Example using @assistant-ui/react with ElevenLabs Conversational AI for realtime voice",
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export default function RootLayout({
|
|
106
|
+
children,
|
|
107
|
+
}: Readonly<{
|
|
108
|
+
children: React.ReactNode;
|
|
109
|
+
}>) {
|
|
110
|
+
return (
|
|
111
|
+
<html lang="en">
|
|
112
|
+
<body className="h-dvh">{children}</body>
|
|
113
|
+
</html>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## app/page.tsx
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
"use client";
|
|
123
|
+
|
|
124
|
+
import { AssistantRuntimeProvider } from "@assistant-ui/react";
|
|
125
|
+
import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
|
|
126
|
+
import { ElevenLabsVoiceAdapter } from "@/lib/elevenlabs-voice-adapter";
|
|
127
|
+
import { VoiceThread } from "./voice-thread";
|
|
128
|
+
|
|
129
|
+
export default function Home() {
|
|
130
|
+
const runtime = useChatRuntime({
|
|
131
|
+
adapters: {
|
|
132
|
+
voice: new ElevenLabsVoiceAdapter({
|
|
133
|
+
agentId: process.env.NEXT_PUBLIC_ELEVENLABS_AGENT_ID ?? "",
|
|
134
|
+
}),
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
140
|
+
<VoiceThread />
|
|
141
|
+
</AssistantRuntimeProvider>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## app/voice-thread.tsx
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
"use client";
|
|
151
|
+
|
|
152
|
+
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
|
|
153
|
+
import {
|
|
154
|
+
VoiceOrb,
|
|
155
|
+
VoiceConnectButton,
|
|
156
|
+
VoiceMuteButton,
|
|
157
|
+
VoiceDisconnectButton,
|
|
158
|
+
deriveVoiceOrbState,
|
|
159
|
+
} from "@/components/assistant-ui/voice";
|
|
160
|
+
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
|
161
|
+
import {
|
|
162
|
+
AuiIf,
|
|
163
|
+
MessagePrimitive,
|
|
164
|
+
ThreadPrimitive,
|
|
165
|
+
useAuiState,
|
|
166
|
+
useVoiceState,
|
|
167
|
+
useVoiceVolume,
|
|
168
|
+
} from "@assistant-ui/react";
|
|
169
|
+
import { ArrowDownIcon } from "lucide-react";
|
|
170
|
+
import type { FC } from "react";
|
|
171
|
+
|
|
172
|
+
export const VoiceThread: FC = () => {
|
|
173
|
+
return (
|
|
174
|
+
<ThreadPrimitive.Root
|
|
175
|
+
className="aui-root aui-thread-root flex h-full flex-col bg-background"
|
|
176
|
+
style={{ ["--thread-max-width" as string]: "44rem" }}
|
|
177
|
+
>
|
|
178
|
+
<ThreadPrimitive.Viewport className="aui-thread-viewport relative flex flex-1 flex-col overflow-y-scroll scroll-smooth px-4 pt-4">
|
|
179
|
+
<AuiIf condition={(s) => s.thread.isEmpty}>
|
|
180
|
+
<VoiceWelcome />
|
|
181
|
+
</AuiIf>
|
|
182
|
+
|
|
183
|
+
<ThreadPrimitive.Messages>
|
|
184
|
+
{() => <ThreadMessage />}
|
|
185
|
+
</ThreadPrimitive.Messages>
|
|
186
|
+
|
|
187
|
+
<ThreadPrimitive.ViewportFooter className="sticky bottom-0 mx-auto mt-auto flex w-full max-w-(--thread-max-width) flex-col items-center bg-background pt-4 pb-6">
|
|
188
|
+
<ThreadScrollToBottom />
|
|
189
|
+
<VoiceControlCenter />
|
|
190
|
+
</ThreadPrimitive.ViewportFooter>
|
|
191
|
+
</ThreadPrimitive.Viewport>
|
|
192
|
+
</ThreadPrimitive.Root>
|
|
193
|
+
);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const VoiceWelcome: FC = () => {
|
|
197
|
+
return (
|
|
198
|
+
<div className="aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col items-center justify-center gap-2">
|
|
199
|
+
<p className="fade-in slide-in-from-bottom-1 animate-in fill-mode-both font-semibold text-2xl duration-200">
|
|
200
|
+
Voice Conversation
|
|
201
|
+
</p>
|
|
202
|
+
<p className="fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-muted-foreground delay-75 duration-200">
|
|
203
|
+
Tap connect to start speaking
|
|
204
|
+
</p>
|
|
205
|
+
</div>
|
|
206
|
+
);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const ThreadScrollToBottom: FC = () => {
|
|
210
|
+
return (
|
|
211
|
+
<ThreadPrimitive.ScrollToBottom asChild>
|
|
212
|
+
<TooltipIconButton
|
|
213
|
+
tooltip="Scroll to bottom"
|
|
214
|
+
variant="outline"
|
|
215
|
+
className="absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible dark:border-border dark:bg-background dark:hover:bg-accent"
|
|
216
|
+
>
|
|
217
|
+
<ArrowDownIcon />
|
|
218
|
+
</TooltipIconButton>
|
|
219
|
+
</ThreadPrimitive.ScrollToBottom>
|
|
220
|
+
);
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const VoiceControlCenter: FC = () => {
|
|
224
|
+
return (
|
|
225
|
+
<div className="aui-voice-control-center flex flex-col items-center gap-4">
|
|
226
|
+
<VoiceOrb variant="blue" className="size-20" />
|
|
227
|
+
<VoiceWaveform />
|
|
228
|
+
|
|
229
|
+
<div className="flex items-center gap-3">
|
|
230
|
+
<AuiIf
|
|
231
|
+
condition={(s) =>
|
|
232
|
+
s.thread.voice == null || s.thread.voice.status.type === "ended"
|
|
233
|
+
}
|
|
234
|
+
>
|
|
235
|
+
<VoiceConnectButton />
|
|
236
|
+
</AuiIf>
|
|
237
|
+
|
|
238
|
+
<AuiIf condition={(s) => s.thread.voice?.status.type === "starting"}>
|
|
239
|
+
<span className="text-muted-foreground text-sm">Connecting...</span>
|
|
240
|
+
</AuiIf>
|
|
241
|
+
|
|
242
|
+
<AuiIf condition={(s) => s.thread.voice?.status.type === "running"}>
|
|
243
|
+
<VoiceMuteButton />
|
|
244
|
+
<VoiceDisconnectButton />
|
|
245
|
+
</AuiIf>
|
|
246
|
+
</div>
|
|
247
|
+
</div>
|
|
248
|
+
);
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const BAR_WEIGHTS = [0.4, 0.65, 0.85, 1.0, 0.9, 0.75, 0.5];
|
|
252
|
+
|
|
253
|
+
const VoiceWaveform: FC = () => {
|
|
254
|
+
const voiceState = useVoiceState();
|
|
255
|
+
const state = deriveVoiceOrbState(voiceState);
|
|
256
|
+
const volume = useVoiceVolume();
|
|
257
|
+
const isActive = state === "listening" || state === "speaking";
|
|
258
|
+
|
|
259
|
+
return (
|
|
260
|
+
<div className="aui-voice-waveform flex h-8 items-center justify-center gap-[3px]">
|
|
261
|
+
{BAR_WEIGHTS.map((weight, i) => {
|
|
262
|
+
const scale = isActive ? 0.1 + volume * 0.9 * weight : 0.1;
|
|
263
|
+
return (
|
|
264
|
+
<span
|
|
265
|
+
key={i}
|
|
266
|
+
className="aui-voice-waveform-bar h-full w-[3px] origin-center rounded-full bg-foreground/50 transition-transform duration-100"
|
|
267
|
+
style={{ transform: `scaleY(${scale})` }}
|
|
268
|
+
/>
|
|
269
|
+
);
|
|
270
|
+
})}
|
|
271
|
+
</div>
|
|
272
|
+
);
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const ThreadMessage: FC = () => {
|
|
276
|
+
const role = useAuiState((s) => s.message.role);
|
|
277
|
+
if (role === "user") return <UserMessage />;
|
|
278
|
+
return <AssistantMessage />;
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const AssistantMessage: FC = () => {
|
|
282
|
+
return (
|
|
283
|
+
<MessagePrimitive.Root
|
|
284
|
+
className="aui-assistant-message-root fade-in slide-in-from-bottom-1 relative mx-auto w-full max-w-(--thread-max-width) animate-in py-3 duration-150"
|
|
285
|
+
data-role="assistant"
|
|
286
|
+
>
|
|
287
|
+
<div className="aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed">
|
|
288
|
+
<MessagePrimitive.Parts>
|
|
289
|
+
{({ part }) => {
|
|
290
|
+
if (part.type === "text") return <MarkdownText />;
|
|
291
|
+
return null;
|
|
292
|
+
}}
|
|
293
|
+
</MessagePrimitive.Parts>
|
|
294
|
+
</div>
|
|
295
|
+
</MessagePrimitive.Root>
|
|
296
|
+
);
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const UserMessage: FC = () => {
|
|
300
|
+
return (
|
|
301
|
+
<MessagePrimitive.Root
|
|
302
|
+
className="aui-user-message-root fade-in slide-in-from-bottom-1 mx-auto flex w-full max-w-(--thread-max-width) animate-in justify-end px-2 py-3 duration-150"
|
|
303
|
+
data-role="user"
|
|
304
|
+
>
|
|
305
|
+
<div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
|
|
306
|
+
<MessagePrimitive.Parts />
|
|
307
|
+
</div>
|
|
308
|
+
</MessagePrimitive.Root>
|
|
309
|
+
);
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## components.json
|
|
315
|
+
|
|
316
|
+
```json
|
|
317
|
+
{
|
|
318
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
319
|
+
"style": "new-york",
|
|
320
|
+
"rsc": true,
|
|
321
|
+
"tsx": true,
|
|
322
|
+
"tailwind": {
|
|
323
|
+
"config": "",
|
|
324
|
+
"css": "app/globals.css",
|
|
325
|
+
"baseColor": "zinc",
|
|
326
|
+
"cssVariables": true,
|
|
327
|
+
"prefix": ""
|
|
328
|
+
},
|
|
329
|
+
"aliases": {
|
|
330
|
+
"components": "@/components",
|
|
331
|
+
"utils": "@/lib/utils",
|
|
332
|
+
"ui": "@/components/ui",
|
|
333
|
+
"lib": "@/lib",
|
|
334
|
+
"hooks": "@/hooks"
|
|
335
|
+
},
|
|
336
|
+
"iconLibrary": "lucide",
|
|
337
|
+
"registries": {
|
|
338
|
+
"@assistant-ui": "https://r.assistant-ui.com/{name}.json"
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## lib/elevenlabs-voice-adapter.ts
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
import type { RealtimeVoiceAdapter } from "@assistant-ui/react";
|
|
348
|
+
import { createVoiceSession } from "@assistant-ui/react";
|
|
349
|
+
import { VoiceConversation } from "@elevenlabs/client";
|
|
350
|
+
|
|
351
|
+
export type ElevenLabsVoiceAdapterOptions = {
|
|
352
|
+
agentId: string;
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
export class ElevenLabsVoiceAdapter implements RealtimeVoiceAdapter {
|
|
356
|
+
private _agentId: string;
|
|
357
|
+
|
|
358
|
+
constructor(options: ElevenLabsVoiceAdapterOptions) {
|
|
359
|
+
this._agentId = options.agentId;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
connect(options: {
|
|
363
|
+
abortSignal?: AbortSignal;
|
|
364
|
+
}): RealtimeVoiceAdapter.Session {
|
|
365
|
+
return createVoiceSession(options, async (session) => {
|
|
366
|
+
let volumeInterval: ReturnType<typeof setInterval> | null = null;
|
|
367
|
+
|
|
368
|
+
const conversation = await VoiceConversation.startSession({
|
|
369
|
+
agentId: this._agentId,
|
|
370
|
+
onConnect: () => {
|
|
371
|
+
session.setStatus({ type: "running" });
|
|
372
|
+
volumeInterval = setInterval(() => {
|
|
373
|
+
if (session.isDisposed()) return;
|
|
374
|
+
const vol = Math.max(
|
|
375
|
+
conversation.getInputVolume(),
|
|
376
|
+
conversation.getOutputVolume(),
|
|
377
|
+
);
|
|
378
|
+
session.emitVolume(vol);
|
|
379
|
+
}, 50);
|
|
380
|
+
},
|
|
381
|
+
onDisconnect: () => {
|
|
382
|
+
if (volumeInterval) clearInterval(volumeInterval);
|
|
383
|
+
session.end("finished");
|
|
384
|
+
},
|
|
385
|
+
onError: (message) => {
|
|
386
|
+
if (volumeInterval) clearInterval(volumeInterval);
|
|
387
|
+
session.end("error", new Error(message));
|
|
388
|
+
},
|
|
389
|
+
onModeChange: ({ mode }) => {
|
|
390
|
+
session.emitMode(mode === "speaking" ? "speaking" : "listening");
|
|
391
|
+
},
|
|
392
|
+
onMessage: (message) => {
|
|
393
|
+
session.emitTranscript({
|
|
394
|
+
role: message.role === "user" ? "user" : "assistant",
|
|
395
|
+
text: message.message,
|
|
396
|
+
isFinal: true,
|
|
397
|
+
});
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
return {
|
|
402
|
+
disconnect: () => {
|
|
403
|
+
if (volumeInterval) clearInterval(volumeInterval);
|
|
404
|
+
conversation.endSession();
|
|
405
|
+
},
|
|
406
|
+
mute: () => conversation.setMicMuted(true),
|
|
407
|
+
unmute: () => conversation.setMicMuted(false),
|
|
408
|
+
};
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## next.config.js
|
|
416
|
+
|
|
417
|
+
```javascript
|
|
418
|
+
/** @type {import('next').NextConfig} */
|
|
419
|
+
const nextConfig = {
|
|
420
|
+
transpilePackages: ["@assistant-ui/react", "@assistant-ui/react-ai-sdk"],
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
export default nextConfig;
|
|
424
|
+
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## package.json
|
|
428
|
+
|
|
429
|
+
```json
|
|
430
|
+
{
|
|
431
|
+
"name": "with-elevenlabs-conversational",
|
|
432
|
+
"private": true,
|
|
433
|
+
"version": "0.0.0",
|
|
434
|
+
"type": "module",
|
|
435
|
+
"dependencies": {
|
|
436
|
+
"@ai-sdk/openai": "^3.0.50",
|
|
437
|
+
"@ai-sdk/react": "^3.0.146",
|
|
438
|
+
"@assistant-ui/react": "workspace:^",
|
|
439
|
+
"@assistant-ui/react-ai-sdk": "workspace:*",
|
|
440
|
+
"@assistant-ui/react-markdown": "workspace:^",
|
|
441
|
+
"@assistant-ui/ui": "workspace:*",
|
|
442
|
+
"@elevenlabs/client": "^1.1.0",
|
|
443
|
+
"@tailwindcss/postcss": "^4.2.2",
|
|
444
|
+
"ai": "^6.0.144",
|
|
445
|
+
"class-variance-authority": "^0.7.1",
|
|
446
|
+
"clsx": "^2.1.1",
|
|
447
|
+
"lucide-react": "^1.7.0",
|
|
448
|
+
"motion": "^12.38.0",
|
|
449
|
+
"next": "^16.2.2",
|
|
450
|
+
"postcss": "^8.5.8",
|
|
451
|
+
"react": "^19.2.4",
|
|
452
|
+
"react-dom": "^19.2.4",
|
|
453
|
+
"tailwind-merge": "^3.5.0",
|
|
454
|
+
"tailwindcss": "^4.2.2",
|
|
455
|
+
"zod": "^4.3.6"
|
|
456
|
+
},
|
|
457
|
+
"devDependencies": {
|
|
458
|
+
"@assistant-ui/x-buildutils": "workspace:*",
|
|
459
|
+
"@types/node": "^25.5.0",
|
|
460
|
+
"@types/react": "^19.2.14",
|
|
461
|
+
"@types/react-dom": "^19.2.3",
|
|
462
|
+
"tw-animate-css": "^1.4.0",
|
|
463
|
+
"typescript": "5.9.3"
|
|
464
|
+
},
|
|
465
|
+
"scripts": {
|
|
466
|
+
"dev": "next dev",
|
|
467
|
+
"build": "next build",
|
|
468
|
+
"start": "next start"
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
## tsconfig.json
|
|
475
|
+
|
|
476
|
+
```json
|
|
477
|
+
{
|
|
478
|
+
"extends": "@assistant-ui/x-buildutils/ts/base",
|
|
479
|
+
"compilerOptions": {
|
|
480
|
+
"target": "ES6",
|
|
481
|
+
"module": "ESNext",
|
|
482
|
+
"incremental": true,
|
|
483
|
+
"plugins": [
|
|
484
|
+
{
|
|
485
|
+
"name": "next"
|
|
486
|
+
}
|
|
487
|
+
],
|
|
488
|
+
"allowJs": true,
|
|
489
|
+
"strictNullChecks": true,
|
|
490
|
+
"jsx": "preserve",
|
|
491
|
+
"paths": {
|
|
492
|
+
"@/*": ["./*"],
|
|
493
|
+
"@/components/assistant-ui/*": [
|
|
494
|
+
"../../packages/ui/src/components/assistant-ui/*"
|
|
495
|
+
],
|
|
496
|
+
"@/components/ui/*": ["../../packages/ui/src/components/ui/*"],
|
|
497
|
+
"@/lib/utils": ["../../packages/ui/src/lib/utils"],
|
|
498
|
+
"@assistant-ui/ui/*": ["../../packages/ui/src/*"],
|
|
499
|
+
"@assistant-ui/*": ["../../packages/*/src"],
|
|
500
|
+
"@assistant-ui/react/*": ["../../packages/react/src/*"],
|
|
501
|
+
"@assistant-ui/tap/*": ["../../packages/tap/src/*"],
|
|
502
|
+
"assistant-stream": ["../../packages/assistant-stream/src"],
|
|
503
|
+
"assistant-stream/*": ["../../packages/assistant-stream/src/*"]
|
|
504
|
+
}
|
|
505
|
+
},
|
|
506
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
507
|
+
"exclude": ["node_modules"]
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
```
|
|
511
|
+
|
|
@@ -562,25 +562,25 @@ export default nextConfig;
|
|
|
562
562
|
"version": "0.0.0",
|
|
563
563
|
"type": "module",
|
|
564
564
|
"dependencies": {
|
|
565
|
-
"@ai-sdk/openai": "^3.0.
|
|
566
|
-
"@ai-sdk/react": "^3.0.
|
|
565
|
+
"@ai-sdk/openai": "^3.0.50",
|
|
566
|
+
"@ai-sdk/react": "^3.0.146",
|
|
567
567
|
"@assistant-ui/react": "workspace:^",
|
|
568
568
|
"@assistant-ui/react-ai-sdk": "workspace:*",
|
|
569
569
|
"@assistant-ui/react-markdown": "workspace:^",
|
|
570
570
|
"@assistant-ui/ui": "workspace:*",
|
|
571
|
-
"@elevenlabs/client": "^
|
|
572
|
-
"@tailwindcss/postcss": "^4.2.
|
|
573
|
-
"ai": "^6.0.
|
|
571
|
+
"@elevenlabs/client": "^1.1.0",
|
|
572
|
+
"@tailwindcss/postcss": "^4.2.2",
|
|
573
|
+
"ai": "^6.0.144",
|
|
574
574
|
"class-variance-authority": "^0.7.1",
|
|
575
575
|
"clsx": "^2.1.1",
|
|
576
|
-
"lucide-react": "^
|
|
577
|
-
"motion": "^12.
|
|
578
|
-
"next": "^16.
|
|
576
|
+
"lucide-react": "^1.7.0",
|
|
577
|
+
"motion": "^12.38.0",
|
|
578
|
+
"next": "^16.2.2",
|
|
579
579
|
"postcss": "^8.5.8",
|
|
580
580
|
"react": "^19.2.4",
|
|
581
581
|
"react-dom": "^19.2.4",
|
|
582
582
|
"tailwind-merge": "^3.5.0",
|
|
583
|
-
"tailwindcss": "^4.2.
|
|
583
|
+
"tailwindcss": "^4.2.2",
|
|
584
584
|
"zod": "^4.3.6"
|
|
585
585
|
},
|
|
586
586
|
"devDependencies": {
|
|
@@ -589,7 +589,7 @@ export default nextConfig;
|
|
|
589
589
|
"@types/react": "^19.2.14",
|
|
590
590
|
"@types/react-dom": "^19.2.3",
|
|
591
591
|
"tw-animate-css": "^1.4.0",
|
|
592
|
-
"typescript": "
|
|
592
|
+
"typescript": "5.9.3"
|
|
593
593
|
},
|
|
594
594
|
"scripts": {
|
|
595
595
|
"dev": "next dev",
|
|
@@ -1940,29 +1940,29 @@ module.exports = config;
|
|
|
1940
1940
|
"export:web": "expo export --platform web && node scripts/flatten-assets.mjs"
|
|
1941
1941
|
},
|
|
1942
1942
|
"dependencies": {
|
|
1943
|
-
"@ai-sdk/openai": "^3.0.
|
|
1944
|
-
"@ai-sdk/react": "^3.0.
|
|
1943
|
+
"@ai-sdk/openai": "^3.0.50",
|
|
1944
|
+
"@ai-sdk/react": "^3.0.146",
|
|
1945
1945
|
"@assistant-ui/react-ai-sdk": "workspace:*",
|
|
1946
1946
|
"@assistant-ui/react-native": "workspace:*",
|
|
1947
1947
|
"@expo/vector-icons": "^15.1.1",
|
|
1948
|
-
"@react-navigation/drawer": "^7.
|
|
1949
|
-
"@react-navigation/native": "^7.
|
|
1950
|
-
"ai": "^6.0.
|
|
1951
|
-
"expo": "~55.0.
|
|
1952
|
-
"expo-constants": "~55.0.
|
|
1953
|
-
"expo-font": "~55.0.
|
|
1954
|
-
"expo-image-picker": "~55.0.
|
|
1955
|
-
"expo-linking": "~55.0.
|
|
1956
|
-
"expo-router": "~55.0.
|
|
1957
|
-
"expo-server": "~55.0.
|
|
1958
|
-
"expo-splash-screen": "~55.0.
|
|
1959
|
-
"expo-status-bar": "~55.0.
|
|
1960
|
-
"expo-system-ui": "~55.0.
|
|
1948
|
+
"@react-navigation/drawer": "^7.9.8",
|
|
1949
|
+
"@react-navigation/native": "^7.2.2",
|
|
1950
|
+
"ai": "^6.0.144",
|
|
1951
|
+
"expo": "~55.0.11",
|
|
1952
|
+
"expo-constants": "~55.0.11",
|
|
1953
|
+
"expo-font": "~55.0.6",
|
|
1954
|
+
"expo-image-picker": "~55.0.16",
|
|
1955
|
+
"expo-linking": "~55.0.11",
|
|
1956
|
+
"expo-router": "~55.0.10",
|
|
1957
|
+
"expo-server": "~55.0.7",
|
|
1958
|
+
"expo-splash-screen": "~55.0.15",
|
|
1959
|
+
"expo-status-bar": "~55.0.5",
|
|
1960
|
+
"expo-system-ui": "~55.0.13",
|
|
1961
1961
|
"react": "19.2.0",
|
|
1962
1962
|
"react-dom": "19.2.0",
|
|
1963
1963
|
"react-native": "0.83.2",
|
|
1964
|
-
"react-native-gesture-handler": "~2.
|
|
1965
|
-
"react-native-reanimated": "~4.
|
|
1964
|
+
"react-native-gesture-handler": "~2.31.0",
|
|
1965
|
+
"react-native-reanimated": "~4.3.0",
|
|
1966
1966
|
"react-native-safe-area-context": "~5.7.0",
|
|
1967
1967
|
"react-native-screens": "~4.24.0",
|
|
1968
1968
|
"react-native-web": "~0.21.2",
|
|
@@ -1971,7 +1971,7 @@ module.exports = config;
|
|
|
1971
1971
|
},
|
|
1972
1972
|
"devDependencies": {
|
|
1973
1973
|
"@types/react": "~19.2.14",
|
|
1974
|
-
"typescript": "
|
|
1974
|
+
"typescript": "5.9.3"
|
|
1975
1975
|
},
|
|
1976
1976
|
"private": true
|
|
1977
1977
|
}
|
|
@@ -319,22 +319,22 @@ export default nextConfig;
|
|
|
319
319
|
"@assistant-ui/ui": "workspace:*",
|
|
320
320
|
"class-variance-authority": "^0.7.1",
|
|
321
321
|
"clsx": "^2.1.1",
|
|
322
|
-
"lucide-react": "^
|
|
323
|
-
"next": "^16.
|
|
322
|
+
"lucide-react": "^1.7.0",
|
|
323
|
+
"next": "^16.2.2",
|
|
324
324
|
"react": "^19.2.4",
|
|
325
325
|
"react-dom": "^19.2.4",
|
|
326
326
|
"tailwind-merge": "^3.5.0"
|
|
327
327
|
},
|
|
328
328
|
"devDependencies": {
|
|
329
329
|
"@assistant-ui/x-buildutils": "workspace:*",
|
|
330
|
-
"@tailwindcss/postcss": "^4.2.
|
|
330
|
+
"@tailwindcss/postcss": "^4.2.2",
|
|
331
331
|
"@types/node": "^25.5.0",
|
|
332
332
|
"@types/react": "^19.2.14",
|
|
333
333
|
"@types/react-dom": "^19.2.3",
|
|
334
334
|
"postcss": "^8.5.8",
|
|
335
|
-
"tailwindcss": "^4.2.
|
|
335
|
+
"tailwindcss": "^4.2.2",
|
|
336
336
|
"tw-animate-css": "^1.4.0",
|
|
337
|
-
"typescript": "
|
|
337
|
+
"typescript": "5.9.3"
|
|
338
338
|
}
|
|
339
339
|
}
|
|
340
340
|
|