@assistant-ui/mcp-docs-server 0.1.17 → 0.1.19

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 (202) hide show
  1. package/.docs/organized/code-examples/with-ag-ui.md +518 -234
  2. package/.docs/organized/code-examples/{with-ai-sdk-v5.md → with-ai-sdk-v6.md} +476 -189
  3. package/.docs/organized/code-examples/with-assistant-transport.md +503 -301
  4. package/.docs/organized/code-examples/with-cloud.md +524 -226
  5. package/.docs/organized/code-examples/with-custom-thread-list.md +433 -146
  6. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +2241 -0
  7. package/.docs/organized/code-examples/with-external-store.md +517 -231
  8. package/.docs/organized/code-examples/with-ffmpeg.md +500 -220
  9. package/.docs/organized/code-examples/with-langgraph.md +630 -319
  10. package/.docs/organized/code-examples/with-parent-id-grouping.md +517 -231
  11. package/.docs/organized/code-examples/with-react-hook-form.md +517 -233
  12. package/.docs/organized/code-examples/with-react-router.md +2167 -0
  13. package/.docs/organized/code-examples/{store-example.md → with-store.md} +18 -22
  14. package/.docs/organized/code-examples/with-tanstack.md +23 -41
  15. package/.docs/raw/blog/2025-01-31-changelog/index.mdx +0 -2
  16. package/.docs/raw/docs/{about-assistantui.mdx → (docs)/about-assistantui.mdx} +2 -1
  17. package/.docs/raw/docs/{architecture.mdx → (docs)/architecture.mdx} +3 -2
  18. package/.docs/raw/docs/{cli.mdx → (docs)/cli.mdx} +1 -19
  19. package/.docs/raw/docs/{copilots → (docs)/copilots}/make-assistant-readable.mdx +1 -0
  20. package/.docs/raw/docs/{copilots → (docs)/copilots}/make-assistant-tool-ui.mdx +2 -1
  21. package/.docs/raw/docs/{copilots → (docs)/copilots}/make-assistant-tool.mdx +2 -1
  22. package/.docs/raw/docs/{copilots → (docs)/copilots}/model-context.mdx +1 -0
  23. package/.docs/raw/docs/{copilots → (docs)/copilots}/motivation.mdx +1 -0
  24. package/.docs/raw/docs/{copilots → (docs)/copilots}/use-assistant-instructions.mdx +1 -0
  25. package/.docs/raw/docs/{devtools.mdx → (docs)/devtools.mdx} +4 -4
  26. package/.docs/raw/docs/{guides/Attachments.mdx → (docs)/guides/attachments.mdx} +4 -5
  27. package/.docs/raw/docs/{guides/Branching.mdx → (docs)/guides/branching.mdx} +2 -1
  28. package/.docs/raw/docs/{guides → (docs)/guides}/context-api.mdx +1 -0
  29. package/.docs/raw/docs/(docs)/guides/dictation.mdx +370 -0
  30. package/.docs/raw/docs/{guides/Editing.mdx → (docs)/guides/editing.mdx} +1 -0
  31. package/.docs/raw/docs/{guides/Latex.mdx → (docs)/guides/latex.mdx} +1 -2
  32. package/.docs/raw/docs/{guides/Speech.mdx → (docs)/guides/speech.mdx} +9 -10
  33. package/.docs/raw/docs/{guides/ToolUI.mdx → (docs)/guides/tool-ui.mdx} +15 -14
  34. package/.docs/raw/docs/{guides/Tools.mdx → (docs)/guides/tools.mdx} +10 -7
  35. package/.docs/raw/docs/{getting-started.mdx → (docs)/index.mdx} +17 -22
  36. package/.docs/raw/docs/{mcp-docs-server.mdx → (docs)/mcp-docs-server.mdx} +1 -2
  37. package/.docs/raw/docs/{api-reference/context-providers/AssistantRuntimeProvider.mdx → (reference)/api-reference/context-providers/assistant-runtime-provider.mdx} +2 -1
  38. package/.docs/raw/docs/{api-reference/context-providers/TextMessagePartProvider.mdx → (reference)/api-reference/context-providers/text-message-part-provider.mdx} +2 -1
  39. package/.docs/raw/docs/{api-reference → (reference)/api-reference}/integrations/react-data-stream.mdx +2 -1
  40. package/.docs/raw/docs/{api-reference → (reference)/api-reference}/integrations/react-hook-form.mdx +2 -1
  41. package/.docs/raw/docs/{api-reference → (reference)/api-reference}/integrations/vercel-ai-sdk.mdx +2 -2
  42. package/.docs/raw/docs/{api-reference → (reference)/api-reference}/overview.mdx +1 -1
  43. package/.docs/raw/docs/(reference)/api-reference/primitives/action-bar-more.mdx +327 -0
  44. package/.docs/raw/docs/{api-reference/primitives/ActionBar.mdx → (reference)/api-reference/primitives/action-bar.mdx} +3 -1
  45. package/.docs/raw/docs/{api-reference/primitives/AssistantIf.mdx → (reference)/api-reference/primitives/assistant-if.mdx} +2 -2
  46. package/.docs/raw/docs/{api-reference/primitives/AssistantModal.mdx → (reference)/api-reference/primitives/assistant-modal.mdx} +3 -1
  47. package/.docs/raw/docs/{api-reference/primitives/Attachment.mdx → (reference)/api-reference/primitives/attachment.mdx} +3 -2
  48. package/.docs/raw/docs/{api-reference/primitives/BranchPicker.mdx → (reference)/api-reference/primitives/branch-picker.mdx} +2 -1
  49. package/.docs/raw/docs/{api-reference/primitives/Composer.mdx → (reference)/api-reference/primitives/composer.mdx} +101 -2
  50. package/.docs/raw/docs/{api-reference → (reference)/api-reference}/primitives/composition.mdx +1 -0
  51. package/.docs/raw/docs/{api-reference/primitives/Error.mdx → (reference)/api-reference/primitives/error.mdx} +2 -1
  52. package/.docs/raw/docs/{api-reference/primitives/MessagePart.mdx → (reference)/api-reference/primitives/message-part.mdx} +2 -2
  53. package/.docs/raw/docs/{api-reference/primitives/Message.mdx → (reference)/api-reference/primitives/message.mdx} +2 -1
  54. package/.docs/raw/docs/(reference)/api-reference/primitives/thread-list-item-more.mdx +221 -0
  55. package/.docs/raw/docs/{api-reference/primitives/ThreadListItem.mdx → (reference)/api-reference/primitives/thread-list-item.mdx} +2 -1
  56. package/.docs/raw/docs/{api-reference/primitives/ThreadList.mdx → (reference)/api-reference/primitives/thread-list.mdx} +2 -1
  57. package/.docs/raw/docs/{api-reference/primitives/Thread.mdx → (reference)/api-reference/primitives/thread.mdx} +2 -1
  58. package/.docs/raw/docs/{api-reference/runtimes/AssistantRuntime.mdx → (reference)/api-reference/runtimes/assistant-runtime.mdx} +2 -1
  59. package/.docs/raw/docs/{api-reference/runtimes/AttachmentRuntime.mdx → (reference)/api-reference/runtimes/attachment-runtime.mdx} +3 -2
  60. package/.docs/raw/docs/{api-reference/runtimes/ComposerRuntime.mdx → (reference)/api-reference/runtimes/composer-runtime.mdx} +2 -1
  61. package/.docs/raw/docs/{api-reference/runtimes/MessagePartRuntime.mdx → (reference)/api-reference/runtimes/message-part-runtime.mdx} +3 -2
  62. package/.docs/raw/docs/{api-reference/runtimes/MessageRuntime.mdx → (reference)/api-reference/runtimes/message-runtime.mdx} +3 -2
  63. package/.docs/raw/docs/{api-reference/runtimes/ThreadListItemRuntime.mdx → (reference)/api-reference/runtimes/thread-list-item-runtime.mdx} +2 -1
  64. package/.docs/raw/docs/{api-reference/runtimes/ThreadListRuntime.mdx → (reference)/api-reference/runtimes/thread-list-runtime.mdx} +2 -1
  65. package/.docs/raw/docs/{api-reference/runtimes/ThreadRuntime.mdx → (reference)/api-reference/runtimes/thread-runtime.mdx} +3 -5
  66. package/.docs/raw/docs/{legacy/styled/AssistantModal.mdx → (reference)/legacy/styled/assistant-modal.mdx} +2 -3
  67. package/.docs/raw/docs/{legacy/styled/Decomposition.mdx → (reference)/legacy/styled/decomposition.mdx} +1 -0
  68. package/.docs/raw/docs/{legacy/styled/Markdown.mdx → (reference)/legacy/styled/markdown.mdx} +2 -4
  69. package/.docs/raw/docs/{legacy/styled/Scrollbar.mdx → (reference)/legacy/styled/scrollbar.mdx} +2 -1
  70. package/.docs/raw/docs/{legacy/styled/ThreadWidth.mdx → (reference)/legacy/styled/thread-width.mdx} +1 -0
  71. package/.docs/raw/docs/{legacy/styled/Thread.mdx → (reference)/legacy/styled/thread.mdx} +2 -3
  72. package/.docs/raw/docs/{migrations → (reference)/migrations}/deprecation-policy.mdx +1 -0
  73. package/.docs/raw/docs/{migrations → (reference)/migrations}/react-langgraph-v0-7.mdx +1 -2
  74. package/.docs/raw/docs/{migrations → (reference)/migrations}/v0-11.mdx +1 -0
  75. package/.docs/raw/docs/{migrations → (reference)/migrations}/v0-12.mdx +1 -0
  76. package/.docs/raw/docs/{react-compatibility.mdx → (reference)/react-compatibility.mdx} +2 -3
  77. package/.docs/raw/docs/cloud/authorization.mdx +1 -0
  78. package/.docs/raw/docs/cloud/overview.mdx +1 -0
  79. package/.docs/raw/docs/cloud/persistence/ai-sdk.mdx +2 -3
  80. package/.docs/raw/docs/cloud/persistence/langgraph.mdx +5 -7
  81. package/.docs/raw/docs/runtimes/ai-sdk/use-chat.mdx +9 -8
  82. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +2 -3
  83. package/.docs/raw/docs/runtimes/assistant-transport.mdx +7 -6
  84. package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +38 -3
  85. package/.docs/raw/docs/runtimes/custom/external-store.mdx +6 -8
  86. package/.docs/raw/docs/runtimes/custom/local.mdx +43 -16
  87. package/.docs/raw/docs/runtimes/data-stream.mdx +32 -4
  88. package/.docs/raw/docs/runtimes/helicone.mdx +1 -0
  89. package/.docs/raw/docs/runtimes/langgraph/index.mdx +3 -3
  90. package/.docs/raw/docs/runtimes/langgraph/tutorial/index.mdx +1 -0
  91. package/.docs/raw/docs/runtimes/langgraph/tutorial/introduction.mdx +1 -0
  92. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-1.mdx +1 -0
  93. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +1 -0
  94. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +2 -1
  95. package/.docs/raw/docs/runtimes/langserve.mdx +2 -2
  96. package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +4 -5
  97. package/.docs/raw/docs/runtimes/mastra/overview.mdx +1 -0
  98. package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +3 -4
  99. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +2 -4
  100. package/.docs/raw/docs/ui/assistant-modal.mdx +163 -0
  101. package/.docs/raw/docs/ui/assistant-sidebar.mdx +90 -0
  102. package/.docs/raw/docs/ui/attachment.mdx +227 -0
  103. package/.docs/raw/docs/ui/{Markdown.mdx → markdown.mdx} +11 -6
  104. package/.docs/raw/docs/ui/{Mermaid.mdx → mermaid.mdx} +12 -5
  105. package/.docs/raw/docs/ui/{PartGrouping.mdx → part-grouping.mdx} +4 -6
  106. package/.docs/raw/docs/ui/reasoning.mdx +148 -0
  107. package/.docs/raw/docs/ui/{Scrollbar.mdx → scrollbar.mdx} +9 -7
  108. package/.docs/raw/docs/ui/sources.mdx +87 -0
  109. package/.docs/raw/docs/ui/{SyntaxHighlighting.mdx → syntax-highlighting.mdx} +9 -5
  110. package/.docs/raw/docs/ui/thread-list.mdx +275 -0
  111. package/.docs/raw/docs/ui/{Thread.mdx → thread.mdx} +5 -6
  112. package/.docs/raw/docs/ui/tool-fallback.mdx +112 -0
  113. package/.docs/raw/docs/ui/tool-group.mdx +214 -0
  114. package/dist/constants.d.ts +10 -0
  115. package/dist/constants.d.ts.map +1 -0
  116. package/dist/constants.js +14 -0
  117. package/dist/constants.js.map +1 -0
  118. package/dist/index.d.ts +4 -0
  119. package/dist/index.d.ts.map +1 -0
  120. package/dist/index.js +33 -1
  121. package/dist/index.js.map +1 -0
  122. package/dist/prepare-docs/code-examples.d.ts +2 -0
  123. package/dist/prepare-docs/code-examples.d.ts.map +1 -0
  124. package/dist/prepare-docs/code-examples.js +129 -0
  125. package/dist/prepare-docs/code-examples.js.map +1 -0
  126. package/dist/prepare-docs/copy-raw.d.ts +2 -0
  127. package/dist/prepare-docs/copy-raw.d.ts.map +1 -0
  128. package/dist/prepare-docs/copy-raw.js +50 -0
  129. package/dist/prepare-docs/copy-raw.js.map +1 -0
  130. package/dist/prepare-docs/prepare.d.ts +2 -0
  131. package/dist/prepare-docs/prepare.d.ts.map +1 -0
  132. package/dist/prepare-docs/prepare.js +18 -195
  133. package/dist/prepare-docs/prepare.js.map +1 -0
  134. package/dist/stdio.d.ts +3 -0
  135. package/dist/stdio.d.ts.map +1 -0
  136. package/dist/stdio.js +4 -5
  137. package/dist/stdio.js.map +1 -0
  138. package/dist/tools/docs.d.ts +23 -0
  139. package/dist/tools/docs.d.ts.map +1 -0
  140. package/dist/tools/docs.js +168 -0
  141. package/dist/tools/docs.js.map +1 -0
  142. package/dist/tools/examples.d.ts +23 -0
  143. package/dist/tools/examples.d.ts.map +1 -0
  144. package/dist/tools/examples.js +95 -0
  145. package/dist/tools/examples.js.map +1 -0
  146. package/dist/tools/tests/test-setup.d.ts +4 -0
  147. package/dist/tools/tests/test-setup.d.ts.map +1 -0
  148. package/dist/tools/tests/test-setup.js +36 -0
  149. package/dist/tools/tests/test-setup.js.map +1 -0
  150. package/dist/utils/logger.d.ts +7 -0
  151. package/dist/utils/logger.d.ts.map +1 -0
  152. package/dist/utils/logger.js +20 -0
  153. package/dist/utils/logger.js.map +1 -0
  154. package/dist/utils/mcp-format.d.ts +7 -0
  155. package/dist/utils/mcp-format.d.ts.map +1 -0
  156. package/dist/utils/mcp-format.js +11 -0
  157. package/dist/utils/mcp-format.js.map +1 -0
  158. package/dist/utils/mdx.d.ts +9 -0
  159. package/dist/utils/mdx.d.ts.map +1 -0
  160. package/dist/utils/mdx.js +27 -0
  161. package/dist/utils/mdx.js.map +1 -0
  162. package/dist/utils/paths.d.ts +8 -0
  163. package/dist/utils/paths.d.ts.map +1 -0
  164. package/dist/utils/paths.js +84 -0
  165. package/dist/utils/paths.js.map +1 -0
  166. package/dist/utils/security.d.ts +2 -0
  167. package/dist/utils/security.d.ts.map +1 -0
  168. package/dist/utils/security.js +43 -0
  169. package/dist/utils/security.js.map +1 -0
  170. package/package.json +37 -19
  171. package/src/constants.ts +22 -0
  172. package/src/index.ts +51 -0
  173. package/src/prepare-docs/code-examples.ts +158 -0
  174. package/src/prepare-docs/copy-raw.ts +55 -0
  175. package/src/prepare-docs/prepare.ts +24 -0
  176. package/src/stdio.ts +7 -0
  177. package/src/tools/docs.ts +207 -0
  178. package/src/tools/examples.ts +107 -0
  179. package/src/tools/tests/docs.test.ts +124 -0
  180. package/src/tools/tests/examples.test.ts +94 -0
  181. package/src/tools/tests/integration.test.ts +46 -0
  182. package/src/tools/tests/json-parsing.test.ts +23 -0
  183. package/src/tools/tests/mcp-protocol.test.ts +133 -0
  184. package/src/tools/tests/path-traversal.test.ts +81 -0
  185. package/src/tools/tests/test-setup.ts +40 -0
  186. package/src/utils/logger.ts +20 -0
  187. package/src/utils/mcp-format.ts +12 -0
  188. package/src/utils/mdx.ts +39 -0
  189. package/src/utils/paths.ts +114 -0
  190. package/src/utils/security.ts +52 -0
  191. package/src/utils/tests/security.test.ts +119 -0
  192. package/.docs/raw/docs/index.mdx +0 -7
  193. package/.docs/raw/docs/ui/AssistantModal.mdx +0 -45
  194. package/.docs/raw/docs/ui/AssistantSidebar.mdx +0 -41
  195. package/.docs/raw/docs/ui/Attachment.mdx +0 -84
  196. package/.docs/raw/docs/ui/Reasoning.mdx +0 -152
  197. package/.docs/raw/docs/ui/ThreadList.mdx +0 -90
  198. package/.docs/raw/docs/ui/ToolFallback.mdx +0 -63
  199. package/.docs/raw/docs/ui/ToolGroup.mdx +0 -96
  200. package/dist/chunk-M2RKUM66.js +0 -38
  201. package/dist/chunk-NVNFQ5ZO.js +0 -423
  202. /package/.docs/raw/docs/{copilots → (docs)/copilots}/assistant-frame.mdx +0 -0
