Skip to content

本页介绍 OpenClaw 的可选 Diffs 插件工具。启用后,agent 可以将代码或 Markdown 变更渲染为只读差异制品——可以生成画布查看器链接(mode: "view"),也可以渲染为 PNG/PDF 文件直接发送到聊天(mode: "file")。接受 before/after 文本或 unified patch 作为输入。

Diffs 差异查看工具

diffs 是一个可选的插件工具,内置简短的系统提示引导,并附带一个技能(skill),能够将变更内容转化为 Agent 可呈现的只读差异制品。

接受以下输入之一:

  • beforeafter 文本
  • unified patch

可返回:

  • 用于画布展示的 Gateway 查看器 URL
  • 用于消息投递的渲染文件路径(PNG 或 PDF)
  • 一次调用同时返回两者

快速开始

  1. 启用插件(见下文)。
  2. 本地画布展示:用 mode: "view" 调用 diffs
  3. 聊天文件投递:用 mode: "file" 调用 diffs
  4. 同时需要两种输出:用 mode: "both" 调用 diffs

启用插件

json5
{
  plugins: {
    entries: {
      diffs: {
        enabled: true,
      },
    },
  },
}

禁用内置系统提示引导

如果想保留 diffs 工具但禁用其内置系统提示引导:

json5
{
  plugins: {
    entries: {
      diffs: {
        enabled: true,
        hooks: {
          allowPromptInjection: false,
        },
      },
    },
  },
}

这会屏蔽 diffs 插件的 before_prompt_build 钩子,同时保持插件、工具和配套技能可用。若要同时禁用引导和工具,直接禁用插件。

典型 Agent 工作流

  1. Agent 调用 diffs
  2. Agent 读取 details 字段。
  3. Agent 选择:
    • canvas present 打开 details.viewerUrl
    • 通过 pathfilePathmessage 中发送 details.filePath
    • 两者都做

输入示例

before 和 after:

json
{
  "before": "# Hello\n\nOne",
  "after": "# Hello\n\nTwo",
  "path": "docs/example.md",
  "mode": "view"
}

unified patch:

json
{
  "patch": "diff --git a/src/example.ts b/src/example.ts\n--- a/src/example.ts\n+++ b/src/example.ts\n@@ -1 +1 @@\n-const x = 1;\n+const x = 2;\n",
  "mode": "both"
}

工具输入参数参考

所有字段均为可选,除非另有说明:

  • beforestring):原始文本。省略 patch 时,需与 after 一起提供。
  • afterstring):更新后文本。省略 patch 时,需与 before 一起提供。
  • patchstring):unified diff 文本。与 before/after 互斥。
  • pathstring):before/after 模式下显示的文件名。
  • langstring):语言覆盖提示,未知值回退为纯文本。
  • titlestring):查看器标题覆盖。
  • mode"view" | "file" | "both"):输出模式,默认为插件默认值 defaults.mode。废弃别名 "image" 等同于 "file",仍向后兼容。
  • theme"light" | "dark"):查看器主题。
  • layout"unified" | "split"):差异布局。
  • expandUnchangedboolean):有完整上下文时展开未改动部分。仅限每次调用设置。
  • fileFormat"png" | "pdf"):渲染文件格式。
  • fileQuality"standard" | "hq" | "print"):PNG 或 PDF 渲染质量预设。
  • fileScalenumber):设备缩放倍率覆盖(1-4)。
  • fileMaxWidthnumber):最大渲染宽度(CSS 像素,640-2400)。
  • ttlSecondsnumber):制品 TTL(秒),默认 1800,最大 21600(6小时)。
  • baseUrlstring):查看器 URL origin 覆盖,必须是 httphttps,不含查询参数和 hash。

验证与限制:

  • beforeafter 各最大 512 KiB。
  • patch 最大 2 MiB,最多 128 个文件、120000 行总计。
  • 渲染文件安全限制:
    • fileQuality: "standard":最大 800 万像素
    • fileQuality: "hq":最大 1400 万像素
    • fileQuality: "print":最大 2400 万像素
    • PDF 另有最大 50 页限制

输出 details 契约

查看器模式下的公共字段: artifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext

文件渲染模式下的文件字段: artifactIdexpiresAtfilePathpath(同 filePath)、fileBytesfileFormatfileQualityfileScalefileMaxWidth

