Markdown Rendering
Relevant source files
The following files were used as context for generating this wiki page:
Markdown rendering in the Agent Cowork project is a core UI feature responsible for transforming raw text from the AI assistant into structured, human-readable content. It leverages a modern React-based stack to provide syntax highlighting, GitHub Flavored Markdown (GFM) support, and custom-styled HTML components that align with the application's aesthetic.
This system is used across several UI components, including the main message thread, tool results, and "thinking" blocks, ensuring that technical outputs and conversational text are presented with high clarity.
Sources: src/ui/render/markdown.tsx, README_ZH.md:73-77, src/ui/components/EventCard.tsx:132-135
Architecture and Components
The rendering architecture is centralized in the MDContent component. It utilizes the react-markdown library as the primary engine, augmented by several plugins for extended functionality.
Core Dependencies
The system relies on the following specialized libraries:
| Dependency | Purpose |
|---|---|
react-markdown | Main parser and renderer for Markdown content. |
remark-gfm | Adds support for GitHub Flavored Markdown (tables, task lists, etc.). |
rehype-raw | Allows the rendering of raw HTML within Markdown strings. |
rehype-highlight | Provides syntax highlighting for code blocks using highlight.js. |
| Sources: package.json:44-47, src/ui/render/markdown.tsx:1-4 |
Data Flow Diagram
The following diagram illustrates how raw text from the AI stream is processed into rendered HTML.
The application checks if a string contains Markdown patterns (like headers or code blocks) before choosing the rendering path in specific contexts like tool outputs.
Sources: src/ui/components/EventCard.tsx:112-116, src/ui/render/markdown.tsx:7-12
Component Mapping and Styling
The MDContent component overrides default HTML element rendering to apply custom Tailwind CSS classes and styles defined in the project's theme.
UI Element Styles
Custom styling is applied to several standard Markdown elements:
- Headings (h1, h2, h3): Styled with
font-semiboldand specific text sizes (text-xl,text-lg,text-base). - Lists (ul, ol): Configured as a grid with specific margins (
ml-4) and gaps. - Typography: Uses "Ink" colors (e.g.,
text-ink-700,text-ink-900) for visual hierarchy. - Code Blocks (pre): Rendered with a tertiary surface background, rounded corners, and overflow handling.
Sources: src/ui/render/markdown.tsx:13-30, src/ui/index.css:7-16
Inline vs. Block Code Logic
The system distinguishes between inline code and multi-line code blocks within the code component override:
code: (props) => {
const { children, className, ...rest } = props;
const match = /language-(\w+)/.exec(className || "");
const isInline = !match && !String(children).includes("\n");
return isInline ? (
<code className="rounded bg-surface-tertiary px-1.5 py-0.5 text-accent font-mono text-base" {...rest}>
{children}
</code>
) : (
<code className={`${className} font-mono`} {...rest}>
{children}
</code>
);
}
Sources: src/ui/render/markdown.tsx:31-45
Markdown Integration in UI
Markdown rendering is integrated into the application's event-driven architecture, specifically within message cards and streaming responses.
Markdown Detection Logic
A utility function isMarkdown is used to determine if content should be passed to the MDContent renderer.
export function isMarkdown(text: string): boolean {
if (!text || typeof text !== "string") return false;
const patterns: RegExp[] = [/^#{1,6}\s+/m, /```[\s\S]*?```/];
return patterns.some((pattern) => pattern.test(text));
}
Sources: src/ui/components/EventCard.tsx:112-116
Streaming Output Sequence
When receiving data from the AI, the application handles partial message updates before final rendering.
The App component manages a partialMessage state that is continuously fed into MDContent during an active session.
Sources: src/ui/App.tsx:61-90, src/ui/App.tsx:243-245
Global CSS Configuration
The rendering appearance is heavily dependent on the CSS theme defined in src/ui/index.css. This file imports highlight.js/styles/github.css for code syntax highlighting and defines the color variables (surfaces and inks) used in the Markdown component.
| CSS Variable | Color | Usage in MD |
|---|---|---|
--color-surface-tertiary | #EFEEE9 | Background for code blocks and inline code. |
--color-ink-900 | #1A1915 | Text color for H1, H2, and Bold text. |
--color-accent | #D97757 | Text color for inline code snippets. |
--color-ink-700 | #4A4A45 | Default text color for paragraphs and list items. |
| Sources: src/ui/index.css:7-25, src/ui/render/markdown.tsx:13-33 |
Summary
The Markdown rendering system in Agent Cowork provides a sophisticated interface for AI collaboration by combining standard Markdown parsing with custom React components and Tailwind CSS styling. By supporting streaming updates and syntax highlighting, it ensures that code-heavy AI responses are as legible as local development environments.