# 回复渲染与工具产物展示

本文定义 Web 侧助手回复的展示边界。目标是让正文、代码、图片、文件各走各的链路，避免互相覆盖。

## 基本原则

- 正文优先，产物其次。消息里的自然语言不应被 artifact 卡片吞掉。
- 不猜测、不降级、不把普通文本硬转成卡片。
- 用户侧上传附件预览保持原链路，不受本文件规则影响。

## 正文层

- 段落、标题、列表、引用、表格、链接、行内代码、数学公式都按普通 Markdown 渲染。
- 围栏代码块仍属于正文层，可以和普通文本共存，但会渲染成内嵌代码面板，统一不显示语言名，也不做语言高亮。
- 正文层里出现的代码块不要升成独立工具卡片。

## 纯输出层 artifact

- 仅当内容是整块 JSON / YAML / Diff / Terminal 时，才进入 artifact 展示。代码块继续留在正文层，并渲染成内嵌代码面板，统一不显示语言名。
- artifact 只负责平铺展示，不做语法高亮或 token 着色。
- JSON、YAML、Diff、终端输出之间不要互相抢优先级；代码块始终留在正文层，不升成 artifact。

## 图片与文件

- 助手正文里的 Markdown 图片 `![](...)` 不渲染、不占位、不发请求。
- 只有 `image_generate` / `image_edit` 的结果可以在助手回复里渲染独立图片气泡。
- 图片气泡需要保留预览、下载、复制路径。
- 文件 artifact 只保留下载和复制路径，不做在线预览。

## 规则边界

- 边界不清时，优先保持文本。
- 只有工具已经明确返回 `artifacts[]` 时，才提升为 artifact。
- 不要靠正则猜路径、猜文件类型或猜远端资源。
- 如果是用户上传的图片或文件，继续走用户侧附件预览链路。

## 参考

- `web/src/components/Chat/MarkdownMessage.tsx`
- `web/src/components/Chat/ArtifactContent.tsx`
- `web/src/components/Chat/AssistantImageBubble.tsx`
- `web/src/components/Chat/AssistantImagePreviewRail.tsx`
- `web/src/components/Chat/markdownImage.ts`
