@assistant-ui/mcp-docs-server 0.1.3 → 0.1.5

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 (48) hide show
  1. package/.docs/organized/code-examples/local-ollama.md +13 -13
  2. package/.docs/organized/code-examples/search-agent-for-e-commerce.md +18 -18
  3. package/.docs/organized/code-examples/{with-vercel-ai-rsc.md → with-ai-sdk-v5.md} +225 -230
  4. package/.docs/organized/code-examples/with-ai-sdk.md +13 -13
  5. package/.docs/organized/code-examples/with-cloud.md +12 -12
  6. package/.docs/organized/code-examples/with-external-store.md +9 -9
  7. package/.docs/organized/code-examples/with-ffmpeg.md +19 -19
  8. package/.docs/organized/code-examples/with-langgraph.md +14 -14
  9. package/.docs/organized/code-examples/with-openai-assistants.md +12 -12
  10. package/.docs/organized/code-examples/with-parent-id-grouping.md +1374 -0
  11. package/.docs/organized/code-examples/with-react-hook-form.md +18 -18
  12. package/.docs/raw/docs/about-assistantui.mdx +9 -0
  13. package/.docs/raw/docs/api-reference/context-providers/{TextContentPartProvider.mdx → TextMessagePartProvider.mdx} +3 -3
  14. package/.docs/raw/docs/api-reference/integrations/react-hook-form.mdx +2 -2
  15. package/.docs/raw/docs/api-reference/overview.mdx +23 -23
  16. package/.docs/raw/docs/api-reference/primitives/Error.mdx +5 -3
  17. package/.docs/raw/docs/api-reference/primitives/Message.mdx +32 -0
  18. package/.docs/raw/docs/api-reference/primitives/{ContentPart.mdx → MessagePart.mdx} +41 -41
  19. package/.docs/raw/docs/api-reference/runtimes/MessagePartRuntime.mdx +22 -0
  20. package/.docs/raw/docs/api-reference/runtimes/ThreadListRuntime.mdx +1 -0
  21. package/.docs/raw/docs/api-reference/runtimes/ThreadRuntime.mdx +1 -0
  22. package/.docs/raw/docs/cloud/persistence/ai-sdk.mdx +89 -32
  23. package/.docs/raw/docs/cloud/persistence/langgraph.mdx +187 -32
  24. package/.docs/raw/docs/concepts/runtime-layer.mdx +7 -7
  25. package/.docs/raw/docs/copilots/make-assistant-tool-ui.mdx +22 -13
  26. package/.docs/raw/docs/copilots/make-assistant-tool.mdx +20 -14
  27. package/.docs/raw/docs/getting-started.mdx +11 -10
  28. package/.docs/raw/docs/guides/Attachments.mdx +24 -21
  29. package/.docs/raw/docs/guides/Latex.mdx +81 -0
  30. package/.docs/raw/docs/guides/ToolUI.mdx +13 -8
  31. package/.docs/raw/docs/migrations/v0-11.mdx +169 -0
  32. package/.docs/raw/docs/migrations/v0-7.mdx +8 -8
  33. package/.docs/raw/docs/migrations/v0-8.mdx +14 -14
  34. package/.docs/raw/docs/migrations/v0-9.mdx +3 -3
  35. package/.docs/raw/docs/runtimes/ai-sdk/rsc.mdx +2 -2
  36. package/.docs/raw/docs/runtimes/ai-sdk/use-assistant-hook.mdx +1 -1
  37. package/.docs/raw/docs/runtimes/ai-sdk/use-chat-hook.mdx +2 -2
  38. package/.docs/raw/docs/runtimes/ai-sdk/use-chat-v5.mdx +129 -0
  39. package/.docs/raw/docs/runtimes/ai-sdk/use-chat.mdx +3 -3
  40. package/.docs/raw/docs/runtimes/custom/external-store.mdx +5 -5
  41. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +2 -2
  42. package/.docs/raw/docs/ui/Attachment.mdx +5 -2
  43. package/.docs/raw/docs/ui/Markdown.mdx +2 -3
  44. package/.docs/raw/docs/ui/PartGrouping.mdx +540 -0
  45. package/.docs/raw/docs/ui/ToolFallback.mdx +2 -2
  46. package/.docs/raw/docs/ui/ToolGroup.mdx +96 -0
  47. package/package.json +8 -8
  48. package/.docs/raw/docs/api-reference/runtimes/ContentPartRuntime.mdx +0 -22
