@assistant-ui/mcp-docs-server 0.1.4 → 0.1.6

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 (26) hide show
  1. package/.docs/organized/code-examples/local-ollama.md +10 -10
  2. package/.docs/organized/code-examples/search-agent-for-e-commerce.md +14 -14
  3. package/.docs/organized/code-examples/{with-vercel-ai-rsc.md → with-ai-sdk-v5.md} +259 -229
  4. package/.docs/organized/code-examples/with-ai-sdk.md +11 -10
  5. package/.docs/organized/code-examples/with-cloud.md +9 -8
  6. package/.docs/organized/code-examples/with-external-store.md +6 -6
  7. package/.docs/organized/code-examples/with-ffmpeg.md +15 -16
  8. package/.docs/organized/code-examples/with-langgraph.md +9 -8
  9. package/.docs/organized/code-examples/with-openai-assistants.md +9 -9
  10. package/.docs/organized/code-examples/with-parent-id-grouping.md +1377 -0
  11. package/.docs/organized/code-examples/with-react-hook-form.md +14 -15
  12. package/.docs/raw/docs/about-assistantui.mdx +9 -0
  13. package/.docs/raw/docs/cloud/persistence/ai-sdk.mdx +89 -32
  14. package/.docs/raw/docs/cloud/persistence/langgraph.mdx +187 -32
  15. package/.docs/raw/docs/guides/Latex.mdx +107 -0
  16. package/.docs/raw/docs/guides/ToolUI.mdx +0 -32
  17. package/.docs/raw/docs/runtimes/ai-sdk/use-chat-v5.mdx +212 -0
  18. package/.docs/raw/docs/runtimes/ai-sdk/use-chat.mdx +1 -1
  19. package/.docs/raw/docs/runtimes/custom/local.mdx +1 -1
  20. package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +2 -2
  21. package/.docs/raw/docs/ui/PartGrouping.mdx +540 -0
  22. package/.docs/raw/docs/ui/ToolGroup.mdx +96 -0
  23. package/dist/{chunk-JS4PWCVA.js → chunk-L4K23SWI.js} +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/stdio.js +1 -1
  26. package/package.json +7 -7
@@ -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
- }
17
-
18
- export interface ClientMessage {
19
- role: "user" | "assistant";
20
- display: ReactNode;
21
- }
16
+ // Allow streaming responses up to 30 seconds
17
+ export const maxDuration = 30;
22
18
 
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
- }
19
+ export async function POST(req: Request) {
20
+ const { messages }: { messages: UIMessage[] } = await req.json();
40
21
 
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,22 @@ 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 { AssistantRuntimeProvider } from "@assistant-ui/react";
203
+ import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
272
204
 
273
205
  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
- };
306
-
307
- const runtime = useVercelRSCRuntime({ messages, isRunning, onNew });
206
+ // Using the new simplified useChatRuntime hook
207
+ const runtime = useChatRuntime();
308
208
 
309
209
  return (
310
210
  <AssistantRuntimeProvider runtime={runtime}>
311
- {children}
211
+ <div className="h-full">
212
+ <Thread />
213
+ </div>
312
214
  </AssistantRuntimeProvider>
313
215
  );
314
- };
216
+ }
315
217
 
316
218
  ```
317
219
 
@@ -332,8 +234,12 @@ const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => {
332
234
  },
333
235
  "aliases": {
334
236
  "components": "@/components",
335
- "utils": "@/lib/utils"
336
- }
237
+ "utils": "@/lib/utils",
238
+ "ui": "@/components/ui",
239
+ "lib": "@/lib",
240
+ "hooks": "@/hooks"
241
+ },
242
+ "iconLibrary": "lucide"
337
243
  }
338
244
 
339
245
  ```
