Дифи
diffs — це необов’язковий інструмент plugin із короткими вбудованими системними вказівками та супровідною навичкою, яка перетворює вміст змін на артефакт дифа лише для читання для агентів.
Він приймає або:
- текст
beforeіafter - уніфікований
patch
- URL переглядача gateway для представлення в canvas
- шлях до відрендереного файла (PNG або PDF) для надсилання в повідомленні
- обидва результати за один виклик
Швидкий старт
- Увімкніть plugin.
- Викликайте
diffsзmode: "view"для сценаріїв, орієнтованих насамперед на canvas. - Викликайте
diffsзmode: "file"для сценаріїв доставки файлів у чаті. - Викликайте
diffsзmode: "both", коли потрібні обидва артефакти.
Увімкнення plugin
Вимкнення вбудованих системних вказівок
Якщо ви хочете залишити інструментdiffs увімкненим, але вимкнути його вбудовані вказівки для системного промпта, встановіть plugins.entries.diffs.hooks.allowPromptInjection у false:
before_prompt_build plugin diffs, але залишає доступними plugin, інструмент і супровідну навичку.
Якщо ви хочете вимкнути і вказівки, і інструмент, натомість вимкніть plugin.
Типовий робочий процес агента
- Агент викликає
diffs. - Агент читає поля
details. - Далі агент або:
- відкриває
details.viewerUrlчерезcanvas present - надсилає
details.filePathчерезmessage, використовуючиpathабоfilePath - робить обидві дії
- відкриває
Приклади вхідних даних
До і після:Довідник вхідних параметрів інструмента
Усі поля необов’язкові, якщо не зазначено інше:before(string): початковий текст. Обов’язковий разом ізafter, якщоpatchпропущено.after(string): оновлений текст. Обов’язковий разом ізbefore, якщоpatchпропущено.patch(string): текст уніфікованого дифа. Взаємовиключний ізbeforeтаafter.path(string): відображуване ім’я файла для режиму before/after.lang(string): підказка перевизначення мови для режиму before/after. Невідомі значення переводяться до простого тексту.title(string): перевизначення заголовка переглядача.mode("view" | "file" | "both"): режим виводу. За замовчуванням використовується значення plugindefaults.mode. Застарілий псевдонім:"image"поводиться як"file"і досі приймається для зворотної сумісності.theme("light" | "dark"): тема переглядача. За замовчуванням використовується значення plugindefaults.theme.layout("unified" | "split"): макет дифа. За замовчуванням використовується значення plugindefaults.layout.expandUnchanged(boolean): розгортати незмінені секції, коли доступний повний контекст. Лише параметр окремого виклику (не ключ значення plugin за замовчуванням).fileFormat("png" | "pdf"): формат відрендереного файла. За замовчуванням використовується значення plugindefaults.fileFormat.fileQuality("standard" | "hq" | "print"): профіль якості для рендерингу PNG або PDF.fileScale(number): перевизначення масштабу пристрою (1-4).fileMaxWidth(number): максимальна ширина рендерингу в CSS-пікселях (640-2400).ttlSeconds(number): TTL артефакта в секундах для переглядача та окремих файлових виводів. За замовчуванням 1800, максимум 21600.baseUrl(string): перевизначення origin URL переглядача. Перевизначає pluginviewerBaseUrl. Має бутиhttpабоhttps, без query/hash.
format->fileFormatimageFormat->fileFormatimageQuality->fileQualityimageScale->fileScaleimageMaxWidth->fileMaxWidth
- Максимум для
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 (14,000,000 відрендерених пікселів).fileQuality: "print": максимум 24 MP (24,000,000 відрендерених пікселів).- Для PDF також діє максимум 50 сторінок.
Контракт details у виводі
Інструмент повертає структуровані метадані вdetails.
Спільні поля для режимів, які створюють переглядач:
artifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext(agentId,sessionId,messageChannel,agentAccountId, якщо доступні)
artifactIdexpiresAtfilePathpath(те саме значення, що йfilePath, для сумісності з інструментом message)fileBytesfileFormatfileQualityfileScalefileMaxWidth
format(те саме значення, що йfileFormat)imagePath(те саме значення, що йfilePath)imageBytes(те саме значення, що йfileBytes)imageQuality(те саме значення, що йfileQuality)imageScale(те саме значення, що йfileScale)imageMaxWidth(те саме значення, що йfileMaxWidth)
mode: "view": лише поля переглядача.mode: "file": лише поля файла, без артефакта переглядача.mode: "both": поля переглядача плюс поля файла. Якщо рендеринг файла не вдається, переглядач усе одно повертається зfileErrorі псевдонімом сумісностіimageError.
Згорнуті незмінені секції
- Переглядач може показувати рядки на кшталт
N unmodified lines. - Елементи керування розгортанням у таких рядках умовні й не гарантуються для кожного виду вхідних даних.
- Елементи керування розгортанням з’являються, коли відрендерений диф має дані розгортаного контексту, що типово для вхідних даних before/after.
- Для багатьох уніфікованих патчів пропущені тіла контексту недоступні в розібраних фрагментах патча, тому рядок може з’являтися без елементів керування розгортанням. Це очікувана поведінка.
expandUnchangedзастосовується лише тоді, коли існує контекст, який можна розгорнути.
Значення plugin за замовчуванням
Установіть загальні значення plugin за замовчуванням у~/.openclaw/openclaw.json:
fontFamilyfontSizelineSpacinglayoutshowLineNumbersdiffIndicatorswordWrapbackgroundthemefileFormatfileQualityfileScalefileMaxWidthmode
viewerBaseUrl(string, необов’язково)- Належний plugin резервний варіант для повернених посилань переглядача, коли виклик інструмента не передає
baseUrl. - Має бути
httpабоhttps, без query/hash.
- Належний plugin резервний варіант для повернених посилань переглядача, коли виклик інструмента не передає
Конфігурація безпеки
security.allowRemoteViewer(boolean, за замовчуваннямfalse)false: запити не через loopback до маршрутів переглядача відхиляються.true: віддалені переглядачі дозволені, якщо токенізований шлях дійсний.
Життєвий цикл артефактів і зберігання
- Артефакти зберігаються в тимчасовій підпапці:
$TMPDIR/openclaw-diffs. - Метадані артефакта переглядача містять:
- випадковий ID артефакта (20 hex-символів)
- випадковий токен (48 hex-символів)
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
baseUrl зберігається також і для запитів до ресурсів.
Поведінка побудови URL:
- Якщо надано
baseUrlу виклику інструмента, він використовується після суворої перевірки. - Інакше, якщо налаштовано plugin
viewerBaseUrl, використовується він. - Без жодного з цих перевизначень URL переглядача за замовчуванням вказує на loopback
127.0.0.1. - Якщо режим прив’язки gateway —
customі встановленоgateway.customBindHost, використовується цей хост.
baseUrl:
- Має бути
http://абоhttps://. - Query і hash відхиляються.
- Дозволено origin плюс необов’язковий базовий шлях.
Модель безпеки
Посилення безпеки переглядача:- Лише loopback за замовчуванням.
- Токенізовані шляхи переглядача зі суворою перевіркою ID і токена.
- CSP відповіді переглядача:
default-src 'none'- скрипти й ресурси лише з того ж джерела
- без зовнішнього
connect-src
- Обмеження частоти віддалених промахів, коли віддалений доступ увімкнено:
- 40 збоїв за 60 секунд
- блокування на 60 секунд (
429 Too Many Requests)
- Маршрутизація запитів браузера для знімків екрана за замовчуванням усе забороняє.
- Дозволено лише локальні ресурси переглядача з
http://127.0.0.1/plugins/diffs/assets/*. - Зовнішні мережеві запити блокуються.
Вимоги до браузера для файлового режиму
Дляmode: "file" і mode: "both" потрібен браузер, сумісний із Chromium.
Порядок визначення:
browser.executablePathу конфігурації OpenClaw.- Змінні середовища:
OPENCLAW_BROWSER_EXECUTABLE_PATHBROWSER_EXECUTABLE_PATHPLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
- Резервне визначення через команди/шляхи платформи.
Diff PNG/PDF rendering requires a Chromium-compatible browser...
Усунення проблем
Помилки перевірки вхідних даних: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.
- Використовуйте origin
{field} exceeds maximum size (...)- Зменште розмір payload.
- Відхилення великого патча
- Зменште кількість файлів у патчі або загальну кількість рядків.
- URL переглядача за замовчуванням вказує на
127.0.0.1. - Для сценаріїв віддаленого доступу:
- установіть plugin
viewerBaseUrl, або - передавайте
baseUrlдля кожного виклику інструмента, або - використовуйте
gateway.bind=customіgateway.customBindHost
- установіть plugin
- Якщо
gateway.trustedProxiesвключає loopback для проксі на тому самому хості (наприклад Tailscale Serve), сирі loopback-запити до переглядача без заголовків forwarded client-IP навмисно завершуються за принципом fail closed. - Для такої топології проксі:
- віддавайте перевагу
mode: "file"абоmode: "both", коли вам потрібне лише вкладення, або - навмисно увімкніть
security.allowRemoteViewerі встановіть pluginviewerBaseUrlабо передайте проксі/publicbaseUrl, коли потрібен URL переглядача, яким можна ділитися
- віддавайте перевагу
- Увімкнюйте
security.allowRemoteViewerлише тоді, коли вам справді потрібен зовнішній доступ до переглядача.
- Це може трапитися для вхідних даних у форматі patch, якщо патч не містить контексту, який можна розгорнути.
- Це очікувана поведінка й не означає збій переглядача.
- Артефакт прострочився через TTL.
- Токен або шлях змінилися.
- Очищення видалило застарілі дані.
Операційні рекомендації
- Віддавайте перевагу
mode: "view"для локального інтерактивного перегляду в canvas. - Віддавайте перевагу
mode: "file"для зовнішніх чат-каналів, яким потрібне вкладення. - Тримайте
allowRemoteViewerвимкненим, якщо вашому розгортанню не потрібні віддалені URL переглядача. - Для чутливих дифів явно задавайте короткий
ttlSeconds. - Уникайте передавання секретів у вхідних даних дифа, якщо це не потрібно.
- Якщо ваш канал сильно стискає зображення (наприклад Telegram або WhatsApp), віддавайте перевагу PDF-виводу (
fileFormat: "pdf").
- Працює на базі Diffs.