@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),
@@ -35,43 +35,41 @@ export async function POST(req: Request) {
35
35
  @custom-variant dark (&:is(.dark *));
36
36
 
37
37
  @theme inline {
38
- --color-background: var(--background);
39
- --color-foreground: var(--foreground);
40
- --font-sans: var(--font-geist-sans);
41
- --font-mono: var(--font-geist-mono);
42
- --color-sidebar-ring: var(--sidebar-ring);
43
- --color-sidebar-border: var(--sidebar-border);
44
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
45
- --color-sidebar-accent: var(--sidebar-accent);
46
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
47
- --color-sidebar-primary: var(--sidebar-primary);
48
- --color-sidebar-foreground: var(--sidebar-foreground);
49
- --color-sidebar: var(--sidebar);
50
- --color-chart-5: var(--chart-5);
51
- --color-chart-4: var(--chart-4);
52
- --color-chart-3: var(--chart-3);
53
- --color-chart-2: var(--chart-2);
54
- --color-chart-1: var(--chart-1);
55
- --color-ring: var(--ring);
56
- --color-input: var(--input);
57
- --color-border: var(--border);
58
- --color-destructive: var(--destructive);
59
- --color-accent-foreground: var(--accent-foreground);
60
- --color-accent: var(--accent);
61
- --color-muted-foreground: var(--muted-foreground);
62
- --color-muted: var(--muted);
63
- --color-secondary-foreground: var(--secondary-foreground);
64
- --color-secondary: var(--secondary);
65
- --color-primary-foreground: var(--primary-foreground);
66
- --color-primary: var(--primary);
67
- --color-popover-foreground: var(--popover-foreground);
68
- --color-popover: var(--popover);
69
- --color-card-foreground: var(--card-foreground);
70
- --color-card: var(--card);
71
38
  --radius-sm: calc(var(--radius) - 4px);
72
39
  --radius-md: calc(var(--radius) - 2px);
73
40
  --radius-lg: var(--radius);
74
41
  --radius-xl: calc(var(--radius) + 4px);
42
+ --color-background: var(--background);
43
+ --color-foreground: var(--foreground);
44
+ --color-card: var(--card);
45
+ --color-card-foreground: var(--card-foreground);
46
+ --color-popover: var(--popover);
47
+ --color-popover-foreground: var(--popover-foreground);
48
+ --color-primary: var(--primary);
49
+ --color-primary-foreground: var(--primary-foreground);
50
+ --color-secondary: var(--secondary);
51
+ --color-secondary-foreground: var(--secondary-foreground);
52
+ --color-muted: var(--muted);
53
+ --color-muted-foreground: var(--muted-foreground);
54
+ --color-accent: var(--accent);
55
+ --color-accent-foreground: var(--accent-foreground);
56
+ --color-destructive: var(--destructive);
57
+ --color-border: var(--border);
58
+ --color-input: var(--input);
59
+ --color-ring: var(--ring);
60
+ --color-chart-1: var(--chart-1);
61
+ --color-chart-2: var(--chart-2);
62
+ --color-chart-3: var(--chart-3);
63
+ --color-chart-4: var(--chart-4);
64
+ --color-chart-5: var(--chart-5);
65
+ --color-sidebar: var(--sidebar);
66
+ --color-sidebar-foreground: var(--sidebar-foreground);
67
+ --color-sidebar-primary: var(--sidebar-primary);
68
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
69
+ --color-sidebar-accent: var(--sidebar-accent);
70
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
71
+ --color-sidebar-border: var(--sidebar-border);
72
+ --color-sidebar-ring: var(--sidebar-ring);
75
73
  }
76
74
 
77
75
  :root {
@@ -307,8 +305,12 @@ export default function Home() {
307
305
  },
308
306
  "aliases": {
309
307
  "components": "@/components",
310
- "utils": "@/lib/utils"
311
- }
308
+ "utils": "@/lib/utils",
309
+ "ui": "@/components/ui",
310
+ "lib": "@/lib",
311
+ "hooks": "@/hooks"
312
+ },
313
+ "iconLibrary": "lucide"
312
314
  }
313
315
 
314
316
  ```
@@ -316,24 +318,20 @@ export default function Home() {
316
318
  ## components/assistant-ui/assistant-sidebar.tsx
317
319
 
318
320
  ```tsx
319
- import {
320
- ResizableHandle,
321
- ResizablePanel,
322
- ResizablePanelGroup,
323
- } from "@/components/ui/resizable";
321
+ import { Separator, ResizablePanel, Group } from "@/components/ui/resizable";
324
322
  import type { FC, PropsWithChildren } from "react";
325
323
 
326
324
  import { Thread } from "@/components/assistant-ui/thread";
327
325
 
328
326
  export const AssistantSidebar: FC<PropsWithChildren> = ({ children }) => {
329
327
  return (
330
- <ResizablePanelGroup direction="horizontal">
328
+ <Group orientation="horizontal">
331
329
  <ResizablePanel>{children}</ResizablePanel>
332
- <ResizableHandle />
330
+ <Separator />
333
331
  <ResizablePanel>
334
332
  <Thread />
335
333
  </ResizablePanel>
336
- </ResizablePanelGroup>
334
+ </Group>
337
335
  );
338
336
  };
