---
read_when:
    - คุณกำลังสร้าง Plugin สำหรับ OpenClaw
    - คุณต้องเผยแพร่สคีมาการกำหนดค่าของ Plugin หรือแก้ไขข้อผิดพลาดในการตรวจสอบความถูกต้องของ Plugin
summary: ข้อกำหนดของไฟล์ manifest ของ Plugin และ JSON schema (การตรวจสอบความถูกต้องของการกำหนดค่าอย่างเคร่งครัด)
title: ไฟล์กำกับ Plugin
x-i18n:
    generated_at: "2026-07-12T16:29:31Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    provider: openai
    source_hash: cd4ab5b10108585abb9a83a416b129e6f6351023016064b5d64b66aeabd04b2f
    source_path: plugins/manifest.md
    workflow: 16
---

หน้านี้กล่าวถึง **ไฟล์แมนิเฟสต์ Plugin แบบเนทีฟของ OpenClaw** คือ `openclaw.plugin.json` สำหรับโครงสร้างบันเดิลที่เข้ากันได้ (Codex, Claude, Cursor) โปรดดู [บันเดิล Plugin](/th/plugins/bundles)

รูปแบบบันเดิลที่เข้ากันได้จะใช้ไฟล์แมนิเฟสต์ของตนเองแทน:

- บันเดิล Codex: `.codex-plugin/plugin.json`
- บันเดิล Claude: `.claude-plugin/plugin.json` หรือโครงสร้างคอมโพเนนต์เริ่มต้นของ Claude ที่ไม่มีไฟล์แมนิเฟสต์
- บันเดิล Cursor: `.cursor-plugin/plugin.json`

OpenClaw ตรวจหาโครงสร้างเหล่านั้นโดยอัตโนมัติ แต่จะไม่ตรวจสอบความถูกต้องเทียบกับสคีมา `openclaw.plugin.json` ด้านล่าง สำหรับบันเดิลที่เข้ากันได้ OpenClaw จะอ่านเมทาดาทาของบันเดิล รูทของ Skills ที่ประกาศไว้ รูทคำสั่งของ Claude ค่าเริ่มต้นใน `settings.json` ของ Claude ค่าเริ่มต้น LSP ของ Claude และชุดฮุกที่รองรับ เมื่อโครงสร้างตรงตามข้อกำหนดรันไทม์ของ OpenClaw

Plugin แบบเนทีฟของ OpenClaw ทุกตัว **ต้อง** มี `openclaw.plugin.json` อยู่ใน **รูทของ Plugin** OpenClaw อ่านไฟล์นี้เพื่อตรวจสอบความถูกต้องของการกำหนดค่า **โดยไม่เรียกใช้โค้ดของ Plugin** หากไฟล์แมนิเฟสต์หายไปหรือไม่ถูกต้อง การตรวจสอบความถูกต้องของการกำหนดค่าจะถูกระงับ และถือว่าเป็นข้อผิดพลาดของ Plugin

