Tools
ส่วนต่าง
diffs เป็นเครื่องมือ Plugin แบบบันเดิลที่เลือกใช้ได้ ซึ่งแปลงข้อความก่อน/หลังหรือแพตช์แบบ unified ให้เป็นอาร์ติแฟกต์ diff แบบอ่านอย่างเดียว นอกจากนี้ยังเพิ่มคำแนะนำสั้นๆ สำหรับเอเจนต์ไว้ด้านหน้าของพรอมต์ระบบ และมาพร้อม Skills คู่กันสำหรับคำแนะนำที่ครบถ้วนยิ่งขึ้น
อินพุต: ข้อความ before + after หรือ patch แบบ unified (ใช้ร่วมกันไม่ได้)
เอาต์พุต: URL ตัวดูของ Gateway สำหรับนำเสนอบนแคนวาส, พาธไฟล์ PNG/PDF ที่เรนเดอร์แล้วสำหรับส่งข้อความ หรือทั้งสองอย่าง
เริ่มต้นอย่างรวดเร็ว
ติดตั้ง Plugin
openclaw plugins install diffsเปิดใช้ Plugin
{ plugins: { entries: { diffs: { enabled: true, }, }, },}เลือกโหมด
view
โฟลว์ที่ให้ความสำคัญกับแคนวาส: เอเจนต์เรียก diffs พร้อม mode: "view" และเปิด details.viewerUrl ด้วย canvas present
file
การส่งไฟล์ผ่านแชต: เอเจนต์เรียก diffs พร้อม mode: "file" และส่ง details.filePath พร้อม message โดยใช้ path หรือ filePath
both
แบบรวม (ค่าเริ่มต้น): เอเจนต์เรียก diffs พร้อม mode: "both" เพื่อรับอาร์ติแฟกต์ทั้งสองรายการในการเรียกครั้งเดียว
ปิดคำแนะนำระบบในตัว
หากต้องการเก็บเครื่องมือไว้แต่ไม่เพิ่มคำแนะนำไว้ด้านหน้าพรอมต์ระบบ ให้ตั้ง plugins.entries.diffs.hooks.allowPromptInjection เป็น false:
{ plugins: { entries: { diffs: { enabled: true, hooks: { allowPromptInjection: false, }, }, }, },}การตั้งค่านี้จะบล็อกฮุก before_prompt_build ของ Plugin ขณะที่ยังคงใช้งานเครื่องมือและ Skills ได้ หากต้องการปิดทั้งคำแนะนำและเครื่องมือ ให้ปิด Plugin แทน
ข้อมูลอ้างอิงอินพุตของเครื่องมือ
ทุกฟิลด์เป็นตัวเลือก เว้นแต่จะระบุไว้เป็นอย่างอื่น
beforestringข้อความต้นฉบับ จำเป็นต้องใช้ร่วมกับ after เมื่อไม่ได้ระบุ patch
afterstringข้อความที่อัปเดตแล้ว จำเป็นต้องใช้ร่วมกับ before เมื่อไม่ได้ระบุ patch
patchstringข้อความ diff แบบ unified ใช้ร่วมกับ before และ after ไม่ได้
pathstringชื่อไฟล์ที่แสดงสำหรับโหมดก่อน/หลัง
langstringคำใบ้สำหรับแทนที่ภาษาของโหมดก่อน/หลัง ค่าที่ไม่รู้จักและภาษาที่อยู่นอกชุดเริ่มต้นของตัวดูจะใช้ข้อความธรรมดาแทน เว้นแต่จะติดตั้ง Plugin Diff Viewer Language Pack
titlestringค่าที่ใช้แทนชื่อเรื่องของตัวดู
mode"view" | "file" | "both"โหมดเอาต์พุต ค่าเริ่มต้นคือค่าเริ่มต้นของ Plugin defaults.mode (both) นามแฝงที่เลิกใช้แล้ว: "image" ทำงานเหมือนกับ "file"
theme"light" | "dark"ธีมของตัวดู ค่าเริ่มต้นคือค่าเริ่มต้นของ Plugin defaults.theme
layout"unified" | "split"เลย์เอาต์ diff ค่าเริ่มต้นคือค่าเริ่มต้นของ Plugin defaults.layout
expandUnchangedbooleanขยายส่วนที่ไม่เปลี่ยนแปลงเมื่อมีบริบทแบบเต็ม เป็นตัวเลือกเฉพาะการเรียกแต่ละครั้งเท่านั้น (ไม่ใช่คีย์ค่าเริ่มต้นของ Plugin)
fileFormat"png" | "pdf"รูปแบบไฟล์ที่เรนเดอร์แล้ว ค่าเริ่มต้นคือค่าเริ่มต้นของ Plugin defaults.fileFormat
fileQuality"standard" | "hq" | "print"ค่าคุณภาพสำเร็จรูปสำหรับการเรนเดอร์ PNG/PDF
fileScalenumberค่าที่ใช้แทนสเกลอุปกรณ์ (1-4)
fileMaxWidthnumberความกว้างสูงสุดของการเรนเดอร์ในหน่วยพิกเซล CSS (640-2400)
ttlSecondsnumberdefault: 1800TTL ของอาร์ติแฟกต์ในหน่วยวินาทีสำหรับตัวดูและเอาต์พุตไฟล์แบบสแตนด์อโลน สูงสุด 21600
baseUrlstringค่าที่ใช้แทนต้นทาง URL ของตัวดู โดยแทนที่ viewerBaseUrl ของ Plugin ต้องเป็น http หรือ https และไม่มีคิวรี/แฮช
การตรวจสอบและขีดจำกัด
before/after: สูงสุดรายการละ 512 KiBpatch: สูงสุด 2 MiBpath: สูงสุด 2048 ไบต์lang: สูงสุด 128 ไบต์title: สูงสุด 1024 ไบต์- ขีดจำกัดความซับซ้อนของแพตช์: สูงสุด 128 ไฟล์และรวม 120000 บรรทัด
- ระบบจะปฏิเสธ
patchที่ใช้ร่วมกับbefore/after - ขีดจำกัดความปลอดภัยของไฟล์ที่เรนเดอร์แล้ว (PNG และ PDF):
fileQuality: "standard": สูงสุด 8 MP (8,000,000 พิกเซลที่เรนเดอร์)fileQuality: "hq": สูงสุด 14 MPfileQuality: "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 เป็นต้น) จะถูกทำให้เป็นมาตรฐานตามภาษาเหล่านั้น
ติดตั้ง Plugin 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หากไม่มีแพ็ก ภาษาที่ไม่รองรับจะยังคงเรนเดอร์เป็นข้อความธรรมดาที่อ่านได้ ดูแค็ตตาล็อกจากต้นทางได้ที่ Plugin Diffs Language Pack และ ภาษาของ Shiki
สัญญารายละเอียดเอาต์พุต
ผลลัพธ์ที่สำเร็จทั้งหมดมี changed: อินพุตก่อน/หลังที่เหมือนกันจะคืนค่า false โดยไม่สร้างอาร์ติแฟกต์ ส่วนผลลัพธ์ที่เรนเดอร์แล้วจะคืนค่า true
ฟิลด์ตัวดู (โหมด view และ both)
changedartifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext(agentId,sessionId,messageChannel,agentAccountIdเมื่อมี)
ฟิลด์ไฟล์ (โหมด file และ both)
changedartifactIdexpiresAtfilePathpath(ค่าเดียวกับfilePathเพื่อให้เข้ากันได้กับเครื่องมือส่งข้อความ)fileBytesfileFormatfileQualityfileScalefileMaxWidth
| โหมด | ส่งคืน |
|---|---|
"view" |
เฉพาะฟิลด์ตัวดู |
"file" |
เฉพาะฟิลด์ไฟล์ ไม่มีอาร์ติแฟกต์ตัวดู |
"both" |
ฟิลด์ตัวดูพร้อมฟิลด์ไฟล์ หากการเรนเดอร์ไฟล์ล้มเหลว ตัวดูจะยังคงส่งคืนพร้อม fileError |
ส่วนที่ไม่เปลี่ยนแปลงซึ่งถูกยุบ
ตัวดูแสดงแถวในลักษณะ N unmodified lines ตัวควบคุมการขยายจะปรากฏเฉพาะเมื่อ diff ที่เรนเดอร์มีข้อมูลบริบทที่ขยายได้ (โดยทั่วไปสำหรับอินพุตก่อน/หลัง) แพตช์แบบ unified จำนวนมากละเว้นเนื้อหาบริบทภายในฮังก์ ดังนั้นแถวอาจปรากฏโดยไม่มีตัวควบคุมการขยาย ซึ่งเป็นพฤติกรรมที่คาดไว้ ไม่ใช่บั๊ก expandUnchanged ใช้ได้เฉพาะเมื่อมีบริบทที่ขยายได้
การนำทางแบบหลายไฟล์
แพตช์ที่แก้ไขมากกว่าหนึ่งไฟล์จะเริ่มด้วยการ์ดสรุปไฟล์ที่เปลี่ยนแปลง: จำนวนรวม +N / -N, จำนวนต่อไฟล์, ป้ายเพิ่ม/ลบ/เปลี่ยนชื่อ และลิงก์แองเคอร์ที่ข้ามไปยังแต่ละไฟล์ ไฟล์ PNG/PDF ที่เรนเดอร์แล้วจะคงจำนวนในส่วนหัวต่อไฟล์ไว้ แต่ตัดตัวสลับมุมมองแบบโต้ตอบออก เนื่องจากตัวควบคุมเหล่านั้นใช้งานไม่ได้ในไฟล์แบบคงที่
ค่าเริ่มต้นของ 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, }, }, }, }, },}คีย์ defaults ที่รองรับ: fontFamily, fontSize, lineSpacing, layout, showLineNumbers, diffIndicators, wordWrap, background, theme, fileFormat, fileQuality, fileScale, fileMaxWidth, mode, ttlSeconds พารามิเตอร์ที่ระบุอย่างชัดเจนในการเรียกเครื่องมือจะแทนที่ค่าเหล่านี้
การกำหนดค่า URL ตัวดูแบบถาวร
viewerBaseUrlstringค่าสำรองที่ Plugin เป็นเจ้าของสำหรับลิงก์ตัวดูที่ส่งคืน เมื่อการเรียกเครื่องมือไม่ได้ส่ง baseUrl ต้องเป็น http หรือ https และไม่มีคิวรี/แฮช
{ plugins: { entries: { diffs: { enabled: true, config: { viewerBaseUrl: "https://gateway.example.com/openclaw", }, }, }, },}การกำหนดค่าความปลอดภัย
security.allowRemoteViewerbooleandefault: falsefalse: คำขอไปยังเส้นทางตัวดูที่ไม่ได้มาจากลูปแบ็กจะถูกปฏิเสธ true: อนุญาตตัวดูระยะไกลหากพาธที่มีโทเค็นถูกต้อง
{ plugins: { entries: { diffs: { enabled: true, config: { security: { allowRemoteViewer: false, }, }, }, }, },}วงจรชีวิตและพื้นที่จัดเก็บอาร์ติแฟกต์
- HTML และข้อมูลเมตาของ Viewer อยู่ในฐานข้อมูล
state/openclaw.sqliteที่ใช้ร่วมกันภายใต้เนมสเปซ Blob ของ Plugin Diffs โดย HTML จะถูกบีบอัดด้วย gzip ส่วน SQLite จะจัดเก็บเฉพาะแฮช SHA-256 ของโทเค็น URL แบบสุ่ม ไม่ได้จัดเก็บตัวโทเค็นเอง - ไฟล์ PNG/PDF ที่เรนเดอร์แล้วยังคงเป็นไฟล์ชั่วคราวภายใต้
$TMPDIR/openclaw-diffsเนื่องจากการส่งผ่านช่องทางต้องใช้พาธไฟล์ SQLite เป็นผู้จัดการข้อมูลเมตาการหมดอายุของไฟล์เหล่านี้ และไม่มีการเขียนไฟล์ JSON ประกอบ - TTL เริ่มต้นของอาร์ติแฟกต์: 30 นาที TTL สูงสุดที่ยอมรับ: 6 ชั่วโมง
- การล้างข้อมูลจะทำงานตามโอกาสหลังการเรียกสร้างอาร์ติแฟกต์แต่ละครั้ง โดยลบแถว SQLite ที่หมดอายุก่อน แล้วจึงลบไดเรกทอรี PNG/PDF ที่เกี่ยวข้อง
- การกวาดข้อมูลสำรองจะลบโฟลเดอร์ชั่วคราวที่ไม่มีแถวข้อมูลและมีอายุเกิน 24 ชั่วโมง โดยจะไม่นำเข้าหรืออ่านแคชเดิม
meta.json,file-meta.jsonและviewer.html
URL ของ Viewer และลักษณะการทำงานของเครือข่าย
เส้นทาง Viewer: /plugins/diffs/view/{artifactId}/{token}
แอสเซ็ตของ Viewer:
/plugins/diffs/assets/viewer.js/plugins/diffs/assets/viewer-runtime.js/plugins/diffs-language-pack/assets/viewer.js(เฉพาะเมื่อ diff ใช้ภาษาของชุดภาษา)
เอกสาร Viewer จะอ้างอิงแอสเซ็ตเหล่านี้โดยสัมพันธ์กับ URL ของ Viewer ดังนั้นคำนำหน้าพาธ baseUrl ซึ่งเป็นตัวเลือกจะถูกใช้กับคำขอแอสเซ็ตด้วย
ลำดับการแก้ไข URL: baseUrl จากการเรียกเครื่องมือ (หลังผ่านการตรวจสอบอย่างเข้มงวด) -> viewerBaseUrl ของ Plugin -> ค่าเริ่มต้นแบบลูปแบ็ก 127.0.0.1 หากโหมดการผูก Gateway เป็น custom และมีการตั้งค่า gateway.customBindHost ระบบจะใช้โฮสต์นั้นแทนลูปแบ็ก
กฎของ baseUrl: ต้องเป็น http:// หรือ https://; ระบบจะปฏิเสธคิวรีและแฮช; อนุญาตให้ใช้ต้นทางพร้อมพาธฐานซึ่งเป็นตัวเลือก
โมเดลความปลอดภัย
การเสริมความปลอดภัยของ Viewer
- ค่าเริ่มต้นอนุญาตเฉพาะลูปแบ็ก
- พาธ Viewer ที่ใช้โทเค็น พร้อมการตรวจสอบรูปแบบ ID และโทเค็นอย่างเข้มงวด
- CSP ของการตอบกลับ Viewer:
default-src 'none'; สคริปต์/แอสเซ็ตมาจากต้นทางเดียวกันเท่านั้น; ไม่มีconnect-srcขาออก - การจำกัดคำขอเมื่อค้นหาจากระยะไกลไม่พบและเปิดใช้การเข้าถึงจากระยะไกล: ความล้มเหลว 40 ครั้งภายใน 60 วินาทีจะทำให้ถูกล็อกเป็นเวลา 60 วินาที (
429 Too Many Requests)
การเสริมความปลอดภัยของการเรนเดอร์ไฟล์
- การกำหนดเส้นทางคำขอของเบราว์เซอร์สำหรับจับภาพหน้าจอจะปฏิเสธโดยค่าเริ่มต้น
- อนุญาตเฉพาะแอสเซ็ต Viewer ภายในเครื่องจาก
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
ทางเลือกสำรองของแพลตฟอร์ม
พาธการติดตั้งทั่วไปและการค้นหา PATH สำหรับ Chrome, Chromium, Edge และ Brave
ข้อความแสดงความล้มเหลวทั่วไป: Diff PNG/PDF rendering requires a Chromium-compatible browser... แก้ไขโดยติดตั้ง Chrome, Chromium, Edge หรือ Brave หรือตั้งค่าตัวเลือกพาธไฟล์ปฏิบัติการรายการใดรายการหนึ่งข้างต้น
การแก้ไขปัญหา
ข้อผิดพลาดในการตรวจสอบอินพุต
Provide patch or both before and after text.-- ระบุทั้งbeforeและafterหรือระบุpatchProvide either patch or before/after input, not both.-- ห้ามใช้โหมดอินพุตร่วมกันInvalid baseUrl: ...-- ใช้ต้นทางhttp(s)พร้อมพาธซึ่งเป็นตัวเลือก โดยไม่มีคิวรี/แฮช{field} exceeds maximum size (...)-- ลดขนาดเพย์โหลด- การปฏิเสธแพตช์ขนาดใหญ่ -- ลดจำนวนไฟล์แพตช์หรือจำนวนบรรทัดทั้งหมด
การเข้าถึง Viewer
- URL ของ Viewer จะอ้างอิงเป็น
127.0.0.1โดยค่าเริ่มต้น - สำหรับการเข้าถึงจากระยะไกล ให้ตั้งค่า
viewerBaseUrlของ Plugin, ส่งbaseUrlในแต่ละครั้งที่เรียก หรือใช้gateway.bind=customร่วมกับgateway.customBindHost - หาก
gateway.trustedProxiesมีลูปแบ็กสำหรับพร็อกซีบนโฮสต์เดียวกัน (เช่น Tailscale Serve) คำขอ Viewer แบบลูปแบ็กโดยตรงที่ไม่มีส่วนหัว IP ของไคลเอ็นต์ซึ่งพร็อกซีส่งต่อมาจะถูกปฏิเสธโดยค่าเริ่มต้นตามการออกแบบ - สำหรับโทโพโลยีพร็อกซีนี้ ควรใช้
mode: "file"/"both"สำหรับไฟล์แนบ หรือเปิดใช้security.allowRemoteViewerพร้อมviewerBaseUrlของ Plugin/พร็อกซีbaseUrlโดยเจตนา เพื่อสร้างลิงก์ Viewer ที่แชร์ได้ - เปิดใช้
security.allowRemoteViewerเฉพาะเมื่อต้องการให้เข้าถึง Viewer จากภายนอก
แถวบรรทัดที่ไม่มีการแก้ไขไม่มีปุ่มขยาย
เป็นลักษณะที่คาดไว้สำหรับอินพุตแพตช์ที่ไม่มีบริบทซึ่งขยายได้ ไม่ใช่ความล้มเหลวของ Viewer
ไม่พบอาร์ติแฟกต์
- อาร์ติแฟกต์หมดอายุเนื่องจาก TTL
- โทเค็นหรือพาธมีการเปลี่ยนแปลง
- การล้างข้อมูลได้ลบข้อมูลที่ล้าสมัยแล้ว
แนวทางการดำเนินงาน
- ควรใช้
mode: "view"สำหรับการรีวิวแบบโต้ตอบภายในเครื่องบนแคนวาส - ควรใช้
mode: "file"สำหรับช่องทางแชตขาออกที่ต้องใช้ไฟล์แนบ - ปิดใช้
allowRemoteViewerไว้ เว้นแต่การนำไปใช้งานของคุณจำเป็นต้องใช้ URL ของ Viewer จากระยะไกล - ตั้งค่า
ttlSecondsแบบสั้นอย่างชัดเจนสำหรับ diff ที่มีข้อมูลละเอียดอ่อน - หลีกเลี่ยงการส่งข้อมูลลับในอินพุต diff เมื่อไม่จำเป็น
- หากช่องทางของคุณบีบอัดรูปภาพอย่างมาก (เช่น Telegram หรือ WhatsApp) ควรใช้เอาต์พุต PDF (
fileFormat: "pdf")