339
337
 
@@ -569,7 +567,7 @@ export const ComposerAddAttachment: FC = () => {
569
567
  side="bottom"
570
568
  variant="ghost"
571
569
  size="icon"
572
- 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"
570
+ 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"
573
571
  aria-label="Add Attachment"
574
572
  >
575
573
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -828,6 +826,7 @@ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button
828
826
  import { Button } from "@/components/ui/button";
829
827
  import { cn } from "@/lib/utils";
830
828
  import {
829
+ ActionBarMorePrimitive,
831
830
  ActionBarPrimitive,
832
831
  AssistantIf,
833
832
  BranchPickerPrimitive,
@@ -844,6 +843,7 @@ import {
844
843
  ChevronRightIcon,
845
844
  CopyIcon,
846
845
  DownloadIcon,
846
+ MoreHorizontalIcon,
847
847
  PencilIcon,
848
848
  RefreshCwIcon,
849
849
  SquareIcon,
@@ -889,7 +889,7 @@ const ThreadScrollToBottom: FC = () => {
889
889
  <TooltipIconButton
890
890
  tooltip="Scroll to bottom"
891
891
  variant="outline"
892
- 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"
892
+ 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"
893
893
  >
894
894
  <ArrowDownIcon />
895
895
  </TooltipIconButton>
@@ -1053,7 +1053,7 @@ const AssistantActionBar: FC = () => {
1053
1053
  hideWhenRunning
1054
1054
  autohide="not-last"
1055
1055
  autohideFloat="single-branch"
1056
- 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"
1056
+ 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"
1057
1057
  >
1058
1058
  <ActionBarPrimitive.Copy asChild>
1059
1059
  <TooltipIconButton tooltip="Copy">
@@ -1065,16 +1065,33 @@ const AssistantActionBar: FC = () => {
1065
1065
  </AssistantIf>
1066
1066
  </TooltipIconButton>
1067
1067
  </ActionBarPrimitive.Copy>
1068
- <ActionBarPrimitive.ExportMarkdown asChild>
1069
- <TooltipIconButton tooltip="Export as Markdown">
1070
- <DownloadIcon />
1071
- </TooltipIconButton>
1072
- </ActionBarPrimitive.ExportMarkdown>
1073
1068
  <ActionBarPrimitive.Reload asChild>
1074
1069
  <TooltipIconButton tooltip="Refresh">
1075
1070
  <RefreshCwIcon />
1076
1071
  </TooltipIconButton>
1077
1072
  </ActionBarPrimitive.Reload>
1073
+ <ActionBarMorePrimitive.Root>
1074
+ <ActionBarMorePrimitive.Trigger asChild>
1075
+ <TooltipIconButton
1076
+ tooltip="More"
1077
+ className="data-[state=open]:bg-accent"
1078
+ >
1079
+ <MoreHorizontalIcon />
1080
+ </TooltipIconButton>
1081
+ </ActionBarMorePrimitive.Trigger>
1082
+ <ActionBarMorePrimitive.Content
1083
+ side="bottom"
1084
+ align="start"
1085
+ 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"
1086
+ >
1087
+ <ActionBarPrimitive.ExportMarkdown asChild>
1088
+ <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">
1089
+ <DownloadIcon className="size-4" />
1090
+ Export as Markdown
1091
+ </ActionBarMorePrimitive.Item>
1092
+ </ActionBarPrimitive.ExportMarkdown>
1093
+ </ActionBarMorePrimitive.Content>
1094
+ </ActionBarMorePrimitive.Root>
1078
1095
  </ActionBarPrimitive.Root>
1079
1096
  );
1080
1097
  };
@@ -1091,12 +1108,12 @@ const UserMessage: FC = () => {
1091
1108
  <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
1092
1109
  <MessagePrimitive.Parts />
1093
1110
  </div>
1094
- <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1111
+ <div className="aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2">
1095
1112
  <UserActionBar />
1096
1113
  </div>
1097
1114
  </div>
1098
1115
 
1099
- <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
1116
+ <BranchPicker className="aui-user-branch-picker col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
1100
1117
  </MessagePrimitive.Root>
1101
1118
  );
1102
1119
  };
@@ -1148,7 +1165,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1148
1165
  <BranchPickerPrimitive.Root
1149
1166
  hideWhenSingleBranch
1150
1167
  className={cn(
1151
- "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1168
+ "aui-branch-picker-root mr-2 -ml-2 inline-flex items-center text-muted-foreground text-xs",
1152
1169
  className,
1153
1170
  )}
1154
1171
  {...rest}
@@ -1175,98 +1192,329 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1175
1192
  ## components/assistant-ui/tool-fallback.tsx
1176
1193
 
1177
1194
  ```tsx
1178
- import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
1195
+ "use client";
1196
+
1197
+ import { memo, useCallback, useRef, useState } from "react";
1179
1198
  import {
1199
+ AlertCircleIcon,
1180
1200
  CheckIcon,
1181
1201
  ChevronDownIcon,
1182
- ChevronUpIcon,
1202
+ LoaderIcon,
1183
1203
  XCircleIcon,
1184
1204
  } from "lucide-react";
1185
- import { useState } from "react";
1186
- import { Button } from "@/components/ui/button";
1205
+ import {
1206
+ useScrollLock,
1207
+ type ToolCallMessagePartStatus,
1208
+ type ToolCallMessagePartComponent,
1209
+ } from "@assistant-ui/react";
1210
+ import {
1211
+ Collapsible,
1212
+ CollapsibleContent,
1213
+ CollapsibleTrigger,
1214
+ } from "@/components/ui/collapsible";
1187
1215
  import { cn } from "@/lib/utils";
1188
1216
 
1189
- export const ToolFallback: ToolCallMessagePartComponent = ({
1217
+ const ANIMATION_DURATION = 200;
1218
+
1219
+ export type ToolFallbackRootProps = Omit<
1220
+ React.ComponentProps<typeof Collapsible>,
1221
+ "open" | "onOpenChange"
1222
+ > & {
1223
+ open?: boolean;
1224
+ onOpenChange?: (open: boolean) => void;
1225
+ defaultOpen?: boolean;
1226
+ };
1227
+
1228
+ function ToolFallbackRoot({
1229
+ className,
1230
+ open: controlledOpen,
1231
+ onOpenChange: controlledOnOpenChange,
1232
+ defaultOpen = false,
1233
+ children,
1234
+ ...props
1235
+ }: ToolFallbackRootProps) {
1236
+ const collapsibleRef = useRef<HTMLDivElement>(null);
1237
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
1238
+ const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
1239
+
1240
+ const isControlled = controlledOpen !== undefined;
1241
+ const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1242
+
1243
+ const handleOpenChange = useCallback(
1244
+ (open: boolean) => {
1245
+ if (!open) {
1246
+ lockScroll();
1247
+ }
1248
+ if (!isControlled) {
1249
+ setUncontrolledOpen(open);
1250
+ }
1251
+ controlledOnOpenChange?.(open);
1252
+ },
1253
+ [lockScroll, isControlled, controlledOnOpenChange],
1254
+ );
1255
+
1256
+ return (
1257
+ <Collapsible
1258
+ ref={collapsibleRef}
1259
+ data-slot="tool-fallback-root"
1260
+ open={isOpen}
1261
+ onOpenChange={handleOpenChange}
1262
+ className={cn(
1263
+ "aui-tool-fallback-root group/tool-fallback-root w-full rounded-lg border py-3",
1264
+ className,
1265
+ )}
1266
+ style={
1267
+ {
1268
+ "--animation-duration": `${ANIMATION_DURATION}ms`,
1269
+ } as React.CSSProperties
1270
+ }
1271
+ {...props}
1272
+ >
1273
+ {children}
1274
+ </Collapsible>
1275
+ );
1276
+ }
1277
+
1278
+ type ToolStatus = ToolCallMessagePartStatus["type"];
1279
+
1280
+ const statusIconMap: Record<ToolStatus, React.ElementType> = {
1281
+ running: LoaderIcon,
1282
+ complete: CheckIcon,
1283
+ incomplete: XCircleIcon,
1284
+ "requires-action": AlertCircleIcon,
1285
+ };
1286
+
1287
+ function ToolFallbackTrigger({
1190
1288
  toolName,
1191
- argsText,
1192
- result,
1193
1289
  status,
1194
- }) => {
1195
- const [isCollapsed, setIsCollapsed] = useState(true);
1196
-
1290
+ className,
1291
+ ...props
1292
+ }: React.ComponentProps<typeof CollapsibleTrigger> & {
1293
+ toolName: string;
1294
+ status?: ToolCallMessagePartStatus;
1295
+ }) {
1296
+ const statusType = status?.type ?? "complete";
1297
+ const isRunning = statusType === "running";
1197
1298
  const isCancelled =
1198
1299
  status?.type === "incomplete" && status.reason === "cancelled";
1199
- const cancelledReason =
1200
- isCancelled && status.error
1201
- ? typeof status.error === "string"
1202
- ? status.error
1203
- : JSON.stringify(status.error)
1204
- : null;
1300
+
1301
+ const Icon = statusIconMap[statusType];
1302
+ const label = isCancelled ? "Cancelled tool" : "Used tool";
1205
1303
 
1206
1304
  return (
1207
- <div
1305
+ <CollapsibleTrigger
1306
+ data-slot="tool-fallback-trigger"
1208
1307
  className={cn(
1209
- "aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
1210
- isCancelled && "border-muted-foreground/30 bg-muted/30",
1308
+ "aui-tool-fallback-trigger group/trigger flex w-full items-center gap-2 px-4 text-sm transition-colors",
1309
+ className,
1211
1310
  )}
1311
+ {...props}
1212
1312
  >
1213
- <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1214
- {isCancelled ? (
1215
- <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1216
- ) : (
1217
- <CheckIcon className="aui-tool-fallback-icon size-4" />
1313
+ <Icon
1314
+ data-slot="tool-fallback-trigger-icon"
1315
+ className={cn(
1316
+ "aui-tool-fallback-trigger-icon size-4 shrink-0",
1317
+ isCancelled && "text-muted-foreground",
1318
+ isRunning && "animate-spin",
1218
1319
  )}
1219
- <p
1220
- className={cn(
1221
- "aui-tool-fallback-title grow",
1222
- isCancelled && "text-muted-foreground line-through",
1223
- )}
1224
- >
1225
- {isCancelled ? "Cancelled tool: " : "Used tool: "}
1226
- <b>{toolName}</b>
1227
- </p>
1228
- <Button onClick={() => setIsCollapsed(!isCollapsed)}>
1229
- {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
1230
- </Button>
1231
- </div>
1232
- {!isCollapsed && (
1233
- <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1234
- {cancelledReason && (
1235
- <div className="aui-tool-fallback-cancelled-root px-4">
1236
- <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1237
- Cancelled reason:
1238
- </p>
1239
- <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
1240
- {cancelledReason}
1241
- </p>
1242
- </div>
1243
- )}
1244
- <div
1245
- className={cn(
1246
- "aui-tool-fallback-args-root px-4",
1247
- isCancelled && "opacity-60",
1248
- )}
1320
+ />
1321
+ <span
1322
+ data-slot="tool-fallback-trigger-label"
1323
+ className={cn(
1324
+ "aui-tool-fallback-trigger-label-wrapper relative inline-block grow text-left leading-none",
1325
+ isCancelled && "text-muted-foreground line-through",
1326
+ )}
1327
+ >
1328
+ <span>
1329
+ {label}: <b>{toolName}</b>
1330
+ </span>
1331
+ {isRunning && (
1332
+ <span
1333
+ aria-hidden
1334
+ data-slot="tool-fallback-trigger-shimmer"
1335
+ className="aui-tool-fallback-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none"
1249
1336
  >
1250
- <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1251
- {argsText}
1252
- </pre>
1253
- </div>
1254
- {!isCancelled && result !== undefined && (
1255
- <div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
1256
- <p className="aui-tool-fallback-result-header font-semibold">
1257
- Result:
1258
- </p>
1259
- <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1260
- {typeof result === "string"
1261
- ? result
1262
- : JSON.stringify(result, null, 2)}
1263
- </pre>
1264
- </div>
1265
- )}
1266
- </div>
1337
+ {label}: <b>{toolName}</b>
1338
+ </span>
1339
+ )}
1340
+ </span>
1341
+ <ChevronDownIcon
1342
+ data-slot="tool-fallback-trigger-chevron"
1343
+ className={cn(
1344
+ "aui-tool-fallback-trigger-chevron size-4 shrink-0",
1345
+ "transition-transform duration-(--animation-duration) ease-out",
1346
+ "group-data-[state=closed]/trigger:-rotate-90",
1347
+ "group-data-[state=open]/trigger:rotate-0",
1348
+ )}
1349
+ />
1350
+ </CollapsibleTrigger>
1351
+ );
1352
+ }
1353
+
1354
+ function ToolFallbackContent({
1355
+ className,
1356
+ children,
1357
+ ...props
1358
+ }: React.ComponentProps<typeof CollapsibleContent>) {
1359
+ return (
1360
+ <CollapsibleContent
1361
+ data-slot="tool-fallback-content"
1362
+ className={cn(
1363
+ "aui-tool-fallback-content relative overflow-hidden text-sm outline-none",
1364
+ "group/collapsible-content ease-out",
1365
+ "data-[state=closed]:animate-collapsible-up",
1366
+ "data-[state=open]:animate-collapsible-down",
1367
+ "data-[state=closed]:fill-mode-forwards",
1368
+ "data-[state=closed]:pointer-events-none",
1369
+ "data-[state=open]:duration-(--animation-duration)",
1370
+ "data-[state=closed]:duration-(--animation-duration)",
1371
+ className,
1372
+ )}
1373
+ {...props}
1374
+ >
1375
+ <div className="mt-3 flex flex-col gap-2 border-t pt-2">{children}</div>
1376
+ </CollapsibleContent>
1377
+ );
1378
+ }
1379
+
1380
+ function ToolFallbackArgs({
1381
+ argsText,
1382
+ className,
1383
+ ...props
1384
+ }: React.ComponentProps<"div"> & {
1385
+ argsText?: string;
1386
+ }) {
1387
+ if (!argsText) return null;
1388
+
1389
+ return (
1390
+ <div
1391
+ data-slot="tool-fallback-args"
1392
+ className={cn("aui-tool-fallback-args px-4", className)}
1393
+ {...props}
1394
+ >
1395
+ <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1396
+ {argsText}
1397
+ </pre>
1398
+ </div>
1399
+ );
1400
+ }
1401
+
1402
+ function ToolFallbackResult({
1403
+ result,
1404
+ className,
1405
+ ...props
1406
+ }: React.ComponentProps<"div"> & {
1407
+ result?: unknown;
1408
+ }) {
1409
+ if (result === undefined) return null;
1410
+
1411
+ return (
1412
+ <div
1413
+ data-slot="tool-fallback-result"
1414
+ className={cn(
1415
+ "aui-tool-fallback-result border-t border-dashed px-4 pt-2",
1416
+ className,
1267
1417
  )}
1418
+ {...props}
1419
+ >
1420
+ <p className="aui-tool-fallback-result-header font-semibold">Result:</p>
1421
+ <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1422
+ {typeof result === "string" ? result : JSON.stringify(result, null, 2)}
1423
+ </pre>
1268
1424
  </div>
1269
1425
  );
1426
+ }
1427
+
1428
+ function ToolFallbackError({
1429
+ status,
1430
+ className,
1431
+ ...props
1432
+ }: React.ComponentProps<"div"> & {
1433
+ status?: ToolCallMessagePartStatus;
1434
+ }) {
1435
+ if (status?.type !== "incomplete") return null;
1436
+
1437
+ const error = status.error;
1438
+ const errorText = error
1439
+ ? typeof error === "string"
1440
+ ? error
1441
+ : JSON.stringify(error)
1442
+ : null;
1443
+
1444
+ if (!errorText) return null;
1445
+
1446
+ const isCancelled = status.reason === "cancelled";
1447
+ const headerText = isCancelled ? "Cancelled reason:" : "Error:";
1448
+
1449
+ return (
1450
+ <div
1451
+ data-slot="tool-fallback-error"
1452
+ className={cn("aui-tool-fallback-error px-4", className)}
1453
+ {...props}
1454
+ >
1455
+ <p className="aui-tool-fallback-error-header font-semibold text-muted-foreground">
1456
+ {headerText}
1457
+ </p>
1458
+ <p className="aui-tool-fallback-error-reason text-muted-foreground">
1459
+ {errorText}
1460
+ </p>
1461
+ </div>
1462
+ );
1463
+ }
1464
+
1465
+ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1466
+ toolName,
1467
+ argsText,
1468
+ result,
1469
+ status,
1470
+ }) => {
1471
+ const isCancelled =
1472
+ status?.type === "incomplete" && status.reason === "cancelled";
1473
+
1474
+ return (
1475
+ <ToolFallbackRoot
1476
+ className={cn(isCancelled && "border-muted-foreground/30 bg-muted/30")}
1477
+ >
1478
+ <ToolFallbackTrigger toolName={toolName} status={status} />
1479
+ <ToolFallbackContent>
1480
+ <ToolFallbackError status={status} />
1481
+ <ToolFallbackArgs
1482
+ argsText={argsText}
1483
+ className={cn(isCancelled && "opacity-60")}
1484
+ />
1485
+ {!isCancelled && <ToolFallbackResult result={result} />}
1486
+ </ToolFallbackContent>
1487
+ </ToolFallbackRoot>
1488
+ );
1489
+ };
1490
+
1491
+ const ToolFallback = memo(
1492
+ ToolFallbackImpl,
1493
+ ) as unknown as ToolCallMessagePartComponent & {
1494
+ Root: typeof ToolFallbackRoot;
1495
+ Trigger: typeof ToolFallbackTrigger;
1496
+ Content: typeof ToolFallbackContent;
1497
+ Args: typeof ToolFallbackArgs;
1498
+ Result: typeof ToolFallbackResult;
1499
+ Error: typeof ToolFallbackError;
1500
+ };
1501
+
1502
+ ToolFallback.displayName = "ToolFallback";
1503
+ ToolFallback.Root = ToolFallbackRoot;
1504
+ ToolFallback.Trigger = ToolFallbackTrigger;
1505
+ ToolFallback.Content = ToolFallbackContent;
1506
+ ToolFallback.Args = ToolFallbackArgs;
1507
+ ToolFallback.Result = ToolFallbackResult;
1508
+ ToolFallback.Error = ToolFallbackError;
1509
+
1510
+ export {
1511
+ ToolFallback,
1512
+ ToolFallbackRoot,
1513
+ ToolFallbackTrigger,
1514
+ ToolFallbackContent,
1515
+ ToolFallbackArgs,
1516
+ ToolFallbackResult,
1517
+ ToolFallbackError,
1270
1518
  };
1271
1519
 
1272
1520
  ```
@@ -1478,47 +1726,50 @@ import * as AvatarPrimitive from "@radix-ui/react-avatar";
1478
1726
 
1479
1727
  import { cn } from "@/lib/utils";
1480
1728
 
1481
- const Avatar = React.forwardRef<
1482
- React.ElementRef<typeof AvatarPrimitive.Root>,
1483
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
1484
- >(({ className, ...props }, ref) => (
1485
- <AvatarPrimitive.Root
1486
- ref={ref}
1487
- className={cn(
1488
- "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
1489
- className,
1490
- )}
1491
- {...props}
1492
- />
1493
- ));
1494
- Avatar.displayName = AvatarPrimitive.Root.displayName;
1495
-
1496
- const AvatarImage = React.forwardRef<
1497
- React.ElementRef<typeof AvatarPrimitive.Image>,
1498
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
1499
- >(({ className, ...props }, ref) => (
1500
- <AvatarPrimitive.Image
1501
- ref={ref}
1502
- className={cn("aspect-square h-full w-full", className)}
1503
- {...props}
1504
- />
1505
- ));
1506
- AvatarImage.displayName = AvatarPrimitive.Image.displayName;
1507
-
1508
- const AvatarFallback = React.forwardRef<
1509
- React.ElementRef<typeof AvatarPrimitive.Fallback>,
1510
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
1511
- >(({ className, ...props }, ref) => (
1512
- <AvatarPrimitive.Fallback
1513
- ref={ref}
1514
- className={cn(
1515
- "flex h-full w-full items-center justify-center rounded-full bg-muted",
1516
- className,
1517
- )}
1518
- {...props}
1519
- />
1520
- ));
1521
- AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
1729
+ function Avatar({
1730
+ className,
1731
+ ...props
1732
+ }: React.ComponentProps<typeof AvatarPrimitive.Root>) {
1733
+ return (
1734
+ <AvatarPrimitive.Root
1735
+ data-slot="avatar"
1736
+ className={cn(
1737
+ "relative flex size-8 shrink-0 overflow-hidden rounded-full",
1738
+ className,
1739
+ )}
1740
+ {...props}
1741
+ />
1742
+ );
1743
+ }
1744
+
1745
+ function AvatarImage({
1746
+ className,
1747
+ ...props
1748
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
1749
+ return (
1750
+ <AvatarPrimitive.Image
1751
+ data-slot="avatar-image"
1752
+ className={cn("aspect-square size-full", className)}
1753
+ {...props}
1754
+ />
1755
+ );
1756
+ }
1757
+
1758
+ function AvatarFallback({
1759
+ className,
1760
+ ...props
1761
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
1762
+ return (
1763
+ <AvatarPrimitive.Fallback
1764
+ data-slot="avatar-fallback"
1765
+ className={cn(
1766
+ "flex size-full items-center justify-center rounded-full bg-muted",
1767
+ className,
1768
+ )}
1769
+ {...props}
1770
+ />
1771
+ );
1772
+ }
1522
1773
 
1523
1774
  export { Avatar, AvatarImage, AvatarFallback };
1524
1775
 
@@ -1538,14 +1789,13 @@ const buttonVariants = cva(
1538
1789
  {
1539
1790
  variants: {
1540
1791
  variant: {
1541
- default:
1542
- "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
1792
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
1543
1793
  destructive:
1544
- "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",
1794
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
1545
1795
  outline:
1546
1796
  "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
1547
1797
  secondary:
1548
- "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
1798
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
1549
1799
  ghost:
1550
1800
  "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
1551
1801
  link: "text-primary underline-offset-4 hover:underline",
@@ -1555,6 +1805,8 @@ const buttonVariants = cva(
1555
1805
  sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
1556
1806
  lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
1557
1807
  icon: "size-9",
1808
+ "icon-sm": "size-8",
1809
+ "icon-lg": "size-10",
1558
1810
  },
1559
1811
  },
1560
1812
  defaultVariants: {
@@ -1566,8 +1818,8 @@ const buttonVariants = cva(
1566
1818
 
1567
1819
  function Button({
1568
1820
  className,
1569
- variant,
1570
- size,
1821
+ variant = "default",
1822
+ size = "default",
1571
1823
  asChild = false,
1572
1824
  ...props
1573
1825
  }: React.ComponentProps<"button"> &
@@ -1579,6 +1831,8 @@ function Button({
1579
1831
  return (
1580
1832
  <Comp
1581
1833
  data-slot="button"
1834
+ data-variant={variant}
1835
+ data-size={size}
1582
1836
  className={cn(buttonVariants({ variant, size, className }))}
1583
1837
  {...props}
1584
1838
  />
@@ -1589,6 +1843,45 @@ export { Button, buttonVariants };
1589
1843
 
1590
1844
  ```
1591
1845
 
1846
+ ## components/ui/collapsible.tsx
1847
+
1848
+ ```tsx
1849
+ "use client";
1850
+
1851
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
1852
+
1853
+ function Collapsible({
1854
+ ...props
1855
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
1856
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
1857
+ }
1858
+
1859
+ function CollapsibleTrigger({
1860
+ ...props
1861
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
1862
+ return (
1863
+ <CollapsiblePrimitive.CollapsibleTrigger
1864
+ data-slot="collapsible-trigger"
1865
+ {...props}
1866
+ />
1867
+ );
1868
+ }
1869
+
1870
+ function CollapsibleContent({
1871
+ ...props
1872
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
1873
+ return (
1874
+ <CollapsiblePrimitive.CollapsibleContent
1875
+ data-slot="collapsible-content"
1876
+ {...props}
1877
+ />
1878
+ );
1879
+ }
1880
+
1881
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent };
1882
+
1883
+ ```
1884
+
1592
1885
  ## components/ui/dialog.tsx
1593
1886
 
1594
1887
  ```tsx
@@ -1632,7 +1925,7 @@ function DialogOverlay({
1632
1925
  <DialogPrimitive.Overlay
1633
1926
  data-slot="dialog-overlay"
1634
1927
  className={cn(
1635
- "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",
1928
+ "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",
1636
1929
  className,
1637
1930
  )}
1638
1931
  {...props}
@@ -1643,24 +1936,32 @@ function DialogOverlay({
1643
1936
  function DialogContent({
1644
1937
  className,
1645
1938
  children,
1939
+ showCloseButton = true,
1646
1940
  ...props
1647
- }: React.ComponentProps<typeof DialogPrimitive.Content>) {
1941
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
1942
+ showCloseButton?: boolean;
1943
+ }) {
1648
1944
  return (
1649
1945
  <DialogPortal data-slot="dialog-portal">
1650
1946
  <DialogOverlay />
1651
1947
  <DialogPrimitive.Content
1652
1948
  data-slot="dialog-content"
1653
1949
  className={cn(
1654
- "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",
1950
+ "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",
1655
1951
  className,
1656
1952
  )}
1657
1953
  {...props}
1658
1954
  >
1659
1955
  {children}
1660
- <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">
1661
- <XIcon />
1662
- <span className="sr-only">Close</span>
1663
- </DialogPrimitive.Close>
1956
+ {showCloseButton && (
1957
+ <DialogPrimitive.Close
1958
+ data-slot="dialog-close"
1959
+ 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"
1960
+ >
1961
+ <XIcon />
1962
+ <span className="sr-only">Close</span>
1963
+ </DialogPrimitive.Close>
1964
+ )}
1664
1965
  </DialogPrimitive.Content>
1665
1966
  </DialogPortal>
1666
1967
  );
@@ -1736,7 +2037,7 @@ export {
1736
2037
  "use client";
1737
2038
 
1738
2039
  import * as React from "react";
1739
- import * as LabelPrimitive from "@radix-ui/react-label";
2040
+ import type * as LabelPrimitive from "@radix-ui/react-label";
1740
2041
  import { Slot } from "@radix-ui/react-slot";
1741
2042
  import {
1742
2043
  Controller,
@@ -1917,7 +2218,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
1917
2218
  type={type}
1918
2219
  data-slot="input"
1919
2220
  className={cn(
1920
- "flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs outline-none transition-[color,box-shadow] selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:font-medium file:text-foreground file:text-sm placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30",
2221
+ "h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs outline-none transition-[color,box-shadow] selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:font-medium file:text-foreground file:text-sm placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30",
1921
2222
  "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
1922
2223
  "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
1923
2224
  className,
@@ -1972,12 +2273,12 @@ import * as ResizablePrimitive from "react-resizable-panels";
1972
2273
 
1973
2274
  import { cn } from "@/lib/utils";
1974
2275
 
1975
- function ResizablePanelGroup({
2276
+ function Group({
1976
2277
  className,
1977
2278
  ...props
1978
- }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) {
2279
+ }: React.ComponentProps<typeof ResizablePrimitive.Group>) {
1979
2280
  return (
1980
- <ResizablePrimitive.PanelGroup
2281
+ <ResizablePrimitive.Group
1981
2282
  data-slot="resizable-panel-group"
1982
2283
  className={cn(
1983
2284
  "flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
@@ -1994,18 +2295,18 @@ function ResizablePanel({
1994
2295
  return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />;
1995
2296
  }
1996
2297
 
1997
- function ResizableHandle({
2298
+ function Separator({
1998
2299
  withHandle,
1999
2300
  className,
2000
2301
  ...props
2001
- }: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
2302
+ }: React.ComponentProps<typeof ResizablePrimitive.Separator> & {
2002
2303
  withHandle?: boolean;
2003
2304
  }) {
2004
2305
  return (
2005
- <ResizablePrimitive.PanelResizeHandle
2306
+ <ResizablePrimitive.Separator
2006
2307
  data-slot="resizable-handle"
2007
2308
  className={cn(
2008
- "after:-translate-x-1/2 data-[panel-group-direction=vertical]:after:-translate-y-1/2 relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
2309
+ "relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90",
2009
2310
  className,
2010
2311
  )}
2011
2312
  {...props}
@@ -2015,11 +2316,11 @@ function ResizableHandle({
2015
2316
  <GripVerticalIcon className="size-2.5" />
2016
2317
  </div>
2017
2318
  )}
2018
- </ResizablePrimitive.PanelResizeHandle>
2319
+ </ResizablePrimitive.Separator>
2019
2320
  );
2020
2321
  }
2021
2322
 
2022
- export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
2323
+ export { Group, ResizablePanel, Separator };
2023
2324
 
2024
2325
  ```
2025
2326
 
@@ -2146,13 +2447,13 @@ function TooltipContent({
2146
2447
  data-slot="tooltip-content"
2147
2448
  sideOffset={sideOffset}
2148
2449
  className={cn(
2149
- "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",
2450
+ "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",
2150
2451
  className,
2151
2452
  )}
2152
2453
  {...props}
2153
2454
  >
2154
2455
  {children}
2155
- <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
2456
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
2156
2457
  </TooltipPrimitive.Content>
2157
2458
  </TooltipPrimitive.Portal>
2158
2459
  );
@@ -2210,50 +2511,51 @@ export default nextConfig;
2210
2511
  ```json
2211
2512
  {
2212
2513
  "name": "with-react-hook-form",
2213
- "version": "0.1.0",
2514
+ "version": "0.0.0",
2214
2515
  "private": true,
2516
+ "type": "module",
2215
2517
  "scripts": {
2216
- "dev": "next dev --turbo",
2518
+ "dev": "next dev",
2217
2519
  "build": "next build",
2218
2520
  "start": "next start"
2219
2521
  },
2220
2522
  "dependencies": {
2221
- "@ai-sdk/openai": "^2.0.84",
2523
+ "@ai-sdk/openai": "^3.0.13",
2222
2524
  "@assistant-ui/react": "workspace:*",
2223
2525
  "@assistant-ui/react-ai-sdk": "workspace:*",
2224
2526
  "@assistant-ui/react-hook-form": "workspace:*",
2225
2527
  "@assistant-ui/react-markdown": "workspace:*",
2226
2528
  "@hookform/resolvers": "^5.2.2",
2227
2529
  "@radix-ui/react-avatar": "^1.1.11",
2530
+ "@radix-ui/react-collapsible": "^1.1.12",
2228
2531
  "@radix-ui/react-dialog": "^1.1.15",
2229
- "@radix-ui/react-icons": "^1.3.2",
2230
2532
  "@radix-ui/react-label": "^2.1.8",
2231
2533
  "@radix-ui/react-slot": "^1.2.4",
2232
2534
  "@radix-ui/react-tabs": "^1.1.13",
2233
2535
  "@radix-ui/react-tooltip": "^1.2.8",
2234
- "@react-hook/media-query": "^1.1.1",
2235
- "ai": "^5.0.112",
2536
+ "ai": "^6.0.42",
2236
2537
  "class-variance-authority": "^0.7.1",
2237
2538
  "clsx": "^2.1.1",
2238
- "lucide-react": "^0.560.0",
2239
- "next": "16.0.10",
2240
- "react": "19.2.3",
2241
- "react-dom": "19.2.3",
2242
- "react-hook-form": "^7.68.0",
2243
- "react-resizable-panels": "^3.0.6",
2539
+ "lucide-react": "^0.562.0",
2540
+ "next": "^16.1.4",
2541
+ "react": "^19.2.3",
2542
+ "react-dom": "^19.2.3",
2543
+ "react-hook-form": "^7.71.1",
2544
+ "react-resizable-panels": "^4.4.1",
2244
2545
  "remark-gfm": "^4.0.1",
2245
2546
  "tailwind-merge": "^3.4.0",
2246
- "tw-animate-css": "^1.4.0",
2247
- "zod": "^4.1.13",
2248
- "zustand": "^5.0.9"
2547
+ "zod": "^4.3.5",
2548
+ "zustand": "^5.0.10"
2249
2549
  },
2250
2550
  "devDependencies": {
2251
2551
  "@assistant-ui/x-buildutils": "workspace:*",
2252
- "@types/node": "^25",
2253
- "@types/react": "^19",
2254
- "@types/react-dom": "^19",
2255
- "postcss": "^8",
2552
+ "@tailwindcss/postcss": "^4.1.18",
2553
+ "@types/node": "^25.0.9",
2554
+ "@types/react": "^19.2.9",
2555
+ "@types/react-dom": "^19.2.3",
2556
+ "postcss": "^8.5.6",
2256
2557
  "tailwindcss": "^4.1.18",
2558
+ "tw-animate-css": "^1.4.0",
2257
2559
  "typescript": "^5.9.3"
2258
2560
  }
2259
2561
  }
@@ -2264,29 +2566,11 @@ export default nextConfig;
2264
2566
 
2265
2567
  ```json
2266
2568
  {
2267
- "extends": "@assistant-ui/x-buildutils/ts/base",
2569
+ "extends": "@assistant-ui/x-buildutils/ts/next",
2268
2570
  "compilerOptions": {
2269
- "target": "ES6",
2270
- "module": "ESNext",
2271
- "incremental": true,
2272
- "plugins": [
2273
- {
2274
- "name": "next"
2275
- }
2276
- ],
2277
- "allowJs": true,
2278
- "strictNullChecks": true,
2279
- "jsx": "preserve",
2280
- "paths": {
2281
- "@/*": ["./*"],
2282
- "@assistant-ui/*": ["../../packages/*/src"],
2283
- "@assistant-ui/react/*": ["../../packages/react/src/*"],
2284
- "@assistant-ui/tap/*": ["../../packages/tap/src/*"],
2285
- "assistant-stream": ["../../packages/assistant-stream/src"],
2286
- "assistant-stream/*": ["../../packages/assistant-stream/src/*"]
2287
- }
2571
+ "paths": { "@/*": ["./*"] }
2288
2572
  },
2289
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
2573
+ "include": ["**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
2290
2574
  "exclude": ["node_modules"]
2291
2575
  }
2292
2576