Перейти к основному содержанию
diffs — необязательный инструмент Plugin с краткими встроенными системными указаниями и сопутствующим Skill, который превращает содержимое изменений в доступный только для чтения артефакт diff для агентов. Он принимает:
  • текст before и after
  • унифицированный patch
Он может возвращать:
  • URL просмотрщика Gateway для представления на canvas
  • путь к отрендеренному файлу (PNG или PDF) для доставки в сообщении
  • оба результата за один вызов
Если плагин включен, он добавляет краткие указания по использованию в пространство системного промпта, а также предоставляет подробный Skill для случаев, когда агенту нужны более полные инструкции.

Быстрый старт

1

Установите плагин

openclaw plugins install diffs
2

Включите плагин

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

Выберите режим

Потоки с приоритетом canvas: агенты вызывают diffs с mode: "view" и открывают details.viewerUrl с помощью canvas present.

Отключение встроенных системных указаний

Если вы хотите оставить инструмент diffs включенным, но отключить его встроенные указания для системного промпта, установите plugins.entries.diffs.hooks.allowPromptInjection в false:
{
  plugins: {
    entries: {
      diffs: {
        enabled: true,
        hooks: {
          allowPromptInjection: false,
        },
      },
    },
  },
}
Это блокирует хук before_prompt_build плагина diffs, сохраняя доступными сам плагин, инструмент и сопутствующий Skill. Если вы хотите отключить и указания, и инструмент, отключите плагин.

Типичный рабочий процесс агента

1

Вызов diffs

Агент вызывает инструмент diffs с входными данными.
2

Чтение details

Агент читает поля details из ответа.
3

Представление

Агент либо открывает details.viewerUrl с помощью canvas present, либо отправляет details.filePath через message, используя path или filePath, либо делает и то и другое.

Примеры входных данных

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

Справочник входных данных инструмента

Все поля необязательны, если не указано иное.
before
string
Исходный текст. Обязательно вместе с after, если patch не указан.
after
string
Обновленный текст. Обязательно вместе с before, если patch не указан.
patch
string
Текст унифицированного diff. Взаимоисключается с before и after.
path
string
Отображаемое имя файла для режима до и после.
lang
string
Подсказка для переопределения языка в режиме до и после. Неизвестные значения и языки вне стандартного набора просмотрщика откатываются к простому тексту, если не установлен плагин Diff Viewer Language Pack.
title
string
Переопределение заголовка просмотрщика.
mode
"view" | "file" | "both"
Режим вывода. По умолчанию используется значение плагина defaults.mode. Устаревший псевдоним: "image" ведет себя как "file" и по-прежнему принимается для обратной совместимости.
theme
"light" | "dark"
Тема просмотрщика. По умолчанию используется значение плагина defaults.theme.
layout
"unified" | "split"
Макет diff. По умолчанию используется значение плагина defaults.layout.
expandUnchanged
boolean
Разворачивать неизмененные разделы, когда доступен полный контекст. Только опция отдельного вызова (не ключ по умолчанию плагина).
fileFormat
"png" | "pdf"
Формат отрендеренного файла. По умолчанию используется значение плагина defaults.fileFormat.
fileQuality
"standard" | "hq" | "print"
Предустановка качества для рендеринга PNG или PDF.
fileScale
number
Переопределение масштаба устройства (1-4).
fileMaxWidth
number
Максимальная ширина рендеринга в CSS-пикселях (640-2400).
ttlSeconds
number
по умолчанию:"1800"
TTL артефакта в секундах для просмотрщика и автономных файловых выводов. Максимум 21600.
baseUrl
string
Переопределение origin URL просмотрщика. Переопределяет viewerBaseUrl плагина. Должен быть http или https, без query/hash.
По-прежнему принимаются для обратной совместимости:
  • format -> fileFormat
  • imageFormat -> fileFormat
  • imageQuality -> fileQuality
  • imageScale -> fileScale
  • imageMaxWidth -> fileMaxWidth
  • before и after: максимум 512 KiB каждый.
  • patch: максимум 2 MiB.
  • path: максимум 2048 байт.
  • lang: максимум 128 байт.
  • title: максимум 1024 байта.
  • Ограничение сложности patch: максимум 128 файлов и 120000 строк суммарно.
  • patch вместе с before или after отклоняется.
  • Ограничения безопасности отрендеренного файла (применяются к PNG и PDF):
    • fileQuality: "standard": максимум 8 MP (8 000 000 отрендеренных пикселей).
    • fileQuality: "hq": максимум 14 MP (14 000 000 отрендеренных пикселей).
    • fileQuality: "print": максимум 24 MP (24 000 000 отрендеренных пикселей).
    • Для PDF также действует максимум 50 страниц.