模式行为:

  • mode: "view":仅查看器字段。
  • mode: "file":仅文件字段,不创建查看器制品。
  • mode: "both":查看器字段加文件字段。若文件渲染失败,查看器仍返回,并附 fileError

插件默认值配置

json5
{
  plugins: {
    entries: {
      diffs: {
        enabled: true,
        config: {
          defaults: {
            fontFamily: "Fira Code",
            fontSize: 15,
            lineSpacing: 1.6,
            layout: "unified",
            showLineNumbers: true,
            diffIndicators: "bars",
            wordWrap: true,
            background: true,
            theme: "dark",
            fileFormat: "png",
            fileQuality: "standard",
            fileScale: 2,
            fileMaxWidth: 960,
            mode: "both",
          },
          viewerBaseUrl: "https://gateway.example.com/openclaw",  // 可选:远程查看器 URL
        },
      },
    },
  },
}

工具显式参数会覆盖这些默认值。

安全配置

json5
{
  plugins: {
    entries: {
      diffs: {
        enabled: true,
        config: {
          security: {
            allowRemoteViewer: false,  // 默认:仅允许 loopback 访问查看器
          },
        },
      },
    },
  },
}

查看器加固:

  • 默认仅限 loopback 地址。
  • Tokenized 查看器路径,严格校验 ID(20 位十六进制)和 token(48 位十六进制)。
  • 查看器响应 CSP:default-src 'none',脚本和资源仅来自 self,无出站 connect-src
  • 启用远程访问时限流:每 60 秒 40 次失败后 60 秒锁定。

制品生命周期与存储

  • 制品存储在 $TMPDIR/openclaw-diffs
  • 默认查看器 TTL 为 30 分钟;最大 6 小时。
  • 清理在制品创建后机会性地运行,过期制品会被删除。
  • 元数据缺失时,回退清理删除 24 小时以上的过期文件夹。

file 模式的浏览器依赖

mode: "file"mode: "both" 需要 Chromium 兼容浏览器。

解析顺序:

  1. OpenClaw 配置中的 browser.executablePath
  2. 环境变量:OPENCLAW_BROWSER_EXECUTABLE_PATHBROWSER_EXECUTABLE_PATHPLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
  3. 平台命令/路径发现回退

常见失败:Diff PNG/PDF rendering requires a Chromium-compatible browser...

解决:安装 Chrome、Chromium、Edge 或 Brave,或设置上述可执行路径选项。

故障排查

问题解决方案
Provide patch or both before and after text.同时提供 beforeafter,或提供 patch
Provide either patch or before/after input, not both.不要混用两种输入模式。
Invalid baseUrl: ...使用不含查询参数/hash 的 http(s) origin。
{field} exceeds maximum size减小 payload 大小。
未改动行无展开按钮patch 输入不包含可展开上下文时的预期行为。
制品未找到制品因 TTL 过期,或 token/路径已变更。
查看器 URL 解析为 127.0.0.1远程访问需设置 viewerBaseUrl 或每次调用传 baseUrl,并启用 security.allowRemoteViewer

运维建议

  • 本地交互式审查,优先使用 mode: "view"
  • 需要作为附件发送到外部聊天渠道时,优先使用 mode: "file"
  • 对 Telegram/WhatsApp(大幅压缩图片的渠道),优先使用 PDF 输出(fileFormat: "pdf")。
  • 对敏感差异设置较短的显式 ttlSeconds
  • 除非部署需要远程查看器 URL,否则保持 allowRemoteViewer 禁用。

差异渲染引擎:由 Diffs 提供支持。

常见问题

Q: mode: "view"mode: "file" 应该怎么选?

A: 如果用户在使用画布(canvas)功能,用 mode: "view" 生成查看器链接,可以在对话中直接展示可交互的差异视图。如果需要把差异发送到 Telegram、WhatsApp 或邮件等不支持 canvas 的渠道,用 mode: "file" 生成 PNG 或 PDF 附件。两者都需要用 mode: "both"

Q: 为什么 patch 输入的未改动行没有展开按钮?

A: 这是预期行为。unified patch 格式只包含变更的 hunk,未改动的上下文行内容通常不在 patch 数据中,所以查看器无法提供展开控件。before/after 输入通常有完整上下文,因此展开控件会出现。

Q: 制品有效期是多长?可以延长吗?

A: 默认 30 分钟(1800 秒),可通过 ttlSeconds 参数调整,最大值为 21600 秒(6 小时)。过期后制品会被清理,无法恢复——需要重新调用 diffs 生成新制品。