@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
  // forward system prompt and tools from the frontend
19
19
  system,
20
20
  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 {
@@ -256,7 +254,7 @@ export default function Home() {
256
254
  "rsc": true,
257
255
  "tsx": true,
258
256
  "tailwind": {
259
- "config": "tailwind.config.ts",
257
+ "config": "",
260
258
  "css": "app/globals.css",
261
259
  "baseColor": "zinc",
262
260
  "cssVariables": true,
@@ -504,7 +502,7 @@ export const ComposerAddAttachment: FC = () => {
504
502
  side="bottom"
505
503
  variant="ghost"
506
504
  size="icon"
507
- 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"
505
+ 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"
508
506
  aria-label="Add Attachment"
509
507
  >
510
508
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -752,15 +750,15 @@ const defaultComponents = memoizeMarkdownComponents({
752
750
  ## components/assistant-ui/thread-list.tsx
753
751
 
754
752
  ```tsx
755
- import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
756
753
  import { Button } from "@/components/ui/button";
757
754
  import { Skeleton } from "@/components/ui/skeleton";
758
755
  import {
759
756
  AssistantIf,
757
+ ThreadListItemMorePrimitive,
760
758
  ThreadListItemPrimitive,
761
759
  ThreadListPrimitive,
762
760
  } from "@assistant-ui/react";
763
- import { ArchiveIcon, PlusIcon } from "lucide-react";
761
+ import { ArchiveIcon, MoreHorizontalIcon, PlusIcon } from "lucide-react";
764
762
  import type { FC } from "react";
765
763
 
766
764
  export const ThreadList: FC = () => {
@@ -810,26 +808,41 @@ const ThreadListSkeleton: FC = () => {
810
808
 
811
809
  const ThreadListItem: FC = () => {
812
810
  return (
813
- <ThreadListItemPrimitive.Root className="aui-thread-list-item group flex h-9 items-center rounded-lg transition-colors hover:bg-muted focus-visible:bg-muted focus-visible:outline-none data-active:bg-muted">
814
- <ThreadListItemPrimitive.Trigger className="aui-thread-list-item-trigger flex h-full flex-1 items-center truncate px-3 text-start text-sm">
811
+ <ThreadListItemPrimitive.Root className="aui-thread-list-item group flex h-9 items-center gap-2 rounded-lg transition-colors hover:bg-muted focus-visible:bg-muted focus-visible:outline-none data-active:bg-muted">
812
+ <ThreadListItemPrimitive.Trigger className="aui-thread-list-item-trigger flex h-full min-w-0 flex-1 items-center truncate px-3 text-start text-sm">
815
813
  <ThreadListItemPrimitive.Title fallback="New Chat" />
816
814
  </ThreadListItemPrimitive.Trigger>
817
- <ThreadListItemArchive />
815
+ <ThreadListItemMore />
818
816
  </ThreadListItemPrimitive.Root>
819
817
  );
820
818
  };
821
819
 
822
- const ThreadListItemArchive: FC = () => {
820
+ const ThreadListItemMore: FC = () => {
823
821
  return (
824
- <ThreadListItemPrimitive.Archive asChild>
825
- <TooltipIconButton
826
- variant="ghost"
827
- tooltip="Archive thread"
828
- className="aui-thread-list-item-archive mr-2 size-7 p-0 opacity-0 transition-opacity group-hover:opacity-100"
822
+ <ThreadListItemMorePrimitive.Root>
823
+ <ThreadListItemMorePrimitive.Trigger asChild>
824
+ <Button
825
+ variant="ghost"
826
+ size="icon"
827
+ className="aui-thread-list-item-more mr-2 size-7 p-0 opacity-0 transition-opacity group-hover:opacity-100 data-[state=open]:bg-accent data-[state=open]:opacity-100 group-data-active:opacity-100"
828
+ >
829
+ <MoreHorizontalIcon className="size-4" />
830
+ <span className="sr-only">More options</span>
831
+ </Button>
832
+ </ThreadListItemMorePrimitive.Trigger>
833
+ <ThreadListItemMorePrimitive.Content
834
+ side="bottom"
835
+ align="start"
836
+ className="aui-thread-list-item-more-content z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md"
829
837
  >
830
- <ArchiveIcon className="size-4" />
831
- </TooltipIconButton>
832
- </ThreadListItemPrimitive.Archive>
838
+ <ThreadListItemPrimitive.Archive asChild>
839
+ <ThreadListItemMorePrimitive.Item className="aui-thread-list-item-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">
840
+ <ArchiveIcon className="size-4" />
841
+ Archive
842
+ </ThreadListItemMorePrimitive.Item>
843
+ </ThreadListItemPrimitive.Archive>
844
+ </ThreadListItemMorePrimitive.Content>
845
+ </ThreadListItemMorePrimitive.Root>
833
846
  );
834
847
  };
835
848
 
@@ -849,6 +862,7 @@ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button
849
862
  import { Button } from "@/components/ui/button";
850
863
  import { cn } from "@/lib/utils";
851
864
  import {
865
+ ActionBarMorePrimitive,
852
866
  ActionBarPrimitive,
853
867
  AssistantIf,
854
868
  BranchPickerPrimitive,
@@ -865,6 +879,7 @@ import {
865
879
  ChevronRightIcon,
866
880
  CopyIcon,
867
881
  DownloadIcon,
882
+ MoreHorizontalIcon,
868
883
  PencilIcon,
869
884
  RefreshCwIcon,
870
885
  SquareIcon,
@@ -910,7 +925,7 @@ const ThreadScrollToBottom: FC = () => {
910
925
  <TooltipIconButton
911
926
  tooltip="Scroll to bottom"
912
927
  variant="outline"
913
- 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"
928
+ 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"
914
929
  >
915
930
  <ArrowDownIcon />
916
931
  </TooltipIconButton>
@@ -1074,7 +1089,7 @@ const AssistantActionBar: FC = () => {
1074
1089
  hideWhenRunning
1075
1090
  autohide="not-last"
1076
1091
  autohideFloat="single-branch"
1077
- 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"
1092
+ 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"
1078
1093
  >
1079
1094
  <ActionBarPrimitive.Copy asChild>
1080
1095
  <TooltipIconButton tooltip="Copy">
@@ -1086,16 +1101,33 @@ const AssistantActionBar: FC = () => {
1086
1101
  </AssistantIf>
1087
1102
  </TooltipIconButton>
1088
1103
  </ActionBarPrimitive.Copy>
1089
- <ActionBarPrimitive.ExportMarkdown asChild>
1090
- <TooltipIconButton tooltip="Export as Markdown">
1091
- <DownloadIcon />
1092
- </TooltipIconButton>
1093
- </ActionBarPrimitive.ExportMarkdown>
1094
1104
  <ActionBarPrimitive.Reload asChild>
1095
1105
  <TooltipIconButton tooltip="Refresh">
1096
1106
  <RefreshCwIcon />
1097
1107
  </TooltipIconButton>
1098
1108
  </ActionBarPrimitive.Reload>
1109
+ <ActionBarMorePrimitive.Root>
1110
+ <ActionBarMorePrimitive.Trigger asChild>
1111
+ <TooltipIconButton
1112
+ tooltip="More"
1113
+ className="data-[state=open]:bg-accent"
1114
+ >
1115
+ <MoreHorizontalIcon />
1116
+ </TooltipIconButton>
1117
+ </ActionBarMorePrimitive.Trigger>
1118
+ <ActionBarMorePrimitive.Content
1119
+ side="bottom"
1120
+ align="start"
1121
+ 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"
1122
+ >
1123
+ <ActionBarPrimitive.ExportMarkdown asChild>
1124
+ <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">
1125
+ <DownloadIcon className="size-4" />
1126
+ Export as Markdown
1127
+ </ActionBarMorePrimitive.Item>
1128
+ </ActionBarPrimitive.ExportMarkdown>
1129
+ </ActionBarMorePrimitive.Content>
1130
+ </ActionBarMorePrimitive.Root>
1099
1131
  </ActionBarPrimitive.Root>
1100
1132
  );
1101
1133
  };
@@ -1112,12 +1144,12 @@ const UserMessage: FC = () => {
1112
1144
  <div className="aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground">
1113
1145
  <MessagePrimitive.Parts />
1114
1146
  </div>
1115
- <div className="aui-user-action-bar-wrapper -translate-x-full -translate-y-1/2 absolute top-1/2 left-0 pr-2">
1147
+ <div className="aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2">
1116
1148
  <UserActionBar />
1117
1149
  </div>
1118
1150
  </div>
1119
1151
 
1120
- <BranchPicker className="aui-user-branch-picker -mr-1 col-span-full col-start-1 row-start-3 justify-end" />
1152
+ <BranchPicker className="aui-user-branch-picker col-span-full col-start-1 row-start-3 -mr-1 justify-end" />
1121
1153
  </MessagePrimitive.Root>
1122
1154
  );
1123
1155
  };
@@ -1169,7 +1201,7 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1169
1201
  <BranchPickerPrimitive.Root
1170
1202
  hideWhenSingleBranch
1171
1203
  className={cn(
1172
- "aui-branch-picker-root -ml-2 mr-2 inline-flex items-center text-muted-foreground text-xs",
1204
+ "aui-branch-picker-root mr-2 -ml-2 inline-flex items-center text-muted-foreground text-xs",
1173
1205
  className,
1174
1206
  )}
1175
1207
  {...rest}
@@ -1196,98 +1228,329 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1196
1228
  ## components/assistant-ui/tool-fallback.tsx
1197
1229
 
1198
1230
  ```tsx
1199
- import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
1231
+ "use client";
1232
+
1233
+ import { memo, useCallback, useRef, useState } from "react";
1200
1234
  import {
1235
+ AlertCircleIcon,
1201
1236
  CheckIcon,
1202
1237
  ChevronDownIcon,
1203
- ChevronUpIcon,
1238
+ LoaderIcon,
1204
1239
  XCircleIcon,
1205
1240
  } from "lucide-react";
1206
- import { useState } from "react";
1207
- import { Button } from "@/components/ui/button";
1241
+ import {
1242
+ useScrollLock,
1243
+ type ToolCallMessagePartStatus,
1244
+ type ToolCallMessagePartComponent,
1245
+ } from "@assistant-ui/react";
1246
+ import {
1247
+ Collapsible,
1248
+ CollapsibleContent,
1249
+ CollapsibleTrigger,
1250
+ } from "@/components/ui/collapsible";
1208
1251
  import { cn } from "@/lib/utils";
1209
1252
 
1210
- export const ToolFallback: ToolCallMessagePartComponent = ({
1253
+ const ANIMATION_DURATION = 200;
1254
+
1255
+ export type ToolFallbackRootProps = Omit<
1256
+ React.ComponentProps<typeof Collapsible>,
1257
+ "open" | "onOpenChange"
1258
+ > & {
1259
+ open?: boolean;
1260
+ onOpenChange?: (open: boolean) => void;
1261
+ defaultOpen?: boolean;
1262
+ };
1263
+
1264
+ function ToolFallbackRoot({
1265
+ className,
1266
+ open: controlledOpen,
1267
+ onOpenChange: controlledOnOpenChange,
1268
+ defaultOpen = false,
1269
+ children,
1270
+ ...props
1271
+ }: ToolFallbackRootProps) {
1272
+ const collapsibleRef = useRef<HTMLDivElement>(null);
1273
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
1274
+ const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
1275
+
1276
+ const isControlled = controlledOpen !== undefined;
1277
+ const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1278
+
1279
+ const handleOpenChange = useCallback(
1280
+ (open: boolean) => {
1281
+ if (!open) {
1282
+ lockScroll();
1283
+ }
1284
+ if (!isControlled) {
1285
+ setUncontrolledOpen(open);
1286
+ }
1287
+ controlledOnOpenChange?.(open);
1288
+ },
1289
+ [lockScroll, isControlled, controlledOnOpenChange],
1290
+ );
1291
+
1292
+ return (
1293
+ <Collapsible
1294
+ ref={collapsibleRef}
1295
+ data-slot="tool-fallback-root"
1296
+ open={isOpen}
1297
+ onOpenChange={handleOpenChange}
1298
+ className={cn(
1299
+ "aui-tool-fallback-root group/tool-fallback-root w-full rounded-lg border py-3",
1300
+ className,
1301
+ )}
1302
+ style={
1303
+ {
1304
+ "--animation-duration": `${ANIMATION_DURATION}ms`,
1305
+ } as React.CSSProperties
1306
+ }
1307
+ {...props}
1308
+ >
1309
+ {children}
1310
+ </Collapsible>
1311
+ );
1312
+ }
1313
+
1314
+ type ToolStatus = ToolCallMessagePartStatus["type"];
1315
+
1316
+ const statusIconMap: Record<ToolStatus, React.ElementType> = {
1317
+ running: LoaderIcon,
1318
+ complete: CheckIcon,
1319
+ incomplete: XCircleIcon,
1320
+ "requires-action": AlertCircleIcon,
1321
+ };
1322
+
1323
+ function ToolFallbackTrigger({
1211
1324
  toolName,
1212
- argsText,
1213
- result,
1214
1325
  status,
1215
- }) => {
1216
- const [isCollapsed, setIsCollapsed] = useState(true);
1217
-
1326
+ className,
1327
+ ...props
1328
+ }: React.ComponentProps<typeof CollapsibleTrigger> & {
1329
+ toolName: string;
1330
+ status?: ToolCallMessagePartStatus;
1331
+ }) {
1332
+ const statusType = status?.type ?? "complete";
1333
+ const isRunning = statusType === "running";
1218
1334
  const isCancelled =
1219
1335
  status?.type === "incomplete" && status.reason === "cancelled";
1220
- const cancelledReason =
1221
- isCancelled && status.error
1222
- ? typeof status.error === "string"
1223
- ? status.error
1224
- : JSON.stringify(status.error)
1225
- : null;
1336
+
1337
+ const Icon = statusIconMap[statusType];
1338
+ const label = isCancelled ? "Cancelled tool" : "Used tool";
1226
1339
 
1227
1340
  return (
1228
- <div
1341
+ <CollapsibleTrigger
1342
+ data-slot="tool-fallback-trigger"
1229
1343
  className={cn(
1230
- "aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
1231
- isCancelled && "border-muted-foreground/30 bg-muted/30",
1344
+ "aui-tool-fallback-trigger group/trigger flex w-full items-center gap-2 px-4 text-sm transition-colors",
1345
+ className,
1232
1346
  )}
1347
+ {...props}
1233
1348
  >
1234
- <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1235
- {isCancelled ? (
1236
- <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1237
- ) : (
1238
- <CheckIcon className="aui-tool-fallback-icon size-4" />
1349
+ <Icon
1350
+ data-slot="tool-fallback-trigger-icon"
1351
+ className={cn(
1352
+ "aui-tool-fallback-trigger-icon size-4 shrink-0",
1353
+ isCancelled && "text-muted-foreground",
1354
+ isRunning && "animate-spin",
1239
1355
  )}
1240
- <p
1241
- className={cn(
1242
- "aui-tool-fallback-title grow",
1243
- isCancelled && "text-muted-foreground line-through",
1244
- )}
1245
- >
1246
- {isCancelled ? "Cancelled tool: " : "Used tool: "}
1247
- <b>{toolName}</b>
1248
- </p>
1249
- <Button onClick={() => setIsCollapsed(!isCollapsed)}>
1250
- {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
1251
- </Button>
1252
- </div>
1253
- {!isCollapsed && (
1254
- <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1255
- {cancelledReason && (
1256
- <div className="aui-tool-fallback-cancelled-root px-4">
1257
- <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1258
- Cancelled reason:
1259
- </p>
1260
- <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
1261
- {cancelledReason}
1262
- </p>
1263
- </div>
1264
- )}
1265
- <div
1266
- className={cn(
1267
- "aui-tool-fallback-args-root px-4",
1268
- isCancelled && "opacity-60",
1269
- )}
1356
+ />
1357
+ <span
1358
+ data-slot="tool-fallback-trigger-label"
1359
+ className={cn(
1360
+ "aui-tool-fallback-trigger-label-wrapper relative inline-block grow text-left leading-none",
1361
+ isCancelled && "text-muted-foreground line-through",
1362
+ )}
1363
+ >
1364
+ <span>
1365
+ {label}: <b>{toolName}</b>
1366
+ </span>
1367
+ {isRunning && (
1368
+ <span
1369
+ aria-hidden
1370
+ data-slot="tool-fallback-trigger-shimmer"
1371
+ className="aui-tool-fallback-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none"
1270
1372
  >
1271
- <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1272
- {argsText}
1273
- </pre>
1274
- </div>
1275
- {!isCancelled && result !== undefined && (
1276
- <div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
1277
- <p className="aui-tool-fallback-result-header font-semibold">
1278
- Result:
1279
- </p>
1280
- <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1281
- {typeof result === "string"
1282
- ? result
1283
- : JSON.stringify(result, null, 2)}
1284
- </pre>
1285
- </div>
1286
- )}
1287
- </div>
1373
+ {label}: <b>{toolName}</b>
1374
+ </span>
1375
+ )}
1376
+ </span>
1377
+ <ChevronDownIcon
1378
+ data-slot="tool-fallback-trigger-chevron"
1379
+ className={cn(
1380
+ "aui-tool-fallback-trigger-chevron size-4 shrink-0",
1381
+ "transition-transform duration-(--animation-duration) ease-out",
1382
+ "group-data-[state=closed]/trigger:-rotate-90",
1383
+ "group-data-[state=open]/trigger:rotate-0",
1384
+ )}
1385
+ />
1386
+ </CollapsibleTrigger>
1387
+ );
1388
+ }
1389
+
1390
+ function ToolFallbackContent({
1391
+ className,
1392
+ children,
1393
+ ...props
1394
+ }: React.ComponentProps<typeof CollapsibleContent>) {
1395
+ return (
1396
+ <CollapsibleContent
1397
+ data-slot="tool-fallback-content"
1398
+ className={cn(
1399
+ "aui-tool-fallback-content relative overflow-hidden text-sm outline-none",
1400
+ "group/collapsible-content ease-out",
1401
+ "data-[state=closed]:animate-collapsible-up",
1402
+ "data-[state=open]:animate-collapsible-down",
1403
+ "data-[state=closed]:fill-mode-forwards",
1404
+ "data-[state=closed]:pointer-events-none",
1405
+ "data-[state=open]:duration-(--animation-duration)",
1406
+ "data-[state=closed]:duration-(--animation-duration)",
1407
+ className,
1288
1408
  )}
1409
+ {...props}
1410
+ >
1411
+ <div className="mt-3 flex flex-col gap-2 border-t pt-2">{children}</div>
1412
+ </CollapsibleContent>
1413
+ );
1414
+ }
1415
+
1416
+ function ToolFallbackArgs({
1417
+ argsText,
1418
+ className,
1419
+ ...props
1420
+ }: React.ComponentProps<"div"> & {
1421
+ argsText?: string;
1422
+ }) {
1423
+ if (!argsText) return null;
1424
+
1425
+ return (
1426
+ <div
1427
+ data-slot="tool-fallback-args"
1428
+ className={cn("aui-tool-fallback-args px-4", className)}
1429
+ {...props}
1430
+ >
1431
+ <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1432
+ {argsText}
1433
+ </pre>
1289
1434
  </div>
1290
1435
  );
1436
+ }
1437
+
1438
+ function ToolFallbackResult({
1439
+ result,
1440
+ className,
1441
+ ...props
1442
+ }: React.ComponentProps<"div"> & {
1443
+ result?: unknown;
1444
+ }) {
1445
+ if (result === undefined) return null;
1446
+
1447
+ return (
1448
+ <div
1449
+ data-slot="tool-fallback-result"
1450
+ className={cn(
1451
+ "aui-tool-fallback-result border-t border-dashed px-4 pt-2",
1452
+ className,
1453
+ )}
1454
+ {...props}
1455
+ >
1456
+ <p className="aui-tool-fallback-result-header font-semibold">Result:</p>
1457
+ <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1458
+ {typeof result === "string" ? result : JSON.stringify(result, null, 2)}
1459
+ </pre>
1460
+ </div>
1461
+ );
1462
+ }
1463
+
1464
+ function ToolFallbackError({
1465
+ status,
1466
+ className,
1467
+ ...props
1468
+ }: React.ComponentProps<"div"> & {
1469
+ status?: ToolCallMessagePartStatus;
1470
+ }) {
1471
+ if (status?.type !== "incomplete") return null;
1472
+
1473
+ const error = status.error;
1474
+ const errorText = error
1475
+ ? typeof error === "string"
1476
+ ? error
1477
+ : JSON.stringify(error)
1478
+ : null;
1479
+
1480
+ if (!errorText) return null;
1481
+
1482
+ const isCancelled = status.reason === "cancelled";
1483
+ const headerText = isCancelled ? "Cancelled reason:" : "Error:";
1484
+
1485
+ return (
1486
+ <div
1487
+ data-slot="tool-fallback-error"
1488
+ className={cn("aui-tool-fallback-error px-4", className)}
1489
+ {...props}
1490
+ >
1491
+ <p className="aui-tool-fallback-error-header font-semibold text-muted-foreground">
1492
+ {headerText}
1493
+ </p>
1494
+ <p className="aui-tool-fallback-error-reason text-muted-foreground">
1495
+ {errorText}
1496
+ </p>
1497
+ </div>
1498
+ );
1499
+ }
1500
+
1501
+ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1502
+ toolName,
1503
+ argsText,
1504
+ result,
1505
+ status,
1506
+ }) => {
1507
+ const isCancelled =
1508
+ status?.type === "incomplete" && status.reason === "cancelled";
1509
+
1510
+ return (
1511
+ <ToolFallbackRoot
1512
+ className={cn(isCancelled && "border-muted-foreground/30 bg-muted/30")}
1513
+ >
1514
+ <ToolFallbackTrigger toolName={toolName} status={status} />
1515
+ <ToolFallbackContent>
1516
+ <ToolFallbackError status={status} />
1517
+ <ToolFallbackArgs
1518
+ argsText={argsText}
1519
+ className={cn(isCancelled && "opacity-60")}
1520
+ />
1521
+ {!isCancelled && <ToolFallbackResult result={result} />}
1522
+ </ToolFallbackContent>
1523
+ </ToolFallbackRoot>
1524
+ );
1525
+ };
1526
+
1527
+ const ToolFallback = memo(
1528
+ ToolFallbackImpl,
1529
+ ) as unknown as ToolCallMessagePartComponent & {
1530
+ Root: typeof ToolFallbackRoot;
1531
+ Trigger: typeof ToolFallbackTrigger;
1532
+ Content: typeof ToolFallbackContent;
1533
+ Args: typeof ToolFallbackArgs;
1534
+ Result: typeof ToolFallbackResult;
1535
+ Error: typeof ToolFallbackError;
1536
+ };
1537
+
1538
+ ToolFallback.displayName = "ToolFallback";
1539
+ ToolFallback.Root = ToolFallbackRoot;
1540
+ ToolFallback.Trigger = ToolFallbackTrigger;
1541
+ ToolFallback.Content = ToolFallbackContent;
1542
+ ToolFallback.Args = ToolFallbackArgs;
1543
+ ToolFallback.Result = ToolFallbackResult;
1544
+ ToolFallback.Error = ToolFallbackError;
1545
+
1546
+ export {
1547
+ ToolFallback,
1548
+ ToolFallbackRoot,
1549
+ ToolFallbackTrigger,
1550
+ ToolFallbackContent,
1551
+ ToolFallbackArgs,
1552
+ ToolFallbackResult,
1553
+ ToolFallbackError,
1291
1554
  };
1292
1555
 
1293
1556
  ```
@@ -1350,47 +1613,50 @@ import * as AvatarPrimitive from "@radix-ui/react-avatar";
1350
1613
 
1351
1614
  import { cn } from "@/lib/utils";
1352
1615
 
1353
- const Avatar = React.forwardRef<
1354
- React.ElementRef<typeof AvatarPrimitive.Root>,
1355
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
1356
- >(({ className, ...props }, ref) => (
1357
- <AvatarPrimitive.Root
1358
- ref={ref}
1359
- className={cn(
1360
- "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
1361
- className,
1362
- )}
1363
- {...props}
1364
- />
1365
- ));
1366
- Avatar.displayName = AvatarPrimitive.Root.displayName;
1367
-
1368
- const AvatarImage = React.forwardRef<
1369
- React.ElementRef<typeof AvatarPrimitive.Image>,
1370
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
1371
- >(({ className, ...props }, ref) => (
1372
- <AvatarPrimitive.Image
1373
- ref={ref}
1374
- className={cn("aspect-square h-full w-full", className)}
1375
- {...props}
1376
- />
1377
- ));
1378
- AvatarImage.displayName = AvatarPrimitive.Image.displayName;
1379
-
1380
- const AvatarFallback = React.forwardRef<
1381
- React.ElementRef<typeof AvatarPrimitive.Fallback>,
1382
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
1383
- >(({ className, ...props }, ref) => (
1384
- <AvatarPrimitive.Fallback
1385
- ref={ref}
1386
- className={cn(
1387
- "flex h-full w-full items-center justify-center rounded-full bg-muted",
1388
- className,
1389
- )}
1390
- {...props}
1391
- />
1392
- ));
1393
- AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
1616
+ function Avatar({
1617
+ className,
1618
+ ...props
1619
+ }: React.ComponentProps<typeof AvatarPrimitive.Root>) {
1620
+ return (
1621
+ <AvatarPrimitive.Root
1622
+ data-slot="avatar"
1623
+ className={cn(
1624
+ "relative flex size-8 shrink-0 overflow-hidden rounded-full",
1625
+ className,
1626
+ )}
1627
+ {...props}
1628
+ />
1629
+ );
1630
+ }
1631
+
1632
+ function AvatarImage({
1633
+ className,
1634
+ ...props
1635
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
1636
+ return (
1637
+ <AvatarPrimitive.Image
1638
+ data-slot="avatar-image"
1639
+ className={cn("aspect-square size-full", className)}
1640
+ {...props}
1641
+ />
1642
+ );
1643
+ }
1644
+
1645
+ function AvatarFallback({
1646
+ className,
1647
+ ...props
1648
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
1649
+ return (
1650
+ <AvatarPrimitive.Fallback
1651
+ data-slot="avatar-fallback"
1652
+ className={cn(
1653
+ "flex size-full items-center justify-center rounded-full bg-muted",
1654
+ className,
1655
+ )}
1656
+ {...props}
1657
+ />
1658
+ );
1659
+ }
1394
1660
 
1395
1661
  export { Avatar, AvatarImage, AvatarFallback };
1396
1662
 
@@ -1410,14 +1676,13 @@ const buttonVariants = cva(
1410
1676
  {
1411
1677
  variants: {
1412
1678
  variant: {
1413
- default:
1414
- "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
1679
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
1415
1680
  destructive:
1416
- "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",
1681
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
1417
1682
  outline:
1418
1683
  "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
1419
1684
  secondary:
1420
- "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
1685
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
1421
1686
  ghost:
1422
1687
  "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
1423
1688
  link: "text-primary underline-offset-4 hover:underline",
@@ -1427,6 +1692,8 @@ const buttonVariants = cva(
1427
1692
  sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
1428
1693
  lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
1429
1694
  icon: "size-9",
1695
+ "icon-sm": "size-8",
1696
+ "icon-lg": "size-10",
1430
1697
  },
1431
1698
  },
1432
1699
  defaultVariants: {
@@ -1438,8 +1705,8 @@ const buttonVariants = cva(
1438
1705
 
1439
1706
  function Button({
1440
1707
  className,
1441
- variant,
1442
- size,
1708
+ variant = "default",
1709
+ size = "default",
1443
1710
  asChild = false,
1444
1711
  ...props
1445
1712
  }: React.ComponentProps<"button"> &
@@ -1451,6 +1718,8 @@ function Button({
1451
1718
  return (
1452
1719
  <Comp
1453
1720
  data-slot="button"
1721
+ data-variant={variant}
1722
+ data-size={size}
1454
1723
  className={cn(buttonVariants({ variant, size, className }))}
1455
1724
  {...props}
1456
1725
  />
@@ -1461,6 +1730,45 @@ export { Button, buttonVariants };
1461
1730
 
1462
1731
  ```
1463
1732
 
1733
+ ## components/ui/collapsible.tsx
1734
+
1735
+ ```tsx
1736
+ "use client";
1737
+
1738
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
1739
+
1740
+ function Collapsible({
1741
+ ...props
1742
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
1743
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
1744
+ }
1745
+
1746
+ function CollapsibleTrigger({
1747
+ ...props
1748
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
1749
+ return (
1750
+ <CollapsiblePrimitive.CollapsibleTrigger
1751
+ data-slot="collapsible-trigger"
1752
+ {...props}
1753
+ />
1754
+ );
1755
+ }
1756
+
1757
+ function CollapsibleContent({
1758
+ ...props
1759
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
1760
+ return (
1761
+ <CollapsiblePrimitive.CollapsibleContent
1762
+ data-slot="collapsible-content"
1763
+ {...props}
1764
+ />
1765
+ );
1766
+ }
1767
+
1768
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent };
1769
+
1770
+ ```
1771
+
1464
1772
  ## components/ui/dialog.tsx
1465
1773
 
1466
1774
  ```tsx
@@ -1504,7 +1812,7 @@ function DialogOverlay({
1504
1812
  <DialogPrimitive.Overlay
1505
1813
  data-slot="dialog-overlay"
1506
1814
  className={cn(
1507
- "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",
1815
+ "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",
1508
1816
  className,
1509
1817
  )}
1510
1818
  {...props}
@@ -1515,24 +1823,32 @@ function DialogOverlay({
1515
1823
  function DialogContent({
1516
1824
  className,
1517
1825
  children,
1826
+ showCloseButton = true,
1518
1827
  ...props
1519
- }: React.ComponentProps<typeof DialogPrimitive.Content>) {
1828
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
1829
+ showCloseButton?: boolean;
1830
+ }) {
1520
1831
  return (
1521
1832
  <DialogPortal data-slot="dialog-portal">
1522
1833
  <DialogOverlay />
1523
1834
  <DialogPrimitive.Content
1524
1835
  data-slot="dialog-content"
1525
1836
  className={cn(
1526
- "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",
1837
+ "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",
1527
1838
  className,
1528
1839
  )}
1529
1840
  {...props}
1530
1841
  >
1531
1842
  {children}
1532
- <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">
1533
- <XIcon />
1534
- <span className="sr-only">Close</span>
1535
- </DialogPrimitive.Close>
1843
+ {showCloseButton && (
1844
+ <DialogPrimitive.Close
1845
+ data-slot="dialog-close"
1846
+ 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"
1847
+ >
1848
+ <XIcon />
1849
+ <span className="sr-only">Close</span>
1850
+ </DialogPrimitive.Close>
1851
+ )}
1536
1852
  </DialogPrimitive.Content>
1537
1853
  </DialogPortal>
1538
1854
  );
@@ -1672,13 +1988,13 @@ function TooltipContent({
1672
1988
  data-slot="tooltip-content"
1673
1989
  sideOffset={sideOffset}
1674
1990
  className={cn(
1675
- "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",
1991
+ "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",
1676
1992
  className,
1677
1993
  )}
1678
1994
  {...props}
1679
1995
  >
1680
1996
  {children}
1681
- <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-primary fill-primary" />
1997
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
1682
1998
  </TooltipPrimitive.Content>
1683
1999
  </TooltipPrimitive.Portal>
1684
2000
  );
@@ -1718,45 +2034,45 @@ export default nextConfig;
1718
2034
  ```json
1719
2035
  {
1720
2036
  "name": "with-cloud",
1721
- "version": "0.1.0",
2037
+ "version": "0.0.0",
1722
2038
  "private": true,
2039
+ "type": "module",
1723
2040
  "scripts": {
1724
- "dev": "next dev --turbo",
2041
+ "dev": "next dev",
1725
2042
  "build": "next build",
1726
2043
  "start": "next start"
1727
2044
  },
1728
2045
  "dependencies": {
1729
- "@ai-sdk/openai": "^2.0.84",
2046
+ "@ai-sdk/openai": "^3.0.13",
1730
2047
  "@assistant-ui/react": "workspace:*",
1731
2048
  "@assistant-ui/react-ai-sdk": "workspace:*",
1732
2049
  "@assistant-ui/react-markdown": "workspace:*",
1733
2050
  "@radix-ui/react-avatar": "^1.1.11",
2051
+ "@radix-ui/react-collapsible": "^1.1.12",
1734
2052
  "@radix-ui/react-dialog": "^1.1.15",
1735
2053
  "@radix-ui/react-slot": "^1.2.4",
1736
2054
  "@radix-ui/react-tooltip": "^1.2.8",
1737
- "ai": "^5.0.112",
2055
+ "ai": "^6.0.42",
1738
2056
  "class-variance-authority": "^0.7.1",
1739
2057
  "clsx": "^2.1.1",
1740
- "jsonwebtoken": "^9.0.3",
1741
- "lucide-react": "^0.560.0",
1742
- "nanoid": "5.1.6",
1743
- "next": "16.0.10",
1744
- "react": "19.2.3",
1745
- "react-dom": "19.2.3",
2058
+ "lucide-react": "^0.562.0",
2059
+ "next": "^16.1.4",
2060
+ "react": "^19.2.3",
2061
+ "react-dom": "^19.2.3",
1746
2062
  "remark-gfm": "^4.0.1",
1747
2063
  "tailwind-merge": "^3.4.0",
1748
- "tw-animate-css": "^1.4.0",
1749
- "zustand": "^5.0.9"
2064
+ "zustand": "^5.0.10"
1750
2065
  },
1751
2066
  "devDependencies": {
1752
2067
  "@assistant-ui/x-buildutils": "workspace:*",
1753
- "@types/jsonwebtoken": "^9.0.10",
1754
- "@types/node": "^25",
1755
- "@types/react": "^19",
1756
- "@types/react-dom": "^19",
1757
- "postcss": "^8",
2068
+ "@tailwindcss/postcss": "^4.1.18",
2069
+ "@types/node": "^25.0.9",
2070
+ "@types/react": "^19.2.9",
2071
+ "@types/react-dom": "^19.2.3",
2072
+ "postcss": "^8.5.6",
1758
2073
  "tailwindcss": "^4.1.18",
1759
- "typescript": "^5"
2074
+ "tw-animate-css": "^1.4.0",
2075
+ "typescript": "^5.9.3"
1760
2076
  }
1761
2077
  }
1762
2078
 
@@ -1766,29 +2082,11 @@ export default nextConfig;
1766
2082
 
1767
2083
  ```json
1768
2084
  {
1769
- "extends": "@assistant-ui/x-buildutils/ts/base",
2085
+ "extends": "@assistant-ui/x-buildutils/ts/next",
1770
2086
  "compilerOptions": {
1771
- "target": "ES6",
1772
- "module": "ESNext",
1773
- "incremental": true,
1774
- "plugins": [
1775
- {
1776
- "name": "next"
1777
- }
1778
- ],
1779
- "allowJs": true,
1780
- "strictNullChecks": true,
1781
- "jsx": "preserve",
1782
- "paths": {
1783
- "@/*": ["./*"],
1784
- "@assistant-ui/*": ["../../packages/*/src"],
1785
- "@assistant-ui/react/*": ["../../packages/react/src/*"],
1786
- "@assistant-ui/tap/*": ["../../packages/tap/src/*"],
1787
- "assistant-stream": ["../../packages/assistant-stream/src"],
1788
- "assistant-stream/*": ["../../packages/assistant-stream/src/*"]
1789
- }
2087
+ "paths": { "@/*": ["./*"] }
1790
2088
  },
1791
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
2089
+ "include": ["**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
1792
2090
  "exclude": ["node_modules"]
1793
2091
  }
1794
2092