@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
@@ -14,7 +14,7 @@ export async function POST(req: Request) {
14
14
 
15
15
  const result = streamText({
16
16
  model: openai("gpt-4o"),
17
- messages: convertToModelMessages(messages),
17
+ messages: await convertToModelMessages(messages),
18
18
  system,
19
19
  tools: {
20
20
  ...frontendTools(tools),
@@ -36,43 +36,41 @@ export async function POST(req: Request) {
36
36
  @custom-variant dark (&:is(.dark *));
37
37
 
38
38
  @theme inline {
39
- --color-background: var(--background);
40
- --color-foreground: var(--foreground);
41
- --font-sans: var(--font-geist-sans);
42
- --font-mono: var(--font-geist-mono);
43
- --color-sidebar-ring: var(--sidebar-ring);
44
- --color-sidebar-border: var(--sidebar-border);
45
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
46
- --color-sidebar-accent: var(--sidebar-accent);
47
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
48
- --color-sidebar-primary: var(--sidebar-primary);
49
- --color-sidebar-foreground: var(--sidebar-foreground);
50
- --color-sidebar: var(--sidebar);
51
- --color-chart-5: var(--chart-5);
52
- --color-chart-4: var(--chart-4);
53
- --color-chart-3: var(--chart-3);
54
- --color-chart-2: var(--chart-2);
55
- --color-chart-1: var(--chart-1);
56
- --color-ring: var(--ring);
57
- --color-input: var(--input);
58
- --color-border: var(--border);
59
- --color-destructive: var(--destructive);
60
- --color-accent-foreground: var(--accent-foreground);
61
- --color-accent: var(--accent);
62
- --color-muted-foreground: var(--muted-foreground);
63
- --color-muted: var(--muted);
64
- --color-secondary-foreground: var(--secondary-foreground);
65
- --color-secondary: var(--secondary);
66
- --color-primary-foreground: var(--primary-foreground);
67
- --color-primary: var(--primary);
68
- --color-popover-foreground: var(--popover-foreground);
69
- --color-popover: var(--popover);
70
- --color-card-foreground: var(--card-foreground);
71
- --color-card: var(--card);
72
39
  --radius-sm: calc(var(--radius) - 4px);
73
40
  --radius-md: calc(var(--radius) - 2px);
74
41
  --radius-lg: var(--radius);
75
42
  --radius-xl: calc(var(--radius) + 4px);
43
+ --color-background: var(--background);
44
+ --color-foreground: var(--foreground);
45
+ --color-card: var(--card);
46
+ --color-card-foreground: var(--card-foreground);
47
+ --color-popover: var(--popover);
48
+ --color-popover-foreground: var(--popover-foreground);
49
+ --color-primary: var(--primary);
50
+ --color-primary-foreground: var(--primary-foreground);
51
+ --color-secondary: var(--secondary);
52
+ --color-secondary-foreground: var(--secondary-foreground);
53
+ --color-muted: var(--muted);
54
+ --color-muted-foreground: var(--muted-foreground);
55
+ --color-accent: var(--accent);
56
+ --color-accent-foreground: var(--accent-foreground);
57
+ --color-destructive: var(--destructive);
58
+ --color-border: var(--border);
59
+ --color-input: var(--input);
60
+ --color-ring: var(--ring);
61
+ --color-chart-1: var(--chart-1);
62
+ --color-chart-2: var(--chart-2);
63
+ --color-chart-3: var(--chart-3);
64
+ --color-chart-4: var(--chart-4);
65
+ --color-chart-5: var(--chart-5);
66
+ --color-sidebar: var(--sidebar);
67
+ --color-sidebar-foreground: var(--sidebar-foreground);
68
+ --color-sidebar-primary: var(--sidebar-primary);
69
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
70
+ --color-sidebar-accent: var(--sidebar-accent);
71
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
72
+ --color-sidebar-border: var(--sidebar-border);
73
+ --color-sidebar-ring: var(--sidebar-ring);
76
74
  }
77
75
 
78
76
  :root {
@@ -465,8 +463,12 @@ export default function Home() {
465
463
  },
466
464
  "aliases": {
467
465
  "components": "@/components",
468
- "utils": "@/lib/utils"
469
- }
466
+ "utils": "@/lib/utils",
467
+ "ui": "@/components/ui",
468
+ "lib": "@/lib",
469
+ "hooks": "@/hooks"
470
+ },
471
+ "iconLibrary": "lucide"
470
472
  }
471
473
 
472
474
  ```
@@ -701,7 +703,7 @@ export const ComposerAddAttachment: FC = () => {
701
703
  side="bottom"
702
704
  variant="ghost"
703
705
  size="icon"
704
- 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"
706
+ 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"
705
707
  aria-label="Add Attachment"
706
708
  >
707
709
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -960,6 +962,7 @@ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button
960
962
  import { Button } from "@/components/ui/button";
961
963
  import { cn } from "@/lib/utils";
962
964
  import {
965
+ ActionBarMorePrimitive,
963
966
  ActionBarPrimitive,
964
967
  AssistantIf,
965
968
  BranchPickerPrimitive,
@@ -976,6 +979,7 @@ import {
976
979
  ChevronRightIcon,
977
980
  CopyIcon,
978
981
  DownloadIcon,
982
+ MoreHorizontalIcon,
979
983
  PencilIcon,
980
984
  RefreshCwIcon,
981
985
  SquareIcon,
@@ -1021,7 +1025,7 @@ const ThreadScrollToBottom: FC = () => {
1021
1025
  <TooltipIconButton
1022
1026
  tooltip="Scroll to bottom"
1023
1027
  variant="outline"
1024
- 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"
1028
+ 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"
1025
1029
  >
1026
1030
  <ArrowDownIcon />
1027
1031
  </TooltipIconButton>
@@ -1185,7 +1189,7 @@ const AssistantActionBar: FC = () => {
1185
1189
  hideWhenRunning
1186
1190
  autohide="not-last"
1187
1191
  autohideFloat="single-branch"
1188
- 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"
1192
+ 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"
1189
1193
  >
1190
1194
  <ActionBarPrimitive.Copy asChild>
1191
1195
  <TooltipIconButton tooltip="Copy">
@@ -1197,16 +1201,33 @@ const AssistantActionBar: FC = () => {
1197
1201
  </AssistantIf>
1198
1202
  </TooltipIconButton>
1199
1203
  </ActionBarPrimitive.Copy>
1200
- <ActionBarPrimitive.ExportMarkdown asChild>
1201
- <TooltipIconButton tooltip="Export as Markdown">
1202
- <DownloadIcon />
1203
- </TooltipIconButton>
1204
- </ActionBarPrimitive.ExportMarkdown>
1205
1204
  <ActionBarPrimitive.Reload asChild>
1206
1205
  <TooltipIconButton tooltip="Refresh">
1207
1206
  <RefreshCwIcon />
1208
1207
  </TooltipIconButton>
1209
1208
  </ActionBarPrimitive.Reload>
1209
+ <ActionBarMorePrimitive.Root>
1210
+ <ActionBarMorePrimitive.Trigger asChild>
1211
+ <TooltipIconButton
1212
+ tooltip="More"
1213
+ className="data-[state=open]:bg-accent"
1214
+ >
1215
+ <MoreHorizontalIcon />
1216
+ </TooltipIconButton>
1217
+ </ActionBarMorePrimitive.Trigger>
1218
+ <ActionBarMorePrimitive.Content
1219
+ side="bottom"
1220
+ align="start"
1221
+ 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"
1222
+ >
1223
+ <ActionBarPrimitive.ExportMarkdown asChild>
1224
+ <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">
1225
+ <DownloadIcon className="size-4" />
1226
+ Export as Markdown
1227
+ </ActionBarMorePrimitive.Item>
1228
+ </ActionBarPrimitive.ExportMarkdown>
1229
+ </ActionBarMorePrimitive.Content>
1230
+ </ActionBarMorePrimitive.Root>
1210
1231
  </ActionBarPrimitive.Root>
1211
1232
  );
1212
1233
  };
@@ -1223,12 +1244,12 @@ const UserMessage: FC = () => {
1223
1244
  <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
1224
1245
  <MessagePrimitive.Parts />
1225
1246
  </div>
1226
- <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1247
+ <div className="aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2">
1227
1248
  <UserActionBar />
1228
1249
  </div>
1229
1250
  </div>
1230
1251
 
1231
- <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
1252
+ <BranchPicker className="aui-user-branch-picker col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
1232
1253
  </MessagePrimitive.Root>
1233
1254
  );
1234
1255
  };
@@ -1280,7 +1301,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1280
1301
  <BranchPickerPrimitive.Root
1281
1302
  hideWhenSingleBranch
1282
1303
  className={cn(
1283
- "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1304
+ "aui-branch-picker-root mr-2 -ml-2 inline-flex items-center text-muted-foreground text-xs",
1284
1305
  className,
1285
1306
  )}
1286
1307
  {...rest}
@@ -1307,98 +1328,329 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1307
1328
  ## components/assistant-ui/tool-fallback.tsx
1308
1329
 
1309
1330
  ```tsx
1310
- import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
1331
+ "use client";
1332
+
1333
+ import { memo, useCallback, useRef, useState } from "react";
1311
1334
  import {
1335
+ AlertCircleIcon,
1312
1336
  CheckIcon,
1313
1337
  ChevronDownIcon,
1314
- ChevronUpIcon,
1338
+ LoaderIcon,
1315
1339
  XCircleIcon,
1316
1340
  } from "lucide-react";
1317
- import { useState } from "react";
1318
- import { Button } from "@/components/ui/button";
1341
+ import {
1342
+ useScrollLock,
1343
+ type ToolCallMessagePartStatus,
1344
+ type ToolCallMessagePartComponent,
1345
+ } from "@assistant-ui/react";
1346
+ import {
1347
+ Collapsible,
1348
+ CollapsibleContent,
1349
+ CollapsibleTrigger,
1350
+ } from "@/components/ui/collapsible";
1319
1351
  import { cn } from "@/lib/utils";
1320
1352
 
1321
- export const ToolFallback: ToolCallMessagePartComponent = ({
1353
+ const ANIMATION_DURATION = 200;
1354
+
1355
+ export type ToolFallbackRootProps = Omit<
1356
+ React.ComponentProps<typeof Collapsible>,
1357
+ "open" | "onOpenChange"
1358
+ > & {
1359
+ open?: boolean;
1360
+ onOpenChange?: (open: boolean) => void;
1361
+ defaultOpen?: boolean;
1362
+ };
1363
+
1364
+ function ToolFallbackRoot({
1365
+ className,
1366
+ open: controlledOpen,
1367
+ onOpenChange: controlledOnOpenChange,
1368
+ defaultOpen = false,
1369
+ children,
1370
+ ...props
1371
+ }: ToolFallbackRootProps) {
1372
+ const collapsibleRef = useRef<HTMLDivElement>(null);
1373
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
1374
+ const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
1375
+
1376
+ const isControlled = controlledOpen !== undefined;
1377
+ const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1378
+
1379
+ const handleOpenChange = useCallback(
1380
+ (open: boolean) => {
1381
+ if (!open) {
1382
+ lockScroll();
1383
+ }
1384
+ if (!isControlled) {
1385
+ setUncontrolledOpen(open);
1386
+ }
1387
+ controlledOnOpenChange?.(open);
1388
+ },
1389
+ [lockScroll, isControlled, controlledOnOpenChange],
1390
+ );
1391
+
1392
+ return (
1393
+ <Collapsible
1394
+ ref={collapsibleRef}
1395
+ data-slot="tool-fallback-root"
1396
+ open={isOpen}
1397
+ onOpenChange={handleOpenChange}
1398
+ className={cn(
1399
+ "aui-tool-fallback-root group/tool-fallback-root w-full rounded-lg border py-3",
1400
+ className,
1401
+ )}
1402
+ style={
1403
+ {
1404
+ "--animation-duration": `${ANIMATION_DURATION}ms`,
1405
+ } as React.CSSProperties
1406
+ }
1407
+ {...props}
1408
+ >
1409
+ {children}
1410
+ </Collapsible>
1411
+ );
1412
+ }
1413
+
1414
+ type ToolStatus = ToolCallMessagePartStatus["type"];
1415
+
1416
+ const statusIconMap: Record<ToolStatus, React.ElementType> = {
1417
+ running: LoaderIcon,
1418
+ complete: CheckIcon,
1419
+ incomplete: XCircleIcon,
1420
+ "requires-action": AlertCircleIcon,
1421
+ };
1422
+
1423
+ function ToolFallbackTrigger({
1322
1424
  toolName,
1323
- argsText,
1324
- result,
1325
1425
  status,
1326
- }) => {
1327
- const [isCollapsed, setIsCollapsed] = useState(true);
1328
-
1426
+ className,
1427
+ ...props
1428
+ }: React.ComponentProps<typeof CollapsibleTrigger> & {
1429
+ toolName: string;
1430
+ status?: ToolCallMessagePartStatus;
1431
+ }) {
1432
+ const statusType = status?.type ?? "complete";
1433
+ const isRunning = statusType === "running";
1329
1434
  const isCancelled =
1330
1435
  status?.type === "incomplete" && status.reason === "cancelled";
1331
- const cancelledReason =
1332
- isCancelled && status.error
1333
- ? typeof status.error === "string"
1334
- ? status.error
1335
- : JSON.stringify(status.error)
1336
- : null;
1436
+
1437
+ const Icon = statusIconMap[statusType];
1438
+ const label = isCancelled ? "Cancelled tool" : "Used tool";
1337
1439
 
1338
1440
  return (
1339
- <div
1441
+ <CollapsibleTrigger
1442
+ data-slot="tool-fallback-trigger"
1340
1443
  className={cn(
1341
- "aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
1342
- isCancelled && "border-muted-foreground/30 bg-muted/30",
1444
+ "aui-tool-fallback-trigger group/trigger flex w-full items-center gap-2 px-4 text-sm transition-colors",
1445
+ className,
1343
1446
  )}
1447
+ {...props}
1344
1448
  >
1345
- <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1346
- {isCancelled ? (
1347
- <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1348
- ) : (
1349
- <CheckIcon className="aui-tool-fallback-icon size-4" />
1449
+ <Icon
1450
+ data-slot="tool-fallback-trigger-icon"
1451
+ className={cn(
1452
+ "aui-tool-fallback-trigger-icon size-4 shrink-0",
1453
+ isCancelled && "text-muted-foreground",
1454
+ isRunning && "animate-spin",
1350
1455
  )}
1351
- <p
1352
- className={cn(
1353
- "aui-tool-fallback-title grow",
1354
- isCancelled && "text-muted-foreground line-through",
1355
- )}
1356
- >
1357
- {isCancelled ? "Cancelled tool: " : "Used tool: "}
1358
- <b>{toolName}</b>
1359
- </p>
1360
- <Button onClick={() => setIsCollapsed(!isCollapsed)}>
1361
- {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
1362
- </Button>
1363
- </div>
1364
- {!isCollapsed && (
1365
- <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1366
- {cancelledReason && (
1367
- <div className="aui-tool-fallback-cancelled-root px-4">
1368
- <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1369
- Cancelled reason:
1370
- </p>
1371
- <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
1372
- {cancelledReason}
1373
- </p>
1374
- </div>
1375
- )}
1376
- <div
1377
- className={cn(
1378
- "aui-tool-fallback-args-root px-4",
1379
- isCancelled && "opacity-60",
1380
- )}
1456
+ />
1457
+ <span
1458
+ data-slot="tool-fallback-trigger-label"
1459
+ className={cn(
1460
+ "aui-tool-fallback-trigger-label-wrapper relative inline-block grow text-left leading-none",
1461
+ isCancelled && "text-muted-foreground line-through",
1462
+ )}
1463
+ >
1464
+ <span>
1465
+ {label}: <b>{toolName}</b>
1466
+ </span>
1467
+ {isRunning && (
1468
+ <span
1469
+ aria-hidden
1470
+ data-slot="tool-fallback-trigger-shimmer"
1471
+ className="aui-tool-fallback-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none"
1381
1472
  >
1382
- <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1383
- {argsText}
1384
- </pre>
1385
- </div>
1386
- {!isCancelled && result !== undefined && (
1387
- <div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
1388
- <p className="aui-tool-fallback-result-header font-semibold">
1389
- Result:
1390
- </p>
1391
- <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1392
- {typeof result === "string"
1393
- ? result
1394
- : JSON.stringify(result, null, 2)}
1395
- </pre>
1396
- </div>
1397
- )}
1398
- </div>
1473
+ {label}: <b>{toolName}</b>
1474
+ </span>
1475
+ )}
1476
+ </span>
1477
+ <ChevronDownIcon
1478
+ data-slot="tool-fallback-trigger-chevron"
1479
+ className={cn(
1480
+ "aui-tool-fallback-trigger-chevron size-4 shrink-0",
1481
+ "transition-transform duration-(--animation-duration) ease-out",
1482
+ "group-data-[state=closed]/trigger:-rotate-90",
1483
+ "group-data-[state=open]/trigger:rotate-0",
1484
+ )}
1485
+ />
1486
+ </CollapsibleTrigger>
1487
+ );
1488
+ }
1489
+
1490
+ function ToolFallbackContent({
1491
+ className,
1492
+ children,
1493
+ ...props
1494
+ }: React.ComponentProps<typeof CollapsibleContent>) {
1495
+ return (
1496
+ <CollapsibleContent
1497
+ data-slot="tool-fallback-content"
1498
+ className={cn(
1499
+ "aui-tool-fallback-content relative overflow-hidden text-sm outline-none",
1500
+ "group/collapsible-content ease-out",
1501
+ "data-[state=closed]:animate-collapsible-up",
1502
+ "data-[state=open]:animate-collapsible-down",
1503
+ "data-[state=closed]:fill-mode-forwards",
1504
+ "data-[state=closed]:pointer-events-none",
1505
+ "data-[state=open]:duration-(--animation-duration)",
1506
+ "data-[state=closed]:duration-(--animation-duration)",
1507
+ className,
1399
1508
  )}
1509
+ {...props}
1510
+ >
1511
+ <div className="mt-3 flex flex-col gap-2 border-t pt-2">{children}</div>
1512
+ </CollapsibleContent>
1513
+ );
1514
+ }
1515
+
1516
+ function ToolFallbackArgs({
1517
+ argsText,
1518
+ className,
1519
+ ...props
1520
+ }: React.ComponentProps<"div"> & {
1521
+ argsText?: string;
1522
+ }) {
1523
+ if (!argsText) return null;
1524
+
1525
+ return (
1526
+ <div
1527
+ data-slot="tool-fallback-args"
1528
+ className={cn("aui-tool-fallback-args px-4", className)}
1529
+ {...props}
1530
+ >
1531
+ <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1532
+ {argsText}
1533
+ </pre>
1400
1534
  </div>
1401
1535
  );
1536
+ }
1537
+
1538
+ function ToolFallbackResult({
1539
+ result,
1540
+ className,
1541
+ ...props
1542
+ }: React.ComponentProps<"div"> & {
1543
+ result?: unknown;
1544
+ }) {
1545
+ if (result === undefined) return null;
1546
+
1547
+ return (
1548
+ <div
1549
+ data-slot="tool-fallback-result"
1550
+ className={cn(
1551
+ "aui-tool-fallback-result border-t border-dashed px-4 pt-2",
1552
+ className,
1553
+ )}
1554
+ {...props}
1555
+ >
1556
+ <p className="aui-tool-fallback-result-header font-semibold">Result:</p>
1557
+ <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1558
+ {typeof result === "string" ? result : JSON.stringify(result, null, 2)}
1559
+ </pre>
1560
+ </div>
1561
+ );
1562
+ }
1563
+
1564
+ function ToolFallbackError({
1565
+ status,
1566
+ className,
1567
+ ...props
1568
+ }: React.ComponentProps<"div"> & {
1569
+ status?: ToolCallMessagePartStatus;
1570
+ }) {
1571
+ if (status?.type !== "incomplete") return null;
1572
+
1573
+ const error = status.error;
1574
+ const errorText = error
1575
+ ? typeof error === "string"
1576
+ ? error
1577
+ : JSON.stringify(error)
1578
+ : null;
1579
+
1580
+ if (!errorText) return null;
1581
+
1582
+ const isCancelled = status.reason === "cancelled";
1583
+ const headerText = isCancelled ? "Cancelled reason:" : "Error:";
1584
+
1585
+ return (
1586
+ <div
1587
+ data-slot="tool-fallback-error"
1588
+ className={cn("aui-tool-fallback-error px-4", className)}
1589
+ {...props}
1590
+ >
1591
+ <p className="aui-tool-fallback-error-header font-semibold text-muted-foreground">
1592
+ {headerText}
1593
+ </p>
1594
+ <p className="aui-tool-fallback-error-reason text-muted-foreground">
1595
+ {errorText}
1596
+ </p>
1597
+ </div>
1598
+ );
1599
+ }
1600
+
1601
+ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1602
+ toolName,
1603
+ argsText,
1604
+ result,
1605
+ status,
1606
+ }) => {
1607
+ const isCancelled =
1608
+ status?.type === "incomplete" && status.reason === "cancelled";
1609
+
1610
+ return (
1611
+ <ToolFallbackRoot
1612
+ className={cn(isCancelled && "border-muted-foreground/30 bg-muted/30")}
1613
+ >
1614
+ <ToolFallbackTrigger toolName={toolName} status={status} />
1615
+ <ToolFallbackContent>
1616
+ <ToolFallbackError status={status} />
1617
+ <ToolFallbackArgs
1618
+ argsText={argsText}
1619
+ className={cn(isCancelled && "opacity-60")}
1620
+ />
1621
+ {!isCancelled && <ToolFallbackResult result={result} />}
1622
+ </ToolFallbackContent>
1623
+ </ToolFallbackRoot>
1624
+ );
1625
+ };
1626
+
1627
+ const ToolFallback = memo(
1628
+ ToolFallbackImpl,
1629
+ ) as unknown as ToolCallMessagePartComponent & {
1630
+ Root: typeof ToolFallbackRoot;
1631
+ Trigger: typeof ToolFallbackTrigger;
1632
+ Content: typeof ToolFallbackContent;
1633
+ Args: typeof ToolFallbackArgs;
1634
+ Result: typeof ToolFallbackResult;
1635
+ Error: typeof ToolFallbackError;
1636
+ };
1637
+
1638
+ ToolFallback.displayName = "ToolFallback";
1639
+ ToolFallback.Root = ToolFallbackRoot;
1640
+ ToolFallback.Trigger = ToolFallbackTrigger;
1641
+ ToolFallback.Content = ToolFallbackContent;
1642
+ ToolFallback.Args = ToolFallbackArgs;
1643
+ ToolFallback.Result = ToolFallbackResult;
1644
+ ToolFallback.Error = ToolFallbackError;
1645
+
1646
+ export {
1647
+ ToolFallback,
1648
+ ToolFallbackRoot,
1649
+ ToolFallbackTrigger,
1650
+ ToolFallbackContent,
1651
+ ToolFallbackArgs,
1652
+ ToolFallbackResult,
1653
+ ToolFallbackError,
1402
1654
  };
1403
1655
 
1404
1656
  ```
@@ -1461,47 +1713,50 @@ import * as AvatarPrimitive from "@radix-ui/react-avatar";
1461
1713
 
1462
1714
  import { cn } from "@/lib/utils";
1463
1715
 
1464
- const Avatar = React.forwardRef<
1465
- React.ElementRef<typeof AvatarPrimitive.Root>,
1466
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
1467
- >(({ className, ...props }, ref) => (
1468
- <AvatarPrimitive.Root
1469
- ref={ref}
1470
- className={cn(
1471
- "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
1472
- className,
1473
- )}
1474
- {...props}
1475
- />
1476
- ));
1477
- Avatar.displayName = AvatarPrimitive.Root.displayName;
1478
-
1479
- const AvatarImage = React.forwardRef<
1480
- React.ElementRef<typeof AvatarPrimitive.Image>,
1481
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
1482
- >(({ className, ...props }, ref) => (
1483
- <AvatarPrimitive.Image
1484
- ref={ref}
1485
- className={cn("aspect-square h-full w-full", className)}
1486
- {...props}
1487
- />
1488
- ));
1489
- AvatarImage.displayName = AvatarPrimitive.Image.displayName;
1490
-
1491
- const AvatarFallback = React.forwardRef<
1492
- React.ElementRef<typeof AvatarPrimitive.Fallback>,
1493
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
1494
- >(({ className, ...props }, ref) => (
1495
- <AvatarPrimitive.Fallback
1496
- ref={ref}
1497
- className={cn(
1498
- "flex h-full w-full items-center justify-center rounded-full bg-muted",
1499
- className,
1500
- )}
1501
- {...props}
1502
- />
1503
- ));
1504
- AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
1716
+ function Avatar({
1717
+ className,
1718
+ ...props
1719
+ }: React.ComponentProps<typeof AvatarPrimitive.Root>) {
1720
+ return (
1721
+ <AvatarPrimitive.Root
1722
+ data-slot="avatar"
1723
+ className={cn(
1724
+ "relative flex size-8 shrink-0 overflow-hidden rounded-full",
1725
+ className,
1726
+ )}
1727
+ {...props}
1728
+ />
1729
+ );
1730
+ }
1731
+
1732
+ function AvatarImage({
1733
+ className,
1734
+ ...props
1735
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
1736
+ return (
1737
+ <AvatarPrimitive.Image
1738
+ data-slot="avatar-image"
1739
+ className={cn("aspect-square size-full", className)}
1740
+ {...props}
1741
+ />
1742
+ );
1743
+ }
1744
+
1745
+ function AvatarFallback({
1746
+ className,
1747
+ ...props
1748
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
1749
+ return (
1750
+ <AvatarPrimitive.Fallback
1751
+ data-slot="avatar-fallback"
1752
+ className={cn(
1753
+ "flex size-full items-center justify-center rounded-full bg-muted",
1754
+ className,
1755
+ )}
1756
+ {...props}
1757
+ />
1758
+ );
1759
+ }
1505
1760
 
1506
1761
  export { Avatar, AvatarImage, AvatarFallback };
1507
1762
 
@@ -1510,8 +1765,6 @@ export { Avatar, AvatarImage, AvatarFallback };
1510
1765
  ## components/ui/button.tsx
1511
1766
 
1512
1767
  ```tsx
1513
- "use client";
1514
-
1515
1768
  import * as React from "react";
1516
1769
  import { Slot } from "@radix-ui/react-slot";
1517
1770
  import { cva, type VariantProps } from "class-variance-authority";
@@ -1523,14 +1776,13 @@ const buttonVariants = cva(
1523
1776
  {
1524
1777
  variants: {
1525
1778
  variant: {
1526
- default:
1527
- "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
1779
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
1528
1780
  destructive:
1529
- "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
1781
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
1530
1782
  outline:
1531
1783
  "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
1532
1784
  secondary:
1533
- "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
1785
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
1534
1786
  ghost:
1535
1787
  "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
1536
1788
  link: "text-primary underline-offset-4 hover:underline",
@@ -1540,6 +1792,8 @@ const buttonVariants = cva(
1540
1792
  sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
1541
1793
  lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
1542
1794
  icon: "size-9",
1795
+ "icon-sm": "size-8",
1796
+ "icon-lg": "size-10",
1543
1797
  },
1544
1798
  },
1545
1799
  defaultVariants: {
@@ -1551,8 +1805,8 @@ const buttonVariants = cva(
1551
1805
 
1552
1806
  function Button({
1553
1807
  className,
1554
- variant,
1555
- size,
1808
+ variant = "default",
1809
+ size = "default",
1556
1810
  asChild = false,
1557
1811
  ...props
1558
1812
  }: React.ComponentProps<"button"> &
@@ -1564,6 +1818,8 @@ function Button({
1564
1818
  return (
1565
1819
  <Comp
1566
1820
  data-slot="button"
1821
+ data-variant={variant}
1822
+ data-size={size}
1567
1823
  className={cn(buttonVariants({ variant, size, className }))}
1568
1824
  {...props}
1569
1825
  />
@@ -1574,6 +1830,45 @@ export { Button, buttonVariants };
1574
1830
 
1575
1831
  ```
1576
1832
 
1833
+ ## components/ui/collapsible.tsx
1834
+
1835
+ ```tsx
1836
+ "use client";
1837
+
1838
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
1839
+
1840
+ function Collapsible({
1841
+ ...props
1842
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
1843
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
1844
+ }
1845
+
1846
+ function CollapsibleTrigger({
1847
+ ...props
1848
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
1849
+ return (
1850
+ <CollapsiblePrimitive.CollapsibleTrigger
1851
+ data-slot="collapsible-trigger"
1852
+ {...props}
1853
+ />
1854
+ );
1855
+ }
1856
+
1857
+ function CollapsibleContent({
1858
+ ...props
1859
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
1860
+ return (
1861
+ <CollapsiblePrimitive.CollapsibleContent
1862
+ data-slot="collapsible-content"
1863
+ {...props}
1864
+ />
1865
+ );
1866
+ }
1867
+
1868
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent };
1869
+
1870
+ ```
1871
+
1577
1872
  ## components/ui/dialog.tsx
1578
1873
 
1579
1874
  ```tsx
@@ -1617,7 +1912,7 @@ function DialogOverlay({
1617
1912
  <DialogPrimitive.Overlay
1618
1913
  data-slot="dialog-overlay"
1619
1914
  className={cn(
1620
- "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",
1915
+ "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",
1621
1916
  className,
1622
1917
  )}
1623
1918
  {...props}
@@ -1628,24 +1923,32 @@ function DialogOverlay({
1628
1923
  function DialogContent({
1629
1924
  className,
1630
1925
  children,
1926
+ showCloseButton = true,
1631
1927
  ...props
1632
- }: React.ComponentProps<typeof DialogPrimitive.Content>) {
1928
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
1929
+ showCloseButton?: boolean;
1930
+ }) {
1633
1931
  return (
1634
1932
  <DialogPortal data-slot="dialog-portal">
1635
1933
  <DialogOverlay />
1636
1934
  <DialogPrimitive.Content
1637
1935
  data-slot="dialog-content"
1638
1936
  className={cn(
1639
- "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",
1937
+ "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",
1640
1938
  className,
1641
1939
  )}
1642
1940
  {...props}
1643
1941
  >
1644
1942
  {children}
1645
- <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">
1646
- <XIcon />
1647
- <span className="sr-only">Close</span>
1648
- </DialogPrimitive.Close>
1943
+ {showCloseButton && (
1944
+ <DialogPrimitive.Close
1945
+ data-slot="dialog-close"
1946
+ 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"
1947
+ >
1948
+ <XIcon />
1949
+ <span className="sr-only">Close</span>
1950
+ </DialogPrimitive.Close>
1951
+ )}
1649
1952
  </DialogPrimitive.Content>
1650
1953
  </DialogPortal>
1651
1954
  );
@@ -1766,13 +2069,13 @@ function TooltipContent({
1766
2069
  data-slot="tooltip-content"
1767
2070
  sideOffset={sideOffset}
1768
2071
  className={cn(
1769
- "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",
2072
+ "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",
1770
2073
  className,
1771
2074
  )}
1772
2075
  {...props}
1773
2076
  >
1774
2077
  {children}
1775
- <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
2078
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
1776
2079
  </TooltipPrimitive.Content>
1777
2080
  </TooltipPrimitive.Portal>
1778
2081
  );
@@ -1812,52 +2115,47 @@ export default nextConfig;
1812
2115
  ```json
1813
2116
  {
1814
2117
  "name": "with-ffmpeg",
1815
- "version": "0.1.0",
2118
+ "version": "0.0.0",
1816
2119
  "private": true,
2120
+ "type": "module",
1817
2121
  "scripts": {
1818
- "dev": "next dev --turbo",
2122
+ "dev": "next dev",
1819
2123
  "build": "next build",
1820
2124
  "start": "next start"
1821
2125
  },
1822
2126
  "dependencies": {
1823
- "@ai-sdk/openai": "^2.0.84",
2127
+ "@ai-sdk/openai": "^3.0.13",
1824
2128
  "@assistant-ui/react": "workspace:*",
1825
2129
  "@assistant-ui/react-ai-sdk": "workspace:*",
1826
- "@assistant-ui/react-hook-form": "workspace:*",
1827
2130
  "@assistant-ui/react-markdown": "workspace:*",
1828
2131
  "@ffmpeg/ffmpeg": "^0.12.15",
1829
2132
  "@ffmpeg/util": "^0.12.2",
1830
- "@hookform/resolvers": "^5.2.2",
1831
2133
  "@radix-ui/react-avatar": "^1.1.11",
2134
+ "@radix-ui/react-collapsible": "^1.1.12",
1832
2135
  "@radix-ui/react-dialog": "^1.1.15",
1833
- "@radix-ui/react-icons": "^1.3.2",
1834
- "@radix-ui/react-label": "^2.1.8",
1835
2136
  "@radix-ui/react-slot": "^1.2.4",
1836
- "@radix-ui/react-tabs": "^1.1.13",
1837
2137
  "@radix-ui/react-tooltip": "^1.2.8",
1838
- "@react-hook/media-query": "^1.1.1",
1839
- "ai": "^5.0.112",
2138
+ "ai": "^6.0.42",
1840
2139
  "class-variance-authority": "^0.7.1",
1841
2140
  "clsx": "^2.1.1",
1842
- "lucide-react": "^0.560.0",
1843
- "next": "16.0.10",
1844
- "react": "19.2.3",
1845
- "react-dom": "19.2.3",
1846
- "react-hook-form": "^7.68.0",
1847
- "react-resizable-panels": "^3.0.6",
2141
+ "lucide-react": "^0.562.0",
2142
+ "next": "^16.1.4",
2143
+ "react": "^19.2.3",
2144
+ "react-dom": "^19.2.3",
1848
2145
  "remark-gfm": "^4.0.1",
1849
2146
  "tailwind-merge": "^3.4.0",
1850
- "tw-animate-css": "^1.4.0",
1851
- "zod": "^4.1.13",
1852
- "zustand": "^5.0.9"
2147
+ "zod": "^4.3.5",
2148
+ "zustand": "^5.0.10"
1853
2149
  },
1854
2150
  "devDependencies": {
1855
2151
  "@assistant-ui/x-buildutils": "workspace:*",
1856
- "@types/node": "^25",
1857
- "@types/react": "^19",
1858
- "@types/react-dom": "^19",
1859
- "postcss": "^8",
2152
+ "@tailwindcss/postcss": "^4.1.18",
2153
+ "@types/node": "^25.0.9",
2154
+ "@types/react": "^19.2.9",
2155
+ "@types/react-dom": "^19.2.3",
2156
+ "postcss": "^8.5.6",
1860
2157
  "tailwindcss": "^4.1.18",
2158
+ "tw-animate-css": "^1.4.0",
1861
2159
  "typescript": "^5.9.3"
1862
2160
  }
1863
2161
  }
@@ -1868,29 +2166,11 @@ export default nextConfig;
1868
2166
 
1869
2167
  ```json
1870
2168
  {
1871
- "extends": "@assistant-ui/x-buildutils/ts/base",
2169
+ "extends": "@assistant-ui/x-buildutils/ts/next",
1872
2170
  "compilerOptions": {
1873
- "target": "ES6",
1874
- "module": "ESNext",
1875
- "incremental": true,
1876
- "plugins": [
1877
- {
1878
- "name": "next"
1879
- }
1880
- ],
1881
- "allowJs": true,
1882
- "strictNullChecks": true,
1883
- "jsx": "preserve",
1884
- "paths": {
1885
- "@/*": ["./*"],
1886
- "@assistant-ui/*": ["../../packages/*/src"],
1887
- "@assistant-ui/react/*": ["../../packages/react/src/*"],
1888
- "@assistant-ui/tap/*": ["../../packages/tap/src/*"],
1889
- "assistant-stream": ["../../packages/assistant-stream/src"],
1890
- "assistant-stream/*": ["../../packages/assistant-stream/src/*"]
1891
- }
2171
+ "paths": { "@/*": ["./*"] }
1892
2172
  },
1893
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
2173
+ "include": ["**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
1894
2174
  "exclude": ["node_modules"]
1895
2175
  }
1896
2176