@assistant-ui/mcp-docs-server 0.1.1

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.
Files changed (109) hide show
  1. package/.docs/organized/code-examples/local-ollama.md +1135 -0
  2. package/.docs/organized/code-examples/search-agent-for-e-commerce.md +1721 -0
  3. package/.docs/organized/code-examples/with-ai-sdk.md +1081 -0
  4. package/.docs/organized/code-examples/with-cloud.md +1164 -0
  5. package/.docs/organized/code-examples/with-external-store.md +1064 -0
  6. package/.docs/organized/code-examples/with-ffmpeg.md +1305 -0
  7. package/.docs/organized/code-examples/with-langgraph.md +1819 -0
  8. package/.docs/organized/code-examples/with-openai-assistants.md +1175 -0
  9. package/.docs/organized/code-examples/with-react-hook-form.md +1727 -0
  10. package/.docs/organized/code-examples/with-vercel-ai-rsc.md +1157 -0
  11. package/.docs/raw/blog/2024-07-29-hello/index.mdx +65 -0
  12. package/.docs/raw/blog/2024-09-11/index.mdx +10 -0
  13. package/.docs/raw/blog/2024-12-15/index.mdx +10 -0
  14. package/.docs/raw/blog/2025-01-31-changelog/index.mdx +129 -0
  15. package/.docs/raw/docs/about-assistantui.mdx +44 -0
  16. package/.docs/raw/docs/api-reference/context-providers/AssistantRuntimeProvider.mdx +30 -0
  17. package/.docs/raw/docs/api-reference/context-providers/TextContentPartProvider.mdx +26 -0
  18. package/.docs/raw/docs/api-reference/integrations/react-hook-form.mdx +103 -0
  19. package/.docs/raw/docs/api-reference/integrations/vercel-ai-sdk.mdx +145 -0
  20. package/.docs/raw/docs/api-reference/overview.mdx +583 -0
  21. package/.docs/raw/docs/api-reference/primitives/ActionBar.mdx +264 -0
  22. package/.docs/raw/docs/api-reference/primitives/AssistantModal.mdx +129 -0
  23. package/.docs/raw/docs/api-reference/primitives/Attachment.mdx +96 -0
  24. package/.docs/raw/docs/api-reference/primitives/BranchPicker.mdx +87 -0
  25. package/.docs/raw/docs/api-reference/primitives/Composer.mdx +204 -0
  26. package/.docs/raw/docs/api-reference/primitives/ContentPart.mdx +173 -0
  27. package/.docs/raw/docs/api-reference/primitives/Error.mdx +70 -0
  28. package/.docs/raw/docs/api-reference/primitives/Message.mdx +181 -0
  29. package/.docs/raw/docs/api-reference/primitives/Thread.mdx +197 -0
  30. package/.docs/raw/docs/api-reference/primitives/composition.mdx +21 -0
  31. package/.docs/raw/docs/api-reference/runtimes/AssistantRuntime.mdx +33 -0
  32. package/.docs/raw/docs/api-reference/runtimes/AttachmentRuntime.mdx +46 -0
  33. package/.docs/raw/docs/api-reference/runtimes/ComposerRuntime.mdx +69 -0
  34. package/.docs/raw/docs/api-reference/runtimes/ContentPartRuntime.mdx +22 -0
  35. package/.docs/raw/docs/api-reference/runtimes/MessageRuntime.mdx +49 -0
  36. package/.docs/raw/docs/api-reference/runtimes/ThreadListItemRuntime.mdx +32 -0
  37. package/.docs/raw/docs/api-reference/runtimes/ThreadListRuntime.mdx +31 -0
  38. package/.docs/raw/docs/api-reference/runtimes/ThreadRuntime.mdx +48 -0
  39. package/.docs/raw/docs/architecture.mdx +92 -0
  40. package/.docs/raw/docs/cloud/authorization.mdx +152 -0
  41. package/.docs/raw/docs/cloud/overview.mdx +55 -0
  42. package/.docs/raw/docs/cloud/persistence/ai-sdk.mdx +54 -0
  43. package/.docs/raw/docs/cloud/persistence/langgraph.mdx +123 -0
  44. package/.docs/raw/docs/concepts/architecture.mdx +19 -0
  45. package/.docs/raw/docs/concepts/runtime-layer.mdx +163 -0
  46. package/.docs/raw/docs/concepts/why.mdx +9 -0
  47. package/.docs/raw/docs/copilots/make-assistant-readable.mdx +71 -0
  48. package/.docs/raw/docs/copilots/make-assistant-tool-ui.mdx +76 -0
  49. package/.docs/raw/docs/copilots/make-assistant-tool.mdx +117 -0
  50. package/.docs/raw/docs/copilots/model-context.mdx +135 -0
  51. package/.docs/raw/docs/copilots/motivation.mdx +191 -0
  52. package/.docs/raw/docs/copilots/use-assistant-instructions.mdx +62 -0
  53. package/.docs/raw/docs/getting-started.mdx +1133 -0
  54. package/.docs/raw/docs/guides/Attachments.mdx +640 -0
  55. package/.docs/raw/docs/guides/Branching.mdx +59 -0
  56. package/.docs/raw/docs/guides/Editing.mdx +56 -0
  57. package/.docs/raw/docs/guides/Speech.mdx +43 -0
  58. package/.docs/raw/docs/guides/ToolUI.mdx +663 -0
  59. package/.docs/raw/docs/guides/Tools.mdx +496 -0
  60. package/.docs/raw/docs/index.mdx +7 -0
  61. package/.docs/raw/docs/legacy/styled/AssistantModal.mdx +85 -0
  62. package/.docs/raw/docs/legacy/styled/Decomposition.mdx +633 -0
  63. package/.docs/raw/docs/legacy/styled/Markdown.mdx +86 -0
  64. package/.docs/raw/docs/legacy/styled/Scrollbar.mdx +71 -0
  65. package/.docs/raw/docs/legacy/styled/Thread.mdx +84 -0
  66. package/.docs/raw/docs/legacy/styled/ThreadWidth.mdx +21 -0
  67. package/.docs/raw/docs/mcp-docs-server.mdx +324 -0
  68. package/.docs/raw/docs/migrations/deprecation-policy.mdx +41 -0
  69. package/.docs/raw/docs/migrations/v0-7.mdx +188 -0
  70. package/.docs/raw/docs/migrations/v0-8.mdx +160 -0
  71. package/.docs/raw/docs/migrations/v0-9.mdx +75 -0
  72. package/.docs/raw/docs/react-compatibility.mdx +208 -0
  73. package/.docs/raw/docs/runtimes/ai-sdk/rsc.mdx +226 -0
  74. package/.docs/raw/docs/runtimes/ai-sdk/use-assistant-hook.mdx +195 -0
  75. package/.docs/raw/docs/runtimes/ai-sdk/use-chat-hook.mdx +138 -0
  76. package/.docs/raw/docs/runtimes/ai-sdk/use-chat.mdx +136 -0
  77. package/.docs/raw/docs/runtimes/custom/external-store.mdx +1624 -0
  78. package/.docs/raw/docs/runtimes/custom/local.mdx +1185 -0
  79. package/.docs/raw/docs/runtimes/helicone.mdx +60 -0
  80. package/.docs/raw/docs/runtimes/langgraph/index.mdx +320 -0
  81. package/.docs/raw/docs/runtimes/langgraph/tutorial/index.mdx +11 -0
  82. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +28 -0
  83. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +120 -0
  84. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +336 -0
  85. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +385 -0
  86. package/.docs/raw/docs/runtimes/langserve.mdx +126 -0
  87. package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +218 -0
  88. package/.docs/raw/docs/runtimes/mastra/overview.mdx +17 -0
  89. package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +196 -0
  90. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +222 -0
  91. package/.docs/raw/docs/ui/AssistantModal.mdx +46 -0
  92. package/.docs/raw/docs/ui/AssistantSidebar.mdx +42 -0
  93. package/.docs/raw/docs/ui/Attachment.mdx +82 -0
  94. package/.docs/raw/docs/ui/Markdown.mdx +72 -0
  95. package/.docs/raw/docs/ui/Mermaid.mdx +79 -0
  96. package/.docs/raw/docs/ui/Scrollbar.mdx +59 -0
  97. package/.docs/raw/docs/ui/SyntaxHighlighting.mdx +253 -0
  98. package/.docs/raw/docs/ui/Thread.mdx +47 -0
  99. package/.docs/raw/docs/ui/ThreadList.mdx +49 -0
  100. package/.docs/raw/docs/ui/ToolFallback.mdx +64 -0
  101. package/.docs/raw/docs/ui/primitives/Thread.mdx +197 -0
  102. package/LICENSE +21 -0
  103. package/README.md +128 -0
  104. package/dist/chunk-C7O7EFKU.js +38 -0
  105. package/dist/chunk-CZCDQ3YH.js +420 -0
  106. package/dist/index.js +1 -0
  107. package/dist/prepare-docs/prepare.js +199 -0
  108. package/dist/stdio.js +8 -0
  109. package/package.json +43 -0
