Files
zclaw_openfang/docs/references/artifact-system-reference.md
iven 4c31471cd6
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
feat(artifact): 产物系统优化 — 共享渲染 + 数据源扩展 + 持久化
- MarkdownRenderer: 从 StreamingText 提取共享 react-markdown + remark-gfm 组件
- ArtifactPanel: 替换手写 MarkdownPreview 为完整 GFM 渲染,添加文件选择器下拉菜单
- 数据源: file_write/str_replace 双工具 + sendMessage/initStreamListener 双路径
- 持久化: artifactStore 添加 zustand persist + IndexedDB (复用 idb-storage)
2026-04-24 10:59:27 +08:00

13 KiB
Raw Blame History

产物系统参考文档

调研 DeerFlow 和 Hermes Agent 的产物/输出面板实现,为 ZCLAW 产物系统重构提供参考。 分析日期2026-04-24


一、DeerFlow 产物系统

DeerFlow 有完整的全栈产物管道,是主要参考对象。

1.1 端到端数据流

Agent tool call (write_file / str_replace / present_files)
    ↓
Backend: ThreadState.artifacts (LangGraph annotated list, merge_artifacts reducer 去重)
    ↓ 文件写入: {base_dir}/threads/{thread_id}/user-data/outputs/
    ↓ 虚拟路径: /mnt/user-data/outputs/filename.ext
    ↓
Backend API: GET /api/threads/{thread_id}/artifacts/{virtual_path}
    ↓ MIME 检测 / .skill ZIP 解压 / download vs inline
    ↓
Frontend: thread.values.artifacts (string[]) → ArtifactsProvider context
    ↓
ChatBox (ResizablePanelGroup) → chat(60%) | artifact panel(40%)
    ↓
ArtifactFileDetail → CodeMirror(代码) / Streamdown(Markdown) / iframe(HTML)

1.2 关键文件

前端核心

文件 职责
frontend/src/core/artifacts/utils.ts URL 构建、产物列表提取、路径解析
frontend/src/core/artifacts/loader.ts 从后端 API 获取产物文本;从 tool call args 直接提取内容
frontend/src/core/artifacts/hooks.ts TanStack React Query hook5 分钟缓存
frontend/src/components/workspace/artifacts/context.tsx ArtifactsProvider + useArtifacts() — 管理列表、选中、开关、自动选中
frontend/src/components/workspace/artifacts/artifact-file-detail.tsx 产物详情视图:头部(文件选择器+code/preview切换) + CodeEditor/Preview
frontend/src/components/workspace/artifacts/artifact-file-list.tsx 卡片式列表视图,每个卡片含图标/名称/扩展名/下载/安装按钮
frontend/src/components/workspace/artifacts/artifact-trigger.tsx 头部触发按钮,仅在产物存在时显示

前端渲染

文件 职责
frontend/src/components/workspace/code-editor.tsx CodeMirror 只读编辑器,支持 CSS/HTML/JS/JSON/MD/Python 语法高亮
frontend/src/components/ai-elements/code-block.tsx Shiki 语法高亮代码块,双主题(light/dark)
frontend/src/components/ai-elements/web-preview.tsx iframe 网页预览,含地址栏和导航按钮
frontend/src/components/workspace/messages/markdown-content.tsx Streamdown 渲染 Markdown (GFM + Math + Raw HTML + KaTeX)
frontend/src/core/utils/files.tsx 140+ 扩展名→语言映射,文件图标/类型判断

后端

文件 职责
backend/.../thread_state.py ThreadState.artifacts 列表 + merge_artifacts 去重 reducer
backend/.../present_file_tool.py present_files 工具 — 标准化路径,返回 Command(update)
backend/.../paths.py 路径管理threads/{id}/user-data/{workspace,uploads,outputs}
backend/app/gateway/routers/artifacts.py FastAPI 路由GET 产物文件MIME 检测,安全处理

1.3 支持的内容类型

类型 渲染方式
代码文件 (140+ 扩展名) CodeMirror 只读 + 语法高亮
Markdown (.md) Streamdown (GFM + Math + KaTeX + Raw HTML)
HTML (.html/.htm) 沙箱 <iframe> (srcDoc)
图片 (.png/.jpg/.svg/.webp) <img> 标签,非代码文件用 iframe
.skill 压缩包 ZIP 解压SKILL.md 渲染为 Markdown
二进制文件 (PDF 等) 后端 inline Content-Disposition
文本文件 (.txt/.csv/.log) CodeMirror 纯文本模式

1.4 持久化架构

磁盘存储:

{DEER_FLOW_HOME}/threads/{thread_id}/user-data/outputs/

状态持久化: artifacts 列表是 LangGraph ThreadState 的一部分,由 checkpoint 系统自动持久化。

前端缓存: TanStack React Query5 分钟 stale time。

