diff --git a/apps/www/components/ui/assistant-ui/markdown-text.ts b/apps/www/components/ui/assistant-ui/markdown-text.ts index a7d238076..143ba6ada 100644 --- a/apps/www/components/ui/assistant-ui/markdown-text.ts +++ b/apps/www/components/ui/assistant-ui/markdown-text.ts @@ -1 +1 @@ -export * from "@assistant-ui/shadcn-registry/registry/assistant-ui/experimental/markdown-text"; +export * from "@assistant-ui/shadcn-registry/registry/assistant-ui/markdown-text"; diff --git a/apps/www/pages/docs/advanced/Markdown.mdx b/apps/www/pages/docs/advanced/Markdown.mdx new file mode 100644 index 000000000..79d5f36db --- /dev/null +++ b/apps/www/pages/docs/advanced/Markdown.mdx @@ -0,0 +1,39 @@ +--- +title: Markdown +description: Allow the assistant to display rich text using markdown. +--- + +import { Steps, Callout } from "nextra/components"; + + + Make sure to upgrade `@assistant-ui/react` to `>=0.2` and to follow steps outlined in the [migration guide](/docs/migrations/v0.2). + + + + Markdown support is alraedy included in the `npx assistant-ui@latest add thread-full` template. + + +## Enabling markdown support + + +### Add the `markdown-text` component to your project. + +```tsx +npx assistant-ui@latest add markdown-text +``` + +### Use it in Thread.tsx + +```tsx +import { MarkdownText } from "@/components/ui/assistant-ui/markdown-text"; + +const AssistantMessage = () => { + return ( + + ... + + + ); +}; +``` + \ No newline at end of file diff --git a/apps/www/pages/docs/advanced/_meta.tsx b/apps/www/pages/docs/advanced/_meta.tsx index a5b471e61..d8e15420f 100644 --- a/apps/www/pages/docs/advanced/_meta.tsx +++ b/apps/www/pages/docs/advanced/_meta.tsx @@ -1,4 +1,5 @@ const meta = { + Markdown: "Markdown", ToolUI: "Tool UIs", Branching: "Branching", Editing: "Editing", diff --git a/packages/react-markdown/package.json b/packages/react-markdown/package.json index 73b8d4314..84a2785a0 100644 --- a/packages/react-markdown/package.json +++ b/packages/react-markdown/package.json @@ -1,7 +1,6 @@ { "name": "@assistant-ui/react-markdown", "version": "0.0.1", - "private": true, "license": "MIT", "exports": { ".": { diff --git a/packages/react-markdown/src/MarkdownText.tsx b/packages/react-markdown/src/MarkdownText.tsx index 0de7bf6c1..57ba552b7 100644 --- a/packages/react-markdown/src/MarkdownText.tsx +++ b/packages/react-markdown/src/MarkdownText.tsx @@ -1,9 +1,11 @@ import { ContentPartPrimitive } from "@assistant-ui/react"; -import { useContentPartContext } from "@assistant-ui/react/experimental"; +import { useContentPartContext } from "@assistant-ui/react"; import type { FC } from "react"; import ReactMarkdown, { type Options } from "react-markdown"; -export const MarkdownText: FC = (options) => { +export const MarkdownTextPrimitive: FC> = ( + options, +) => { const { useContentPart } = useContentPartContext(); const text = useContentPart((c) => { if (c.part.type !== "text") @@ -14,9 +16,9 @@ export const MarkdownText: FC = (options) => { return c.part.text; }); return ( - + <> {text} - + ); }; diff --git a/packages/react-markdown/src/index.ts b/packages/react-markdown/src/index.ts index 98152cbf4..d712f103e 100644 --- a/packages/react-markdown/src/index.ts +++ b/packages/react-markdown/src/index.ts @@ -1 +1 @@ -export { MarkdownText as unstable_MarkdownTextPrimitive } from "./MarkdownText"; +export { MarkdownTextPrimitive } from "./MarkdownText"; diff --git a/packages/shadcn-registry/components/ui/assistant-ui/markdown-text.tsx b/packages/shadcn-registry/components/ui/assistant-ui/markdown-text.tsx index ee511f66a..f743622db 100644 --- a/packages/shadcn-registry/components/ui/assistant-ui/markdown-text.tsx +++ b/packages/shadcn-registry/components/ui/assistant-ui/markdown-text.tsx @@ -1 +1 @@ -export * from "@/registry/assistant-ui/experimental/markdown-text"; +export * from "@/registry/assistant-ui/markdown-text"; diff --git a/packages/shadcn-registry/registry/assistant-ui/experimental/markdown-text.tsx b/packages/shadcn-registry/registry/assistant-ui/experimental/markdown-text.tsx deleted file mode 100644 index 623fc485a..000000000 --- a/packages/shadcn-registry/registry/assistant-ui/experimental/markdown-text.tsx +++ /dev/null @@ -1,49 +0,0 @@ -"use client"; - -import { unstable_MarkdownTextPrimitive as MarkdownTextPrimitive } from "@assistant-ui/react-markdown"; -import remarkGfm from "remark-gfm"; -import remarkMath from "remark-math"; - -export const MarkdownText = () => { - return ( - {children}