@@ -0,0 +1,1133 @@
1
+ ---
2
+ title: Getting Started
3
+ ---
4
+
5
+ import { Step, Steps } from "fumadocs-ui/components/steps";
6
+ import { Tab, Tabs } from "fumadocs-ui/components/tabs";
7
+ import { Callout } from "fumadocs-ui/components/callout";
8
+ import { Card, Cards } from "fumadocs-ui/components/card";
9
+
10
+ ## Start with a new project
11
+
12
+ ![animated gif showing the steps to create a new project](../../../../.github/assets/assistant-ui-starter.gif)
13
+
14
+ <Steps>
15
+ <Step>
16
+
17
+ ### Initialize assistant-ui
18
+ **Create a new project:**
19
+
20
+ ```sh
21
+ # Create a new project with the default template
22
+ npx assistant-ui@latest create
23
+
24
+ # Or start with a template:
25
+ # LangGraph
26
+ npx assistant-ui@latest create -t langgraph
27
+
28
+ # MCP support
29
+ npx assistant-ui@latest create -t mcp
30
+ ```
31
+
32
+ **Add assistant-ui to an existing React project:**
33
+
34
+ ```sh
35
+ # Add assistant-ui to an existing React project
36
+ npx assistant-ui@latest init
37
+ ```
38
+
39
+ </Step>
40
+ <Step>
41
+
42
+ ### Add API key
43
+
44
+ Add a new `.env` file to your project with your OpenAI API key:
45
+
46
+ ```
47
+ OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
48
+
49
+ # chat history -- sign up for free on https://cloud.assistant-ui.com
50
+ # NEXT_PUBLIC_ASSISTANT_BASE_URL="https://..."
51
+ ```
52
+
53
+ </Step>
54
+ <Step>
55
+
56
+ ### Start the app
57
+
58
+ ```sh
59
+ npm run dev
60
+ ```
61
+
62
+ </Step>
63
+ </Steps>
64
+
65
+ ## Manual installation
66
+
67
+ <Callout>
68
+ We recommend `npx assistant-ui init` to setup existing projects.
69
+ </Callout>
70
+
71
+ <Steps>
72
+ <Step>
73
+
74
+ ### Add assistant-ui
75
+
76
+ <Tabs items={["With Tailwind (Recommended)", "Without Tailwind"]}>
77
+ <Tab>
78
+
79
+ ```sh npm2yarn
80
+ npx assistant-ui add thread thread-list
81
+ ```
82
+
83
+ </Tab>
84
+ <Tab>
85
+ <Steps>
86
+ <Step>
87
+
88
+ Add the following packages:
89
+
90
+ ```sh
91
+ npm install \
92
+ @assistant-ui/react \
93
+ @assistant-ui/react-markdown \
94
+ @assistant-ui/styles \
95
+ @radix-ui/react-tooltip \
96
+ @radix-ui/react-slot \
97
+ lucide-react \
98
+ remark-gfm \
99
+ class-variance-authority \
100
+ clsx
101
+ ```
102
+
103
+ </Step>
104
+
105
+ <Step>
106
+
107
+ Copy the following components into your project:
108
+
109
+ ```tsx title="components/ui/button.tsx"
110
+ import * as React from "react";
111
+ import { Slot } from "@radix-ui/react-slot";
112
+ import { cva, type VariantProps } from "class-variance-authority";
113
+
114
+ import { cn } from "@/lib/utils";
115
+
116
+ const buttonVariants = cva("aui-button", {
117
+ variants: {
118
+ variant: {
119
+ default: "aui-button-primary",
120
+ outline: "aui-button-outline",
121
+ ghost: "aui-button-ghost",
122
+ },
123
+ size: {
124
+ default: "aui-button-medium",
125
+ icon: "aui-button-icon",
126
+ },
127
+ },
128
+ defaultVariants: {
129
+ variant: "default",
130
+ size: "default",
131
+ },
132
+ });
133
+
134
+ function Button({
135
+ className,
136
+ variant,
137
+ size,
138
+ asChild = false,
139
+ ...props
140
+ }: React.ComponentProps<"button"> &
141
+ VariantProps<typeof buttonVariants> & {
142
+ asChild?: boolean;
143
+ }) {
144
+ const Comp = asChild ? Slot : "button";
145
+
146
+ return (
147
+ <Comp
148
+ data-slot="button"
149
+ className={cn(buttonVariants({ variant, size, className }))}
150
+ {...props}
151
+ />
152
+ );
153
+ }
154
+
155
+ export { Button, buttonVariants };
156
+ ```
157
+
158
+ ```tsx title="components/ui/tooltip.tsx"
159
+ "use client";
160
+
161
+ import * as React from "react";
162
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
163
+
164
+ import { cn } from "@/lib/utils";
165
+
166
+ const TooltipProvider = TooltipPrimitive.Provider;
167
+
168
+ const Tooltip = TooltipPrimitive.Root;
169
+
170
+ const TooltipTrigger = TooltipPrimitive.Trigger;
171
+
172
+ const TooltipContent = React.forwardRef<
173
+ React.ElementRef<typeof TooltipPrimitive.Content>,
174
+ React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
175
+ >(({ className, sideOffset = 4, ...props }, ref) => (
176
+ <TooltipPrimitive.Portal>
177
+ <TooltipPrimitive.Content
178
+ ref={ref}
179
+ sideOffset={sideOffset}
180
+ className={cn("aui-tooltip-content", className)}
181
+ {...props}
182
+ />
183
+ </TooltipPrimitive.Portal>
184
+ ));
185
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
186
+
187
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
188
+ ```
189
+
190
+ ```tsx title="components/assistant-ui/thread.tsx"
191
+ import {
192
+ ActionBarPrimitive,
193
+ BranchPickerPrimitive,
194
+ ComposerPrimitive,
195
+ MessagePrimitive,
196
+ ThreadPrimitive,
197
+ } from "@assistant-ui/react";
198
+ import type { FC } from "react";
199
+ import {
200
+ ArrowDownIcon,
201
+ CheckIcon,
202
+ ChevronLeftIcon,
203
+ ChevronRightIcon,
204
+ CopyIcon,
205
+ PencilIcon,
206
+ RefreshCwIcon,
207
+ SendHorizontalIcon,
208
+ } from "lucide-react";
209
+ import { cn } from "@/lib/utils";
210
+
211
+ import { Button } from "@/components/ui/button";
212
+ import { MarkdownText } from "@/components/assistant-ui/markdown-text";
213
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
214
+
215
+ export const Thread: FC = () => {
216
+ return (
217
+ <ThreadPrimitive.Root
218
+ className="aui-root aui-thread-root"
219
+ style={{
220
+ ["--thread-max-width" as string]: "42rem",
221
+ }}
222
+ >
223
+ <ThreadPrimitive.Viewport className="aui-thread-viewport">
224
+ <ThreadWelcome />
225
+
226
+ <ThreadPrimitive.Messages
227
+ components={{
228
+ UserMessage: UserMessage,
229
+ EditComposer: EditComposer,
230
+ AssistantMessage: AssistantMessage,
231
+ }}
232
+ />
233
+
234
+ <ThreadPrimitive.If empty={false}>
235
+ <div className="aui-thread-viewport-spacer" />
236
+ </ThreadPrimitive.If>
237
+
238
+ <div className="aui-thread-viewport-footer">
239
+ <ThreadScrollToBottom />
240
+ <Composer />
241
+ </div>
242
+ </ThreadPrimitive.Viewport>
243
+ </ThreadPrimitive.Root>
244
+ );
245
+ };
246
+
247
+ const ThreadScrollToBottom: FC = () => {
248
+ return (
249
+ <ThreadPrimitive.ScrollToBottom asChild>
250
+ <TooltipIconButton
251
+ tooltip="Scroll to bottom"
252
+ variant="outline"
253
+ className="aui-thread-scroll-to-bottom"
254
+ >
255
+ <ArrowDownIcon />
256
+ </TooltipIconButton>
257
+ </ThreadPrimitive.ScrollToBottom>
258
+ );
259
+ };
260
+
261
+ const ThreadWelcome: FC = () => {
262
+ return (
263
+ <ThreadPrimitive.Empty>
264
+ <div className="aui-thread-welcome-root">
265
+ <div className="aui-thread-welcome-center">
266
+ <p className="aui-thread-welcome-message">
267
+ How can I help you today?
268
+ </p>
269
+ </div>
270
+ <ThreadWelcomeSuggestions />
271
+ </div>
272
+ </ThreadPrimitive.Empty>
273
+ );
274
+ };
275
+
276
+ const ThreadWelcomeSuggestions: FC = () => {
277
+ return (
278
+ <div className="aui-thread-welcome-suggestions">
279
+ <ThreadPrimitive.Suggestion
280
+ className="aui-thread-welcome-suggestion"
281
+ prompt="What is the weather in Tokyo?"
282
+ method="replace"
283
+ autoSend
284
+ >
285
+ <span className="aui-thread-welcome-suggestion-text">
286
+ What is the weather in Tokyo?
287
+ </span>
288
+ </ThreadPrimitive.Suggestion>
289
+ <ThreadPrimitive.Suggestion
290
+ className="aui-thread-welcome-suggestion"
291
+ prompt="What is assistant-ui?"
292
+ method="replace"
293
+ autoSend
294
+ >
295
+ <span className="aui-thread-welcome-suggestion-text">
296
+ What is assistant-ui?
297
+ </span>
298
+ </ThreadPrimitive.Suggestion>
299
+ </div>
300
+ );
301
+ };
302
+
303
+ const Composer: FC = () => {
304
+ return (
305
+ <ComposerPrimitive.Root className="aui-composer-root">
306
+ <ComposerPrimitive.Input
307
+ rows={1}
308
+ autoFocus
309
+ placeholder="Write a message..."
310
+ className="aui-composer-input"
311
+ />
312
+ <ComposerAction />
313
+ </ComposerPrimitive.Root>
314
+ );
315
+ };
316
+
317
+ const ComposerAction: FC = () => {
318
+ return (
319
+ <>
320
+ <ThreadPrimitive.If running={false}>
321
+ <ComposerPrimitive.Send asChild>
322
+ <TooltipIconButton
323
+ tooltip="Send"
324
+ variant="default"
325
+ className="aui-composer-send"
326
+ >
327
+ <SendHorizontalIcon />
328
+ </TooltipIconButton>
329
+ </ComposerPrimitive.Send>
330
+ </ThreadPrimitive.If>
331
+ <ThreadPrimitive.If running>
332
+ <ComposerPrimitive.Cancel asChild>
333
+ <TooltipIconButton
334
+ tooltip="Cancel"
335
+ variant="default"
336
+ className="aui-composer-cancel"
337
+ >
338
+ <CircleStopIcon />
339
+ </TooltipIconButton>
340
+ </ComposerPrimitive.Cancel>
341
+ </ThreadPrimitive.If>
342
+ </>
343
+ );
344
+ };
345
+
346
+ const UserMessage: FC = () => {
347
+ return (
348
+ <MessagePrimitive.Root className="aui-user-message-root">
349
+ <UserActionBar />
350
+
351
+ <div className="aui-user-message-content">
352
+ <MessagePrimitive.Content />
353
+ </div>
354
+
355
+ <BranchPicker className="aui-user-branch-picker" />
356
+ </MessagePrimitive.Root>
357
+ );
358
+ };
359
+
360
+ const UserActionBar: FC = () => {
361
+ return (
362
+ <ActionBarPrimitive.Root
363
+ hideWhenRunning
364
+ autohide="not-last"
365
+ className="aui-user-action-bar-root"
366
+ >
367
+ <ActionBarPrimitive.Edit asChild>
368
+ <TooltipIconButton tooltip="Edit">
369
+ <PencilIcon />
370
+ </TooltipIconButton>
371
+ </ActionBarPrimitive.Edit>
372
+ </ActionBarPrimitive.Root>
373
+ );
374
+ };
375
+
376
+ const EditComposer: FC = () => {
377
+ return (
378
+ <ComposerPrimitive.Root className="aui-edit-composer-root">
379
+ <ComposerPrimitive.Input className="aui-edit-composer-input" />
380
+
381
+ <div className="aui-edit-composer-footer">
382
+ <ComposerPrimitive.Cancel asChild>
383
+ <Button variant="ghost">Cancel</Button>
384
+ </ComposerPrimitive.Cancel>
385
+ <ComposerPrimitive.Send asChild>
386
+ <Button>Send</Button>
387
+ </ComposerPrimitive.Send>
388
+ </div>
389
+ </ComposerPrimitive.Root>
390
+ );
391
+ };
392
+
393
+ const AssistantMessage: FC = () => {
394
+ return (
395
+ <MessagePrimitive.Root className="aui-assistant-message-root">
396
+ <div className="aui-assistant-message-content">
397
+ <MessagePrimitive.Content components={{ Text: MarkdownText }} />
398
+ </div>
399
+
400
+ <AssistantActionBar />
401
+
402
+ <BranchPicker className="aui-assistant-branch-picker" />
403
+ </MessagePrimitive.Root>
404
+ );
405
+ };
406
+
407
+ const AssistantActionBar: FC = () => {
408
+ return (
409
+ <ActionBarPrimitive.Root
410
+ hideWhenRunning
411
+ autohide="not-last"
412
+ autohideFloat="single-branch"
413
+ className="aui-assistant-action-bar-root"
414
+ >
415
+ <ActionBarPrimitive.Copy asChild>
416
+ <TooltipIconButton tooltip="Copy">
417
+ <MessagePrimitive.If copied>
418
+ <CheckIcon />
419
+ </MessagePrimitive.If>
420
+ <MessagePrimitive.If copied={false}>
421
+ <CopyIcon />
422
+ </MessagePrimitive.If>
423
+ </TooltipIconButton>
424
+ </ActionBarPrimitive.Copy>
425
+ <ActionBarPrimitive.Reload asChild>
426
+ <TooltipIconButton tooltip="Refresh">
427
+ <RefreshCwIcon />
428
+ </TooltipIconButton>
429
+ </ActionBarPrimitive.Reload>
430
+ </ActionBarPrimitive.Root>
431
+ );
432
+ };
433
+
434
+ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
435
+ className,
436
+ ...rest
437
+ }) => {
438
+ return (
439
+ <BranchPickerPrimitive.Root
440
+ hideWhenSingleBranch
441
+ className={cn("aui-branch-picker-root", className)}
442
+ {...rest}
443
+ >
444
+ <BranchPickerPrimitive.Previous asChild>
445
+ <TooltipIconButton tooltip="Previous">
446
+ <ChevronLeftIcon />
447
+ </TooltipIconButton>
448
+ </BranchPickerPrimitive.Previous>
449
+ <span className="aui-branch-picker-state">
450
+ <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
451
+ </span>
452
+ <BranchPickerPrimitive.Next asChild>
453
+ <TooltipIconButton tooltip="Next">
454
+ <ChevronRightIcon />
455
+ </TooltipIconButton>
456
+ </BranchPickerPrimitive.Next>
457
+ </BranchPickerPrimitive.Root>
458
+ );
459
+ };
460
+
461
+ const CircleStopIcon = () => {
462
+ return (
463
+ <svg
464
+ xmlns="http://www.w3.org/2000/svg"
465
+ viewBox="0 0 16 16"
466
+ fill="currentColor"
467
+ width="16"
468
+ height="16"
469
+ >
470
+ <rect width="10" height="10" x="3" y="3" rx="2" />
471
+ </svg>
472
+ );
473
+ };
474
+ ```
475
+
476
+ ```tsx title="components/assistant-ui/thread-list.tsx"
477
+ import type { FC } from "react";
478
+ import {
479
+ ThreadListItemPrimitive,
480
+ ThreadListPrimitive,
481
+ } from "@assistant-ui/react";
482
+ import { ArchiveIcon, PlusIcon } from "lucide-react";
483
+
484
+ import { Button } from "@/components/ui/button";
485
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
486
+
487
+ export const ThreadList: FC = () => {
488
+ return (
489
+ <ThreadListPrimitive.Root className="aui-root aui-thread-list-root">
490
+ <ThreadListNew />
491
+ <ThreadListItems />
492
+ </ThreadListPrimitive.Root>
493
+ );
494
+ };
495
+
496
+ const ThreadListNew: FC = () => {
497
+ return (
498
+ <ThreadListPrimitive.New asChild>
499
+ <Button className="aui-thread-list-new" variant="ghost">
500
+ <PlusIcon />
501
+ New Thread
502
+ </Button>
503
+ </ThreadListPrimitive.New>
504
+ );
505
+ };
506
+
507
+ const ThreadListItems: FC = () => {
508
+ return <ThreadListPrimitive.Items components={{ ThreadListItem }} />;
509
+ };
510
+
511
+ const ThreadListItem: FC = () => {
512
+ return (
513
+ <ThreadListItemPrimitive.Root className="aui-thread-list-item">
514
+ <ThreadListItemPrimitive.Trigger className="aui-thread-list-item-trigger">
515
+ <ThreadListItemTitle />
516
+ </ThreadListItemPrimitive.Trigger>
517
+ <ThreadListItemArchive />
518
+ </ThreadListItemPrimitive.Root>
519
+ );
520
+ };
521
+
522
+ const ThreadListItemTitle: FC = () => {
523
+ return (
524
+ <p className="aui-thread-list-item-title">
525
+ <ThreadListItemPrimitive.Title fallback="New Chat" />
526
+ </p>
527
+ );
528
+ };
529
+
530
+ const ThreadListItemArchive: FC = () => {
531
+ return (
532
+ <ThreadListItemPrimitive.Archive asChild>
533
+ <TooltipIconButton
534
+ className="aui-thread-list-item-archive"
535
+ variant="ghost"
536
+ tooltip="Archive thread"
537
+ >
538
+ <ArchiveIcon />
539
+ </TooltipIconButton>
540
+ </ThreadListItemPrimitive.Archive>
541
+ );
542
+ };
543
+ ```
544
+
545
+ ```tsx title="components/assistant-ui/markdown-text.tsx"
546
+ "use client";
547
+
548
+ import "@assistant-ui/react-markdown/styles/dot.css";
549
+
550
+ import {
551
+ CodeHeaderProps,
552
+ MarkdownTextPrimitive,
553
+ unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
554
+ useIsMarkdownCodeBlock,
555
+ } from "@assistant-ui/react-markdown";
556
+ import remarkGfm from "remark-gfm";
557
+ import { FC, memo, useState } from "react";
558
+ import { CheckIcon, CopyIcon } from "lucide-react";
559
+
560
+ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
561
+ import { cn } from "@/lib/utils";
562
+
563
+ const MarkdownTextImpl = () => {
564
+ return (
565
+ <MarkdownTextPrimitive
566
+ remarkPlugins={[remarkGfm]}
567
+ className="aui-md"
568
+ components={defaultComponents}
569
+ />
570
+ );
571
+ };
572
+
573
+ export const MarkdownText = memo(MarkdownTextImpl);
574
+
575
+ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
576
+ const { isCopied, copyToClipboard } = useCopyToClipboard();
577
+ const onCopy = () => {
578
+ if (!code || isCopied) return;
579
+ copyToClipboard(code);
580
+ };
581
+
582
+ return (
583
+ <div className="aui-code-header-root">
584
+ <span className="aui-code-header-language">{language}</span>
585
+ <TooltipIconButton tooltip="Copy" onClick={onCopy}>
586
+ {!isCopied && <CopyIcon />}
587
+ {isCopied && <CheckIcon />}
588
+ </TooltipIconButton>
589
+ </div>
590
+ );
591
+ };
592
+
593
+ const useCopyToClipboard = ({
594
+ copiedDuration = 3000,
595
+ }: {
596
+ copiedDuration?: number;
597
+ } = {}) => {
598
+ const [isCopied, setIsCopied] = useState<boolean>(false);
599
+
600
+ const copyToClipboard = (value: string) => {
601
+ if (!value) return;
602
+
603
+ navigator.clipboard.writeText(value).then(() => {
604
+ setIsCopied(true);
605
+ setTimeout(() => setIsCopied(false), copiedDuration);
606
+ });
607
+ };
608
+
609
+ return { isCopied, copyToClipboard };
610
+ };
611
+
612
+ const defaultComponents = memoizeMarkdownComponents({
613
+ h1: ({ className, ...props }) => (
614
+ <h1 className={cn("aui-md-h1", className)} {...props} />
615
+ ),
616
+ h2: ({ className, ...props }) => (
617
+ <h2 className={cn("aui-md-h2", className)} {...props} />
618
+ ),
619
+ h3: ({ className, ...props }) => (
620
+ <h3 className={cn("aui-md-h3", className)} {...props} />
621
+ ),
622
+ h4: ({ className, ...props }) => (
623
+ <h4 className={cn("aui-md-h4", className)} {...props} />
624
+ ),
625
+ h5: ({ className, ...props }) => (
626
+ <h5 className={cn("aui-md-h5", className)} {...props} />
627
+ ),
628
+ h6: ({ className, ...props }) => (
629
+ <h6 className={cn("aui-md-h6", className)} {...props} />
630
+ ),
631
+ p: ({ className, ...props }) => (
632
+ <p className={cn("aui-md-p", className)} {...props} />
633
+ ),
634
+ a: ({ className, ...props }) => (
635
+ <a className={cn("aui-md-a", className)} {...props} />
636
+ ),
637
+ blockquote: ({ className, ...props }) => (
638
+ <blockquote className={cn("aui-md-blockquote", className)} {...props} />
639
+ ),
640
+ ul: ({ className, ...props }) => (
641
+ <ul className={cn("aui-md-ul", className)} {...props} />
642
+ ),
643
+ ol: ({ className, ...props }) => (
644
+ <ol className={cn("aui-md-ol", className)} {...props} />
645
+ ),
646
+ hr: ({ className, ...props }) => (
647
+ <hr className={cn("aui-md-hr", className)} {...props} />
648
+ ),
649
+ table: ({ className, ...props }) => (
650
+ <table className={cn("aui-md-table", className)} {...props} />
651
+ ),
652
+ th: ({ className, ...props }) => (
653
+ <th className={cn("aui-md-th", className)} {...props} />
654
+ ),
655
+ td: ({ className, ...props }) => (
656
+ <td className={cn("aui-md-td", className)} {...props} />
657
+ ),
658
+ tr: ({ className, ...props }) => (
659
+ <tr className={cn("aui-md-tr", className)} {...props} />
660
+ ),
661
+ sup: ({ className, ...props }) => (
662
+ <sup className={cn("aui-md-sup", className)} {...props} />
663
+ ),
664
+ pre: ({ className, ...props }) => (
665
+ <pre className={cn("aui-md-pre", className)} {...props} />
666
+ ),
667
+ code: function Code({ className, ...props }) {
668
+ const isCodeBlock = useIsMarkdownCodeBlock();
669
+ return (
670
+ <code
671
+ className={cn(!isCodeBlock && "aui-md-inline-code", className)}
672
+ {...props}
673
+ />
674
+ );
675
+ },
676
+ CodeHeader,
677
+ });
678
+ ```
679
+
680
+ ```tsx title="components/assistant-ui/tooltip-icon-button.tsx"
681
+ "use client";
682
+
683
+ import { ComponentPropsWithoutRef, forwardRef } from "react";
684
+
685
+ import {
686
+ Tooltip,
687
+ TooltipContent,
688
+ TooltipProvider,
689
+ TooltipTrigger,
690
+ } from "@/components/ui/tooltip";
691
+ import { Button } from "@/components/ui/button";
692
+ import { cn } from "@/lib/utils";
693
+
694
+ export type TooltipIconButtonProps = ComponentPropsWithoutRef<typeof Button> & {
695
+ tooltip: string;
696
+ side?: "top" | "bottom" | "left" | "right";
697
+ };
698
+
699
+ export const TooltipIconButton = forwardRef<
700
+ HTMLButtonElement,
701
+ TooltipIconButtonProps
702
+ >(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
703
+ return (
704
+ <TooltipProvider>
705
+ <Tooltip>
706
+ <TooltipTrigger asChild>
707
+ <Button
708
+ variant="ghost"
709
+ size="icon"
710
+ {...rest}
711
+ className={cn("", className)}
712
+ ref={ref}
713
+ >
714
+ {children}
715
+ <span className="aui-sr-only">{tooltip}</span>
716
+ </Button>
717
+ </TooltipTrigger>
718
+ <TooltipContent side={side}>{tooltip}</TooltipContent>
719
+ </Tooltip>
720
+ </TooltipProvider>
721
+ );
722
+ });
723
+
724
+ TooltipIconButton.displayName = "TooltipIconButton";
725
+ ```
726
+
727
+ ```ts title="lib/utils.ts"
728
+ import { type ClassValue, clsx } from "clsx";
729
+
730
+ export function cn(...inputs: ClassValue[]) {
731
+ return clsx(inputs);
732
+ }
733
+ ```
734
+
735
+ </Step>
736
+
737
+ <Step>
738
+ The components above reference CSS class names like `aui-thread-root`, `aui-composer-input`, etc. These are normally replaced by our CLI with Tailwind class names, but in this case you'll use our pre-compiled CSS files without a need for Tailwind:
739
+
740
+ ```ts
741
+ import "@assistant-ui/styles/index.css";
742
+ import "@assistant-ui/styles/markdown.css";
743
+ // import "@assistant-ui/styles/modal.css"; // for future reference, only if you use our modal component
744
+ ```
745
+
746
+ </Step>
747
+ </Steps>
748
+
749
+ </Tab>
750
+ </Tabs>
751
+
752
+ </Step>
753
+ <Step>
754
+
755
+ ### Setup Backend Endpoint
756
+
757
+ Install provider SDK:
758
+
759
+ <Tabs id="provider" items={["OpenAI", "Anthropic", "Azure", "AWS", "Gemini", "GCP", "Groq", "Fireworks", "Cohere", "Ollama", "Chrome AI"]}>
760
+
761
+ ```sh title="Terminal" tab="OpenAI"
762
+ npm install ai @assistant-ui/react-ai-sdk @ai-sdk/openai
763
+ ```
764
+
765
+ ```sh title="Terminal" tab="Anthropic"
766
+ npm install ai @assistant-ui/react-ai-sdk @ai-sdk/anthropic
767
+ ```
768
+
769
+ ```sh title="Terminal" tab="Azure"
770
+ npm install ai @assistant-ui/react-ai-sdk @ai-sdk/azure
771
+ ```
772
+
773
+ ```sh title="Terminal" tab="AWS"
774
+ npm install ai @assistant-ui/react-ai-sdk @ai-sdk/amazon-bedrock
775
+ ```
776
+
777
+ ```sh title="Terminal" tab="Gemini"
778
+ npm install ai @assistant-ui/react-ai-sdk @ai-sdk/google
779
+ ```
780
+
781
+ ```sh title="Terminal" tab="GCP"
782
+ npm install ai @assistant-ui/react-ai-sdk @ai-sdk/google-vertex
783
+ ```
784
+
785
+ ```sh title="Terminal" tab="Groq"
786
+ npm install ai @assistant-ui/react-ai-sdk @ai-sdk/openai
787
+ ```
788
+
789
+ ```sh title="Terminal" tab="Fireworks"
790
+ npm install ai @assistant-ui/react-ai-sdk @ai-sdk/openai
791
+ ```
792
+
793
+ ```sh title="Terminal" tab="Cohere"
794
+ npm install ai @assistant-ui/react-ai-sdk @ai-sdk/cohere
795
+ ```
796
+
797
+ ```sh title="Terminal" tab="Ollama"
798
+ npm install ai @assistant-ui/react-ai-sdk ollama-ai-provider
799
+ ```
800
+
801
+ ```sh title="Terminal" tab="Chrome AI"
802
+ npm install ai @assistant-ui/react-ai-sdk chrome-ai
803
+ ```
804
+
805
+ </Tabs>
806
+
807
+ Add an API endpoint:
808
+
809
+ <Tabs id="provider" items={["OpenAI", "Anthropic", "Azure", "AWS", "Gemini", "GCP", "Groq", "Fireworks", "Cohere", "Ollama", "Chrome AI"]}>
810
+ ```ts title="/app/api/chat/route.ts" tab="OpenAI"
811
+ import { openai } from "@ai-sdk/openai";
812
+ import { streamText } from "ai";
813
+
814
+ export const maxDuration = 30;
815
+
816
+ export async function POST(req: Request) {
817
+ const { messages } = await req.json();
818
+ const result = streamText({
819
+ model: openai("gpt-4o-mini"),
820
+ messages,
821
+ });
822
+ return result.toDataStreamResponse();
823
+ }
824
+ ```
825
+
826
+ ```ts title="/app/api/chat/route.ts" tab="Anthropic"
827
+ import { anthropic } from "@ai-sdk/anthropic";
828
+ import { streamText } from "ai";
829
+
830
+ export const maxDuration = 30;
831
+
832
+ export async function POST(req: Request) {
833
+ const { messages } = await req.json();
834
+ const result = streamText({
835
+ model: anthropic("claude-3-5-sonnet-20240620"),
836
+ messages,
837
+ });
838
+ return result.toDataStreamResponse();
839
+ }
840
+ ```
841
+
842
+ ```ts title="/app/api/chat/route.ts" tab="Azure"
843
+ import { azure } from "@ai-sdk/azure";
844
+ import { streamText } from "ai";
845
+
846
+ export const maxDuration = 30;
847
+
848
+ export async function POST(req: Request) {
849
+ const { messages } = await req.json();
850
+ const result = streamText({
851
+ model: azure("your-deployment-name"),
852
+ messages,
853
+ });
854
+ return result.toDataStreamResponse();
855
+ }
856
+ ```
857
+
858
+ ```ts title="/app/api/chat/route.ts" tab="AWS"
859
+ import { bedrock } from "@ai-sdk/amazon-bedrock";
860
+ import { streamText } from "ai";
861
+
862
+ export const maxDuration = 30;
863
+
864
+ export async function POST(req: Request) {
865
+ const { messages } = await req.json();
866
+ const result = streamText({
867
+ model: bedrock("anthropic.claude-3-5-sonnet-20240620-v1:0"),
868
+ messages,
869
+ });
870
+ return result.toDataStreamResponse();
871
+ }
872
+ ```
873
+
874
+ ```ts title="/app/api/chat/route.ts" tab="Gemini"
875
+ import { google } from "@ai-sdk/google";
876
+ import { streamText } from "ai";
877
+
878
+ export const maxDuration = 30;
879
+
880
+ export async function POST(req: Request) {
881
+ const { messages } = await req.json();
882
+ const result = streamText({
883
+ model: google("gemini-2.0-flash"),
884
+ messages,
885
+ });
886
+ return result.toDataStreamResponse();
887
+ }
888
+ ```
889
+
890
+ ```ts title="/app/api/chat/route.ts" tab="GCP"
891
+ import { vertex } from "@ai-sdk/google-vertex";
892
+ import { streamText } from "ai";
893
+
894
+ export const maxDuration = 30;
895
+
896
+ export async function POST(req: Request) {
897
+ const { messages } = await req.json();
898
+ const result = streamText({
899
+ model: vertex("gemini-1.5-pro"),
900
+ messages,
901
+ });
902
+ return result.toDataStreamResponse();
903
+ }
904
+ ```
905
+
906
+ ```ts title="/app/api/chat/route.ts" tab="Groq"
907
+ import { createOpenAI } from "@ai-sdk/openai";
908
+ import { streamText } from "ai";
909
+
910
+ export const maxDuration = 30;
911
+
912
+ const groq = createOpenAI({
913
+ apiKey: process.env.GROQ_API_KEY ?? "",
914
+ baseURL: "https://api.groq.com/openai/v1",
915
+ });
916
+
917
+ export async function POST(req: Request) {
918
+ const { messages } = await req.json();
919
+ const result = streamText({
920
+ model: groq("llama3-70b-8192"),
921
+ messages,
922
+ });
923
+ return result.toDataStreamResponse();
924
+ }
925
+ ```
926
+
927
+ ```ts title="/app/api/chat/route.ts" tab="Fireworks"
928
+ import { createOpenAI } from "@ai-sdk/openai";
929
+ import { streamText } from "ai";
930
+
931
+ export const maxDuration = 30;
932
+
933
+ const fireworks = createOpenAI({
934
+ apiKey: process.env.FIREWORKS_API_KEY ?? "",
935
+ baseURL: "https://api.fireworks.ai/inference/v1",
936
+ });
937
+
938
+ export async function POST(req: Request) {
939
+ const { messages } = await req.json();
940
+ const result = streamText({
941
+ model: fireworks("accounts/fireworks/models/firefunction-v2"),
942
+ messages,
943
+ });
944
+ return result.toDataStreamResponse();
945
+ }
946
+ ```
947
+
948
+ ```ts title="/app/api/chat/route.ts" tab="Cohere"
949
+ import { cohere } from "@ai-sdk/cohere";
950
+ import { streamText } from "ai";
951
+
952
+ export const maxDuration = 30;
953
+
954
+ export async function POST(req: Request) {
955
+ const { messages } = await req.json();
956
+ const result = streamText({
957
+ model: cohere("command-r-plus"),
958
+ messages,
959
+ });
960
+ return result.toDataStreamResponse();
961
+ }
962
+ ```
963
+
964
+ ```ts title="/app/api/chat/route.ts" tab="Ollama"
965
+ import { ollama } from "ollama-ai-provider";
966
+ import { streamText } from "ai";
967
+
968
+ export const maxDuration = 30;
969
+
970
+ export async function POST(req: Request) {
971
+ const { messages } = await req.json();
972
+ const result = streamText({
973
+ model: ollama("llama3"),
974
+ messages,
975
+ });
976
+ return result.toDataStreamResponse();
977
+ }
978
+ ```
979
+
980
+ ```ts title="/app/api/chat/route.ts" tab="Chrome AI"
981
+ import { chromeai } from "chrome-ai";
982
+ import { streamText } from "ai";
983
+
984
+ export const maxDuration = 30;
985
+
986
+ export async function POST(req: Request) {
987
+ const { messages } = await req.json();
988
+ const result = streamText({
989
+ model: chromeai(),
990
+ messages,
991
+ });
992
+ return result.toDataStreamResponse();
993
+ }
994
+ ```
995
+
996
+ </Tabs>
997
+
998
+ Define environment variables:
999
+
1000
+ <Tabs id="provider" items={["OpenAI", "Anthropic", "Azure", "AWS", "Gemini", "GCP", "Groq", "Fireworks", "Cohere", "Ollama", "Chrome AI"]}>
1001
+
1002
+ ```sh title="/.env.local" tab="OpenAI"
1003
+ OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1004
+ ```
1005
+
1006
+ ```sh title="/.env.local" tab="Anthropic"
1007
+ ANTHROPIC_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1008
+ ```
1009
+
1010
+ ```sh title="/.env.local" tab="Azure"
1011
+ AZURE_RESOURCE_NAME="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1012
+ AZURE_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1013
+ ```
1014
+
1015
+ ```sh title="/.env.local" tab="AWS"
1016
+ AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1017
+ AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1018
+ AWS_REGION="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1019
+ ```
1020
+
1021
+ ```sh title="/.env.local" tab="Gemini"
1022
+ GOOGLE_GENERATIVE_AI_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1023
+ ```
1024
+
1025
+ ```sh title="/.env.local" tab="GCP"
1026
+ GOOGLE_VERTEX_PROJECT="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1027
+ GOOGLE_VERTEX_LOCATION="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1028
+ GOOGLE_APPLICATION_CREDENTIALS="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1029
+ ```
1030
+
1031
+ ```sh title="/.env.local" tab="Groq"
1032
+ GROQ_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1033
+ ```
1034
+
1035
+ ```sh title="/.env.local" tab="Fireworks"
1036
+ FIREWORKS_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1037
+ ```
1038
+
1039
+ ```sh title="/.env.local" tab="Cohere"
1040
+ COHERE_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
1041
+ ```
1042
+
1043
+ ```sh tab="Ollama"
1044
+ <none>
1045
+ ```
1046
+
1047
+ ```sh tab="Chrome AI"
1048
+ <none>
1049
+ ```
1050
+
1051
+ </Tabs>
1052
+
1053
+ If you aren't using Next.js, you can also deploy this endpoint to Cloudflare Workers, or any other serverless platform.
1054
+
1055
+ </Step>
1056
+
1057
+ <Step>
1058
+
1059
+ ### Use it in your app
1060
+
1061
+ <Tabs items={["Thread", "AssistantModal"]}>
1062
+
1063
+ ```tsx title="/app/page.tsx" tab="Thread"
1064
+ import { AssistantRuntimeProvider } from "@assistant-ui/react";
1065
+ import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
1066
+ import { ThreadList } from "@/components/assistant-ui/thread-list";
1067
+ import { Thread } from "@/components/assistant-ui/thread";
1068
+
1069
+ const MyApp = () => {
1070
+ const runtime = useChatRuntime({
1071
+ api: "/api/chat",
1072
+ });
1073
+
1074
+ return (
1075
+ <AssistantRuntimeProvider runtime={runtime}>
1076
+ <div className="grid h-dvh grid-cols-[200px_1fr] gap-x-2 px-4 py-4">
1077
+ <ThreadList />
1078
+ <Thread />
1079
+ </div>
1080
+ </AssistantRuntimeProvider>
1081
+ );
1082
+ };
1083
+ ```
1084
+
1085
+ ```tsx title="/app/page.tsx" tab="AssistantModal"
1086
+ // run `npx shadcn@latest add "https://r.assistant-ui.com/assistant-modal"`
1087
+
1088
+ import { AssistantRuntimeProvider } from "@assistant-ui/react";
1089
+ import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
1090
+ import { AssistantModal } from "@/components/assistant-ui/assistant-modal";
1091
+
1092
+ const MyApp = () => {
1093
+ const runtime = useChatRuntime({
1094
+ api: "/api/chat",
1095
+ });
1096
+
1097
+ return (
1098
+ <AssistantRuntimeProvider runtime={runtime}>
1099
+ <AssistantModal />
1100
+ </AssistantRuntimeProvider>
1101
+ );
1102
+ };
1103
+ ```
1104
+
1105
+ </Tabs>
1106
+
1107
+ </Step>
1108
+ </Steps>
1109
+
1110
+ ## What's Next?
1111
+
1112
+ <Cards>
1113
+ <Card
1114
+ title="Pick a Runtime"
1115
+ description="Choose the right runtime for your needs"
1116
+ href="/docs/runtimes/pick-a-runtime"
1117
+ />
1118
+ <Card
1119
+ title="Generative UI"
1120
+ description="Create rich UI components for tool executions"
1121
+ href="/docs/guides/ToolUI"
1122
+ />
1123
+ <Card
1124
+ title="Add Persistence"
1125
+ description="Save and restore chat conversations"
1126
+ href="/docs/cloud/overview"
1127
+ />
1128
+ <Card
1129
+ title="Examples"
1130
+ description="Explore full implementations and demos"
1131
+ href="https://github.com/assistant-ui/assistant-ui/tree/main/examples"
1132
+ />
1133
+ </Cards>