Diff
diffs è uno strumento plugin opzionale con una breve guida di sistema integrata e una skill complementare che trasforma il contenuto delle modifiche in un artefatto diff in sola lettura per gli agenti.
Accetta uno dei seguenti input:
- testo
beforeeafter - una
patchunificata
- un URL del visualizzatore del gateway per la presentazione in canvas
- un percorso file renderizzato (PNG o PDF) per la consegna nei messaggi
- entrambi gli output in una sola chiamata
Avvio rapido
- Abilita il plugin.
- Chiama
diffsconmode: "view"per flussi incentrati prima di tutto sul canvas. - Chiama
diffsconmode: "file"per flussi di consegna file in chat. - Chiama
diffsconmode: "both"quando ti servono entrambi gli artefatti.
Abilitare il plugin
Disabilitare la guida di sistema integrata
Se vuoi mantenere abilitato lo strumentodiffs ma disabilitare la sua guida integrata nel prompt di sistema, imposta plugins.entries.diffs.hooks.allowPromptInjection su false:
before_prompt_build del plugin diffs mantenendo disponibili il plugin, lo strumento e la skill complementare.
Se vuoi disabilitare sia la guida sia lo strumento, disabilita invece il plugin.
Flusso di lavoro tipico dell’agente
- L’agente chiama
diffs. - L’agente legge i campi
details. - L’agente quindi:
- apre
details.viewerUrlconcanvas present - invia
details.filePathconmessageusandopathofilePath - fa entrambe le cose
- apre
Esempi di input
Before e after:Riferimento dell’input dello strumento
Tutti i campi sono facoltativi salvo diversa indicazione:before(string): testo originale. Obbligatorio conafterquandopatchè omesso.after(string): testo aggiornato. Obbligatorio conbeforequandopatchè omesso.patch(string): testo diff unificato. Mutuamente esclusivo conbeforeeafter.path(string): nome file visualizzato per la modalità before e after.lang(string): suggerimento di override della lingua per la modalità before e after. I valori sconosciuti ricadono su testo semplice.title(string): override del titolo del visualizzatore.mode("view" | "file" | "both"): modalità di output. Il valore predefinito è quello del plugindefaults.mode. Alias deprecato:"image"si comporta come"file"ed è ancora accettato per retrocompatibilità.theme("light" | "dark"): tema del visualizzatore. Il valore predefinito è quello del plugindefaults.theme.layout("unified" | "split"): layout del diff. Il valore predefinito è quello del plugindefaults.layout.expandUnchanged(boolean): espande le sezioni non modificate quando è disponibile il contesto completo. Opzione solo per chiamata singola (non è una chiave predefinita del plugin).fileFormat("png" | "pdf"): formato del file renderizzato. Il valore predefinito è quello del plugindefaults.fileFormat.fileQuality("standard" | "hq" | "print"): preset di qualità per il rendering PNG o PDF.fileScale(number): override della scala del dispositivo (1-4).fileMaxWidth(number): larghezza massima di rendering in pixel CSS (640-2400).ttlSeconds(number): TTL dell’artefatto in secondi per visualizzatore e output file standalone. Predefinito 1800, massimo 21600.baseUrl(string): override dell’origine URL del visualizzatore. Sostituisce il pluginviewerBaseUrl. Deve esserehttpohttps, senza query/hash.
format->fileFormatimageFormat->fileFormatimageQuality->fileQualityimageScale->fileScaleimageMaxWidth->fileMaxWidth
beforeeaftermassimo 512 KiB ciascuno.patchmassimo 2 MiB.pathmassimo 2048 byte.langmassimo 128 byte.titlemassimo 1024 byte.- Limite di complessità della patch: massimo 128 file e 120000 righe totali.
patchinsieme abeforeoafterviene rifiutato.- Limiti di sicurezza per i file renderizzati (si applicano a PNG e PDF):
fileQuality: "standard": massimo 8 MP (8.000.000 pixel renderizzati).fileQuality: "hq": massimo 14 MP (14.000.000 pixel renderizzati).fileQuality: "print": massimo 24 MP (24.000.000 pixel renderizzati).- Il PDF ha inoltre un massimo di 50 pagine.
Contratto dei dettagli di output
Lo strumento restituisce metadati strutturati sottodetails.
Campi condivisi per le modalità che creano un visualizzatore:
artifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext(agentId,sessionId,messageChannel,agentAccountIdquando disponibili)
artifactIdexpiresAtfilePathpath(stesso valore difilePath, per compatibilità con lo strumento message)fileBytesfileFormatfileQualityfileScalefileMaxWidth
format(stesso valore difileFormat)imagePath(stesso valore difilePath)imageBytes(stesso valore difileBytes)imageQuality(stesso valore difileQuality)imageScale(stesso valore difileScale)imageMaxWidth(stesso valore difileMaxWidth)
mode: "view": solo campi del visualizzatore.mode: "file": solo campi file, nessun artefatto del visualizzatore.mode: "both": campi del visualizzatore più campi file. Se il rendering del file fallisce, il visualizzatore viene comunque restituito confileErrore l’alias di compatibilitàimageError.
Sezioni non modificate compresse
- Il visualizzatore può mostrare righe come
N unmodified lines. - I controlli di espansione su quelle righe sono condizionali e non garantiti per ogni tipo di input.
- I controlli di espansione compaiono quando il diff renderizzato ha dati di contesto espandibili, cosa tipica dell’input before e after.
- Per molti input patch unificati, i corpi del contesto omesso non sono disponibili negli hunk della patch analizzata, quindi la riga può apparire senza controlli di espansione. Questo è un comportamento previsto.
expandUnchangedsi applica solo quando esiste un contesto espandibile.
Valori predefiniti del plugin
Imposta i valori predefiniti a livello plugin in~/.openclaw/openclaw.json:
fontFamilyfontSizelineSpacinglayoutshowLineNumbersdiffIndicatorswordWrapbackgroundthemefileFormatfileQualityfileScalefileMaxWidthmode
viewerBaseUrl(string, facoltativo)- Fallback di proprietà del plugin per i link del visualizzatore restituiti quando una chiamata dello strumento non passa
baseUrl. - Deve essere
httpohttps, senza query/hash.
- Fallback di proprietà del plugin per i link del visualizzatore restituiti quando una chiamata dello strumento non passa
Configurazione della sicurezza
security.allowRemoteViewer(boolean, predefinitofalse)false: le richieste non loopback alle route del visualizzatore vengono negate.true: i visualizzatori remoti sono consentiti se il percorso con token è valido.
Ciclo di vita e archiviazione degli artefatti
- Gli artefatti vengono archiviati nella sottocartella temporanea:
$TMPDIR/openclaw-diffs. - I metadati dell’artefatto del visualizzatore contengono:
- ID artefatto casuale (20 caratteri esadecimali)
- token casuale (48 caratteri esadecimali)
createdAteexpiresAt- percorso
viewer.htmlarchiviato
- Il TTL predefinito dell’artefatto è 30 minuti quando non specificato.
- Il TTL massimo accettato per il visualizzatore è 6 ore.
- La pulizia viene eseguita in modo opportunistico dopo la creazione dell’artefatto.
- Gli artefatti scaduti vengono eliminati.
- La pulizia di fallback rimuove le cartelle obsolete più vecchie di 24 ore quando mancano i metadati.
URL del visualizzatore e comportamento di rete
Route del visualizzatore:/plugins/diffs/view/{artifactId}/{token}
/plugins/diffs/assets/viewer.js/plugins/diffs/assets/viewer-runtime.js
baseUrl facoltativo viene preservato anche per entrambe le richieste delle risorse.
Comportamento di costruzione dell’URL:
- Se viene fornito
baseUrlnella chiamata dello strumento, viene usato dopo una rigorosa convalida. - Altrimenti, se è configurato il plugin
viewerBaseUrl, viene usato quello. - Senza nessuno dei due override, l’URL del visualizzatore usa per impostazione predefinita loopback
127.0.0.1. - Se la modalità di bind del gateway è
customegateway.customBindHostè impostato, viene usato quell’host.
baseUrl:
- Deve essere
http://ohttps://. - Query e hash vengono rifiutati.
- Sono consentiti l’origine più un percorso base facoltativo.
Modello di sicurezza
Rinforzo del visualizzatore:- Solo loopback per impostazione predefinita.
- Percorsi del visualizzatore con token e convalida rigorosa di ID e token.
- CSP della risposta del visualizzatore:
default-src 'none'- script e risorse solo da self
- nessun
connect-srcin uscita
- Limitazione delle mancate corrispondenze remote quando l’accesso remoto è abilitato:
- 40 errori in 60 secondi
- blocco di 60 secondi (
429 Too Many Requests)
- L’instradamento delle richieste del browser per screenshot è deny-by-default.
- Sono consentite solo risorse locali del visualizzatore da
http://127.0.0.1/plugins/diffs/assets/*. - Le richieste di rete esterne sono bloccate.
Requisiti del browser per la modalità file
mode: "file" e mode: "both" richiedono un browser compatibile con Chromium.
Ordine di risoluzione:
browser.executablePathnella configurazione di OpenClaw.- Variabili d’ambiente:
OPENCLAW_BROWSER_EXECUTABLE_PATHBROWSER_EXECUTABLE_PATHPLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
- Fallback di rilevamento del comando/percorso della piattaforma.
Diff PNG/PDF rendering requires a Chromium-compatible browser...
Risoluzione dei problemi
Errori di convalida dell’input:Provide patch or both before and after text.- Includi sia
beforesiaafter, oppure forniscipatch.
- Includi sia
Provide either patch or before/after input, not both.- Non mescolare le modalità di input.
Invalid baseUrl: ...- Usa un’origine
http(s)con percorso facoltativo, senza query/hash.
- Usa un’origine
{field} exceeds maximum size (...)- Riduci la dimensione del payload.
- Rifiuto di patch troppo grande
- Riduci il numero di file della patch o il totale delle righe.
- L’URL del visualizzatore usa per impostazione predefinita
127.0.0.1. - Per scenari di accesso remoto, puoi:
- impostare il plugin
viewerBaseUrl, oppure - passare
baseUrlper singola chiamata dello strumento, oppure - usare
gateway.bind=customegateway.customBindHost
- impostare il plugin
- Se
gateway.trustedProxiesinclude loopback per un proxy sullo stesso host (per esempio Tailscale Serve), le richieste raw loopback al visualizzatore senza header IP client inoltrati vengono chiuse in modo sicuro per progettazione. - Per questa topologia proxy:
- preferisci
mode: "file"omode: "both"quando ti serve solo un allegato, oppure - abilita intenzionalmente
security.allowRemoteViewere imposta il pluginviewerBaseUrlo passa unbaseUrlproxy/pubblico quando ti serve un URL del visualizzatore condivisibile
- preferisci
- Abilita
security.allowRemoteViewersolo quando intendi consentire l’accesso esterno al visualizzatore.
- Questo può accadere per input patch quando la patch non include contesto espandibile.
- È un comportamento previsto e non indica un errore del visualizzatore.
- L’artefatto è scaduto a causa del TTL.
- Il token o il percorso sono cambiati.
- La pulizia ha rimosso dati obsoleti.
Linee guida operative
- Preferisci
mode: "view"per revisioni interattive locali in canvas. - Preferisci
mode: "file"per canali di chat in uscita che richiedono un allegato. - Mantieni
allowRemoteViewerdisabilitato a meno che la tua distribuzione non richieda URL di visualizzatore remoti. - Imposta un
ttlSecondsbreve ed esplicito per diff sensibili. - Evita di inviare segreti nell’input diff quando non necessario.
- Se il tuo canale comprime aggressivamente le immagini (per esempio Telegram o WhatsApp), preferisci l’output PDF (
fileFormat: "pdf").
- Basato su Diffs.