1.5 UI/UX 设计模式

分栏布局 (chat-box.tsx)

  • react-resizable-panels 水平分栏
  • 关闭态chat=100%, artifacts=0%
  • 打开态chat=60%, artifacts=40%
  • 300ms CSS 过渡动画

自动打开 + 自动选中

  • 检测到 write_file / str_replace tool call 时自动打开面板并选中文件
  • autoOpen / autoSelect 标志防止用户手动关闭后重复打开

代码/预览切换

  • HTML/Markdown 默认 Preview其他默认 Code
  • Preview 用 Streamdown(MD) 或 iframe(HTML)

头部操作栏

  • 文件选择器下拉菜单(不用返回列表即可切换)
  • 复制 / 下载 / 新窗口打开 / 关闭

聊天内嵌展示

  • present_files tool call → 聊天流内渲染卡片网格
  • 点击卡片 → 侧栏打开该文件

双路径方案

  1. 真实文件路径 — 从后端 API 获取React Query 缓存
  2. write-file: 虚拟路径 — 直接从 tool call args 提取内容,无需后端请求,支持流式显示

1.6 Provider 层级

ArtifactsProvider → 提供useArtifacts() context
  ChatBox → ResizablePanelGroup
    Panel(chat) → MessageList → ToolCall 自动打开产物面板
    Panel(artifacts) → ArtifactFileDetail → useArtifactContent() hook

二、Hermes Agent 产物机制

结论Hermes Agent 无产物面板、无 Web 前端、无分栏布局。 它是终端 CLI 工具,所有输出在终端内联渲染。但有值得借鉴的大输出处理机制。

2.1 项目定位

Hermes Agent 是 Python CLI/TUI Agent(类似 Claude Code通过 prompt_toolkit TUI 运行,同时支持 Telegram/Discord/Slack/WhatsApp 等 IM 平台网关。

无 React/Next.js/Web UI。 暴露 OpenAI 兼容 API 供 Open WebUI/LobeChat 等第三方 UI 接入。

2.2 大输出处理3 层防御)

这是唯一接近"产物管理"的机制,值得借鉴。

文件:tools/tool_result_storage.py

层级 机制 说明
Layer 1 工具自身截断 每个工具限制自己的输出长度
Layer 2 maybe_persist_tool_result 单个结果超阈值 → 写入沙箱临时文件,上下文中替换为 <persisted-output> 预览块
Layer 3 enforce_turn_budget 整轮超过 200K 字符 → 最大的几个溢出到磁盘

核心逻辑:

# 超阈值时:完整内容写入文件,上下文替换为预览
remote_path = f"{storage_dir}/{tool_use_id}.txt"
_write_to_sandbox(content, remote_path, env)
return _build_persisted_message(preview, has_more, len(content), remote_path)
# 后续 agent 可用 read_file + offset/limit 读取完整内容

2.3 预算配置

文件:tools/budget_config.py

参数 默认值
DEFAULT_RESULT_SIZE_CHARS 100,000单工具阈值
DEFAULT_TURN_BUDGET_CHARS 200,000整轮上限
DEFAULT_PREVIEW_SIZE_CHARS 1,500内联预览长度

2.4 CLI 渲染方式

文件:agent/display.py

  • 工具进度KawaiiSpinner 动画 + 一行摘要
  • 文件编辑:内联 colored unified diffwrite_file / patch 工具)
  • 最终响应Rich Panel 边框包裹主题色可换7 套 skin

2.5 会话持久化

文件:hermes_state.py

SQLite (~/.hermes/state.db) + FTS5 全文搜索:

  • sessions 表元数据、模型配置、token 计数、费用、标题
  • messages 表role、content、tool_call_id、reasoning、时间戳

2.6 值得借鉴的点

借鉴价值
大输出溢出到磁盘 + 内联预览 解决 context window 溢出问题
3 层递进防御 对 ZCLAW 中间件链有参考价值
预算配置化 阈值可调,不同场景不同策略

三、对比分析ZCLAW 现状 vs 参考方案

3.1 现状差距

维度 DeerFlow ZCLAW 现状 差距
数据源 3 个工具(present_files/write_file/str_replace)主动注册 仅 streamStore 解析 tool output 的 filePath 极窄,几乎不触发
持久化 磁盘文件 + LangGraph checkpoint 纯内存 Zustand 刷新即丢失
渲染-代码 CodeMirror 只读 + 语法高亮 (140+ 语言) <pre> 标签,无高亮 无高亮
渲染-Markdown Streamdown (GFM+Math+KaTeX+RawHTML) 手写 30 行正则渲染器 仅标题/粗体/列表
渲染-HTML 沙箱 iframe 不支持
渲染-图片 <img> + iframe 类型声明了无实现
渲染-表格 GFM 表格 纯文本 <pre>
面板布局 react-resizable-panels 60/40 react-resizable-panels 65/35 已有,可复用
自动打开 write_file/str_replace 触发 addArtifact 时打开 已有
文件选择 下拉菜单不离开详情视图 必须返回列表再选 体验差
聊天内嵌 present_files → 卡片网格 缺失
缓存 React Query 5min 缺失
双路径 真实路径 + write-file: 虚拟路径 仅运行时内存 缺失
右面板重叠 单一面板 ArtifactPanel + RightPanel"文件"tab 职责交叉 架构问题

