@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
@@ -9,43 +9,41 @@
9
9
  @custom-variant dark (&:is(.dark *));
10
10
 
11
11
  @theme inline {
12
- --color-background: var(--background);
13
- --color-foreground: var(--foreground);
14
- --font-sans: var(--font-geist-sans);
15
- --font-mono: var(--font-geist-mono);
16
- --color-sidebar-ring: var(--sidebar-ring);
17
- --color-sidebar-border: var(--sidebar-border);
18
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
19
- --color-sidebar-accent: var(--sidebar-accent);
20
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
21
- --color-sidebar-primary: var(--sidebar-primary);
22
- --color-sidebar-foreground: var(--sidebar-foreground);
23
- --color-sidebar: var(--sidebar);
24
- --color-chart-5: var(--chart-5);
25
- --color-chart-4: var(--chart-4);
26
- --color-chart-3: var(--chart-3);
27
- --color-chart-2: var(--chart-2);
28
- --color-chart-1: var(--chart-1);
29
- --color-ring: var(--ring);
30
- --color-input: var(--input);
31
- --color-border: var(--border);
32
- --color-destructive: var(--destructive);
33
- --color-accent-foreground: var(--accent-foreground);
34
- --color-accent: var(--accent);
35
- --color-muted-foreground: var(--muted-foreground);
36
- --color-muted: var(--muted);
37
- --color-secondary-foreground: var(--secondary-foreground);
38
- --color-secondary: var(--secondary);
39
- --color-primary-foreground: var(--primary-foreground);
40
- --color-primary: var(--primary);
41
- --color-popover-foreground: var(--popover-foreground);
42
- --color-popover: var(--popover);
43
- --color-card-foreground: var(--card-foreground);
44
- --color-card: var(--card);
45
12
  --radius-sm: calc(var(--radius) - 4px);
46
13
  --radius-md: calc(var(--radius) - 2px);
47
14
  --radius-lg: var(--radius);
48
15
  --radius-xl: calc(var(--radius) + 4px);
16
+ --color-background: var(--background);
17
+ --color-foreground: var(--foreground);
18
+ --color-card: var(--card);
19
+ --color-card-foreground: var(--card-foreground);
20
+ --color-popover: var(--popover);
21
+ --color-popover-foreground: var(--popover-foreground);
22
+ --color-primary: var(--primary);
23
+ --color-primary-foreground: var(--primary-foreground);
24
+ --color-secondary: var(--secondary);
25
+ --color-secondary-foreground: var(--secondary-foreground);
26
+ --color-muted: var(--muted);
27
+ --color-muted-foreground: var(--muted-foreground);
28
+ --color-accent: var(--accent);
29
+ --color-accent-foreground: var(--accent-foreground);
30
+ --color-destructive: var(--destructive);
31
+ --color-border: var(--border);
32
+ --color-input: var(--input);
33
+ --color-ring: var(--ring);
34
+ --color-chart-1: var(--chart-1);
35
+ --color-chart-2: var(--chart-2);
36
+ --color-chart-3: var(--chart-3);
37
+ --color-chart-4: var(--chart-4);
38
+ --color-chart-5: var(--chart-5);
39
+ --color-sidebar: var(--sidebar);
40
+ --color-sidebar-foreground: var(--sidebar-foreground);
41
+ --color-sidebar-primary: var(--sidebar-primary);
42
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
43
+ --color-sidebar-accent: var(--sidebar-accent);
44
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
45
+ --color-sidebar-border: var(--sidebar-border);
46
+ --color-sidebar-ring: var(--sidebar-ring);
49
47
  }
50
48
 
