跳到正文
FunCoding

搜索

搜索文档、文章、Skill 和 MCP

Diffs

面向智能体的只读差异查看器和文件渲染器(可选插件工具)

diffs 是一个可选的内置插件工具,可将修改前/后的文本或统一补丁转换为只读 diff 工件。它还会在系统提示词前添加简短的智能体指导,并随附一项配套 Skills,以提供更完整的说明。

输入:before + after 文本,或统一 patch(互斥)。

输出:用于画布呈现的 Gateway 网关查看器 URL、用于消息传递的已渲染 PNG/PDF 文件路径,或两者。

快速开始

安装插件

openclaw plugins install diffs

启用插件

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

选择模式

view

画布优先流程:智能体使用 mode: "view" 调用 diffs,并使用 canvas present 打开 details.viewerUrl。

file

聊天文件传递:智能体使用 mode: "file" 调用 diffs,并通过 path 或 filePath 使用 message 发送 details.filePath。

both

组合模式(默认):智能体使用 mode: "both" 调用 diffs,通过一次调用获取两种工件。

禁用内置系统指导

要保留工具但移除添加到系统提示词前的指导,请将 plugins.entries.diffs.hooks.allowPromptInjection 设置为 false:

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

这会阻止插件的 before_prompt_build 钩子,同时保持工具和 Skills 可用。要同时禁用指导和工具,请改为禁用插件。

工具输入参考

除非特别注明,否则所有字段均为可选。

原始文本。省略 patch 时,必须与 after 一起提供。

更新后的文本。省略 patch 时,必须与 before 一起提供。

统一 diff 文本。与 before 和 after 互斥。

修改前/后模式的显示文件名。

修改前/后模式的语言覆盖提示。未知值和默认查看器集合以外的语言会回退为纯文本,除非安装了 Diff Viewer Language Pack 插件。

查看器标题覆盖值。

输出模式。默认为插件默认值 defaults.mode(both)。已弃用的别名:"image" 的行为与 "file" 完全相同。

查看器主题。默认为插件默认值 defaults.theme。

Diff 布局。默认为插件默认值 defaults.layout。

在完整上下文可用时展开未更改的部分。仅限单次调用的选项(不是插件默认键)。

渲染后的文件格式。默认为插件默认值 defaults.fileFormat。

PNG/PDF 渲染的质量预设。

设备缩放覆盖值(1-4)。

最大渲染宽度,以 CSS 像素为单位(640-2400)。

查看器和独立文件输出的工件 TTL,以秒为单位。最大值为 21600。

查看器 URL 来源覆盖值。覆盖插件的 viewerBaseUrl。必须为 http 或 https,不得包含查询参数/哈希。

验证和限制
  • before/after:每个最大 512 KiB。
  • patch:最大 2 MiB。
  • path:最大 2048 字节。
  • lang:最大 128 字节。
  • title:最大 1024 字节。
  • 补丁复杂度上限:最多 128 个文件,总计 120000 行。
  • 同时使用 patch 和 before/after 将被拒绝。
  • 渲染文件的安全限制(PNG 和 PDF):
    • fileQuality: "standard":最大 8 MP(8,000,000 个渲染像素)。
    • fileQuality: "hq":最大 14 MP。
    • fileQuality: "print":最大 24 MP。
    • PDF 还限制为最多 50 页。

语法高亮

内置语言:

javascript、typescript、tsx、jsx、json、markdown、yaml、css、html、sh、python、go、rust、java、c、cpp、csharp、php、sql、docker、ruby、swift、kotlin、r、dart、lua、powershell、xml 和 toml。

常用别名(js、ts、bash、md、yml、c++、dockerfile、rb、kt、ps1 等)会规范化为这些语言。

安装 Diff Viewer Language Pack 插件可支持更多语言(Astro、Vue、Svelte、MDX、GraphQL、Terraform/HCL、Nix、Clojure、Elixir、Haskell、OCaml、Scala、Zig、Solidity、Verilog/VHDL、Fortran、MATLAB、LaTeX、Mermaid、Sass/Less/SCSS、Nginx、Apache、CSV、dotenv、INI、diff 等):

