@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
@@ -10,6 +10,7 @@ import {
10
10
  convertToModelMessages,
11
11
  tool,
12
12
  stepCountIs,
13
+ zodSchema,
13
14
  } from "ai";
14
15
  import { z } from "zod";
15
16
 
@@ -21,15 +22,16 @@ export async function POST(req: Request) {
21
22
 
22
23
  const result = streamText({
23
24
  model: openai("gpt-4o"),
24
- messages: convertToModelMessages(messages),
25
+ messages: await convertToModelMessages(messages),
25
26
  stopWhen: stepCountIs(10),
26
27
  tools: {
27
28
  get_current_weather: tool({
28
- name: "",
29
29
  description: "Get the current weather",
30
- inputSchema: z.object({
31
- city: z.string(),
32
- }),
30
+ inputSchema: zodSchema(
31
+ z.object({
32
+ city: z.string(),
33
+ }),
34
+ ),
33
35
  execute: async ({ city }) => {
34
36
  return `The weather in ${city} is sunny`;
35
37
  },
@@ -562,7 +564,7 @@ export const ComposerAddAttachment: FC = () => {
562
564
  side="bottom"
563
565
  variant="ghost"
564
566
  size="icon"
565
- 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"
567
+ 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"
566
568
  aria-label="Add Attachment"
567
569
  >
568
570
  <PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
@@ -810,15 +812,15 @@ const defaultComponents = memoizeMarkdownComponents({
810
812
  ## components/assistant-ui/thread-list.tsx
811
813
 
812
814
  ```tsx
813
- import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
814
815
  import { Button } from "@/components/ui/button";
815
816
  import { Skeleton } from "@/components/ui/skeleton";
816
817
  import {
817
818
  AssistantIf,
819
+ ThreadListItemMorePrimitive,
818
820
  ThreadListItemPrimitive,
819
821
  ThreadListPrimitive,
820
822
  } from "@assistant-ui/react";
821
- import { ArchiveIcon, PlusIcon } from "lucide-react";
823
+ import { ArchiveIcon, MoreHorizontalIcon, PlusIcon } from "lucide-react";
822
824
  import type { FC } from "react";
823
825
 
824
826
  export const ThreadList: FC = () => {
@@ -868,26 +870,41 @@ const ThreadListSkeleton: FC = () => {
868
870
 
869
871
  const ThreadListItem: FC = () => {
870
872
  return (
871
- <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">
872
- <ThreadListItemPrimitive.Trigger className="aui-thread-list-item-trigger flex h-full flex-1 items-center truncate px-3 text-start text-sm">
873
+ <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">
874
+ <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">
873
875
  <ThreadListItemPrimitive.Title fallback="New Chat" />
874
876
  </ThreadListItemPrimitive.Trigger>
875
- <ThreadListItemArchive />
877
+ <ThreadListItemMore />
876
878
  </ThreadListItemPrimitive.Root>
877
879
  );
878
880
  };
879
881
 
880
- const ThreadListItemArchive: FC = () => {
882
+ const ThreadListItemMore: FC = () => {
881
883
  return (
882
- <ThreadListItemPrimitive.Archive asChild>
883
- <TooltipIconButton
884
- variant="ghost"
885
- tooltip="Archive thread"
886
- className="aui-thread-list-item-archive mr-2 size-7 p-0 opacity-0 transition-opacity group-hover:opacity-100"
884
+ <ThreadListItemMorePrimitive.Root>
885
+ <ThreadListItemMorePrimitive.Trigger asChild>
886
+ <Button
887
+ variant="ghost"
888
+ size="icon"
889
+ 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"
890
+ >
891
+ <MoreHorizontalIcon className="size-4" />
892
+ <span className="sr-only">More options</span>
893
+ </Button>
894
+ </ThreadListItemMorePrimitive.Trigger>
895
+ <ThreadListItemMorePrimitive.Content
896
+ side="bottom"
897
+ align="start"
898
+ 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"
887
899
  >
888
- <ArchiveIcon className="size-4" />
889
- </TooltipIconButton>
890
- </ThreadListItemPrimitive.Archive>
900
+ <ThreadListItemPrimitive.Archive asChild>
901
+ <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">
902
+ <ArchiveIcon className="size-4" />
903
+ Archive
904
+ </ThreadListItemMorePrimitive.Item>
905
+ </ThreadListItemPrimitive.Archive>
906
+ </ThreadListItemMorePrimitive.Content>
907
+ </ThreadListItemMorePrimitive.Root>
891
908
  );
892
909
  };
893
910
 
@@ -907,6 +924,7 @@ import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button
907
924
  import { Button } from "@/components/ui/button";
908
925
  import { cn } from "@/lib/utils";
909
926
  import {
927
+ ActionBarMorePrimitive,
910
928
  ActionBarPrimitive,
911
929
  AssistantIf,
912
930
  BranchPickerPrimitive,
@@ -923,6 +941,7 @@ import {
923
941
  ChevronRightIcon,
924
942
  CopyIcon,
925
943
  DownloadIcon,
944
+ MoreHorizontalIcon,
926
945
  PencilIcon,
927
946
  RefreshCwIcon,
928
947
  SquareIcon,
@@ -1144,16 +1163,33 @@ const AssistantActionBar: FC = () => {
1144
1163
  </AssistantIf>
1145
1164
  </TooltipIconButton>
1146
1165
  </ActionBarPrimitive.Copy>
1147
- <ActionBarPrimitive.ExportMarkdown asChild>
1148
- <TooltipIconButton tooltip="Export as Markdown">
1149
- <DownloadIcon />
1150
- </TooltipIconButton>
1151
- </ActionBarPrimitive.ExportMarkdown>
1152
1166
  <ActionBarPrimitive.Reload asChild>
1153
1167
  <TooltipIconButton tooltip="Refresh">
1154
1168
  <RefreshCwIcon />
1155
1169
  </TooltipIconButton>
1156
1170
  </ActionBarPrimitive.Reload>
1171
+ <ActionBarMorePrimitive.Root>
1172
+ <ActionBarMorePrimitive.Trigger asChild>
1173
+ <TooltipIconButton
1174
+ tooltip="More"
1175
+ className="data-[state=open]:bg-accent"
1176
+ >
1177
+ <MoreHorizontalIcon />
1178
+ </TooltipIconButton>
1179
+ </ActionBarMorePrimitive.Trigger>
1180
+ <ActionBarMorePrimitive.Content
1181
+ side="bottom"
1182
+ align="start"
1183
+ 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"
1184
+ >
1185
+ <ActionBarPrimitive.ExportMarkdown asChild>
1186
+ <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">
1187
+ <DownloadIcon className="size-4" />
1188
+ Export as Markdown
1189
+ </ActionBarMorePrimitive.Item>
1190
+ </ActionBarPrimitive.ExportMarkdown>
1191
+ </ActionBarMorePrimitive.Content>
1192
+ </ActionBarMorePrimitive.Root>
1157
1193
  </ActionBarPrimitive.Root>
1158
1194
  );
1159
1195
  };
@@ -1254,98 +1290,329 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
1254
1290
  ## components/assistant-ui/tool-fallback.tsx
1255
1291
 
1256
1292
  ```tsx
1257
- import type { ToolCallMessagePartComponent } from "@assistant-ui/react";
1293
+ "use client";
1294
+
1295
+ import { memo, useCallback, useRef, useState } from "react";
1258
1296
  import {
1297
+ AlertCircleIcon,
1259
1298
  CheckIcon,
1260
1299
  ChevronDownIcon,
1261
- ChevronUpIcon,
1300
+ LoaderIcon,
1262
1301
  XCircleIcon,
1263
1302
  } from "lucide-react";
1264
- import { useState } from "react";
1265
- import { Button } from "@/components/ui/button";
1303
+ import {
1304
+ useScrollLock,
1305
+ type ToolCallMessagePartStatus,
1306
+ type ToolCallMessagePartComponent,
1307
+ } from "@assistant-ui/react";
1308
+ import {
1309
+ Collapsible,
1310
+ CollapsibleContent,
1311
+ CollapsibleTrigger,
1312
+ } from "@/components/ui/collapsible";
1266
1313
  import { cn } from "@/lib/utils";
1267
1314
 
1268
- export const ToolFallback: ToolCallMessagePartComponent = ({
1315
+ const ANIMATION_DURATION = 200;
1316
+
1317
+ export type ToolFallbackRootProps = Omit<
1318
+ React.ComponentProps<typeof Collapsible>,
1319
+ "open" | "onOpenChange"
1320
+ > & {
1321
+ open?: boolean;
1322
+ onOpenChange?: (open: boolean) => void;
1323
+ defaultOpen?: boolean;
1324
+ };
1325
+
1326
+ function ToolFallbackRoot({
1327
+ className,
1328
+ open: controlledOpen,
1329
+ onOpenChange: controlledOnOpenChange,
1330
+ defaultOpen = false,
1331
+ children,
1332
+ ...props
1333
+ }: ToolFallbackRootProps) {
1334
+ const collapsibleRef = useRef<HTMLDivElement>(null);
1335
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
1336
+ const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
1337
+
1338
+ const isControlled = controlledOpen !== undefined;
1339
+ const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
1340
+
1341
+ const handleOpenChange = useCallback(
1342
+ (open: boolean) => {
1343
+ if (!open) {
1344
+ lockScroll();
1345
+ }
1346
+ if (!isControlled) {
1347
+ setUncontrolledOpen(open);
1348
+ }
1349
+ controlledOnOpenChange?.(open);
1350
+ },
1351
+ [lockScroll, isControlled, controlledOnOpenChange],
1352
+ );
1353
+
1354
+ return (
1355
+ <Collapsible
1356
+ ref={collapsibleRef}
1357
+ data-slot="tool-fallback-root"
1358
+ open={isOpen}
1359
+ onOpenChange={handleOpenChange}
1360
+ className={cn(
1361
+ "aui-tool-fallback-root group/tool-fallback-root w-full rounded-lg border py-3",
1362
+ className,
1363
+ )}
1364
+ style={
1365
+ {
1366
+ "--animation-duration": `${ANIMATION_DURATION}ms`,
1367
+ } as React.CSSProperties
1368
+ }
1369
+ {...props}
1370
+ >
1371
+ {children}
1372
+ </Collapsible>
1373
+ );
1374
+ }
1375
+
1376
+ type ToolStatus = ToolCallMessagePartStatus["type"];
1377
+
1378
+ const statusIconMap: Record<ToolStatus, React.ElementType> = {
1379
+ running: LoaderIcon,
1380
+ complete: CheckIcon,
1381
+ incomplete: XCircleIcon,
1382
+ "requires-action": AlertCircleIcon,
1383
+ };
1384
+
1385
+ function ToolFallbackTrigger({
1269
1386
  toolName,
1270
- argsText,
1271
- result,
1272
1387
  status,
1273
- }) => {
1274
- const [isCollapsed, setIsCollapsed] = useState(true);
1275
-
1388
+ className,
1389
+ ...props
1390
+ }: React.ComponentProps<typeof CollapsibleTrigger> & {
1391
+ toolName: string;
1392
+ status?: ToolCallMessagePartStatus;
1393
+ }) {
1394
+ const statusType = status?.type ?? "complete";
1395
+ const isRunning = statusType === "running";
1276
1396
  const isCancelled =
1277
1397
  status?.type === "incomplete" && status.reason === "cancelled";
1278
- const cancelledReason =
1279
- isCancelled && status.error
1280
- ? typeof status.error === "string"
1281
- ? status.error
1282
- : JSON.stringify(status.error)
1283
- : null;
1398
+
1399
+ const Icon = statusIconMap[statusType];
1400
+ const label = isCancelled ? "Cancelled tool" : "Used tool";
1284
1401
 
1285
1402
  return (
1286
- <div
1403
+ <CollapsibleTrigger
1404
+ data-slot="tool-fallback-trigger"
1287
1405
  className={cn(
1288
- "aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3",
1289
- isCancelled && "border-muted-foreground/30 bg-muted/30",
1406
+ "aui-tool-fallback-trigger group/trigger flex w-full items-center gap-2 px-4 text-sm transition-colors",
1407
+ className,
1290
1408
  )}
1409
+ {...props}
1291
1410
  >
1292
- <div className="aui-tool-fallback-header flex items-center gap-2 px-4">
1293
- {isCancelled ? (
1294
- <XCircleIcon className="aui-tool-fallback-icon size-4 text-muted-foreground" />
1295
- ) : (
1296
- <CheckIcon className="aui-tool-fallback-icon size-4" />
1411
+ <Icon
1412
+ data-slot="tool-fallback-trigger-icon"
1413
+ className={cn(
1414
+ "aui-tool-fallback-trigger-icon size-4 shrink-0",
1415
+ isCancelled && "text-muted-foreground",
1416
+ isRunning && "animate-spin",
1297
1417
  )}
1298
- <p
1299
- className={cn(
1300
- "aui-tool-fallback-title grow",
1301
- isCancelled && "text-muted-foreground line-through",
1302
- )}
1303
- >
1304
- {isCancelled ? "Cancelled tool: " : "Used tool: "}
1305
- <b>{toolName}</b>
1306
- </p>
1307
- <Button onClick={() => setIsCollapsed(!isCollapsed)}>
1308
- {isCollapsed ? <ChevronUpIcon /> : <ChevronDownIcon />}
1309
- </Button>
1310
- </div>
1311
- {!isCollapsed && (
1312
- <div className="aui-tool-fallback-content flex flex-col gap-2 border-t pt-2">
1313
- {cancelledReason && (
1314
- <div className="aui-tool-fallback-cancelled-root px-4">
1315
- <p className="aui-tool-fallback-cancelled-header font-semibold text-muted-foreground">
1316
- Cancelled reason:
1317
- </p>
1318
- <p className="aui-tool-fallback-cancelled-reason text-muted-foreground">
1319
- {cancelledReason}
1320
- </p>
1321
- </div>
1322
- )}
1323
- <div
1324
- className={cn(
1325
- "aui-tool-fallback-args-root px-4",
1326
- isCancelled && "opacity-60",
1327
- )}
1418
+ />
1419
+ <span
1420
+ data-slot="tool-fallback-trigger-label"
1421
+ className={cn(
1422
+ "aui-tool-fallback-trigger-label-wrapper relative inline-block grow text-left leading-none",
1423
+ isCancelled && "text-muted-foreground line-through",
1424
+ )}
1425
+ >
1426
+ <span>
1427
+ {label}: <b>{toolName}</b>
1428
+ </span>
1429
+ {isRunning && (
1430
+ <span
1431
+ aria-hidden
1432
+ data-slot="tool-fallback-trigger-shimmer"
1433
+ className="aui-tool-fallback-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none"
1328
1434
  >
1329
- <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1330
- {argsText}
1331
- </pre>
1332
- </div>
1333
- {!isCancelled && result !== undefined && (
1334
- <div className="aui-tool-fallback-result-root border-t border-dashed px-4 pt-2">
1335
- <p className="aui-tool-fallback-result-header font-semibold">
1336
- Result:
1337
- </p>
1338
- <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1339
- {typeof result === "string"
1340
- ? result
1341
- : JSON.stringify(result, null, 2)}
1342
- </pre>
1343
- </div>
1344
- )}
1345
- </div>
1435
+ {label}: <b>{toolName}</b>
1436
+ </span>
1437
+ )}
1438
+ </span>
1439
+ <ChevronDownIcon
1440
+ data-slot="tool-fallback-trigger-chevron"
1441
+ className={cn(
1442
+ "aui-tool-fallback-trigger-chevron size-4 shrink-0",
1443
+ "transition-transform duration-(--animation-duration) ease-out",
1444
+ "group-data-[state=closed]/trigger:-rotate-90",
1445
+ "group-data-[state=open]/trigger:rotate-0",
1446
+ )}
1447
+ />
1448
+ </CollapsibleTrigger>
1449
+ );
1450
+ }
1451
+
1452
+ function ToolFallbackContent({
1453
+ className,
1454
+ children,
1455
+ ...props
1456
+ }: React.ComponentProps<typeof CollapsibleContent>) {
1457
+ return (
1458
+ <CollapsibleContent
1459
+ data-slot="tool-fallback-content"
1460
+ className={cn(
1461
+ "aui-tool-fallback-content relative overflow-hidden text-sm outline-none",
1462
+ "group/collapsible-content ease-out",
1463
+ "data-[state=closed]:animate-collapsible-up",
1464
+ "data-[state=open]:animate-collapsible-down",
1465
+ "data-[state=closed]:fill-mode-forwards",
1466
+ "data-[state=closed]:pointer-events-none",
1467
+ "data-[state=open]:duration-(--animation-duration)",
1468
+ "data-[state=closed]:duration-(--animation-duration)",
1469
+ className,
1346
1470
  )}
1471
+ {...props}
1472
+ >
1473
+ <div className="mt-3 flex flex-col gap-2 border-t pt-2">{children}</div>
1474
+ </CollapsibleContent>
1475
+ );
1476
+ }
1477
+
1478
+ function ToolFallbackArgs({
1479
+ argsText,
1480
+ className,
1481
+ ...props
1482
+ }: React.ComponentProps<"div"> & {
1483
+ argsText?: string;
1484
+ }) {
1485
+ if (!argsText) return null;
1486
+
1487
+ return (
1488
+ <div
1489
+ data-slot="tool-fallback-args"
1490
+ className={cn("aui-tool-fallback-args px-4", className)}
1491
+ {...props}
1492
+ >
1493
+ <pre className="aui-tool-fallback-args-value whitespace-pre-wrap">
1494
+ {argsText}
1495
+ </pre>
1496
+ </div>
1497
+ );
1498
+ }
1499
+
1500
+ function ToolFallbackResult({
1501
+ result,
1502
+ className,
1503
+ ...props
1504
+ }: React.ComponentProps<"div"> & {
1505
+ result?: unknown;
1506
+ }) {
1507
+ if (result === undefined) return null;
1508
+
1509
+ return (
1510
+ <div
1511
+ data-slot="tool-fallback-result"
1512
+ className={cn(
1513
+ "aui-tool-fallback-result border-t border-dashed px-4 pt-2",
1514
+ className,
1515
+ )}
1516
+ {...props}
1517
+ >
1518
+ <p className="aui-tool-fallback-result-header font-semibold">Result:</p>
1519
+ <pre className="aui-tool-fallback-result-content whitespace-pre-wrap">
1520
+ {typeof result === "string" ? result : JSON.stringify(result, null, 2)}
1521
+ </pre>
1347
1522
  </div>
1348
1523
  );
1524
+ }
1525
+
1526
+ function ToolFallbackError({
1527
+ status,
1528
+ className,
1529
+ ...props
1530
+ }: React.ComponentProps<"div"> & {
1531
+ status?: ToolCallMessagePartStatus;
1532
+ }) {
1533
+ if (status?.type !== "incomplete") return null;
1534
+
1535
+ const error = status.error;
1536
+ const errorText = error
1537
+ ? typeof error === "string"
1538
+ ? error
1539
+ : JSON.stringify(error)
1540
+ : null;
1541
+
1542
+ if (!errorText) return null;
1543
+
1544
+ const isCancelled = status.reason === "cancelled";
1545
+ const headerText = isCancelled ? "Cancelled reason:" : "Error:";
1546
+
1547
+ return (
1548
+ <div
1549
+ data-slot="tool-fallback-error"
1550
+ className={cn("aui-tool-fallback-error px-4", className)}
1551
+ {...props}
1552
+ >
1553
+ <p className="aui-tool-fallback-error-header font-semibold text-muted-foreground">
1554
+ {headerText}
1555
+ </p>
1556
+ <p className="aui-tool-fallback-error-reason text-muted-foreground">
1557
+ {errorText}
1558
+ </p>
1559
+ </div>
1560
+ );
1561
+ }
1562
+
1563
+ const ToolFallbackImpl: ToolCallMessagePartComponent = ({
1564
+ toolName,
1565
+ argsText,
1566
+ result,
1567
+ status,
1568
+ }) => {
1569
+ const isCancelled =
1570
+ status?.type === "incomplete" && status.reason === "cancelled";
1571
+
1572
+ return (
1573
+ <ToolFallbackRoot
1574
+ className={cn(isCancelled && "border-muted-foreground/30 bg-muted/30")}
1575
+ >
1576
+ <ToolFallbackTrigger toolName={toolName} status={status} />
1577
+ <ToolFallbackContent>
1578
+ <ToolFallbackError status={status} />
1579
+ <ToolFallbackArgs
1580
+ argsText={argsText}
1581
+ className={cn(isCancelled && "opacity-60")}
1582
+ />
1583
+ {!isCancelled && <ToolFallbackResult result={result} />}
1584
+ </ToolFallbackContent>
1585
+ </ToolFallbackRoot>
1586
+ );
1587
+ };
1588
+
1589
+ const ToolFallback = memo(
1590
+ ToolFallbackImpl,
1591
+ ) as unknown as ToolCallMessagePartComponent & {
1592
+ Root: typeof ToolFallbackRoot;
1593
+ Trigger: typeof ToolFallbackTrigger;
1594
+ Content: typeof ToolFallbackContent;
1595
+ Args: typeof ToolFallbackArgs;
1596
+ Result: typeof ToolFallbackResult;
1597
+ Error: typeof ToolFallbackError;
1598
+ };
1599
+
1600
+ ToolFallback.displayName = "ToolFallback";
1601
+ ToolFallback.Root = ToolFallbackRoot;
1602
+ ToolFallback.Trigger = ToolFallbackTrigger;
1603
+ ToolFallback.Content = ToolFallbackContent;
1604
+ ToolFallback.Args = ToolFallbackArgs;
1605
+ ToolFallback.Result = ToolFallbackResult;
1606
+ ToolFallback.Error = ToolFallbackError;
1607
+
1608
+ export {
1609
+ ToolFallback,
1610
+ ToolFallbackRoot,
1611
+ ToolFallbackTrigger,
1612
+ ToolFallbackContent,
1613
+ ToolFallbackArgs,
1614
+ ToolFallbackResult,
1615
+ ToolFallbackError,
1349
1616
  };
1350
1617
 
1351
1618
  ```
@@ -1519,6 +1786,45 @@ export { Button, buttonVariants };
1519
1786
 
1520
1787
  ```
1521
1788
 
1789
+ ## components/ui/collapsible.tsx
1790
+
1791
+ ```tsx
1792
+ "use client";
1793
+
1794
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
1795
+
1796
+ function Collapsible({
1797
+ ...props
1798
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
1799
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
1800
+ }
1801
+
1802
+ function CollapsibleTrigger({
1803
+ ...props
1804
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
1805
+ return (
1806
+ <CollapsiblePrimitive.CollapsibleTrigger
1807
+ data-slot="collapsible-trigger"
1808
+ {...props}
1809
+ />
1810
+ );
1811
+ }
1812
+
1813
+ function CollapsibleContent({
1814
+ ...props
1815
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
1816
+ return (
1817
+ <CollapsiblePrimitive.CollapsibleContent
1818
+ data-slot="collapsible-content"
1819
+ {...props}
1820
+ />
1821
+ );
1822
+ }
1823
+
1824
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent };
1825
+
1826
+ ```
1827
+
1522
1828
  ## components/ui/dialog.tsx
1523
1829
 
1524
1830
  ```tsx
@@ -1783,32 +2089,33 @@ export default nextConfig;
1783
2089
  "start": "next start"
1784
2090
  },
1785
2091
  "dependencies": {
1786
- "@ai-sdk/openai": "^2.0.88",
2092
+ "@ai-sdk/openai": "^3.0.13",
1787
2093
  "@assistant-ui/react": "workspace:*",
1788
2094
  "@assistant-ui/react-ai-sdk": "workspace:*",
1789
2095
  "@assistant-ui/react-markdown": "workspace:*",
1790
2096
  "@radix-ui/react-avatar": "^1.1.11",
2097
+ "@radix-ui/react-collapsible": "^1.1.12",
1791
2098
  "@radix-ui/react-dialog": "^1.1.15",
1792
2099
  "@radix-ui/react-slot": "^1.2.4",
1793
2100
  "@radix-ui/react-tooltip": "^1.2.8",
1794
- "ai": "^5.0.116",
2101
+ "ai": "^6.0.42",
1795
2102
  "assistant-stream": "workspace:*",
1796
2103
  "class-variance-authority": "^0.7.1",
1797
2104
  "clsx": "^2.1.1",
1798
2105
  "lucide-react": "^0.562.0",
1799
- "next": "16.1.0",
1800
- "react": "19.2.3",
1801
- "react-dom": "19.2.3",
2106
+ "next": "^16.1.4",
2107
+ "react": "^19.2.3",
2108
+ "react-dom": "^19.2.3",
1802
2109
  "remark-gfm": "^4.0.1",
1803
2110
  "tailwind-merge": "^3.4.0",
1804
- "zod": "^4.2.1",
1805
- "zustand": "^5.0.9"
2111
+ "zod": "^4.3.5",
2112
+ "zustand": "^5.0.10"
1806
2113
  },
1807
2114
  "devDependencies": {
1808
2115
  "@assistant-ui/x-buildutils": "workspace:*",
1809
2116
  "@tailwindcss/postcss": "^4.1.18",
1810
- "@types/node": "^25.0.3",
1811
- "@types/react": "^19.2.7",
2117
+ "@types/node": "^25.0.9",
2118
+ "@types/react": "^19.2.9",
1812
2119
  "@types/react-dom": "^19.2.3",
1813
2120
  "postcss": "^8.5.6",
1814
2121
  "tailwindcss": "^4.1.18",