@@ -346,13 +252,13 @@ const MyRuntimeProvider = ({ children }: { children: React.ReactNode }) => {
346
252
  import "@assistant-ui/react-markdown/styles/dot.css";
347
253
 
348
254
  import {
349
- CodeHeaderProps,
255
+ type CodeHeaderProps,
350
256
  MarkdownTextPrimitive,
351
257
  unstable_memoizeMarkdownComponents as memoizeMarkdownComponents,
352
258
  useIsMarkdownCodeBlock,
353
259
  } from "@assistant-ui/react-markdown";
354
260
  import remarkGfm from "remark-gfm";
355
- import { FC, memo, useState } from "react";
261
+ import { type FC, memo, useState } from "react";
356
262
  import { CheckIcon, CopyIcon } from "lucide-react";
357
263
 
358
264
  import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
@@ -378,7 +284,7 @@ const CodeHeader: FC<CodeHeaderProps> = ({ language, code }) => {
378
284
  };
379
285
 
380
286
  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">
287
+ <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
288
  <span className="lowercase [&>span]:text-xs">{language}</span>
383
289
  <TooltipIconButton tooltip="Copy" onClick={onCopy}>
384
290
  {!isCopied && <CopyIcon />}
@@ -540,7 +446,7 @@ const defaultComponents = memoizeMarkdownComponents({
540
446
  pre: ({ className, ...props }) => (
541
447
  <pre
542
448
  className={cn(
543
- "overflow-x-auto rounded-b-lg bg-black p-4 text-white",
449
+ "overflow-x-auto !rounded-t-none rounded-b-lg bg-black p-4 text-white",
544
450
  className,
545
451
  )}
546
452
  {...props}
@@ -570,6 +476,7 @@ import {
570
476
  ActionBarPrimitive,
571
477
  BranchPickerPrimitive,
572
478
  ComposerPrimitive,
479
+ ErrorPrimitive,
573
480
  MessagePrimitive,
574
481
  ThreadPrimitive,
575
482
  } from "@assistant-ui/react";
@@ -589,11 +496,12 @@ import { cn } from "@/lib/utils";
589
496
  import { Button } from "@/components/ui/button";
590
497
  import { MarkdownText } from "@/components/assistant-ui/markdown-text";
591
498
  import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
499
+ import { ToolFallback } from "./tool-fallback";
592
500
 
593
501
  export const Thread: FC = () => {
594
502
  return (
595
503
  <ThreadPrimitive.Root
596
- className="bg-background box-border flex h-full flex-col overflow-hidden"
504
+ className="text-foreground bg-background box-border flex h-full flex-col overflow-hidden"
597
505
  style={{
598
506
  ["--thread-max-width" as string]: "42rem",
599
507
  }}
@@ -770,7 +678,10 @@ const AssistantMessage: FC = () => {
770
678
  return (
771
679
  <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
680
  <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.Parts components={{ Text: MarkdownText }} />
681
+ <MessagePrimitive.Parts
682
+ components={{ Text: MarkdownText, tools: { Fallback: ToolFallback } }}
683
+ />
684
+ <MessageError />
774
685
  </div>
775
686
 
776
687
  <AssistantActionBar />
@@ -780,6 +691,16 @@ const AssistantMessage: FC = () => {
780
691
  );
781
692
  };
782
693
 
694
+ const MessageError: FC = () => {
695
+ return (
696
+ <MessagePrimitive.Error>
697
+ <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">
698
+ <ErrorPrimitive.Message className="line-clamp-2" />
699
+ </ErrorPrimitive.Root>
700
+ </MessagePrimitive.Error>
701
+ );
702
+ };
703
+
783
704
  const AssistantActionBar: FC = () => {
784
705
  return (
785
706
  <ActionBarPrimitive.Root
@@ -853,6 +774,54 @@ const CircleStopIcon = () => {
853
774
 
854
775
  ```
855
776
 
777
+ ## components/assistant-ui/tool-fallback.tsx
778
+
779
+ ```tsx
780
+ import { ToolCallMessagePartComponent } from "@assistant-ui/react";
781
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
782
+ import { useState } from "react";
783
+ import { Button } from "../ui/button";
784
+
785
+ export const ToolFallback: ToolCallMessagePartComponent = ({
786
+ toolName,
787
+ argsText,
788
+ result,
789
+ }) => {
790
+ const [isCollapsed, setIsCollapsed] = useState(true);
791
+ return (
792
+ <div className="mb-4 flex w-full flex-col gap-3 rounded-lg border py-3">
793
+ <div className="flex items-center gap-2 px-4">
794
+ <CheckIcon className="size-4" />
795
+ <p className="flex-grow">
796
+ Used tool: <b>{toolName}</b>
797
+ </p>
798
+ <Button onClick={() => setIsCollapsed(!isCollapsed)}>
799
+ {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
800
+ </Button>
801
+ </div>
802
+ {!isCollapsed && (
803
+ <div className="flex flex-col gap-2 border-t pt-2">
804
+ <div className="px-4">
805
+ <pre className="whitespace-pre-wrap">{argsText}</pre>
806
+ </div>
807
+ {result !== undefined && (
808
+ <div className="border-t border-dashed px-4 pt-2">
809
+ <p className="font-semibold">Result:</p>
810
+ <pre className="whitespace-pre-wrap">
811
+ {typeof result === "string"
812
+ ? result
813
+ : JSON.stringify(result, null, 2)}
814
+ </pre>
815
+ </div>
816
+ )}
817
+ </div>
818
+ )}
819
+ </div>
820
+ );
821
+ };
822
+
823
+ ```
824
+
856
825
  ## components/assistant-ui/tooltip-icon-button.tsx
857
826
 
858
827
  ```tsx
@@ -1016,7 +985,7 @@ function TooltipContent({
1016
985
  data-slot="tooltip-content"
1017
986
  sideOffset={sideOffset}
1018
987
  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",
988
+ "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
989
  className,
1021
990
  )}
1022
991
  {...props}
@@ -1032,17 +1001,10 @@ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
1032
1001
 
1033
1002
  ```
1034
1003
 
1035
- ## eslint.config.ts
1036
-
1037
- ```typescript
1038
- export { default } from "@assistant-ui/x-buildutils/eslint";
1039
-
1040
- ```
1041
-
1042
1004
  ## lib/utils.ts
1043
1005
 
1044
1006
  ```typescript
1045
- import { type ClassValue, clsx } from "clsx";
1007
+ import { clsx, type ClassValue } from "clsx";
1046
1008
  import { twMerge } from "tailwind-merge";
1047
1009
 
1048
1010
  export function cn(...inputs: ClassValue[]) {
@@ -1051,24 +1013,12 @@ export function cn(...inputs: ClassValue[]) {
1051
1013
 
1052
1014
  ```
1053
1015
 
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.
1016
+ ## next.config.js
1062
1017
 
1063
- ```
1064
-
1065
- ## next.config.ts
1066
-
1067
- ```typescript
1068
- import type { NextConfig } from "next";
1069
-
1070
- const nextConfig: NextConfig = {
1071
- /* config options here */
1018
+ ```javascript
1019
+ /** @type {import('next').NextConfig} */
1020
+ const nextConfig = {
1021
+ transpilePackages: ["@assistant-ui/react", "@assistant-ui/react-ai-sdk"],
1072
1022
  };
1073
1023
 
1074
1024
  export default nextConfig;
@@ -1079,51 +1029,131 @@ export default nextConfig;
1079
1029
 
1080
1030
  ```json
1081
1031
  {
1082
- "name": "with-vercel-ai-rsc",
1083
- "version": "0.1.0",
1032
+ "name": "example-with-ai-sdk-v5",
1084
1033
  "private": true,
1085
- "scripts": {
1086
- "dev": "next dev --turbo",
1087
- "build": "next build",
1088
- "start": "next start",
1089
- "lint": "next lint"
1090
- },
1034
+ "version": "0.0.0",
1035
+ "type": "module",
1091
1036
  "dependencies": {
1092
- "@ai-sdk/openai": "^1.3.22",
1093
- "@assistant-ui/react": "workspace:*",
1037
+ "@ai-sdk/openai": "^2.0.0",
1038
+ "@ai-sdk/react": "^2.0.0",
1039
+ "@assistant-ui/react": "workspace:^",
1094
1040
  "@assistant-ui/react-ai-sdk": "workspace:*",
1095
- "@assistant-ui/react-markdown": "workspace:*",
1096
- "@radix-ui/react-icons": "^1.3.2",
1041
+ "@assistant-ui/react-markdown": "workspace:^",
1097
1042
  "@radix-ui/react-slot": "^1.2.3",
1098
1043
  "@radix-ui/react-tooltip": "^1.2.7",
1099
- "ai": "^4.3.16",
1044
+ "@tailwindcss/postcss": "^4.1.11",
1045
+ "ai": "^5.0.0",
1100
1046
  "class-variance-authority": "^0.7.1",
1101
1047
  "clsx": "^2.1.1",
1102
- "lucide-react": "^0.523.0",
1103
- "nanoid": "5.1.5",
1104
- "next": "15.3.4",
1105
- "react": "19.1.0",
1106
- "react-dom": "19.1.0",
1048
+ "lucide-react": "^0.535.0",
1049
+ "next": "15.4.5",
1050
+ "postcss": "^8.5.6",
1051
+ "react": "19.1.1",
1052
+ "react-dom": "19.1.1",
1107
1053
  "remark-gfm": "^4.0.1",
1108
1054
  "tailwind-merge": "^3.3.1",
1109
- "tw-animate-css": "^1.3.4",
1110
- "zod": "^3.25.67"
1055
+ "tailwindcss": "^4.1.11",
1056
+ "zod": "^4.0.14"
1111
1057
  },
1112
1058
  "devDependencies": {
1113
1059
  "@assistant-ui/x-buildutils": "workspace:*",
1114
- "@types/node": "^24",
1115
- "@types/react": "^19",
1116
- "@types/react-dom": "^19",
1060
+ "@types/node": "^24.1.0",
1061
+ "@types/react": "^19.1.9",
1062
+ "@types/react-dom": "^19.1.7",
1117
1063
  "eslint": "^9",
1118
- "eslint-config-next": "15.3.4",
1119
- "postcss": "^8",
1120
- "tailwindcss": "^4.1.11",
1121
- "typescript": "^5.8.3"
1064
+ "eslint-config-next": "15.4.5",
1065
+ "tw-animate-css": "^1.3.6",
1066
+ "typescript": "^5.9.2"
1067
+ },
1068
+ "scripts": {
1069
+ "dev": "next dev",
1070
+ "build": "next build",
1071
+ "start": "next start",
1072
+ "lint": "next lint"
1122
1073
  }
1123
1074
  }
1124
1075
 
1125
1076
  ```
1126
1077
 
1078
+ ## README.md
1079
+
1080
+ ```markdown
1081
+ # AI SDK v5 Example
1082
+
1083
+ This example demonstrates how to use `@assistant-ui/react-ai-sdk-v5` with the Vercel AI SDK v5.
1084
+
1085
+ ## Getting Started
1086
+
1087
+ 1. Install dependencies:
1088
+
1089
+ ```bash
1090
+ npm install
1091
+ ```
1092
+
1093
+ 2. Set up your environment variables:
1094
+
1095
+ ```bash
1096
+ cp .env.example .env.local
1097
+ ```
1098
+
1099
+ Add your Anthropic API key to `.env.local`:
1100
+
1101
+ ```
1102
+ ANTHROPIC_API_KEY=your-api-key-here
1103
+ ```
1104
+
1105
+ 3. Run the development server:
1106
+
1107
+ ```bash
1108
+ npm run dev
1109
+ ```
1110
+
1111
+ Open [http://localhost:3000](http://localhost:3000) to see the result.
1112
+
1113
+ ## Key Features
1114
+
1115
+ - Uses the new AI SDK v5 with `@ai-sdk/react` and `@ai-sdk/anthropic`
1116
+ - Integrates with `@assistant-ui/react` using the new `useChatRuntime` hook
1117
+ - No RSC support (client-side only)
1118
+ - Simplified integration with the `useChatRuntime` hook that wraps AI SDK v5's `useChat`
1119
+ - Automatically uses `AssistantChatTransport` to pass system messages and frontend tools to the backend
1120
+
1121
+ ## Custom Transport Configuration
1122
+
1123
+ By default, `useChatRuntime` uses `AssistantChatTransport` which automatically forwards system messages and frontend tools to the backend.
1124
+
1125
+ ### Custom API URL with Forwarding
1126
+
1127
+ When customizing the API URL, you must explicitly use `AssistantChatTransport` to keep system/tools forwarding:
1128
+
1129
+ ```typescript
1130
+ import { AssistantChatTransport } from "@assistant-ui/react-ai-sdk";
1131
+
1132
+ const runtime = useChatRuntime({
1133
+ transport: new AssistantChatTransport({
1134
+ api: "/my-custom-api/chat", // Custom URL with system/tools forwarding
1135
+ }),
1136
+ });
1137
+ ```
1138
+
1139
+ ### Disable System/Tools Forwarding
1140
+
1141
+ To use the standard AI SDK transport without forwarding:
1142
+
1143
+ ```typescript
1144
+ import { DefaultChatTransport } from "ai";
1145
+
1146
+ const runtime = useChatRuntime({
1147
+ transport: new DefaultChatTransport(), // No system/tools forwarding
1148
+ });
1149
+ ```
1150
+
1151
+ ## API Route
1152
+
1153
+ The API route at `/api/chat` uses the new `streamText` function from AI SDK v5 to handle chat completions.
1154
+
1155
+ ```
1156
+
1127
1157
  ## tsconfig.json
1128
1158
 
1129
1159
  ```json