Diffs
diffs to opcjonalne narzędzie pluginu z krótkimi wbudowanymi wskazówkami systemowymi oraz towarzyszącym Skill, który zamienia treść zmian w artefakt różnic tylko do odczytu dla agentów.
Akceptuje ono:
- tekst
beforeiafter - ujednolicony
patch
- adres URL widoku Gateway do prezentacji w Canvas
- ścieżkę do wyrenderowanego pliku (PNG lub PDF) do dostarczenia w wiadomości
- oba wyniki w jednym wywołaniu
Szybki start
- Włącz plugin.
- Wywołaj
diffszmode: "view"dla przepływów zorientowanych najpierw na Canvas. - Wywołaj
diffszmode: "file"dla przepływów dostarczania plików w czacie. - Wywołaj
diffszmode: "both", gdy potrzebujesz obu artefaktów.
Włącz plugin
Wyłącz wbudowane wskazówki systemowe
Jeśli chcesz pozostawić narzędziediffs włączone, ale wyłączyć jego wbudowane wskazówki promptu systemowego, ustaw plugins.entries.diffs.hooks.allowPromptInjection na false:
before_prompt_build pluginu diffs, pozostawiając plugin, narzędzie i towarzyszący Skill dostępne.
Jeśli chcesz wyłączyć zarówno wskazówki, jak i narzędzie, wyłącz sam plugin.
Typowy przepływ pracy agenta
- Agent wywołuje
diffs. - Agent odczytuje pola
details. - Agent:
- otwiera
details.viewerUrlprzezcanvas present - wysyła
details.filePathza pomocąmessage, używającpathlubfilePath - robi obie rzeczy
- otwiera
Przykłady wejścia
Before i after:Odniesienie do danych wejściowych narzędzia
Wszystkie pola są opcjonalne, o ile nie zaznaczono inaczej:before(string): tekst oryginalny. Wymagany wraz zafter, gdy pominiętopatch.after(string): zaktualizowany tekst. Wymagany wraz zbefore, gdy pominiętopatch.patch(string): tekst ujednoliconej różnicy. Wzajemnie wyklucza się zbeforeiafter.path(string): wyświetlana nazwa pliku dla trybu before i after.lang(string): wskazówka nadpisania języka dla trybu before i after. Nieznane wartości wracają do zwykłego tekstu.title(string): nadpisanie tytułu widoku.mode("view" | "file" | "both"): tryb wyjścia. Domyślnie używa ustawienia pluginudefaults.mode. Przestarzały alias:"image"działa jak"file"i nadal jest akceptowany dla zgodności wstecznej.theme("light" | "dark"): motyw widoku. Domyślnie używa ustawienia pluginudefaults.theme.layout("unified" | "split"): układ różnic. Domyślnie używa ustawienia pluginudefaults.layout.expandUnchanged(boolean): rozwija niezmienione sekcje, gdy dostępny jest pełny kontekst. Opcja tylko dla pojedynczego wywołania (nie jest kluczem domyślnym pluginu).fileFormat("png" | "pdf"): format wyrenderowanego pliku. Domyślnie używa ustawienia pluginudefaults.fileFormat.fileQuality("standard" | "hq" | "print"): preset jakości dla renderowania PNG lub PDF.fileScale(number): nadpisanie skali urządzenia (1-4).fileMaxWidth(number): maksymalna szerokość renderowania w pikselach CSS (640-2400).ttlSeconds(number): TTL artefaktu w sekundach dla widoku i samodzielnych wyników plikowych. Domyślnie 1800, maksymalnie 21600.baseUrl(string): nadpisanie źródła URL widoku. Nadpisuje pluginoweviewerBaseUrl. Musi używaćhttplubhttps, bez query/hash.
format->fileFormatimageFormat->fileFormatimageQuality->fileQualityimageScale->fileScaleimageMaxWidth->fileMaxWidth
beforeiaftermają maksymalnie po 512 KiB.patchma maksymalnie 2 MiB.pathma maksymalnie 2048 bajtów.langma maksymalnie 128 bajtów.titlema maksymalnie 1024 bajty.- Limit złożoności patcha: maksymalnie 128 plików i 120000 linii łącznie.
patchorazbeforelubafterrazem są odrzucane.- Limity bezpieczeństwa dla renderowanych plików (dotyczą PNG i PDF):
fileQuality: "standard": maksymalnie 8 MP (8 000 000 wyrenderowanych pikseli).fileQuality: "hq": maksymalnie 14 MP (14 000 000 wyrenderowanych pikseli).fileQuality: "print": maksymalnie 24 MP (24 000 000 wyrenderowanych pikseli).- PDF ma także limit 50 stron.
Kontrakt wyjściowy details
Narzędzie zwraca ustrukturyzowane metadane w details.
Pola współdzielone dla trybów tworzących widok:
artifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext(agentId,sessionId,messageChannel,agentAccountId, gdy dostępne)
artifactIdexpiresAtfilePathpath(ta sama wartość cofilePath, dla zgodności z narzędziem wiadomości)fileBytesfileFormatfileQualityfileScalefileMaxWidth
format(ta sama wartość cofileFormat)imagePath(ta sama wartość cofilePath)imageBytes(ta sama wartość cofileBytes)imageQuality(ta sama wartość cofileQuality)imageScale(ta sama wartość cofileScale)imageMaxWidth(ta sama wartość cofileMaxWidth)
mode: "view": tylko pola widoku.mode: "file": tylko pola pliku, bez artefaktu widoku.mode: "both": pola widoku plus pola pliku. Jeśli renderowanie pliku się nie powiedzie, widok nadal jest zwracany zfileErrori aliasem zgodnościimageError.
Zwinięte niezmienione sekcje
- Widok może pokazywać wiersze takie jak
N unmodified lines. - Kontrolki rozwijania w tych wierszach są warunkowe i nie są gwarantowane dla każdego rodzaju wejścia.
- Kontrolki rozwijania pojawiają się, gdy wyrenderowana różnica zawiera rozwijalne dane kontekstu, co jest typowe dla wejścia before i after.
- Dla wielu wejść ujednoliconego patcha pominięte treści kontekstu nie są dostępne w sparsowanych fragmentach patcha, więc wiersz może pojawić się bez kontrolek rozwijania. To oczekiwane zachowanie.
expandUnchangedma zastosowanie tylko wtedy, gdy istnieje rozwijalny kontekst.
Domyślne ustawienia pluginu
Ustaw domyślne wartości dla całego pluginu w~/.openclaw/openclaw.json:
fontFamilyfontSizelineSpacinglayoutshowLineNumbersdiffIndicatorswordWrapbackgroundthemefileFormatfileQualityfileScalefileMaxWidthmode
viewerBaseUrl(string, opcjonalne)- Własny fallback pluginu dla zwracanych linków widoku, gdy wywołanie narzędzia nie przekazuje
baseUrl. - Musi używać
httplubhttps, bez query/hash.
- Własny fallback pluginu dla zwracanych linków widoku, gdy wywołanie narzędzia nie przekazuje
Konfiguracja bezpieczeństwa
security.allowRemoteViewer(boolean, domyślniefalse)false: żądania spoza loopback do tras widoku są odrzucane.true: zdalne widoki są dozwolone, jeśli ścieżka z tokenem jest prawidłowa.
Cykl życia artefaktów i przechowywanie
- Artefakty są przechowywane w podfolderze katalogu tymczasowego:
$TMPDIR/openclaw-diffs. - Metadane artefaktu widoku zawierają:
- losowy identyfikator artefaktu (20 znaków hex)
- losowy token (48 znaków hex)
createdAtiexpiresAt- zapisaną ścieżkę
viewer.html
- Domyślny TTL artefaktu to 30 minut, jeśli nie został określony.
- Maksymalny akceptowany TTL widoku to 6 godzin.
- Czyszczenie uruchamia się oportunistycznie po utworzeniu artefaktu.
- Wygasłe artefakty są usuwane.
- Zapasowe czyszczenie usuwa nieaktualne foldery starsze niż 24 godziny, gdy brakuje metadanych.
URL widoku i zachowanie sieciowe
Trasa widoku:/plugins/diffs/view/{artifactId}/{token}
/plugins/diffs/assets/viewer.js/plugins/diffs/assets/viewer-runtime.js
baseUrl jest zachowywany również dla żądań tych zasobów.
Zachowanie budowy URL:
- Jeśli podano
baseUrlw wywołaniu narzędzia, jest używane po ścisłej walidacji. - W przeciwnym razie, jeśli skonfigurowano pluginowe
viewerBaseUrl, ono jest używane. - Bez żadnego nadpisania URL widoku domyślnie wskazuje na loopback
127.0.0.1. - Jeśli tryb bindowania gateway to
customi ustawionogateway.customBindHost, używany jest ten host.
baseUrl:
- Musi zaczynać się od
http://lubhttps://. - Query i hash są odrzucane.
- Dozwolone jest źródło plus opcjonalna ścieżka bazowa.
Model bezpieczeństwa
Wzmocnienia widoku:- Domyślnie tylko loopback.
- Ścieżki widoku z tokenem oraz ścisłą walidacją identyfikatora i tokenu.
- CSP odpowiedzi widoku:
default-src 'none'- skrypty i zasoby tylko z self
- brak wychodzącego
connect-src
- Ograniczanie zdalnych nieudanych prób, gdy dostęp zdalny jest włączony:
- 40 niepowodzeń na 60 sekund
- blokada na 60 sekund (
429 Too Many Requests)
- Trasowanie żądań przeglądarki dla zrzutów ekranu domyślnie odrzuca wszystko.
- Dozwolone są tylko lokalne zasoby widoku z
http://127.0.0.1/plugins/diffs/assets/*. - Zewnętrzne żądania sieciowe są blokowane.
Wymagania przeglądarki dla trybu plikowego
mode: "file" i mode: "both" wymagają przeglądarki zgodnej z Chromium.
Kolejność rozstrzygania:
browser.executablePathw konfiguracji OpenClaw.- Zmienne środowiskowe:
OPENCLAW_BROWSER_EXECUTABLE_PATHBROWSER_EXECUTABLE_PATHPLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
- Zapasowe wykrywanie poleceń/ścieżek na platformie.
Diff PNG/PDF rendering requires a Chromium-compatible browser...
Rozwiązywanie problemów
Błędy walidacji danych wejściowych:Provide patch or both before and after text.- Dołącz oba pola
beforeiafteralbo podajpatch.
- Dołącz oba pola
Provide either patch or before/after input, not both.- Nie mieszaj trybów wejścia.
Invalid baseUrl: ...- Użyj źródła
http(s)z opcjonalną ścieżką, bez query/hash.
- Użyj źródła
{field} exceeds maximum size (...)- Zmniejsz rozmiar ładunku.
- Odrzucenie dużego patcha
- Zmniejsz liczbę plików w patchu lub łączną liczbę linii.
- URL widoku domyślnie wskazuje na
127.0.0.1. - W scenariuszach dostępu zdalnego:
- ustaw pluginowe
viewerBaseUrl, albo - przekaż
baseUrldla danego wywołania narzędzia, albo - użyj
gateway.bind=customigateway.customBindHost
- ustaw pluginowe
- Jeśli
gateway.trustedProxieszawiera loopback dla proxy działającego na tym samym hoście (na przykład Tailscale Serve), surowe żądania widoku loopback bez nagłówków przekazanego IP klienta są zgodnie z projektem bezpiecznie odrzucane. - Dla tej topologii proxy:
- preferuj
mode: "file"lubmode: "both", gdy potrzebujesz tylko załącznika, albo - świadomie włącz
security.allowRemoteVieweri ustaw pluginoweviewerBaseUrllub przekaż proxy/publicznebaseUrl, gdy potrzebujesz współdzielonego URL widoku
- preferuj
- Włączaj
security.allowRemoteViewertylko wtedy, gdy zamierzasz umożliwić zewnętrzny dostęp do widoku.
- Może się to zdarzyć dla wejścia patch, gdy patch nie zawiera rozwijalnego kontekstu.
- To oczekiwane i nie oznacza błędu widoku.
- Artefakt wygasł z powodu TTL.
- Token lub ścieżka zostały zmienione.
- Czyszczenie usunęło nieaktualne dane.
Wskazówki operacyjne
- Preferuj
mode: "view"dla lokalnych interaktywnych przeglądów w Canvas. - Preferuj
mode: "file"dla wychodzących kanałów czatu, które wymagają załącznika. - Pozostaw
allowRemoteViewerwyłączone, chyba że wdrożenie wymaga zdalnych URL-i widoku. - Ustaw jawne krótkie
ttlSecondsdla wrażliwych różnic. - Unikaj wysyłania sekretów w danych wejściowych różnic, jeśli nie jest to konieczne.
- Jeśli kanał agresywnie kompresuje obrazy (na przykład Telegram lub WhatsApp), preferuj wynik PDF (
fileFormat: "pdf").
- Napędzany przez Diffs.