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
-
-
-
-
- );
-};
-
-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: ({ node, ...props }) => (
+ |
+ ),
+ tr: ({ 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"],
},
];