โปรดดู [Plugin](/th/tools/plugin) สำหรับคู่มือระบบ Plugin ฉบับเต็ม และ [โมเดลความสามารถ](/th/plugins/architecture#public-capability-model) สำหรับโมเดลความสามารถแบบเนทีฟและแนวทางความเข้ากันได้ภายนอกในปัจจุบัน

## ไฟล์นี้ทำหน้าที่อะไร

`openclaw.plugin.json` คือเมทาดาทาที่ OpenClaw อ่าน **ก่อนโหลดโค้ด Plugin ของคุณ** ทุกอย่างในไฟล์นี้ต้องตรวจสอบได้โดยใช้ทรัพยากรน้อยเพียงพอ โดยไม่ต้องเริ่มรันไทม์ของ Plugin

**ใช้ไฟล์นี้สำหรับ:**

- ข้อมูลประจำตัวของ Plugin การตรวจสอบความถูกต้องของการกำหนดค่า และคำแนะนำสำหรับ UI การกำหนดค่า
- เมทาดาทาสำหรับการยืนยันตัวตน การเริ่มต้นใช้งาน และการตั้งค่า (ชื่อแทน การเปิดใช้งานอัตโนมัติ ตัวแปรสภาพแวดล้อมของผู้ให้บริการ และตัวเลือกการยืนยันตัวตน)
- คำแนะนำการเปิดใช้งานสำหรับพื้นผิวของระนาบควบคุม
- การกำหนดความเป็นเจ้าของตระกูลโมเดลแบบย่อ
- สแนปช็อตความเป็นเจ้าของความสามารถแบบคงที่ (`contracts`)
- เมทาดาทาของตัวรัน QA ที่โฮสต์ `openclaw qa` ส่วนกลางสามารถตรวจสอบได้
- เมทาดาทาการกำหนดค่าเฉพาะช่องทางที่ผสานเข้ากับแค็ตตาล็อกและพื้นผิวการตรวจสอบความถูกต้อง

**อย่าใช้ไฟล์นี้สำหรับ:** การลงทะเบียนพฤติกรรมรันไทม์ การประกาศจุดเริ่มต้นของโค้ด หรือเมทาดาทาการติดตั้ง npm สิ่งเหล่านี้ควรอยู่ในโค้ด Plugin และ `package.json` ของคุณ

## ตัวอย่างขั้นต่ำ

```json
{
  "id": "voice-call",
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {}
  }
}
```

## ตัวอย่างแบบละเอียด

```json
{
  "id": "openrouter",
  "name": "OpenRouter",
  "description": "OpenRouter provider plugin",
  "version": "1.0.0",
  "providers": ["openrouter"],
  "modelSupport": {
    "modelPrefixes": ["router-"]
  },
  "modelIdNormalization": {
    "providers": {
      "openrouter": {
        "prefixWhenBare": "openrouter"
      }
    }
  },
  "providerEndpoints": [
    {
      "endpointClass": "openrouter",
      "hostSuffixes": ["openrouter.ai"]
    }
  ],
  "providerRequest": {
    "providers": {
      "openrouter": {
        "family": "openrouter"
      }
    }
  },
  "cliBackends": ["openrouter-cli"],
  "syntheticAuthRefs": ["openrouter-cli"],
  "setup": {
    "providers": [
      {
        "id": "openrouter",
        "envVars": ["OPENROUTER_API_KEY"]
      }
    ]
  },
  "providerAuthAliases": {
    "openrouter-coding": "openrouter"
  },
  "channelEnvVars": {
    "openrouter-chatops": ["OPENROUTER_CHATOPS_TOKEN"]
  },
  "providerAuthChoices": [
    {
      "provider": "openrouter",
      "method": "api-key",
      "choiceId": "openrouter-api-key",
      "choiceLabel": "OpenRouter API key",
      "groupId": "openrouter",
      "groupLabel": "OpenRouter",
      "optionKey": "openrouterApiKey",
      "cliFlag": "--openrouter-api-key",
      "cliOption": "--openrouter-api-key <key>",
      "cliDescription": "OpenRouter API key",
      "onboardingScopes": ["text-inference"]
    }
  ],
  "uiHints": {
    "apiKey": {
      "label": "API key",
      "placeholder": "sk-or-v1-...",
      "sensitive": true
    }
  },
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "apiKey": {
        "type": "string"
      }
    }
  }
}
```

## ข้อมูลอ้างอิงฟิลด์ระดับบนสุด

| ฟิลด์                                | จำเป็น | ชนิด                         | ความหมาย                                                                                                                                                                                                                                                              |
| ------------------------------------ | -------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                                 | ใช่      | `string`                     | รหัส Plugin มาตรฐาน นี่คือรหัสที่ใช้ใน `plugins.entries.<id>`                                                                                                                                                                                                        |
| `configSchema`                       | ใช่      | `object`                     | JSON Schema แบบอินไลน์สำหรับการกำหนดค่าของ Plugin นี้                                                                                                                                                                                                                               |
| `requiresPlugins`                    | ไม่       | `string[]`                   | รหัส Plugin ที่ต้องติดตั้งด้วยเพื่อให้ Plugin นี้ทำงานได้ การค้นหายังคงอนุญาตให้โหลด Plugin ได้ แต่จะแจ้งเตือนเมื่อไม่มี Plugin ที่จำเป็นรายการใดรายการหนึ่ง                                                                                                               |
| `enabledByDefault`                   | ไม่       | `true`                       | ระบุให้ Plugin ที่รวมมาในชุดเปิดใช้งานโดยค่าเริ่มต้น หากละเว้นหรือกำหนดเป็นค่าอื่นที่ไม่ใช่ `true` Plugin จะยังคงปิดใช้งานโดยค่าเริ่มต้น                                                                                                                                               |
| `enabledByDefaultOnPlatforms`        | ไม่       | `string[]`                   | ระบุให้ Plugin ที่รวมมาในชุดเปิดใช้งานโดยค่าเริ่มต้นเฉพาะบนแพลตฟอร์ม Node.js ที่ระบุ เช่น `["darwin"]` การกำหนดค่าโดยชัดแจ้งยังคงมีลำดับความสำคัญสูงกว่า                                                                                                                                   |
| `legacyPluginIds`                    | ไม่       | `string[]`                   | รหัสเดิมที่ปรับให้เป็นรหัส Plugin มาตรฐานนี้                                                                                                                                                                                                                     |
| `autoEnableWhenConfiguredProviders`  | ไม่       | `string[]`                   | รหัสผู้ให้บริการที่ควรเปิดใช้งาน Plugin นี้โดยอัตโนมัติเมื่อมีการอ้างถึงในข้อมูลรับรอง การกำหนดค่า หรือการอ้างอิงโมเดล                                                                                                                                                                            |
| `kind`                               | ไม่       | `PluginKind \| PluginKind[]` | ประกาศชนิด Plugin แบบเฉพาะหนึ่งชนิดขึ้นไป (`"memory"`, `"context-engine"`) ซึ่งใช้โดย `plugins.slots.*` Plugin ที่เป็นเจ้าของทั้งสองสล็อตจะประกาศทั้งสองชนิดในอาร์เรย์เดียว                                                                                                    |
| `channels`                           | ไม่       | `string[]`                   | รหัสช่องทางที่ Plugin นี้เป็นเจ้าของ ใช้สำหรับการค้นหาและการตรวจสอบความถูกต้องของการกำหนดค่า                                                                                                                                                                                                |
| `providers`                          | ไม่       | `string[]`                   | รหัสผู้ให้บริการที่ Plugin นี้เป็นเจ้าของ                                                                                                                                                                                                                                         |
| `providerCatalogEntry`               | ไม่       | `string`                     | พาธโมดูลแค็ตตาล็อกผู้ให้บริการแบบน้ำหนักเบาซึ่งสัมพันธ์กับรากของ Plugin สำหรับเมทาดาทาแค็ตตาล็อกผู้ให้บริการที่อยู่ในขอบเขตไฟล์กำกับ และสามารถโหลดได้โดยไม่ต้องเปิดใช้งานรันไทม์ของ Plugin ทั้งหมด                                                                                        |
| `modelSupport`                       | ไม่       | `object`                     | เมทาดาทาตระกูลโมเดลแบบย่อที่ไฟล์กำกับเป็นเจ้าของ ซึ่งใช้โหลด Plugin โดยอัตโนมัติก่อนรันไทม์                                                                                                                                                                                |
| `modelCatalog`                       | ไม่       | `object`                     | เมทาดาทาแค็ตตาล็อกโมเดลแบบประกาศสำหรับผู้ให้บริการที่ Plugin นี้เป็นเจ้าของ นี่คือสัญญาของระนาบควบคุมสำหรับการแสดงรายการแบบอ่านอย่างเดียว การเริ่มต้นใช้งาน ตัวเลือกโมเดล นามแฝง และการระงับในอนาคต โดยไม่ต้องโหลดรันไทม์ของ Plugin                                                |
| `modelPricing`                       | ไม่       | `object`                     | นโยบายค้นหาราคาภายนอกที่ผู้ให้บริการเป็นเจ้าของ ใช้เพื่อยกเว้นผู้ให้บริการภายในเครื่องหรือโฮสต์เองออกจากแค็ตตาล็อกราคาระยะไกล หรือจับคู่การอ้างอิงผู้ให้บริการกับรหัสแค็ตตาล็อก OpenRouter/LiteLLM โดยไม่เขียนรหัสผู้ให้บริการแบบตายตัวในแกนหลัก                                                    |
| `modelIdNormalization`               | ไม่       | `object`                     | การล้างนามแฝงหรือคำนำหน้าของรหัสโมเดลที่ผู้ให้บริการเป็นเจ้าของ ซึ่งต้องทำงานก่อนโหลดรันไทม์ของผู้ให้บริการ                                                                                                                                                                                  |
| `providerEndpoints`                  | ไม่       | `object[]`                   | เมทาดาทาโฮสต์/`baseUrl` ของปลายทางที่ไฟล์กำกับเป็นเจ้าของ สำหรับเส้นทางผู้ให้บริการที่แกนหลักต้องจัดประเภทก่อนโหลดรันไทม์ของผู้ให้บริการ                                                                                                                                                   |
| `providerRequest`                    | ไม่       | `object`                     | เมทาดาทาตระกูลผู้ให้บริการและความเข้ากันได้ของคำขอที่ประมวลผลได้รวดเร็ว ซึ่งนโยบายคำขอทั่วไปใช้ก่อนโหลดรันไทม์ของผู้ให้บริการ                                                                                                                                                     |
| `secretProviderIntegrations`         | ไม่       | `Record<string, object>`     | ค่าที่ตั้งไว้ล่วงหน้าของผู้ให้บริการดำเนินการ SecretRef แบบประกาศ ซึ่งพื้นผิวการตั้งค่าหรือการติดตั้งสามารถนำเสนอได้โดยไม่เขียนการผสานรวมเฉพาะผู้ให้บริการแบบตายตัวในแกนหลัก                                                                                                                            |
| `cliBackends`                        | ไม่       | `string[]`                   | รหัสแบ็กเอนด์การอนุมานของ CLI ที่ Plugin นี้เป็นเจ้าของ ใช้สำหรับเปิดใช้งานโดยอัตโนมัติเมื่อเริ่มต้นระบบจากการอ้างอิงการกำหนดค่าโดยชัดแจ้ง                                                                                                                                                                |
| `syntheticAuthRefs`                  | ไม่       | `string[]`                   | การอ้างอิงผู้ให้บริการหรือแบ็กเอนด์ CLI ที่ควรตรวจสอบฮุกการยืนยันตัวตนสังเคราะห์ซึ่ง Plugin เป็นเจ้าของ ระหว่างการค้นหาโมเดลแบบเริ่มต้นเย็นก่อนโหลดรันไทม์                                                                                                                                     |
| `nonSecretAuthMarkers`               | ไม่       | `string[]`                   | ค่าคีย์ API ตัวแทนที่ Plugin ซึ่งรวมมาในชุดเป็นเจ้าของ และใช้แทนสถานะข้อมูลรับรองภายในเครื่อง, OAuth หรือข้อมูลรับรองจากสภาพแวดล้อมที่ไม่ใช่ความลับ                                                                                                                                                       |
| `commandAliases`                     | ไม่       | `object[]`                   | ชื่อคำสั่งที่ Plugin นี้เป็นเจ้าของ ซึ่งควรสร้างการวินิจฉัยการกำหนดค่าและ CLI ที่รับรู้ Plugin ก่อนโหลดรันไทม์                                                                                                                                                       |
| `providerAuthEnvVars`                | ไม่       | `Record<string, string[]>`   | เมทาดาทาตัวแปรสภาพแวดล้อมเพื่อความเข้ากันได้ซึ่งเลิกใช้แล้ว สำหรับค้นหาการยืนยันตัวตน/สถานะของผู้ให้บริการ สำหรับ Plugin ใหม่ให้ใช้ `setup.providers[].envVars` แทน โดย OpenClaw ยังคงอ่านค่านี้ระหว่างช่วงเลิกใช้งาน                                                                                        |
| `providerUsageAuthEnvVars`           | ไม่       | `Record<string, string[]>`   | ข้อมูลรับรองผู้ให้บริการที่ใช้สำหรับการใช้งาน/การเรียกเก็บเงินเท่านั้น OpenClaw ใช้ชื่อเหล่านี้เพื่อค้นหาการใช้งานและลบข้อมูลลับ แต่ไม่ใช้สำหรับการยืนยันตัวตนเพื่อการอนุมานโดยเด็ดขาด                                                                                                                                  |
| `providerAuthAliases`                | ไม่       | `Record<string, string>`     | รหัสผู้ให้บริการที่ควรใช้รหัสผู้ให้บริการอื่นซ้ำสำหรับการค้นหาการยืนยันตัวตน เช่น ผู้ให้บริการด้านการเขียนโค้ดที่ใช้คีย์ API และโปรไฟล์การยืนยันตัวตนร่วมกับผู้ให้บริการพื้นฐาน                                                                                                                 |
| `channelEnvVars`                     | ไม่       | `Record<string, string[]>`   | เมทาดาทาตัวแปรสภาพแวดล้อมของช่องทางที่ประมวลผลได้รวดเร็ว ซึ่ง OpenClaw สามารถตรวจสอบได้โดยไม่โหลดโค้ด Plugin ใช้สำหรับการตั้งค่าช่องทางหรือพื้นผิวการยืนยันตัวตนที่ขับเคลื่อนด้วยตัวแปรสภาพแวดล้อม ซึ่งตัวช่วยเริ่มต้นระบบ/กำหนดค่าทั่วไปควรมองเห็น                                                                                   |
| `providerAuthChoices`                | ไม่       | `object[]`                   | เมทาดาทาตัวเลือกการยืนยันตัวตนที่ประมวลผลได้รวดเร็ว สำหรับตัวเลือกการเริ่มต้นใช้งาน การแก้ไขผู้ให้บริการที่ต้องการ และการเชื่อมต่อแฟล็ก CLI แบบง่าย                                                                                                                                                              |
| `activation`                         | ไม่       | `object`                     | เมทาดาทาตัววางแผนการเปิดใช้งานที่ประมวลผลได้รวดเร็ว สำหรับการโหลดที่ทริกเกอร์โดยการเริ่มต้นระบบ ผู้ให้บริการ คำสั่ง ช่องทาง เส้นทาง และความสามารถ เป็นเพียงเมทาดาทาเท่านั้น รันไทม์ของ Plugin ยังคงเป็นเจ้าของพฤติกรรมจริง                                                                                              |
| `setup`                              | ไม่       | `object`                     | ตัวอธิบายการตั้งค่า/การเริ่มต้นใช้งานที่ประมวลผลได้รวดเร็ว ซึ่งพื้นผิวการค้นหาและการตั้งค่าสามารถตรวจสอบได้โดยไม่โหลดรันไทม์ของ Plugin                                                                                                                                                           |
| `qaRunners`                          | ไม่       | `object[]`                   | ตัวอธิบายตัวรัน QA ที่ประมวลผลได้รวดเร็ว ซึ่งโฮสต์ `openclaw qa` ที่ใช้ร่วมกันใช้ก่อนโหลดรันไทม์ของ Plugin                                                                                                                                                                             |
| `contracts`                          | ไม่       | `object`                     | สแนปช็อตคงที่ของความเป็นเจ้าของความสามารถ สำหรับฮุกการยืนยันตัวตนภายนอก การฝังข้อมูล เสียงพูด การถอดเสียงแบบเรียลไทม์ เสียงพูดแบบเรียลไทม์ การทำความเข้าใจสื่อ การสร้างภาพ/วิดีโอ/เพลง การดึงข้อมูลเว็บ การค้นหาเว็บ ผู้ให้บริการเวิร์กเกอร์ การแยกเนื้อหาจากเอกสาร/เว็บ และความเป็นเจ้าของเครื่องมือ |
| `configContracts`                    | ไม่       | `object`                     | พฤติกรรมการกำหนดค่าที่ไฟล์กำกับเป็นเจ้าของและตัวช่วยแกนหลักทั่วไปใช้งาน ได้แก่ การตรวจจับแฟล็กอันตราย เป้าหมายการย้าย SecretRef และการจำกัดพาธการกำหนดค่าเดิมให้แคบลง ดู[ข้อมูลอ้างอิง configContracts](#configcontracts-reference)                                                     |
| `mediaUnderstandingProviderMetadata` | ไม่       | `Record<string, object>`     | ค่าเริ่มต้นต้นทุนต่ำสำหรับการทำความเข้าใจสื่อของรหัสผู้ให้บริการที่ประกาศใน `contracts.mediaUnderstandingProviders`                                                                                                                                                                   |
| `imageGenerationProviderMetadata`    | ไม่       | `Record<string, object>`     | เมทาดาทาการยืนยันตัวตนต้นทุนต่ำสำหรับการสร้างรูปภาพของรหัสผู้ให้บริการที่ประกาศใน `contracts.imageGenerationProviders` รวมถึงนามแฝงการยืนยันตัวตนที่ผู้ให้บริการเป็นเจ้าของและตัวป้องกัน URL ฐาน                                                                                                         |
| `videoGenerationProviderMetadata`    | ไม่       | `Record<string, object>`     | เมทาดาทาการยืนยันตัวตนต้นทุนต่ำสำหรับการสร้างวิดีโอของรหัสผู้ให้บริการที่ประกาศใน `contracts.videoGenerationProviders` รวมถึงนามแฝงการยืนยันตัวตนที่ผู้ให้บริการเป็นเจ้าของและตัวป้องกัน URL ฐาน                                                                                                         |
| `musicGenerationProviderMetadata`    | ไม่       | `Record<string, object>`     | เมทาดาทาการยืนยันตัวตนต้นทุนต่ำสำหรับการสร้างเพลงของรหัสผู้ให้บริการที่ประกาศใน `contracts.musicGenerationProviders` รวมถึงนามแฝงการยืนยันตัวตนที่ผู้ให้บริการเป็นเจ้าของและตัวป้องกัน URL ฐาน                                                                                                         |
| `toolMetadata`                       | ไม่       | `Record<string, object>`     | เมทาดาทาความพร้อมใช้งานต้นทุนต่ำสำหรับเครื่องมือที่ Plugin เป็นเจ้าของซึ่งประกาศใน `contracts.tools` ใช้เมื่อไม่ควรโหลดรันไทม์ของเครื่องมือ เว้นแต่จะมีหลักฐานจากการกำหนดค่า ตัวแปรสภาพแวดล้อม หรือการยืนยันตัวตน                                                                                                  |
| `channelConfigs`                     | ไม่       | `Record<string, object>`     | เมทาดาทาการกำหนดค่าช่องทางที่ไฟล์แมนิเฟสต์เป็นเจ้าของ ซึ่งจะผสานเข้ากับส่วนการค้นพบและการตรวจสอบความถูกต้องก่อนโหลดรันไทม์                                                                                                                                                                 |
| `skills`                             | ไม่       | `string[]`                   | ไดเรกทอรี Skills ที่จะโหลด โดยระบุพาธสัมพัทธ์จากรากของ Plugin                                                                                                                                                                                                                    |
| `name`                               | ไม่       | `string`                     | ชื่อ Plugin ที่มนุษย์อ่านเข้าใจได้                                                                                                                                                                                                                                                |
| `description`                        | ไม่       | `string`                     | ข้อมูลสรุปสั้น ๆ ที่แสดงในส่วนต่าง ๆ ของ Plugin                                                                                                                                                                                                                                    |
| `catalog`                            | ไม่       | `object`                     | คำแนะนำด้านการนำเสนอแบบไม่บังคับสำหรับส่วนต่าง ๆ ของแค็ตตาล็อก Plugin เมทาดาทานี้ไม่ได้ติดตั้ง เปิดใช้งาน หรือมอบความไว้วางใจให้ Plugin                                                                                                                                               |
| `icon`                               | ไม่       | `string`                     | URL รูปภาพ HTTPS สำหรับการ์ดในมาร์เก็ตเพลสหรือแค็ตตาล็อก ClawHub ยอมรับ URL `https://` ที่ถูกต้องทุกรายการ และจะใช้ไอคอน Plugin เริ่มต้นแทนเมื่อไม่ได้ระบุค่านี้หรือค่าไม่ถูกต้อง                                                                                                         |
| `version`                            | ไม่       | `string`                     | เวอร์ชันของ Plugin สำหรับให้ข้อมูล                                                                                                                                                                                                                                              |
| `uiHints`                            | ไม่       | `Record<string, object>`     | ป้ายกำกับ UI ข้อความตัวอย่าง และคำแนะนำด้านความละเอียดอ่อนสำหรับฟิลด์การกำหนดค่า                                                                                                                                                                                                          |

## ข้อมูลอ้างอิง catalog

`catalog` ให้คำแนะนำการแสดงผลเพิ่มเติมแก่เบราว์เซอร์ Plugin โฮสต์อาจไม่สนใจคำแนะนำเหล่านี้ คำแนะนำเหล่านี้จะไม่ติดตั้งหรือเปิดใช้งาน Plugin และจะไม่เปลี่ยนลักษณะการทำงานขณะรันหรือระดับความน่าเชื่อถือของ Plugin

```json
{
  "catalog": {
    "featured": true,
    "order": 10
  }
}
```

| ฟิลด์       | ชนิดข้อมูล | ความหมาย                                                                  |
| ----------- | ----------- | ------------------------------------------------------------------------- |
| `featured`  | `boolean`   | พื้นที่แสดงผล catalog ควรนำเสนอ Plugin นี้เป็นรายการเด่นหรือไม่           |
| `order`     | `number`    | คำแนะนำลำดับการแสดงผลแบบน้อยไปมากในกลุ่ม Plugin ที่คัดสรรไว้ ค่าที่ต่ำกว่าจะแสดงก่อน |

## ข้อมูลอ้างอิงเมทาดาทาของผู้ให้บริการการสร้าง

ฟิลด์เมทาดาทาของผู้ให้บริการการสร้างอธิบายสัญญาณการยืนยันตัวตนแบบคงที่สำหรับผู้ให้บริการที่ประกาศไว้ในรายการ `contracts.*GenerationProviders` ที่ตรงกัน OpenClaw อ่านฟิลด์เหล่านี้ก่อนโหลดรันไทม์ของผู้ให้บริการ เพื่อให้เครื่องมือแกนหลักตัดสินได้ว่าผู้ให้บริการการสร้างพร้อมใช้งานหรือไม่ โดยไม่ต้องนำเข้า Plugin ของผู้ให้บริการทุกรายการ

ใช้ฟิลด์เหล่านี้เฉพาะกับข้อเท็จจริงเชิงประกาศที่ตรวจสอบได้โดยใช้ทรัพยากรน้อยเท่านั้น การรับส่งข้อมูล การแปลงคำขอ การรีเฟรชโทเค็น การตรวจสอบข้อมูลประจำตัว และพฤติกรรมการสร้างจริงยังคงอยู่ในรันไทม์ของ Plugin

```json
{
  "contracts": {
    "imageGenerationProviders": ["example-image"]
  },
  "imageGenerationProviderMetadata": {
    "example-image": {
      "aliases": ["example-image-oauth"],
      "authProviders": ["example-image"],
      "configSignals": [
        {
          "rootPath": "plugins.entries.example-image.config",
          "overlayPath": "image",
          "mode": {
            "path": "mode",
            "default": "local",
            "allowed": ["local"]
          },
          "requiredAny": ["workflow", "workflowPath"],
          "required": ["promptNodeId"]
        }
      ],
      "authSignals": [
        {
          "provider": "example-image"
        },
        {
          "provider": "example-image-oauth",
          "providerBaseUrl": {
            "provider": "example-image",
            "defaultBaseUrl": "https://api.example.com/v1",
            "allowedBaseUrls": ["https://api.example.com/v1"]
          }
        }
      ]
    }
  }
}
```

แต่ละรายการเมทาดาทารองรับ:

| ฟิลด์                  | จำเป็น | ชนิดข้อมูล | ความหมาย                                                                                                                                                    |
| ---------------------- | ------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `aliases`              | ไม่    | `string[]` | รหัสผู้ให้บริการเพิ่มเติมที่ควรนับเป็นนามแฝงการยืนยันตัวตนแบบคงที่สำหรับผู้ให้บริการการสร้าง                                                                 |
| `authProviders`        | ไม่    | `string[]` | รหัสผู้ให้บริการซึ่งโปรไฟล์การยืนยันตัวตนที่กำหนดค่าไว้ควรนับเป็นการยืนยันตัวตนสำหรับผู้ให้บริการการสร้างนี้                                                 |
| `configSignals`        | ไม่    | `object[]` | สัญญาณความพร้อมใช้งานจากการกำหนดค่าเท่านั้นที่ตรวจสอบได้โดยใช้ทรัพยากรน้อย สำหรับผู้ให้บริการภายในเครื่องหรือโฮสต์เองที่กำหนดค่าได้โดยไม่ต้องใช้โปรไฟล์การยืนยันตัวตนหรือตัวแปรสภาพแวดล้อม |
| `authSignals`          | ไม่    | `object[]` | สัญญาณการยืนยันตัวตนที่ระบุอย่างชัดเจน เมื่อมีฟิลด์นี้ สัญญาณเหล่านี้จะแทนที่ชุดสัญญาณเริ่มต้นจากรหัสผู้ให้บริการ `aliases` และ `authProviders`             |
| `referenceAudioInputs` | ไม่    | `boolean`  | สำหรับการสร้างวิดีโอเท่านั้น ตั้งค่าเป็น `true` เมื่อผู้ให้บริการยอมรับแอสเซ็ตเสียงอ้างอิง มิฉะนั้น `video_generate` จะซ่อนพารามิเตอร์เสียงอ้างอิง             |

แต่ละรายการ `configSignals` รองรับ:

| ฟิลด์            | จำเป็น | ชนิดข้อมูล | ความหมาย                                                                                                                                                                                         |
| ---------------- | ------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `rootPath`       | ใช่    | `string`   | พาธแบบจุดไปยังออบเจ็กต์การกำหนดค่าที่ Plugin เป็นเจ้าของและต้องตรวจสอบ เช่น `plugins.entries.example.config`                                                                                     |
| `overlayPath`    | ไม่    | `string`   | พาธแบบจุดภายในการกำหนดค่าราก ซึ่งออบเจ็กต์ที่ตำแหน่งนั้นควรซ้อนทับออบเจ็กต์รากก่อนประเมินสัญญาณ ใช้สำหรับการกำหนดค่าเฉพาะความสามารถ เช่น `image`, `video` หรือ `music` |
| `overlayMapPath` | ไม่    | `string`   | พาธแบบจุดภายในการกำหนดค่าราก ซึ่งค่าออบเจ็กต์แต่ละค่าที่ตำแหน่งนั้นควรซ้อนทับออบเจ็กต์ราก ใช้สำหรับแมปบัญชีที่มีชื่อ เช่น `accounts` โดยบัญชีใดก็ตามที่กำหนดค่าไว้ถือว่าผ่านเกณฑ์ |
| `required`       | ไม่    | `string[]` | พาธแบบจุดภายในการกำหนดค่าที่มีผล ซึ่งต้องมีค่าที่กำหนดไว้ สตริงต้องไม่ว่าง และออบเจ็กต์กับอาร์เรย์ต้องไม่ว่าง                                                                                       |
| `requiredAny`    | ไม่    | `string[]` | พาธแบบจุดภายในการกำหนดค่าที่มีผล ซึ่งอย่างน้อยหนึ่งพาธต้องมีค่าที่กำหนดไว้                                                                                                                         |
| `mode`           | ไม่    | `object`   | เงื่อนไขกำกับโหมดแบบสตริงที่ไม่บังคับภายในการกำหนดค่าที่มีผล ใช้เมื่อความพร้อมใช้งานจากการกำหนดค่าเท่านั้นใช้ได้กับโหมดเดียว                                                                        |

เงื่อนไขกำกับ `mode` แต่ละรายการรองรับ:

| ฟิลด์        | จำเป็น | ชนิดข้อมูล | ความหมาย                                                                                     |
| ------------ | ------ | ---------- | -------------------------------------------------------------------------------------------- |
| `path`       | ไม่    | `string`   | พาธแบบจุดภายในการกำหนดค่าที่มีผล ค่าเริ่มต้นคือ `mode`                                       |
| `default`    | ไม่    | `string`   | ค่าโหมดที่จะใช้เมื่อการกำหนดค่าไม่มีพาธนี้                                                    |
| `allowed`    | ไม่    | `string[]` | หากมีฟิลด์นี้ สัญญาณจะผ่านเฉพาะเมื่อโหมดที่มีผลเป็นหนึ่งในค่าเหล่านี้                        |
| `disallowed` | ไม่    | `string[]` | หากมีฟิลด์นี้ สัญญาณจะไม่ผ่านเมื่อโหมดที่มีผลเป็นหนึ่งในค่าเหล่านี้                          |

แต่ละรายการ `authSignals` รองรับ:

| ฟิลด์             | จำเป็น | ชนิดข้อมูล | ความหมาย                                                                                                                                                                      |
| ----------------- | ------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider`        | ใช่    | `string`   | รหัสผู้ให้บริการที่จะตรวจสอบในโปรไฟล์การยืนยันตัวตนที่กำหนดค่าไว้                                                                                                             |
| `providerBaseUrl` | ไม่    | `object`   | เงื่อนไขกำกับที่ไม่บังคับ ซึ่งทำให้สัญญาณมีผลเฉพาะเมื่อผู้ให้บริการที่กำหนดค่าและอ้างถึงใช้ URL ฐานที่อนุญาต ใช้เมื่อนามแฝงการยืนยันตัวตนใช้ได้กับ API บางรายการเท่านั้น         |

เงื่อนไขกำกับ `providerBaseUrl` แต่ละรายการรองรับ:

| ฟิลด์             | จำเป็น | ชนิดข้อมูล | ความหมาย                                                                                                                                             |
| ----------------- | ------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider`        | ใช่    | `string`   | รหัสการกำหนดค่าผู้ให้บริการซึ่งต้องตรวจสอบ `baseUrl`                                                                                                 |
| `defaultBaseUrl`  | ไม่    | `string`   | URL ฐานที่ใช้เมื่อการกำหนดค่าผู้ให้บริการไม่มี `baseUrl`                                                                                             |
| `allowedBaseUrls` | ใช่    | `string[]` | URL ฐานที่อนุญาตสำหรับสัญญาณการยืนยันตัวตนนี้ สัญญาณจะถูกละเว้นเมื่อ URL ฐานที่กำหนดค่าไว้หรือค่าเริ่มต้นไม่ตรงกับค่าที่ปรับให้อยู่ในรูปแบบมาตรฐานเหล่านี้ |

## ข้อมูลอ้างอิงเมทาดาทาของเครื่องมือ

`toolMetadata` ใช้โครงสร้าง `configSignals` และ `authSignals` แบบเดียวกับเมทาดาทาของผู้ให้บริการการสร้าง โดยใช้ชื่อเครื่องมือเป็นคีย์ `contracts.tools` ประกาศความเป็นเจ้าของ ส่วน `toolMetadata` ประกาศหลักฐานความพร้อมใช้งานที่ตรวจสอบได้โดยใช้ทรัพยากรน้อย เพื่อให้ OpenClaw หลีกเลี่ยงการนำเข้ารันไทม์ของ Plugin เพียงเพื่อให้แฟกทอรีของเครื่องมือคืนค่า `null`

```json
{
  "setup": {
    "providers": [
      {
        "id": "example",
        "envVars": ["EXAMPLE_API_KEY"]
      }
    ]
  },
  "contracts": {
    "tools": ["example_search"]
  },
  "toolMetadata": {
    "example_search": {
      "authSignals": [
        {
          "provider": "example"
        }
      ],
      "configSignals": [
        {
          "rootPath": "plugins.entries.example.config",
          "overlayPath": "search",
          "required": ["apiKey"]
        }
      ]
    }
  }
}
```

รายการ `toolMetadata` ยังรองรับ `optional` (ระบุว่าเครื่องมือนี้ไม่จำเป็นต่อการเปิดใช้งาน Plugin) และ `replaySafe` (ระบุว่าการเรียกใช้เครื่องมือนั้นสามารถทำซ้ำได้อย่างปลอดภัยหลังจากรอบการทำงานของโมเดลที่ไม่สมบูรณ์) นอกเหนือจากฟิลด์ `configSignals`/`authSignals` ที่ใช้ร่วมกันข้างต้น

หากเครื่องมือไม่มี `toolMetadata` OpenClaw จะคงพฤติกรรมเดิมไว้และโหลด Plugin ที่เป็นเจ้าของเมื่อสัญญาเครื่องมือตรงกับนโยบาย สำหรับเครื่องมือในเส้นทางการทำงานที่ต้องการประสิทธิภาพสูงซึ่งแฟกทอรีขึ้นอยู่กับการยืนยันตัวตนหรือการกำหนดค่า ผู้เขียน Plugin ควรประกาศ `toolMetadata` แทนการให้แกนหลักนำเข้ารันไทม์เพื่อสอบถาม

## ข้อมูลอ้างอิง providerAuthChoices

แต่ละรายการ `providerAuthChoices` อธิบายตัวเลือกหนึ่งรายการสำหรับการเริ่มต้นใช้งานหรือการยืนยันตัวตน OpenClaw อ่านข้อมูลนี้ก่อนโหลดรันไทม์ของผู้ให้บริการ รายการตั้งค่าผู้ให้บริการใช้ตัวเลือกจากไฟล์ manifest เหล่านี้ ตัวเลือกการตั้งค่าที่ได้มาจากตัวอธิบาย และเมทาดาทาจาก catalog การติดตั้ง โดยไม่โหลดรันไทม์ของผู้ให้บริการ

| ฟิลด์                 | จำเป็น | ชนิด                                                                  | ความหมาย                                                                                             |
| --------------------- | -------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `provider`            | ใช่      | `string`                                                              | รหัสผู้ให้บริการที่ตัวเลือกนี้สังกัด                                                                       |
| `method`              | ใช่      | `string`                                                              | รหัสวิธีการยืนยันตัวตนที่จะส่งต่อไปดำเนินการ                                                                            |
| `choiceId`            | ใช่      | `string`                                                              | รหัสตัวเลือกการยืนยันตัวตนแบบคงที่ที่ใช้ในขั้นตอนการเริ่มต้นใช้งานและ CLI                                                   |
| `choiceLabel`         | ไม่       | `string`                                                              | ป้ายกำกับที่แสดงต่อผู้ใช้ หากไม่ระบุ OpenClaw จะใช้ `choiceId` แทน                                         |
| `choiceHint`          | ไม่       | `string`                                                              | ข้อความช่วยเหลือสั้น ๆ สำหรับตัวเลือก                                                                         |
| `assistantPriority`   | ไม่       | `number`                                                              | ค่าที่ต่ำกว่าจะเรียงลำดับก่อนในตัวเลือกแบบโต้ตอบที่ขับเคลื่อนโดยผู้ช่วย                                        |
| `assistantVisibility` | ไม่       | `"visible"` \| `"manual-only"`                                        | ซ่อนตัวเลือกจากตัวเลือกของผู้ช่วย แต่ยังอนุญาตให้เลือกด้วยตนเองผ่าน CLI                         |
| `deprecatedChoiceIds` | ไม่       | `string[]`                                                            | รหัสตัวเลือกเดิมที่ควรเปลี่ยนเส้นทางผู้ใช้มายังตัวเลือกทดแทนนี้                                  |
| `groupId`             | ไม่       | `string`                                                              | รหัสกลุ่มที่ไม่บังคับสำหรับจัดกลุ่มตัวเลือกที่เกี่ยวข้อง                                                           |
| `groupLabel`          | ไม่       | `string`                                                              | ป้ายกำกับที่แสดงต่อผู้ใช้สำหรับกลุ่มนั้น                                                                         |
| `groupHint`           | ไม่       | `string`                                                              | ข้อความช่วยเหลือสั้น ๆ สำหรับกลุ่ม                                                                          |
| `onboardingFeatured`  | ไม่       | `boolean`                                                             | แสดงกลุ่มนี้ในระดับรายการเด่นของตัวเลือกการเริ่มต้นใช้งานแบบโต้ตอบ ก่อนรายการ "เพิ่มเติม..." |
| `optionKey`           | ไม่       | `string`                                                              | คีย์ตัวเลือกภายในสำหรับขั้นตอนการยืนยันตัวตนแบบแฟล็กเดียวที่เรียบง่าย                                                       |
| `cliFlag`             | ไม่       | `string`                                                              | ชื่อแฟล็ก CLI เช่น `--openrouter-api-key`                                                            |
| `cliOption`           | ไม่       | `string`                                                              | รูปแบบตัวเลือก CLI แบบเต็ม เช่น `--openrouter-api-key <key>`                                              |
| `cliDescription`      | ไม่       | `string`                                                              | คำอธิบายที่ใช้ในความช่วยเหลือของ CLI                                                                             |
| `onboardingScopes`    | ไม่       | `Array<"text-inference" \| "image-generation" \| "music-generation">` | พื้นที่การเริ่มต้นใช้งานที่ควรแสดงตัวเลือกนี้ หากไม่ระบุ ค่าเริ่มต้นคือ `["text-inference"]`  |

## ข้อมูลอ้างอิง `commandAliases`

ใช้ `commandAliases` เมื่อ Plugin เป็นเจ้าของชื่อคำสั่งรันไทม์ที่ผู้ใช้อาจใส่ใน `plugins.allow` โดยไม่ตั้งใจ หรือพยายามเรียกใช้เป็นคำสั่ง CLI ระดับราก OpenClaw ใช้ข้อมูลเมตานี้เพื่อการวินิจฉัยโดยไม่ต้องนำเข้าโค้ดรันไทม์ของ Plugin

```json
{
  "commandAliases": [
    {
      "name": "dreaming",
      "kind": "runtime-slash",
      "cliCommand": "memory"
    }
  ]
}
```

| ฟิลด์        | จำเป็น | ชนิด              | ความหมาย                                                           |
| ------------ | -------- | ----------------- | ----------------------------------------------------------------------- |
| `name`       | ใช่      | `string`          | ชื่อคำสั่งที่เป็นของ Plugin นี้                               |
| `kind`       | ไม่       | `"runtime-slash"` | ระบุว่านามแฝงเป็นคำสั่งสแลชในแชต ไม่ใช่คำสั่ง CLI ระดับราก |
| `cliCommand` | ไม่       | `string`          | คำสั่ง CLI ระดับรากที่เกี่ยวข้องซึ่งจะแนะนำสำหรับการดำเนินการผ่าน CLI หากมี  |

## ข้อมูลอ้างอิง `activation`

ใช้ `activation` เมื่อ Plugin สามารถประกาศได้โดยมีต้นทุนต่ำว่าเหตุการณ์ใดของระนาบควบคุมควรรวม Plugin นี้ไว้ในแผนการเปิดใช้งาน/โหลด

บล็อกนี้เป็นข้อมูลเมตาสำหรับตัววางแผน ไม่ใช่ API วงจรชีวิต บล็อกนี้ไม่ได้ลงทะเบียนพฤติกรรมรันไทม์ ไม่ได้ใช้แทน `register(...)` และไม่ได้รับรองว่าโค้ดของ Plugin ได้ทำงานแล้ว ตัววางแผนการเปิดใช้งานใช้ฟิลด์เหล่านี้เพื่อจำกัด Plugin ที่เป็นตัวเลือก ก่อนย้อนกลับไปใช้ข้อมูลเมตาความเป็นเจ้าของจากแมนิเฟสต์ที่มีอยู่ เช่น `providers`, `channels`, `commandAliases`, `setup.providers`, `contracts.tools` และฮุก

ควรใช้ข้อมูลเมตาที่แคบที่สุดซึ่งอธิบายความเป็นเจ้าของได้อยู่แล้ว ใช้ `providers`, `channels`, `commandAliases`, ตัวอธิบายการตั้งค่า หรือ `contracts` เมื่อฟิลด์เหล่านั้นแสดงความสัมพันธ์ได้ ใช้ `activation` สำหรับคำใบ้เพิ่มเติมแก่ตัววางแผนที่ไม่สามารถแทนด้วยฟิลด์ความเป็นเจ้าของเหล่านั้นได้ ใช้ `cliBackends` ระดับบนสุดสำหรับนามแฝงรันไทม์ CLI เช่น `claude-cli`, `my-cli` หรือ `google-gemini-cli`; `activation.onAgentHarnesses` ใช้เฉพาะรหัสชุดควบคุมเอเจนต์แบบฝังที่ยังไม่มีฟิลด์ความเป็นเจ้าของเท่านั้น

Plugin ทุกตัวควรกำหนด `activation.onStartup` อย่างชัดเจน กำหนดเป็น `true` เฉพาะเมื่อ Plugin ต้องทำงานระหว่างการเริ่มต้น Gateway กำหนดเป็น `false` เมื่อ Plugin ไม่มีการทำงานตอนเริ่มต้นและควรโหลดจากทริกเกอร์ที่แคบกว่าเท่านั้น การละ `onStartup` จะไม่ทำให้ Plugin โหลดตอนเริ่มต้นโดยปริยายอีกต่อไป ให้ใช้ข้อมูลเมตาการเปิดใช้งานที่ชัดเจนสำหรับทริกเกอร์การเปิดใช้งานจากการเริ่มต้น ช่องทาง การกำหนดค่า ชุดควบคุมเอเจนต์ หน่วยความจำ หรือทริกเกอร์อื่นที่แคบกว่า

```json
{
  "activation": {
    "onStartup": false,
    "onProviders": ["openai"],
    "onCommands": ["models"],
    "onChannels": ["web"],
    "onRoutes": ["gateway-webhook"],
    "onConfigPaths": ["browser"],
    "onCapabilities": ["provider", "tool"]
  }
}
```

| ฟิลด์              | จำเป็น | ชนิด                                                 | ความหมาย                                                                                                                                                                               |
| ------------------ | -------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onStartup`        | ไม่       | `boolean`                                            | การเปิดใช้งานอย่างชัดเจนเมื่อ Gateway เริ่มต้น Plugin ทุกตัวควรกำหนดค่านี้ `true` จะนำเข้า Plugin ระหว่างการเริ่มต้น ส่วน `false` จะคงการโหลดแบบหน่วงไว้ในช่วงเริ่มต้น เว้นแต่ทริกเกอร์อื่นที่ตรงกันจะกำหนดให้โหลด |
| `onProviders`      | ไม่       | `string[]`                                           | รหัสผู้ให้บริการที่ควรรวม Plugin นี้ไว้ในแผนการเปิดใช้งาน/โหลด                                                                                                                      |
| `onAgentHarnesses` | ไม่       | `string[]`                                           | รหัสรันไทม์ชุดควบคุมเอเจนต์แบบฝังที่ควรรวม Plugin นี้ไว้ในแผนการเปิดใช้งาน/โหลด ใช้ `cliBackends` ระดับบนสุดสำหรับนามแฝงแบ็กเอนด์ CLI                                           |
| `onCommands`       | ไม่       | `string[]`                                           | รหัสคำสั่งที่ควรรวม Plugin นี้ไว้ในแผนการเปิดใช้งาน/โหลด                                                                                                                       |
| `onChannels`       | ไม่       | `string[]`                                           | รหัสช่องทางที่ควรรวม Plugin นี้ไว้ในแผนการเปิดใช้งาน/โหลด                                                                                                                       |
| `onRoutes`         | ไม่       | `string[]`                                           | ชนิดเส้นทางที่ควรรวม Plugin นี้ไว้ในแผนการเปิดใช้งาน/โหลด                                                                                                                       |
| `onConfigPaths`    | ไม่       | `string[]`                                           | เส้นทางการกำหนดค่าที่สัมพันธ์กับราก ซึ่งควรรวม Plugin นี้ไว้ในแผนการเริ่มต้น/โหลดเมื่อมีเส้นทางนั้นอยู่และไม่ได้ถูกปิดใช้งานอย่างชัดเจน                                                      |
| `onCapabilities`   | ไม่       | `Array<"provider" \| "channel" \| "tool" \| "hook">` | คำใบ้ความสามารถแบบกว้างที่ใช้ในการวางแผนการเปิดใช้งานของระนาบควบคุม ควรใช้ฟิลด์ที่แคบกว่าเมื่อเป็นไปได้                                                                                     |

ส่วนที่ใช้งานจริงในปัจจุบัน:

- การวางแผนเริ่มต้น Gateway ใช้ `activation.onStartup` สำหรับการนำเข้าอย่างชัดเจนตอนเริ่มต้น
- การวางแผน CLI ที่ทริกเกอร์ด้วยคำสั่งจะย้อนกลับไปใช้ `commandAliases[].cliCommand` หรือ `commandAliases[].name` แบบเดิม
- การวางแผนเริ่มต้นรันไทม์ของเอเจนต์ใช้ `activation.onAgentHarnesses` สำหรับชุดควบคุมแบบฝัง และใช้ `cliBackends[]` ระดับบนสุดสำหรับนามแฝงรันไทม์ CLI
- การวางแผนการตั้งค่า/ช่องทางที่ทริกเกอร์ด้วยช่องทางจะย้อนกลับไปใช้ความเป็นเจ้าของ `channels[]` แบบเดิมเมื่อไม่มีข้อมูลเมตาการเปิดใช้งานช่องทางที่ชัดเจน
- การวางแผน Plugin ตอนเริ่มต้นใช้ `activation.onConfigPaths` สำหรับพื้นผิวการกำหนดค่าระดับรากที่ไม่ใช่ช่องทาง เช่น บล็อก `browser` ของ Plugin เบราว์เซอร์ที่รวมมาให้
- การวางแผนการตั้งค่า/รันไทม์ที่ทริกเกอร์ด้วยผู้ให้บริการจะย้อนกลับไปใช้ความเป็นเจ้าของ `providers[]` แบบเดิมและ `cliBackends[]` ระดับบนสุด เมื่อไม่มีข้อมูลเมตาการเปิดใช้งานผู้ให้บริการที่ชัดเจน

การวินิจฉัยของตัววางแผนสามารถแยกคำใบ้การเปิดใช้งานที่ชัดเจนออกจากการย้อนกลับไปใช้ความเป็นเจ้าของจากแมนิเฟสต์ได้ ตัวอย่างเช่น `activation-command-hint` หมายถึง `activation.onCommands` ตรงกัน ขณะที่ `manifest-command-alias` หมายถึงตัววางแผนใช้ความเป็นเจ้าของจาก `commandAliases` แทน ป้ายกำกับเหตุผลเหล่านี้มีไว้สำหรับการวินิจฉัยของโฮสต์และการทดสอบ ผู้เขียน Plugin ควรประกาศข้อมูลเมตาที่อธิบายความเป็นเจ้าของได้ดีที่สุดต่อไป

## ข้อมูลอ้างอิง `qaRunners`

ใช้ `qaRunners` เมื่อ Plugin เพิ่มตัวรันการรับส่งข้อมูลอย่างน้อยหนึ่งตัวภายใต้
คำสั่งราก `openclaw qa` ที่ใช้ร่วมกัน รักษาข้อมูลเมตานี้ให้มีต้นทุนต่ำและเป็นแบบคงที่ รันไทม์ของ Plugin
ยังคงเป็นเจ้าของการลงทะเบียน CLI จริงผ่านพื้นผิว
`runtime-api.ts` แบบเบาที่ส่งออก `qaRunnerCliRegistrations` ที่ตรงกัน
`adapterFactory` ที่เป็นทางเลือกจะเปิดเผยการรับส่งข้อมูลให้กับสถานการณ์ QA ที่ใช้ร่วมกัน โดยไม่
เปลี่ยนตัวรันของคำสั่งที่ลงทะเบียนไว้

```json
{
  "qaRunners": [
    {
      "commandName": "matrix",
      "description": "Run the Docker-backed Matrix live QA lane against a disposable homeserver"
    }
  ]
}
```

| ฟิลด์         | จำเป็น | ชนิด     | ความหมาย                                                      |
| ------------- | -------- | -------- | ------------------------------------------------------------------ |
| `commandName` | ใช่      | `string` | คำสั่งย่อยที่ติดตั้งภายใต้ `openclaw qa` เช่น `matrix`    |
| `description` | ไม่       | `string` | ข้อความช่วยเหลือสำรองที่ใช้เมื่อโฮสต์ส่วนกลางต้องการคำสั่งจำลอง |

รหัส `adapterFactory` ต้องตรงกับ `commandName` ห้ามส่งออกการลงทะเบียน
สำหรับคำสั่งที่ไม่มีอยู่ในแมนิเฟสต์

## ข้อมูลอ้างอิง setup

ใช้ `setup` เมื่อพื้นผิวการตั้งค่าและการเริ่มต้นใช้งานต้องใช้เมทาดาทาราคาถูกที่ Plugin เป็นเจ้าของ ก่อนโหลดรันไทม์

```json
{
  "setup": {
    "providers": [
      {
        "id": "openai",
        "authMethods": ["api-key"],
        "envVars": ["OPENAI_API_KEY"],
        "authEvidence": [
          {
            "type": "local-file-with-env",
            "fileEnvVar": "OPENAI_CREDENTIALS_FILE",
            "requiresAllEnv": ["OPENAI_PROJECT"],
            "credentialMarker": "openai-local-credentials",
            "source": "openai local credentials"
          }
        ]
      }
    ],
    "cliBackends": ["openai-cli"],
    "configMigrations": ["legacy-openai-auth"],
    "requiresRuntime": false
  }
}
```

`cliBackends` ระดับบนสุดยังคงใช้ได้และยังคงใช้อธิบายแบ็กเอนด์การอนุมานของ CLI ส่วน `setup.cliBackends` คือพื้นผิวตัวระบุเฉพาะสำหรับการตั้งค่า ซึ่งใช้กับโฟลว์ของระนาบควบคุม/การตั้งค่าที่ควรใช้เฉพาะเมทาดาทา

เมื่อมี `setup.providers` และ `setup.cliBackends` ให้ใช้เป็นพื้นผิวการค้นหาแบบใช้ตัวระบุก่อนสำหรับการค้นพบการตั้งค่า หากตัวระบุเพียงจำกัดขอบเขต Plugin ที่เป็นตัวเลือก และการตั้งค่ายังต้องใช้ฮุกของรันไทม์ที่มีความสามารถมากกว่าในช่วงการตั้งค่า ให้กำหนด `requiresRuntime: true` และคง `setup-api` ไว้เป็นเส้นทางดำเนินการสำรอง

OpenClaw ยังรวม `setup.providers[].envVars` ไว้ในการค้นหาการยืนยันตัวตนของผู้ให้บริการและตัวแปรสภาพแวดล้อมแบบทั่วไปด้วย `providerAuthEnvVars` ยังคงรองรับผ่านอะแดปเตอร์ความเข้ากันได้ในช่วงเลิกใช้งาน แต่ Plugin ที่ไม่ได้รวมมาในชุดและยังคงใช้ค่านี้จะได้รับการวินิจฉัยแมนิเฟสต์ Plugin ใหม่ควรใส่เมทาดาทาตัวแปรสภาพแวดล้อมสำหรับการตั้งค่า/สถานะไว้ใน `setup.providers[].envVars`

ใช้ `providerUsageAuthEnvVars` เมื่อข้อมูลประจำตัวระดับการเรียกเก็บเงินหรือองค์กรจำเป็นต้องเปิดใช้งาน `resolveUsageAuth` โดยไม่กลายเป็นข้อมูลประจำตัวสำหรับการอนุมาน ชื่อเหล่านี้จะรวมอยู่ในการบล็อก dotenv ของเวิร์กสเปซ การตัดออกจากโพรเซสลูกของ ACP การกรองข้อมูลลับในแซนด์บ็อกซ์ และการล้างข้อมูลลับในวงกว้าง รันไทม์ของผู้ให้บริการยังคงอ่านและจำแนกค่าภายใน `resolveUsageAuth`

OpenClaw ยังสามารถสร้างตัวเลือกการตั้งค่าแบบง่ายจาก `setup.providers[].authMethods` เมื่อไม่มีรายการการตั้งค่า หรือเมื่อ `setup.requiresRuntime: false` ระบุว่าไม่จำเป็นต้องใช้รันไทม์สำหรับการตั้งค่า รายการ `providerAuthChoices` ที่ระบุอย่างชัดเจนยังคงมีลำดับความสำคัญสูงกว่าสำหรับป้ายกำกับแบบกำหนดเอง แฟล็ก CLI ขอบเขตการเริ่มต้นใช้งาน และเมทาดาทาของผู้ช่วย

กำหนด `requiresRuntime: false` เฉพาะเมื่อตัวระบุเหล่านั้นเพียงพอสำหรับพื้นผิวการตั้งค่า OpenClaw ถือว่าค่า `false` ที่ระบุอย่างชัดเจนเป็นสัญญาที่ใช้เฉพาะตัวระบุ และจะไม่ดำเนินการ `setup-api` หรือ `openclaw.setupEntry` สำหรับการค้นหาการตั้งค่า หาก Plugin ที่ใช้เฉพาะตัวระบุยังคงมีรายการรันไทม์สำหรับการตั้งค่าอย่างใดอย่างหนึ่งดังกล่าว OpenClaw จะรายงานการวินิจฉัยเพิ่มเติมและยังคงเพิกเฉยต่อรายการนั้น การละ `requiresRuntime` จะคงพฤติกรรมสำรองแบบเดิมไว้ เพื่อไม่ให้ Plugin ที่มีอยู่ซึ่งเพิ่มตัวระบุโดยไม่มีแฟล็กนี้เสียหาย

เนื่องจากการค้นหาการตั้งค่าสามารถดำเนินการโค้ด `setup-api` ที่ Plugin เป็นเจ้าของได้ ค่า `setup.providers[].id` และ `setup.cliBackends[]` ที่ผ่านการปรับให้เป็นรูปแบบมาตรฐานแล้วต้องไม่ซ้ำกันในบรรดา Plugin ที่ค้นพบ หากความเป็นเจ้าของไม่ชัดเจน ระบบจะปฏิเสธโดยปริยายแทนการเลือกผู้ชนะตามลำดับการค้นพบ

เมื่อมีการดำเนินการรันไทม์สำหรับการตั้งค่า การวินิจฉัยรีจิสทรีการตั้งค่าจะรายงานความคลาดเคลื่อนของตัวระบุ หาก `setup-api` ลงทะเบียนผู้ให้บริการหรือแบ็กเอนด์ CLI ที่ตัวระบุในแมนิเฟสต์ไม่ได้ประกาศไว้ หรือหากตัวระบุไม่มีการลงทะเบียนรันไทม์ที่ตรงกัน การวินิจฉัยเหล่านี้เป็นข้อมูลเพิ่มเติมและไม่ปฏิเสธ Plugin รุ่นเดิม

### ข้อมูลอ้างอิง setup.providers

| ฟิลด์          | จำเป็น | ชนิด       | ความหมาย                                                                                    |
| -------------- | -------- | ---------- | ------------------------------------------------------------------------------------------------ |
| `id`           | ใช่      | `string`   | รหัสผู้ให้บริการที่เปิดเผยระหว่างการตั้งค่าหรือการเริ่มต้นใช้งาน ต้องทำให้รหัสที่ปรับเป็นรูปแบบมาตรฐานแล้วไม่ซ้ำกันทั่วทั้งระบบ             |
| `authMethods`  | ไม่       | `string[]` | รหัสวิธีการตั้งค่า/ยืนยันตัวตนที่ผู้ให้บริการนี้รองรับโดยไม่ต้องโหลดรันไทม์เต็มรูปแบบ                       |
| `envVars`      | ไม่       | `string[]` | ตัวแปรสภาพแวดล้อมที่พื้นผิวการตั้งค่า/สถานะแบบทั่วไปสามารถตรวจสอบได้ก่อนโหลดรันไทม์ของ Plugin               |
| `authEvidence` | ไม่       | `object[]` | การตรวจสอบหลักฐานการยืนยันตัวตนภายในเครื่องที่มีต้นทุนต่ำ สำหรับผู้ให้บริการที่สามารถยืนยันตัวตนผ่านตัวบ่งชี้ที่ไม่ใช่ข้อมูลลับ |

`authEvidence` ใช้สำหรับตัวบ่งชี้ข้อมูลประจำตัวภายในเครื่องที่ผู้ให้บริการเป็นเจ้าของ ซึ่งสามารถตรวจสอบได้โดยไม่ต้องโหลดโค้ดรันไทม์ การตรวจสอบเหล่านี้ต้องมีต้นทุนต่ำและทำภายในเครื่องเท่านั้น: ห้ามเรียกเครือข่าย ห้ามอ่านพวงกุญแจหรือเครื่องมือจัดการข้อมูลลับ ห้ามใช้คำสั่งเชลล์ และห้ามตรวจสอบ API ของผู้ให้บริการ

รายการหลักฐานที่รองรับ:

| ฟิลด์              | จำเป็น | ชนิด       | ความหมาย                                                                                                  |
| ------------------ | -------- | ---------- | -------------------------------------------------------------------------------------------------------------- |
| `type`             | ใช่      | `string`   | ปัจจุบันคือ `local-file-with-env`                                                                               |
| `fileEnvVar`       | ไม่       | `string`   | ตัวแปรสภาพแวดล้อมที่มีพาธไฟล์ข้อมูลประจำตัวซึ่งระบุอย่างชัดเจน                                                           |
| `fallbackPaths`    | ไม่       | `string[]` | พาธไฟล์ข้อมูลประจำตัวภายในเครื่องที่จะตรวจสอบเมื่อไม่มี `fileEnvVar` หรือมีค่าว่าง รองรับ `${HOME}` และ `${APPDATA}` |
| `requiresAnyEnv`   | ไม่       | `string[]` | ตัวแปรสภาพแวดล้อมที่ระบุไว้อย่างน้อยหนึ่งรายการต้องไม่ว่างก่อนที่หลักฐานจะใช้ได้                                    |
| `requiresAllEnv`   | ไม่       | `string[]` | ตัวแปรสภาพแวดล้อมที่ระบุไว้ทุกรายการต้องไม่ว่างก่อนที่หลักฐานจะใช้ได้                                           |
| `credentialMarker` | ใช่      | `string`   | ตัวบ่งชี้ที่ไม่ใช่ข้อมูลลับซึ่งส่งคืนเมื่อพบหลักฐาน                                                       |
| `source`           | ไม่       | `string`   | ป้ายกำกับแหล่งที่มาที่ผู้ใช้เห็นสำหรับผลลัพธ์การยืนยันตัวตน/สถานะ                                                               |

### ฟิลด์ setup

| ฟิลด์              | จำเป็น | ชนิด       | ความหมาย                                                                                       |
| ------------------ | -------- | ---------- | --------------------------------------------------------------------------------------------------- |
| `providers`        | ไม่       | `object[]` | ตัวระบุการตั้งค่าผู้ให้บริการที่เปิดเผยระหว่างการตั้งค่าและการเริ่มต้นใช้งาน                                     |
| `cliBackends`      | ไม่       | `string[]` | รหัสแบ็กเอนด์ในช่วงการตั้งค่าที่ใช้สำหรับการค้นหาการตั้งค่าแบบใช้ตัวระบุก่อน ต้องทำให้รหัสที่ปรับเป็นรูปแบบมาตรฐานแล้วไม่ซ้ำกันทั่วทั้งระบบ |
| `configMigrations` | ไม่       | `string[]` | รหัสการย้ายข้อมูลการกำหนดค่าที่พื้นผิวการตั้งค่าของ Plugin นี้เป็นเจ้าของ                                          |
| `requiresRuntime`  | ไม่       | `boolean`  | การตั้งค่ายังต้องดำเนินการ `setup-api` หลังจากค้นหาตัวระบุหรือไม่                            |

## ข้อมูลอ้างอิง uiHints

`uiHints` คือแมปจากชื่อฟิลด์การกำหนดค่าไปยังคำแนะนำการแสดงผลขนาดเล็ก คีย์สามารถใช้จุดสำหรับฟิลด์การกำหนดค่าที่ซ้อนกันได้ แต่ไม่มีเซกเมนต์ใดในพาธที่เป็น `__proto__`, `constructor` หรือ `prototype`; การตั้งค่าจะปฏิเสธชื่อเหล่านั้น

```json
{
  "uiHints": {
    "apiKey": {
      "label": "API key",
      "help": "Used for OpenRouter requests",
      "placeholder": "sk-or-v1-...",
      "sensitive": true
    }
  }
}
```

คำแนะนำของแต่ละฟิลด์สามารถมีรายการต่อไปนี้:

| ฟิลด์         | ชนิด       | ความหมาย                           |
| ------------- | ---------- | --------------------------------------- |
| `label`       | `string`   | ป้ายกำกับฟิลด์ที่ผู้ใช้เห็น                |
| `help`        | `string`   | ข้อความช่วยเหลือแบบสั้น                      |
| `tags`        | `string[]` | แท็ก UI ที่ไม่บังคับ                       |
| `advanced`    | `boolean`  | ทำเครื่องหมายฟิลด์ว่าเป็นขั้นสูง            |
| `sensitive`   | `boolean`  | ทำเครื่องหมายฟิลด์ว่าเป็นข้อมูลลับหรือข้อมูลละเอียดอ่อน |
| `placeholder` | `string`   | ข้อความตัวอย่างสำหรับช่องป้อนข้อมูลในฟอร์ม       |

## ข้อมูลอ้างอิง contracts

ใช้ `contracts` เฉพาะสำหรับเมทาดาทาความเป็นเจ้าของความสามารถแบบคงที่ ซึ่ง OpenClaw สามารถอ่านได้โดยไม่ต้องนำเข้ารันไทม์ของ Plugin

```json
{
  "contracts": {
    "agentToolResultMiddleware": ["openclaw", "codex"],
    "trustedToolPolicies": ["workflow-budget"],
    "externalAuthProviders": ["acme-ai"],
    "embeddingProviders": ["openai-compatible"],
    "speechProviders": ["openai"],
    "realtimeTranscriptionProviders": ["openai"],
    "realtimeVoiceProviders": ["openai"],
    "memoryEmbeddingProviders": ["local"],
    "mediaUnderstandingProviders": ["openai"],
    "imageGenerationProviders": ["openai"],
    "videoGenerationProviders": ["qwen"],
    "musicGenerationProviders": ["stability-audio"],
    "documentExtractors": ["example-docs"],
    "webContentExtractors": ["firecrawl"],
    "webFetchProviders": ["firecrawl"],
    "webSearchProviders": ["gemini"],
    "workerProviders": ["example-worker"],
    "usageProviders": ["acme-ai"],
    "migrationProviders": ["hermes"],
    "gatewayMethodDispatch": ["authenticated-request"],
    "tools": ["firecrawl_search", "firecrawl_scrape"]
  }
}
```

แต่ละรายการไม่บังคับ:

| ฟิลด์                            | ชนิด       | ความหมาย                                                                                                                        |
| -------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `embeddedExtensionFactories`     | `string[]` | รหัสโรงงานส่วนขยายของเซิร์ฟเวอร์แอป Codex ปัจจุบันคือ `codex-app-server`                                                                |
| `agentToolResultMiddleware`      | `string[]` | รหัสรันไทม์ที่ Plugin นี้อาจลงทะเบียนมิดเดิลแวร์ผลลัพธ์ของเครื่องมือให้                                                                     |
| `trustedToolPolicies`            | `string[]` | รหัสนโยบายก่อนใช้เครื่องมือที่เชื่อถือได้ภายใน Plugin ซึ่ง Plugin ที่ติดตั้งอาจลงทะเบียน Plugin ที่มาพร้อมระบบสามารถลงทะเบียนนโยบายได้โดยไม่ต้องมีฟิลด์นี้ |
| `externalAuthProviders`          | `string[]` | รหัสผู้ให้บริการที่ Plugin นี้เป็นเจ้าของฮุกโปรไฟล์การยืนยันตัวตนภายนอก                                                                      |
| `embeddingProviders`             | `string[]` | รหัสผู้ให้บริการเวกเตอร์ฝังตัวทั่วไปที่ Plugin นี้เป็นเจ้าของสำหรับการใช้เวกเตอร์ฝังตัวซ้ำ รวมถึงหน่วยความจำ                                 |
| `speechProviders`                | `string[]` | รหัสผู้ให้บริการเสียงพูดที่ Plugin นี้เป็นเจ้าของ                                                                                                |
| `realtimeTranscriptionProviders` | `string[]` | รหัสผู้ให้บริการถอดเสียงแบบเรียลไทม์ที่ Plugin นี้เป็นเจ้าของ                                                                                |
| `realtimeVoiceProviders`         | `string[]` | รหัสผู้ให้บริการเสียงแบบเรียลไทม์ที่ Plugin นี้เป็นเจ้าของ                                                                                      |
| `memoryEmbeddingProviders`       | `string[]` | รหัสผู้ให้บริการเวกเตอร์ฝังตัวเฉพาะหน่วยความจำที่เลิกใช้แล้วซึ่ง Plugin นี้เป็นเจ้าของ                                                          |
| `mediaUnderstandingProviders`    | `string[]` | รหัสผู้ให้บริการทำความเข้าใจสื่อที่ Plugin นี้เป็นเจ้าของ                                                                                   |
| `transcriptSourceProviders`      | `string[]` | รหัสผู้ให้บริการแหล่งที่มาของบทถอดเสียงที่ Plugin นี้เป็นเจ้าของ                                                                             |
| `documentExtractors`             | `string[]` | รหัสผู้ให้บริการแยกข้อมูลจากเอกสาร (เช่น PDF) ที่ Plugin นี้เป็นเจ้าของ                                                                  |
| `imageGenerationProviders`       | `string[]` | รหัสผู้ให้บริการสร้างรูปภาพที่ Plugin นี้เป็นเจ้าของ                                                                                      |
| `videoGenerationProviders`       | `string[]` | รหัสผู้ให้บริการสร้างวิดีโอที่ Plugin นี้เป็นเจ้าของ                                                                                      |
| `musicGenerationProviders`       | `string[]` | รหัสผู้ให้บริการสร้างเพลงที่ Plugin นี้เป็นเจ้าของ                                                                                      |
| `webContentExtractors`           | `string[]` | รหัสผู้ให้บริการแยกเนื้อหาจากหน้าเว็บที่ Plugin นี้เป็นเจ้าของ                                                                           |
| `webFetchProviders`              | `string[]` | รหัสผู้ให้บริการดึงข้อมูลเว็บที่ Plugin นี้เป็นเจ้าของ                                                                                             |
| `webSearchProviders`             | `string[]` | รหัสผู้ให้บริการค้นหาเว็บที่ Plugin นี้เป็นเจ้าของ                                                                                            |
| `workerProviders`                | `string[]` | รหัสผู้ให้บริการเวิร์กเกอร์บนคลาวด์ที่ Plugin นี้เป็นเจ้าของ สำหรับการจัดเตรียมและวงจรชีวิตสัญญาเช่าที่อิงโปรไฟล์                                      |
| `usageProviders`                 | `string[]` | รหัสผู้ให้บริการที่ Plugin นี้เป็นเจ้าของฮุกการยืนยันตัวตนเพื่อดูการใช้งานและสแนปช็อตการใช้งาน                                                             |
| `migrationProviders`             | `string[]` | รหัสผู้ให้บริการนำเข้าที่ Plugin นี้เป็นเจ้าของสำหรับ `openclaw migrate`                                                                         |
| `gatewayMethodDispatch`          | `string[]` | สิทธิ์ที่สงวนไว้สำหรับเส้นทาง HTTP ของ Plugin ที่ผ่านการยืนยันตัวตน ซึ่งส่งต่อเมธอด Gateway ภายในโพรเซส                                  |
| `tools`                          | `string[]` | ชื่อเครื่องมือของเอเจนต์ที่ Plugin นี้เป็นเจ้าของ                                                                                                   |

`contracts.embeddedExtensionFactories` ยังคงเก็บไว้สำหรับโรงงานส่วนขยายที่ใช้เฉพาะกับเซิร์ฟเวอร์แอป Codex ซึ่งมาพร้อมระบบ การแปลงผลลัพธ์ของเครื่องมือที่มาพร้อมระบบควรประกาศ `contracts.agentToolResultMiddleware` และลงทะเบียนด้วย `api.registerAgentToolResultMiddleware(...)` แทน Plugin ที่ติดตั้งสามารถใช้ช่องทางมิดเดิลแวร์เดียวกันได้เฉพาะเมื่อเปิดใช้งานอย่างชัดเจน และเฉพาะกับรันไทม์ที่ประกาศไว้ใน `contracts.agentToolResultMiddleware`

Plugin ที่ติดตั้งซึ่งต้องใช้ระดับนโยบายก่อนใช้เครื่องมือที่โฮสต์เชื่อถือ ต้องประกาศรหัสภายในแต่ละรายการที่ลงทะเบียนใน `contracts.trustedToolPolicies` และต้องได้รับการเปิดใช้งานอย่างชัดเจน Plugin ที่มาพร้อมระบบยังคงใช้เส้นทางนโยบายที่เชื่อถือได้เดิม แต่ Plugin ที่ติดตั้งซึ่งมีรหัสนโยบายที่ไม่ได้ประกาศจะถูกปฏิเสธก่อนการลงทะเบียน รหัสนโยบายมีขอบเขตตาม Plugin ที่ลงทะเบียน ดังนั้น Plugin สองตัวสามารถประกาศและลงทะเบียน `workflow-budget` ได้ทั้งคู่ แต่ Plugin เดียวไม่สามารถลงทะเบียนรหัสภายในเดียวกันซ้ำสองครั้งได้

การลงทะเบียน `api.registerTool(...)` ขณะรันไทม์ต้องตรงกับ `contracts.tools` การค้นหาเครื่องมือใช้รายการนี้เพื่อโหลดเฉพาะรันไทม์ของ Plugin ที่สามารถเป็นเจ้าของเครื่องมือที่ร้องขอได้

Plugin ผู้ให้บริการที่นำ `resolveExternalAuthProfiles` ไปใช้ควรประกาศ `contracts.externalAuthProviders` ฮุกการยืนยันตัวตนภายนอกที่ไม่ได้ประกาศจะถูกละเว้น

Plugin ผู้ให้บริการที่นำทั้ง `resolveUsageAuth` และ `fetchUsageSnapshot` ไปใช้ควรประกาศรหัสผู้ให้บริการที่ค้นพบอัตโนมัติแต่ละรหัสใน `contracts.usageProviders` การค้นหาการใช้งานจะอ่านสัญญานี้ก่อนโหลดโค้ดรันไทม์ จากนั้นตรวจสอบฮุกทั้งสองหลังจากโหลดเฉพาะเจ้าของที่ประกาศไว้แล้ว

ผู้ให้บริการเวกเตอร์ฝังตัวทั่วไปควรประกาศ `contracts.embeddingProviders` สำหรับอะแดปเตอร์แต่ละตัวที่ลงทะเบียนด้วย `api.registerEmbeddingProvider(...)` ใช้สัญญาทั่วไปสำหรับการสร้างเวกเตอร์ที่นำกลับมาใช้ซ้ำได้ รวมถึงผู้ให้บริการที่การค้นหาหน่วยความจำใช้ `contracts.memoryEmbeddingProviders` เป็นความเข้ากันได้เฉพาะหน่วยความจำที่เลิกใช้แล้ว และจะคงอยู่เฉพาะระหว่างที่ผู้ให้บริการเดิมย้ายไปยังช่องทางผู้ให้บริการเวกเตอร์ฝังตัวทั่วไป

ผู้ให้บริการเวิร์กเกอร์ต้องประกาศรหัส `api.registerWorkerProvider(...)` แต่ละรายการใน `contracts.workerProviders` คอร์จะบันทึกเจตนาที่คงทนก่อนเรียก `provision` ผู้ให้บริการจะตรวจสอบการตั้งค่าก่อนจัดสรรทรัพยากรภายนอก และการเรียกซ้ำด้วยรหัสการดำเนินการเดียวกันต้องรับช่วงสัญญาเช่าเดิม คอร์ยังบันทึกสแนปช็อตการตั้งค่าที่ผ่านการตรวจสอบนั้น และส่งพร้อม `leaseId` ไปยัง `inspect({ leaseId, profile })` และ `destroy({ leaseId, profile })` รวมถึงหลังจากโปรไฟล์ที่ระบุชื่อถูกเปลี่ยนแปลงหรือลบแล้ว การทำลายเป็นแบบเรียกซ้ำได้โดยให้ผลลัพธ์เดิม การตรวจสอบส่งคืนยูเนียนสถานะแบบปิด `active` / `destroyed` / `unknown` และวัสดุคีย์ส่วนตัว SSH จะถูกอ้างอิงผ่าน `SecretRef` เท่านั้น ปลายทาง SSH ที่จัดเตรียมแล้วต้องมี `hostKey` สาธารณะจากผลลัพธ์การจัดเตรียมที่เชื่อถือได้ในรูปแบบ `algorithm base64` อย่างเคร่งครัด โดยไม่มีชื่อโฮสต์หรือความคิดเห็น เพื่อให้คอร์สามารถตรึงโฮสต์ก่อนเชื่อมต่อ ผู้ให้บริการที่สร้างการอ้างอิงข้อมูลประจำตัวแบบไดนามิกอาจนำ `resolveSshIdentity({ leaseId, profile, keyRef })` ที่มีอำนาจตัดสินเด็ดขาดไปใช้ ส่วนผู้ให้บริการที่ไม่มีเมธอดนี้จะใช้ตัวแก้ไขข้อมูลลับทั่วไปของคอร์ ค่า `unknown` ที่มีอำนาจตัดสินเด็ดขาดจะทำให้ระเบียนภายในที่ยังใช้งานอยู่เป็นกำพร้า และหลังจากคำขอทำลายถูกบันทึกแล้ว ค่านี้จะยืนยันว่าการรื้อถอนเสร็จสมบูรณ์

ปัจจุบัน `contracts.gatewayMethodDispatch` ยอมรับ `"authenticated-request"` นี่คือด่านรักษาความสะอาดของ API สำหรับเส้นทาง HTTP แบบเนทีฟของ Plugin ที่ตั้งใจส่งต่อเมธอดระนาบควบคุมของ Gateway ภายในโพรเซส ไม่ใช่แซนด์บ็อกซ์สำหรับป้องกัน Plugin แบบเนทีฟที่ประสงค์ร้าย ใช้เฉพาะกับพื้นผิวแบบมาพร้อมระบบหรือสำหรับผู้ปฏิบัติงานที่ผ่านการตรวจสอบอย่างเข้มงวด และกำหนดให้ใช้การยืนยันตัวตน HTTP ของ Gateway อยู่แล้ว เส้นทางที่มีสิทธิ์จะยังเข้าถึงได้ขณะที่การรับงานระดับรากของ Gateway ปิดอยู่ เฉพาะเมื่อเส้นทางนั้นประกาศทั้ง `auth: "gateway"` และ `gatewayRuntimeScopeSurface: "trusted-operator"` ที่เฉพาะเจาะจงกับเส้นทาง เส้นทางข้างเคียงทั่วไปจาก Plugin เดียวกันยังคงอยู่หลังขอบเขตการรับงาน วิธีนี้ทำให้ยังเข้าถึงสถานะการระงับและการทำงานต่อได้โดยไม่มอบสิทธิ์ข้ามการรับงานให้ทั้ง Plugin ควบคุมขอบเขตของการแยกวิเคราะห์และการจัดรูปแบบการตอบกลับไว้นอกการส่งต่อ งานที่มีสาระสำคัญหรือมีการแก้ไขต้องผ่านการส่งต่อเมธอด Gateway ซึ่งเป็นเจ้าของการบังคับใช้การรับงานและขอบเขต

## เอกสารอ้างอิง configContracts

ใช้ `configContracts` สำหรับพฤติกรรมการกำหนดค่าที่แมนิเฟสต์เป็นเจ้าของ ซึ่งตัวช่วยทั่วไปของคอร์ต้องใช้โดยไม่ต้องนำเข้ารันไทม์ของ Plugin ได้แก่ การตรวจจับแฟล็กอันตราย เป้าหมายการย้าย `SecretRef` และการจำกัดเส้นทางการกำหนดค่าแบบเก่า

```json
{
  "configContracts": {
    "compatibilityMigrationPaths": ["legacyProvider"],
    "compatibilityRuntimePaths": ["legacyProvider.webhook"],
    "dangerousFlags": [
      {
        "path": "accounts.*.allowUnverifiedSenders",
        "equals": true
      }
    ],
    "secretInputs": {
      "bundledDefaultEnabled": false,
      "paths": [
        {
          "path": "apiKey",
          "expected": "string"
        }
      ]
    }
  }
}
```

| ฟิลด์                         | จำเป็น | ชนิด       | ความหมาย                                                                                                                                                                                                                          |
| ----------------------------- | -------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `compatibilityMigrationPaths` | ไม่       | `string[]` | เส้นทางการกำหนดค่าที่สัมพันธ์กับราก ซึ่งบ่งชี้ว่าการย้ายความเข้ากันได้ในช่วงตั้งค่าของ Plugin นี้อาจมีผล ช่วยให้การอ่านการกำหนดค่ารันไทม์ทั่วไปข้ามพื้นผิวการตั้งค่าของ Plugin ทั้งหมดได้ เมื่อการกำหนดค่าไม่ได้อ้างถึง Plugin นั้นเลย                 |
| `compatibilityRuntimePaths`   | ไม่       | `string[]` | เส้นทางความเข้ากันได้ที่สัมพันธ์กับราก ซึ่ง Plugin นี้ให้บริการได้ระหว่างรันไทม์ก่อนที่โค้ด Plugin จะเปิดใช้งานอย่างสมบูรณ์ ใช้สำหรับพื้นผิวแบบเก่าที่ควรจำกัดชุดผู้สมัครที่มาพร้อมระบบโดยไม่ต้องนำเข้ารันไทม์ของ Plugin ที่เข้ากันได้ทุกตัว |
| `dangerousFlags`              | ไม่       | `object[]` | ค่าลิเทอรัลการกำหนดค่าที่ `openclaw doctor` ควรตั้งค่าสถานะว่าไม่ปลอดภัยหรือเป็นอันตรายเมื่อเปิดใช้งาน ดูด้านล่าง                                                                                                                                   |
| `secretInputs`                | ไม่       | `object`   | เส้นทางการกำหนดค่าภายใต้ `plugins.entries.<id>.config` ซึ่งรีจิสทรีเป้าหมายการย้าย/ตรวจสอบ `SecretRef` ควรถือว่าเป็นสตริงที่มีรูปแบบข้อมูลลับ ดูด้านล่าง                                                                                  |

แต่ละรายการ `dangerousFlags` รองรับ:

| ฟิลด์    | จำเป็น | ชนิด                                  | ความหมาย                                                                                                       |
| -------- | -------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `path`   | ใช่      | `string`                              | เส้นทางการกำหนดค่าที่คั่นด้วยจุด โดยสัมพันธ์กับ `plugins.entries.<id>.config` รองรับไวลด์การ์ด `*` สำหรับส่วนของแมป/อาร์เรย์ |
| `equals` | ใช่      | `string \| number \| boolean \| null` | ค่าลิเทอรัลที่ตรงกันทุกประการซึ่งระบุว่าค่าการกำหนดค่านี้เป็นอันตราย                                                            |

`secretInputs` รองรับ:

| ฟิลด์                   | จำเป็น | ชนิด       | ความหมาย                                                                                                                                                                                                   |
| ----------------------- | -------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `bundledDefaultEnabled` | ไม่       | `boolean`  | เขียนทับการเปิดใช้งานเริ่มต้นของ Plugin ที่รวมมาให้ เมื่อพิจารณาว่าพื้นผิว SecretRef นี้ทำงานอยู่หรือไม่ ใช้เมื่อ Plugin รวมมาให้ แต่พื้นผิวควรไม่ทำงานจนกว่าจะเปิดใช้งานอย่างชัดเจนในการกำหนดค่า |
| `paths`                 | ใช่      | `object[]` | พาธการกำหนดค่าที่มีรูปแบบเป็นข้อมูลลับ โดยแต่ละรายการมี `path` (คั่นด้วยจุด สัมพันธ์กับ `plugins.entries.<id>.config` และรองรับอักขระตัวแทน `*`) และ `expected` ซึ่งระบุหรือไม่ก็ได้ (ปัจจุบันรองรับเฉพาะ `"string"`) |

## ข้อมูลอ้างอิง `mediaUnderstandingProviderMetadata`

ใช้ `mediaUnderstandingProviderMetadata` เมื่อผู้ให้บริการทำความเข้าใจสื่อมีโมเดลเริ่มต้น ลำดับความสำคัญของทางเลือกสำรองสำหรับการยืนยันตัวตนอัตโนมัติ หรือการรองรับเอกสารแบบเนทีฟที่ตัวช่วยทั่วไปของแกนหลักต้องใช้ก่อนโหลดรันไทม์ นอกจากนี้ คีย์ต่าง ๆ ต้องประกาศไว้ใน `contracts.mediaUnderstandingProviders` ด้วย

```json
{
  "contracts": {
    "mediaUnderstandingProviders": ["example"]
  },
  "mediaUnderstandingProviderMetadata": {
    "example": {
      "capabilities": ["image", "audio"],
      "defaultModels": {
        "image": "example-vision-latest",
        "audio": "example-transcribe-latest"
      },
      "autoPriority": {
        "image": 40
      },
      "nativeDocumentInputs": ["pdf"],
      "documentModels": {
        "pdf": {
          "textExtraction": "example-doc-text-latest",
          "image": "example-doc-vision-latest"
        }
      }
    }
  }
}
```

รายการผู้ให้บริการแต่ละรายการสามารถมีข้อมูลต่อไปนี้:

| ฟิลด์                  | ชนิด                                                             | ความหมาย                                                                                                   |
| ---------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `capabilities`         | `("image" \| "audio" \| "video")[]`                              | ความสามารถด้านสื่อที่ผู้ให้บริการนี้เปิดให้ใช้                                                                    |
| `defaultModels`        | `Record<string, string>`                                         | ค่าเริ่มต้นที่จับคู่ความสามารถกับโมเดล ซึ่งใช้เมื่อการกำหนดค่าไม่ได้ระบุโมเดล                                         |
| `autoPriority`         | `Record<string, number>`                                         | ตัวเลขที่น้อยกว่าจะเรียงก่อน สำหรับทางเลือกสำรองของผู้ให้บริการโดยอัตโนมัติที่อิงข้อมูลประจำตัว                                    |
| `nativeDocumentInputs` | `"pdf"[]`                                                        | อินพุตเอกสารแบบเนทีฟที่ผู้ให้บริการรองรับ                                                               |
| `documentModels`       | `{ pdf?: { textExtraction?: string; image?: string \| false } }` | การเขียนทับโมเดลแยกตามชนิดเอกสาร ตั้งค่า `image: false` เพื่อปิดใช้งานการสกัดข้อมูลด้วยภาพสำหรับเอกสารชนิดนั้น |

## ข้อมูลอ้างอิง `channelConfigs`

ใช้ `channelConfigs` เมื่อ Plugin ช่องทางต้องการเมทาดาทาการกำหนดค่าที่มีต้นทุนต่ำก่อนโหลดรันไทม์ การค้นหาการตั้งค่า/สถานะช่องทางแบบอ่านอย่างเดียวสามารถใช้เมทาดาทานี้โดยตรงสำหรับช่องทางภายนอกที่กำหนดค่าไว้ เมื่อไม่มีรายการการตั้งค่า หรือเมื่อ `setup.requiresRuntime: false` ประกาศว่าไม่จำเป็นต้องใช้รันไทม์สำหรับการตั้งค่า

`channelConfigs` เป็นเมทาดาทาในแมนิเฟสต์ของ Plugin ไม่ใช่ส่วนการกำหนดค่าระดับบนสุดใหม่สำหรับผู้ใช้ ผู้ใช้ยังคงกำหนดค่าอินสแตนซ์ช่องทางภายใต้ `channels.<channel-id>` OpenClaw อ่านเมทาดาทาในแมนิเฟสต์เพื่อพิจารณาว่า Plugin ใดเป็นเจ้าของช่องทางที่กำหนดค่าไว้นั้น ก่อนที่โค้ดรันไทม์ของ Plugin จะทำงาน

สำหรับ Plugin ช่องทาง `configSchema` และ `channelConfigs` อธิบายพาธที่ต่างกัน:

- `configSchema` ตรวจสอบความถูกต้องของ `plugins.entries.<plugin-id>.config`
- `channelConfigs.<channel-id>.schema` ตรวจสอบความถูกต้องของ `channels.<channel-id>`

Plugin ที่ไม่ได้รวมมาให้และประกาศ `channels[]` ควรประกาศรายการ `channelConfigs` ที่ตรงกันด้วย หากไม่มีรายการเหล่านี้ OpenClaw ยังคงโหลด Plugin ได้ แต่พื้นผิวสคีมาการกำหนดค่า การตั้งค่า และ Control UI ในเส้นทางเริ่มต้นไม่สามารถทราบรูปแบบตัวเลือกที่ช่องทางเป็นเจ้าของได้จนกว่ารันไทม์ของ Plugin จะทำงาน

`channelConfigs.<channel-id>.commands.nativeCommandsAutoEnabled` และ `nativeSkillsAutoEnabled` สามารถประกาศค่าเริ่มต้น `auto` แบบคงที่สำหรับการตรวจสอบการกำหนดค่าคำสั่งที่ทำงานก่อนโหลดรันไทม์ของช่องทาง ช่องทางที่รวมมาให้ยังสามารถเผยแพร่ค่าเริ่มต้นเดียวกันผ่าน `package.json#openclaw.channel.commands` ควบคู่กับเมทาดาทาแค็ตตาล็อกช่องทางอื่นที่แพ็กเกจเป็นเจ้าของ

```json
{
  "channelConfigs": {
    "matrix": {
      "schema": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "homeserverUrl": { "type": "string" }
        }
      },
      "uiHints": {
        "homeserverUrl": {
          "label": "Homeserver URL",
          "placeholder": "https://matrix.example.com"
        }
      },
      "label": "Matrix",
      "description": "Matrix homeserver connection",
      "commands": {
        "nativeCommandsAutoEnabled": true,
        "nativeSkillsAutoEnabled": true
      },
      "preferOver": ["matrix-legacy"]
    }
  }
}
```

รายการช่องทางแต่ละรายการสามารถมีข้อมูลต่อไปนี้:

| ฟิลด์         | ชนิด                     | ความหมาย                                                                             |
| ------------- | ------------------------ | ----------------------------------------------------------------------------------------- |
| `schema`      | `object`                 | JSON Schema สำหรับ `channels.<id>` จำเป็นสำหรับรายการการกำหนดค่าช่องทางที่ประกาศไว้แต่ละรายการ         |
| `uiHints`     | `Record<string, object>` | ป้ายกำกับ UI/ข้อความตัวอย่าง/คำแนะนำเกี่ยวกับข้อมูลละเอียดอ่อนที่ระบุหรือไม่ก็ได้ สำหรับส่วนการกำหนดค่าช่องทางนั้น          |
| `label`       | `string`                 | ป้ายกำกับช่องทางที่รวมเข้ากับพื้นผิวตัวเลือกและการตรวจสอบเมื่อเมทาดาทารันไทม์ยังไม่พร้อม |
| `description` | `string`                 | คำอธิบายช่องทางแบบสั้นสำหรับพื้นผิวการตรวจสอบและแค็ตตาล็อก                               |
| `commands`    | `object`                 | ค่าเริ่มต้นอัตโนมัติแบบคงที่สำหรับคำสั่งเนทีฟและ Skills เนทีฟ เพื่อใช้ตรวจสอบการกำหนดค่าก่อนรันไทม์       |
| `preferOver`  | `string[]`               | รหัส Plugin แบบเก่าหรือที่มีลำดับความสำคัญต่ำกว่า ซึ่งช่องทางนี้ควรมีอันดับเหนือกว่าในพื้นผิวการเลือก    |

### การแทนที่ Plugin ช่องทางอื่น

ใช้ `preferOver` เมื่อ Plugin ของคุณเป็นเจ้าของที่ควรเลือกสำหรับรหัสช่องทางซึ่ง Plugin อื่นก็สามารถให้บริการได้เช่นกัน กรณีที่พบบ่อย ได้แก่ รหัส Plugin ที่เปลี่ยนชื่อ Plugin แบบสแตนด์อโลนที่มาแทน Plugin ที่รวมมาให้ หรือฟอร์กที่ยังได้รับการดูแลและคงรหัสช่องทางเดิมไว้เพื่อความเข้ากันได้ของการกำหนดค่า

```json
{
  "id": "acme-chat",
  "channels": ["chat"],
  "channelConfigs": {
    "chat": {
      "schema": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "webhookUrl": { "type": "string" }
        }
      },
      "preferOver": ["chat"]
    }
  }
}
```

เมื่อกำหนดค่า `channels.chat` แล้ว OpenClaw จะพิจารณาทั้งรหัสช่องทางและรหัส Plugin ที่ควรเลือก หาก Plugin ที่มีลำดับความสำคัญต่ำกว่าถูกเลือกเพียงเพราะรวมมาให้หรือเปิดใช้งานเป็นค่าเริ่มต้น OpenClaw จะปิดใช้งาน Plugin นั้นในการกำหนดค่ารันไทม์ที่มีผล เพื่อให้ Plugin เพียงรายการเดียวเป็นเจ้าของช่องทางและเครื่องมือของช่องทางนั้น การเลือกอย่างชัดเจนของผู้ใช้ยังคงมีผลเหนือกว่า: หากผู้ใช้เปิดใช้งาน Plugin ทั้งสองอย่างชัดเจน (ผ่าน `plugins.allow` หรือการกำหนดค่า `plugins.entries` ที่มีสาระสำคัญ) OpenClaw จะคงตัวเลือกนั้นไว้และรายงานการวินิจฉัยช่องทาง/เครื่องมือที่ซ้ำกัน แทนที่จะเปลี่ยนชุด Plugin ที่ร้องขอโดยไม่แจ้งให้ทราบ

จำกัดขอบเขต `preferOver` ให้ใช้เฉพาะกับรหัส Plugin ที่สามารถให้บริการช่องทางเดียวกันได้จริงเท่านั้น ค่านี้ไม่ใช่ฟิลด์ลำดับความสำคัญทั่วไป และไม่เปลี่ยนชื่อคีย์การกำหนดค่าของผู้ใช้

## ข้อมูลอ้างอิง `modelSupport`

ใช้ `modelSupport` เมื่อ OpenClaw ควรอนุมาน Plugin ผู้ให้บริการของคุณจากรหัสโมเดลแบบย่อ เช่น `gpt-5.6-sol` หรือ `claude-sonnet-4.6` ก่อนโหลดรันไทม์ของ Plugin

```json
{
  "modelSupport": {
    "modelPrefixes": ["gpt-", "o1", "o3", "o4"],
    "modelPatterns": ["^computer-use-preview"]
  }
}
```

OpenClaw ใช้ลำดับความสำคัญดังนี้:

- การอ้างอิง `provider/model` ที่ระบุอย่างชัดเจนจะใช้เมทาดาทาแมนิเฟสต์ `providers` ของเจ้าของ
- `modelPatterns` มีลำดับความสำคัญเหนือ `modelPrefixes`
- หาก Plugin ที่ไม่ได้รวมมาให้หนึ่งรายการและ Plugin ที่รวมมาให้หนึ่งรายการตรงกันทั้งคู่ Plugin ที่ไม่ได้รวมมาให้จะมีผลเหนือกว่า
- ความกำกวมที่เหลือจะถูกละเว้นจนกว่าผู้ใช้หรือการกำหนดค่าจะระบุผู้ให้บริการ

ฟิลด์:

| ฟิลด์           | ชนิด       | ความหมาย                                                                   |
| --------------- | ---------- | ------------------------------------------------------------------------------- |
| `modelPrefixes` | `string[]` | คำนำหน้าที่จับคู่กับรหัสโมเดลแบบย่อโดยใช้ `startsWith`                 |
| `modelPatterns` | `string[]` | ซอร์สของนิพจน์ปรกติที่จับคู่กับรหัสโมเดลแบบย่อหลังจากนำส่วนต่อท้ายโปรไฟล์ออก |

รายการ `modelPatterns` จะถูกคอมไพล์ผ่าน `compileSafeRegex` ซึ่งปฏิเสธรูปแบบที่มีการทำซ้ำซ้อนกัน (เช่น `(a+)+$`) รูปแบบที่ไม่ผ่านการตรวจสอบความปลอดภัยจะถูกข้ามโดยไม่แจ้งเตือน เช่นเดียวกับนิพจน์ปรกติที่มีไวยากรณ์ไม่ถูกต้อง ควรใช้รูปแบบที่เรียบง่ายและหลีกเลี่ยงตัวระบุจำนวนแบบซ้อนกัน

## ข้อมูลอ้างอิง `modelCatalog`

ใช้ `modelCatalog` เมื่อ OpenClaw ควรทราบเมทาดาทาโมเดลของผู้ให้บริการก่อนโหลดรันไทม์ของ Plugin นี่คือแหล่งข้อมูลที่แมนิเฟสต์เป็นเจ้าของสำหรับแถวแค็ตตาล็อกแบบคงที่ นามแฝงของผู้ให้บริการ กฎการระงับ และโหมดการค้นหา การรีเฟรชระหว่างรันไทม์ยังคงเป็นความรับผิดชอบของโค้ดรันไทม์ผู้ให้บริการ แต่แมนิเฟสต์จะแจ้งแกนหลักว่าจำเป็นต้องใช้รันไทม์เมื่อใด

```json
{
  "providers": ["openai"],
  "modelCatalog": {
    "providers": {
      "openai": {
        "baseUrl": "https://api.openai.com/v1",
        "api": "openai-responses",
        "models": [
          {
            "id": "gpt-5.4",
            "name": "GPT-5.4",
            "input": ["text", "image"],
            "reasoning": true,
            "contextWindow": 256000,
            "maxTokens": 128000,
            "cost": {
              "input": 1.25,
              "output": 10,
              "cacheRead": 0.125
            },
            "status": "available",
            "tags": ["default"]
          }
        ]
      }
    },
    "aliases": {
      "azure-openai-responses": {
        "provider": "openai",
        "api": "azure-openai-responses"
      }
    },
    "suppressions": [
      {
        "provider": "azure-openai-responses",
        "model": "gpt-5.3-codex-spark",
        "reason": "not available on Azure OpenAI Responses"
      }
    ],
    "discovery": {
      "openai": "static"
    }
  }
}
```

ฟิลด์ระดับบนสุด:

| ฟิลด์            | ชนิด                                                     | ความหมาย                                                                                               |
| ---------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `providers`      | `Record<string, object>`                                 | แถวแค็ตตาล็อกสำหรับรหัสผู้ให้บริการที่ Plugin นี้เป็นเจ้าของ คีย์ควรปรากฏใน `providers` ระดับบนสุดด้วย       |
| `aliases`        | `Record<string, object>`                                 | นามแฝงของผู้ให้บริการที่ควรแปลงเป็นผู้ให้บริการที่เป็นเจ้าของ สำหรับการวางแผนแค็ตตาล็อกหรือการระงับ              |
| `suppressions`   | `object[]`                                               | แถวโมเดลจากแหล่งอื่นที่ Plugin นี้ระงับด้วยเหตุผลเฉพาะของผู้ให้บริการ                  |
| `discovery`      | `Record<string, "static" \| "refreshable" \| "runtime">` | ระบุว่าสามารถอ่านแค็ตตาล็อกผู้ให้บริการจากเมทาดาทาในแมนิเฟสต์ รีเฟรชเข้าสู่แคช หรือต้องใช้รันไทม์ |
| `runtimeAugment` | `boolean`                                                | ตั้งเป็น `true` เฉพาะเมื่อรันไทม์ของผู้ให้บริการต้องเพิ่มแถวแค็ตตาล็อกหลังการวางแผนแมนิเฟสต์/การกำหนดค่า       |

`aliases` มีส่วนในการค้นหาความเป็นเจ้าของผู้ให้บริการสำหรับการวางแผนแค็ตตาล็อกโมเดล เป้าหมายของนามแฝงต้องเป็นผู้ให้บริการระดับบนสุดที่ Plugin เดียวกันเป็นเจ้าของ เมื่อรายการที่กรองตามผู้ให้บริการใช้นามแฝง OpenClaw จะสามารถอ่านแมนิเฟสต์ของเจ้าของและใช้ค่าการแทนที่ API/URL ฐานของนามแฝงได้โดยไม่ต้องโหลดรันไทม์ของผู้ให้บริการ นามแฝงจะไม่ขยายรายการแค็ตตาล็อกที่ไม่ได้กรอง รายการแบบกว้างจะแสดงเฉพาะแถวผู้ให้บริการมาตรฐานของเจ้าของเท่านั้น

`suppressions` ใช้แทนฮุก `suppressBuiltInModel` ของรันไทม์ผู้ให้บริการแบบเดิม รายการระงับจะมีผลเฉพาะเมื่อ Plugin เป็นเจ้าของผู้ให้บริการ หรือประกาศผู้ให้บริการเป็นคีย์ `modelCatalog.aliases` ที่ชี้ไปยังผู้ให้บริการที่เป็นเจ้าของ ระบบจะไม่เรียกฮุกระงับของรันไทม์ระหว่างการแปลงโมเดลอีกต่อไป

ฟิลด์ของผู้ให้บริการ:

| ฟิลด์                 | ชนิด                     | ความหมาย                                                                                                                                                                                                     |
| --------------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `baseUrl`             | `string`                 | URL ฐานเริ่มต้นที่ระบุหรือไม่ก็ได้สำหรับโมเดลในแค็ตตาล็อกผู้ให้บริการนี้                                                                                                                                                    |
| `api`                 | `ModelApi`               | อะแดปเตอร์ API เริ่มต้นที่ระบุหรือไม่ก็ได้สำหรับโมเดลในแค็ตตาล็อกผู้ให้บริการนี้                                                                                                                                                 |
| `headers`             | `Record<string, string>` | ส่วนหัวแบบคงที่ที่ระบุหรือไม่ก็ได้ซึ่งใช้กับแค็ตตาล็อกผู้ให้บริการนี้                                                                                                                                                      |
| `defaultUtilityModel` | `string`                 | รหัสโมเดลขนาดเล็กที่ผู้ให้บริการแนะนำซึ่งระบุหรือไม่ก็ได้ สำหรับงานอรรถประโยชน์ภายในระยะสั้น (ชื่อเรื่อง การบรรยายความคืบหน้า) ใช้เมื่อไม่ได้ตั้งค่า `agents.defaults.utilityModel` และผู้ให้บริการนี้ให้บริการโมเดลหลักของเอเจนต์ |
| `models`              | `object[]`               | แถวโมเดลที่จำเป็น แถวที่ไม่มี `id` จะถูกละเว้น                                                                                                                                                            |

ฟิลด์ของโมเดล:

| ฟิลด์              | ชนิด                                                           | ความหมาย                                                               |
| ------------------ | -------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `id`               | `string`                                                       | รหัสโมเดลภายในผู้ให้บริการ โดยไม่มีคำนำหน้า `provider/`                    |
| `name`             | `string`                                                       | ชื่อที่ใช้แสดงซึ่งระบุหรือไม่ก็ได้                                                      |
| `api`              | `ModelApi`                                                     | ค่าการแทนที่ API รายโมเดลซึ่งระบุหรือไม่ก็ได้                                            |
| `baseUrl`          | `string`                                                       | ค่าการแทนที่ URL ฐานรายโมเดลซึ่งระบุหรือไม่ก็ได้                                       |
| `headers`          | `Record<string, string>`                                       | ส่วนหัวแบบคงที่รายโมเดลซึ่งระบุหรือไม่ก็ได้                                          |
| `input`            | `Array<"text" \| "image" \| "document">`                       | รูปแบบข้อมูลที่โมเดลยอมรับ ค่าอื่นจะถูกตัดทิ้งโดยไม่แจ้งเตือน            |
| `reasoning`        | `boolean`                                                      | ระบุว่าโมเดลเปิดเผยพฤติกรรมการให้เหตุผลหรือไม่                               |
| `contextWindow`    | `number`                                                       | หน้าต่างบริบทดั้งเดิมของผู้ให้บริการ                                             |
| `contextTokens`    | `number`                                                       | ขีดจำกัดบริบทรันไทม์ที่มีผลซึ่งระบุหรือไม่ก็ได้ เมื่อแตกต่างจาก `contextWindow` |
| `maxTokens`        | `number`                                                       | จำนวนโทเค็นเอาต์พุตสูงสุดเมื่อทราบ                                           |
| `thinkingLevelMap` | `Record<string, string \| null>`                               | ค่าการแทนที่รหัสโมเดลหรือพารามิเตอร์รายระดับการคิดซึ่งระบุหรือไม่ก็ได้                    |
| `cost`             | `object`                                                       | ราคาเป็นดอลลาร์สหรัฐต่อหนึ่งล้านโทเค็นซึ่งระบุหรือไม่ก็ได้ รวมถึง `tieredPricing` ที่ระบุหรือไม่ก็ได้ |
| `compat`           | `object`                                                       | แฟล็กความเข้ากันได้ซึ่งระบุหรือไม่ก็ได้ที่ตรงกับความเข้ากันได้ของการกำหนดค่าโมเดล OpenClaw  |
| `mediaInput`       | `object`                                                       | การกำหนดค่าอินพุตรายรูปแบบซึ่งระบุหรือไม่ก็ได้ ปัจจุบันรองรับเฉพาะรูปภาพ                   |
| `status`           | `"available"` \| `"preview"` \| `"deprecated"` \| `"disabled"` | สถานะในรายการ ให้ระงับเฉพาะเมื่อแถวนั้นต้องไม่ปรากฏเลย          |
| `statusReason`     | `string`                                                       | เหตุผลที่ระบุหรือไม่ก็ได้ซึ่งแสดงร่วมกับสถานะที่ไม่พร้อมใช้งาน                            |
| `replaces`         | `string[]`                                                     | รหัสโมเดลภายในผู้ให้บริการรุ่นเก่าที่โมเดลนี้เข้ามาแทนที่                       |
| `replacedBy`       | `string`                                                       | รหัสโมเดลภายในผู้ให้บริการที่ใช้ทดแทนสำหรับแถวที่เลิกใช้แล้ว                    |
| `tags`             | `string[]`                                                     | แท็กที่คงที่ซึ่งใช้โดยตัวเลือกและตัวกรอง                                    |

ฟิลด์การระงับ:

| ฟิลด์                      | ชนิด       | ความหมาย                                                                                             |
| -------------------------- | ---------- | --------------------------------------------------------------------------------------------------------- |
| `provider`                 | `string`   | รหัสผู้ให้บริการของแถวต้นทางที่ต้องการระงับ Plugin นี้ต้องเป็นเจ้าของ หรือผู้ให้บริการต้องประกาศเป็นนามแฝงที่เป็นเจ้าของ |
| `model`                    | `string`   | รหัสโมเดลภายในผู้ให้บริการที่ต้องการระงับ                                                                      |
| `reason`                   | `string`   | ข้อความที่ระบุหรือไม่ก็ได้ซึ่งแสดงเมื่อมีการร้องขอแถวที่ถูกระงับโดยตรง                                     |
| `when.baseUrlHosts`        | `string[]` | รายการโฮสต์ URL ฐานของผู้ให้บริการที่มีผลซึ่งระบุหรือไม่ก็ได้ โดยต้องตรงก่อนจึงจะใช้การระงับ               |
| `when.providerConfigApiIn` | `string[]` | รายการค่า `api` ที่ตรงกันทุกประการจากการกำหนดค่าผู้ให้บริการซึ่งระบุหรือไม่ก็ได้ โดยต้องตรงก่อนจึงจะใช้การระงับ              |

อย่าใส่ข้อมูลที่ใช้เฉพาะรันไทม์ใน `modelCatalog` ใช้ `static` เฉพาะเมื่อแถวในแมนิเฟสต์สมบูรณ์เพียงพอให้รายการที่กรองตามผู้ให้บริการและพื้นผิวตัวเลือกข้ามการค้นหารีจิสทรี/รันไทม์ได้ ใช้ `refreshable` เมื่อแถวในแมนิเฟสต์เป็นข้อมูลตั้งต้นหรือข้อมูลเสริมที่มีประโยชน์และแสดงในรายการได้ แต่การรีเฟรช/แคชสามารถเพิ่มแถวได้ภายหลัง แถวแบบรีเฟรชได้ไม่ถือเป็นแหล่งข้อมูลที่เชื่อถือได้โดยลำพัง ใช้ `runtime` เมื่อ OpenClaw ต้องโหลดรันไทม์ของผู้ให้บริการเพื่อให้ทราบรายการ

## ข้อมูลอ้างอิง modelIdNormalization

ใช้ `modelIdNormalization` สำหรับการจัดรูปแบบรหัสโมเดลที่ผู้ให้บริการเป็นเจ้าของแบบต้นทุนต่ำ ซึ่งต้องเกิดขึ้นก่อนโหลดรันไทม์ของผู้ให้บริการ วิธีนี้ช่วยเก็บนามแฝง เช่น ชื่อโมเดลแบบสั้น รหัสเดิมภายในผู้ให้บริการ และกฎคำนำหน้าพร็อกซี ไว้ในแมนิเฟสต์ของ Plugin เจ้าของ แทนที่จะอยู่ในตารางการเลือกโมเดลของแกนหลัก

```json
{
  "providers": ["anthropic", "openrouter"],
  "modelIdNormalization": {
    "providers": {
      "anthropic": {
        "aliases": {
          "sonnet-4.6": "claude-sonnet-4-6"
        }
      },
      "openrouter": {
        "prefixWhenBare": "openrouter"
      }
    }
  }
}
```

ฟิลด์ของผู้ให้บริการ:

| ฟิลด์                                | ชนิด                    | ความหมาย                                                                             |
| ------------------------------------ | ----------------------- | ----------------------------------------------------------------------------------------- |
| `aliases`                            | `Record<string,string>` | นามแฝงรหัสโมเดลแบบตรงกันทุกประการโดยไม่คำนึงถึงตัวพิมพ์เล็ก-ใหญ่ ค่าจะถูกส่งคืนตามที่เขียนไว้                  |
| `stripPrefixes`                      | `string[]`              | คำนำหน้าที่ต้องนำออกก่อนค้นหานามแฝง มีประโยชน์สำหรับการซ้ำซ้อนของผู้ให้บริการ/โมเดลแบบเดิม     |
| `prefixWhenBare`                     | `string`                | คำนำหน้าที่ต้องเพิ่มเมื่อรหัสโมเดลที่จัดรูปแบบแล้วไม่มี `/` อยู่                  |
| `prefixWhenBareAfterAliasStartsWith` | `object[]`              | กฎคำนำหน้ารหัสเปล่าแบบมีเงื่อนไขหลังค้นหานามแฝง โดยใช้ `modelPrefix` และ `prefix` เป็นคีย์ |

## ข้อมูลอ้างอิง providerEndpoints

ใช้ `providerEndpoints` สำหรับการจำแนกปลายทางที่นโยบายคำขอทั่วไปต้องทราบก่อนโหลดรันไทม์ของผู้ให้บริการ แกนหลักยังคงเป็นเจ้าของความหมายของ `endpointClass` แต่ละค่า ส่วนแมนิเฟสต์ของ Plugin เป็นเจ้าของเมทาดาทาโฮสต์และ URL ฐาน

Plugin ผู้ให้บริการที่แยกออกเป็นภายนอกอย่างเป็นทางการจะไม่รวมอยู่ในชุดแจกจ่ายแกนหลัก ดังนั้น
แมนิเฟสต์ของ Plugin เหล่านั้นจะมองไม่เห็นจนกว่าจะติดตั้ง `providerEndpoints` ของ Plugin เหล่านั้น
ต้องทำสำเนาไว้ใน `scripts/lib/official-external-provider-catalog.json` ด้วย เพื่อให้
การจำแนกปลายทางยังทำงานได้โดยไม่มี Plugin โดยมีการทดสอบสัญญา
คอยบังคับให้ข้อมูลสำเนาตรงกัน

ฟิลด์ของปลายทาง:

| ฟิลด์                          | ชนิด       | ความหมาย                                                                                  |
| ------------------------------ | ---------- | ---------------------------------------------------------------------------------------------- |
| `endpointClass`                | `string`   | คลาสเอนด์พอยต์หลักที่รู้จัก เช่น `openrouter`, `moonshot-native` หรือ `google-vertex`        |
| `hosts`                        | `string[]` | ชื่อโฮสต์ที่ตรงกันทุกอักขระซึ่งแมปกับคลาสเอนด์พอยต์                                                |
| `hostSuffixes`                 | `string[]` | ส่วนต่อท้ายของโฮสต์ที่แมปกับคลาสเอนด์พอยต์ เติม `.` นำหน้าเพื่อจับคู่เฉพาะส่วนต่อท้ายของโดเมน |
| `baseUrls`                     | `string[]` | URL ฐาน HTTP(S) ที่ปรับรูปแบบมาตรฐานและตรงกันทุกอักขระ ซึ่งแมปกับคลาสเอนด์พอยต์                             |
| `googleVertexRegion`           | `string`   | ภูมิภาค Google Vertex แบบคงที่สำหรับโฮสต์ส่วนกลางที่ตรงกันทุกอักขระ                                            |
| `googleVertexRegionHostSuffix` | `string`   | ส่วนต่อท้ายที่จะตัดออกจากโฮสต์ที่ตรงกัน เพื่อแสดงคำนำหน้าภูมิภาค Google Vertex                 |

## ข้อมูลอ้างอิง providerRequest

ใช้ `providerRequest` สำหรับเมทาดาทาความเข้ากันได้ของคำขอที่ตรวจสอบได้โดยมีต้นทุนต่ำ ซึ่งนโยบายคำขอทั่วไปต้องใช้โดยไม่ต้องโหลดรันไทม์ของผู้ให้บริการ เก็บการเขียนเพย์โหลดใหม่ที่เฉพาะเจาะจงกับพฤติกรรมไว้ในฮุกของรันไทม์ผู้ให้บริการหรือตัวช่วยที่ใช้ร่วมกันในตระกูลผู้ให้บริการ

```json
{
  "providerRequest": {
    "providers": {
      "vllm": {
        "family": "vllm",
        "openAICompletions": {
          "supportsStreamingUsage": true
        }
      }
    }
  }
}
```

ฟิลด์ของผู้ให้บริการ:

| ฟิลด์                 | ชนิด         | ความหมาย                                                                          |
| --------------------- | ------------ | -------------------------------------------------------------------------------------- |
| `family`              | `string`     | ป้ายกำกับตระกูลผู้ให้บริการที่ใช้ในการตัดสินใจเกี่ยวกับความเข้ากันได้ของคำขอทั่วไปและการวินิจฉัย |
| `compatibilityFamily` | `"moonshot"` | กลุ่มความเข้ากันได้ของตระกูลผู้ให้บริการที่ระบุหรือไม่ก็ได้ สำหรับตัวช่วยคำขอที่ใช้ร่วมกัน              |
| `openAICompletions`   | `object`     | แฟล็กคำขอการเติมข้อความที่เข้ากันได้กับ OpenAI ซึ่งปัจจุบันคือ `supportsStreamingUsage`       |

## ข้อมูลอ้างอิง secretProviderIntegrations

ใช้ `secretProviderIntegrations` เมื่อ Plugin สามารถเผยแพร่ค่าที่ตั้งไว้ล่วงหน้าของผู้ให้บริการ exec สำหรับ SecretRef ที่นำกลับมาใช้ใหม่ได้ OpenClaw อ่านเมทาดาทานี้ก่อนโหลดรันไทม์ของ Plugin จัดเก็บความเป็นเจ้าของ Plugin ไว้ใน `secrets.providers.<alias>.pluginIntegration` และปล่อยให้การแก้ค่า secret จริงเป็นหน้าที่ของรันไทม์ SecretRef ค่าที่ตั้งไว้ล่วงหน้าจะแสดงเฉพาะสำหรับ Plugin ที่รวมมากับระบบและ Plugin ที่ติดตั้งซึ่งค้นพบจากรากการติดตั้ง Plugin ที่มีการจัดการ เช่น การติดตั้งผ่าน git และ ClawHub

```json
{
  "secretProviderIntegrations": {
    "secret-store": {
      "providerAlias": "team-secrets",
      "displayName": "Team secrets",
      "source": "exec",
      "command": "${node}",
      "args": ["./bin/resolve-secrets.mjs"]
    }
  }
}
```

คีย์ของแมปคือรหัสการผสานรวม หากละเว้น `providerAlias` OpenClaw จะใช้รหัสการผสานรวมเป็นนามแฝงผู้ให้บริการ SecretRef นามแฝงผู้ให้บริการต้องตรงกับรูปแบบนามแฝงผู้ให้บริการ SecretRef ปกติ เช่น `team-secrets` หรือ `onepassword-work`

เมื่อผู้ดำเนินการเลือกค่าที่ตั้งไว้ล่วงหน้า OpenClaw จะเขียนการอ้างอิงผู้ให้บริการดังนี้:

```json
{
  "secrets": {
    "providers": {
      "team-secrets": {
        "source": "exec",
        "pluginIntegration": {
          "pluginId": "acme-secrets",
          "integrationId": "secret-store"
        }
      }
    }
  }
}
```

เมื่อเริ่มต้นหรือโหลดใหม่ OpenClaw จะแก้ผู้ให้บริการนั้นโดยโหลดเมทาดาทามานิเฟสต์ปัจจุบันของ Plugin ตรวจสอบว่า Plugin เจ้าของได้รับการติดตั้งและทำงานอยู่ และสร้างคำสั่ง exec จากมานิเฟสต์ การปิดใช้งานหรือลบ Plugin จะเพิกถอนผู้ให้บริการสำหรับ SecretRef ที่ใช้งานอยู่ ผู้ดำเนินการที่ต้องการการกำหนดค่า exec แบบสแตนด์อโลนยังคงสามารถเขียนผู้ให้บริการ `command`/`args` ด้วยตนเองได้โดยตรง

ขณะนี้รองรับเฉพาะค่าที่ตั้งไว้ล่วงหน้า `source: "exec"` เท่านั้น `command` ต้องเป็น `${node}` และ `args[0]` ต้องเป็นสคริปต์ตัวแก้ค่าที่ขึ้นต้นด้วย `./` และมีพาธสัมพัทธ์จากรากของ Plugin OpenClaw จะสร้างค่าเหล่านี้เมื่อเริ่มต้นหรือโหลดใหม่ให้เป็นไฟล์ปฏิบัติการ Node ปัจจุบันและพาธแบบสัมบูรณ์ของสคริปต์ภายใน Plugin ตัวเลือก Node เช่น `--require`, `--import`, `--loader`, `--env-file`, `--eval` และ `--print` ไม่ได้เป็นส่วนหนึ่งของสัญญาค่าที่ตั้งไว้ล่วงหน้าของมานิเฟสต์ ผู้ดำเนินการที่ต้องการคำสั่งซึ่งไม่ใช่ Node สามารถกำหนดค่าผู้ให้บริการ exec แบบสแตนด์อโลนด้วยตนเองได้โดยตรง

OpenClaw สร้าง `trustedDirs` สำหรับค่าที่ตั้งไว้ล่วงหน้าของมานิเฟสต์จากรากของ Plugin และสำหรับค่าที่ตั้งไว้ล่วงหน้า `${node}` จะรวมไดเรกทอรีของไฟล์ปฏิบัติการ Node ปัจจุบันด้วย `trustedDirs` ที่ระบุในมานิเฟสต์จะถูกละเว้น ตัวเลือกผู้ให้บริการ exec อื่น ๆ เช่น `timeoutMs`, `noOutputTimeoutMs`, `maxOutputBytes`, `jsonOnly`, `env`, `passEnv` และ `allowInsecurePath` จะถูกส่งต่อไปยังการกำหนดค่าผู้ให้บริการ exec ของ SecretRef ตามปกติ

## ข้อมูลอ้างอิง modelPricing

ใช้ `modelPricing` เมื่อผู้ให้บริการต้องควบคุมพฤติกรรมการกำหนดราคาในระนาบควบคุมก่อนโหลดรันไทม์ แคชการกำหนดราคาของ Gateway จะอ่านเมทาดาทานี้โดยไม่อิมพอร์ตโค้ดรันไทม์ของผู้ให้บริการ

```json
{
  "providers": ["ollama", "openrouter"],
  "modelPricing": {
    "providers": {
      "ollama": {
        "external": false
      },
      "openrouter": {
        "openRouter": {
          "passthroughProviderModel": true
        },
        "liteLLM": false
      }
    }
  }
}
```

ฟิลด์ของผู้ให้บริการ:

| ฟิลด์        | ชนิด              | ความหมาย                                                                                      |
| ------------ | ----------------- | -------------------------------------------------------------------------------------------------- |
| `external`   | `boolean`         | ตั้งค่าเป็น `false` สำหรับผู้ให้บริการในเครื่องหรือที่โฮสต์เอง ซึ่งต้องไม่ดึงข้อมูลราคาจาก OpenRouter หรือ LiteLLM |
| `openRouter` | `false \| object` | การแมปสำหรับค้นหาราคาจาก OpenRouter ค่า `false` จะปิดการค้นหาจาก OpenRouter สำหรับผู้ให้บริการนี้           |
| `liteLLM`    | `false \| object` | การแมปสำหรับค้นหาราคาจาก LiteLLM ค่า `false` จะปิดการค้นหาจาก LiteLLM สำหรับผู้ให้บริการนี้                 |

ฟิลด์ของแหล่งข้อมูล:

| ฟิลด์                      | ชนิด               | ความหมาย                                                                                                        |
| -------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------- |
| `provider`                 | `string`           | รหัสผู้ให้บริการในแค็ตตาล็อกภายนอกเมื่อแตกต่างจากรหัสผู้ให้บริการของ OpenClaw เช่น `z-ai` สำหรับผู้ให้บริการ `zai` |
| `passthroughProviderModel` | `boolean`          | ถือว่ารหัสโมเดลที่มีเครื่องหมายทับเป็นการอ้างอิงผู้ให้บริการ/โมเดลแบบซ้อน เหมาะสำหรับผู้ให้บริการพร็อกซี เช่น OpenRouter       |
| `modelIdTransforms`        | `"version-dots"[]` | รูปแบบรหัสโมเดลเพิ่มเติมสำหรับแค็ตตาล็อกภายนอก `version-dots` จะลองใช้รหัสเวอร์ชันแบบจุด เช่น `claude-opus-4.6`            |

### ดัชนีผู้ให้บริการของ OpenClaw

ดัชนีผู้ให้บริการของ OpenClaw คือเมทาดาทาตัวอย่างที่ OpenClaw เป็นเจ้าของ สำหรับผู้ให้บริการซึ่ง Plugin อาจยังไม่ได้รับการติดตั้ง ดัชนีนี้ไม่ใช่ส่วนหนึ่งของมานิเฟสต์ Plugin มานิเฟสต์ Plugin ยังคงเป็นแหล่งข้อมูลหลักของ Plugin ที่ติดตั้งแล้ว ดัชนีผู้ให้บริการคือสัญญาสำรองภายในที่พื้นผิวสำหรับผู้ให้บริการที่ติดตั้งได้และตัวเลือกโมเดลก่อนติดตั้งในอนาคตจะใช้ เมื่อ Plugin ของผู้ให้บริการยังไม่ได้รับการติดตั้ง

ลำดับอำนาจของแค็ตตาล็อก:

1. การกำหนดค่าของผู้ใช้
2. `modelCatalog` ในมานิเฟสต์ของ Plugin ที่ติดตั้ง
3. แคชแค็ตตาล็อกโมเดลจากการรีเฟรชอย่างชัดเจน
4. แถวตัวอย่างจากดัชนีผู้ให้บริการของ OpenClaw

ดัชนีผู้ให้บริการต้องไม่มี secret สถานะการเปิดใช้งาน ฮุกรันไทม์ หรือข้อมูลโมเดลสดที่เฉพาะเจาะจงกับบัญชี แค็ตตาล็อกตัวอย่างใช้รูปแบบแถวผู้ให้บริการ `modelCatalog` เดียวกับมานิเฟสต์ Plugin แต่ควรจำกัดไว้เฉพาะเมทาดาทาการแสดงผลที่เสถียร เว้นแต่ฟิลด์อะแดปเตอร์รันไทม์ เช่น `api`, `baseUrl`, การกำหนดราคา หรือแฟล็กความเข้ากันได้ จะถูกตั้งใจให้สอดคล้องกับมานิเฟสต์ของ Plugin ที่ติดตั้ง ผู้ให้บริการที่มีการค้นหา `/models` แบบสดควรเขียนแถวที่รีเฟรชผ่านพาธแคชแค็ตตาล็อกโมเดลแบบชัดเจน แทนที่จะให้การแสดงรายการหรือการเริ่มต้นใช้งานตามปกติเรียก API ของผู้ให้บริการ

รายการในดัชนีผู้ให้บริการอาจมีเมทาดาทา Plugin ที่ติดตั้งได้ สำหรับผู้ให้บริการซึ่ง Plugin ถูกย้ายออกจากแกนหลักหรือยังไม่ได้รับการติดตั้ง เมทาดาทานี้สะท้อนรูปแบบแค็ตตาล็อกช่องทาง ได้แก่ ชื่อแพ็กเกจ ข้อกำหนดการติดตั้ง npm ค่าความสมบูรณ์ที่คาดไว้ และป้ายกำกับตัวเลือกการยืนยันตัวตนที่ตรวจสอบได้โดยมีต้นทุนต่ำ ซึ่งเพียงพอสำหรับแสดงตัวเลือกการตั้งค่าที่ติดตั้งได้ เมื่อติดตั้ง Plugin แล้ว มานิเฟสต์ของ Plugin จะมีลำดับความสำคัญเหนือกว่า และรายการในดัชนีผู้ให้บริการจะถูกละเว้นสำหรับผู้ให้บริการนั้น

`openclaw doctor --fix` จะย้ายคีย์ความสามารถระดับบนสุดแบบเก่าของมานิเฟสต์ชุดเล็กที่กำหนดตายตัวไปไว้ใน `contracts.*` ได้แก่ `speechProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders` และ `tools` คีย์เหล่านี้ทั้งหมด (รวมถึงรายการความสามารถอื่นใด) จะไม่ถูกอ่านเป็นฟิลด์ระดับบนสุดของมานิเฟสต์อีกต่อไป การโหลดมานิเฟสต์ตามปกติจะรู้จักคีย์เหล่านี้เฉพาะภายใต้ `contracts` เท่านั้น

## มานิเฟสต์เทียบกับ package.json

ไฟล์ทั้งสองมีหน้าที่ต่างกัน:

| ไฟล์                   | ใช้สำหรับ                                                                                                                       |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `openclaw.plugin.json` | การค้นพบ การตรวจสอบความถูกต้องของการกำหนดค่า เมทาดาทาตัวเลือกการยืนยันตัวตน และคำแนะนำ UI ที่ต้องมีอยู่ก่อนโค้ด Plugin ทำงาน                         |
| `package.json`         | เมทาดาทา npm การติดตั้งการขึ้นต่อกัน และบล็อก `openclaw` ที่ใช้สำหรับจุดเริ่มต้น เงื่อนไขการติดตั้ง การตั้งค่า หรือเมทาดาทาแค็ตตาล็อก |

หากไม่แน่ใจว่าเมทาดาทาส่วนหนึ่งควรอยู่ที่ใด ให้ใช้กฎนี้:

- หาก OpenClaw ต้องทราบข้อมูลนั้นก่อนโหลดโค้ด Plugin ให้ใส่ไว้ใน `openclaw.plugin.json`
- หากข้อมูลนั้นเกี่ยวกับการจัดแพ็กเกจ ไฟล์จุดเริ่มต้น หรือพฤติกรรมการติดตั้ง npm ให้ใส่ไว้ใน `package.json`

### ฟิลด์ package.json ที่มีผลต่อการค้นพบ

เมทาดาทา Plugin ก่อนรันไทม์บางส่วนตั้งใจให้อยู่ใน `package.json` ภายใต้บล็อก `openclaw` แทนที่จะอยู่ใน `openclaw.plugin.json` โดย `openclaw.bundle` และ `openclaw.bundle.json` ไม่ใช่สัญญา Plugin ของ OpenClaw แต่ Plugin แบบเนทีฟต้องใช้ `openclaw.plugin.json` ร่วมกับฟิลด์ `package.json#openclaw` ที่รองรับด้านล่าง

ตัวอย่างสำคัญ:

| ฟิลด์                                                                                      | ความหมาย                                                                                                                                                                        |
| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `openclaw.extensions`                                                                      | ประกาศจุดเริ่มต้นของ Plugin แบบเนทีฟ ต้องอยู่ภายในไดเรกทอรีแพ็กเกจ Plugin                                                                                                   |
| `openclaw.runtimeExtensions`                                                               | ประกาศจุดเริ่มต้นรันไทม์ JavaScript ที่บิลด์แล้วสำหรับแพ็กเกจที่ติดตั้ง ต้องอยู่ภายในไดเรกทอรีแพ็กเกจ Plugin                                                                 |
| `openclaw.setupEntry`                                                                      | จุดเริ่มต้นแบบเบาที่ใช้เฉพาะการตั้งค่า ระหว่างการเริ่มต้นใช้งาน การเริ่มช่องทางแบบเลื่อนเวลา และการตรวจหาสถานะช่องทาง/SecretRef แบบอ่านอย่างเดียว ต้องอยู่ภายในไดเรกทอรีแพ็กเกจ Plugin |
| `openclaw.runtimeSetupEntry`                                                               | ประกาศจุดเริ่มต้นการตั้งค่า JavaScript ที่บิลด์แล้วสำหรับแพ็กเกจที่ติดตั้ง ต้องมี `setupEntry` ต้องมีอยู่จริง และต้องอยู่ภายในไดเรกทอรีแพ็กเกจ Plugin                         |
| `openclaw.channel`                                                                         | เมทาดาทาแค็ตตาล็อกช่องทางที่มีต้นทุนต่ำ เช่น ป้ายกำกับ พาธเอกสาร นามแฝง และข้อความสำหรับการเลือก                                                                                                 |
| `openclaw.channel.commands`                                                                | เมทาดาทาแบบคงที่ของคำสั่งเนทีฟและค่าเริ่มต้นอัตโนมัติของ Skills เนทีฟ ซึ่งใช้โดยส่วนกำหนดค่า การตรวจสอบ และรายการคำสั่งก่อนโหลดรันไทม์ช่องทาง                                          |
| `openclaw.channel.configuredState`                                                         | เมทาดาทาตัวตรวจสอบสถานะการกำหนดค่าแบบเบา ซึ่งตอบได้ว่า "มีการตั้งค่าเฉพาะผ่านตัวแปรสภาพแวดล้อมอยู่แล้วหรือไม่" โดยไม่ต้องโหลดรันไทม์ช่องทางทั้งหมด                                         |
| `openclaw.channel.persistedAuthState`                                                      | เมทาดาทาตัวตรวจสอบสถานะการยืนยันตัวตนที่จัดเก็บไว้แบบเบา ซึ่งตอบได้ว่า "มีสิ่งใดลงชื่อเข้าใช้อยู่แล้วหรือไม่" โดยไม่ต้องโหลดรันไทม์ช่องทางทั้งหมด                                               |
| `openclaw.install.clawhubSpec` / `openclaw.install.npmSpec` / `openclaw.install.localPath` | คำแนะนำการติดตั้ง/อัปเดตสำหรับ Plugin ที่รวมมากับระบบและ Plugin ที่เผยแพร่ภายนอก                                                                                                                   |
| `openclaw.install.defaultChoice`                                                           | เส้นทางติดตั้งที่แนะนำเมื่อมีแหล่งติดตั้งหลายแหล่ง                                                                                                                  |
| `openclaw.install.minHostVersion`                                                          | เวอร์ชันโฮสต์ OpenClaw ต่ำสุดที่รองรับ โดยใช้ขอบเขตล่างแบบ semver เช่น `>=2026.3.22` หรือ `>=2026.5.1-beta.1`                                                                             |
| `openclaw.compat.pluginApi`                                                                | ช่วง API ของ Plugin OpenClaw ต่ำสุดที่แพ็กเกจนี้ต้องใช้ โดยใช้ขอบเขตล่างแบบ semver เช่น `>=2026.5.27`                                                                                 |
| `openclaw.install.expectedIntegrity`                                                       | สตริงความสมบูรณ์ของ npm dist ที่คาดไว้ เช่น `sha512-...` ขั้นตอนติดตั้งและอัปเดตจะตรวจสอบอาร์ติแฟกต์ที่ดึงมากับค่านี้                                                            |
| `openclaw.install.allowInvalidConfigRecovery`                                              | อนุญาตเส้นทางกู้คืนแบบจำกัดด้วยการติดตั้ง Plugin ที่รวมมากับระบบใหม่ เมื่อการกำหนดค่าไม่ถูกต้อง                                                                                                       |
| `openclaw.install.requiredPlatformPackages`                                                | นามแฝงแพ็กเกจ npm ที่ต้องปรากฏเมื่อข้อจำกัดแพลตฟอร์มใน lockfile ตรงกับโฮสต์ปัจจุบัน                                                                           |
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen`                          | ทำให้พื้นผิวช่องทางของรันไทม์การตั้งค่าโหลดได้ก่อนเริ่มรับฟัง จากนั้นเลื่อนการโหลด Plugin ช่องทางที่กำหนดค่าไว้แบบเต็มไปจนถึงการเปิดใช้งานหลังเริ่มรับฟัง                                                 |

เมทาดาทา manifest กำหนดว่าตัวเลือกผู้ให้บริการ/ช่องทาง/การตั้งค่าใดจะปรากฏในการเริ่มต้นใช้งานก่อนโหลดรันไทม์ `package.json#openclaw.install` บอกกระบวนการเริ่มต้นใช้งานว่าจะดึงหรือเปิดใช้ Plugin นั้นอย่างไรเมื่อผู้ใช้เลือกหนึ่งในตัวเลือกเหล่านั้น อย่าย้ายคำแนะนำการติดตั้งไปไว้ใน `openclaw.plugin.json`

ระบบบังคับใช้ `openclaw.install.minHostVersion` ระหว่างการติดตั้งและการโหลดรีจิสทรี manifest สำหรับแหล่ง Plugin ที่ไม่ได้รวมมากับระบบ ค่าที่ไม่ถูกต้องจะถูกปฏิเสธ ส่วนค่าที่ถูกต้องแต่ใหม่กว่าจะทำให้ข้าม Plugin ภายนอกบนโฮสต์รุ่นเก่า ระบบถือว่า Plugin ต้นทางที่รวมมากับระบบใช้เวอร์ชันเดียวกับซอร์สโค้ดโฮสต์ที่เช็กเอาต์

`openclaw.install.requiredPlatformPackages` ใช้สำหรับแพ็กเกจ npm ที่เปิดเผยไบนารีเนทีฟที่จำเป็นผ่านนามแฝงแบบเลือกติดตั้งเฉพาะแพลตฟอร์ม ระบุชื่อแพ็กเกจ npm แบบไม่มีส่วนขยายสำหรับทุกนามแฝงแพลตฟอร์มที่รองรับ ระหว่างการติดตั้งด้วย npm OpenClaw จะตรวจสอบเฉพาะนามแฝงที่ประกาศไว้ซึ่งข้อจำกัดใน lockfile ตรงกับโฮสต์ปัจจุบัน หาก npm รายงานว่าสำเร็จแต่ไม่รวมนามแฝงนั้น OpenClaw จะลองอีกครั้งหนึ่งด้วยแคชใหม่ และย้อนกลับการติดตั้งหากยังขาดนามแฝงนั้น

ระบบบังคับใช้ `openclaw.compat.pluginApi` ระหว่างการติดตั้งแพ็กเกจสำหรับแหล่ง Plugin ที่ไม่ได้รวมมากับระบบ ใช้ค่านี้เป็นขอบเขตล่างของ API SDK/รันไทม์ Plugin OpenClaw ที่แพ็กเกจใช้ในการบิลด์ ค่านี้อาจเข้มงวดกว่า `minHostVersion` เมื่อแพ็กเกจ Plugin ต้องใช้ API ที่ใหม่กว่า แต่ยังคงคำแนะนำการติดตั้งที่ต่ำกว่าสำหรับขั้นตอนอื่นไว้ โดยค่าเริ่มต้น การซิงก์รุ่นอย่างเป็นทางการของ OpenClaw จะปรับขอบเขตล่าง API ของ Plugin อย่างเป็นทางการที่มีอยู่ให้เป็นเวอร์ชันรุ่นของ OpenClaw แต่รุ่นที่เผยแพร่เฉพาะ Plugin สามารถคงขอบเขตล่างที่ต่ำกว่าไว้ได้ เมื่อแพ็กเกจตั้งใจรองรับโฮสต์รุ่นเก่า อย่าใช้เพียงเวอร์ชันแพ็กเกจเป็นสัญญาความเข้ากันได้ `peerDependencies.openclaw` ยังคงเป็นเมทาดาทาแพ็กเกจ npm ส่วน OpenClaw ใช้สัญญา `openclaw.compat.pluginApi` เพื่อตัดสินความเข้ากันได้ในการติดตั้ง

เมทาดาทาการติดตั้งตามคำขออย่างเป็นทางการควรใช้ `clawhubSpec` เมื่อ Plugin เผยแพร่บน ClawHub กระบวนการเริ่มต้นใช้งานจะถือว่านี่เป็นแหล่งระยะไกลที่แนะนำ และบันทึกข้อมูลอาร์ติแฟกต์ ClawHub หลังติดตั้ง `npmSpec` ยังคงเป็นทางเลือกสำรองเพื่อความเข้ากันได้สำหรับแพ็กเกจที่ยังไม่ได้ย้ายไป ClawHub

การตรึงเวอร์ชัน npm แบบตรงตัวมีอยู่แล้วใน `npmSpec` ตัวอย่างเช่น `"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"` รายการแค็ตตาล็อกภายนอกอย่างเป็นทางการควรจับคู่ข้อกำหนดแบบตรงตัวกับ `expectedIntegrity` เพื่อให้ขั้นตอนอัปเดตหยุดอย่างปลอดภัย หากอาร์ติแฟกต์ npm ที่ดึงมาไม่ตรงกับรุ่นที่ตรึงไว้อีกต่อไป การเริ่มต้นใช้งานแบบโต้ตอบยังคงเสนอข้อกำหนด npm จากรีจิสทรีที่เชื่อถือได้ รวมถึงชื่อแพ็กเกจแบบไม่มีส่วนขยายและ dist-tags เพื่อความเข้ากันได้ การวินิจฉัยแค็ตตาล็อกสามารถแยกแยะแหล่งที่เป็นแบบตรงตัว แบบลอยตัว แบบตรึงความสมบูรณ์ แบบขาดค่าความสมบูรณ์ ชื่อแพ็กเกจไม่ตรงกัน และตัวเลือกเริ่มต้นไม่ถูกต้อง นอกจากนี้ยังเตือนเมื่อมี `expectedIntegrity` แต่ไม่มีแหล่ง npm ที่ถูกต้องให้ตรึง เมื่อมี `expectedIntegrity` ขั้นตอนติดตั้ง/อัปเดตจะบังคับใช้ค่านี้ เมื่อไม่ระบุ ระบบจะบันทึกผลการแก้ชื่อจากรีจิสทรีโดยไม่มีการตรึงความสมบูรณ์

Plugin ช่องทางควรมี `openclaw.setupEntry` เมื่อการสแกนสถานะ รายการช่องทาง หรือ SecretRef จำเป็นต้องระบุบัญชีที่กำหนดค่าไว้โดยไม่โหลดรันไทม์ทั้งหมด จุดเริ่มต้นการตั้งค่าควรเปิดเผยเมทาดาทาช่องทาง รวมถึงอะแดปเตอร์การกำหนดค่า สถานะ และข้อมูลลับที่ปลอดภัยสำหรับการตั้งค่า ส่วนไคลเอนต์เครือข่าย ตัวรับฟัง Gateway และรันไทม์การขนส่งให้เก็บไว้ในจุดเริ่มต้นส่วนขยายหลัก

ฟิลด์จุดเริ่มต้นรันไทม์ไม่ลบล้างการตรวจสอบขอบเขตแพ็กเกจสำหรับฟิลด์จุดเริ่มต้นซอร์ส ตัวอย่างเช่น `openclaw.runtimeExtensions` ไม่สามารถทำให้พาธ `openclaw.extensions` ที่ออกนอกขอบเขตสามารถโหลดได้

`openclaw.install.allowInvalidConfigRecovery` ถูกจำกัดขอบเขตโดยเจตนา ไม่ได้ทำให้การกำหนดค่าที่เสียหายใด ๆ ติดตั้งได้ ปัจจุบันค่านี้อนุญาตให้ขั้นตอนติดตั้งกู้คืนได้เฉพาะจากความล้มเหลวบางรูปแบบของการอัปเกรด Plugin ที่รวมมากับระบบซึ่งตกค้าง เช่น พาธ Plugin ที่รวมมากับระบบหายไป หรือรายการ `channels.<id>` ที่ตกค้างสำหรับ Plugin ที่รวมมากับระบบเดียวกัน ข้อผิดพลาดการกำหนดค่าอื่นที่ไม่เกี่ยวข้องยังคงปิดกั้นการติดตั้ง และส่งผู้ดูแลระบบไปยัง `openclaw doctor --fix`

`openclaw.channel.persistedAuthState` คือเมทาดาทาแพ็กเกจสำหรับโมดูลตัวตรวจสอบขนาดเล็ก:

```json
{
  "openclaw": {
    "channel": {
      "id": "whatsapp",
      "persistedAuthState": {
        "specifier": "./auth-presence",
        "exportName": "hasAnyWhatsAppAuth"
      }
    }
  }
}
```

ใช้เมื่อขั้นตอนการตั้งค่า doctor สถานะ หรือขั้นตอนตรวจสอบการมีอยู่แบบอ่านอย่างเดียว ต้องการการตรวจสอบการยืนยันตัวตนแบบใช่/ไม่ใช่ที่มีต้นทุนต่ำก่อนโหลด Plugin ช่องทางทั้งหมด สถานะการยืนยันตัวตนที่จัดเก็บไว้ไม่ใช่สถานะช่องทางที่กำหนดค่าไว้ อย่าใช้เมทาดาทานี้เพื่อเปิดใช้ Plugin โดยอัตโนมัติ ซ่อมแซมการขึ้นต่อกันของรันไทม์ หรือตัดสินว่าควรโหลดรันไทม์ช่องทางหรือไม่ ส่วนส่งออกเป้าหมายควรเป็นฟังก์ชันขนาดเล็กที่อ่านเฉพาะสถานะที่จัดเก็บไว้ อย่าส่งผ่าน barrel ของรันไทม์ช่องทางทั้งหมด

`openclaw.channel.configuredState` ใช้โครงสร้างเดียวกันสำหรับการตรวจสอบสถานะการกำหนดค่าเฉพาะผ่านตัวแปรสภาพแวดล้อมแบบต้นทุนต่ำ:

```json
{
  "openclaw": {
    "channel": {
      "id": "telegram",
      "configuredState": {
        "specifier": "./configured-state",
        "exportName": "hasTelegramConfiguredState"
      }
    }
  }
}
```

ใช้เมื่อช่องทางสามารถตอบสถานะการกำหนดค่าจากตัวแปรสภาพแวดล้อมหรืออินพุตขนาดเล็กอื่นที่ไม่ใช่รันไทม์ หากการตรวจสอบต้องใช้การแก้ค่าการกำหนดค่าแบบเต็มหรือรันไทม์ช่องทางจริง ให้เก็บตรรกะนั้นไว้ในฮุก `config.hasConfiguredState` ของ Plugin แทน

## ลำดับความสำคัญในการค้นพบ (รหัส Plugin ซ้ำ)

OpenClaw ค้นหา Plugin จากรากสามแห่ง โดยตรวจสอบตามลำดับดังนี้: Plugin ที่รวมมากับ OpenClaw, รากการติดตั้งส่วนกลาง (`~/.openclaw/extensions`) และรากพื้นที่ทำงานปัจจุบัน (`<workspace>/.openclaw/extensions`) รวมถึงรายการ `plugins.load.paths` ที่ระบุไว้อย่างชัดเจน

หากผลการค้นพบสองรายการใช้ `id` เดียวกัน ระบบจะเก็บเฉพาะ manifest ที่มี **ลำดับความสำคัญสูงสุด** ส่วนรายการซ้ำที่มีลำดับความสำคัญต่ำกว่าจะถูกทิ้งแทนที่จะโหลดควบคู่กัน ลำดับความสำคัญจากสูงสุดไปต่ำสุด:

1. **เลือกโดยการกำหนดค่า** — พาธที่ตรึงไว้อย่างชัดเจนใน `plugins.entries.<id>`
2. **การติดตั้งส่วนกลางที่ตรงกับระเบียนการติดตั้งที่ติดตามไว้** — Plugin ที่ติดตั้งผ่าน `openclaw plugin install`/`openclaw plugin update` ซึ่งระบบติดตามการติดตั้งของ OpenClaw ยอมรับว่าเป็นรหัสเดียวกัน แม้รหัสนั้นจะเป็นของ Plugin ที่รวมมากับระบบด้วย
3. **รวมมากับระบบ** — Plugin ที่จัดส่งพร้อม OpenClaw
4. **พื้นที่ทำงาน** — Plugin ที่ค้นพบโดยอ้างอิงจากพื้นที่ทำงานปัจจุบัน
5. ตัวเลือกอื่นใดที่ค้นพบ

ผลที่ตามมา:

- สำเนาแตกแขนงหรือสำเนาเก่าของ Plugin ที่รวมมากับระบบ ซึ่งอยู่ในพื้นที่ทำงานหรือรากส่วนกลางโดยไม่ได้รับการติดตาม จะไม่บดบังบิลด์ที่รวมมากับระบบ
- หากต้องการแทนที่ Plugin ที่รวมมากับระบบ ให้เรียกใช้ `openclaw plugin install` สำหรับรหัสนั้น เพื่อให้การติดตั้งส่วนกลางที่ติดตามไว้มีลำดับสูงกว่าสำเนาที่รวมมากับระบบ หรือตรึงพาธเฉพาะผ่าน `plugins.entries.<id>` เพื่อให้พาธนั้นชนะด้วยลำดับความสำคัญแบบเลือกโดยการกำหนดค่า
- ระบบบันทึกการทิ้งรายการซ้ำลงในบันทึก เพื่อให้ Doctor และการวินิจฉัยขณะเริ่มต้นชี้ไปยังสำเนาที่ถูกละทิ้งได้
- การแทนที่รายการซ้ำที่เลือกโดยการกำหนดค่าจะแสดงถ้อยคำว่าเป็นการแทนที่อย่างชัดเจนในการวินิจฉัย แต่ยังคงเตือนเพื่อให้มองเห็นสำเนาแตกแขนงที่ตกค้างและการบดบังโดยไม่ตั้งใจ

## ข้อกำหนด JSON Schema

- **Plugin ทุกตัวต้องมาพร้อม JSON Schema** แม้ว่าจะไม่รับการกำหนดค่าใด ๆ ก็ตาม
- อนุญาตให้ใช้สคีมาว่างได้ (เช่น `{ "type": "object", "additionalProperties": false }`)
- ระบบตรวจสอบความถูกต้องของสคีมาขณะอ่าน/เขียนการกำหนดค่า ไม่ใช่ขณะรันไทม์
- เมื่อขยายหรือฟอร์ก Plugin ที่รวมมาให้โดยเพิ่มคีย์การกำหนดค่าใหม่ ให้อัปเดต `configSchema` ใน `openclaw.plugin.json` ของ Plugin นั้นพร้อมกัน สคีมาของ Plugin ที่รวมมาให้เป็นแบบเข้มงวด ดังนั้นการเพิ่ม `plugins.entries.<id>.config.myNewKey` ในการกำหนดค่าของผู้ใช้โดยไม่เพิ่ม `myNewKey` ลงใน `configSchema.properties` จะถูกปฏิเสธก่อนโหลดรันไทม์ของ Plugin

ตัวอย่างการขยายสคีมา:

```json
{
  "configSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "myNewKey": {
        "type": "string"
      }
    }
  }
}
```

## พฤติกรรมการตรวจสอบความถูกต้อง

- คีย์ `channels.*` ที่ไม่รู้จักถือเป็น **ข้อผิดพลาด** เว้นแต่รหัสช่องทางนั้นจะประกาศไว้ในไฟล์กำกับ Plugin หากรหัสเดียวกันปรากฏใน `plugins.allow`, `plugins.entries` หรือ `plugins.installs` ด้วย (Plugin ที่มีการอ้างอิงอยู่แต่ระบบค้นหาไม่พบในขณะนี้) OpenClaw จะลดระดับกรณีนี้เป็น **คำเตือน** แทน
- การอ้างอิงรหัส Plugin ที่ไม่รู้จักใน `plugins.entries.<id>`, `plugins.allow` และ `plugins.deny` ถือเป็น **คำเตือน** ("ละเว้นรายการการกำหนดค่าที่ล้าสมัย") ไม่ใช่ข้อผิดพลาด เพื่อให้การอัปเกรดและ Plugin ที่ถูกลบหรือเปลี่ยนชื่อไม่ขัดขวางการเริ่มต้น Gateway
- การที่ `plugins.slots.memory` อ้างอิงรหัส Plugin ที่ไม่รู้จักถือเป็น **ข้อผิดพลาด** ยกเว้น Plugin ภายนอกอย่างเป็นทางการ `memory-lancedb` ที่รู้จัก ซึ่งจะแสดงคำเตือนแทน
- หากติดตั้ง Plugin แล้ว แต่ไฟล์กำกับหรือสคีมาเสียหายหรือหายไป การตรวจสอบความถูกต้องจะล้มเหลวและ Doctor จะรายงานข้อผิดพลาดของ Plugin
- หากมีการกำหนดค่าของ Plugin แต่ Plugin ถูก **ปิดใช้งาน** ระบบจะเก็บการกำหนดค่าไว้และแสดง **คำเตือน** ใน Doctor และบันทึกเหตุการณ์

ดูสคีมา `plugins.*` ฉบับเต็มได้ที่ [ข้อมูลอ้างอิงการกำหนดค่า](/th/gateway/configuration)

## หมายเหตุ

- ไฟล์กำกับเป็นสิ่งที่ **จำเป็นสำหรับ Plugin แบบเนทีฟของ OpenClaw** รวมถึงการโหลดจากระบบไฟล์ภายในเครื่อง รันไทม์ยังคงโหลดโมดูล Plugin แยกต่างหาก โดยไฟล์กำกับมีไว้สำหรับการค้นพบและการตรวจสอบความถูกต้องเท่านั้น
- ไฟล์กำกับแบบเนทีฟได้รับการแยกวิเคราะห์ด้วย JSON5 จึงรองรับความคิดเห็น เครื่องหมายจุลภาคท้ายรายการ และคีย์ที่ไม่มีเครื่องหมายคำพูด ตราบใดที่ค่าสุดท้ายยังคงเป็นออบเจ็กต์
- ตัวโหลดไฟล์กำกับจะอ่านเฉพาะฟิลด์ที่มีเอกสารกำกับเท่านั้น หลีกเลี่ยงการใช้คีย์ระดับบนสุดแบบกำหนดเอง
- สามารถละเว้น `channels`, `providers`, `cliBackends` และ `skills` ได้ทั้งหมดเมื่อ Plugin ไม่จำเป็นต้องใช้
- `providerCatalogEntry` ต้องมีขนาดเล็กและไม่ควรนำเข้าโค้ดรันไทม์ในวงกว้าง ใช้สำหรับเมทาดาทาแค็ตตาล็อกผู้ให้บริการแบบคงที่หรือตัวบรรยายการค้นพบที่จำกัด ไม่ใช่สำหรับการดำเนินการขณะประมวลผลคำขอ
- ประเภท Plugin แบบเฉพาะสิทธิ์เลือกผ่าน `plugins.slots.*`: `kind: "memory"` ผ่าน `plugins.slots.memory` (ค่าเริ่มต้นคือ `memory-core`) และ `kind: "context-engine"` ผ่าน `plugins.slots.contextEngine` (ค่าเริ่มต้นคือ `legacy`)
- ให้ประกาศประเภท Plugin แบบเฉพาะสิทธิ์ในไฟล์กำกับนี้ `OpenClawPluginDefinition.kind` ของรายการรันไทม์เลิกแนะนำให้ใช้แล้ว และคงไว้เป็นเพียงกลไกสำรองเพื่อความเข้ากันได้สำหรับ Plugin รุ่นเก่า
- เมทาดาทาของตัวแปรสภาพแวดล้อม (`setup.providers[].envVars`, `providerAuthEnvVars` ที่เลิกแนะนำให้ใช้แล้ว และ `channelEnvVars`) มีไว้เพื่อการประกาศเท่านั้น สถานะ การตรวจสอบ การตรวจสอบความถูกต้องของการส่ง Cron และส่วนแสดงผลแบบอ่านอย่างเดียวอื่น ๆ ยังคงใช้นโยบายความเชื่อถือและการเปิดใช้งานที่มีผลของ Plugin ก่อนถือว่าตัวแปรสภาพแวดล้อมได้รับการกำหนดค่าแล้ว
- สำหรับเมทาดาทาของตัวช่วยตั้งค่ารันไทม์ที่ต้องใช้โค้ดผู้ให้บริการ โปรดดู [ฮุกของรันไทม์ผู้ให้บริการ](/th/plugins/architecture-internals#provider-runtime-hooks)
- หาก Plugin ของคุณขึ้นอยู่กับโมดูลเนทีฟ ให้จัดทำเอกสารขั้นตอนการบิลด์และข้อกำหนดเกี่ยวกับรายการอนุญาตของตัวจัดการแพ็กเกจ (เช่น `allow-build-scripts` ของ pnpm และ `pnpm rebuild <package>`)

## เนื้อหาที่เกี่ยวข้อง

<CardGroup cols={3}>
  <Card title="การสร้าง Plugin" href="/th/plugins/building-plugins" icon="rocket">
    เริ่มต้นใช้งาน Plugin
  </Card>
  <Card title="สถาปัตยกรรม Plugin" href="/th/plugins/architecture" icon="diagram-project">
    สถาปัตยกรรมภายในและแบบจำลองความสามารถ
  </Card>
  <Card title="ภาพรวม SDK" href="/th/plugins/sdk-overview" icon="book">
    ข้อมูลอ้างอิง SDK ของ Plugin และการนำเข้าพาธย่อย
  </Card>
</CardGroup>
