@assistant-ui/mcp-docs-server 0.1.18 → 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 (132) hide show
  1. package/.docs/organized/code-examples/with-ag-ui.md +375 -85
  2. package/.docs/organized/code-examples/{with-ai-sdk-v5.md → with-ai-sdk-v6.md} +386 -94
  3. package/.docs/organized/code-examples/with-assistant-transport.md +374 -84
  4. package/.docs/organized/code-examples/with-cloud.md +405 -100
  5. package/.docs/organized/code-examples/with-custom-thread-list.md +412 -105
  6. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +2241 -0
  7. package/.docs/organized/code-examples/with-external-store.md +374 -83
  8. package/.docs/organized/code-examples/with-ffmpeg.md +377 -87
  9. package/.docs/organized/code-examples/with-langgraph.md +403 -98
  10. package/.docs/organized/code-examples/with-parent-id-grouping.md +374 -83
  11. package/.docs/organized/code-examples/with-react-hook-form.md +379 -89
  12. package/.docs/organized/code-examples/with-react-router.md +2167 -0
  13. package/.docs/organized/code-examples/with-store.md +5 -5
  14. package/.docs/organized/code-examples/with-tanstack.md +10 -10
  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 +2 -3
  85. package/.docs/raw/docs/runtimes/custom/external-store.mdx +6 -8
  86. package/.docs/raw/docs/runtimes/custom/local.mdx +12 -8
  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 -1
  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/tools/docs.js +1 -1
  115. package/dist/tools/examples.js +1 -1
  116. package/dist/tools/examples.js.map +1 -1
  117. package/package.json +5 -5
  118. package/src/tools/docs.ts +1 -1
  119. package/src/tools/examples.ts +1 -1
  120. package/src/tools/tests/docs.test.ts +18 -16
  121. package/src/tools/tests/examples.test.ts +5 -5
  122. package/src/tools/tests/path-traversal.test.ts +3 -3
  123. package/src/utils/tests/security.test.ts +3 -3
  124. package/.docs/raw/docs/index.mdx +0 -7
  125. package/.docs/raw/docs/ui/AssistantModal.mdx +0 -45
  126. package/.docs/raw/docs/ui/AssistantSidebar.mdx +0 -41
  127. package/.docs/raw/docs/ui/Attachment.mdx +0 -84
  128. package/.docs/raw/docs/ui/Reasoning.mdx +0 -152
  129. package/.docs/raw/docs/ui/ThreadList.mdx +0 -90
  130. package/.docs/raw/docs/ui/ToolFallback.mdx +0 -63
  131. package/.docs/raw/docs/ui/ToolGroup.mdx +0 -96
  132. /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: {
@@ -502,7 +502,7 @@ export const ComposerAddAttachment: FC = () => {
502
502
  side="bottom"
503
503
  variant="ghost"
504
504
  size="icon"
505
- 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"
506
506
  aria-label="Add Attachment"
507
507
  >
508
508
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -750,15 +750,15 @@ const defaultComponents = memoizeMarkdownComponents({
750
750
  ## components/assistant-ui/thread-list.tsx
751
751
 
752
752
  ```tsx
753
- import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
754
753
  import { Button } from "@/components/ui/button";
755
754
  import { Skeleton } from "@/components/ui/skeleton";
756
755
  import {
757
756
  AssistantIf,
757
+ ThreadListItemMorePrimitive,
758
758
  ThreadListItemPrimitive,
759
759
  ThreadListPrimitive,
760
760
  } from "@assistant-ui/react";
761
- import { ArchiveIcon, PlusIcon } from "lucide-react";
761
+ import { ArchiveIcon, MoreHorizontalIcon, PlusIcon } from "lucide-react";
762
762
  import type { FC } from "react";
763
763
 
764
764
  export const ThreadList: FC = () => {
@@ -808,26 +808,41 @@ const ThreadListSkeleton: FC = () => {
808
808
 
809
809
  const ThreadListItem: FC = () => {
810
810
  return (
811
- <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">
812
- <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">
813
813
  <ThreadListItemPrimitive.Title fallback="New Chat" />
814
814
  </ThreadListItemPrimitive.Trigger>
815
- <ThreadListItemArchive />
815
+ <ThreadListItemMore />
816
816
  </ThreadListItemPrimitive.Root>
817
817
  );
818
818
  };
819
819
 
820
- const ThreadListItemArchive: FC = () => {
820
+ const ThreadListItemMore: FC = () => {
821
821
  return (
822
- <ThreadListItemPrimitive.Archive asChild>
823
- <TooltipIconButton
824
- variant="ghost"
825
- tooltip="Archive thread"
826
- 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"
827
837
  >
828
- <ArchiveIcon className="size-4" />
829
- </TooltipIconButton>
830
- </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>
831
846
  );
832
847
  };
833
848
 
@@ -847,6 +862,7 @@ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button
847
862
  import { Button } from "@/components/ui/button";
848
863
  import { cn } from "@/lib/utils";
849
864
  import {
865
+ ActionBarMorePrimitive,
850
866
  ActionBarPrimitive,
851
867
  AssistantIf,
852
868
  BranchPickerPrimitive,
@@ -863,6 +879,7 @@ import {
863
879
  ChevronRightIcon,
864
880
  CopyIcon,
865
881
  DownloadIcon,
882
+ MoreHorizontalIcon,
866
883
  PencilIcon,
867
884
  RefreshCwIcon,
868
885
  SquareIcon,
@@ -1084,16 +1101,33 @@ const AssistantActionBar: FC = () => {
1084
1101
  </AssistantIf>
1085
1102
  </TooltipIconButton>
1086
1103
  </ActionBarPrimitive.Copy>
1087
- <ActionBarPrimitive.ExportMarkdown asChild>
1088
- <TooltipIconButton tooltip="Export as Markdown">
1089
- <DownloadIcon />
1090
- </TooltipIconButton>
1091
- </ActionBarPrimitive.ExportMarkdown>
1092
1104
  <ActionBarPrimitive.Reload asChild>
1093
1105
  <TooltipIconButton tooltip="Refresh">
1094
1106
  <RefreshCwIcon />
1095
1107
  </TooltipIconButton>
1096
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>
1097
1131
  </ActionBarPrimitive.Root>
1098
1132
  );
1099
1133
  };
@@ -1194,98 +1228,329 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1194
1228
  ## components/assistant-ui/tool-fallback.tsx
1195
1229
 
1196
1230
  ```tsx
1197
- import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
1231
+ "use client";
1232
+
1233
+ import { memo, useCallback, useRef, useState } from "react";
1198
1234
  import {
1235
+ AlertCircleIcon,
1199
1236
  CheckIcon,
1200
1237
  ChevronDownIcon,
1201
- ChevronUpIcon,
1238
+ LoaderIcon,
1202
1239
  XCircleIcon,
1203
1240
  } from "lucide-react";
1204
- import { useState } from "react";
1205
- 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";
1206
1251
  import { cn } from "@/lib/utils";
1207
1252
 
1208
- 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({
1209
1324
  toolName,
1210
- argsText,
1211
- result,
1212
1325
  status,
1213
- }) => {
1214
- const [isCollapsed, setIsCollapsed] = useState(true);
1215
-
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";
1216
1334
  const isCancelled =
1217
1335
  status?.type === "incomplete" && status.reason === "cancelled";
1218
- const cancelledReason =
1219
- isCancelled && status.error
1220
- ? typeof status.error === "string"
1221
- ? status.error
1222
- : JSON.stringify(status.error)
1223
- : null;
1336
+
1337
+ const Icon = statusIconMap[statusType];
1338
+ const label = isCancelled ? "Cancelled tool" : "Used tool";
1224
1339
 
1225
1340
  return (
1226
- <div
1341
+ <CollapsibleTrigger
1342
+ data-slot="tool-fallback-trigger"
1227
1343
  className={cn(
1228
- "aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
1229
- 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,
1230
1346
  )}
1347
+ {...props}
1231
1348
  >
1232
- <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1233
- {isCancelled ? (
1234
- <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1235
- ) : (
1236
- <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",
1237
1355
  )}
1238
- <p
1239
- className={cn(
1240
- "aui-tool-fallback-title grow",
1241
- isCancelled && "text-muted-foreground line-through",
1242
- )}
1243
- >
1244
- {isCancelled ? "Cancelled tool: " : "Used tool: "}
1245
- <b>{toolName}</b>
1246
- </p>
1247
- <Button onClick={() => setIsCollapsed(!isCollapsed)}>
1248
- {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
1249
- </Button>
1250
- </div>
1251
- {!isCollapsed && (
1252
- <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1253
- {cancelledReason && (
1254
- <div className="aui-tool-fallback-cancelled-root px-4">
1255
- <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1256
- Cancelled reason:
1257
- </p>
1258
- <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
1259
- {cancelledReason}
1260
- </p>
1261
- </div>
1262
- )}
1263
- <div
1264
- className={cn(
1265
- "aui-tool-fallback-args-root px-4",
1266
- isCancelled && "opacity-60",
1267
- )}
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"
1268
1372
  >
1269
- <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1270
- {argsText}
1271
- </pre>
1272
- </div>
1273
- {!isCancelled && result !== undefined && (
1274
- <div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
1275
- <p className="aui-tool-fallback-result-header font-semibold">
1276
- Result:
1277
- </p>
1278
- <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1279
- {typeof result === "string"
1280
- ? result
1281
- : JSON.stringify(result, null, 2)}
1282
- </pre>
1283
- </div>
1284
- )}
1285
- </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,
1286
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>
1287
1434
  </div>
1288
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,
1289
1554
  };
1290
1555
 
1291
1556
  ```
@@ -1465,6 +1730,45 @@ export { Button, buttonVariants };
1465
1730
 
1466
1731
  ```
1467
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
+
1468
1772
  ## components/ui/dialog.tsx
1469
1773
 
1470
1774
  ```tsx
@@ -1739,30 +2043,31 @@ export default nextConfig;
1739
2043
  "start": "next start"
1740
2044
  },
1741
2045
  "dependencies": {
1742
- "@ai-sdk/openai": "^2.0.88",
2046
+ "@ai-sdk/openai": "^3.0.13",
1743
2047
  "@assistant-ui/react": "workspace:*",
1744
2048
  "@assistant-ui/react-ai-sdk": "workspace:*",
1745
2049
  "@assistant-ui/react-markdown": "workspace:*",
1746
2050
  "@radix-ui/react-avatar": "^1.1.11",
2051
+ "@radix-ui/react-collapsible": "^1.1.12",
1747
2052
  "@radix-ui/react-dialog": "^1.1.15",
1748
2053
  "@radix-ui/react-slot": "^1.2.4",
1749
2054
  "@radix-ui/react-tooltip": "^1.2.8",
1750
- "ai": "^5.0.116",
2055
+ "ai": "^6.0.42",
1751
2056
  "class-variance-authority": "^0.7.1",
1752
2057
  "clsx": "^2.1.1",
1753
2058
  "lucide-react": "^0.562.0",
1754
- "next": "16.1.0",
1755
- "react": "19.2.3",
1756
- "react-dom": "19.2.3",
2059
+ "next": "^16.1.4",
2060
+ "react": "^19.2.3",
2061
+ "react-dom": "^19.2.3",
1757
2062
  "remark-gfm": "^4.0.1",
1758
2063
  "tailwind-merge": "^3.4.0",
1759
- "zustand": "^5.0.9"
2064
+ "zustand": "^5.0.10"
1760
2065
  },
1761
2066
  "devDependencies": {
1762
2067
  "@assistant-ui/x-buildutils": "workspace:*",
1763
2068
  "@tailwindcss/postcss": "^4.1.18",
1764
- "@types/node": "^25.0.3",
1765
- "@types/react": "^19.2.7",
2069
+ "@types/node": "^25.0.9",
2070
+ "@types/react": "^19.2.9",
1766
2071
  "@types/react-dom": "^19.2.3",
1767
2072
  "postcss": "^8.5.6",
1768
2073
  "tailwindcss": "^4.1.18",