Подсветка синтаксиса

OpenClaw включает подсветку синтаксиса для распространенных языков исходного кода, конфигурации и документации: 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, нормализуются к этим стандартным языкам. Установите Plugin языкового пакета просмотрщика различий, чтобы подсвечивать другие языки:
openclaw plugins install clawhub:@openclaw/diffs-language-pack
Когда языковой пакет доступен, OpenClaw может подсвечивать гораздо больше языков. Если пакет не установлен, файлы вне списка по умолчанию все равно отображаются как читаемый простой текст. Примеры включают 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-файлы. Подробности см. в разделе Plugin Diffs Language Pack, а каталог языков и псевдонимов верхнего уровня Shiki — в языках Shiki.

Контракт сведений вывода

Инструмент возвращает структурированные метаданные в details.
Общие поля для режимов, создающих просмотрщик:
  • artifactId
  • viewerUrl
  • viewerPath
  • title
  • expiresAt
  • inputKind
  • fileCount
  • mode
  • context (agentId, sessionId, messageChannel, agentAccountId, если доступны)
Поля файла при рендеринге PNG или PDF:
  • artifactId
  • expiresAt
  • filePath
  • path (то же значение, что и filePath, для совместимости с инструментом сообщений)
  • fileBytes
  • fileFormat
  • fileQuality
  • fileScale
  • fileMaxWidth
Также возвращаются для существующих вызывающих сторон:
  • format (то же значение, что и fileFormat)
  • imagePath (то же значение, что и filePath)
  • imageBytes (то же значение, что и fileBytes)
  • imageQuality (то же значение, что и fileQuality)
  • imageScale (то же значение, что и fileScale)
  • imageMaxWidth (то же значение, что и fileMaxWidth)
Сводка поведения режимов:
РежимЧто возвращается
"view"Только поля просмотрщика.
"file"Только поля файла, без артефакта просмотрщика.
"both"Поля просмотрщика плюс поля файла. Если рендеринг файла завершается неудачей, просмотрщик все равно возвращается с псевдонимом fileError и imageError.

Свернутые неизмененные разделы

  • Средство просмотра может показывать строки вида N unmodified lines.
  • Элементы управления раскрытием для таких строк условны и не гарантируются для каждого вида ввода.
  • Элементы управления раскрытием появляются, когда отрисованный diff содержит данные раскрываемого контекста, что типично для ввода до и после.
  • Для многих входных данных в формате unified patch пропущенные тела контекста недоступны в разобранных hunks патча, поэтому строка может отображаться без элементов управления раскрытием. Это ожидаемое поведение.
  • expandUnchanged применяется только при наличии раскрываемого контекста.

Настройки Plugin по умолчанию

Задайте настройки по умолчанию для всего plugin в ~/.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,
          },
        },
      },
    },
  },
}
Поддерживаемые настройки по умолчанию:
  • fontFamily
  • fontSize
  • lineSpacing
  • layout
  • showLineNumbers
  • diffIndicators
  • wordWrap
  • background
  • theme
  • fileFormat
  • fileQuality
  • fileScale
  • fileMaxWidth
  • mode
  • ttlSeconds
Явные параметры инструмента переопределяют эти настройки по умолчанию.

Постоянная конфигурация URL средства просмотра

viewerBaseUrl
string
Резервное значение, принадлежащее Plugin, для возвращаемых ссылок средства просмотра, когда вызов инструмента не передает baseUrl. Должно быть http или https, без строки запроса/хэша.
{
  plugins: {
    entries: {
      diffs: {
        enabled: true,
        config: {
          viewerBaseUrl: "https://gateway.example.com/openclaw",
        },
      },
    },
  },
}

Конфигурация безопасности

security.allowRemoteViewer
boolean
по умолчанию:"false"
false: не-loopback-запросы к маршрутам средства просмотра отклоняются. true: удаленные средства просмотра разрешены, если токенизированный путь действителен.
{
  plugins: {
    entries: {
      diffs: {
        enabled: true,
        config: {
          security: {
            allowRemoteViewer: false,
          },
        },
      },
    },
  },
}