3.2 核心差距总结

按优先级排列:

  1. P0 数据源断裂 — 产物几乎没有来源,是最根本的问题
  2. P0 无持久化 — 产物刷新即丢
  3. P1 Markdown 渲染残缺 — 30 行正则 vs 完整 GFM 渲染器
  4. P1 代码无语法高亮 — 纯 <pre> vs CodeMirror/Shiki
  5. P2 双面板职责交叉 — ArtifactPanel vs RightPanel"文件"tab
  6. P2 缺少详情内文件切换 — 需返回列表才能切换文件
  7. P3 聊天内嵌产物卡片缺失
  8. P3 HTML/图片/表格渲染缺失

3.3 推荐方案

方案 A最小可行基于现有架构补全

在现有 ArtifactPanel + artifactStore 上修补:

  • 数据源:扩展 streamStore 中的 tool output 解析,覆盖更多工具类型
  • 持久化artifactStore 追加 IndexedDB 写入(复用 messageStore 模式)
  • Markdown:引入 react-markdown + remark-gfm 替换手写渲染器
  • 代码高亮:引入 shikihighlight.js
  • 合并面板RightPanel "文件"tab 功能合并到 ArtifactPanel删除 RightPanel 的 files tab

工作量~2-3 天

方案 B参照 DeerFlow 重构(推荐)

借鉴 DeerFlow 架构但适配 ZCLAW Tauri 本地架构:

DeerFlow 组件 ZCLAW 适配
FastAPI 产物路由 Tauri 命令 artifact_list / artifact_read / artifact_serve
磁盘 outputs/ 目录 {workspace}/artifacts/{session_key}/
LangGraph checkpoint SQLite (已有 zclaw-memory)
React Query 缓存 TanStack Query 或 Zustand + stale cache
CodeMirror 只读 引入 @uiw/react-codemirror
Streamdown MD react-markdown + remark-gfm + rehype-katex
iframe HTML 预览 Tauri webview window (安全隔离)

核心改动清单:

  1. Rust 侧zclaw-kernel

    • 新增 artifact_create / artifact_list / artifact_read Tauri 命令
    • 产物写入 {workspace}/artifacts/{session_key}/
    • 中间件链中 ToolEnd 事件触发产物注册
  2. 前端 Store

    • artifactStore 增加 IndexedDB 持久化
    • 从 streamStore 解耦产物创建逻辑到独立 hook
  3. 前端组件

    • 替换 MarkdownPreview → react-markdown + GFM
    • 引入 CodeMirror/shiki 代码高亮
    • 详情视图增加文件下拉切换
    • RightPanel "文件" tab 合并或移除

工作量~5-7 天

方案 C借鉴 Hermes 防御机制(附加)

无论选 A 还是 B都可叠加 Hermes 的大输出防御:

  • 中间件链 ToolOutputGuard 层增加溢出检测
  • 超阈值产物自动持久化到磁盘,上下文替换为 <persisted-output> 预览
  • agent 可通过 read_file 回读完整内容

四、关键依赖库参考

用途 DeerFlow 使用 推荐
react-markdown Markdown 渲染 (Streamdown)
remark-gfm GFM 表格/删除线/任务列表
rehype-katex 数学公式渲染 按需
@uiw/react-codemirror 代码编辑器/高亮
shiki 静态代码高亮 (chat 内代码块)
react-resizable-panels 分栏布局 已有
@tanstack/react-query 数据缓存 可选

五、文件索引

参考项目 关键路径
DeerFlow 前端 G:/deerflow/frontend/src/components/workspace/artifacts/
DeerFlow 前端工具 G:/deerflow/frontend/src/core/artifacts/
DeerFlow 布局 G:/deerflow/frontend/src/components/workspace/chats/chat-box.tsx
DeerFlow 代码编辑 G:/deerflow/frontend/src/components/workspace/code-editor.tsx
DeerFlow 后端路由 G:/deerflow/backend/app/gateway/routers/artifacts.py
DeerFlow 后端工具 G:/deerflow/backend/packages/harness/deerflow/tools/builtins/present_file_tool.py
Hermes 输出管理 G:/hermes-agent-main/tools/tool_result_storage.py
Hermes 预算配置 G:/hermes-agent-main/tools/budget_config.py