feat(ai): AI 消息代码块外壳与思维卡流式计时 - shiki 双主题高亮/流式光标/复制工具条, 250ms 节流 mono 秒数 (DCE 工具卡清理)

This commit is contained in:
maomaochong-ai committed 2026-09-06 20:33:22 +08:00
1 parent 1190a1b310
commit ab9d2422f9
6 files changed
+254 -22

No files matched your search

@@ -1,4 +1,5 @@
import { Streamdown, type Components } from "streamdown";
import { AiMessageCodeBlock } from "./ai-message-code-block";
import "streamdown/styles.css";
@@ -8,7 +9,8 @@ type AIMessageMarkdownProps = {
className?: string;
};
const components: Components = {
function buildComponents(isStreaming: boolean): Components {
return {
h1: ({ children, ...props }) => <h2 {...props} className="ai-message-markdown-heading ai-message-markdown-heading-1">{children}</h2>,
h2: ({ children, ...props }) => <h3 {...props} className="ai-message-markdown-heading ai-message-markdown-heading-2">{children}</h3>,
h3: ({ children, ...props }) => <h4 {...props} className="ai-message-markdown-heading ai-message-markdown-heading-3">{children}</h4>,
@@ -18,7 +20,7 @@ const components: Components = {
ol: ({ children, ...props }) => <ol {...props} className="ai-message-markdown-list ai-message-markdown-list-ordered">{children}</ol>,
li: ({ children, ...props }) => <li {...props} className="ai-message-markdown-list-item">{children}</li>,
blockquote: ({ children, ...props }) => <blockquote {...props} className="ai-message-markdown-blockquote">{children}</blockquote>,
pre: ({ children, ...props }) => <pre {...props} className="ai-message-markdown-pre">{children}</pre>,
pre: ({ children, ...props }) => <AiMessageCodeBlock isStreaming={isStreaming} {...props}>{children}</AiMessageCodeBlock>,
code: ({ children, className, ...props }) => <code {...props} className={`ai-message-markdown-code ${className || ""}`.trim()}>{children}</code>,
a: ({ children, ...props }) => <a {...props} className="ai-message-markdown-link" target="_blank" rel="noreferrer">{children}</a>,
hr: (props) => <hr {...props} className="ai-message-markdown-rule" />,
@@ -26,7 +28,9 @@ const components: Components = {
th: ({ children, ...props }) => <th {...props} className="ai-message-markdown-table-cell ai-message-markdown-table-header">{children}</th>,
td: ({ children, ...props }) => <td {...props} className="ai-message-markdown-table-cell">{children}</td>,
input: ({ ...props }) => <input {...props} className="ai-message-markdown-task" disabled />,
};
};
}
export function AIMessageMarkdown({ children, isStreaming = false, className = "" }: AIMessageMarkdownProps) {
if (!children.trim()) return null;
@@ -40,7 +44,7 @@ export function AIMessageMarkdown({ children, isStreaming = false, className = "
parseIncompleteMarkdown
skipHtml
lineNumbers={false}
components={components}
components={buildComponents(isStreaming)}
>
{children}
</Streamdown>