Жизненный цикл и хранение артефактов

  • Артефакты хранятся во временной подпапке: $TMPDIR/openclaw-diffs.
  • Метаданные артефакта просмотрщика содержат:
    • случайный ID артефакта (20 шестнадцатеричных символов)
    • случайный токен (48 шестнадцатеричных символов)
    • createdAt и expiresAt
    • сохраненный путь viewer.html
  • TTL артефакта по умолчанию составляет 30 минут, если не указан.
  • Максимально допустимый TTL просмотрщика составляет 6 часов.
  • Очистка запускается оппортунистически после создания артефакта.
  • Истекшие артефакты удаляются.
  • Резервная очистка удаляет устаревшие папки старше 24 часов, если метаданные отсутствуют.

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 использует язык из Diff Viewer Language Pack
Документ просмотрщика разрешает эти ресурсы относительно URL просмотрщика, поэтому необязательный префикс пути baseUrl также сохраняется для обоих запросов ресурсов. Поведение построения URL:
  • Если в tool-call предоставлен baseUrl, он используется после строгой проверки.
  • Иначе, если настроен viewerBaseUrl плагина, используется он.
  • Без любого из этих переопределений URL просмотрщика по умолчанию указывает на loopback 127.0.0.1.
  • Если режим привязки Gateway равен custom и задан gateway.customBindHost, используется этот хост.
Правила baseUrl:
  • Должен быть http:// или https://.
  • Query и hash отклоняются.
  • Разрешены origin плюс необязательный базовый путь.

Модель безопасности

  • По умолчанию только loopback.
  • Токенизированные пути просмотрщика со строгой проверкой ID и токена.
  • CSP ответа просмотрщика:
    • default-src 'none'
    • скрипты и ресурсы только из self
    • без исходящих connect-src
  • Ограничение удаленных промахов при включенном удаленном доступе:
    • 40 сбоев за 60 секунд
    • блокировка на 60 секунд (429 Too Many Requests)
  • Маршрутизация запросов браузера для скриншотов по умолчанию запрещающая.
  • Разрешены только локальные ресурсы просмотрщика из http://127.0.0.1/plugins/diffs/assets/*.
  • Внешние сетевые запросы блокируются.

Требования браузера для файлового режима

mode: "file" и mode: "both" требуют Chromium-совместимый браузер. Порядок разрешения:
1

Config

browser.executablePath в конфигурации OpenClaw.
2

Environment variables

  • OPENCLAW_BROWSER_EXECUTABLE_PATH
  • BROWSER_EXECUTABLE_PATH
  • PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
3

Platform fallback

Резервное обнаружение команды/пути платформы.
Распространенный текст ошибки:
  • 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: ... — используйте origin http(s) с необязательным путем, без query/hash.
  • {field} exceeds maximum size (...) — уменьшите размер полезной нагрузки.
  • Отклонение большого patch — уменьшите количество файлов patch или общее число строк.
  • URL просмотрщика по умолчанию разрешается в 127.0.0.1.
  • Для сценариев удаленного доступа:
    • задайте viewerBaseUrl плагина, или
    • передайте baseUrl для каждого вызова инструмента, или
    • используйте gateway.bind=custom и gateway.customBindHost
  • Если gateway.trustedProxies включает loopback для прокси на том же хосте (например, Tailscale Serve), необработанные loopback-запросы просмотрщика без перенаправленных заголовков client-IP завершаются отказом по замыслу.
  • Для такой топологии прокси:
    • предпочитайте mode: "file" или mode: "both", когда вам нужно только вложение, или
    • намеренно включите security.allowRemoteViewer и задайте viewerBaseUrl плагина либо передайте прокси/публичный baseUrl, когда нужен URL просмотрщика, которым можно поделиться
  • Включайте security.allowRemoteViewer только если вам намеренно нужен внешний доступ к просмотрщику.
Это может происходить для ввода patch, когда patch не содержит разворачиваемого контекста. Это ожидаемо и не указывает на сбой просмотрщика.
  • Срок действия артефакта истек из-за TTL.
  • Токен или путь изменился.
  • Очистка удалила устаревшие данные.

Эксплуатационные рекомендации

  • Предпочитайте mode: "view" для локальных интерактивных ревью в canvas.
  • Предпочитайте mode: "file" для исходящих чат-каналов, которым нужно вложение.
  • Оставляйте allowRemoteViewer отключенным, если вашему развертыванию не требуются URL удаленного просмотрщика.
  • Задавайте явный короткий ttlSeconds для чувствительных diff.
  • Избегайте отправки секретов во входных данных diff, когда это не требуется.
  • Если ваш канал агрессивно сжимает изображения (например, Telegram или WhatsApp), предпочитайте вывод PDF (fileFormat: "pdf").
Движок рендеринга diff работает на Diffs.

Связанные материалы