51
49
  :root {
@@ -651,7 +649,7 @@ export const ComposerAddAttachment: FC = () => {
651
649
  side="bottom"
652
650
  variant="ghost"
653
651
  size="icon"
654
- 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"
652
+ 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"
655
653
  aria-label="Add Attachment"
656
654
  >
657
655
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -910,6 +908,7 @@ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button
910
908
  import { Button } from "@/components/ui/button";
911
909
  import { cn } from "@/lib/utils";
912
910
  import {
911
+ ActionBarMorePrimitive,
913
912
  ActionBarPrimitive,
914
913
  AssistantIf,
915
914
  BranchPickerPrimitive,
@@ -926,6 +925,7 @@ import {
926
925
  ChevronRightIcon,
927
926
  CopyIcon,
928
927
  DownloadIcon,
928
+ MoreHorizontalIcon,
929
929
  PencilIcon,
930
930
  RefreshCwIcon,
931
931
  SquareIcon,
@@ -971,7 +971,7 @@ const ThreadScrollToBottom: FC = () => {
971
971
  <TooltipIconButton
972
972
  tooltip="Scroll to bottom"
973
973
  variant="outline"
974
- 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"
974
+ 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"
975
975
  >
976
976
  <ArrowDownIcon />
977
977
  </TooltipIconButton>
@@ -1135,7 +1135,7 @@ const AssistantActionBar: FC = () => {
1135
1135
  hideWhenRunning
1136
1136
  autohide="not-last"
1137
1137
  autohideFloat="single-branch"
1138
- 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"
1138
+ 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"
1139
1139
  >
1140
1140
  <ActionBarPrimitive.Copy asChild>
1141
1141
  <TooltipIconButton tooltip="Copy">
@@ -1147,16 +1147,33 @@ const AssistantActionBar: FC = () => {
1147
1147
  </AssistantIf>
1148
1148
  </TooltipIconButton>
1149
1149
  </ActionBarPrimitive.Copy>
1150
- <ActionBarPrimitive.ExportMarkdown asChild>
1151
- <TooltipIconButton tooltip="Export as Markdown">
1152
- <DownloadIcon />
1153
- </TooltipIconButton>
1154
- </ActionBarPrimitive.ExportMarkdown>
1155
1150
  <ActionBarPrimitive.Reload asChild>
1156
1151
  <TooltipIconButton tooltip="Refresh">
1157
1152
  <RefreshCwIcon />
1158
1153
  </TooltipIconButton>
1159
1154
  </ActionBarPrimitive.Reload>
1155
+ <ActionBarMorePrimitive.Root>
1156
+ <ActionBarMorePrimitive.Trigger asChild>
1157
+ <TooltipIconButton
1158
+ tooltip="More"
1159
+ className="data-[state=open]:bg-accent"
1160
+ >
1161
+ <MoreHorizontalIcon />
1162
+ </TooltipIconButton>
1163
+ </ActionBarMorePrimitive.Trigger>
1164
+ <ActionBarMorePrimitive.Content
1165
+ side="bottom"
1166
+ align="start"
1167
+ 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"
1168
+ >
1169
+ <ActionBarPrimitive.ExportMarkdown asChild>
1170
+ <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">
1171
+ <DownloadIcon className="size-4" />
1172
+ Export as Markdown
1173
+ </ActionBarMorePrimitive.Item>
1174
+ </ActionBarPrimitive.ExportMarkdown>
1175
+ </ActionBarMorePrimitive.Content>
1176
+ </ActionBarMorePrimitive.Root>
1160
1177
  </ActionBarPrimitive.Root>
1161
1178
  );
1162
1179
  };
@@ -1173,12 +1190,12 @@ const UserMessage: FC = () => {
1173
1190
  <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
1174
1191
  <MessagePrimitive.Parts />
1175
1192
  </div>
1176
- <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1193
+ <div className="aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2">
1177
1194
  <UserActionBar />
1178
1195
  </div>
1179
1196
  </div>
1180
1197
 
1181
- <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
1198
+ <BranchPicker className="aui-user-branch-picker col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
1182
1199
  </MessagePrimitive.Root>
1183
1200
  );
1184
1201
  };
@@ -1230,7 +1247,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1230
1247
  <BranchPickerPrimitive.Root
1231
1248
  hideWhenSingleBranch
1232
1249
  className={cn(
1233
- "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1250
+ "aui-branch-picker-root mr-2 -ml-2 inline-flex items-center text-muted-foreground text-xs",
1234
1251
  className,
1235
1252
  )}
1236
1253
  {...rest}
@@ -1257,98 +1274,329 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1257
1274
  ## components/assistant-ui/tool-fallback.tsx
1258
1275
 
1259
1276
  ```tsx
1260
- import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
1277
+ "use client";
1278
+
1279
+ import { memo, useCallback, useRef, useState } from "react";
1261
1280
  import {
1281
+ AlertCircleIcon,
1262
1282
  CheckIcon,
1263
1283
  ChevronDownIcon,
1264
- ChevronUpIcon,
1284
+ LoaderIcon,
1265
1285
  XCircleIcon,
1266
1286
  } from "lucide-react";
1267
- import { useState } from "react";
1268
- import { Button } from "@/components/ui/button";
1287
+ import {
1288
+ useScrollLock,
1289
+ type ToolCallMessagePartStatus,
1290
+ type ToolCallMessagePartComponent,
1291
+ } from "@assistant-ui/react";
1292
+ import {
1293
+ Collapsible,
1294
+ CollapsibleContent,
1295
+ CollapsibleTrigger,
1296
+ } from "@/components/ui/collapsible";
1269
1297
  import { cn } from "@/lib/utils";
1270
1298
 
1271
- export const ToolFallback: ToolCallMessagePartComponent = ({
1299
+ const ANIMATION_DURATION = 200;
1300
+
1301
+ export type ToolFallbackRootProps = Omit<
1302
+ React.ComponentProps<typeof Collapsible>,
1303
+ "open" | "onOpenChange"
1304
+ > & {
1305
+ open?: boolean;
1306
+ onOpenChange?: (open: boolean) => void;
1307
+ defaultOpen?: boolean;
1308
+ };
1309
+
1310
+ function ToolFallbackRoot({
1311
+ className,
1312
+ open: controlledOpen,
1313
+ onOpenChange: controlledOnOpenChange,
1314
+ defaultOpen = false,
1315
+ children,
1316
+ ...props
1317
+ }: ToolFallbackRootProps) {
1318
+ const collapsibleRef = useRef<HTMLDivElement>(null);
1319
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
1320
+ const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
1321
+
1322
+ const isControlled = controlledOpen !== undefined;
1323
+ const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1324
+
1325
+ const handleOpenChange = useCallback(
1326
+ (open: boolean) => {
1327
+ if (!open) {
1328
+ lockScroll();
1329
+ }
1330
+ if (!isControlled) {
1331
+ setUncontrolledOpen(open);
1332
+ }
1333
+ controlledOnOpenChange?.(open);
1334
+ },
1335
+ [lockScroll, isControlled, controlledOnOpenChange],
1336
+ );
1337
+
1338
+ return (
1339
+ <Collapsible
1340
+ ref={collapsibleRef}
1341
+ data-slot="tool-fallback-root"
1342
+ open={isOpen}
1343
+ onOpenChange={handleOpenChange}
1344
+ className={cn(
1345
+ "aui-tool-fallback-root group/tool-fallback-root w-full rounded-lg border py-3",
1346
+ className,
1347
+ )}
1348
+ style={
1349
+ {
1350
+ "--animation-duration": `${ANIMATION_DURATION}ms`,
1351
+ } as React.CSSProperties
1352
+ }
1353
+ {...props}
1354
+ >
1355
+ {children}
1356
+ </Collapsible>
1357
+ );
1358
+ }
1359
+
1360
+ type ToolStatus = ToolCallMessagePartStatus["type"];
1361
+
1362
+ const statusIconMap: Record<ToolStatus, React.ElementType> = {
1363
+ running: LoaderIcon,
1364
+ complete: CheckIcon,
1365
+ incomplete: XCircleIcon,
1366
+ "requires-action": AlertCircleIcon,
1367
+ };
1368
+
1369
+ function ToolFallbackTrigger({
1272
1370
  toolName,
1273
- argsText,
1274
- result,
1275
1371
  status,
1276
- }) => {
1277
- const [isCollapsed, setIsCollapsed] = useState(true);
1278
-
1372
+ className,
1373
+ ...props
1374
+ }: React.ComponentProps<typeof CollapsibleTrigger> & {
1375
+ toolName: string;
1376
+ status?: ToolCallMessagePartStatus;
1377
+ }) {
1378
+ const statusType = status?.type ?? "complete";
1379
+ const isRunning = statusType === "running";
1279
1380
  const isCancelled =
1280
1381
  status?.type === "incomplete" && status.reason === "cancelled";
1281
- const cancelledReason =
1282
- isCancelled && status.error
1283
- ? typeof status.error === "string"
1284
- ? status.error
1285
- : JSON.stringify(status.error)
1286
- : null;
1382
+
1383
+ const Icon = statusIconMap[statusType];
1384
+ const label = isCancelled ? "Cancelled tool" : "Used tool";
1287
1385
 
1288
1386
  return (
1289
- <div
1387
+ <CollapsibleTrigger
1388
+ data-slot="tool-fallback-trigger"
1290
1389
  className={cn(
1291
- "aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
1292
- isCancelled && "border-muted-foreground/30 bg-muted/30",
1390
+ "aui-tool-fallback-trigger group/trigger flex w-full items-center gap-2 px-4 text-sm transition-colors",
1391
+ className,
1293
1392
  )}
1393
+ {...props}
1294
1394
  >
1295
- <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1296
- {isCancelled ? (
1297
- <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1298
- ) : (
1299
- <CheckIcon className="aui-tool-fallback-icon size-4" />
1395
+ <Icon
1396
+ data-slot="tool-fallback-trigger-icon"
1397
+ className={cn(
1398
+ "aui-tool-fallback-trigger-icon size-4 shrink-0",
1399
+ isCancelled && "text-muted-foreground",
1400
+ isRunning && "animate-spin",
1300
1401
  )}
1301
- <p
1302
- className={cn(
1303
- "aui-tool-fallback-title grow",
1304
- isCancelled && "text-muted-foreground line-through",
1305
- )}
1306
- >
1307
- {isCancelled ? "Cancelled tool: " : "Used tool: "}
1308
- <b>{toolName}</b>
1309
- </p>
1310
- <Button onClick={() => setIsCollapsed(!isCollapsed)}>
1311
- {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
1312
- </Button>
1313
- </div>
1314
- {!isCollapsed && (
1315
- <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1316
- {cancelledReason && (
1317
- <div className="aui-tool-fallback-cancelled-root px-4">
1318
- <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1319
- Cancelled reason:
1320
- </p>
1321
- <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
1322
- {cancelledReason}
1323
- </p>
1324
- </div>
1325
- )}
1326
- <div
1327
- className={cn(
1328
- "aui-tool-fallback-args-root px-4",
1329
- isCancelled && "opacity-60",
1330
- )}
1402
+ />
1403
+ <span
1404
+ data-slot="tool-fallback-trigger-label"
1405
+ className={cn(
1406
+ "aui-tool-fallback-trigger-label-wrapper relative inline-block grow text-left leading-none",
1407
+ isCancelled && "text-muted-foreground line-through",
1408
+ )}
1409
+ >
1410
+ <span>
1411
+ {label}: <b>{toolName}</b>
1412
+ </span>
1413
+ {isRunning && (
1414
+ <span
1415
+ aria-hidden
1416
+ data-slot="tool-fallback-trigger-shimmer"
1417
+ className="aui-tool-fallback-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none"
1331
1418
  >
1332
- <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1333
- {argsText}
1334
- </pre>
1335
- </div>
1336
- {!isCancelled && result !== undefined && (
1337
- <div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
1338
- <p className="aui-tool-fallback-result-header font-semibold">
1339
- Result:
1340
- </p>
1341
- <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1342
- {typeof result === "string"
1343
- ? result
1344
- : JSON.stringify(result, null, 2)}
1345
- </pre>
1346
- </div>
1347
- )}
1348
- </div>
1419
+ {label}: <b>{toolName}</b>
1420
+ </span>
1421
+ )}
1422
+ </span>
1423
+ <ChevronDownIcon
1424
+ data-slot="tool-fallback-trigger-chevron"
1425
+ className={cn(
1426
+ "aui-tool-fallback-trigger-chevron size-4 shrink-0",
1427
+ "transition-transform duration-(--animation-duration) ease-out",
1428
+ "group-data-[state=closed]/trigger:-rotate-90",
1429
+ "group-data-[state=open]/trigger:rotate-0",
1430
+ )}
1431
+ />
1432
+ </CollapsibleTrigger>
1433
+ );
1434
+ }
1435
+
1436
+ function ToolFallbackContent({
1437
+ className,
1438
+ children,
1439
+ ...props
1440
+ }: React.ComponentProps<typeof CollapsibleContent>) {
1441
+ return (
1442
+ <CollapsibleContent
1443
+ data-slot="tool-fallback-content"
1444
+ className={cn(
1445
+ "aui-tool-fallback-content relative overflow-hidden text-sm outline-none",
1446
+ "group/collapsible-content ease-out",
1447
+ "data-[state=closed]:animate-collapsible-up",
1448
+ "data-[state=open]:animate-collapsible-down",
1449
+ "data-[state=closed]:fill-mode-forwards",
1450
+ "data-[state=closed]:pointer-events-none",
1451
+ "data-[state=open]:duration-(--animation-duration)",
1452
+ "data-[state=closed]:duration-(--animation-duration)",
1453
+ className,
1454
+ )}
1455
+ {...props}
1456
+ >
1457
+ <div className="mt-3 flex flex-col gap-2 border-t pt-2">{children}</div>
1458
+ </CollapsibleContent>
1459
+ );
1460
+ }
1461
+
1462
+ function ToolFallbackArgs({
1463
+ argsText,
1464
+ className,
1465
+ ...props
1466
+ }: React.ComponentProps<"div"> & {
1467
+ argsText?: string;
1468
+ }) {
1469
+ if (!argsText) return null;
1470
+
1471
+ return (
1472
+ <div
1473
+ data-slot="tool-fallback-args"
1474
+ className={cn("aui-tool-fallback-args px-4", className)}
1475
+ {...props}
1476
+ >
1477
+ <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1478
+ {argsText}
1479
+ </pre>
1480
+ </div>
1481
+ );
1482
+ }
1483
+
1484
+ function ToolFallbackResult({
1485
+ result,
1486
+ className,
1487
+ ...props
1488
+ }: React.ComponentProps<"div"> & {
1489
+ result?: unknown;
1490
+ }) {
1491
+ if (result === undefined) return null;
1492
+
1493
+ return (
1494
+ <div
1495
+ data-slot="tool-fallback-result"
1496
+ className={cn(
1497
+ "aui-tool-fallback-result border-t border-dashed px-4 pt-2",
1498
+ className,
1349
1499
  )}
1500
+ {...props}
1501
+ >
1502
+ <p className="aui-tool-fallback-result-header font-semibold">Result:</p>
1503
+ <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1504
+ {typeof result === "string" ? result : JSON.stringify(result, null, 2)}
1505
+ </pre>
1350
1506
  </div>
1351
1507
  );
1508
+ }
1509
+
1510
+ function ToolFallbackError({
1511
+ status,
1512
+ className,
1513
+ ...props
1514
+ }: React.ComponentProps<"div"> & {
1515
+ status?: ToolCallMessagePartStatus;
1516
+ }) {
1517
+ if (status?.type !== "incomplete") return null;
1518
+
1519
+ const error = status.error;
1520
+ const errorText = error
1521
+ ? typeof error === "string"
1522
+ ? error
1523
+ : JSON.stringify(error)
1524
+ : null;
1525
+
1526
+ if (!errorText) return null;
1527
+
1528
+ const isCancelled = status.reason === "cancelled";
1529
+ const headerText = isCancelled ? "Cancelled reason:" : "Error:";
1530
+
1531
+ return (
1532
+ <div
1533
+ data-slot="tool-fallback-error"
1534
+ className={cn("aui-tool-fallback-error px-4", className)}
1535
+ {...props}
1536
+ >
1537
+ <p className="aui-tool-fallback-error-header font-semibold text-muted-foreground">
1538
+ {headerText}
1539
+ </p>
1540
+ <p className="aui-tool-fallback-error-reason text-muted-foreground">
1541
+ {errorText}
1542
+ </p>
1543
+ </div>
1544
+ );
1545
+ }
1546
+
1547
+ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1548
+ toolName,
1549
+ argsText,
1550
+ result,
1551
+ status,
1552
+ }) => {
1553
+ const isCancelled =
1554
+ status?.type === "incomplete" && status.reason === "cancelled";
1555
+
1556
+ return (
1557
+ <ToolFallbackRoot
1558
+ className={cn(isCancelled && "border-muted-foreground/30 bg-muted/30")}
1559
+ >
1560
+ <ToolFallbackTrigger toolName={toolName} status={status} />
1561
+ <ToolFallbackContent>
1562
+ <ToolFallbackError status={status} />
1563
+ <ToolFallbackArgs
1564
+ argsText={argsText}
1565
+ className={cn(isCancelled && "opacity-60")}
1566
+ />
1567
+ {!isCancelled && <ToolFallbackResult result={result} />}
1568
+ </ToolFallbackContent>
1569
+ </ToolFallbackRoot>
1570
+ );
1571
+ };
1572
+
1573
+ const ToolFallback = memo(
1574
+ ToolFallbackImpl,
1575
+ ) as unknown as ToolCallMessagePartComponent & {
1576
+ Root: typeof ToolFallbackRoot;
1577
+ Trigger: typeof ToolFallbackTrigger;
1578
+ Content: typeof ToolFallbackContent;
1579
+ Args: typeof ToolFallbackArgs;
1580
+ Result: typeof ToolFallbackResult;
1581
+ Error: typeof ToolFallbackError;
1582
+ };
1583
+
1584
+ ToolFallback.displayName = "ToolFallback";
1585
+ ToolFallback.Root = ToolFallbackRoot;
1586
+ ToolFallback.Trigger = ToolFallbackTrigger;
1587
+ ToolFallback.Content = ToolFallbackContent;
1588
+ ToolFallback.Args = ToolFallbackArgs;
1589
+ ToolFallback.Result = ToolFallbackResult;
1590
+ ToolFallback.Error = ToolFallbackError;
1591
+
1592
+ export {
1593
+ ToolFallback,
1594
+ ToolFallbackRoot,
1595
+ ToolFallbackTrigger,
1596
+ ToolFallbackContent,
1597
+ ToolFallbackArgs,
1598
+ ToolFallbackResult,
1599
+ ToolFallbackError,
1352
1600
  };
1353
1601
 
1354
1602
  ```
@@ -1411,47 +1659,50 @@ import * as AvatarPrimitive from "@radix-ui/react-avatar";
1411
1659
 
1412
1660
  import { cn } from "@/lib/utils";
1413
1661
 
1414
- const Avatar = React.forwardRef<
1415
- React.ElementRef<typeof AvatarPrimitive.Root>,
1416
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
1417
- >(({ className, ...props }, ref) => (
1418
- <AvatarPrimitive.Root
1419
- ref={ref}
1420
- className={cn(
1421
- "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
1422
- className,
1423
- )}
1424
- {...props}
1425
- />
1426
- ));
1427
- Avatar.displayName = AvatarPrimitive.Root.displayName;
1428
-
1429
- const AvatarImage = React.forwardRef<
1430
- React.ElementRef<typeof AvatarPrimitive.Image>,
1431
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
1432
- >(({ className, ...props }, ref) => (
1433
- <AvatarPrimitive.Image
1434
- ref={ref}
1435
- className={cn("aspect-square h-full w-full", className)}
1436
- {...props}
1437
- />
1438
- ));
1439
- AvatarImage.displayName = AvatarPrimitive.Image.displayName;
1440
-
1441
- const AvatarFallback = React.forwardRef<
1442
- React.ElementRef<typeof AvatarPrimitive.Fallback>,
1443
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
1444
- >(({ className, ...props }, ref) => (
1445
- <AvatarPrimitive.Fallback
1446
- ref={ref}
1447
- className={cn(
1448
- "flex h-full w-full items-center justify-center rounded-full bg-muted",
1449
- className,
1450
- )}
1451
- {...props}
1452
- />
1453
- ));
1454
- AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
1662
+ function Avatar({
1663
+ className,
1664
+ ...props
1665
+ }: React.ComponentProps<typeof AvatarPrimitive.Root>) {
1666
+ return (
1667
+ <AvatarPrimitive.Root
1668
+ data-slot="avatar"
1669
+ className={cn(
1670
+ "relative flex size-8 shrink-0 overflow-hidden rounded-full",
1671
+ className,
1672
+ )}
1673
+ {...props}
1674
+ />
1675
+ );
1676
+ }
1677
+
1678
+ function AvatarImage({
1679
+ className,
1680
+ ...props
1681
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
1682
+ return (
1683
+ <AvatarPrimitive.Image
1684
+ data-slot="avatar-image"
1685
+ className={cn("aspect-square size-full", className)}
1686
+ {...props}
1687
+ />
1688
+ );
1689
+ }
1690
+
1691
+ function AvatarFallback({
1692
+ className,
1693
+ ...props
1694
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
1695
+ return (
1696
+ <AvatarPrimitive.Fallback
1697
+ data-slot="avatar-fallback"
1698
+ className={cn(
1699
+ "flex size-full items-center justify-center rounded-full bg-muted",
1700
+ className,
1701
+ )}
1702
+ {...props}
1703
+ />
1704
+ );
1705
+ }
1455
1706
 
1456
1707
  export { Avatar, AvatarImage, AvatarFallback };
1457
1708
 
@@ -1460,8 +1711,6 @@ export { Avatar, AvatarImage, AvatarFallback };
1460
1711
  ## components/ui/button.tsx
1461
1712
 
1462
1713
  ```tsx
1463
- "use client";
1464
-
1465
1714
  import * as React from "react";
1466
1715
  import { Slot } from "@radix-ui/react-slot";
1467
1716
  import { cva, type VariantProps } from "class-variance-authority";
@@ -1469,26 +1718,28 @@ import { cva, type VariantProps } from "class-variance-authority";
1469
1718
  import { cn } from "@/lib/utils";
1470
1719
 
1471
1720
  const buttonVariants = cva(
1472
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md font-medium text-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
1721
+ "inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md font-medium text-sm outline-none transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
1473
1722
  {
1474
1723
  variants: {
1475
1724
  variant: {
1476
- default:
1477
- "bg-primary text-primary-foreground shadow hover:bg-primary/90",
1725
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
1478
1726
  destructive:
1479
- "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
1727
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
1480
1728
  outline:
1481
- "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
1729
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
1482
1730
  secondary:
1483
- "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
1484
- ghost: "hover:bg-accent hover:text-accent-foreground",
1731
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
1732
+ ghost:
1733
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
1485
1734
  link: "text-primary underline-offset-4 hover:underline",
1486
1735
  },
1487
1736
  size: {
1488
- default: "h-9 px-4 py-2",
1489
- sm: "h-8 rounded-md px-3 text-xs",
1490
- lg: "h-10 rounded-md px-8",
1491
- icon: "h-9 w-9",
1737
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
1738
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
1739
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
1740
+ icon: "size-9",
1741
+ "icon-sm": "size-8",
1742
+ "icon-lg": "size-10",
1492
1743
  },
1493
1744
  },
1494
1745
  defaultVariants: {
@@ -1498,30 +1749,72 @@ const buttonVariants = cva(
1498
1749
  },
1499
1750
  );
1500
1751
 
1501
- export interface ButtonProps
1502
- extends React.ButtonHTMLAttributes<HTMLButtonElement>,
1503
- VariantProps<typeof buttonVariants> {
1504
- asChild?: boolean;
1505
- }
1752
+ function Button({
1753
+ className,
1754
+ variant = "default",
1755
+ size = "default",
1756
+ asChild = false,
1757
+ ...props
1758
+ }: React.ComponentProps<"button"> &
1759
+ VariantProps<typeof buttonVariants> & {
1760
+ asChild?: boolean;
1761
+ }) {
1762
+ const Comp = asChild ? Slot : "button";
1506
1763
 
1507
- const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
1508
- ({ className, variant, size, asChild = false, ...props }, ref) => {
1509
- const Comp = asChild ? Slot : "button";
1510
- return (
1511
- <Comp
1512
- className={cn(buttonVariants({ variant, size, className }))}
1513
- ref={ref}
1514
- {...props}
1515
- />
1516
- );
1517
- },
1518
- );
1519
- Button.displayName = "Button";
1764
+ return (
1765
+ <Comp
1766
+ data-slot="button"
1767
+ data-variant={variant}
1768
+ data-size={size}
1769
+ className={cn(buttonVariants({ variant, size, className }))}
1770
+ {...props}
1771
+ />
1772
+ );
1773
+ }
1520
1774
 
1521
1775
  export { Button, buttonVariants };
1522
1776
 
1523
1777
  ```
1524
1778
 
1779
+ ## components/ui/collapsible.tsx
1780
+
1781
+ ```tsx
1782
+ "use client";
1783
+
1784
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
1785
+
1786
+ function Collapsible({
1787
+ ...props
1788
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
1789
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
1790
+ }
1791
+
1792
+ function CollapsibleTrigger({
1793
+ ...props
1794
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
1795
+ return (
1796
+ <CollapsiblePrimitive.CollapsibleTrigger
1797
+ data-slot="collapsible-trigger"
1798
+ {...props}
1799
+ />
1800
+ );
1801
+ }
1802
+
1803
+ function CollapsibleContent({
1804
+ ...props
1805
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
1806
+ return (
1807
+ <CollapsiblePrimitive.CollapsibleContent
1808
+ data-slot="collapsible-content"
1809
+ {...props}
1810
+ />
1811
+ );
1812
+ }
1813
+
1814
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent };
1815
+
1816
+ ```
1817
+
1525
1818
  ## components/ui/dialog.tsx
1526
1819
 
1527
1820
  ```tsx
@@ -1565,7 +1858,7 @@ function DialogOverlay({
1565
1858
  <DialogPrimitive.Overlay
1566
1859
  data-slot="dialog-overlay"
1567
1860
  className={cn(
1568
- "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",
1861
+ "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",
1569
1862
  className,
1570
1863
  )}
1571
1864
  {...props}
@@ -1576,24 +1869,32 @@ function DialogOverlay({
1576
1869
  function DialogContent({
1577
1870
  className,
1578
1871
  children,
1872
+ showCloseButton = true,
1579
1873
  ...props
1580
- }: React.ComponentProps<typeof DialogPrimitive.Content>) {
1874
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
1875
+ showCloseButton?: boolean;
1876
+ }) {
1581
1877
  return (
1582
1878
  <DialogPortal data-slot="dialog-portal">
1583
1879
  <DialogOverlay />
1584
1880
  <DialogPrimitive.Content
1585
1881
  data-slot="dialog-content"
1586
1882
  className={cn(
1587
- "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",
1883
+ "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",
1588
1884
  className,
1589
1885
  )}
1590
1886
  {...props}
1591
1887
  >
1592
1888
  {children}
1593
- <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">
1594
- <XIcon />
1595
- <span className="sr-only">Close</span>
1596
- </DialogPrimitive.Close>
1889
+ {showCloseButton && (
1890
+ <DialogPrimitive.Close
1891
+ data-slot="dialog-close"
1892
+ 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"
1893
+ >
1894
+ <XIcon />
1895
+ <span className="sr-only">Close</span>
1896
+ </DialogPrimitive.Close>
1897
+ )}
1597
1898
  </DialogPrimitive.Content>
1598
1899
  </DialogPortal>
1599
1900
  );
@@ -1714,13 +2015,13 @@ function TooltipContent({
1714
2015
  data-slot="tooltip-content"
1715
2016
  sideOffset={sideOffset}
1716
2017
  className={cn(
1717
- "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",
2018
+ "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",
1718
2019
  className,
1719
2020
  )}
1720
2021
  {...props}
1721
2022
  >
1722
2023
  {children}
1723
- <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
2024
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
1724
2025
  </TooltipPrimitive.Content>
1725
2026
  </TooltipPrimitive.Portal>
1726
2027
  );
@@ -1760,40 +2061,43 @@ export default nextConfig;
1760
2061
  ```json
1761
2062
  {
1762
2063
  "name": "with-parent-id-grouping",
1763
- "version": "0.1.0",
2064
+ "version": "0.0.0",
1764
2065
  "private": true,
2066
+ "type": "module",
1765
2067
  "scripts": {
1766
- "dev": "next dev --turbo",
2068
+ "dev": "next dev",
1767
2069
  "build": "next build",
1768
2070
  "start": "next start"
1769
2071
  },
1770
2072
  "dependencies": {
1771
- "@ai-sdk/openai": "^2.0.84",
2073
+ "@ai-sdk/openai": "^3.0.13",
1772
2074
  "@assistant-ui/react": "workspace:*",
1773
2075
  "@assistant-ui/react-markdown": "workspace:*",
1774
2076
  "@radix-ui/react-avatar": "^1.1.11",
2077
+ "@radix-ui/react-collapsible": "^1.1.12",
1775
2078
  "@radix-ui/react-dialog": "^1.1.15",
1776
2079
  "@radix-ui/react-slot": "^1.2.4",
1777
2080
  "@radix-ui/react-tooltip": "^1.2.8",
1778
2081
  "class-variance-authority": "^0.7.1",
1779
2082
  "clsx": "^2.1.1",
1780
- "lucide-react": "^0.560.0",
1781
- "next": "16.0.10",
1782
- "react": "19.2.3",
1783
- "react-dom": "19.2.3",
2083
+ "lucide-react": "^0.562.0",
2084
+ "next": "^16.1.4",
2085
+ "react": "^19.2.3",
2086
+ "react-dom": "^19.2.3",
1784
2087
  "remark-gfm": "^4.0.1",
1785
2088
  "tailwind-merge": "^3.4.0",
1786
- "tw-animate-css": "^1.4.0",
1787
- "zustand": "^5.0.9"
2089
+ "zustand": "^5.0.10"
1788
2090
  },
1789
2091
  "devDependencies": {
1790
2092
  "@assistant-ui/x-buildutils": "workspace:*",
1791
- "@types/node": "^25",
1792
- "@types/react": "^19",
1793
- "@types/react-dom": "^19",
1794
- "postcss": "^8",
2093
+ "@tailwindcss/postcss": "^4.1.18",
2094
+ "@types/node": "^25.0.9",
2095
+ "@types/react": "^19.2.9",
2096
+ "@types/react-dom": "^19.2.3",
2097
+ "postcss": "^8.5.6",
1795
2098
  "tailwindcss": "^4.1.18",
1796
- "typescript": "^5"
2099
+ "tw-animate-css": "^1.4.0",
2100
+ "typescript": "^5.9.3"
1797
2101
  }
1798
2102
  }
1799
2103
 
@@ -1870,29 +2174,11 @@ This pattern is useful for:
1870
2174
 
1871
2175
  ```json
1872
2176
  {
1873
- "extends": "@assistant-ui/x-buildutils/ts/base",
2177
+ "extends": "@assistant-ui/x-buildutils/ts/next",
1874
2178
  "compilerOptions": {
1875
- "target": "ES6",
1876
- "module": "ESNext",
1877
- "incremental": true,
1878
- "plugins": [
1879
- {
1880
- "name": "next"
1881
- }
1882
- ],
1883
- "allowJs": true,
1884
- "strictNullChecks": true,
1885
- "jsx": "preserve",
1886
- "paths": {
1887
- "@/*": ["./*"],
1888
- "@assistant-ui/*": ["../../packages/*/src"],
1889
- "@assistant-ui/react/*": ["../../packages/react/src/*"],
1890
- "@assistant-ui/tap/*": ["../../packages/tap/src/*"],
1891
- "assistant-stream": ["../../packages/assistant-stream/src"],
1892
- "assistant-stream/*": ["../../packages/assistant-stream/src/*"]
1893
- }
2179
+ "paths": { "@/*": ["./*"] }
1894
2180
  },
1895
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
2181
+ "include": ["**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
1896
2182
  "exclude": ["node_modules"]
1897
2183
  }
1898
2184