@@ -1,4 +1,4 @@
1
- # Example: with-ai-sdk-v5
1
+ # Example: with-ai-sdk-v6
2
2
 
3
3
  ## app/api/chat/route.ts
4
4
 
@@ -6,11 +6,12 @@
6
6
  import { openai } from "@ai-sdk/openai";
7
7
  import {
8
8
  streamText,
9
- UIMessage,
10
9
  convertToModelMessages,
11
10
  tool,
12
11
  stepCountIs,
12
+ zodSchema,
13
13
  } from "ai";
14
+ import type { UIMessage } from "ai";
14
15
  import { z } from "zod";
15
16
 
16
17
  // Allow streaming responses up to 30 seconds
@@ -21,15 +22,16 @@ export async function POST(req: Request) {
21
22
 
22
23
  const result = streamText({
23
24
  model: openai("gpt-4o"),
24
- messages: convertToModelMessages(messages),
25
+ messages: await convertToModelMessages(messages),
25
26
  stopWhen: stepCountIs(10),
26
27
  tools: {
27
28
  get_current_weather: tool({
28
- name: "",
29
29
  description: "Get the current weather",
30
- inputSchema: z.object({
31
- city: z.string(),
32
- }),
30
+ inputSchema: zodSchema(
31
+ z.object({
32
+ city: z.string(),
33
+ }),
34
+ ),
33
35
  execute: async ({ city }) => {
34
36
  return `The weather in ${city} is sunny`;
35
37
  },
@@ -474,7 +476,7 @@ export const ComposerAddAttachment: FC = () => {
474
476
  side="bottom"
475
477
  variant="ghost"
476
478
  size="icon"
477
- className="aui-composer-add-attachment size-[34px] rounded-full p-1 font-semibold text-xs hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30"
479
+ className="aui-composer-add-attachment size-8.5 rounded-full p-1 font-semibold text-xs hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30"
478
480
  aria-label="Add Attachment"
479
481
  >
480
482
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -733,6 +735,7 @@ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button
733
735
  import { Button } from "@/components/ui/button";
734
736
  import { cn } from "@/lib/utils";
735
737
  import {
738
+ ActionBarMorePrimitive,
736
739
  ActionBarPrimitive,
737
740
  AssistantIf,
738
741
  BranchPickerPrimitive,
@@ -749,6 +752,7 @@ import {
749
752
  ChevronRightIcon,
750
753
  CopyIcon,
751
754
  DownloadIcon,
755
+ MoreHorizontalIcon,
752
756
  PencilIcon,
753
757
  RefreshCwIcon,
754
758
  SquareIcon,
@@ -794,7 +798,7 @@ const ThreadScrollToBottom: FC = () => {
794
798
  <TooltipIconButton
795
799
  tooltip="Scroll to bottom"
796
800
  variant="outline"
797
- className="aui-thread-scroll-to-bottom -top-12 absolute z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent"
801
+ className="aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent"
798
802
  >
799
803
  <ArrowDownIcon />
800
804
  </TooltipIconButton>
@@ -958,7 +962,7 @@ const AssistantActionBar: FC = () => {
958
962
  hideWhenRunning
959
963
  autohide="not-last"
960
964
  autohideFloat="single-branch"
961
- className="aui-assistant-action-bar-root -ml-1 col-start-3 row-start-2 flex gap-1 text-muted-foreground data-floating:absolute data-floating:rounded-md data-floating:border data-floating:bg-background data-floating:p-1 data-floating:shadow-sm"
965
+ className="aui-assistant-action-bar-root col-start-3 row-start-2 -ml-1 flex gap-1 text-muted-foreground data-floating:absolute data-floating:rounded-md data-floating:border data-floating:bg-background data-floating:p-1 data-floating:shadow-sm"
962
966
  >
963
967
  <ActionBarPrimitive.Copy asChild>
964
968
  <TooltipIconButton tooltip="Copy">
@@ -970,16 +974,33 @@ const AssistantActionBar: FC = () => {
970
974
  </AssistantIf>
971
975
  </TooltipIconButton>
972
976
  </ActionBarPrimitive.Copy>
973
- <ActionBarPrimitive.ExportMarkdown asChild>
974
- <TooltipIconButton tooltip="Export as Markdown">
975
- <DownloadIcon />
976
- </TooltipIconButton>
977
- </ActionBarPrimitive.ExportMarkdown>
978
977
  <ActionBarPrimitive.Reload asChild>
979
978
  <TooltipIconButton tooltip="Refresh">
980
979
  <RefreshCwIcon />
981
980
  </TooltipIconButton>
982
981
  </ActionBarPrimitive.Reload>
982
+ <ActionBarMorePrimitive.Root>
983
+ <ActionBarMorePrimitive.Trigger asChild>
984
+ <TooltipIconButton
985
+ tooltip="More"
986
+ className="data-[state=open]:bg-accent"
987
+ >
988
+ <MoreHorizontalIcon />
989
+ </TooltipIconButton>
990
+ </ActionBarMorePrimitive.Trigger>
991
+ <ActionBarMorePrimitive.Content
992
+ side="bottom"
993
+ align="start"
994
+ className="aui-action-bar-more-content z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md"
995
+ >
996
+ <ActionBarPrimitive.ExportMarkdown asChild>
997
+ <ActionBarMorePrimitive.Item className="aui-action-bar-more-item flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground">
998
+ <DownloadIcon className="size-4" />
999
+ Export as Markdown
1000
+ </ActionBarMorePrimitive.Item>
1001
+ </ActionBarPrimitive.ExportMarkdown>
1002
+ </ActionBarMorePrimitive.Content>
1003
+ </ActionBarMorePrimitive.Root>
983
1004
  </ActionBarPrimitive.Root>
984
1005
  );
985
1006
  };
@@ -996,12 +1017,12 @@ const UserMessage: FC = () => {
996
1017
  <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
997
1018
  <MessagePrimitive.Parts />
998
1019
  </div>
999
- <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1020
+ <div className="aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2">
1000
1021
  <UserActionBar />
1001
1022
  </div>
1002
1023
  </div>
1003
1024
 
1004
- <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
1025
+ <BranchPicker className="aui-user-branch-picker col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
1005
1026
  </MessagePrimitive.Root>
1006
1027
  );
1007
1028
  };
@@ -1053,7 +1074,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1053
1074
  <BranchPickerPrimitive.Root
1054
1075
  hideWhenSingleBranch
1055
1076
  className={cn(
1056
- "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1077
+ "aui-branch-picker-root mr-2 -ml-2 inline-flex items-center text-muted-foreground text-xs",
1057
1078
  className,
1058
1079
  )}
1059
1080
  {...rest}
@@ -1080,98 +1101,329 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1080
1101
  ## components/assistant-ui/tool-fallback.tsx
1081
1102
 
1082
1103
  ```tsx
1083
- import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
1104
+ "use client";
1105
+
1106
+ import { memo, useCallback, useRef, useState } from "react";
1084
1107
  import {
1108
+ AlertCircleIcon,
1085
1109
  CheckIcon,
1086
1110
  ChevronDownIcon,
1087
- ChevronUpIcon,
1111
+ LoaderIcon,
1088
1112
  XCircleIcon,
1089
1113
  } from "lucide-react";
1090
- import { useState } from "react";
1091
- import { Button } from "@/components/ui/button";
1114
+ import {
1115
+ useScrollLock,
1116
+ type ToolCallMessagePartStatus,
1117
+ type ToolCallMessagePartComponent,
1118
+ } from "@assistant-ui/react";
1119
+ import {
1120
+ Collapsible,
1121
+ CollapsibleContent,
1122
+ CollapsibleTrigger,
1123
+ } from "@/components/ui/collapsible";
1092
1124
  import { cn } from "@/lib/utils";
1093
1125
 
1094
- export const ToolFallback: ToolCallMessagePartComponent = ({
1126
+ const ANIMATION_DURATION = 200;
1127
+
1128
+ export type ToolFallbackRootProps = Omit<
1129
+ React.ComponentProps<typeof Collapsible>,
1130
+ "open" | "onOpenChange"
1131
+ > & {
1132
+ open?: boolean;
1133
+ onOpenChange?: (open: boolean) => void;
1134
+ defaultOpen?: boolean;
1135
+ };
1136
+
1137
+ function ToolFallbackRoot({
1138
+ className,
1139
+ open: controlledOpen,
1140
+ onOpenChange: controlledOnOpenChange,
1141
+ defaultOpen = false,
1142
+ children,
1143
+ ...props
1144
+ }: ToolFallbackRootProps) {
1145
+ const collapsibleRef = useRef<HTMLDivElement>(null);
1146
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
1147
+ const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
1148
+
1149
+ const isControlled = controlledOpen !== undefined;
1150
+ const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1151
+
1152
+ const handleOpenChange = useCallback(
1153
+ (open: boolean) => {
1154
+ if (!open) {
1155
+ lockScroll();
1156
+ }
1157
+ if (!isControlled) {
1158
+ setUncontrolledOpen(open);
1159
+ }
1160
+ controlledOnOpenChange?.(open);
1161
+ },
1162
+ [lockScroll, isControlled, controlledOnOpenChange],
1163
+ );
1164
+
1165
+ return (
1166
+ <Collapsible
1167
+ ref={collapsibleRef}
1168
+ data-slot="tool-fallback-root"
1169
+ open={isOpen}
1170
+ onOpenChange={handleOpenChange}
1171
+ className={cn(
1172
+ "aui-tool-fallback-root group/tool-fallback-root w-full rounded-lg border py-3",
1173
+ className,
1174
+ )}
1175
+ style={
1176
+ {
1177
+ "--animation-duration": `${ANIMATION_DURATION}ms`,
1178
+ } as React.CSSProperties
1179
+ }
1180
+ {...props}
1181
+ >
1182
+ {children}
1183
+ </Collapsible>
1184
+ );
1185
+ }
1186
+
1187
+ type ToolStatus = ToolCallMessagePartStatus["type"];
1188
+
1189
+ const statusIconMap: Record<ToolStatus, React.ElementType> = {
1190
+ running: LoaderIcon,
1191
+ complete: CheckIcon,
1192
+ incomplete: XCircleIcon,
1193
+ "requires-action": AlertCircleIcon,
1194
+ };
1195
+
1196
+ function ToolFallbackTrigger({
1095
1197
  toolName,
1096
- argsText,
1097
- result,
1098
1198
  status,
1099
- }) => {
1100
- const [isCollapsed, setIsCollapsed] = useState(true);
1101
-
1199
+ className,
1200
+ ...props
1201
+ }: React.ComponentProps<typeof CollapsibleTrigger> & {
1202
+ toolName: string;
1203
+ status?: ToolCallMessagePartStatus;
1204
+ }) {
1205
+ const statusType = status?.type ?? "complete";
1206
+ const isRunning = statusType === "running";
1102
1207
  const isCancelled =
1103
1208
  status?.type === "incomplete" && status.reason === "cancelled";
1104
- const cancelledReason =
1105
- isCancelled && status.error
1106
- ? typeof status.error === "string"
1107
- ? status.error
1108
- : JSON.stringify(status.error)
1109
- : null;
1209
+
1210
+ const Icon = statusIconMap[statusType];
1211
+ const label = isCancelled ? "Cancelled tool" : "Used tool";
1110
1212
 
1111
1213
  return (
1112
- <div
1214
+ <CollapsibleTrigger
1215
+ data-slot="tool-fallback-trigger"
1113
1216
  className={cn(
1114
- "aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
1115
- isCancelled && "border-muted-foreground/30 bg-muted/30",
1217
+ "aui-tool-fallback-trigger group/trigger flex w-full items-center gap-2 px-4 text-sm transition-colors",
1218
+ className,
1116
1219
  )}
1220
+ {...props}
1117
1221
  >
1118
- <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1119
- {isCancelled ? (
1120
- <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1121
- ) : (
1122
- <CheckIcon className="aui-tool-fallback-icon size-4" />
1222
+ <Icon
1223
+ data-slot="tool-fallback-trigger-icon"
1224
+ className={cn(
1225
+ "aui-tool-fallback-trigger-icon size-4 shrink-0",
1226
+ isCancelled && "text-muted-foreground",
1227
+ isRunning && "animate-spin",
1123
1228
  )}
1124
- <p
1125
- className={cn(
1126
- "aui-tool-fallback-title grow",
1127
- isCancelled && "text-muted-foreground line-through",
1128
- )}
1129
- >
1130
- {isCancelled ? "Cancelled tool: " : "Used tool: "}
1131
- <b>{toolName}</b>
1132
- </p>
1133
- <Button onClick={() => setIsCollapsed(!isCollapsed)}>
1134
- {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
1135
- </Button>
1136
- </div>
1137
- {!isCollapsed && (
1138
- <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1139
- {cancelledReason && (
1140
- <div className="aui-tool-fallback-cancelled-root px-4">
1141
- <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1142
- Cancelled reason:
1143
- </p>
1144
- <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
1145
- {cancelledReason}
1146
- </p>
1147
- </div>
1148
- )}
1149
- <div
1150
- className={cn(
1151
- "aui-tool-fallback-args-root px-4",
1152
- isCancelled && "opacity-60",
1153
- )}
1229
+ />
1230
+ <span
1231
+ data-slot="tool-fallback-trigger-label"
1232
+ className={cn(
1233
+ "aui-tool-fallback-trigger-label-wrapper relative inline-block grow text-left leading-none",
1234
+ isCancelled && "text-muted-foreground line-through",
1235
+ )}
1236
+ >
1237
+ <span>
1238
+ {label}: <b>{toolName}</b>
1239
+ </span>
1240
+ {isRunning && (
1241
+ <span
1242
+ aria-hidden
1243
+ data-slot="tool-fallback-trigger-shimmer"
1244
+ className="aui-tool-fallback-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none"
1154
1245
  >
1155
- <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1156
- {argsText}
1157
- </pre>
1158
- </div>
1159
- {!isCancelled && result !== undefined && (
1160
- <div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
1161
- <p className="aui-tool-fallback-result-header font-semibold">
1162
- Result:
1163
- </p>
1164
- <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1165
- {typeof result === "string"
1166
- ? result
1167
- : JSON.stringify(result, null, 2)}
1168
- </pre>
1169
- </div>
1170
- )}
1171
- </div>
1246
+ {label}: <b>{toolName}</b>
1247
+ </span>
1248
+ )}
1249
+ </span>
1250
+ <ChevronDownIcon
1251
+ data-slot="tool-fallback-trigger-chevron"
1252
+ className={cn(
1253
+ "aui-tool-fallback-trigger-chevron size-4 shrink-0",
1254
+ "transition-transform duration-(--animation-duration) ease-out",
1255
+ "group-data-[state=closed]/trigger:-rotate-90",
1256
+ "group-data-[state=open]/trigger:rotate-0",
1257
+ )}
1258
+ />
1259
+ </CollapsibleTrigger>
1260
+ );
1261
+ }
1262
+
1263
+ function ToolFallbackContent({
1264
+ className,
1265
+ children,
1266
+ ...props
1267
+ }: React.ComponentProps<typeof CollapsibleContent>) {
1268
+ return (
1269
+ <CollapsibleContent
1270
+ data-slot="tool-fallback-content"
1271
+ className={cn(
1272
+ "aui-tool-fallback-content relative overflow-hidden text-sm outline-none",
1273
+ "group/collapsible-content ease-out",
1274
+ "data-[state=closed]:animate-collapsible-up",
1275
+ "data-[state=open]:animate-collapsible-down",
1276
+ "data-[state=closed]:fill-mode-forwards",
1277
+ "data-[state=closed]:pointer-events-none",
1278
+ "data-[state=open]:duration-(--animation-duration)",
1279
+ "data-[state=closed]:duration-(--animation-duration)",
1280
+ className,
1281
+ )}
1282
+ {...props}
1283
+ >
1284
+ <div className="mt-3 flex flex-col gap-2 border-t pt-2">{children}</div>
1285
+ </CollapsibleContent>
1286
+ );
1287
+ }
1288
+
1289
+ function ToolFallbackArgs({
1290
+ argsText,
1291
+ className,
1292
+ ...props
1293
+ }: React.ComponentProps<"div"> & {
1294
+ argsText?: string;
1295
+ }) {
1296
+ if (!argsText) return null;
1297
+
1298
+ return (
1299
+ <div
1300
+ data-slot="tool-fallback-args"
1301
+ className={cn("aui-tool-fallback-args px-4", className)}
1302
+ {...props}
1303
+ >
1304
+ <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1305
+ {argsText}
1306
+ </pre>
1307
+ </div>
1308
+ );
1309
+ }
1310
+
1311
+ function ToolFallbackResult({
1312
+ result,
1313
+ className,
1314
+ ...props
1315
+ }: React.ComponentProps<"div"> & {
1316
+ result?: unknown;
1317
+ }) {
1318
+ if (result === undefined) return null;
1319
+
1320
+ return (
1321
+ <div
1322
+ data-slot="tool-fallback-result"
1323
+ className={cn(
1324
+ "aui-tool-fallback-result border-t border-dashed px-4 pt-2",
1325
+ className,
1172
1326
  )}
1327
+ {...props}
1328
+ >
1329
+ <p className="aui-tool-fallback-result-header font-semibold">Result:</p>
1330
+ <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1331
+ {typeof result === "string" ? result : JSON.stringify(result, null, 2)}
1332
+ </pre>
1173
1333
  </div>
1174
1334
  );
1335
+ }
1336
+
1337
+ function ToolFallbackError({
1338
+ status,
1339
+ className,
1340
+ ...props
1341
+ }: React.ComponentProps<"div"> & {
1342
+ status?: ToolCallMessagePartStatus;
1343
+ }) {
1344
+ if (status?.type !== "incomplete") return null;
1345
+
1346
+ const error = status.error;
1347
+ const errorText = error
1348
+ ? typeof error === "string"
1349
+ ? error
1350
+ : JSON.stringify(error)
1351
+ : null;
1352
+
1353
+ if (!errorText) return null;
1354
+
1355
+ const isCancelled = status.reason === "cancelled";
1356
+ const headerText = isCancelled ? "Cancelled reason:" : "Error:";
1357
+
1358
+ return (
1359
+ <div
1360
+ data-slot="tool-fallback-error"
1361
+ className={cn("aui-tool-fallback-error px-4", className)}
1362
+ {...props}
1363
+ >
1364
+ <p className="aui-tool-fallback-error-header font-semibold text-muted-foreground">
1365
+ {headerText}
1366
+ </p>
1367
+ <p className="aui-tool-fallback-error-reason text-muted-foreground">
1368
+ {errorText}
1369
+ </p>
1370
+ </div>
1371
+ );
1372
+ }
1373
+
1374
+ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1375
+ toolName,
1376
+ argsText,
1377
+ result,
1378
+ status,
1379
+ }) => {
1380
+ const isCancelled =
1381
+ status?.type === "incomplete" && status.reason === "cancelled";
1382
+
1383
+ return (
1384
+ <ToolFallbackRoot
1385
+ className={cn(isCancelled && "border-muted-foreground/30 bg-muted/30")}
1386
+ >
1387
+ <ToolFallbackTrigger toolName={toolName} status={status} />
1388
+ <ToolFallbackContent>
1389
+ <ToolFallbackError status={status} />
1390
+ <ToolFallbackArgs
1391
+ argsText={argsText}
1392
+ className={cn(isCancelled && "opacity-60")}
1393
+ />
1394
+ {!isCancelled && <ToolFallbackResult result={result} />}
1395
+ </ToolFallbackContent>
1396
+ </ToolFallbackRoot>
1397
+ );
1398
+ };
1399
+
1400
+ const ToolFallback = memo(
1401
+ ToolFallbackImpl,
1402
+ ) as unknown as ToolCallMessagePartComponent & {
1403
+ Root: typeof ToolFallbackRoot;
1404
+ Trigger: typeof ToolFallbackTrigger;
1405
+ Content: typeof ToolFallbackContent;
1406
+ Args: typeof ToolFallbackArgs;
1407
+ Result: typeof ToolFallbackResult;
1408
+ Error: typeof ToolFallbackError;
1409
+ };
1410
+
1411
+ ToolFallback.displayName = "ToolFallback";
1412
+ ToolFallback.Root = ToolFallbackRoot;
1413
+ ToolFallback.Trigger = ToolFallbackTrigger;
1414
+ ToolFallback.Content = ToolFallbackContent;
1415
+ ToolFallback.Args = ToolFallbackArgs;
1416
+ ToolFallback.Result = ToolFallbackResult;
1417
+ ToolFallback.Error = ToolFallbackError;
1418
+
1419
+ export {
1420
+ ToolFallback,
1421
+ ToolFallbackRoot,
1422
+ ToolFallbackTrigger,
1423
+ ToolFallbackContent,
1424
+ ToolFallbackArgs,
1425
+ ToolFallbackResult,
1426
+ ToolFallbackError,
1175
1427
  };
1176
1428
 
1177
1429
  ```
@@ -1234,47 +1486,50 @@ import * as AvatarPrimitive from "@radix-ui/react-avatar";
1234
1486
 
1235
1487
  import { cn } from "@/lib/utils";
1236
1488
 
1237
- const Avatar = React.forwardRef<
1238
- React.ElementRef<typeof AvatarPrimitive.Root>,
1239
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
1240
- >(({ className, ...props }, ref) => (
1241
- <AvatarPrimitive.Root
1242
- ref={ref}
1243
- className={cn(
1244
- "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
1245
- className,
1246
- )}
1247
- {...props}
1248
- />
1249
- ));
1250
- Avatar.displayName = AvatarPrimitive.Root.displayName;
1251
-
1252
- const AvatarImage = React.forwardRef<
1253
- React.ElementRef<typeof AvatarPrimitive.Image>,
1254
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
1255
- >(({ className, ...props }, ref) => (
1256
- <AvatarPrimitive.Image
1257
- ref={ref}
1258
- className={cn("aspect-square h-full w-full", className)}
1259
- {...props}
1260
- />
1261
- ));
1262
- AvatarImage.displayName = AvatarPrimitive.Image.displayName;
1263
-
1264
- const AvatarFallback = React.forwardRef<
1265
- React.ElementRef<typeof AvatarPrimitive.Fallback>,
1266
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
1267
- >(({ className, ...props }, ref) => (
1268
- <AvatarPrimitive.Fallback
1269
- ref={ref}
1270
- className={cn(
1271
- "flex h-full w-full items-center justify-center rounded-full bg-muted",
1272
- className,
1273
- )}
1274
- {...props}
1275
- />
1276
- ));
1277
- AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
1489
+ function Avatar({
1490
+ className,
1491
+ ...props
1492
+ }: React.ComponentProps<typeof AvatarPrimitive.Root>) {
1493
+ return (
1494
+ <AvatarPrimitive.Root
1495
+ data-slot="avatar"
1496
+ className={cn(
1497
+ "relative flex size-8 shrink-0 overflow-hidden rounded-full",
1498
+ className,
1499
+ )}
1500
+ {...props}
1501
+ />
1502
+ );
1503
+ }
1504
+
1505
+ function AvatarImage({
1506
+ className,
1507
+ ...props
1508
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
1509
+ return (
1510
+ <AvatarPrimitive.Image
1511
+ data-slot="avatar-image"
1512
+ className={cn("aspect-square size-full", className)}
1513
+ {...props}
1514
+ />
1515
+ );
1516
+ }
1517
+
1518
+ function AvatarFallback({
1519
+ className,
1520
+ ...props
1521
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
1522
+ return (
1523
+ <AvatarPrimitive.Fallback
1524
+ data-slot="avatar-fallback"
1525
+ className={cn(
1526
+ "flex size-full items-center justify-center rounded-full bg-muted",
1527
+ className,
1528
+ )}
1529
+ {...props}
1530
+ />
1531
+ );
1532
+ }
1278
1533
 
1279
1534
  export { Avatar, AvatarImage, AvatarFallback };
1280
1535
 
@@ -1294,14 +1549,13 @@ const buttonVariants = cva(
1294
1549
  {
1295
1550
  variants: {
1296
1551
  variant: {
1297
- default:
1298
- "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
1552
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
1299
1553
  destructive:
1300
- "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
1554
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
1301
1555
  outline:
1302
1556
  "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
1303
1557
  secondary:
1304
- "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
1558
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
1305
1559
  ghost:
1306
1560
  "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
1307
1561
  link: "text-primary underline-offset-4 hover:underline",
@@ -1311,6 +1565,8 @@ const buttonVariants = cva(
1311
1565
  sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
1312
1566
  lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
1313
1567
  icon: "size-9",
1568
+ "icon-sm": "size-8",
1569
+ "icon-lg": "size-10",
1314
1570
  },
1315
1571
  },
1316
1572
  defaultVariants: {
@@ -1322,8 +1578,8 @@ const buttonVariants = cva(
1322
1578
 
1323
1579
  function Button({
1324
1580
  className,
1325
- variant,
1326
- size,
1581
+ variant = "default",
1582
+ size = "default",
1327
1583
  asChild = false,
1328
1584
  ...props
1329
1585
  }: React.ComponentProps<"button"> &
@@ -1335,6 +1591,8 @@ function Button({
1335
1591
  return (
1336
1592
  <Comp
1337
1593
  data-slot="button"
1594
+ data-variant={variant}
1595
+ data-size={size}
1338
1596
  className={cn(buttonVariants({ variant, size, className }))}
1339
1597
  {...props}
1340
1598
  />
@@ -1345,6 +1603,45 @@ export { Button, buttonVariants };
1345
1603
 
1346
1604
  ```
1347
1605
 
1606
+ ## components/ui/collapsible.tsx
1607
+
1608
+ ```tsx
1609
+ "use client";
1610
+
1611
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
1612
+
1613
+ function Collapsible({
1614
+ ...props
1615
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
1616
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
1617
+ }
1618
+
1619
+ function CollapsibleTrigger({
1620
+ ...props
1621
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
1622
+ return (
1623
+ <CollapsiblePrimitive.CollapsibleTrigger
1624
+ data-slot="collapsible-trigger"
1625
+ {...props}
1626
+ />
1627
+ );
1628
+ }
1629
+
1630
+ function CollapsibleContent({
1631
+ ...props
1632
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
1633
+ return (
1634
+ <CollapsiblePrimitive.CollapsibleContent
1635
+ data-slot="collapsible-content"
1636
+ {...props}
1637
+ />
1638
+ );
1639
+ }
1640
+
1641
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent };
1642
+
1643
+ ```
1644
+
1348
1645
  ## components/ui/dialog.tsx
1349
1646
 
1350
1647
  ```tsx
@@ -1388,7 +1685,7 @@ function DialogOverlay({
1388
1685
  <DialogPrimitive.Overlay
1389
1686
  data-slot="dialog-overlay"
1390
1687
  className={cn(
1391
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80 data-[state=closed]:animate-out data-[state=open]:animate-in",
1688
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=open]:animate-in",
1392
1689
  className,
1393
1690
  )}
1394
1691
  {...props}
@@ -1399,24 +1696,32 @@ function DialogOverlay({
1399
1696
  function DialogContent({
1400
1697
  className,
1401
1698
  children,
1699
+ showCloseButton = true,
1402
1700
  ...props
1403
- }: React.ComponentProps<typeof DialogPrimitive.Content>) {
1701
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
1702
+ showCloseButton?: boolean;
1703
+ }) {
1404
1704
  return (
1405
1705
  <DialogPortal data-slot="dialog-portal">
1406
1706
  <DialogOverlay />
1407
1707
  <DialogPrimitive.Content
1408
1708
  data-slot="dialog-content"
1409
1709
  className={cn(
1410
- "data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in sm:max-w-lg",
1710
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg outline-none duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in sm:max-w-lg",
1411
1711
  className,
1412
1712
  )}
1413
1713
  {...props}
1414
1714
  >
1415
1715
  {children}
1416
- <DialogPrimitive.Close className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0">
1417
- <XIcon />
1418
- <span className="sr-only">Close</span>
1419
- </DialogPrimitive.Close>
1716
+ {showCloseButton && (
1717
+ <DialogPrimitive.Close
1718
+ data-slot="dialog-close"
1719
+ className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0"
1720
+ >
1721
+ <XIcon />
1722
+ <span className="sr-only">Close</span>
1723
+ </DialogPrimitive.Close>
1724
+ )}
1420
1725
  </DialogPrimitive.Content>
1421
1726
  </DialogPortal>
1422
1727
  );
@@ -1537,13 +1842,13 @@ function TooltipContent({
1537
1842
  data-slot="tooltip-content"
1538
1843
  sideOffset={sideOffset}
1539
1844
  className={cn(
1540
- "fade-in-0 zoom-in-95 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) animate-in text-balance rounded-md bg-primary px-3 py-1.5 text-primary-foreground text-xs data-[state=closed]:animate-out",
1845
+ "fade-in-0 zoom-in-95 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) animate-in text-balance rounded-md bg-foreground px-3 py-1.5 text-background text-xs data-[state=closed]:animate-out",
1541
1846
  className,
1542
1847
  )}
1543
1848
  {...props}
1544
1849
  >
1545
1850
  {children}
1546
- <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
1851
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
1547
1852
  </TooltipPrimitive.Content>
1548
1853
  </TooltipPrimitive.Portal>
1549
1854
  );
@@ -1581,47 +1886,47 @@ export default nextConfig;
1581
1886
 
1582
1887
  ```json
1583
1888
  {
1584
- "name": "example-with-ai-sdk-v5",
1585
- "private": true,
1889
+ "name": "with-ai-sdk-v6",
1586
1890
  "version": "0.0.0",
1891
+ "private": true,
1587
1892
  "type": "module",
1893
+ "scripts": {
1894
+ "dev": "next dev",
1895
+ "build": "next build",
1896
+ "start": "next start"
1897
+ },
1588
1898
  "dependencies": {
1589
- "@ai-sdk/openai": "^2.0.84",
1590
- "@ai-sdk/react": "^2.0.114",
1591
- "@assistant-ui/react": "workspace:^",
1899
+ "@ai-sdk/openai": "^3.0.13",
1900
+ "@assistant-ui/react": "workspace:*",
1592
1901
  "@assistant-ui/react-ai-sdk": "workspace:*",
1593
- "@assistant-ui/react-markdown": "workspace:^",
1902
+ "@assistant-ui/react-markdown": "workspace:*",
1594
1903
  "@radix-ui/react-avatar": "^1.1.11",
1904
+ "@radix-ui/react-collapsible": "^1.1.12",
1595
1905
  "@radix-ui/react-dialog": "^1.1.15",
1596
1906
  "@radix-ui/react-slot": "^1.2.4",
1597
1907
  "@radix-ui/react-tooltip": "^1.2.8",
1598
- "@tailwindcss/postcss": "^4.1.18",
1599
- "ai": "^5.0.112",
1908
+ "ai": "^6.0.42",
1600
1909
  "class-variance-authority": "^0.7.1",
1601
1910
  "clsx": "^2.1.1",
1602
- "lucide-react": "^0.560.0",
1603
- "next": "16.0.10",
1604
- "postcss": "^8.5.6",
1605
- "react": "19.2.3",
1606
- "react-dom": "19.2.3",
1911
+ "lucide-react": "^0.562.0",
1912
+ "next": "^16.1.4",
1913
+ "react": "^19.2.3",
1914
+ "react-dom": "^19.2.3",
1607
1915
  "remark-gfm": "^4.0.1",
1608
1916
  "tailwind-merge": "^3.4.0",
1609
- "tailwindcss": "^4.1.18",
1610
- "zod": "^4.1.13",
1611
- "zustand": "^5.0.9"
1917
+ "zod": "^4.3.5",
1918
+ "zustand": "^5.0.10"
1612
1919
  },
1613
1920
  "devDependencies": {
1614
1921
  "@assistant-ui/x-buildutils": "workspace:*",
1615
- "@types/node": "^25.0.0",
1616
- "@types/react": "^19.2.7",
1922
+ "@tailwindcss/postcss": "^4.1.18",
1923
+ "@types/node": "^25.0.9",
1924
+ "@types/react": "^19.2.9",
1617
1925
  "@types/react-dom": "^19.2.3",
1926
+ "postcss": "^8.5.6",
1927
+ "tailwindcss": "^4.1.18",
1618
1928
  "tw-animate-css": "^1.4.0",
1619
1929
  "typescript": "^5.9.3"
1620
- },
1621
- "scripts": {
1622
- "dev": "next dev",
1623
- "build": "next build",
1624
- "start": "next start"
1625
1930
  }
1626
1931
  }
1627
1932
 
@@ -1710,29 +2015,11 @@ The API route at `/api/chat` uses the new `streamText` function from AI SDK v5 t
1710
2015
 
1711
2016
  ```json
1712
2017
  {
1713
- "extends": "@assistant-ui/x-buildutils/ts/base",
2018
+ "extends": "@assistant-ui/x-buildutils/ts/next",
1714
2019
  "compilerOptions": {
1715
- "target": "ES6",
1716
- "module": "ESNext",
1717
- "incremental": true,
1718
- "plugins": [
1719
- {
1720
- "name": "next"
1721
- }
1722
- ],
1723
- "allowJs": true,
1724
- "strictNullChecks": true,
1725
- "jsx": "preserve",
1726
- "paths": {
1727
- "@/*": ["./*"],
1728
- "@assistant-ui/*": ["../../packages/*/src"],
1729
- "@assistant-ui/react/*": ["../../packages/react/src/*"],
1730
- "@assistant-ui/tap/*": ["../../packages/tap/src/*"],
1731
- "assistant-stream": ["../../packages/assistant-stream/src"],
1732
- "assistant-stream/*": ["../../packages/assistant-stream/src/*"]
1733
- }
2020
+ "paths": { "@/*": ["./*"] }
1734
2021
  },
1735
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
2022
+ "include": ["**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
1736
2023
  "exclude": ["node_modules"]
1737
2024
  }
1738
2025