; - }, - // code({ node, className, children, ...props }) { - // if (children.length) { - // if (children[0] == "▍") { - // return ( - // - // ); - // } - - // children[0] = (children[0] as string).replace("`▍`", "▍"); - // } - - // const match = /language-(\w+)/.exec(className || ""); - - // if (inline) { - // return ( - // - // {children} - // - // ); - // } - - // return ( - // - // ); - // }, - }} - /> - ); -}; diff --git a/packages/shadcn-registry/registry/assistant-ui/experimental/thread.tsx b/packages/shadcn-registry/registry/assistant-ui/experimental/thread.tsx deleted file mode 100644 index 219b3ec78..000000000 --- a/packages/shadcn-registry/registry/assistant-ui/experimental/thread.tsx +++ /dev/null @@ -1,260 +0,0 @@ -"use client"; - -import { - ActionBarPrimitive, - BranchPickerPrimitive, - ComposerPrimitive, - MessagePrimitive, - ThreadPrimitive, -} from "@assistant-ui/react"; -import type { FC } from "react"; - -import { MarkdownText } from "@/components/ui/assistant-ui/markdown-text"; -import { Avatar, AvatarFallback } from "@/components/ui/avatar"; -import { Button, type ButtonProps } from "@/components/ui/button"; -import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from "@/components/ui/tooltip"; -import { cn } from "@/lib/utils"; -import { TooltipProvider } from "@radix-ui/react-tooltip"; -import { - ArrowDownIcon, - CheckIcon, - ChevronLeftIcon, - ChevronRightIcon, - CopyIcon, - PencilIcon, - RefreshCwIcon, - SendHorizonalIcon, -} from "lucide-react"; - -export const Thread: FC = () => { - return ( - - - - - - - - - - - - - - - - ); -}; - -const ThreadEmpty: FC = () => { - return ( -
- - C - -

How can I help you today?