@@ -1,86 +1,45 @@
1
- # Example: with-vercel-ai-rsc
1
+ # Example: with-ai-sdk-v5
2
2
 
3
- ## app/actions.tsx
4
-
5
- ```tsx
6
- "use server";
3
+ ## app/api/chat/route.ts
7
4
 
5
+ ```typescript
8
6
  import { openai } from "@ai-sdk/openai";
9
- import { createAI, getMutableAIState, streamUI } from "ai/rsc";
10
- import type { ReactNode } from "react";
7
+ import {
8
+ streamText,
9
+ UIMessage,
10
+ convertToModelMessages,
11
+ tool,
12
+ stepCountIs,
13
+ } from "ai";
11
14
  import { z } from "zod";
12
15
 
13
- export interface ServerMessage {
14
- role: "user" | "assistant";
15
- content: string;
16
- }
16
+ // Allow streaming responses up to 30 seconds
17
+ export const maxDuration = 30;
17
18
 
18
- export interface ClientMessage {
19
- role: "user" | "assistant";
20
- display: ReactNode;
21
- }
19
+ export async function POST(req: Request) {
20
+ const { messages }: { messages: UIMessage[] } = await req.json();
22
21
 
23
- export async function continueConversation(
24
- input: string,
25
- ): Promise<ClientMessage> {
26
- "use server";
27
-
28
- const history = getMutableAIState();
29
-
30
- const result = await streamUI({
31
- model: openai("gpt-3.5-turbo"),
32
- messages: [...history.get(), { role: "user", content: input }],
33
- text: ({ content, done }) => {
34
- if (done) {
35
- history.done((messages: ServerMessage[]) => [
36
- ...messages,
37
- { role: "assistant", content },
38
- ]);
39
- }
40
-
41
- return <div>{content}</div>;
42
- },
22
+ const result = streamText({
23
+ model: openai("gpt-4o"),
24
+ messages: convertToModelMessages(messages),
25
+ stopWhen: stepCountIs(10),
43
26
  tools: {
44
- showStockInformation: {
45
- description:
46
- "Get stock information for symbol for the last numOfMonths months",
47
- parameters: z.object({
48
- symbol: z
49
- .string()
50
- .describe("The stock symbol to get information for"),
51
- numOfMonths: z
52
- .number()
53
- .describe("The number of months to get historical information for"),
27
+ get_current_weather: tool({
28
+ name: "",
29
+ description: "Get the current weather",
30
+ inputSchema: z.object({
31
+ city: z.string(),
54
32
  }),
55
- generate: async ({ symbol }) => {
56
- history.done((messages: ServerMessage[]) => [
57
- ...messages,
58
- {
59
- role: "assistant",
60
- content: `Showing stock information for ${symbol}`,
61
- },
62
- ]);
63
-
64
- return <p className="font-bold">Test</p>;
33
+ execute: async ({ city }) => {
34
+ return `The weather in ${city} is sunny`;
65
35
  },
66
- },
36
+ }),
67
37
  },
68
38
  });
69
39
 
70
- return {
71
- role: "assistant",
72
- display: result.value,
73
- };
40
+ return result.toUIMessageStreamResponse();
74
41
  }
75
42
 
76
- export const AI = createAI<ServerMessage[], ClientMessage[]>({
77
- actions: {
78
- continueConversation,
79
- },
80
- initialAIState: [],
81
- initialUIState: [],
82
- });
83
-
84
43
  ```
85
44
 
86
45
  ## app/globals.css
@@ -92,43 +51,41 @@ export const AI = createAI<ServerMessage[], ClientMessage[]>({
92
51
  @custom-variant dark (&:is(.dark *));
93
52
 
94
53
  @theme inline {
95
- --color-background: var(--background);
96
- --color-foreground: var(--foreground);
97
- --font-sans: var(--font-geist-sans);
98
- --font-mono: var(--font-geist-mono);
99
- --color-sidebar-ring: var(--sidebar-ring);
100
- --color-sidebar-border: var(--sidebar-border);
101
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
102
- --color-sidebar-accent: var(--sidebar-accent);
103
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
104
- --color-sidebar-primary: var(--sidebar-primary);
105
- --color-sidebar-foreground: var(--sidebar-foreground);
106
- --color-sidebar: var(--sidebar);
107
- --color-chart-5: var(--chart-5);
108
- --color-chart-4: var(--chart-4);
109
- --color-chart-3: var(--chart-3);
110
- --color-chart-2: var(--chart-2);
111
- --color-chart-1: var(--chart-1);
112
- --color-ring: var(--ring);
113
- --color-input: var(--input);
114
- --color-border: var(--border);
115
- --color-destructive: var(--destructive);
116
- --color-accent-foreground: var(--accent-foreground);
117
- --color-accent: var(--accent);
118
- --color-muted-foreground: var(--muted-foreground);
119
- --color-muted: var(--muted);
120
- --color-secondary-foreground: var(--secondary-foreground);
121
- --color-secondary: var(--secondary);
122
- --color-primary-foreground: var(--primary-foreground);
123
- --color-primary: var(--primary);
124
- --color-popover-foreground: var(--popover-foreground);
125
- --color-popover: var(--popover);
126
- --color-card-foreground: var(--card-foreground);
127
- --color-card: var(--card);
128
54
  --radius-sm: calc(var(--radius) - 4px);
129
55
  --radius-md: calc(var(--radius) - 2px);
130
56
  --radius-lg: var(--radius);
131
57
  --radius-xl: calc(var(--radius) + 4px);
58
+ --color-background: var(--background);
59
+ --color-foreground: var(--foreground);
60
+ --color-card: var(--card);
61
+ --color-card-foreground: var(--card-foreground);
62
+ --color-popover: var(--popover);
63
+ --color-popover-foreground: var(--popover-foreground);
64
+ --color-primary: var(--primary);
65
+ --color-primary-foreground: var(--primary-foreground);
66
+ --color-secondary: var(--secondary);
67
+ --color-secondary-foreground: var(--secondary-foreground);
68
+ --color-muted: var(--muted);
69
+ --color-muted-foreground: var(--muted-foreground);
70
+ --color-accent: var(--accent);
71
+ --color-accent-foreground: var(--accent-foreground);
72
+ --color-destructive: var(--destructive);
73
+ --color-border: var(--border);
74
+ --color-input: var(--input);
75
+ --color-ring: var(--ring);
76
+ --color-chart-1: var(--chart-1);
77
+ --color-chart-2: var(--chart-2);
78
+ --color-chart-3: var(--chart-3);
79
+ --color-chart-4: var(--chart-4);
80
+ --color-chart-5: var(--chart-5);
81
+ --color-sidebar: var(--sidebar);
82
+ --color-sidebar-foreground: var(--sidebar-foreground);
83
+ --color-sidebar-primary: var(--sidebar-primary);
84
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
85
+ --color-sidebar-accent: var(--sidebar-accent);
86
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
87
+ --color-sidebar-border: var(--sidebar-border);
88
+ --color-sidebar-ring: var(--sidebar-ring);
132
89
  }
133
90
 
134
91
  :root {
@@ -215,24 +172,11 @@ export const AI = createAI<ServerMessage[], ClientMessage[]>({
215
172
 
216
173
  ```tsx
217
174
  import type { Metadata } from "next";
218
- import { Geist, Geist_Mono } from "next/font/google";
219
- import { AI } from "./actions";
220
-
221
175
  import "./globals.css";
222
176
 
223
- const geistSans = Geist({
224
- variable: "--font-geist-sans",
225
- subsets: ["latin"],
226
- });
227
-
228
- const geistMono = Geist_Mono({
229
- variable: "--font-geist-mono",
230
- subsets: ["latin"],
231
- });
232
-
233
177
  export const metadata: Metadata = {
234
- title: "assistant-ui App",
235
- description: "Generated by create-assistant-ui",
178
+ title: "AI SDK v5 Example",
179
+ description: "Example using @assistant-ui/react with AI SDK v5",
236
180
  };
237
181
 
238
182
  export default function RootLayout({
@@ -241,12 +185,8 @@ export default function RootLayout({
241
185
  children: React.ReactNode;
242
186
  }>) {
243
187
  return (
244
- <html lang="en" className="h-dvh">
245
- <body
246
- className={`${geistSans.variable} ${geistMono.variable} h-dvh antialiased`}
247
- >
248
- <AI>{children}</AI>
249
- </body>
188
+ <html lang="en">
189
+ <body className="h-dvh">{children}</body>
250
190
  </html>
251
191
  );
252
192
  }
@@ -258,60 +198,24 @@ export default function RootLayout({
258
198
  ```tsx
259
199
  "use client";
260
200
 
261
- import { useActions, useUIState } from "ai/rsc";
262
- import { nanoid } from "nanoid";
263
- import type { AI } from "./actions";
264
-
265
201
  import { Thread } from "@/components/assistant-ui/thread";
266
- import {
267
- type AppendMessage,
268
- AssistantRuntimeProvider,
269
- } from "@assistant-ui/react";
270
- import { useVercelRSCRuntime } from "@assistant-ui/react-ai-sdk";
271
- import { useState } from "react";
202
+ import { useChat } from "@ai-sdk/react";
203
+ import { AssistantRuntimeProvider } from "@assistant-ui/react";
204
+ import { useAISDKRuntime } from "@assistant-ui/react-ai-sdk";
272
205
 
273
206
  export default function Home() {
274
- return (
275
- <main className="h-dvh">
276
- <MyRuntimeProvider>
277
- <Thread />
278
- </MyRuntimeProvider>
279
- </main>
280
- );
281
- }
282
-
283
- const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => {
284
- const { continueConversation } = useActions();
285
- const [isRunning, setIsRunning] = useState(false);
286
- const [messages, setMessages] = useUIState<typeof AI>();
287
-
288
- const onNew = async (m: AppendMessage) => {
289
- if (m.content[0]?.type !== "text")
290
- throw new Error("Only text messages are supported");
291
-
292
- const input = m.content[0].text;
293
- setMessages((currentConversation) => [
294
- ...currentConversation,
295
- { id: nanoid(), role: "user", display: input },
296
- ]);
297
-
298
- try {
299
- setIsRunning(true);
300
- const message = await continueConversation(input);
301
- setMessages((currentConversation) => [...currentConversation, message]);
302
- } finally {
303
- setIsRunning(false);
304
- }
305
- };
207
+ const chat = useChat();
306
208
 
307
- const runtime = useVercelRSCRuntime({ messages, isRunning, onNew });
209
+ const runtime = useAISDKRuntime(chat);
308
210
 
309
211
  return (
310
212
  <AssistantRuntimeProvider runtime={runtime}>
311
- {children}
213
+ <div className="h-full">
214
+ <Thread />
215
+ </div>
312
216
  </AssistantRuntimeProvider>
313
217
  );
314
- };
218
+ }
315
219
 
316
220
  ```
317
221
 
@@ -332,10 +236,13 @@ const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => {
332
236
  },
333
237
  "aliases": {
334
238
  "components": "@/components",
335
- "utils": "@/lib/utils"
336
- }
239
+ "utils": "@/lib/utils",
240
+ "ui": "@/components/ui",
241
+ "lib": "@/lib",
242
+ "hooks": "@/hooks"
243
+ },
244
+ "iconLibrary": "lucide"
337
245
  }
338
-
339
246
  ```
340
247
 
341
248
  ## components/assistant-ui/markdown-text.tsx
@@ -346,13 +253,13 @@ const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => {
346
253
  import "@assistant-ui/react-markdown/styles/dot.css";
347
254
 
348
255
  import {
349
- CodeHeaderProps,
256
+ type CodeHeaderProps,
350
257
  MarkdownTextPrimitive,
351
258
  unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
352
259
  useIsMarkdownCodeBlock,
353
260
  } from "@assistant-ui/react-markdown";
354
261
  import remarkGfm from "remark-gfm";
355
- import { FC, memo, useState } from "react";
262
+ import { type FC, memo, useState } from "react";
356
263
  import { CheckIcon, CopyIcon } from "lucide-react";
357
264
 
358
265
  import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
@@ -378,7 +285,7 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
378
285
  };
379
286
 
380
287
  return (
381
- <div className="flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white">
288
+ <div className="mt-4 flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white">
382
289
  <span className="lowercase [&>span]:text-xs">{language}</span>
383
290
  <TooltipIconButton tooltip="Copy" onClick={onCopy}>
384
291
  {!isCopied && <CopyIcon />}
@@ -540,7 +447,7 @@ const defaultComponents = memoizeMarkdownComponents({
540
447
  pre: ({ className, ...props }) => (
541
448
  <pre
542
449
  className={cn(
543
- "overflow-x-auto rounded-b-lg bg-black p-4 text-white",
450
+ "overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
544
451
  className,
545
452
  )}
546
453
  {...props}
@@ -570,6 +477,7 @@ import {
570
477
  ActionBarPrimitive,
571
478
  BranchPickerPrimitive,
572
479
  ComposerPrimitive,
480
+ ErrorPrimitive,
573
481
  MessagePrimitive,
574
482
  ThreadPrimitive,
575
483
  } from "@assistant-ui/react";
@@ -589,11 +497,12 @@ import { cn } from "@/lib/utils";
589
497
  import { Button } from "@/components/ui/button";
590
498
  import { MarkdownText } from "@/components/assistant-ui/markdown-text";
591
499
  import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
500
+ import { ToolFallback } from "./tool-fallback";
592
501
 
593
502
  export const Thread: FC = () => {
594
503
  return (
595
504
  <ThreadPrimitive.Root
596
- className="bg-background box-border flex h-full flex-col overflow-hidden"
505
+ className="text-foreground bg-background box-border flex h-full flex-col overflow-hidden"
597
506
  style={{
598
507
  ["--thread-max-width" as string]: "42rem",
599
508
  }}
@@ -725,7 +634,7 @@ const UserMessage: FC = () => {
725
634
  <UserActionBar />
726
635
 
727
636
  <div className="bg-muted text-foreground col-start-2 row-start-2 max-w-[calc(var(--thread-max-width)*0.8)] break-words rounded-3xl px-5 py-2.5">
728
- <MessagePrimitive.Content />
637
+ <MessagePrimitive.Parts />
729
638
  </div>
730
639
 
731
640
  <BranchPicker className="col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
@@ -770,7 +679,10 @@ const AssistantMessage: FC = () => {
770
679
  return (
771
680
  <MessagePrimitive.Root className="relative grid w-full max-w-[var(--thread-max-width)] grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr] py-4">
772
681
  <div className="text-foreground col-span-2 col-start-2 row-start-1 my-1.5 max-w-[calc(var(--thread-max-width)*0.8)] break-words leading-7">
773
- <MessagePrimitive.Content components={{ Text: MarkdownText }} />
682
+ <MessagePrimitive.Parts
683
+ components={{ Text: MarkdownText, tools: { Fallback: ToolFallback } }}
684
+ />
685
+ <MessageError />
774
686
  </div>
775
687
 
776
688
  <AssistantActionBar />
@@ -780,6 +692,16 @@ const AssistantMessage: FC = () => {
780
692
  );
781
693
  };
782
694
 
695
+ const MessageError: FC = () => {
696
+ return (
697
+ <MessagePrimitive.Error>
698
+ <ErrorPrimitive.Root className="border-destructive bg-destructive/10 dark:bg-destructive/5 text-destructive mt-2 rounded-md border p-3 text-sm dark:text-red-200">
699
+ <ErrorPrimitive.Message className="line-clamp-2" />
700
+ </ErrorPrimitive.Root>
701
+ </MessagePrimitive.Error>
702
+ );
703
+ };
704
+
783
705
  const AssistantActionBar: FC = () => {
784
706
  return (
785
707
  <ActionBarPrimitive.Root
@@ -853,6 +775,54 @@ const CircleStopIcon = () => {
853
775
 
854
776
  ```
855
777
 
778
+ ## components/assistant-ui/tool-fallback.tsx
779
+
780
+ ```tsx
781
+ import { ToolCallMessagePartComponent } from "@assistant-ui/react";
782
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
783
+ import { useState } from "react";
784
+ import { Button } from "../ui/button";
785
+
786
+ export const ToolFallback: ToolCallMessagePartComponent = ({
787
+ toolName,
788
+ argsText,
789
+ result,
790
+ }) => {
791
+ const [isCollapsed, setIsCollapsed] = useState(true);
792
+ return (
793
+ <div className="mb-4 flex w-full flex-col gap-3 rounded-lg border py-3">
794
+ <div className="flex items-center gap-2 px-4">
795
+ <CheckIcon className="size-4" />
796
+ <p className="flex-grow">
797
+ Used tool: <b>{toolName}</b>
798
+ </p>
799
+ <Button onClick={() => setIsCollapsed(!isCollapsed)}>
800
+ {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
801
+ </Button>
802
+ </div>
803
+ {!isCollapsed && (
804
+ <div className="flex flex-col gap-2 border-t pt-2">
805
+ <div className="px-4">
806
+ <pre className="whitespace-pre-wrap">{argsText}</pre>
807
+ </div>
808
+ {result !== undefined && (
809
+ <div className="border-t border-dashed px-4 pt-2">
810
+ <p className="font-semibold">Result:</p>
811
+ <pre className="whitespace-pre-wrap">
812
+ {typeof result === "string"
813
+ ? result
814
+ : JSON.stringify(result, null, 2)}
815
+ </pre>
816
+ </div>
817
+ )}
818
+ </div>
819
+ )}
820
+ </div>
821
+ );
822
+ };
823
+
824
+ ```
825
+
856
826
  ## components/assistant-ui/tooltip-icon-button.tsx
857
827
 
858
828
  ```tsx
@@ -1016,7 +986,7 @@ function TooltipContent({
1016
986
  data-slot="tooltip-content"
1017
987
  sideOffset={sideOffset}
1018
988
  className={cn(
1019
- "bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-[--radix-tooltip-content-transform-origin] text-balance rounded-md px-3 py-1.5 text-xs",
989
+ "bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-tooltip-content-transform-origin) z-50 w-fit text-balance rounded-md px-3 py-1.5 text-xs",
1020
990
  className,
1021
991
  )}
1022
992
  {...props}
@@ -1032,17 +1002,10 @@ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
1032
1002
 
1033
1003
  ```
1034
1004
 
1035
- ## eslint.config.ts
1036
-
1037
- ```typescript
1038
- export { default } from "@assistant-ui/x-buildutils/eslint";
1039
-
1040
- ```
1041
-
1042
1005
  ## lib/utils.ts
1043
1006
 
1044
1007
  ```typescript
1045
- import { type ClassValue, clsx } from "clsx";
1008
+ import { clsx, type ClassValue } from "clsx";
1046
1009
  import { twMerge } from "tailwind-merge";
1047
1010
 
1048
1011
  export function cn(...inputs: ClassValue[]) {
@@ -1051,24 +1014,12 @@ export function cn(...inputs: ClassValue[]) {
1051
1014
 
1052
1015
  ```
1053
1016
 
1054
- ## next-env.d.ts
1055
-
1056
- ```typescript
1057
- /// <reference types="next" />
1058
- /// <reference types="next/image-types/global" />
1059
-
1060
- // NOTE: This file should not be edited
1061
- // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
1062
-
1063
- ```
1064
-
1065
- ## next.config.ts
1066
-
1067
- ```typescript
1068
- import type { NextConfig } from "next";
1017
+ ## next.config.js
1069
1018
 
1070
- const nextConfig: NextConfig = {
1071
- /* config options here */
1019
+ ```javascript
1020
+ /** @type {import('next').NextConfig} */
1021
+ const nextConfig = {
1022
+ transpilePackages: ["@assistant-ui/react", "@assistant-ui/react-ai-sdk"],
1072
1023
  };
1073
1024
 
1074
1025
  export default nextConfig;
@@ -1079,51 +1030,95 @@ export default nextConfig;
1079
1030
 
1080
1031
  ```json
1081
1032
  {
1082
- "name": "with-vercel-ai-rsc",
1083
- "version": "0.1.0",
1033
+ "name": "example-with-ai-sdk-v5",
1084
1034
  "private": true,
1085
- "scripts": {
1086
- "dev": "next dev --turbo",
1087
- "build": "next build",
1088
- "start": "next start",
1089
- "lint": "next lint"
1090
- },
1035
+ "version": "0.0.0",
1036
+ "type": "module",
1091
1037
  "dependencies": {
1092
- "@ai-sdk/openai": "^1.3.22",
1093
- "@assistant-ui/react": "workspace:*",
1038
+ "@ai-sdk/openai": "^2.0.0",
1039
+ "@ai-sdk/react": "^2.0.0",
1040
+ "@assistant-ui/react": "workspace:^",
1094
1041
  "@assistant-ui/react-ai-sdk": "workspace:*",
1095
- "@assistant-ui/react-markdown": "workspace:*",
1096
- "@radix-ui/react-icons": "^1.3.2",
1042
+ "@assistant-ui/react-markdown": "workspace:^",
1097
1043
  "@radix-ui/react-slot": "^1.2.3",
1098
1044
  "@radix-ui/react-tooltip": "^1.2.7",
1099
- "ai": "^4.3.16",
1045
+ "@tailwindcss/postcss": "^4.1.11",
1046
+ "ai": "^5.0.0",
1100
1047
  "class-variance-authority": "^0.7.1",
1101
1048
  "clsx": "^2.1.1",
1102
- "lucide-react": "^0.515.0",
1103
- "nanoid": "5.1.5",
1104
- "next": "15.3.3",
1105
- "react": "19.1.0",
1106
- "react-dom": "19.1.0",
1049
+ "lucide-react": "^0.535.0",
1050
+ "next": "15.4.5",
1051
+ "postcss": "^8.5.6",
1052
+ "react": "19.1.1",
1053
+ "react-dom": "19.1.1",
1107
1054
  "remark-gfm": "^4.0.1",
1108
1055
  "tailwind-merge": "^3.3.1",
1109
- "tw-animate-css": "^1.3.4",
1110
- "zod": "^3.25.64"
1056
+ "tailwindcss": "^4.1.11",
1057
+ "zod": "^4.0.14"
1111
1058
  },
1112
1059
  "devDependencies": {
1113
1060
  "@assistant-ui/x-buildutils": "workspace:*",
1114
- "@types/node": "^24",
1115
- "@types/react": "^19",
1116
- "@types/react-dom": "^19",
1061
+ "@types/node": "^24.1.0",
1062
+ "@types/react": "^19.1.9",
1063
+ "@types/react-dom": "^19.1.7",
1117
1064
  "eslint": "^9",
1118
- "eslint-config-next": "15.3.3",
1119
- "postcss": "^8",
1120
- "tailwindcss": "^4.1.10",
1121
- "typescript": "^5.8.3"
1065
+ "eslint-config-next": "15.4.5",
1066
+ "tw-animate-css": "^1.3.6",
1067
+ "typescript": "^5.9.2"
1068
+ },
1069
+ "scripts": {
1070
+ "dev": "next dev",
1071
+ "build": "next build",
1072
+ "start": "next start",
1073
+ "lint": "next lint"
1122
1074
  }
1123
1075
  }
1124
1076
 
1125
1077
  ```
1126
1078
 
1079
+ ## README.md
1080
+
1081
+ ```markdown
1082
+ # AI SDK v5 Example
1083
+
1084
+ This example demonstrates how to use `@assistant-ui/react-ai-sdk-v5` with the Vercel AI SDK v5.
1085
+
1086
+ ## Getting Started
1087
+
1088
+ 1. Install dependencies:
1089
+ ```bash
1090
+ npm install
1091
+ ```
1092
+
1093
+ 2. Set up your environment variables:
1094
+ ```bash
1095
+ cp .env.example .env.local
1096
+ ```
1097
+
1098
+ Add your Anthropic API key to `.env.local`:
1099
+ ```
1100
+ ANTHROPIC_API_KEY=your-api-key-here
1101
+ ```
1102
+
1103
+ 3. Run the development server:
1104
+ ```bash
1105
+ npm run dev
1106
+ ```
1107
+
1108
+ Open [http://localhost:3000](http://localhost:3000) to see the result.
1109
+
1110
+ ## Key Features
1111
+
1112
+ - Uses the new AI SDK v5 with `@ai-sdk/react` and `@ai-sdk/anthropic`
1113
+ - Integrates with `@assistant-ui/react` using the v5-compatible runtime
1114
+ - No RSC support (client-side only)
1115
+ - Uses the `useChat` hook from AI SDK v5
1116
+
1117
+ ## API Route
1118
+
1119
+ The API route at `/api/chat` uses the new `streamText` function from AI SDK v5 to handle chat completions.
1120
+ ```
1121
+
1127
1122
  ## tsconfig.json
1128
1123
 
1129
1124
  ```json