@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 {
@@ -491,7 +489,7 @@ export const ComposerAddAttachment: FC = () => {
491
489
  side="bottom"
492
490
  variant="ghost"
493
491
  size="icon"
494
- 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"
492
+ 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"
495
493
  aria-label="Add Attachment"
496
494
  >
497
495
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -750,6 +748,7 @@ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button
750
748
  import { Button } from "@/components/ui/button";
751
749
  import { cn } from "@/lib/utils";
752
750
  import {
751
+ ActionBarMorePrimitive,
753
752
  ActionBarPrimitive,
754
753
  AssistantIf,
755
754
  BranchPickerPrimitive,
@@ -766,6 +765,7 @@ import {
766
765
  ChevronRightIcon,
767
766
  CopyIcon,
768
767
  DownloadIcon,
768
+ MoreHorizontalIcon,
769
769
  PencilIcon,
770
770
  RefreshCwIcon,
771
771
  SquareIcon,
@@ -811,7 +811,7 @@ const ThreadScrollToBottom: FC = () => {
811
811
  <TooltipIconButton
812
812
  tooltip="Scroll to bottom"
813
813
  variant="outline"
814
- 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"
814
+ 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"
815
815
  >
816
816
  <ArrowDownIcon />
817
817
  </TooltipIconButton>
@@ -975,7 +975,7 @@ const AssistantActionBar: FC = () => {
975
975
  hideWhenRunning
976
976
  autohide="not-last"
977
977
  autohideFloat="single-branch"
978
- 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"
978
+ 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"
979
979
  >
980
980
  <ActionBarPrimitive.Copy asChild>
981
981
  <TooltipIconButton tooltip="Copy">
@@ -987,16 +987,33 @@ const AssistantActionBar: FC = () => {
987
987
  </AssistantIf>
988
988
  </TooltipIconButton>
989
989
  </ActionBarPrimitive.Copy>
990
- <ActionBarPrimitive.ExportMarkdown asChild>
991
- <TooltipIconButton tooltip="Export as Markdown">
992
- <DownloadIcon />
993
- </TooltipIconButton>
994
- </ActionBarPrimitive.ExportMarkdown>
995
990
  <ActionBarPrimitive.Reload asChild>
996
991
  <TooltipIconButton tooltip="Refresh">
997
992
  <RefreshCwIcon />
998
993
  </TooltipIconButton>
999
994
  </ActionBarPrimitive.Reload>
995
+ <ActionBarMorePrimitive.Root>
996
+ <ActionBarMorePrimitive.Trigger asChild>
997
+ <TooltipIconButton
998
+ tooltip="More"
999
+ className="data-[state=open]:bg-accent"
1000
+ >
1001
+ <MoreHorizontalIcon />
1002
+ </TooltipIconButton>
1003
+ </ActionBarMorePrimitive.Trigger>
1004
+ <ActionBarMorePrimitive.Content
1005
+ side="bottom"
1006
+ align="start"
1007
+ 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"
1008
+ >
1009
+ <ActionBarPrimitive.ExportMarkdown asChild>
1010
+ <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">
1011
+ <DownloadIcon className="size-4" />
1012
+ Export as Markdown
1013
+ </ActionBarMorePrimitive.Item>
1014
+ </ActionBarPrimitive.ExportMarkdown>
1015
+ </ActionBarMorePrimitive.Content>
1016
+ </ActionBarMorePrimitive.Root>
1000
1017
  </ActionBarPrimitive.Root>
1001
1018
  );
1002
1019
  };
@@ -1013,12 +1030,12 @@ const UserMessage: FC = () => {
1013
1030
  <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
1014
1031
  <MessagePrimitive.Parts />
1015
1032
  </div>
1016
- <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1033
+ <div className="aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2">
1017
1034
  <UserActionBar />
1018
1035
  </div>
1019
1036
  </div>
1020
1037
 
1021
- <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
1038
+ <BranchPicker className="aui-user-branch-picker col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
1022
1039
  </MessagePrimitive.Root>
1023
1040
  );
1024
1041
  };
@@ -1070,7 +1087,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1070
1087
  <BranchPickerPrimitive.Root
1071
1088
  hideWhenSingleBranch
1072
1089
  className={cn(
1073
- "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1090
+ "aui-branch-picker-root mr-2 -ml-2 inline-flex items-center text-muted-foreground text-xs",
1074
1091
  className,
1075
1092
  )}
1076
1093
  {...rest}
@@ -1097,98 +1114,329 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1097
1114
  ## components/assistant-ui/tool-fallback.tsx
1098
1115
 
1099
1116
  ```tsx
1100
- import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
1117
+ "use client";
1118
+
1119
+ import { memo, useCallback, useRef, useState } from "react";
1101
1120
  import {
1121
+ AlertCircleIcon,
1102
1122
  CheckIcon,
1103
1123
  ChevronDownIcon,
1104
- ChevronUpIcon,
1124
+ LoaderIcon,
1105
1125
  XCircleIcon,
1106
1126
  } from "lucide-react";
1107
- import { useState } from "react";
1108
- import { Button } from "@/components/ui/button";
1127
+ import {
1128
+ useScrollLock,
1129
+ type ToolCallMessagePartStatus,
1130
+ type ToolCallMessagePartComponent,
1131
+ } from "@assistant-ui/react";
1132
+ import {
1133
+ Collapsible,
1134
+ CollapsibleContent,
1135
+ CollapsibleTrigger,
1136
+ } from "@/components/ui/collapsible";
1109
1137
  import { cn } from "@/lib/utils";
1110
1138
 
1111
- export const ToolFallback: ToolCallMessagePartComponent = ({
1139
+ const ANIMATION_DURATION = 200;
1140
+
1141
+ export type ToolFallbackRootProps = Omit<
1142
+ React.ComponentProps<typeof Collapsible>,
1143
+ "open" | "onOpenChange"
1144
+ > & {
1145
+ open?: boolean;
1146
+ onOpenChange?: (open: boolean) => void;
1147
+ defaultOpen?: boolean;
1148
+ };
1149
+
1150
+ function ToolFallbackRoot({
1151
+ className,
1152
+ open: controlledOpen,
1153
+ onOpenChange: controlledOnOpenChange,
1154
+ defaultOpen = false,
1155
+ children,
1156
+ ...props
1157
+ }: ToolFallbackRootProps) {
1158
+ const collapsibleRef = useRef<HTMLDivElement>(null);
1159
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
1160
+ const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
1161
+
1162
+ const isControlled = controlledOpen !== undefined;
1163
+ const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1164
+
1165
+ const handleOpenChange = useCallback(
1166
+ (open: boolean) => {
1167
+ if (!open) {
1168
+ lockScroll();
1169
+ }
1170
+ if (!isControlled) {
1171
+ setUncontrolledOpen(open);
1172
+ }
1173
+ controlledOnOpenChange?.(open);
1174
+ },
1175
+ [lockScroll, isControlled, controlledOnOpenChange],
1176
+ );
1177
+
1178
+ return (
1179
+ <Collapsible
1180
+ ref={collapsibleRef}
1181
+ data-slot="tool-fallback-root"
1182
+ open={isOpen}
1183
+ onOpenChange={handleOpenChange}
1184
+ className={cn(
1185
+ "aui-tool-fallback-root group/tool-fallback-root w-full rounded-lg border py-3",
1186
+ className,
1187
+ )}
1188
+ style={
1189
+ {
1190
+ "--animation-duration": `${ANIMATION_DURATION}ms`,
1191
+ } as React.CSSProperties
1192
+ }
1193
+ {...props}
1194
+ >
1195
+ {children}
1196
+ </Collapsible>
1197
+ );
1198
+ }
1199
+
1200
+ type ToolStatus = ToolCallMessagePartStatus["type"];
1201
+
1202
+ const statusIconMap: Record<ToolStatus, React.ElementType> = {
1203
+ running: LoaderIcon,
1204
+ complete: CheckIcon,
1205
+ incomplete: XCircleIcon,
1206
+ "requires-action": AlertCircleIcon,
1207
+ };
1208
+
1209
+ function ToolFallbackTrigger({
1112
1210
  toolName,
1113
- argsText,
1114
- result,
1115
1211
  status,
1116
- }) => {
1117
- const [isCollapsed, setIsCollapsed] = useState(true);
1118
-
1212
+ className,
1213
+ ...props
1214
+ }: React.ComponentProps<typeof CollapsibleTrigger> & {
1215
+ toolName: string;
1216
+ status?: ToolCallMessagePartStatus;
1217
+ }) {
1218
+ const statusType = status?.type ?? "complete";
1219
+ const isRunning = statusType === "running";
1119
1220
  const isCancelled =
1120
1221
  status?.type === "incomplete" && status.reason === "cancelled";
1121
- const cancelledReason =
1122
- isCancelled && status.error
1123
- ? typeof status.error === "string"
1124
- ? status.error
1125
- : JSON.stringify(status.error)
1126
- : null;
1222
+
1223
+ const Icon = statusIconMap[statusType];
1224
+ const label = isCancelled ? "Cancelled tool" : "Used tool";
1127
1225
 
1128
1226
  return (
1129
- <div
1227
+ <CollapsibleTrigger
1228
+ data-slot="tool-fallback-trigger"
1130
1229
  className={cn(
1131
- "aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
1132
- isCancelled && "border-muted-foreground/30 bg-muted/30",
1230
+ "aui-tool-fallback-trigger group/trigger flex w-full items-center gap-2 px-4 text-sm transition-colors",
1231
+ className,
1133
1232
  )}
1233
+ {...props}
1134
1234
  >
1135
- <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1136
- {isCancelled ? (
1137
- <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1138
- ) : (
1139
- <CheckIcon className="aui-tool-fallback-icon size-4" />
1235
+ <Icon
1236
+ data-slot="tool-fallback-trigger-icon"
1237
+ className={cn(
1238
+ "aui-tool-fallback-trigger-icon size-4 shrink-0",
1239
+ isCancelled && "text-muted-foreground",
1240
+ isRunning && "animate-spin",
1140
1241
  )}
1141
- <p
1142
- className={cn(
1143
- "aui-tool-fallback-title grow",
1144
- isCancelled && "text-muted-foreground line-through",
1145
- )}
1146
- >
1147
- {isCancelled ? "Cancelled tool: " : "Used tool: "}
1148
- <b>{toolName}</b>
1149
- </p>
1150
- <Button onClick={() => setIsCollapsed(!isCollapsed)}>
1151
- {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
1152
- </Button>
1153
- </div>
1154
- {!isCollapsed && (
1155
- <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1156
- {cancelledReason && (
1157
- <div className="aui-tool-fallback-cancelled-root px-4">
1158
- <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1159
- Cancelled reason:
1160
- </p>
1161
- <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
1162
- {cancelledReason}
1163
- </p>
1164
- </div>
1165
- )}
1166
- <div
1167
- className={cn(
1168
- "aui-tool-fallback-args-root px-4",
1169
- isCancelled && "opacity-60",
1170
- )}
1242
+ />
1243
+ <span
1244
+ data-slot="tool-fallback-trigger-label"
1245
+ className={cn(
1246
+ "aui-tool-fallback-trigger-label-wrapper relative inline-block grow text-left leading-none",
1247
+ isCancelled && "text-muted-foreground line-through",
1248
+ )}
1249
+ >
1250
+ <span>
1251
+ {label}: <b>{toolName}</b>
1252
+ </span>
1253
+ {isRunning && (
1254
+ <span
1255
+ aria-hidden
1256
+ data-slot="tool-fallback-trigger-shimmer"
1257
+ className="aui-tool-fallback-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none"
1171
1258
  >
1172
- <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1173
- {argsText}
1174
- </pre>
1175
- </div>
1176
- {!isCancelled && result !== undefined && (
1177
- <div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
1178
- <p className="aui-tool-fallback-result-header font-semibold">
1179
- Result:
1180
- </p>
1181
- <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1182
- {typeof result === "string"
1183
- ? result
1184
- : JSON.stringify(result, null, 2)}
1185
- </pre>
1186
- </div>
1187
- )}
1188
- </div>
1259
+ {label}: <b>{toolName}</b>
1260
+ </span>
1261
+ )}
1262
+ </span>
1263
+ <ChevronDownIcon
1264
+ data-slot="tool-fallback-trigger-chevron"
1265
+ className={cn(
1266
+ "aui-tool-fallback-trigger-chevron size-4 shrink-0",
1267
+ "transition-transform duration-(--animation-duration) ease-out",
1268
+ "group-data-[state=closed]/trigger:-rotate-90",
1269
+ "group-data-[state=open]/trigger:rotate-0",
1270
+ )}
1271
+ />
1272
+ </CollapsibleTrigger>
1273
+ );
1274
+ }
1275
+
1276
+ function ToolFallbackContent({
1277
+ className,
1278
+ children,
1279
+ ...props
1280
+ }: React.ComponentProps<typeof CollapsibleContent>) {
1281
+ return (
1282
+ <CollapsibleContent
1283
+ data-slot="tool-fallback-content"
1284
+ className={cn(
1285
+ "aui-tool-fallback-content relative overflow-hidden text-sm outline-none",
1286
+ "group/collapsible-content ease-out",
1287
+ "data-[state=closed]:animate-collapsible-up",
1288
+ "data-[state=open]:animate-collapsible-down",
1289
+ "data-[state=closed]:fill-mode-forwards",
1290
+ "data-[state=closed]:pointer-events-none",
1291
+ "data-[state=open]:duration-(--animation-duration)",
1292
+ "data-[state=closed]:duration-(--animation-duration)",
1293
+ className,
1189
1294
  )}
1295
+ {...props}
1296
+ >
1297
+ <div className="mt-3 flex flex-col gap-2 border-t pt-2">{children}</div>
1298
+ </CollapsibleContent>
1299
+ );
1300
+ }
1301
+
1302
+ function ToolFallbackArgs({
1303
+ argsText,
1304
+ className,
1305
+ ...props
1306
+ }: React.ComponentProps<"div"> & {
1307
+ argsText?: string;
1308
+ }) {
1309
+ if (!argsText) return null;
1310
+
1311
+ return (
1312
+ <div
1313
+ data-slot="tool-fallback-args"
1314
+ className={cn("aui-tool-fallback-args px-4", className)}
1315
+ {...props}
1316
+ >
1317
+ <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1318
+ {argsText}
1319
+ </pre>
1320
+ </div>
1321
+ );
1322
+ }
1323
+
1324
+ function ToolFallbackResult({
1325
+ result,
1326
+ className,
1327
+ ...props
1328
+ }: React.ComponentProps<"div"> & {
1329
+ result?: unknown;
1330
+ }) {
1331
+ if (result === undefined) return null;
1332
+
1333
+ return (
1334
+ <div
1335
+ data-slot="tool-fallback-result"
1336
+ className={cn(
1337
+ "aui-tool-fallback-result border-t border-dashed px-4 pt-2",
1338
+ className,
1339
+ )}
1340
+ {...props}
1341
+ >
1342
+ <p className="aui-tool-fallback-result-header font-semibold">Result:</p>
1343
+ <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1344
+ {typeof result === "string" ? result : JSON.stringify(result, null, 2)}
1345
+ </pre>
1346
+ </div>
1347
+ );
1348
+ }
1349
+
1350
+ function ToolFallbackError({
1351
+ status,
1352
+ className,
1353
+ ...props
1354
+ }: React.ComponentProps<"div"> & {
1355
+ status?: ToolCallMessagePartStatus;
1356
+ }) {
1357
+ if (status?.type !== "incomplete") return null;
1358
+
1359
+ const error = status.error;
1360
+ const errorText = error
1361
+ ? typeof error === "string"
1362
+ ? error
1363
+ : JSON.stringify(error)
1364
+ : null;
1365
+
1366
+ if (!errorText) return null;
1367
+
1368
+ const isCancelled = status.reason === "cancelled";
1369
+ const headerText = isCancelled ? "Cancelled reason:" : "Error:";
1370
+
1371
+ return (
1372
+ <div
1373
+ data-slot="tool-fallback-error"
1374
+ className={cn("aui-tool-fallback-error px-4", className)}
1375
+ {...props}
1376
+ >
1377
+ <p className="aui-tool-fallback-error-header font-semibold text-muted-foreground">
1378
+ {headerText}
1379
+ </p>
1380
+ <p className="aui-tool-fallback-error-reason text-muted-foreground">
1381
+ {errorText}
1382
+ </p>
1190
1383
  </div>
1191
1384
  );
1385
+ }
1386
+
1387
+ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1388
+ toolName,
1389
+ argsText,
1390
+ result,
1391
+ status,
1392
+ }) => {
1393
+ const isCancelled =
1394
+ status?.type === "incomplete" && status.reason === "cancelled";
1395
+
1396
+ return (
1397
+ <ToolFallbackRoot
1398
+ className={cn(isCancelled && "border-muted-foreground/30 bg-muted/30")}
1399
+ >
1400
+ <ToolFallbackTrigger toolName={toolName} status={status} />
1401
+ <ToolFallbackContent>
1402
+ <ToolFallbackError status={status} />
1403
+ <ToolFallbackArgs
1404
+ argsText={argsText}
1405
+ className={cn(isCancelled && "opacity-60")}
1406
+ />
1407
+ {!isCancelled && <ToolFallbackResult result={result} />}
1408
+ </ToolFallbackContent>
1409
+ </ToolFallbackRoot>
1410
+ );
1411
+ };
1412
+
1413
+ const ToolFallback = memo(
1414
+ ToolFallbackImpl,
1415
+ ) as unknown as ToolCallMessagePartComponent & {
1416
+ Root: typeof ToolFallbackRoot;
1417
+ Trigger: typeof ToolFallbackTrigger;
1418
+ Content: typeof ToolFallbackContent;
1419
+ Args: typeof ToolFallbackArgs;
1420
+ Result: typeof ToolFallbackResult;
1421
+ Error: typeof ToolFallbackError;
1422
+ };
1423
+
1424
+ ToolFallback.displayName = "ToolFallback";
1425
+ ToolFallback.Root = ToolFallbackRoot;
1426
+ ToolFallback.Trigger = ToolFallbackTrigger;
1427
+ ToolFallback.Content = ToolFallbackContent;
1428
+ ToolFallback.Args = ToolFallbackArgs;
1429
+ ToolFallback.Result = ToolFallbackResult;
1430
+ ToolFallback.Error = ToolFallbackError;
1431
+
1432
+ export {
1433
+ ToolFallback,
1434
+ ToolFallbackRoot,
1435
+ ToolFallbackTrigger,
1436
+ ToolFallbackContent,
1437
+ ToolFallbackArgs,
1438
+ ToolFallbackResult,
1439
+ ToolFallbackError,
1192
1440
  };
1193
1441
 
1194
1442
  ```
@@ -1251,47 +1499,50 @@ import * as AvatarPrimitive from "@radix-ui/react-avatar";
1251
1499
 
1252
1500
  import { cn } from "@/lib/utils";
1253
1501
 
1254
- const Avatar = React.forwardRef<
1255
- React.ElementRef<typeof AvatarPrimitive.Root>,
1256
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
1257
- >(({ className, ...props }, ref) => (
1258
- <AvatarPrimitive.Root
1259
- ref={ref}
1260
- className={cn(
1261
- "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
1262
- className,
1263
- )}
1264
- {...props}
1265
- />
1266
- ));
1267
- Avatar.displayName = AvatarPrimitive.Root.displayName;
1268
-
1269
- const AvatarImage = React.forwardRef<
1270
- React.ElementRef<typeof AvatarPrimitive.Image>,
1271
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
1272
- >(({ className, ...props }, ref) => (
1273
- <AvatarPrimitive.Image
1274
- ref={ref}
1275
- className={cn("aspect-square h-full w-full", className)}
1276
- {...props}
1277
- />
1278
- ));
1279
- AvatarImage.displayName = AvatarPrimitive.Image.displayName;
1280
-
1281
- const AvatarFallback = React.forwardRef<
1282
- React.ElementRef<typeof AvatarPrimitive.Fallback>,
1283
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
1284
- >(({ className, ...props }, ref) => (
1285
- <AvatarPrimitive.Fallback
1286
- ref={ref}
1287
- className={cn(
1288
- "flex h-full w-full items-center justify-center rounded-full bg-muted",
1289
- className,
1290
- )}
1291
- {...props}
1292
- />
1293
- ));
1294
- AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
1502
+ function Avatar({
1503
+ className,
1504
+ ...props
1505
+ }: React.ComponentProps<typeof AvatarPrimitive.Root>) {
1506
+ return (
1507
+ <AvatarPrimitive.Root
1508
+ data-slot="avatar"
1509
+ className={cn(
1510
+ "relative flex size-8 shrink-0 overflow-hidden rounded-full",
1511
+ className,
1512
+ )}
1513
+ {...props}
1514
+ />
1515
+ );
1516
+ }
1517
+
1518
+ function AvatarImage({
1519
+ className,
1520
+ ...props
1521
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
1522
+ return (
1523
+ <AvatarPrimitive.Image
1524
+ data-slot="avatar-image"
1525
+ className={cn("aspect-square size-full", className)}
1526
+ {...props}
1527
+ />
1528
+ );
1529
+ }
1530
+
1531
+ function AvatarFallback({
1532
+ className,
1533
+ ...props
1534
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
1535
+ return (
1536
+ <AvatarPrimitive.Fallback
1537
+ data-slot="avatar-fallback"
1538
+ className={cn(
1539
+ "flex size-full items-center justify-center rounded-full bg-muted",
1540
+ className,
1541
+ )}
1542
+ {...props}
1543
+ />
1544
+ );
1545
+ }
1295
1546
 
1296
1547
  export { Avatar, AvatarImage, AvatarFallback };
1297
1548
 
@@ -1300,8 +1551,6 @@ export { Avatar, AvatarImage, AvatarFallback };
1300
1551
  ## components/ui/button.tsx
1301
1552
 
1302
1553
  ```tsx
1303
- "use client";
1304
-
1305
1554
  import * as React from "react";
1306
1555
  import { Slot } from "@radix-ui/react-slot";
1307
1556
  import { cva, type VariantProps } from "class-variance-authority";
@@ -1309,26 +1558,28 @@ import { cva, type VariantProps } from "class-variance-authority";
1309
1558
  import { cn } from "@/lib/utils";
1310
1559
 
1311
1560
  const buttonVariants = cva(
1312
- "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",
1561
+ "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",
1313
1562
  {
1314
1563
  variants: {
1315
1564
  variant: {
1316
- default:
1317
- "bg-primary text-primary-foreground shadow hover:bg-primary/90",
1565
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
1318
1566
  destructive:
1319
- "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
1567
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
1320
1568
  outline:
1321
- "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
1569
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
1322
1570
  secondary:
1323
- "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
1324
- ghost: "hover:bg-accent hover:text-accent-foreground",
1571
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
1572
+ ghost:
1573
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
1325
1574
  link: "text-primary underline-offset-4 hover:underline",
1326
1575
  },
1327
1576
  size: {
1328
- default: "h-9 px-4 py-2",
1329
- sm: "h-8 rounded-md px-3 text-xs",
1330
- lg: "h-10 rounded-md px-8",
1331
- icon: "h-9 w-9",
1577
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
1578
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
1579
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
1580
+ icon: "size-9",
1581
+ "icon-sm": "size-8",
1582
+ "icon-lg": "size-10",
1332
1583
  },
1333
1584
  },
1334
1585
  defaultVariants: {
@@ -1338,30 +1589,72 @@ const buttonVariants = cva(
1338
1589
  },
1339
1590
  );
1340
1591
 
1341
- export interface ButtonProps
1342
- extends React.ButtonHTMLAttributes<HTMLButtonElement>,
1343
- VariantProps<typeof buttonVariants> {
1344
- asChild?: boolean;
1345
- }
1592
+ function Button({
1593
+ className,
1594
+ variant = "default",
1595
+ size = "default",
1596
+ asChild = false,
1597
+ ...props
1598
+ }: React.ComponentProps<"button"> &
1599
+ VariantProps<typeof buttonVariants> & {
1600
+ asChild?: boolean;
1601
+ }) {
1602
+ const Comp = asChild ? Slot : "button";
1346
1603
 
1347
- const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
1348
- ({ className, variant, size, asChild = false, ...props }, ref) => {
1349
- const Comp = asChild ? Slot : "button";
1350
- return (
1351
- <Comp
1352
- className={cn(buttonVariants({ variant, size, className }))}
1353
- ref={ref}
1354
- {...props}
1355
- />
1356
- );
1357
- },
1358
- );
1359
- Button.displayName = "Button";
1604
+ return (
1605
+ <Comp
1606
+ data-slot="button"
1607
+ data-variant={variant}
1608
+ data-size={size}
1609
+ className={cn(buttonVariants({ variant, size, className }))}
1610
+ {...props}
1611
+ />
1612
+ );
1613
+ }
1360
1614
 
1361
1615
  export { Button, buttonVariants };
1362
1616
 
1363
1617
  ```
1364
1618
 
1619
+ ## components/ui/collapsible.tsx
1620
+
1621
+ ```tsx
1622
+ "use client";
1623
+
1624
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
1625
+
1626
+ function Collapsible({
1627
+ ...props
1628
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
1629
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
1630
+ }
1631
+
1632
+ function CollapsibleTrigger({
1633
+ ...props
1634
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
1635
+ return (
1636
+ <CollapsiblePrimitive.CollapsibleTrigger
1637
+ data-slot="collapsible-trigger"
1638
+ {...props}
1639
+ />
1640
+ );
1641
+ }
1642
+
1643
+ function CollapsibleContent({
1644
+ ...props
1645
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
1646
+ return (
1647
+ <CollapsiblePrimitive.CollapsibleContent
1648
+ data-slot="collapsible-content"
1649
+ {...props}
1650
+ />
1651
+ );
1652
+ }
1653
+
1654
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent };
1655
+
1656
+ ```
1657
+
1365
1658
  ## components/ui/dialog.tsx
1366
1659
 
1367
1660
  ```tsx
@@ -1405,7 +1698,7 @@ function DialogOverlay({
1405
1698
  <DialogPrimitive.Overlay
1406
1699
  data-slot="dialog-overlay"
1407
1700
  className={cn(
1408
- "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",
1701
+ "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",
1409
1702
  className,
1410
1703
  )}
1411
1704
  {...props}
@@ -1416,24 +1709,32 @@ function DialogOverlay({
1416
1709
  function DialogContent({
1417
1710
  className,
1418
1711
  children,
1712
+ showCloseButton = true,
1419
1713
  ...props
1420
- }: React.ComponentProps<typeof DialogPrimitive.Content>) {
1714
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
1715
+ showCloseButton?: boolean;
1716
+ }) {
1421
1717
  return (
1422
1718
  <DialogPortal data-slot="dialog-portal">
1423
1719
  <DialogOverlay />
1424
1720
  <DialogPrimitive.Content
1425
1721
  data-slot="dialog-content"
1426
1722
  className={cn(
1427
- "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",
1723
+ "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",
1428
1724
  className,
1429
1725
  )}
1430
1726
  {...props}
1431
1727
  >
1432
1728
  {children}
1433
- <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">
1434
- <XIcon />
1435
- <span className="sr-only">Close</span>
1436
- </DialogPrimitive.Close>
1729
+ {showCloseButton && (
1730
+ <DialogPrimitive.Close
1731
+ data-slot="dialog-close"
1732
+ 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"
1733
+ >
1734
+ <XIcon />
1735
+ <span className="sr-only">Close</span>
1736
+ </DialogPrimitive.Close>
1737
+ )}
1437
1738
  </DialogPrimitive.Content>
1438
1739
  </DialogPortal>
1439
1740
  );
@@ -1554,13 +1855,13 @@ function TooltipContent({
1554
1855
  data-slot="tooltip-content"
1555
1856
  sideOffset={sideOffset}
1556
1857
  className={cn(
1557
- "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",
1858
+ "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",
1558
1859
  className,
1559
1860
  )}
1560
1861
  {...props}
1561
1862
  >
1562
1863
  {children}
1563
- <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
1864
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
1564
1865
  </TooltipPrimitive.Content>
1565
1866
  </TooltipPrimitive.Portal>
1566
1867
  );
@@ -1600,40 +1901,43 @@ export default nextConfig;
1600
1901
  ```json
1601
1902
  {
1602
1903
  "name": "with-external-store",
1603
- "version": "0.1.0",
1904
+ "version": "0.0.0",
1604
1905
  "private": true,
1906
+ "type": "module",
1605
1907
  "scripts": {
1606
- "dev": "next dev --turbo",
1908
+ "dev": "next dev",
1607
1909
  "build": "next build",
1608
1910
  "start": "next start"
1609
1911
  },
1610
1912
  "dependencies": {
1611
- "@ai-sdk/openai": "^2.0.84",
1913
+ "@ai-sdk/openai": "^3.0.13",
1612
1914
  "@assistant-ui/react": "workspace:*",
1613
1915
  "@assistant-ui/react-markdown": "workspace:*",
1614
1916
  "@radix-ui/react-avatar": "^1.1.11",
1917
+ "@radix-ui/react-collapsible": "^1.1.12",
1615
1918
  "@radix-ui/react-dialog": "^1.1.15",
1616
1919
  "@radix-ui/react-slot": "^1.2.4",
1617
1920
  "@radix-ui/react-tooltip": "^1.2.8",
1618
1921
  "class-variance-authority": "^0.7.1",
1619
1922
  "clsx": "^2.1.1",
1620
- "lucide-react": "^0.560.0",
1621
- "next": "16.0.10",
1622
- "react": "19.2.3",
1623
- "react-dom": "19.2.3",
1923
+ "lucide-react": "^0.562.0",
1924
+ "next": "^16.1.4",
1925
+ "react": "^19.2.3",
1926
+ "react-dom": "^19.2.3",
1624
1927
  "remark-gfm": "^4.0.1",
1625
1928
  "tailwind-merge": "^3.4.0",
1626
- "tw-animate-css": "^1.4.0",
1627
- "zustand": "^5.0.9"
1929
+ "zustand": "^5.0.10"
1628
1930
  },
1629
1931
  "devDependencies": {
1630
1932
  "@assistant-ui/x-buildutils": "workspace:*",
1631
- "@types/node": "^25",
1632
- "@types/react": "^19",
1633
- "@types/react-dom": "^19",
1634
- "postcss": "^8",
1933
+ "@tailwindcss/postcss": "^4.1.18",
1934
+ "@types/node": "^25.0.9",
1935
+ "@types/react": "^19.2.9",
1936
+ "@types/react-dom": "^19.2.3",
1937
+ "postcss": "^8.5.6",
1635
1938
  "tailwindcss": "^4.1.18",
1636
- "typescript": "^5"
1939
+ "tw-animate-css": "^1.4.0",
1940
+ "typescript": "^5.9.3"
1637
1941
  }
1638
1942
  }
1639
1943
 
@@ -1643,29 +1947,11 @@ export default nextConfig;
1643
1947
 
1644
1948
  ```json
1645
1949
  {
1646
- "extends": "@assistant-ui/x-buildutils/ts/base",
1950
+ "extends": "@assistant-ui/x-buildutils/ts/next",
1647
1951
  "compilerOptions": {
1648
- "target": "ES6",
1649
- "module": "ESNext",
1650
- "incremental": true,
1651
- "plugins": [
1652
- {
1653
- "name": "next"
1654
- }
1655
- ],
1656
- "allowJs": true,
1657
- "strictNullChecks": true,
1658
- "jsx": "preserve",
1659
- "paths": {
1660
- "@/*": ["./*"],
1661
- "@assistant-ui/*": ["../../packages/*/src"],
1662
- "@assistant-ui/react/*": ["../../packages/react/src/*"],
1663
- "@assistant-ui/tap/*": ["../../packages/tap/src/*"],
1664
- "assistant-stream": ["../../packages/assistant-stream/src"],
1665
- "assistant-stream/*": ["../../packages/assistant-stream/src/*"]
1666
- }
1952
+ "paths": { "@/*": ["./*"] }
1667
1953
  },
1668
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
1954
+ "include": ["**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
1669
1955
  "exclude": ["node_modules"]
1670
1956
  }
1671
1957