-
- ); -}; - -const ThreadScrollToBottom: FC = () => { - return ( -
- - - - - -
- ); -}; - -const Composer: FC = () => { - return ( - - - - - - - - - -
- - - - ); -}; - -const UserMessage: FC = () => { - return ( - - - Y - - -
-

You

- -

- -

- -
- - - - - - - - - -
-
-
- ); -}; - -const EditComposer: FC = () => { - return ( - - - Y - - -
-

You

- - - - -
- - - - - - -
-
-
-
- ); -}; - -const AssistantMessage: FC = () => { - return ( - - - A - - -
-

Assistant

- - -

- -

- -
- - - - - - - - - - - - - - - - - - - -
-
-
- ); -}; - -const BranchPicker: FC = () => { - return ( - - - - - - - / - - - - - - - ); -}; - -type IconButton = ButtonProps & { tooltip: string }; - -const IconButton: FC = ({ - children, - tooltip, - className, - ...rest -}) => { - return ( - - - - - {tooltip} - - ); -}; diff --git a/packages/shadcn-registry/registry/assistant-ui/full/thread.tsx b/packages/shadcn-registry/registry/assistant-ui/full/thread.tsx index c99e2cc3c..9a95e3064 100644 --- a/packages/shadcn-registry/registry/assistant-ui/full/thread.tsx +++ b/packages/shadcn-registry/registry/assistant-ui/full/thread.tsx @@ -28,6 +28,7 @@ import { RefreshCwIcon, SendHorizonalIcon, } from "lucide-react"; +import { MarkdownText } from "@/components/ui/assistant-ui/markdown-text"; export const Thread: FC = () => { return ( @@ -159,7 +160,7 @@ const AssistantMessage: FC = () => {
- +
diff --git a/packages/shadcn-registry/registry/assistant-ui/markdown-text.tsx b/packages/shadcn-registry/registry/assistant-ui/markdown-text.tsx new file mode 100644 index 000000000..5837489f0 --- /dev/null +++ b/packages/shadcn-registry/registry/assistant-ui/markdown-text.tsx @@ -0,0 +1,155 @@ +"use client"; + +import { MarkdownTextPrimitive } from "@assistant-ui/react-markdown"; +import remarkGfm from "remark-gfm"; +import { memo } from "react"; +import { cn } from "@/lib/utils"; + +const MarkdownTextImpl = () => { + return ( + ( +

+ ), + h2: ({ node, className, ...props }) => ( +

+ ), + h3: ({ node, className, ...props }) => ( +

+ ), + h4: ({ node, className, ...props }) => ( +

+ ), + h5: ({ node, className, ...props }) => ( +

+ ), + h6: ({ node, className, ...props }) => ( +
+ ), + p: ({ node, className, ...props }) => ( +

+ ), + a: ({ node, ...props }) => ( + + ), + blockquote: ({ node, ...props }) => ( +

+ ), + ul: ({ node, ...props }) => ( +
    li]:mt-2", props.className)} + {...props} + /> + ), + ol: ({ node, ...props }) => ( +
      li]:mt-2", + props.className, + )} + {...props} + /> + ), + hr: ({ node, ...props }) => ( +
      + ), + + table: ({ node, ...props }) => ( + + ), + th: ({ node, ...props }) => ( + td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg", + props.className, + )} + {...props} + /> + ), + + sup: ({ node, ...props }) => ( + a]:text-xs [&>a]:no-underline", props.className)} + {...props} + /> + ), + }} + /> + ); +}; + +export const MarkdownText = memo(MarkdownTextImpl); diff --git a/packages/shadcn-registry/registry/registry.ts b/packages/shadcn-registry/registry/registry.ts index 409b9550e..da8b1792e 100644 --- a/packages/shadcn-registry/registry/registry.ts +++ b/packages/shadcn-registry/registry/registry.ts @@ -34,34 +34,22 @@ export const registry: RegistryIndex = [ ], }, { - name: "unstable-markdown-text", + name: "markdown-text", type: "components:ui", - files: ["assistant-ui/experimental/markdown-text.tsx"], + files: ["assistant-ui/markdown-text.tsx"], // registryDependencies: ["unstable-codeblock"], dependencies: [ "@assistant-ui/react", "@assistant-ui/react-markdown", "remark-gfm", - "remark-math", + // "remark-math", ], }, - { - name: "unstable-thread-full", - type: "components:ui", - files: ["assistant-ui/experimental/thread.tsx"], - registryDependencies: [ - "unstable-markdown-text", - "button", - "avatar", - "tooltip", - ], - dependencies: ["@assistant-ui/react", "lucide-react"], - }, { name: "thread-full", type: "components:ui", files: ["assistant-ui/full/thread.tsx"], - registryDependencies: ["button", "avatar", "tooltip"], + registryDependencies: ["markdown-text", "button", "avatar", "tooltip"], dependencies: ["@assistant-ui/react", "lucide-react"], }, ];
      + ), + td: ({ node, ...props }) => ( + + ), + tr: ({ node, ...props }) => ( +