Template
Replace Streamdown with a plugin-free markdown renderer
The assistant only ever renders prose, links and the odd list, but Streamdown's plugin set dragged in shiki, mermaid and katex — and streamdown core declares mermaid as a hard dependency, so dropping the plugins alone would have left it installed. Rendering now runs on the same unified pipeline Streamdown used internally, minus the plugin surface: remark-parse -> remark-gfm -> remark-rehype -> rehype-sanitize -> hast-util-to-jsx-runtime. GFM, streaming repair and the link-safety hook all survive; fenced code renders as plain <pre>. Net -264/+101 packages. remend now runs only while a part is still streaming. On settled text it reads `*$89*` as an unclosed italic — the `$` throws off its closing-delimiter scan — and appends a stray `*` that parses as an empty bullet. Italic prices are ordinary storefront copy, so that would have shown up in production. Route-relative links go through next/link in the same tab; sending a shopper to a product page in a new tab would strand the conversation behind it. Only external destinations get the confirmation dialog. code-block.tsx and tool.tsx were the sole users of shiki and had no importers, so both are gone. Also folded in two unrelated changes that were already in the tree: the loader move out of app/components/ui, and dropping the fade on the command palette so it opens instantly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KuySwKLSF4uEPpZjHkdHBP
This commit is contained in:
co-authored by
Claude Opus 5
parent
526982691c
commit
64af00e702
@@ -12,23 +12,19 @@ import {
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cjk } from "@streamdown/cjk";
|
||||
import { code } from "@streamdown/code";
|
||||
import { math } from "@streamdown/math";
|
||||
import { mermaid } from "@streamdown/mermaid";
|
||||
import type { UIMessage } from "ai";
|
||||
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
||||
import type { ComponentProps, HTMLAttributes, ReactElement } from "react";
|
||||
import {
|
||||
createContext,
|
||||
memo,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from "react";
|
||||
import { Streamdown } from "streamdown";
|
||||
|
||||
import { Markdown } from "./markdown";
|
||||
|
||||
export type MessageProps = HTMLAttributes<HTMLDivElement> & {
|
||||
from: UIMessage["role"];
|
||||
@@ -319,27 +315,10 @@ export const MessageBranchPage = ({
|
||||
);
|
||||
};
|
||||
|
||||
export type MessageResponseProps = ComponentProps<typeof Streamdown>;
|
||||
export type MessageResponseProps = ComponentProps<typeof Markdown>;
|
||||
|
||||
const streamdownPlugins = { cjk, code, math, mermaid };
|
||||
|
||||
export const MessageResponse = memo(
|
||||
({ className, ...props }: MessageResponseProps) => (
|
||||
<Streamdown
|
||||
className={cn(
|
||||
"size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0",
|
||||
className
|
||||
)}
|
||||
plugins={streamdownPlugins}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
(prevProps, nextProps) =>
|
||||
prevProps.children === nextProps.children &&
|
||||
nextProps.isAnimating === prevProps.isAnimating
|
||||
);
|
||||
|
||||
MessageResponse.displayName = "MessageResponse";
|
||||
// Markdown already memoises on children/isAnimating.
|
||||
export const MessageResponse = Markdown;
|
||||
|
||||
export type MessageToolbarProps = ComponentProps<"div">;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user