openclaw plugins install clawhub:@openclaw/diffs-language-pack

未安装该语言包时,不支持的语言仍会以易读的纯文本呈现。有关上游目录,请参阅 Diffs Language Pack 插件和 Shiki 语言。

输出详情契约

所有成功结果都包含 changed:修改前/后输入相同时返回 false,且不会创建工件;已渲染的结果返回 true。

查看器字段(view 和 both 模式)
  • changed
  • artifactId
  • viewerUrl
  • viewerPath
  • title
  • expiresAt
  • inputKind
  • fileCount
  • mode
  • context(可用时为 agentId、sessionId、messageChannel、agentAccountId)
文件字段(file 和 both 模式)
  • changed
  • artifactId
  • expiresAt
  • filePath
  • path(与 filePath 的值相同,用于消息工具兼容性)
  • fileBytes
  • fileFormat
  • fileQuality
  • fileScale
  • fileMaxWidth
模式返回内容
"view"仅查看器字段。
"file"仅文件字段,不含查看器工件。
"both"查看器字段加文件字段。如果文件渲染失败,查看器仍会随 fileError 返回。

折叠的未更改部分

查看器会显示类似 N unmodified lines 的行。仅当渲染后的 diff 包含可展开的上下文数据时,才会显示展开控件(修改前/后输入通常如此)。许多统一补丁会在其区块中省略上下文正文,因此该行可能出现但没有展开控件——这是预期行为,并非错误。expandUnchanged 仅在存在可展开上下文时适用。

多文件导航

涉及多个文件的补丁以已更改文件摘要卡片开头:+N / -N 总数、各文件计数、新增/删除/重命名徽章,以及跳转到各文件的锚点链接。渲染后的 PNG/PDF 文件会保留各文件的标题计数,但会移除交互式视图切换控件,因为这些控件在静态文件中无法使用。

插件默认值

在 ~/.openclaw/openclaw.json 中设置插件范围的默认值:

{
  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",
            ttlSeconds: 21600,
          },
        },
      },
    },
  },
}

支持的 defaults 键:fontFamily、fontSize、lineSpacing、layout、showLineNumbers、diffIndicators、wordWrap、background、theme、fileFormat、fileQuality、fileScale、fileMaxWidth、mode、ttlSeconds。显式工具调用参数会覆盖这些值。

持久化查看器 URL 配置

当工具调用未传递 baseUrl 时,由插件管理的返回查看器链接回退值。必须为 http 或 https,不得包含查询参数/哈希。

{
  plugins: {
    entries: {
      diffs: {
        enabled: true,
        config: {
          viewerBaseUrl: "https://gateway.example.com/openclaw",
        },
      },
    },
  },
}

安全配置

false:拒绝向查看器路由发出的非 local loopback 请求。true:如果令牌化路径有效,则允许远程查看器。

{
  plugins: {
    entries: {
      diffs: {
        enabled: true,
        config: {
          security: {
            allowRemoteViewer: false,
          },
        },
      },
    },
  },
}

工件生命周期和存储

  • 查看器 HTML 和元数据位于共享的 state/openclaw.sqlite 数据库中,归属 Diffs 插件的 blob 命名空间。HTML 使用 gzip 压缩;SQLite 仅存储随机 URL 令牌的 SHA-256 哈希,而不存储令牌本身。
  • 渲染后的 PNG/PDF 文件仍是 $TMPDIR/openclaw-diffs 下的临时实体,因为渠道投递需要文件路径。SQLite 管理其过期元数据;不会写入 JSON 辅助文件。
  • 默认工件 TTL:30 分钟。可接受的最大 TTL:6 小时。
  • 每次创建工件调用后都会择机运行清理。首先删除已过期的 SQLite 行,随后删除任何对应的 PNG/PDF 目录。
  • 兜底扫描会移除超过 24 小时且没有对应行的临时文件夹。不会导入或读取旧版 meta.json、file-meta.json 和 viewer.html 缓存。

查看器 URL 和网络行为

查看器路由:/plugins/diffs/view/{artifactId}/{token}

查看器资源:

  • /plugins/diffs/assets/viewer.js
  • /plugins/diffs/assets/viewer-runtime.js
  • /plugins/diffs-language-pack/assets/viewer.js(仅当 diff 使用语言包所支持的语言时)

查看器文档会相对于查看器 URL 解析这些资源,因此可选的 baseUrl 路径前缀也会应用于资源请求。

URL 解析顺序:工具调用的 baseUrl(经过严格验证后)-> 插件的 viewerBaseUrl -> local loopback 的 127.0.0.1 默认值。如果 Gateway 网关绑定模式为 custom,且已设置 gateway.customBindHost,则使用该主机而非 local loopback。

baseUrl 规则:必须为 http:// 或 https://;拒绝查询参数和哈希;允许使用源站以及可选的基础路径。

安全模型

查看器加固
  • 默认仅限 local loopback。
  • 使用令牌化查看器路径,并严格验证 ID 和令牌格式。
  • 查看器响应 CSP:default-src 'none';脚本/资源只能来自自身;不允许出站 connect-src。
  • 启用远程访问时会对远程访问失败进行限流:60 秒内失败 40 次将触发 60 秒锁定(429 Too Many Requests)。
文件渲染加固
  • 屏幕截图浏览器请求路由默认拒绝。
  • 仅允许来自 http://127.0.0.1/plugins/diffs/assets/* 的本地查看器资源。
  • 阻止外部网络请求。

文件模式的浏览器要求

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

解析顺序:

配置

OpenClaw 配置中的 browser.executablePath。

环境变量

  • OPENCLAW_BROWSER_EXECUTABLE_PATH
  • BROWSER_EXECUTABLE_PATH
  • PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH

平台回退

Chrome、Chromium、Edge 和 Brave 的常见安装路径与 PATH 查找。

常见失败文本:Diff PNG/PDF rendering requires a Chromium-compatible browser...。可通过安装 Chrome、Chromium、Edge 或 Brave,或设置上述任一可执行文件路径选项来修复。

故障排查

输入验证错误
  • Provide patch or both before and after text. —— 同时包含 before 和 after,或提供 patch。
  • Provide either patch or before/after input, not both. —— 不要混用输入模式。
  • Invalid baseUrl: ... —— 使用带可选路径的 http(s) 源站,不要包含查询参数/哈希。
  • {field} exceeds maximum size (...) —— 减小有效载荷大小。
  • 大型补丁被拒绝 —— 减少补丁文件数量或总行数。
查看器可访问性
  • 查看器 URL 默认解析为 127.0.0.1。
  • 如需远程访问,可设置插件的 viewerBaseUrl、在每次调用时传入 baseUrl,或将 gateway.bind=custom 与 gateway.customBindHost 配合使用。
  • 如果 gateway.trustedProxies 包含用于同主机代理的 local loopback(例如 Tailscale Serve),则根据设计,不带转发客户端 IP 标头的原始 local loopback 查看器请求会以失败关闭。
  • 对于该代理拓扑,优先使用 mode: "file"/"both" 作为附件;或者有意启用 security.allowRemoteViewer,并配合插件的 viewerBaseUrl/代理的 baseUrl,以提供可共享的查看器链接。
  • 仅当确实需要外部查看器访问时,才启用 security.allowRemoteViewer。
未修改行没有展开按钮

如果补丁输入缺少可展开的上下文,这是预期行为,并非查看器故障。

找不到工件
  • 工件因 TTL 到期。
  • 令牌或路径已更改。
  • 清理操作移除了陈旧数据。

操作指南

  • 在画布中进行本地交互式审查时,优先使用 mode: "view"。
  • 对于需要附件的出站聊天渠道,优先使用 mode: "file"。
  • 除非部署需要远程查看器 URL,否则请保持 allowRemoteViewer 禁用。
  • 对于敏感 diff,请显式设置较短的 ttlSeconds。
  • 非必要时,避免在 diff 输入中发送机密信息。
  • 如果你的渠道会大幅压缩图像(例如 Telegram 或 WhatsApp),请优先使用 PDF 输出(fileFormat: "pdf")。

Diff 渲染引擎由 Diffs 提供支持。

相关内容