From 1fbb99ed0197cdda3b06399596cd6a2e75a46987 Mon Sep 17 00:00:00 2001 From: "openclaw-docs-i18n[bot]" Date: Fri, 1 May 2026 02:47:51 +0000 Subject: [PATCH] chore(i18n): refresh zh-TW translations --- docs/zh-TW/ci.md | 366 ++++---- docs/zh-TW/cli/models.md | 165 ++-- docs/zh-TW/concepts/commitments.md | 113 +-- docs/zh-TW/concepts/openclaw-sdk.md | 167 ++-- docs/zh-TW/gateway/protocol.md | 518 ++++++----- docs/zh-TW/gateway/troubleshooting.md | 355 ++++---- docs/zh-TW/help/testing.md | 857 +++++++++--------- docs/zh-TW/plugins/codex-harness.md | 618 ++++++------- docs/zh-TW/reference/RELEASING.md | 350 +++---- .../reference/full-release-validation.md | 156 ++++ docs/zh-TW/reference/test.md | 113 +-- 11 files changed, 2003 insertions(+), 1775 deletions(-) create mode 100644 docs/zh-TW/reference/full-release-validation.md diff --git a/docs/zh-TW/ci.md b/docs/zh-TW/ci.md index 4ef6b28f9..4b7c3d5ab 100644 --- a/docs/zh-TW/ci.md +++ b/docs/zh-TW/ci.md @@ -1,75 +1,75 @@ --- read_when: - 你需要了解 CI 作業為何執行或未執行 - - 你正在偵錯一個失敗的 GitHub Actions 檢查 - - 您正在協調發布驗證的執行或重新執行 -summary: CI 作業圖、範圍閘門、發行總括項與本機命令對應項 + - 你正在偵錯失敗的 GitHub Actions 檢查 + - 你正在協調一次發布驗證執行或重新執行 +summary: CI 作業圖、範圍閘門、發行總括項,以及本機命令對應項 title: CI 管線 x-i18n: - generated_at: "2026-04-30T18:38:35Z" + generated_at: "2026-05-01T02:44:56Z" model: gpt-5.5 provider: openai - source_hash: a24afc27606ac7f4e9ead89acdd319bffa23336610f8a6cd8b576ea1a5b233dd + source_hash: 0c2ee36f96ccf86d4adb739f5f7efb82c05f733e7693571ce391269d2538fec7 source_path: ci.md workflow: 16 --- -OpenClaw CI 會在每次推送到 `main` 以及每個 pull request 上執行。`preflight` 工作會分類 diff,並在只有不相關區域變更時關閉昂貴的執行路徑。手動 `workflow_dispatch` 執行會刻意略過智慧範圍界定,並為候選版本與廣泛驗證展開完整圖。Android 執行路徑透過 `include_android` 維持選擇加入。僅限發行的 Plugin 涵蓋範圍位於獨立的 [`Plugin Prerelease`](#plugin-prerelease) workflow,且只會從 [`Full Release Validation`](#full-release-validation) 或明確的手動 dispatch 執行。 +OpenClaw CI 會在每次推送到 `main` 以及每個拉取請求時執行。`preflight` 工作會分類差異,並在只有不相關區域變更時關閉昂貴的路徑。手動 `workflow_dispatch` 執行會刻意略過智慧範圍判定,並展開完整圖形,用於候選版本與廣泛驗證。Android 路徑透過 `include_android` 維持選擇加入。僅限發行版的 Plugin 覆蓋位於獨立的 [`Plugin 預發行`](#plugin-prerelease) 工作流程中,且只會從 [`完整發行驗證`](#full-release-validation) 或明確的手動派發執行。 -## 管線概覽 +## 管線總覽 | 工作 | 目的 | 執行時機 | | -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- | -| `preflight` | 偵測僅文件變更、變更範圍、變更的 Plugin,並建立 CI manifest | 一律在非草稿 push 與 PR 上執行 | -| `security-scm-fast` | 透過 `zizmor` 進行私鑰偵測與 workflow 稽核 | 一律在非草稿 push 與 PR 上執行 | -| `security-dependency-audit` | 針對 npm advisories 進行不需安裝相依套件的 production lockfile 稽核 | 一律在非草稿 push 與 PR 上執行 | -| `security-fast` | 快速安全性工作的必要彙總 | 一律在非草稿 push 與 PR 上執行 | -| `check-dependencies` | Production Knip 僅相依套件檢查,加上未使用檔案 allowlist 防護 | Node 相關變更 | -| `build-artifacts` | 建置 `dist/`、Control UI、建置成品檢查,以及可重用的下游 artifacts | Node 相關變更 | -| `checks-fast-core` | 快速 Linux 正確性執行路徑,例如 bundled/plugin-contract/protocol 檢查 | Node 相關變更 | -| `checks-fast-contracts-channels` | 分片的 channel contract 檢查,並具備穩定的彙總檢查結果 | Node 相關變更 | -| `checks-node-core-test` | Core Node 測試分片,排除 channel、bundled、contract 與 Plugin 執行路徑 | Node 相關變更 | -| `check` | 分片的主要本機 gate 等價檢查:prod types、lint、guards、test types 與 strict smoke | Node 相關變更 | -| `check-additional` | 架構、邊界、Plugin 介面防護、package-boundary 與 gateway-watch 分片 | Node 相關變更 | -| `build-smoke` | Built-CLI smoke tests 與 startup-memory smoke | Node 相關變更 | -| `checks` | 建置成品 channel tests 的驗證器 | Node 相關變更 | -| `checks-node-compat-node22` | Node 22 相容性建置與 smoke 執行路徑 | 發行用手動 CI dispatch | -| `check-docs` | 文件格式、lint 與 broken-link 檢查 | 文件已變更 | -| `skills-python` | Python-backed skills 的 Ruff + pytest | Python-skill 相關變更 | -| `checks-windows` | Windows 特定的 process/path 測試,加上共用 runtime import specifier 回歸檢查 | Windows 相關變更 | -| `macos-node` | 使用共用建置成品的 macOS TypeScript 測試執行路徑 | macOS 相關變更 | -| `macos-swift` | macOS app 的 Swift lint、build 與 tests | macOS 相關變更 | -| `android` | 兩種 flavor 的 Android unit tests,加上一個 debug APK build | Android 相關變更 | -| `test-performance-agent` | 受信任活動後的每日 Codex slow-test 最佳化 | Main CI 成功或手動 dispatch | +| `preflight` | 偵測僅文件變更、變更範圍、變更的擴充功能,並建置 CI 清單 | 一律在非草稿推送與 PR 上執行 | +| `security-scm-fast` | 透過 `zizmor` 進行私鑰偵測與工作流程稽核 | 一律在非草稿推送與 PR 上執行 | +| `security-dependency-audit` | 針對 npm advisories 的無依賴生產 lockfile 稽核 | 一律在非草稿推送與 PR 上執行 | +| `security-fast` | 快速安全工作所需的彙總 | 一律在非草稿推送與 PR 上執行 | +| `check-dependencies` | 僅限生產 Knip 依賴檢查,加上未使用檔案允許清單防護 | Node 相關變更 | +| `build-artifacts` | 建置 `dist/`、Control UI、已建置成品檢查,以及可重用的下游成品 | Node 相關變更 | +| `checks-fast-core` | 快速 Linux 正確性路徑,例如 bundled/plugin-contract/protocol 檢查 | Node 相關變更 | +| `checks-fast-contracts-channels` | 分片的頻道合約檢查,並提供穩定的彙總檢查結果 | Node 相關變更 | +| `checks-node-core-test` | 核心 Node 測試分片,不包含頻道、bundled、contract 與擴充功能路徑 | Node 相關變更 | +| `check` | 分片的主要本機閘門等價項:生產型別、lint、防護、測試型別與嚴格 smoke | Node 相關變更 | +| `check-additional` | 架構、邊界、擴充功能表面防護、套件邊界,以及 gateway-watch 分片 | Node 相關變更 | +| `build-smoke` | 已建置 CLI smoke 測試與啟動記憶體 smoke | Node 相關變更 | +| `checks` | 已建置成品頻道測試的驗證器 | Node 相關變更 | +| `checks-node-compat-node22` | Node 22 相容性建置與 smoke 路徑 | 發行版的手動 CI 派發 | +| `check-docs` | 文件格式化、lint 與損壞連結檢查 | 文件已變更 | +| `skills-python` | Python 支援 Skills 的 Ruff + pytest | Python Skill 相關變更 | +| `checks-windows` | Windows 專用處理程序/路徑測試,以及共享執行階段 import specifier 迴歸 | Windows 相關變更 | +| `macos-node` | 使用共享已建置成品的 macOS TypeScript 測試路徑 | macOS 相關變更 | +| `macos-swift` | macOS App 的 Swift lint、建置與測試 | macOS 相關變更 | +| `android` | 兩種 flavor 的 Android 單元測試,加上一個 debug APK 建置 | Android 相關變更 | +| `test-performance-agent` | 可信活動後每日的 Codex 慢速測試最佳化 | 主要 CI 成功或手動派發 | -## Fail-fast 順序 +## 快速失敗順序 -1. `preflight` 決定哪些執行路徑實際存在。`docs-scope` 與 `changed-scope` 邏輯是此工作內的步驟,不是獨立工作。 -2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 與 `skills-python` 會快速失敗,不等待較重的 artifact 與平台矩陣工作。 -3. `build-artifacts` 會與快速 Linux 執行路徑重疊,因此下游消費者可以在共用 build 準備好後立即開始。 -4. 較重的平台與 runtime 執行路徑接著展開:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 與 `android`。 +1. `preflight` 會決定哪些路徑實際存在。`docs-scope` 與 `changed-scope` 邏輯是此工作內的步驟,而不是獨立工作。 +2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 與 `skills-python` 會快速失敗,不需等待較重的成品與平台矩陣工作。 +3. `build-artifacts` 會與快速 Linux 路徑重疊,讓下游消費者能在共享建置準備好後立即開始。 +4. 較重的平台與執行階段路徑會在之後展開:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 與 `android`。 -當較新的 push 落在同一個 PR 或 `main` ref 上時,GitHub 可能會將被取代的工作標記為 `cancelled`。除非同一 ref 的最新執行也失敗,否則將其視為 CI 雜訊。彙總分片檢查使用 `!cancelled() && always()`,因此仍會回報一般分片失敗,但不會在整個 workflow 已被取代後繼續排隊。自動 CI concurrency key 已版本化(`CI-v7-*`),因此 GitHub 端舊佇列群組中的 zombie 不會無限期封鎖較新的 main 執行。手動 full-suite 執行使用 `CI-manual-v1-*`,且不會取消進行中的執行。 +當同一個 PR 或 `main` ref 上有較新的推送到達時,GitHub 可能會將被取代的工作標記為 `cancelled`。除非同一 ref 的最新執行也失敗,否則將其視為 CI 雜訊。彙總分片檢查使用 `!cancelled() && always()`,因此它們仍會回報一般分片失敗,但不會在整個工作流程已被取代後繼續排隊。自動 CI 並行鍵有版本標記(`CI-v7-*`),因此 GitHub 端舊佇列群組中的殭屍工作無法無限期封鎖較新的 main 執行。手動完整套件執行使用 `CI-manual-v1-*`,且不會取消正在進行中的執行。 ## 範圍與路由 -範圍邏輯位於 `scripts/ci-changed-scope.mjs`,並由 `src/scripts/ci-changed-scope.test.ts` 中的 unit tests 涵蓋。手動 dispatch 會略過 changed-scope detection,並讓 preflight manifest 表現得像每個 scoped area 都已變更。 +範圍邏輯位於 `scripts/ci-changed-scope.mjs`,並由 `src/scripts/ci-changed-scope.test.ts` 中的單元測試涵蓋。手動派發會略過變更範圍偵測,並讓 preflight 清單表現得像每個有範圍的區域都已變更。 -- **CI workflow 編輯**會驗證 Node CI 圖與 workflow linting,但本身不會強制 Windows、Android 或 macOS native builds;那些平台執行路徑仍限定於平台原始碼變更。 -- **CI routing-only 編輯、選定的低成本 core-test fixture 編輯,以及狹窄的 plugin contract helper/test-routing 編輯**會使用快速 Node-only manifest 路徑:`preflight`、security 與單一 `checks-fast-core` task。當變更僅限於 fast task 直接執行的 routing 或 helper surfaces 時,該路徑會略過 build artifacts、Node 22 compatibility、channel contracts、full core shards、bundled-plugin shards 與 additional guard matrices。 -- **Windows Node checks**限定於 Windows 特定的 process/path wrappers、npm/pnpm/UI runner helpers、package manager config,以及執行該執行路徑的 CI workflow surfaces;不相關的 source、Plugin、install-smoke 與 test-only 變更會留在 Linux Node 執行路徑。 +- **CI 工作流程編輯**會驗證 Node CI 圖形與工作流程 lint,但不會單獨強制執行 Windows、Android 或 macOS 原生建置;這些平台路徑仍僅限於平台原始碼變更。 +- **僅 CI 路由編輯、選定的低成本核心測試 fixture 編輯,以及狹窄的 Plugin 合約輔助/測試路由編輯**會使用快速的僅 Node 清單路徑:`preflight`、安全性,以及單一 `checks-fast-core` 工作。當變更僅限於該快速工作會直接執行的路由或輔助表面時,此路徑會略過建置成品、Node 22 相容性、頻道合約、完整核心分片、bundled-plugin 分片,以及額外的防護矩陣。 +- **Windows Node 檢查**的範圍限於 Windows 專用處理程序/路徑包裝器、npm/pnpm/UI runner 輔助、套件管理器設定,以及執行該路徑的 CI 工作流程表面;不相關的原始碼、Plugin、install-smoke 與僅測試變更會留在 Linux Node 路徑上。 -最慢的 Node test families 會被拆分或平衡,讓每個工作維持小型且不過度保留 runners:channel contracts 以三個加權分片執行,小型 core unit 執行路徑會配對,auto-reply 以四個平衡 workers 執行(reply subtree 拆成 agent-runner、dispatch 與 commands/state-routing 分片),而 agentic gateway/plugin configs 會分散在既有的 source-only agentic Node jobs 中,而不是等待 built artifacts。廣泛的 browser、QA、media 與 miscellaneous plugin tests 使用各自專用的 Vitest configs,而不是共用 plugin catch-all。Include-pattern shards 會使用 CI shard name 記錄 timing entries,因此 `.artifacts/vitest-shard-timings.json` 可以區分完整 config 與 filtered shard。`check-additional` 會將 package-boundary compile/canary 工作放在一起,並將 runtime topology architecture 與 gateway watch coverage 分開;boundary guard shard 會在單一工作內並行執行其小型獨立 guards。Gateway watch、channel tests 與 core support-boundary shard 會在 `dist/` 與 `dist-runtime/` 已建置後,於 `build-artifacts` 內並行執行。 +最慢的 Node 測試家族會被拆分或平衡,讓每個工作保持較小且不過度保留 runner:頻道合約以三個加權分片執行,小型核心單元路徑會配對,auto-reply 以四個平衡 worker 執行(reply 子樹拆成 agent-runner、dispatch 與 commands/state-routing 分片),而 agentic gateway/plugin 設定會分散到現有的僅原始碼 agentic Node 工作中,而不是等待已建置成品。廣泛的瀏覽器、QA、媒體與雜項 Plugin 測試會使用其專用 Vitest 設定,而不是共享的 Plugin catch-all。include-pattern 分片會使用 CI 分片名稱記錄時間項目,因此 `.artifacts/vitest-shard-timings.json` 可以區分整個設定與過濾後的分片。`check-additional` 會將套件邊界編譯/canary 工作保持在一起,並將執行階段拓撲架構與 gateway watch 覆蓋分開;邊界防護分片會在一個工作內並行執行其小型獨立防護。Gateway watch、頻道測試與核心支援邊界分片會在 `dist/` 與 `dist-runtime/` 已建置後,於 `build-artifacts` 內並行執行。 -Android CI 會執行 `testPlayDebugUnitTest` 與 `testThirdPartyDebugUnitTest`,然後建置 Play debug APK。third-party flavor 沒有獨立的 source set 或 manifest;其 unit-test 執行路徑仍會使用 SMS/call-log BuildConfig flags 編譯該 flavor,同時避免在每個 Android 相關 push 上重複 debug APK packaging job。 +Android CI 會同時執行 `testPlayDebugUnitTest` 與 `testThirdPartyDebugUnitTest`,然後建置 Play debug APK。third-party flavor 沒有獨立的 source set 或 manifest;其單元測試路徑仍會使用 SMS/call-log BuildConfig 旗標編譯該 flavor,同時避免在每個 Android 相關推送上重複 debug APK 封裝工作。 -`check-dependencies` shard 會執行 `pnpm deadcode:dependencies`(production Knip 僅相依套件檢查,釘選到最新 Knip 版本,且為 `dlx` 安裝停用 pnpm 的 minimum release age)與 `pnpm deadcode:unused-files`,後者會將 Knip 的 production unused-file findings 與 `scripts/deadcode-unused-files.allowlist.mjs` 比對。當 PR 新增未經審查的 unused file,或留下過期的 allowlist entry 時,unused-file guard 會失敗,同時保留 Knip 無法靜態解析的 intentional dynamic plugin、generated、build、live-test 與 package bridge surfaces。 +`check-dependencies` 分片會執行 `pnpm deadcode:dependencies`(固定使用最新 Knip 版本的僅限生產 Knip 依賴檢查,並為 `dlx` 安裝停用 pnpm 的最低發行年齡)以及 `pnpm deadcode:unused-files`,後者會將 Knip 的生產未使用檔案發現結果與 `scripts/deadcode-unused-files.allowlist.mjs` 比對。當 PR 新增未審查的未使用檔案或留下過時的允許清單項目時,未使用檔案防護會失敗,同時保留 Knip 無法靜態解析的刻意動態 Plugin、產生檔、建置、live-test 與套件橋接表面。 -## 手動 Dispatch +## 手動派發 -手動 CI dispatch 會執行與一般 CI 相同的 job graph,但強制開啟每個非 Android scoped lane:Linux Node shards、bundled-plugin shards、channel contracts、Node 22 compatibility、`check`、`check-additional`、build smoke、docs checks、Python skills、Windows、macOS 與 Control UI i18n。獨立手動 CI dispatch 只有在 `include_android=true` 時才會執行 Android;完整發行 umbrella 會透過傳入 `include_android=true` 啟用 Android。Plugin prerelease static checks、僅限發行的 `agentic-plugins` shard、完整 Plugin batch sweep,以及 plugin prerelease Docker lanes 都排除於 CI 之外。Docker prerelease suite 只會在 `Full Release Validation` 以啟用 release-validation gate 的方式 dispatch 獨立的 `Plugin Prerelease` workflow 時執行。 +手動 CI 派發會執行與一般 CI 相同的工作圖形,但會強制開啟每個非 Android 範圍路徑:Linux Node 分片、bundled-plugin 分片、頻道合約、Node 22 相容性、`check`、`check-additional`、建置 smoke、文件檢查、Python Skills、Windows、macOS 與 Control UI i18n。獨立的手動 CI 派發只有在 `include_android=true` 時才會執行 Android;完整發行傘狀流程會透過傳遞 `include_android=true` 啟用 Android。Plugin 預發行靜態檢查、僅限發行版的 `agentic-plugins` 分片、完整擴充功能批次掃描,以及 Plugin 預發行 Docker 路徑都排除在 CI 之外。Docker 預發行套件只會在 `Full Release Validation` 以啟用 release-validation 閘門的方式派發獨立 `Plugin Prerelease` 工作流程時執行。 -手動執行使用唯一的 concurrency group,因此 release-candidate full suite 不會被同一 ref 上的另一個 push 或 PR run 取消。選用的 `target_ref` input 讓受信任的 caller 可以針對 branch、tag 或完整 commit SHA 執行該圖,同時使用所選 dispatch ref 的 workflow file。 +手動執行會使用唯一的並行群組,因此候選版本完整套件不會被同一 ref 上的另一個推送或 PR 執行取消。選用的 `target_ref` 輸入允許可信呼叫者針對分支、標籤或完整 commit SHA 執行該圖形,同時使用所選派發 ref 中的工作流程檔案。 ```bash gh workflow run ci.yml --ref release/YYYY.M.D @@ -77,19 +77,19 @@ gh workflow run ci.yml --ref main -f target_ref= -f include_andro gh workflow run full-release-validation.yml --ref main -f ref= ``` -## Runners +## Runner -| 執行器 | 作業 | +| 執行器 | 工作 | | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ubuntu-24.04` | `preflight`、快速安全性作業與彙總(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速協定/合約/ bundled 檢查、分片的頻道合約檢查、除 lint 以外的 `check` 分片、`check-additional` 分片與彙總、Node 測試彙總驗證器、文件檢查、Python Skills、workflow-sanity、labeler、auto-response;install-smoke preflight 也使用 GitHub 託管的 Ubuntu,讓 Blacksmith 矩陣能更早排入佇列 | -| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`、較低權重的 Plugin 分片、`checks-fast-core`、`checks-node-compat-node22`、`check-prod-types` 和 `check-test-types` | -| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 測試分片、bundled Plugin 測試分片、`android` | -| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(對 CPU 夠敏感,8 vCPU 的成本高過省下的時間);install-smoke Docker 建置(32 vCPU 的佇列時間成本高過省下的時間) | +| `ubuntu-24.04` | `preflight`、快速安全性工作與彙總(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速通訊協定/合約/內建檢查、分片頻道合約檢查、除 lint 以外的 `check` 分片、`check-additional` 分片與彙總、Node 測試彙總驗證器、文件檢查、Python skills、workflow-sanity、labeler、auto-response;install-smoke preflight 也使用 GitHub 代管的 Ubuntu,讓 Blacksmith 矩陣可以更早排入佇列 | +| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`、較低負載的 Plugin 分片、`checks-fast-core`、`checks-node-compat-node22`、`check-prod-types` 和 `check-test-types` | +| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 測試分片、內建 Plugin 測試分片、`android` | +| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(對 CPU 足夠敏感,以至於 8 vCPU 增加的成本高於節省的成本);install-smoke Docker 建置(32-vCPU 佇列時間的成本高於節省的成本) | | `blacksmith-16vcpu-windows-2025` | `checks-windows` | | `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`;fork 會退回 `macos-latest` | | `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`;fork 會退回 `macos-latest` | -## 本機等效命令 +## 本機對應項目 ```bash pnpm changed:lanes # inspect the local changed-lane classifier for origin/main...HEAD @@ -117,27 +117,39 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac ## 完整發行驗證 -`Full Release Validation` 是「發行前執行所有內容」的手動總括工作流程。它接受分支、標籤或完整 commit SHA,使用該目標派送手動 `CI` 工作流程,為僅發行用的 Plugin/套件/靜態/Docker 證明派送 `Plugin Prerelease`,並為安裝煙霧測試、套件接受度、Docker 發行路徑套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道派送 `OpenClaw Release Checks`。提供已發布套件規格時,它也可以執行發布後的 `NPM Telegram Beta E2E` 工作流程。 +`Full Release Validation` 是「發行前執行所有項目」的手動傘狀工作流程。它接受分支、標籤或完整提交 SHA,使用該目標派送手動 `CI` 工作流程,派送 `Plugin Prerelease` 以取得僅限發行的 Plugin/package/static/Docker 證明,並派送 `OpenClaw Release Checks` 以執行安裝 smoke、package acceptance、Docker 發行路徑套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 路徑。提供已發布套件規格時,它也可以執行發布後的 `NPM Telegram Beta E2E` 工作流程。 -`release_profile` 控制傳入發行檢查的 live/供應商涵蓋範圍: +請參閱[完整發行驗證](/zh-TW/reference/full-release-validation),了解 +階段矩陣、確切的工作流程工作名稱、profile 差異、成品,以及 +聚焦重新執行控制代碼。 -- `minimum` 保留最快的 OpenAI/核心發行關鍵通道。 -- `stable` 加入穩定供應商/後端集合。 -- `full` 執行廣泛的諮詢供應商/媒體矩陣。 +`release_profile` 控制傳遞給發行檢查的 live/provider 廣度。 +手動發行工作流程預設為 `stable`;只有在你 +有意需要廣泛的 advisory provider/media 矩陣時,才使用 `full`。 -總括流程會記錄已派送的子執行 ID,而最終的 `Verify full validation` 作業會重新檢查目前子執行結論,並為每個子執行附加最慢作業表。如果子工作流程重新執行後轉為綠燈,只需重新執行父驗證器作業,即可重新整理總括結果與時間摘要。 +- `minimum` 保留最快的 OpenAI/core 發行關鍵路徑。 +- `stable` 加入穩定的 provider/backend 集合。 +- `full` 執行廣泛的 advisory provider/media 矩陣。 -若要復原,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。發行候選版本使用 `all`,僅一般完整 CI 子項使用 `ci`,每個發行子項使用 `release-checks`,或在總括流程上使用較窄的群組:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。這會讓失敗的發行盒在針對性修復後,重新執行範圍保持有界。 +傘狀工作流程會記錄已派送的子執行 ID,最終的 `Verify full validation` 工作會重新檢查目前子執行結論,並為每個子執行附加最慢工作表。如果子工作流程重新執行後轉為綠燈,只需重新執行父驗證器工作,即可重新整理傘狀結果與時間摘要。 -`OpenClaw Release Checks` 使用受信任的工作流程 ref,將所選 ref 解析一次為 `release-package-under-test` tarball,然後將該成品傳給 live/E2E 發行路徑 Docker 工作流程和套件接受度分片。這能讓套件位元組在各發行盒之間保持一致,並避免在多個子作業中重新打包同一個候選版本。 +若要復原,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。對發行候選版本使用 `all`,只重新執行一般完整 CI 子項時使用 `ci`,只重新執行 Plugin 預發行子項時使用 `plugin-prerelease`,重新執行每個發行子項時使用 `release-checks`,或在傘狀工作流程上使用更窄的群組:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。這讓修正聚焦問題後,失敗的發行方塊重新執行仍保持有界。 + +`OpenClaw Release Checks` 使用受信任的工作流程 ref,將選取的 ref 解析一次為 `release-package-under-test` tarball,然後將該成品同時傳遞給 live/E2E 發行路徑 Docker 工作流程和 package acceptance 分片。這讓發行方塊之間的套件位元組保持一致,並避免在多個子工作中重新封裝同一個候選版本。 + +`ref=main` 和 `rerun_group=all` 的重複 `Full Release Validation` 執行 +會取代較舊的傘狀工作流程。父監視器會在父項取消時取消任何它 +已派送的子工作流程,因此較新的 main 驗證 +不會卡在過期的兩小時 release-check 執行之後。發行分支/標籤 +驗證和聚焦重新執行群組會保留 `cancel-in-progress: false`。 ## Live 和 E2E 分片 -發行 live/E2E 子項保留廣泛的原生 `pnpm test:live` 涵蓋範圍,但它會透過 `scripts/test-live-shard.mjs` 以具名分片執行,而不是單一序列作業: +發行 live/E2E 子項保留廣泛的原生 `pnpm test:live` 覆蓋範圍,但它會透過 `scripts/test-live-shard.mjs` 以命名分片執行,而不是單一序列工作: - `native-live-src-agents` - `native-live-src-gateway-core` -- 依供應商篩選的 `native-live-src-gateway-profiles` 作業 +- provider 篩選的 `native-live-src-gateway-profiles` 工作 - `native-live-src-gateway-backends` - `native-live-test` - `native-live-extensions-a-k` @@ -145,57 +157,57 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac - `native-live-extensions-openai` - `native-live-extensions-o-z-other` - `native-live-extensions-xai` -- 拆分的媒體音訊/視訊分片,以及依供應商篩選的音樂分片 +- 分割的 media audio/video 分片,以及 provider 篩選的 music 分片 -這會保留相同的檔案涵蓋範圍,同時讓緩慢的 live 供應商失敗更容易重新執行與診斷。彙總的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名稱仍可用於手動一次性重新執行。 +這會保留相同的檔案覆蓋範圍,同時讓緩慢的 live provider 失敗更容易重新執行和診斷。彙總的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名稱仍可用於手動一次性重新執行。 -原生 live 媒體分片在 `Live Media Runner Image` 工作流程建置的 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中執行。該映像已預先安裝 `ffmpeg` 和 `ffprobe`;媒體作業只會在設定前驗證二進位檔。請將 Docker 支援的 live 套件放在一般 Blacksmith 執行器上,container 作業不是啟動巢狀 Docker 測試的合適位置。 +原生 live media 分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中執行,該映像由 `Live Media Runner Image` 工作流程建置。該映像預先安裝 `ffmpeg` 和 `ffprobe`;media 工作只會在設定前驗證二進位檔。請將 Docker 支援的 live 套件保留在一般 Blacksmith 執行器上,容器工作並不適合啟動巢狀 Docker 測試。 -Docker 支援的 live 模型/後端分片會對每個所選 commit 使用個別共用的 `ghcr.io/openclaw/openclaw-live-test:` 映像。live 發行工作流程會建置並推送該映像一次,接著 Docker live 模型、Gateway、CLI 後端、ACP bind 和 Codex harness 分片會以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行。如果這些分片各自重新建置完整原始碼 Docker 目標,表示發行執行設定錯誤,會在重複映像建置上浪費牆鐘時間。 +Docker 支援的 live model/backend 分片會針對每個選取的提交使用獨立的共用 `ghcr.io/openclaw/openclaw-live-test:` 映像。live 發行工作流程會建置並推送該映像一次,然後 Docker live model、provider 分片 Gateway、CLI backend、ACP bind 和 Codex harness 分片會以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行。Gateway Docker 分片在 workflow job timeout 以下帶有明確的 script-level `timeout` 上限,因此卡住的容器或清理路徑會快速失敗,而不是耗盡整個 release-check 預算。如果這些分片各自獨立重建完整 source Docker 目標,表示發行執行設定錯誤,並會在重複映像建置上浪費實際時間。 -## 套件接受度 +## Package Acceptance -當問題是「這個可安裝的 OpenClaw 套件是否能作為產品運作?」時,請使用 `Package Acceptance`。它不同於一般 CI:一般 CI 驗證原始碼樹,而套件接受度會透過使用者在安裝或更新後實際執行的同一套 Docker E2E harness 來驗證單一 tarball。 +當問題是「這個可安裝的 OpenClaw 套件是否能作為產品運作?」時,請使用 `Package Acceptance`。它不同於一般 CI:一般 CI 驗證來源樹,而 package acceptance 會透過使用者安裝或更新後執行的同一套 Docker E2E harness 驗證單一 tarball。 -### 作業 +### 工作 -1. `resolve_package` 會 checkout `workflow_ref`、解析一個套件候選、寫入 `.artifacts/docker-e2e-package/openclaw-current.tgz`、寫入 `.artifacts/docker-e2e-package/package-candidate.json`、將兩者作為 `package-under-test` 成品上傳,並在 GitHub 步驟摘要中列印來源、工作流程 ref、套件 ref、版本、SHA-256 和 profile。 -2. `docker_acceptance` 會以 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 呼叫 `openclaw-live-and-e2e-checks-reusable.yml`。可重用工作流程會下載該成品、驗證 tarball 清單、在需要時準備 package-digest Docker 映像,並針對該套件而不是打包工作流程 checkout 執行所選 Docker 通道。當 profile 選取多個目標 `docker_lanes` 時,可重用工作流程會準備套件與共用映像一次,然後將這些通道展開為具有唯一成品的平行目標 Docker 作業。 -3. `package_telegram` 會選擇性呼叫 `NPM Telegram Beta E2E`。當 `telegram_mode` 不是 `none` 時它會執行,並在 Package Acceptance 已解析套件時安裝相同的 `package-under-test` 成品;獨立 Telegram 派送仍可安裝已發布的 npm 規格。 -4. 如果套件解析、Docker 接受度或選用的 Telegram 通道失敗,`summary` 會使工作流程失敗。 +1. `resolve_package` 簽出 `workflow_ref`,解析一個套件候選項,寫入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,寫入 `.artifacts/docker-e2e-package/package-candidate.json`,將兩者都上傳為 `package-under-test` 成品,並在 GitHub 步驟摘要中列印來源、工作流程 ref、套件 ref、版本、SHA-256 與設定檔。 +2. `docker_acceptance` 以 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 呼叫 `openclaw-live-and-e2e-checks-reusable.yml`。可重用工作流程會下載該成品、驗證 tarball 清單、在需要時準備套件摘要 Docker 映像,並針對該套件執行選定的 Docker 路徑,而不是打包工作流程簽出的內容。當設定檔選取多個目標 `docker_lanes` 時,可重用工作流程會先準備一次套件與共用映像,然後將這些路徑展開為平行的目標 Docker 工作,並使用唯一成品。 +3. `package_telegram` 可選擇呼叫 `NPM Telegram Beta E2E`。當 `telegram_mode` 不是 `none` 時會執行,且在 Package Acceptance 已解析套件時安裝同一個 `package-under-test` 成品;獨立 Telegram 派送仍可安裝已發佈的 npm 規格。 +4. 如果套件解析、Docker acceptance,或選用的 Telegram 路徑失敗,`summary` 會讓工作流程失敗。 ### 候選來源 -- `source=npm` 只接受 `openclaw@beta`、`openclaw@latest`,或精確的 OpenClaw 發行版本,例如 `openclaw@2026.4.27-beta.2`。請將此用於已發布 beta/穩定版的驗收。 -- `source=ref` 會封裝受信任的 `package_ref` 分支、標籤或完整 commit SHA。解析器會擷取 OpenClaw 分支/標籤、驗證所選 commit 可從儲存庫分支歷史或發行標籤到達、在分離的 worktree 中安裝相依套件,並使用 `scripts/package-openclaw-for-docker.mjs` 封裝。 +- `source=npm` 只接受 `openclaw@beta`、`openclaw@latest`,或精確的 OpenClaw 發行版本,例如 `openclaw@2026.4.27-beta.2`。這用於已發佈 beta/stable 的 acceptance。 +- `source=ref` 會打包受信任的 `package_ref` 分支、標籤或完整 commit SHA。解析器會擷取 OpenClaw 分支/標籤、驗證所選 commit 可從儲存庫分支歷史或發行標籤到達、在 detached worktree 中安裝相依套件,並用 `scripts/package-openclaw-for-docker.mjs` 打包。 - `source=url` 會下載 HTTPS `.tgz`;必須提供 `package_sha256`。 -- `source=artifact` 會從 `artifact_run_id` 和 `artifact_name` 下載一個 `.tgz`;`package_sha256` 是選用,但外部共享的 artifact 應提供。 +- `source=artifact` 會從 `artifact_run_id` 和 `artifact_name` 下載一個 `.tgz`;`package_sha256` 是選用,但外部共享的成品應提供。 -請將 `workflow_ref` 和 `package_ref` 分開。`workflow_ref` 是執行測試的受信任 workflow/harness 程式碼。`package_ref` 是在 `source=ref` 時會被封裝的來源 commit。這讓目前的測試 harness 可以驗證較舊的受信任來源 commit,而不必執行舊的 workflow 邏輯。 +請將 `workflow_ref` 和 `package_ref` 分開。`workflow_ref` 是執行測試的受信任工作流程/測試框架程式碼。`package_ref` 是當 `source=ref` 時會被打包的來源 commit。這讓目前的測試框架可驗證較舊的受信任來源 commit,而不執行舊的工作流程邏輯。 -### 套件組合設定檔 +### 套件設定檔 - `smoke` — `npm-onboard-channel-agent`, `gateway-network`, `config-reload` -- `package` — `npm-onboard-channel-agent`, `doctor-switch`, `update-channel-switch`, `upgrade-survivor`, `bundled-channel-deps-compat`, `plugins-offline`, `plugin-update` +- `package` — `npm-onboard-channel-agent`, `doctor-switch`, `update-channel-switch`, `upgrade-survivor`, `published-upgrade-survivor`, `bundled-channel-deps-compat`, `plugins-offline`, `plugin-update` - `product` — `package` 加上 `mcp-channels`, `cron-mcp-cleanup`, `openai-web-search-minimal`, `openwebui` - `full` — 含 OpenWebUI 的完整 Docker 發行路徑區塊 -- `custom` — 精確的 `docker_lanes`;當 `suite_profile=custom` 時必填 +- `custom` — 精確的 `docker_lanes`;當 `suite_profile=custom` 時為必填 -`package` 設定檔使用離線 Plugin 覆蓋範圍,因此已發布套件驗證不會受限於即時 ClawHub 可用性。選用的 Telegram lane 會在 `NPM Telegram Beta E2E` 中重用 `package-under-test` artifact,並保留已發布 npm 規格路徑供獨立 dispatch 使用。 +`package` 設定檔使用離線 plugin 涵蓋範圍,因此已發佈套件驗證不會受限於即時 ClawHub 可用性。選用的 Telegram 路徑會在 `NPM Telegram Beta E2E` 中重用 `package-under-test` 成品,並保留已發佈 npm 規格路徑供獨立派送使用。 -發行檢查會以 `source=ref`、`package_ref=`、`workflow_ref=`、`suite_profile=custom`、`docker_lanes='bundled-channel-deps-compat plugins-offline'` 和 `telegram_mode=mock-openai` 呼叫 Package Acceptance。發行路徑 Docker 區塊涵蓋重疊的 package/update/Plugin lane;Package Acceptance 會針對同一個已解析套件 tarball 保留 artifact-native 的內建 channel 相容性、離線 Plugin 和 Telegram 證明。跨 OS 發行檢查仍涵蓋 OS 專屬的 onboarding、安裝程式和平台行為;package/update 產品驗證應從 Package Acceptance 開始。Windows 封裝與安裝程式全新 lane 也會驗證已安裝套件可從原始絕對 Windows 路徑匯入 browser-control override。OpenAI 跨 OS agent-turn smoke 會在已設定時預設使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否則使用 `openai/gpt-5.4-mini`,因此安裝與 Gateway 證明會保持快速且具決定性。 +發行檢查會以 `source=ref`、`package_ref=`、`workflow_ref=`、`suite_profile=custom`、`docker_lanes='bundled-channel-deps-compat plugins-offline'` 和 `telegram_mode=mock-openai` 呼叫 Package Acceptance。發行路徑 Docker 區塊涵蓋重疊的套件/update/plugin 路徑;Package Acceptance 則保留對同一個已解析套件 tarball 的成品原生 bundled-channel 相容性、離線 plugin 與 Telegram 證明。跨 OS 發行檢查仍涵蓋 OS 特定的 onboarding、安裝程式與平台行為;套件/update 產品驗證應從 Package Acceptance 開始。Windows packaged 與 installer fresh 路徑也會驗證已安裝套件可以從原始的 Windows 絕對路徑匯入 browser-control 覆寫。OpenAI 跨 OS agent-turn 冒煙測試在已設定時預設使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否則使用 `openai/gpt-5.4-mini`,因此安裝與 Gateway 證明能保持快速且具確定性。 -### 舊版相容性期間 +### 舊版相容性窗口 -Package Acceptance 對已發布套件有有限的舊版相容性期間。到 `2026.4.25` 為止的套件,包括 `2026.4.25-beta.*`,可以使用相容性路徑: +Package Acceptance 對已發佈套件有有限的舊版相容性窗口。到 `2026.4.25` 為止的套件,包括 `2026.4.25-beta.*`,可使用相容性路徑: -- `dist/postinstall-inventory.json` 中已知的私有 QA 項目可以指向 tarball 省略的檔案; -- 當套件未公開該旗標時,`doctor-switch` 可以略過 `gateway install --wrapper` 持久化子案例; -- `update-channel-switch` 可以從 tarball 衍生的假 git fixture 中剪除缺失的 `pnpm.patchedDependencies`,並可記錄缺失的持久化 `update.channel`; -- Plugin smoke 可以讀取舊版安裝記錄位置,或接受缺失的 marketplace 安裝記錄持久化; -- `plugin-update` 可以允許 config metadata 遷移,但仍要求安裝記錄和無重新安裝行為保持不變。 +- `dist/postinstall-inventory.json` 中已知的私人 QA 項目可能指向 tarball 省略的檔案; +- 當套件未公開該旗標時,`doctor-switch` 可略過 `gateway install --wrapper` 持久化子案例; +- `update-channel-switch` 可從 tarball 衍生的假 git fixture 中修剪缺少的 `pnpm.patchedDependencies`,且可記錄缺少的持久化 `update.channel`; +- plugin 冒煙測試可讀取舊版安裝記錄位置,或接受缺少 marketplace 安裝記錄持久化; +- `plugin-update` 可允許設定中繼資料遷移,同時仍要求安裝記錄與不重新安裝行為保持不變。 -已發布的 `2026.4.26` 套件也可以對已出貨的本機 build metadata stamp 檔案發出警告。後續套件必須滿足現代合約;相同條件會失敗,而不是警告或略過。 +已發佈的 `2026.4.26` 套件也可能對已出貨的本機建置中繼資料戳記檔提出警告。之後的套件必須符合現代合約;相同條件會失敗,而不是警告或略過。 ### 範例 @@ -238,152 +250,152 @@ gh workflow run package-acceptance.yml \ -f docker_lanes='install-e2e plugin-update' ``` -偵錯失敗的 package acceptance 執行時,請從 `resolve_package` 摘要開始,確認套件來源、版本和 SHA-256。接著檢查 `docker_acceptance` 子執行及其 Docker artifacts:`.artifacts/docker-tests/**/summary.json`、`failures.json`、lane 記錄、階段計時,以及重新執行命令。請優先重新執行失敗的 package 設定檔或精確的 Docker lanes,而不是重新執行完整發行驗證。 +偵錯失敗的 package acceptance 執行時,請從 `resolve_package` 摘要開始,以確認套件來源、版本與 SHA-256。接著檢查 `docker_acceptance` 子執行及其 Docker 成品:`.artifacts/docker-tests/**/summary.json`、`failures.json`、路徑記錄、階段計時與重新執行指令。偏好重新執行失敗的套件設定檔或精確的 Docker 路徑,而不是重新執行完整發行驗證。 -## 安裝 smoke +## 安裝冒煙測試 -獨立的 `Install Smoke` workflow 會透過自己的 `preflight` job 重用相同的範圍腳本。它會將 smoke 覆蓋範圍拆分為 `run_fast_install_smoke` 和 `run_full_install_smoke`。 +獨立的 `Install Smoke` 工作流程透過自己的 `preflight` 工作重用相同的範圍腳本。它將冒煙測試涵蓋範圍分成 `run_fast_install_smoke` 和 `run_full_install_smoke`。 -- **快速路徑**會針對觸及 Docker/package 表面、內建 Plugin 套件/manifest 變更,或 Docker smoke jobs 會執行的核心 Plugin/channel/Gateway/Plugin SDK 表面的 pull request 執行。僅來源的內建 Plugin 變更、僅測試編輯和僅文件編輯不會保留 Docker worker。快速路徑會建置 root Dockerfile image 一次、檢查 CLI、執行 agents delete shared-workspace CLI smoke、執行容器 gateway-network e2e、驗證內建 extension build arg,並在 240 秒彙總命令逾時內執行受限的內建 Plugin Docker 設定檔(每個情境的 Docker 執行另有上限)。 -- **完整路徑**會保留 QR 套件安裝與安裝程式 Docker/update 覆蓋範圍,用於夜間排程執行、手動 dispatch、workflow-call 發行檢查,以及真正觸及安裝程式/package/Docker 表面的 pull request。在完整模式中,install-smoke 會準備或重用一個目標 SHA 的 GHCR root Dockerfile smoke image,然後將 QR 套件安裝、root Dockerfile/Gateway smoke、安裝程式/update smoke,以及快速內建 Plugin Docker E2E 作為獨立 job 執行,讓安裝程式工作不必等待 root image smoke。 +- **快速路徑** 會在 pull request 觸及 Docker/套件表面、bundled plugin 套件/manifest 變更,或 Docker 冒煙工作會測試到的核心 plugin/channel/gateway/Plugin SDK 表面時執行。僅來源的 bundled plugin 變更、僅測試編輯,以及僅文件編輯不會保留 Docker worker。快速路徑會建置一次根 Dockerfile 映像、檢查 CLI、執行 agents delete shared-workspace CLI 冒煙測試、執行容器 gateway-network e2e、驗證 bundled extension 建置參數,並在 240 秒彙總指令逾時下執行有界的 bundled-plugin Docker 設定檔(每個情境的 Docker 執行會另外設上限)。 +- **完整路徑** 會保留 QR 套件安裝與安裝程式 Docker/update 涵蓋範圍,用於 nightly 排程執行、手動派送、workflow-call 發行檢查,以及真正觸及安裝程式/套件/Docker 表面的 pull request。在完整模式中,install-smoke 會準備或重用一個目標 SHA 的 GHCR 根 Dockerfile 冒煙映像,然後將 QR 套件安裝、根 Dockerfile/gateway 冒煙測試、安裝程式/update 冒煙測試,以及快速 bundled-plugin Docker E2E 作為獨立工作執行,讓安裝程式工作不會排在根映像冒煙測試後面等待。 -`main` push(包括 merge commit)不會強制完整路徑;當變更範圍邏輯會在 push 上要求完整覆蓋範圍時,workflow 會保留快速 Docker smoke,並將完整 install smoke 留給夜間或發行驗證。 +`main` 推送(包括 merge commit)不會強制完整路徑;當變更範圍邏輯會在推送上要求完整涵蓋範圍時,工作流程會保留快速 Docker 冒煙測試,並將完整 install smoke 留給 nightly 或發行驗證。 -慢速的 Bun 全域安裝 image-provider smoke 由 `run_bun_global_install_smoke` 另行控管。它會在夜間排程和發行檢查 workflow 中執行,手動 `Install Smoke` dispatch 可以選擇加入,但 pull request 和 `main` push 不會。QR 和安裝程式 Docker 測試保留各自專注於安裝的 Dockerfile。 +較慢的 Bun 全域安裝 image-provider 冒煙測試由 `run_bun_global_install_smoke` 另行控管。它會在 nightly 排程和發行檢查工作流程中執行,手動 `Install Smoke` 派送也可選擇加入,但 pull request 和 `main` 推送不會執行。QR 與安裝程式 Docker 測試保留各自專注於安裝的 Dockerfile。 ## 本機 Docker E2E -`pnpm test:docker:all` 會預先建置一個共享 live-test image、將 OpenClaw 封裝一次為 npm tarball,並建置兩個共享 `scripts/e2e/Dockerfile` images: +`pnpm test:docker:all` 會預先建置一個共用的即時測試映像、將 OpenClaw 打包一次為 npm tarball,並建置兩個共用的 `scripts/e2e/Dockerfile` 映像: -- 用於安裝程式/update/Plugin 相依性 lane 的裸 Node/Git runner; -- 將相同 tarball 安裝到 `/app` 的功能 image,用於一般功能 lane。 +- 一個裸 Node/Git runner,用於安裝程式/update/plugin 相依性路徑; +- 一個功能映像,會將同一個 tarball 安裝到 `/app`,用於一般功能路徑。 -Docker lane 定義位於 `scripts/lib/docker-e2e-scenarios.mjs`,planner 邏輯位於 `scripts/lib/docker-e2e-plan.mjs`,runner 只會執行選取的 plan。排程器會使用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 為每個 lane 選擇 image,然後以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行 lanes。 +Docker 路徑定義位於 `scripts/lib/docker-e2e-scenarios.mjs`,規劃器邏輯位於 `scripts/lib/docker-e2e-plan.mjs`,runner 只會執行所選計畫。排程器會使用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 依路徑選取映像,然後以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行路徑。 -### 可調參數 +### 可調整項目 -| 變數 | 預設值 | 用途 | +| 變數 | 預設值 | 目的 | | -------------------------------------- | ------- | --------------------------------------------------------------------------------------------- | -| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 一般 lane 的 main-pool slot 數量。 | -| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | provider-sensitive tail-pool slot 數量。 | -| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 並行 live lane 上限,避免 provider 進行節流。 | -| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 並行 npm install lane 上限。 | -| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 並行 multi-service lane 上限。 | -| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | lane 啟動之間的 stagger,用來避免 Docker daemon create 風暴;設為 `0` 表示不 stagger。 | -| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每個 lane 的 fallback 逾時(120 分鐘);選取的 live/tail lane 會使用更嚴格的上限。 | -| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` 會列印排程器 plan 而不執行 lanes。 | -| `OPENCLAW_DOCKER_ALL_LANES` | unset | 逗號分隔的精確 lane 清單;會略過 cleanup smoke,讓 agents 可以重現一個失敗的 lane。 | +| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 一般路徑的主集區 slot 數量。 | +| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 對供應商敏感的尾端集區 slot 數量。 | +| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 並行即時路徑上限,避免供應商節流。 | +| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 並行 npm 安裝路徑上限。 | +| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 並行多服務路徑上限。 | +| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | 路徑啟動之間的錯開時間,用於避免 Docker daemon create 風暴;設為 `0` 表示不錯開。 | +| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每個路徑的備援逾時(120 分鐘);選定的即時/尾端路徑會使用更緊的上限。 | +| `OPENCLAW_DOCKER_ALL_DRY_RUN` | 未設定 | `1` 會列印排程器計畫而不執行路徑。 | +| `OPENCLAW_DOCKER_ALL_LANES` | 未設定 | 以逗號分隔的精確路徑清單;略過清理冒煙測試,讓代理程式能重現單一失敗路徑。 | -比有效上限更重的 lane 仍可從空 pool 啟動,然後單獨執行直到釋放容量。本機彙總會 preflight Docker、移除過期的 OpenClaw E2E 容器、發出 active-lane 狀態、保存 lane 計時以便 longest-first 排序,並預設在第一次失敗後停止排程新的 pooled lane。 +比其有效上限更重的路徑仍可從空集區啟動,然後單獨執行直到釋放容量。本機彙總會預先檢查 Docker、移除過時的 OpenClaw E2E 容器、發出作用中路徑狀態、持久化路徑計時以供最長優先排序,且預設在第一次失敗後停止排程新的集區路徑。 -### 可重用的 live/E2E workflow +### 可重用的即時/E2E 工作流程 -可重用的 live/E2E workflow 會詢問 `scripts/test-docker-all.mjs --plan-json` 需要哪個 package、image kind、live image、lane 和 credential 覆蓋範圍。`scripts/docker-e2e.mjs` 接著會將該 plan 轉換為 GitHub outputs 和摘要。它會透過 `scripts/package-openclaw-for-docker.mjs` 封裝 OpenClaw、下載目前執行的 package artifact,或從 `package_artifact_run_id` 下載 package artifact;驗證 tarball inventory;當 plan 需要已安裝 package 的 lane 時,透過 Blacksmith 的 Docker layer cache 建置並推送以 package digest 標記的 bare/functional GHCR Docker E2E images;並重用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` inputs 或現有的 package-digest images,而不是重新建置。Docker image pull 會以每次嘗試 180 秒的受限逾時重新嘗試,讓卡住的 registry/cache stream 能快速重試,而不是消耗大部分 CI 關鍵路徑。 +可重用的 live/E2E 工作流程會詢問 `scripts/test-docker-all.mjs --plan-json` 需要哪些套件、映像種類、live 映像、lane 和認證覆蓋範圍。`scripts/docker-e2e.mjs` 接著會把該計畫轉換成 GitHub 輸出和摘要。它會透過 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw、下載目前執行中的套件成品,或從 `package_artifact_run_id` 下載套件成品;驗證 tarball 清單;在計畫需要套件安裝 lane 時,透過 Blacksmith 的 Docker layer cache 建置並推送以套件 digest 標記的 bare/functional GHCR Docker E2E 映像;並且重用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 輸入或現有的套件 digest 映像,而不是重新建置。Docker 映像拉取會以每次嘗試 180 秒的有界逾時重試,讓卡住的 registry/cache 串流能快速重試,而不是消耗 CI 關鍵路徑的大部分時間。 ### 發行路徑區塊 -發行 Docker 覆蓋範圍會以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行較小的分塊 jobs,因此每個區塊只會 pull 它需要的 image kind,並透過相同的加權排程器執行多個 lanes: +發行 Docker 覆蓋範圍會以較小的分塊工作執行,並搭配 `OPENCLAW_SKIP_DOCKER_BUILD=1`,因此每個區塊只會拉取它需要的映像種類,並透過同一個加權排程器執行多個 lane: - `OPENCLAW_DOCKER_ALL_PROFILE=release-path` - `OPENCLAW_DOCKER_ALL_CHUNK=core | package-update-openai | package-update-anthropic | package-update-core | plugins-runtime-plugins | plugins-runtime-services | plugins-runtime-install-a..h | bundled-channels` -目前發行版本的 Docker 分塊為 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a` 到 `plugins-runtime-install-h`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b`,以及 `bundled-channels-contracts`。彙總的 `bundled-channels` 分塊仍可用於手動一次性重新執行,而 `plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍保留為彙總的 Plugin/runtime 別名。`install-e2e` 通道別名仍是兩個供應商安裝程式通道的彙總手動重新執行別名。`bundled-channels` 分塊會執行拆分的 `bundled-channel-*` 和 `bundled-channel-update-*` 通道,而不是序列式全包的 `bundled-channel-deps` 通道。 +目前的發行 Docker 區塊是 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a` 到 `plugins-runtime-install-h`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b`,以及 `bundled-channels-contracts`。彙總 `bundled-channels` 區塊仍可用於手動一次性重新執行,而 `plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍是彙總 Plugin/runtime 別名。`install-e2e` lane 別名仍是兩個 provider 安裝器 lane 的彙總手動重新執行別名。`bundled-channels` 區塊會執行拆分後的 `bundled-channel-*` 和 `bundled-channel-update-*` lane,而不是序列式全包的 `bundled-channel-deps` lane。 -當完整發行路徑涵蓋範圍要求時,OpenWebUI 會併入 `plugins-runtime-services`,並且只在僅限 OpenWebUI 的派送中保留獨立的 `openwebui` 分塊。內建通道更新通道會針對暫時性 npm 網路失敗重試一次。 +當完整 release-path 覆蓋範圍要求 OpenWebUI 時,OpenWebUI 會併入 `plugins-runtime-services`,並且只在 OpenWebUI-only dispatch 時保留獨立的 `openwebui` 區塊。Bundled-channel 更新 lane 會針對暫時性的 npm 網路失敗重試一次。 -每個分塊都會上傳 `.artifacts/docker-tests/`,其中包含通道記錄、計時、`summary.json`、`failures.json`、階段計時、排程器計畫 JSON、慢速通道表格,以及每個通道的重新執行命令。工作流程的 `docker_lanes` 輸入會針對已準備的映像執行所選通道,而不是分塊作業,這會將失敗通道的偵錯限制在一個目標 Docker 作業內,並為該次執行準備、下載或重用套件成品;如果所選通道是即時 Docker 通道,目標作業會在本機建置即時測試映像以供該次重新執行使用。產生的每個通道 GitHub 重新執行命令會在這些值存在時包含 `package_artifact_run_id`、`package_artifact_name` 和已準備映像輸入,因此失敗的通道可以重用失敗執行中的確切套件與映像。 +每個區塊都會上傳 `.artifacts/docker-tests/`,其中包含 lane 記錄、時間、`summary.json`、`failures.json`、階段時間、排程器計畫 JSON、慢速 lane 表格,以及每個 lane 的重新執行指令。工作流程的 `docker_lanes` 輸入會針對已準備的映像執行所選 lane,而不是執行分塊工作,這會將失敗 lane 的偵錯範圍限制在一個目標 Docker 工作,並為該次執行準備、下載或重用套件成品;如果所選 lane 是 live Docker lane,目標工作會在本機為該次重新執行建置 live-test 映像。產生的每個 lane GitHub 重新執行指令會在這些值存在時包含 `package_artifact_run_id`、`package_artifact_name` 和已準備的映像輸入,因此失敗的 lane 可以重用失敗執行中的確切套件和映像。 ```bash -pnpm test:docker:rerun # download Docker artifacts and print combined/per-lane targeted rerun commands -pnpm test:docker:timings # slow-lane and phase critical-path summaries +pnpm test:docker:rerun # 下載 Docker 成品並列印合併/每個 lane 的目標重新執行指令 +pnpm test:docker:timings # 慢速 lane 和階段關鍵路徑摘要 ``` -排程的即時/E2E 工作流程會每日執行完整的發行路徑 Docker 套件。 +排程的 live/E2E 工作流程每天執行完整的 release-path Docker 套件。 ## Plugin 預發行 -`Plugin Prerelease` 是成本較高的產品/套件涵蓋範圍,因此它是由 `Full Release Validation` 或明確的操作員派送的獨立工作流程。一般 pull request、`main` 推送,以及獨立的手動 CI 派送會保持該套件關閉。它會在八個擴充工作器之間平衡內建 Plugin 測試;這些擴充分片作業每次最多執行兩個 Plugin 設定群組,每個群組使用一個 Vitest 工作器和較大的 Node heap,讓匯入量大的 Plugin 批次不會建立額外的 CI 作業。 +`Plugin Prerelease` 是成本較高的產品/套件覆蓋範圍,因此它是一個獨立工作流程,由 `Full Release Validation` 或明確的操作員觸發。一般 pull request、`main` push,以及獨立的手動 CI dispatch 都會停用該套件。它會在八個 extension worker 之間平衡 bundled plugin 測試;這些 extension shard 工作一次最多執行兩個 Plugin 設定群組,每個群組使用一個 Vitest worker 和較大的 Node heap,因此 import-heavy 的 Plugin 批次不會建立額外 CI 工作。僅限發行的 Docker 預發行路徑會以小群組批次執行目標 Docker lane,以避免為一到三分鐘的工作保留數十個 runner。 ## QA Lab -QA Lab 在主要的智慧範圍工作流程之外有專用的 CI 通道。 +QA Lab 在主要 smart-scoped 工作流程之外有專用 CI lane。 -- `Parity gate` 工作流程會在相符的 PR 變更和手動派送時執行;它會建置私有 QA runtime,並比較模擬 GPT-5.5 和 Opus 4.6 agentic 套件。 -- `QA-Lab - All Lanes` 工作流程會在 `main` 上每晚執行,並在手動派送時執行;它會將模擬同位閘門、即時 Matrix 通道,以及即時 Telegram 和 Discord 通道扇出為平行作業。即時作業使用 `qa-live-shared` 環境,而 Telegram/Discord 使用 Convex 租約。 +- `Parity gate` 工作流程會在相符的 PR 變更和手動 dispatch 時執行;它會建置私有 QA runtime,並比較模擬 GPT-5.5 和 Opus 4.6 agentic pack。 +- `QA-Lab - All Lanes` 工作流程會在 `main` 上每晚執行,並在手動 dispatch 時執行;它會將模擬 parity gate、live Matrix lane,以及 live Telegram 和 Discord lane 展開為平行工作。Live 工作使用 `qa-live-shared` 環境,而 Telegram/Discord 使用 Convex lease。 -發行檢查會使用確定性的模擬供應商和符合模擬資格的模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)執行 Matrix 和 Telegram 即時傳輸通道,因此通道合約會與即時模型延遲和一般供應商 Plugin 啟動隔離。即時傳輸 Gateway 會停用記憶搜尋,因為 QA 同位會另外涵蓋記憶行為;供應商連線能力由獨立的即時模型、原生供應商和 Docker 供應商套件涵蓋。 +發行檢查會搭配確定性的 mock provider 和 mock-qualified 模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)執行 Matrix 和 Telegram live transport lane,因此 channel contract 會與 live 模型延遲和一般 provider-plugin 啟動隔離。live transport Gateway 會停用記憶體搜尋,因為 QA parity 會另外覆蓋記憶體行為;provider 連線能力則由獨立的 live 模型、原生 provider 和 Docker provider 套件覆蓋。 -Matrix 會在排程和發行閘門使用 `--profile fast`,並且只在簽出的 CLI 支援時加入 `--fail-fast`。CLI 預設值和手動工作流程輸入仍為 `all`;手動 `matrix_profile=all` 派送一律會將完整 Matrix 涵蓋範圍分片為 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作業。 +Matrix 會針對排程和發行 gate 使用 `--profile fast`,且只有在 checkout 的 CLI 支援時才加入 `--fail-fast`。CLI 預設值和手動工作流程輸入仍為 `all`;手動 `matrix_profile=all` dispatch 一律會將完整 Matrix 覆蓋範圍切分成 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 工作。 -`OpenClaw Release Checks` 也會在發行核准前執行發行關鍵的 QA Lab 通道;它的 QA 同位閘門會將候選與基準套件作為平行通道作業執行,接著將兩個成品下載到一個小型報告作業中進行最終同位比較。 +`OpenClaw Release Checks` 也會在發行核准前執行發行關鍵的 QA Lab lane;其 QA parity gate 會將候選 pack 和 baseline pack 作為平行 lane 工作執行,接著把兩者的成品下載到小型報告工作中,以進行最終 parity 比較。 -除非變更實際觸及 QA runtime、模型套件同位,或同位工作流程擁有的表面,否則不要將 PR 合併路徑置於 `Parity gate` 之後。對於一般通道、設定、文件或單元測試修正,請將其視為選用訊號,並遵循範圍化 CI/檢查證據。 +除非變更實際觸及 QA runtime、model-pack parity,或 parity 工作流程擁有的 surface,否則不要把 PR landing path 放在 `Parity gate` 之後。對一般 channel、設定、文件或單元測試修正,將其視為選用訊號,並遵循 scoped CI/check 證據。 ## CodeQL -`CodeQL` 工作流程刻意作為狹窄的第一輪安全掃描器,而不是完整儲存庫掃描。每日、手動和非草稿 pull request 守門執行會掃描 Actions 工作流程程式碼,以及最高風險的 JavaScript/TypeScript 表面,並使用高信心安全查詢,篩選為高/嚴重 `security-severity`。 +`CodeQL` 工作流程刻意是狹窄的第一輪安全掃描器,而不是完整 repository 掃描。每日、手動和非草稿 pull request guard 執行會掃描 Actions 工作流程程式碼,以及最高風險的 JavaScript/TypeScript surface,並使用篩選為高/嚴重 `security-severity` 的高信心安全查詢。 -pull request 守門保持輕量:它只會在 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 底下的變更啟動,並執行與排程工作流程相同的高信心安全矩陣。Android 和 macOS CodeQL 不包含在 PR 預設值中。 +pull request guard 保持輕量:它只會針對 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 底下的變更啟動,並執行與排程工作流程相同的高信心安全矩陣。Android 和 macOS CodeQL 不在 PR 預設值中。 ### 安全類別 -| 類別 | 表面 | +| 類別 | Surface | | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| `/codeql-security-high/core-auth-secrets` | Auth、秘密、sandbox、cron 和 Gateway 基準 | -| `/codeql-security-high/channel-runtime-boundary` | 核心通道實作合約,以及通道 Plugin runtime、Gateway、Plugin SDK、秘密、稽核接觸點 | -| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、網路防護、web-fetch,以及 Plugin SDK SSRF policy 表面 | -| `/codeql-security-high/mcp-process-tool-boundary` | MCP 伺服器、程序執行協助工具、輸出交付,以及 agent 工具執行閘門 | -| `/codeql-security-high/plugin-trust-boundary` | Plugin 安裝、載入器、manifest、registry、runtime-dependency staging、source-loading,以及 Plugin SDK 套件合約信任表面 | +| `/codeql-security-high/core-auth-secrets` | Auth、secrets、sandbox、Cron 和 Gateway baseline | +| `/codeql-security-high/channel-runtime-boundary` | 核心 channel 實作 contract,加上 channel Plugin runtime、Gateway、Plugin SDK、secrets、audit touchpoint | +| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP parsing、network guard、web-fetch,以及 Plugin SDK SSRF policy surface | +| `/codeql-security-high/mcp-process-tool-boundary` | MCP server、process execution helper、outbound delivery,以及 agent tool-execution gate | +| `/codeql-security-high/plugin-trust-boundary` | Plugin install、loader、manifest、registry、runtime-dependency staging、source-loading,以及 Plugin SDK package contract trust surface | -### 平台特定安全分片 +### 平台特定安全 shard -- `CodeQL Android Critical Security` — 排程的 Android 安全分片。為 CodeQL 在工作流程健全性接受的最小 Blacksmith Linux runner 上手動建置 Android 應用程式。上傳到 `/codeql-critical-security/android` 底下。 -- `CodeQL macOS Critical Security` — 每週/手動 macOS 安全分片。在 Blacksmith macOS 上為 CodeQL 手動建置 macOS 應用程式,從上傳的 SARIF 中篩除依賴項建置結果,並上傳到 `/codeql-critical-security/macos` 底下。因為即使乾淨時 macOS 建置也主導 runtime,所以保留在每日預設值之外。 +- `CodeQL Android Critical Security` — 排程的 Android 安全 shard。為 CodeQL 在 workflow sanity 接受的最小 Blacksmith Linux runner 上手動建置 Android app。上傳到 `/codeql-critical-security/android` 底下。 +- `CodeQL macOS Critical Security` — 每週/手動 macOS 安全 shard。在 Blacksmith macOS 上為 CodeQL 手動建置 macOS app,從上傳的 SARIF 中過濾掉依賴項建置結果,並上傳到 `/codeql-critical-security/macos` 底下。因為 macOS 建置即使乾淨也會主導 runtime,所以保留在每日預設值之外。 ### 關鍵品質類別 -`CodeQL Critical Quality` 是對應的非安全分片。它只在較小的 Blacksmith Linux runner 上,針對狹窄的高價值表面執行錯誤嚴重性、非安全的 JavaScript/TypeScript 品質查詢。其 pull request 守門刻意小於排程設定檔:非草稿 PR 只會針對 agent 命令/模型/工具執行與回覆派送程式碼、設定 schema/migration/IO 程式碼、auth/secrets/sandbox/security 程式碼、核心通道和內建通道 Plugin runtime、Gateway protocol/server-method、memory runtime/SDK glue、MCP/process/outbound delivery、provider runtime/model catalog、session diagnostics/delivery queues、Plugin loader、Plugin SDK/package-contract,或 Plugin SDK reply runtime 變更,執行相符的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 設定和品質工作流程變更會執行全部十二個 PR 品質分片。 +`CodeQL Critical Quality` 是對應的非安全 shard。它只會在較小的 Blacksmith Linux runner 上,針對狹窄的高價值 surface 執行 error-severity、非安全 JavaScript/TypeScript 品質查詢。它的 pull request guard 刻意比排程 profile 更小:非草稿 PR 只會針對 agent command/model/tool execution 和 reply dispatch code、config schema/migration/IO code、auth/secrets/sandbox/security code、核心 channel 和 bundled channel Plugin runtime、Gateway protocol/server-method、memory runtime/SDK glue、MCP/process/outbound delivery、provider runtime/model catalog、session diagnostics/delivery queues、Plugin loader、Plugin SDK/package-contract,或 Plugin SDK reply runtime 變更,執行相符的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` shard。CodeQL 設定和品質工作流程變更會執行全部十二個 PR quality shard。 -手動派送接受: +手動 dispatch 接受: ``` profile=all|agent-runtime-boundary|config-boundary|core-auth-secrets|channel-runtime-boundary|gateway-runtime-boundary|memory-runtime-boundary|mcp-process-runtime-boundary|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary ``` -狹窄設定檔是用於單獨執行一個品質分片的教學/迭代掛鉤。 +狹窄的 profile 是用來單獨執行一個 quality shard 的教學/迭代 hook。 -| 類別 | 介面 | -| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `/codeql-critical-quality/core-auth-secrets` | Auth、祕密、沙箱、Cron 與 Gateway 安全邊界程式碼 | -| `/codeql-critical-quality/config-boundary` | 設定結構描述、遷移、正規化與 IO 合約 | -| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 協定結構描述與伺服器方法合約 | -| `/codeql-critical-quality/channel-runtime-boundary` | 核心通道與隨附通道 Plugin 實作合約 | -| `/codeql-critical-quality/agent-runtime-boundary` | 命令執行、模型/提供者分派、自動回覆分派與佇列,以及 ACP 控制平面執行階段合約 | -| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 伺服器與工具橋接、程序監督輔助工具,以及對外傳遞合約 | -| `/codeql-critical-quality/memory-runtime-boundary` | 記憶體主機 SDK、記憶體執行階段外觀、記憶體 Plugin SDK 別名、記憶體執行階段啟用黏合層,以及記憶體 doctor 命令 | -| `/codeql-critical-quality/session-diagnostics-boundary` | 回覆佇列內部、工作階段傳遞佇列、對外工作階段繫結/傳遞輔助工具、診斷事件/記錄組合包介面,以及工作階段 doctor CLI 合約 | -| `/codeql-critical-quality/plugin-sdk-reply-runtime` | Plugin SDK 傳入回覆分派、回覆承載/分塊/執行階段輔助工具、通道回覆選項、傳遞佇列,以及工作階段/執行緒繫結輔助工具 | -| `/codeql-critical-quality/provider-runtime-boundary` | 模型型錄正規化、提供者驗證與探索、提供者執行階段註冊、提供者預設值/型錄,以及網頁/搜尋/擷取/嵌入註冊表 | +| 類別 | 表面 | +| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `/codeql-critical-quality/core-auth-secrets` | 驗證、密鑰、沙盒、Cron 和 Gateway 安全邊界程式碼 | +| `/codeql-critical-quality/config-boundary` | 設定結構描述、遷移、正規化和 IO 合約 | +| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 協定結構描述和伺服器方法合約 | +| `/codeql-critical-quality/channel-runtime-boundary` | 核心通道和內建通道 Plugin 實作合約 | +| `/codeql-critical-quality/agent-runtime-boundary` | 命令執行、模型/供應商分派、自動回覆分派和佇列,以及 ACP 控制平面執行階段合約 | +| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 伺服器和工具橋接、程序監督協助工具,以及對外傳遞合約 | +| `/codeql-critical-quality/memory-runtime-boundary` | 記憶體主機 SDK、記憶體執行階段 facade、記憶體 Plugin SDK 別名、記憶體執行階段啟用黏合層,以及記憶體 doctor 命令 | +| `/codeql-critical-quality/session-diagnostics-boundary` | 回覆佇列內部、工作階段傳遞佇列、對外工作階段繫結/傳遞協助工具、診斷事件/記錄套件表面,以及工作階段 doctor CLI 合約 | +| `/codeql-critical-quality/plugin-sdk-reply-runtime` | Plugin SDK 傳入回覆分派、回覆承載/分塊/執行階段協助工具、通道回覆選項、傳遞佇列,以及工作階段/執行緒繫結協助工具 | +| `/codeql-critical-quality/provider-runtime-boundary` | 模型目錄正規化、供應商驗證與探索、供應商執行階段註冊、供應商預設值/目錄,以及網頁/搜尋/擷取/嵌入註冊表 | | `/codeql-critical-quality/ui-control-plane` | 控制 UI 啟動程序、本機持久化、Gateway 控制流程,以及任務控制平面執行階段合約 | -| `/codeql-critical-quality/web-media-runtime-boundary` | 核心網頁擷取/搜尋、媒體 IO、媒體理解、影像生成,以及媒體生成執行階段合約 | -| `/codeql-critical-quality/plugin-boundary` | 載入器、註冊表、公開介面,以及 Plugin SDK 進入點合約 | -| `/codeql-critical-quality/plugin-sdk-package-contract` | 已發布套件端 Plugin SDK 原始碼與 Plugin 套件合約輔助工具 | +| `/codeql-critical-quality/web-media-runtime-boundary` | 核心網頁擷取/搜尋、媒體 IO、媒體理解、影像生成和媒體生成執行階段合約 | +| `/codeql-critical-quality/plugin-boundary` | 載入器、註冊表、公開表面和 Plugin SDK 進入點合約 | +| `/codeql-critical-quality/plugin-sdk-package-contract` | 已發布套件端 Plugin SDK 原始碼和 Plugin 套件合約協助工具 | -品質會與安全性分開,因此品質發現可以排程、衡量、停用或擴充,而不會掩蓋安全性訊號。Swift、Python 與隨附 Plugin 的 CodeQL 擴充,應只在窄範圍設定檔具備穩定執行階段與訊號之後,作為具範圍或分片的後續工作加回。 +品質與安全性保持分離,讓品質發現項目可以排程、量測、停用或擴展,而不會遮蔽安全性訊號。Swift、Python 和內建 Plugin 的 CodeQL 擴展,應只在窄範圍設定檔具備穩定執行階段和訊號後,作為具範圍或分片的後續工作加回。 ## 維護工作流程 -### 文件 Agent +### Docs Agent -`Docs Agent` 工作流程是一條事件驅動的 Codex 維護通道,用於讓現有文件與最近落地的變更保持一致。它沒有純排程:在 `main` 上成功的非機器人推送 CI 執行可以觸發它,手動派送也可以直接執行它。當 `main` 已前進,或上一小時內已建立另一個未略過的 Docs Agent 執行時,工作流程執行叫用會略過。執行時,它會審查從前一個未略過的 Docs Agent 來源 SHA 到目前 `main` 的提交範圍,因此一次每小時執行可以涵蓋自上次文件巡檢以來累積的所有 main 變更。 +`Docs Agent` 工作流程是一條事件驅動的 Codex 維護通道,用於讓既有文件與最近落地的變更保持一致。它沒有純排程:`main` 上成功的非機器人 push CI 執行可以觸發它,也可以透過手動分派直接執行。當 `main` 已向前推進,或過去一小時內已建立另一個未略過的 Docs Agent 執行時,工作流程執行叫用會略過。執行時,它會檢閱從前一次未略過的 Docs Agent 來源 SHA 到目前 `main` 的提交範圍,因此每小時一次的執行可以涵蓋自上次文件檢查以來累積的所有 main 變更。 -### 測試效能 Agent +### Test Performance Agent -`Test Performance Agent` 工作流程是一條事件驅動的 Codex 維護通道,用於處理緩慢測試。它沒有純排程:在 `main` 上成功的非機器人推送 CI 執行可以觸發它,但如果另一個工作流程執行叫用在該 UTC 日已經執行或正在執行,它就會略過。手動派送會略過該每日活動閘門。此通道會建立完整套件分組 Vitest 效能報告,讓 Codex 只進行小型且保留覆蓋率的測試效能修正,而不是大範圍重構,接著重新執行完整套件報告,並拒絕會降低通過基準測試數量的變更。如果基準有失敗測試,Codex 只能修正明顯的失敗,而且 Agent 後的完整套件報告必須通過,才會提交任何內容。當 `main` 在機器人推送落地前前進時,此通道會將已驗證的修補重新基底化、重新執行 `pnpm check:changed`,並重試推送;有衝突的過期修補會被略過。它使用 GitHub 託管的 Ubuntu,因此 Codex 動作可以維持與文件 Agent 相同的 drop-sudo 安全姿態。 +`Test Performance Agent` 工作流程是一條事件驅動的 Codex 維護通道,用於處理緩慢測試。它沒有純排程:`main` 上成功的非機器人 push CI 執行可以觸發它,但如果同一 UTC 日已有另一個工作流程執行叫用已執行或正在執行,則會略過。手動分派會繞過該每日活動閘門。此通道會建立完整套件分組的 Vitest 效能報告,讓 Codex 只進行保留覆蓋率的小型測試效能修正,而不是大範圍重構,接著重新執行完整套件報告,並拒絕會降低通過基準測試數量的變更。如果基準有失敗測試,Codex 只能修正明顯的失敗,且代理之後的完整套件報告必須通過,才會提交任何內容。當 `main` 在機器人 push 落地前向前推進時,此通道會 rebase 已驗證的修補程式、重新執行 `pnpm check:changed`,並重試 push;有衝突的過期修補程式會被略過。它使用 GitHub 託管的 Ubuntu,因此 Codex action 可以保持與 docs agent 相同的 drop-sudo 安全姿態。 ### 合併後的重複 PR -`Duplicate PRs After Merge` 工作流程是用於落地後重複項清理的手動維護者工作流程。它預設為 dry-run,且只有在 `apply=true` 時才會關閉明確列出的 PR。在變更 GitHub 之前,它會驗證已落地的 PR 已合併,並且每個重複項都有共用的參照 issue,或有重疊的變更 hunk。 +`Duplicate PRs After Merge` 工作流程是用於落地後重複項清理的手動維護者工作流程。它預設為 dry-run,且只有在 `apply=true` 時才會關閉明確列出的 PR。在變更 GitHub 之前,它會驗證已落地 PR 已合併,且每個重複項都有共用的引用 issue 或重疊的已變更 hunk。 ```bash gh workflow run duplicate-after-merge.yml \ @@ -392,27 +404,27 @@ gh workflow run duplicate-after-merge.yml \ -f apply=true ``` -## 本機檢查閘門與變更路由 +## 本機檢查閘門和變更路由 -本機變更通道邏輯位於 `scripts/changed-lanes.mjs`,並由 `scripts/check-changed.mjs` 執行。該本機檢查閘門對架構邊界比廣泛 CI 平台範圍更嚴格: +本機變更通道邏輯位於 `scripts/changed-lanes.mjs`,並由 `scripts/check-changed.mjs` 執行。該本機檢查閘門對架構邊界的要求,比廣泛的 CI 平台範圍更嚴格: -- 核心生產變更會執行核心生產與核心測試型別檢查,加上核心 lint/guard; -- 僅核心測試變更只會執行核心測試型別檢查,加上核心 lint; -- 擴充功能生產變更會執行擴充功能生產與擴充功能測試型別檢查,加上擴充功能 lint; -- 僅擴充功能測試變更會執行擴充功能測試型別檢查,加上擴充功能 lint; -- 公開 Plugin SDK 或 Plugin 合約變更會擴大到擴充功能型別檢查,因為擴充功能依賴這些核心合約(Vitest 擴充功能掃描仍是明確的測試工作); -- 僅發布中繼資料的版本升級會執行目標式版本/設定/根相依性檢查; -- 未知根目錄/設定變更會以安全失敗方式進入所有檢查通道。 +- 核心生產程式碼變更會執行核心 prod 和核心 test 型別檢查,以及核心 lint/guards; +- 僅核心測試變更只會執行核心 test 型別檢查和核心 lint; +- 擴充生產程式碼變更會執行擴充 prod 和擴充 test 型別檢查,以及擴充 lint; +- 僅擴充測試變更會執行擴充 test 型別檢查和擴充 lint; +- 公開 Plugin SDK 或 Plugin 合約變更會擴展到擴充型別檢查,因為擴充依賴這些核心合約(Vitest 擴充掃描仍是明確的測試工作); +- 僅發布中繼資料的版本遞增會執行目標版本/設定/根相依性檢查; +- 未知的根目錄/設定變更會 fail safe 到所有檢查通道。 -本機變更測試路由位於 `scripts/test-projects.test-support.mjs`,且刻意比 `check:changed` 更便宜:直接測試編輯會執行自身,原始碼編輯優先使用明確對應,接著是同層測試與匯入圖相依項。共用群組房間傳遞設定是其中一個明確對應:群組可見回覆設定、來源回覆傳遞模式,或訊息工具系統提示的變更,會透過核心回覆測試加上 Discord 與 Slack 傳遞回歸測試路由,因此共用預設值變更會在第一次 PR 推送前失敗。只有在變更的範圍涵蓋整個測試框架,使得便宜的對應集合不是可信代理時,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 +本機變更測試路由位於 `scripts/test-projects.test-support.mjs`,且刻意比 `check:changed` 更便宜:直接測試編輯會執行自身,原始碼編輯優先使用明確對應,接著是同層測試和匯入圖相依項。共用群組房間傳遞設定是其中一個明確對應:群組可見回覆設定、來源回覆傳遞模式,或訊息工具系統提示的變更,會路由至核心回覆測試加上 Discord 和 Slack 傳遞迴歸測試,讓共用預設值變更在第一次 PR push 前失敗。只有當變更範圍大到涵蓋整個 harness,使便宜的對應集合不再是可信代理時,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 ## Testbox 驗證 -從 repo 根目錄執行 Testbox,並優先使用全新預熱的 box 進行廣泛證明。在把緩慢閘門花在已重用、過期,或剛回報異常大量同步的 box 之前,先在 box 內執行 `pnpm testbox:sanity`。 +從 repo root 執行 Testbox,並優先使用新預熱的 box 進行廣泛證明。在對已重用、已過期,或剛回報非預期大型同步的 box 花時間執行慢速閘門前,先在 box 內執行 `pnpm testbox:sanity`。 -當必要根目錄檔案(例如 `pnpm-lock.yaml`)消失,或 `git status --short` 顯示至少 200 個已追蹤刪除時,健全性檢查會快速失敗。這通常代表遠端同步狀態不是 PR 的可信副本;請停止該 box 並預熱新的,而不是偵錯產品測試失敗。對於刻意的大量刪除 PR,請為該健全性執行設定 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。 +當必要的根目錄檔案(例如 `pnpm-lock.yaml`)消失,或 `git status --short` 顯示至少 200 個受追蹤刪除時,sanity check 會快速失敗。這通常表示遠端同步狀態不是 PR 的可信副本;停止該 box,改為預熱新的 box,而不是除錯產品測試失敗。對於刻意的大量刪除 PR,為該 sanity 執行設定 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。 -`pnpm testbox:run` 也會終止本機 Blacksmith CLI 叫用,如果它停留在同步階段超過五分鐘且沒有同步後輸出。設定 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可停用該 guard,或針對異常大的本機 diff 使用更大的毫秒值。 +`pnpm testbox:run` 也會終止在同步階段停留超過五分鐘且沒有同步後輸出的本機 Blacksmith CLI 叫用。設定 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可停用該 guard,或針對異常大型本機 diff 使用較大的毫秒值。 ## 相關 diff --git a/docs/zh-TW/cli/models.md b/docs/zh-TW/cli/models.md index ea165e817..199334045 100644 --- a/docs/zh-TW/cli/models.md +++ b/docs/zh-TW/cli/models.md @@ -1,29 +1,29 @@ --- read_when: - - 您想要變更預設模型或檢視提供者驗證狀態 - - 您想掃描可用的模型/供應商並除錯身分驗證設定檔 -summary: '`openclaw models` 的 CLI 參考(status/list/set/scan、別名、備援機制、身分驗證)' + - 你想變更預設模型或檢視提供者驗證狀態 + - 您想掃描可用的模型/提供者並偵錯驗證設定檔 +summary: '`openclaw models` 的 CLI 參考(status/list/set/scan、別名、備援、身分驗證)' title: 模型 x-i18n: - generated_at: "2026-04-30T02:54:49Z" + generated_at: "2026-05-01T02:44:44Z" model: gpt-5.5 provider: openai - source_hash: 95e2361989b583f7f52947dad1faaaba44dc6a5f58719cc2e83c13fce7c33adc + source_hash: 538d3e4808329737fdc044dc6e14e5c7c78052e75d8a8b3b257b1ebd821c84d1 source_path: cli/models.md workflow: 16 --- # `openclaw models` -模型探索、掃描與設定(預設模型、備援、驗證設定檔)。 +模型探索、掃描與設定(預設模型、備援、認證設定檔)。 相關: - 供應商 + 模型:[模型](/zh-TW/providers/models) -- 模型選擇概念 + `/models` 斜線指令:[模型概念](/zh-TW/concepts/models) -- 供應商驗證設定:[開始使用](/zh-TW/start/getting-started) +- 模型選擇概念 + `/models` 斜線命令:[模型概念](/zh-TW/concepts/models) +- 供應商認證設定:[開始使用](/zh-TW/start/getting-started) -## 常用指令 +## 常用命令 ```bash openclaw models status @@ -32,64 +32,69 @@ openclaw models set openclaw models scan ``` -`openclaw models status` 會顯示解析後的預設值/備援,以及驗證概覽。 -當供應商使用量快照可用時,OAuth/API 金鑰狀態區段會包含 -供應商使用時段與配額快照。 -目前的使用時段供應商:Anthropic、GitHub Copilot、Gemini CLI、OpenAI -Codex、MiniMax、Xiaomi 和 z.ai。使用量驗證在可用時會來自供應商專屬掛鉤; -否則 OpenClaw 會退回使用來自驗證設定檔、環境或設定中相符的 OAuth/API 金鑰 +`openclaw models status` 會顯示解析後的預設/備援模型,以及認證概覽。 +當供應商用量快照可用時,OAuth/API 金鑰狀態區段會包含 +供應商用量視窗與配額快照。 +目前支援用量視窗的供應商:Anthropic、GitHub Copilot、Gemini CLI、OpenAI +Codex、MiniMax、Xiaomi 與 z.ai。用量認證會在可用時來自供應商專屬掛鉤; +否則 OpenClaw 會退回使用認證設定檔、環境變數或設定中相符的 OAuth/API 金鑰 憑證。 -在 `--json` 輸出中,`auth.providers` 是感知環境/設定/儲存區的供應商 -概覽,而 `auth.oauth` 只代表驗證儲存區設定檔健康狀態。 -加入 `--probe` 可對每個已設定的供應商設定檔執行即時驗證探測。 -探測是真實請求(可能會消耗權杖並觸發速率限制)。 -使用 `--agent ` 檢查已設定代理程式的模型/驗證狀態。省略時, -此指令會使用已設定的預設代理程式,除非已設定 -`OPENCLAW_AGENT_DIR`/`PI_CODING_AGENT_DIR`。 -探測列可能來自驗證設定檔、環境憑證或 `models.json`。 +在 `--json` 輸出中,`auth.providers` 是感知環境變數/設定/儲存區的供應商 +概覽,而 `auth.oauth` 只代表認證儲存區設定檔健康狀態。 +加入 `--probe` 可對每個已設定的供應商設定檔執行即時認證探測。 +探測是真實請求(可能會消耗 token 並觸發速率限制)。 +使用 `--agent ` 檢查已設定代理程式的模型/認證狀態。省略時, +命令會在已設定時使用 `OPENCLAW_AGENT_DIR`/`PI_CODING_AGENT_DIR`,否則使用 +已設定的預設代理程式。 +探測列可來自認證設定檔、環境變數憑證或 `models.json`。 -備註: +注意事項: - `models set ` 接受 `provider/model` 或別名。 -- `models list` 是唯讀的:它會讀取設定、驗證設定檔、現有目錄 - 狀態,以及供應商擁有的目錄列,但不會重寫 +- `models list` 是唯讀的:它會讀取設定、認證設定檔、既有目錄 + 狀態與供應商擁有的目錄列,但不會重寫 `models.json`。 -- `Auth` 欄位是供應商層級且唯讀。它會根據本機 - 驗證設定檔中繼資料、環境標記、已設定的供應商金鑰、本機供應商 - 標記、AWS Bedrock 環境/設定檔標記,以及 Plugin 合成驗證中繼資料計算; +- `Auth` 欄位是供應商層級且唯讀。它是根據本機 + 認證設定檔中繼資料、環境變數標記、已設定的供應商金鑰、本機供應商 + 標記、AWS Bedrock 環境變數/設定檔標記,以及 Plugin 合成認證中繼資料計算而成; 它不會載入供應商執行階段、讀取鑰匙圈祕密、呼叫供應商 API,或證明精確的逐模型執行就緒狀態。 -- `models list --all --provider ` 可包含來自 Plugin 資訊清單或隨附供應商目錄中繼資料的供應商擁有靜態目錄 - 列,即使你尚未向該供應商完成驗證。這些列在設定相符驗證之前仍會顯示為 - 不可用。 +- `models list --all --provider ` 可以包含來自 Plugin 資訊清單或隨附供應商目錄中繼資料的供應商擁有靜態目錄 + 列,即使你尚未向該供應商完成認證也一樣。這些列仍會顯示為 + 不可用,直到設定相符認證為止。 +- `models list` 會在供應商目錄 + 探索緩慢時讓控制平面保持回應。預設與已設定檢視會在短暫等待後退回使用已設定或 + 合成模型列,並讓探索在 + 背景中完成。當你需要精確完整的已探索目錄,且 + 願意等待供應商探索時,請使用 `--all`。 - 廣泛的 `models list --all` 會將資訊清單目錄列合併到登錄列之上, 而不載入供應商執行階段補充掛鉤。供應商篩選的資訊清單 快速路徑只使用標記為 `static` 的供應商;標記為 `refreshable` 的供應商 - 保持以登錄/快取為基礎,並附加資訊清單列作為補充,而 + 保持以登錄/快取為基礎並附加資訊清單列作為補充,而 標記為 `runtime` 的供應商則保持使用登錄/執行階段探索。 -- `models list` 會將原生模型中繼資料與執行階段上限分開。在表格 - 輸出中,當有效執行階段上限不同於原生內容視窗時,`Ctx` 會顯示 - `contextTokens/contextWindow`;當供應商公開該上限時,JSON 列會包含 `contextTokens`。 -- `models list --provider ` 會依供應商 ID 篩選,例如 `moonshot` 或 +- `models list` 會保持原生模型中繼資料與執行階段上限分開。在表格 + 輸出中,當有效執行階段 + 上限不同於原生上下文視窗時,`Ctx` 會顯示 `contextTokens/contextWindow`;當供應商公開該上限時,JSON 列會包含 `contextTokens`。 +- `models list --provider ` 依供應商 id 篩選,例如 `moonshot` 或 `openai-codex`。它不接受互動式供應商 選擇器中的顯示標籤,例如 `Moonshot AI`。 -- 模型參照會透過分割**第一個** `/` 來解析。如果模型 ID 包含 `/`(OpenRouter 風格),請包含供應商前綴(範例:`openrouter/moonshotai/kimi-k2`)。 -- 如果你省略供應商,OpenClaw 會先將輸入解析為別名,接著 - 解析為該精確模型 ID 的唯一已設定供應商相符項,最後才 - 退回至已設定的預設供應商並顯示淘汰警告。 +- 模型參照會透過在**第一個** `/` 分割來剖析。如果模型 ID 包含 `/`(OpenRouter 風格),請包含供應商前綴(範例:`openrouter/moonshotai/kimi-k2`)。 +- 如果省略供應商,OpenClaw 會先將輸入解析為別名,接著 + 解析為該精確模型 id 在已設定供應商中的唯一相符項目,之後才 + 退回使用已設定的預設供應商並顯示棄用警告。 如果該供應商不再公開已設定的預設模型,OpenClaw - 會退回到第一個已設定的供應商/模型,而不是顯示 + 會退回使用第一個已設定的供應商/模型,而不是顯示 過時的已移除供應商預設值。 -- `models status` 可能會在驗證輸出中,針對非祕密佔位符顯示 `marker()`(例如 `OPENAI_API_KEY`、`secretref-managed`、`minimax-oauth`、`oauth:chutes`、`ollama-local`),而不是將其遮罩為祕密。 +- `models status` 可能會在認證輸出中為非祕密預留位置顯示 `marker()`(例如 `OPENAI_API_KEY`、`secretref-managed`、`minimax-oauth`、`oauth:chutes`、`ollama-local`),而不是將它們遮罩為祕密。 ### 模型掃描 -`models scan` 會讀取 OpenRouter 的公開 `:free` 目錄,並為 -備援用途排序候選項。目錄本身是公開的,因此僅中繼資料掃描不需要 +`models scan` 會讀取 OpenRouter 的公開 `:free` 目錄,並針對 +備援用途為候選項目排序。目錄本身是公開的,因此僅中繼資料掃描不需要 OpenRouter 金鑰。 -預設情況下,OpenClaw 會嘗試透過即時模型呼叫探測工具與圖片支援。 -如果未設定 OpenRouter 金鑰,此指令會退回至僅中繼資料 +預設情況下,OpenClaw 會嘗試透過即時模型呼叫探測工具與影像支援。 +如果未設定 OpenRouter 金鑰,命令會退回僅中繼資料 輸出,並說明 `:free` 模型仍需要 `OPENROUTER_API_KEY` 才能進行 探測與推論。 @@ -108,8 +113,8 @@ OpenRouter 金鑰。 - `--set-image` - `--json` -`--set-default` 和 `--set-image` 需要即時探測;僅中繼資料掃描 -結果只供參考,不會套用至設定。 +`--set-default` 與 `--set-image` 需要即時探測;僅中繼資料掃描 +結果僅供參考,不會套用到設定。 ### 模型狀態 @@ -118,17 +123,17 @@ OpenRouter 金鑰。 - `--json` - `--plain` - `--check`(結束碼 1=已過期/缺少,2=即將過期) -- `--probe`(即時探測已設定的驗證設定檔) +- `--probe`(即時探測已設定的認證設定檔) - `--probe-provider `(探測單一供應商) -- `--probe-profile `(重複或以逗號分隔的設定檔 ID) +- `--probe-profile `(重複或以逗號分隔的設定檔 id) - `--probe-timeout ` - `--probe-concurrency ` - `--probe-max-tokens ` -- `--agent `(已設定的代理程式 ID;覆寫 `OPENCLAW_AGENT_DIR`/`PI_CODING_AGENT_DIR`) +- `--agent `(已設定代理程式 id;覆寫 `OPENCLAW_AGENT_DIR`/`PI_CODING_AGENT_DIR`) -`--json` 會保留 stdout 供 JSON 承載使用。驗證設定檔、供應商, -以及啟動診斷會路由到 stderr,讓指令碼可以將 stdout 直接管線傳送 -到 `jq` 等工具。 +`--json` 會保留 stdout 給 JSON 承載使用。認證設定檔、供應商, +以及啟動診斷會路由到 stderr,因此指令碼可以將 stdout 直接管線傳入 +`jq` 等工具。 探測狀態分類: @@ -141,15 +146,15 @@ OpenRouter 金鑰。 - `unknown` - `no_model` -可預期的探測詳細資料/原因碼案例: +可預期的探測詳細資訊/原因碼案例: - `excluded_by_auth_order`:已存在儲存的設定檔,但明確的 - `auth.order.` 省略了它,因此探測會回報此排除,而不是 + `auth.order.` 省略了它,因此探測會回報該排除狀態,而不是 嘗試它。 - `missing_credential`、`invalid_expires`、`expired`、`unresolved_ref`: 設定檔存在,但不符合資格/無法解析。 -- `no_model`:供應商驗證存在,但 OpenClaw 無法為該供應商解析可探測的 - 模型候選項。 +- `no_model`:供應商認證存在,但 OpenClaw 無法為該供應商解析出可探測的 + 模型候選項目。 ## 別名 + 備援 @@ -158,7 +163,7 @@ openclaw models aliases list openclaw models fallbacks list ``` -## 驗證設定檔 +## 認證設定檔 ```bash openclaw models auth add @@ -167,15 +172,15 @@ openclaw models auth setup-token --provider openclaw models auth paste-token ``` -`models auth add` 是互動式驗證輔助工具。它可以啟動供應商驗證 -流程(OAuth/API 金鑰),或根據你選擇的 -供應商,引導你手動貼上權杖。 +`models auth add` 是互動式認證輔助工具。它可以啟動供應商認證 +流程(OAuth/API 金鑰),或依據你選擇的 +供應商,引導你手動貼上 token。 -`models auth login` 會執行供應商 Plugin 的驗證流程(OAuth/API 金鑰)。使用 -`openclaw plugins list` 查看已安裝哪些供應商。 -使用 `openclaw models auth --agent ` 可將驗證結果寫入 -特定已設定的代理程式儲存區。父層 `--agent` 旗標會由 -`add`、`login`、`setup-token`、`paste-token` 和 `login-github-copilot` 遵循。 +`models auth login` 會執行供應商 Plugin 的認證流程(OAuth/API 金鑰)。使用 +`openclaw plugins list` 查看已安裝的供應商。 +使用 `openclaw models auth --agent ` 將認證結果寫入 +特定已設定代理程式儲存區。父層 `--agent` 旗標會被 +`add`、`login`、`setup-token`、`paste-token` 與 `login-github-copilot` 採用。 範例: @@ -183,21 +188,23 @@ openclaw models auth paste-token openclaw models auth login --provider openai-codex --set-default ``` -備註: +注意事項: -- `setup-token` 和 `paste-token` 仍是供公開權杖驗證方法的供應商使用的通用權杖指令。 -- `setup-token` 需要互動式 TTY,並會執行供應商的權杖驗證 - 方法(當該供應商公開 `setup-token` 方法時,預設使用該方法)。 -- `paste-token` 接受在其他地方產生或來自自動化的權杖字串。 -- `paste-token` 需要 `--provider`,會提示輸入權杖值,並將 - 它寫入預設設定檔 ID `:manual`,除非你傳入 +- `setup-token` 與 `paste-token` 仍是供應商的通用 token 命令, + 供公開 token 認證方法的供應商使用。 +- `setup-token` 需要互動式 TTY,並執行供應商的 token 認證 + 方法(當該供應商公開 + 其中一個方法時,預設使用該供應商的 `setup-token` 方法)。 +- `paste-token` 接受在其他地方產生或來自自動化的 token 字串。 +- `paste-token` 需要 `--provider`,會提示輸入 token 值,並將 + 它寫入預設設定檔 id `:manual`,除非你傳入 `--profile-id`。 -- `paste-token --expires-in ` 會根據相對持續時間(例如 `365d` 或 `12h`)儲存絕對權杖到期時間。 -- Anthropic 備註:Anthropic 人員告訴我們,OpenClaw 風格的 Claude CLI 使用方式已再次被允許,因此除非 Anthropic 發布新政策,OpenClaw 會將 Claude CLI 重用與 `claude -p` 使用視為此整合已核准的方式。 -- Anthropic `setup-token` / `paste-token` 仍可作為受支援的 OpenClaw 權杖路徑使用,但 OpenClaw 現在會優先使用 Claude CLI 重用與可用時的 `claude -p`。 +- `paste-token --expires-in ` 會根據相對持續時間(例如 `365d` 或 `12h`)儲存絕對 token 到期時間。 +- Anthropic 注意事項:Anthropic 員工告訴我們 OpenClaw 風格的 Claude CLI 使用方式已再次獲准,因此 OpenClaw 會將 Claude CLI 重用與 `claude -p` 使用方式視為此整合受認可的做法,除非 Anthropic 發布新政策。 +- Anthropic `setup-token` / `paste-token` 仍可作為受支援的 OpenClaw token 路徑使用,但 OpenClaw 現在會在可用時優先使用 Claude CLI 重用與 `claude -p`。 ## 相關 - [CLI 參考](/zh-TW/cli) - [模型選擇](/zh-TW/concepts/model-providers) -- [模型故障轉移](/zh-TW/concepts/model-failover) +- [模型容錯移轉](/zh-TW/concepts/model-failover) diff --git a/docs/zh-TW/concepts/commitments.md b/docs/zh-TW/concepts/commitments.md index a45014c45..080d87833 100644 --- a/docs/zh-TW/concepts/commitments.md +++ b/docs/zh-TW/concepts/commitments.md @@ -1,38 +1,37 @@ --- read_when: - - 你想讓 OpenClaw 記住自然的後續提問 - - 您想了解推斷的報到與提醒有何不同 - - 你想要檢視或解除後續承諾事項 + - 你希望 OpenClaw 記住自然的後續提問 + - 你想了解推斷式簽到與提醒有何不同 + - 您想檢閱或解除後續承諾 sidebarTitle: Commitments -summary: 針對非精確提醒的例行確認所推斷出的後續記憶 -title: 推斷出的承諾事項 +summary: 針對非精確提醒的簽到所推斷的後續追蹤記憶 +title: 推斷出的承諾 x-i18n: - generated_at: "2026-04-30T02:58:34Z" + generated_at: "2026-05-01T02:44:57Z" model: gpt-5.5 provider: openai - source_hash: 3f51af0ac2c9841258fbeeb8f2f98dba6f438b8e0c9433f601a0504d6ef27111 + source_hash: 78841d87fe749aa5b04a967218396df1c1a7884c5767b09215c96aee34fa2014 source_path: concepts/commitments.md workflow: 16 --- -承諾是短期存在的後續記憶。啟用後,OpenClaw 可以 -注意到某段對話建立了未來回訪的機會,並記得 -稍後再提出。 +承諾是短期存在的後續追蹤記憶。啟用後,OpenClaw 可以 +注意到某段對話建立了未來回訪的機會,並記得稍後再提出。 範例: -- 你提到明天有面試。OpenClaw 之後可能會回訪。 -- 你說你很疲憊。OpenClaw 稍後可能會詢問你是否睡了覺。 -- 代理說它會在某件事改變後跟進。OpenClaw 可能會追蹤 - 這個未閉合循環。 +- 你提到明天有面試。OpenClaw 可能會在之後回訪。 +- 你說你很疲憊。OpenClaw 可能稍後詢問你是否睡了覺。 +- 代理表示會在某件事改變後跟進。OpenClaw 可能會追蹤 + 那個未閉合事項。 承諾不是像 `MEMORY.md` 那樣的持久事實,也不是精確的 -提醒。它們位於記憶與自動化之間:OpenClaw 會記住一個 -受對話約束的義務,然後由 Heartbeat 在到期時送達。 +提醒。它們介於記憶與自動化之間:OpenClaw 會記住一個 +綁定於對話的義務,然後由 Heartbeat 在到期時送出。 ## 啟用承諾 -承諾預設為關閉。在設定中啟用: +承諾預設為關閉。請在設定中啟用: ```bash openclaw config set commitments.enabled true @@ -50,54 +49,57 @@ openclaw config set commitments.maxPerDay 3 } ``` -`commitments.maxPerDay` 會限制每個代理工作階段在滾動一天內 -可送達的推論後續追蹤數量。預設值為 `3`。 +`commitments.maxPerDay` 會限制在滾動的一天內,每個代理工作階段 +可以送出的推斷後續追蹤數量。預設值為 `3`。 ## 運作方式 -在代理回覆後,OpenClaw 可能會在獨立脈絡中執行隱藏的背景 -擷取流程。該流程只尋找推論出的後續承諾。它不會寫入可見 -對話,也不會要求主要代理推理擷取結果。 +代理回覆後,OpenClaw 可能會在獨立脈絡中執行隱藏的背景擷取流程。 +該流程只尋找推斷出的後續追蹤承諾。它不會寫入可見對話,也不會要求主要代理 +針對擷取流程進行推理。 -當它找到高信心候選項時,OpenClaw 會儲存一項承諾,其中包含: +找到高信心候選項目時,OpenClaw 會儲存一項承諾,其中包含: -- 代理 ID +- 代理 id - 工作階段金鑰 -- 原始頻道與送達目標 +- 原始頻道與傳送目標 - 到期時間範圍 - 簡短的建議回訪內容 -- 足夠的來源脈絡,供 Heartbeat 判斷是否送出 +- 供 Heartbeat 判斷是否送出的非指令性中繼資料 -送達透過 Heartbeat 進行。當承諾到期時,Heartbeat 會將該承諾 -加入同一代理與頻道範圍的 Heartbeat 回合。模型可以送出一則 -自然的回訪,或回覆 `HEARTBEAT_OK` 來略過。 +傳送會透過 Heartbeat 進行。承諾到期時,Heartbeat +會將該承諾加入同一代理與頻道範圍的 Heartbeat 回合中。 +模型可以送出一則自然的回訪訊息,或回覆 `HEARTBEAT_OK` 來略過它。 +如果 Heartbeat 設定為 `target: "none"`,到期承諾會保留在內部, +不會送出外部回訪。承諾傳送提示不會重播原始對話文字,而到期承諾的 Heartbeat 回合 +會在沒有 OpenClaw 工具的情況下執行。 -OpenClaw 絕不會在寫入推論承諾後立即送達。到期時間會被限制為 -至少在承諾建立後的一個 Heartbeat 間隔之後,因此後續追蹤不會在 -被推論出的同一刻回響回來。 +OpenClaw 絕不會在寫入推斷出的承諾後立即傳送它。 +到期時間會被限制在承諾建立後至少一個 Heartbeat 間隔之後, +因此後續追蹤不會在被推斷出的同一刻回響。 ## 範圍 -承諾的範圍限定在建立時的精確代理與頻道脈絡中。在 Discord 與 -某個代理對話時推論出的後續追蹤,不會由另一個代理、另一個頻道 -或無關的工作階段送達。 +承諾會限定在建立時的確切代理與頻道脈絡中。在 Discord 中與某個代理對話時 +推斷出的後續追蹤,不會由另一個代理、另一個頻道或不相關的工作階段送出。 -這個範圍是此功能的一部分。自然回訪應該感覺像同一段對話的延續, +此範圍是此功能的一部分。自然回訪應該感覺像同一段對話的延續, 而不是全域提醒系統。 ## 承諾與提醒 -| 需求 | 使用 | +| 需求 | 使用 | | ----------------------------------------------- | ---------------------------------------- | -| "下午 3 點提醒我" | [排程工作](/zh-TW/automation/cron-jobs) | -| "20 分鐘後提醒我" | [排程工作](/zh-TW/automation/cron-jobs) | -| "每個工作日執行這份報告" | [排程工作](/zh-TW/automation/cron-jobs) | -| "我明天有面試" | 承諾 | -| "我整晚沒睡" | 承諾 | -| "如果我沒有回覆這個開放討論串就跟進" | 承諾 | +| "Remind me at 3 PM" | [排程任務](/zh-TW/automation/cron-jobs) | +| "Ping me in 20 minutes" | [排程任務](/zh-TW/automation/cron-jobs) | +| "Run this report every weekday" | [排程任務](/zh-TW/automation/cron-jobs) | +| "I have an interview tomorrow" | 承諾 | +| "I was up all night" | 承諾 | +| "Follow up if I do not answer this open thread" | 承諾 | -精確的使用者請求已屬於排程器路徑。承諾只適用於推論出的後續追蹤: -也就是使用者沒有要求提醒,但對話明確建立了有用未來回訪的時刻。 +精確的使用者請求本來就屬於排程器路徑。承諾只用於 +推斷出的後續追蹤:也就是使用者沒有要求提醒, +但對話明確建立了有用的未來回訪時刻。 ## 管理承諾 @@ -113,11 +115,11 @@ openclaw commitments dismiss cm_abc123 請參閱 [`openclaw commitments`](/zh-TW/cli/commitments) 取得命令參考。 -## 隱私與成本 +## 隱私權與成本 -承諾擷取會使用一次 LLM 流程,因此啟用後會在符合條件的回合之後 -增加背景模型使用量。該流程對使用者可見的對話是隱藏的,但它可以 -讀取判斷是否存在後續追蹤所需的近期交流。 +承諾擷取會使用一次 LLM 流程,因此啟用它會在符合條件的回合後增加背景模型 +用量。該流程會對使用者可見的對話隱藏,但它可以讀取最近的交流,以判斷是否存在 +後續追蹤。 已儲存的承諾是本機 OpenClaw 狀態。它們是操作性記憶,不是 長期記憶。使用以下命令停用此功能: @@ -131,18 +133,17 @@ openclaw config set commitments.enabled false 如果預期的後續追蹤沒有出現: - 確認 `commitments.enabled` 為 `true`。 -- 檢查 `openclaw commitments --all`,查看待處理、已略過、已延後或已過期的 +- 檢查 `openclaw commitments --all` 中是否有待處理、已略過、已延後或已過期的 記錄。 -- 確保代理的 Heartbeat 正在執行。 -- 檢查該代理工作階段是否已達到 `commitments.maxPerDay`。 -- 請記住,精確提醒會被承諾擷取略過,並且應改為出現在 - [排程工作](/zh-TW/automation/cron-jobs) 下。 +- 確保該代理的 Heartbeat 正在執行。 +- 檢查該代理工作階段的 `commitments.maxPerDay` 是否已達上限。 +- 請記住,精確提醒會被承諾擷取略過,應改為出現在[排程任務](/zh-TW/automation/cron-jobs)下。 ## 相關 - [記憶概觀](/zh-TW/concepts/memory) -- [Active Memory](/zh-TW/concepts/active-memory) +- [Active memory](/zh-TW/concepts/active-memory) - [Heartbeat](/zh-TW/gateway/heartbeat) -- [排程工作](/zh-TW/automation/cron-jobs) +- [排程任務](/zh-TW/automation/cron-jobs) - [`openclaw commitments`](/zh-TW/cli/commitments) - [設定參考](/zh-TW/gateway/configuration-reference#commitments) diff --git a/docs/zh-TW/concepts/openclaw-sdk.md b/docs/zh-TW/concepts/openclaw-sdk.md index be9013956..a8cbeef6b 100644 --- a/docs/zh-TW/concepts/openclaw-sdk.md +++ b/docs/zh-TW/concepts/openclaw-sdk.md @@ -1,58 +1,60 @@ --- read_when: - - 你正在建置與 OpenClaw 通訊的外部應用程式、指令碼、儀表板、CI 作業或 IDE 擴充功能 - - 你正在應用程式 SDK 與 Plugin SDK 之間做選擇 - - 你正在與 Gateway 代理程式執行、工作階段、事件、核准、模型或工具整合 + - 你正在建置一個與 OpenClaw 通訊的外部應用程式、指令碼、儀表板、CI 作業或 IDE 擴充功能 + - 您正在 App SDK 與 Plugin SDK 之間做選擇 + - 您正在整合 Gateway 代理程式執行、工作階段、事件、核准、模型或工具 sidebarTitle: App SDK -summary: 供外部應用程式、腳本、儀表板、CI 作業和 IDE 擴充功能使用的公開 OpenClaw 應用程式 SDK -title: OpenClaw 應用程式 SDK +summary: 公開的 OpenClaw App SDK,適用於外部應用程式、指令碼、儀表板、CI 作業和 IDE 擴充功能 +title: OpenClaw 應用程式軟體開發套件 x-i18n: - generated_at: "2026-04-30T03:01:13Z" + generated_at: "2026-05-01T02:44:57Z" model: gpt-5.5 provider: openai - source_hash: 9c46454d172a25d329a796461982dc4307d3720a28df777eda8605996505e38c + source_hash: e531e985ca82026b230b03f8df5ab908d66e2b608e09c46af2ec060b9def0c24 source_path: concepts/openclaw-sdk.md workflow: 16 --- -**OpenClaw App SDK** 是供 OpenClaw 程序外應用程式使用的公開用戶端 API。當腳本、儀表板、CI 工作、IDE 擴充功能,或其他外部應用程式想連接到 Gateway、啟動代理程式執行、串流事件、等待結果、取消工作,或檢查 Gateway 資源時,請使用 `@openclaw/sdk`。 +**OpenClaw App SDK** 是供 OpenClaw 行程外部應用程式使用的公開用戶端 API。當指令碼、儀表板、CI 工作、IDE 擴充功能或其他外部應用程式想要連線到 Gateway、啟動 agent 執行、串流事件、等待結果、取消工作,或檢視 Gateway 資源時,請使用 `@openclaw/sdk`。 App SDK 不同於 [Plugin SDK](/zh-TW/plugins/sdk-overview)。 `@openclaw/sdk` 會從 OpenClaw 外部與 Gateway 通訊。 - `openclaw/plugin-sdk/*` 只供在 OpenClaw 內部執行,並註冊提供者、頻道、工具、掛鉤或可信任執行階段的 plugins 使用。 + `openclaw/plugin-sdk/*` 僅供在 OpenClaw 內部執行,並註冊提供者、頻道、工具、hook 或受信任執行階段的 plugins 使用。 ## 目前提供的內容 -`@openclaw/sdk` 隨附: +`@openclaw/sdk` 目前提供: | 介面 | 狀態 | 功能 | | ------------------------- | ------- | ---------------------------------------------------------------------------- | -| `OpenClaw` | 就緒 | 主要用戶端進入點。擁有傳輸、連線、請求與事件。 | +| `OpenClaw` | 就緒 | 主要用戶端進入點。負責傳輸、連線、請求與事件。 | | `GatewayClientTransport` | 就緒 | 由 Gateway 用戶端支援的 WebSocket 傳輸。 | -| `oc.agents` | 就緒 | 列出、建立、更新、刪除並取得代理程式控制代碼。 | +| `oc.agents` | 就緒 | 列出、建立、更新、刪除與取得 agent handle。 | | `Agent.run()` | 就緒 | 啟動 Gateway `agent` 執行並傳回 `Run`。 | -| `oc.runs` | 就緒 | 建立、取得、等待、取消並串流執行。 | -| `Run.events()` | 就緒 | 串流已正規化的每次執行事件,並為快速執行提供重播。 | +| `oc.runs` | 就緒 | 建立、取得、等待、取消與串流執行。 | +| `Run.events()` | 就緒 | 串流已正規化的每次執行事件,並支援快速執行的重播。 | | `Run.wait()` | 就緒 | 呼叫 `agent.wait` 並傳回穩定的 `RunResult`。 | -| `Run.cancel()` | 就緒 | 依執行 ID 呼叫 `sessions.abort`,可用時會附上工作階段金鑰。 | -| `oc.sessions` | 就緒 | 建立、解析、傳送至、修補、壓縮並取得工作階段控制代碼。 | +| `Run.cancel()` | 就緒 | 依 run id 呼叫 `sessions.abort`,可用時會帶上 session key。 | +| `oc.sessions` | 就緒 | 建立、解析、傳送至、修補、壓縮與取得 session handle。 | | `Session.send()` | 就緒 | 呼叫 `sessions.send` 並傳回 `Run`。 | | `oc.models` | 就緒 | 呼叫 `models.list` 與目前的 `models.authStatus` 狀態 RPC。 | -| `oc.tools` | 部分 | 列出工具目錄與有效工具;尚未接線直接工具叫用。 | -| `oc.approvals` | 就緒 | 透過 Gateway 核准 RPC 列出並解析 exec 核准。 | -| `oc.rawEvents()` | 就緒 | 為進階消費者公開原始 Gateway 事件。 | -| `normalizeGatewayEvent()` | 就緒 | 將原始 Gateway 事件轉換成穩定的 SDK 事件形狀。 | +| `oc.tools` | 部分 | 列出工具目錄與有效工具;尚未接上直接工具呼叫。 | +| `oc.artifacts` | 就緒 | 列出、取得與下載 Gateway transcript artifact。 | +| `oc.approvals` | 就緒 | 透過 Gateway approval RPC 列出並解析 exec approval。 | +| `oc.rawEvents()` | 就緒 | 向進階消費者公開原始 Gateway 事件。 | +| `normalizeGatewayEvent()` | 就緒 | 將原始 Gateway 事件轉換為穩定的 SDK 事件形狀。 | -SDK 也會匯出這些介面使用的核心型別: +SDK 也匯出這些介面使用的核心型別: `AgentRunParams`, `RunResult`, `RunStatus`, `OpenClawEvent`, `OpenClawEventType`, `GatewayEvent`, `OpenClawTransport`, `GatewayRequestOptions`, `SessionCreateParams`, `SessionSendParams`, -`RuntimeSelection`, `EnvironmentSelection`, `WorkspaceSelection`, -`ApprovalMode`,以及相關結果型別。 +`ArtifactSummary`, `ArtifactQuery`, `ArtifactsListResult`, +`ArtifactsGetResult`, `ArtifactsDownloadResult`, `RuntimeSelection`, +`EnvironmentSelection`, `WorkspaceSelection`, `ApprovalMode`,以及相關的結果型別。 -## 連接到 Gateway +## 連線到 Gateway 使用明確的 Gateway URL 建立用戶端,或為測試與嵌入式應用程式執行階段注入自訂傳輸。 @@ -68,9 +70,9 @@ const oc = new OpenClaw({ await oc.connect(); ``` -`new OpenClaw({ gateway: "ws://..." })` 等同於 `url`。建構函式接受 `gateway: "auto"` 選項,但自動 Gateway 探索尚未是獨立的 SDK 功能;當應用程式尚不知道如何探索 Gateway 時,請傳入 `url`。 +`new OpenClaw({ gateway: "ws://..." })` 等同於 `url`。建構函式接受 `gateway: "auto"` 選項,但自動 Gateway 探索尚不是獨立的 SDK 功能;當應用程式尚不知道如何探索 Gateway 時,請傳入 `url`。 -對於測試,請傳入實作 `OpenClawTransport` 的物件: +測試時,傳入實作 `OpenClawTransport` 的物件: ```typescript const oc = new OpenClaw({ @@ -83,9 +85,9 @@ const oc = new OpenClaw({ }); ``` -## 執行代理程式 +## 執行 Agent -當應用程式需要代理程式控制代碼時,使用 `oc.agents.get(id)`,然後呼叫 `agent.run()`。 +當應用程式想要 agent handle 時,使用 `oc.agents.get(id)`,然後呼叫 `agent.run()`。 ```typescript const agent = await oc.agents.get("main"); @@ -108,13 +110,13 @@ const result = await run.wait({ timeoutMs: 120_000 }); console.log(result.status); ``` -像 `openai/gpt-5.5` 這類提供者限定模型參照,會被拆成 Gateway `provider` 與 `model` 覆寫。`timeoutMs` 在 SDK 中維持毫秒,並會為 `agent` RPC 轉換成 Gateway 逾時秒數。 +像 `openai/gpt-5.5` 這樣含提供者限定的模型參照,會拆成 Gateway `provider` 與 `model` 覆寫。`timeoutMs` 在 SDK 中維持毫秒,並會為 `agent` RPC 轉換成 Gateway timeout 秒數。 -`run.wait()` 使用 Gateway `agent.wait` RPC。若等待期限到期時執行仍在進行中,會傳回 `status: "accepted"`,而不是假裝執行本身已逾時。執行階段逾時、中止的執行與已取消的執行,會被正規化為 `timed_out` 或 `cancelled`。 +`run.wait()` 使用 Gateway `agent.wait` RPC。若等待期限到期時執行仍在進行中,會傳回 `status: "accepted"`,而不是假裝執行本身已逾時。執行階段逾時、中止的執行,以及取消的執行都會正規化為 `timed_out` 或 `cancelled`。 -## 建立並重複使用工作階段 +## 建立並重用 Sessions -當應用程式需要持久的對話紀錄狀態時,請使用工作階段。 +當應用程式需要持久的 transcript 狀態時,請使用 sessions。 ```typescript const session = await oc.sessions.create({ @@ -126,7 +128,7 @@ const run = await session.send("Prepare release notes from the current diff."); await run.wait(); ``` -`Session.send()` 呼叫 `sessions.send` 並傳回 `Run`。工作階段控制代碼也支援: +`Session.send()` 會呼叫 `sessions.send` 並傳回 `Run`。Session handle 也支援: ```typescript await session.abort(run.id); @@ -136,7 +138,7 @@ await session.compact({ maxLines: 200 }); ## 串流事件 -SDK 會將原始 Gateway 事件正規化為穩定的 `OpenClawEvent` 信封: +SDK 會將原始 Gateway 事件正規化為穩定的 `OpenClawEvent` 封套: ```typescript type OpenClawEvent = { @@ -157,29 +159,29 @@ type OpenClawEvent = { 常見事件類型包括: | 事件類型 | 來源 Gateway 事件 | -| --------------------- | ------------------------------------------- | -| `run.started` | `agent` 生命週期開始 | -| `run.completed` | `agent` 生命週期結束 | -| `run.failed` | `agent` 生命週期錯誤 | -| `run.cancelled` | 已中止/已取消的生命週期結束 | -| `run.timed_out` | 逾時生命週期結束 | -| `assistant.delta` | 助理串流增量 | -| `assistant.message` | 助理訊息 | -| `thinking.delta` | 思考或計畫串流 | -| `tool.call.started` | 工具/項目/命令開始 | -| `tool.call.delta` | 工具/項目/命令更新 | -| `tool.call.completed` | 工具/項目/命令完成 | -| `tool.call.failed` | 工具/項目/命令失敗或受阻狀態 | -| `approval.requested` | Exec 或 Plugin 核准請求 | -| `approval.resolved` | Exec 或 Plugin 核准解析 | +| --------------------- | ------------------------------------------ | +| `run.started` | `agent` 生命週期開始 | +| `run.completed` | `agent` 生命週期結束 | +| `run.failed` | `agent` 生命週期錯誤 | +| `run.cancelled` | 已中止/已取消的生命週期結束 | +| `run.timed_out` | 逾時生命週期結束 | +| `assistant.delta` | Assistant 串流 delta | +| `assistant.message` | Assistant 訊息 | +| `thinking.delta` | 思考或計畫串流 | +| `tool.call.started` | 工具/項目/命令開始 | +| `tool.call.delta` | 工具/項目/命令更新 | +| `tool.call.completed` | 工具/項目/命令完成 | +| `tool.call.failed` | 工具/項目/命令失敗或被封鎖狀態 | +| `approval.requested` | Exec 或 plugin approval 請求 | +| `approval.resolved` | Exec 或 plugin approval 解析 | | `session.created` | `sessions.changed` 建立 | | `session.updated` | `sessions.changed` 更新 | -| `session.compacted` | `sessions.changed` 壓縮 | -| `task.updated` | 任務更新事件 | -| `artifact.updated` | 修補串流事件 | +| `session.compacted` | `sessions.changed` Compaction | +| `task.updated` | Task 更新事件 | +| `artifact.updated` | Patch 串流事件 | | `raw` | 尚無穩定 SDK 對應的任何事件 | -`Run.events()` 會將事件篩選為單一執行 ID,並為快速執行重播已看過的事件。這表示文件化流程是安全的: +`Run.events()` 會將事件篩選為單一 run id,並為快速執行重播已看過的事件。這代表文件化的流程是安全的: ```typescript const run = await agent.run("Summarize the latest session."); @@ -191,25 +193,38 @@ for await (const event of run.events()) { } ``` -對於整個應用程式的串流,請使用 `oc.events()`。對於原始 Gateway 框架,請使用 `oc.rawEvents()`。 +若要使用應用程式範圍的串流,請使用 `oc.events()`。若要使用原始 Gateway frame,請使用 `oc.rawEvents()`。 -## 模型、工具與核准 +## Models、工具、Artifacts 與 Approvals -模型輔助工具會對應到目前的 Gateway 方法: +模型輔助函式會對應到目前的 Gateway 方法: ```typescript await oc.models.list(); await oc.models.status({ probe: false }); // calls models.authStatus ``` -工具輔助工具會公開 Gateway 目錄與有效工具檢視: +工具輔助函式會公開 Gateway 目錄與有效工具檢視: ```typescript await oc.tools.list(); await oc.tools.effective({ sessionKey: "main" }); ``` -核准輔助工具使用 exec 核准 RPC: +Artifact 輔助函式會公開適用於 session、run 或 task 情境的 Gateway artifact 投影。每次呼叫都需要一個明確的 `sessionKey`、`runId` 或 `taskId` 範圍: + +```typescript +const { artifacts } = await oc.artifacts.list({ sessionKey: "main" }); +const first = artifacts[0]; + +if (first) { + const { artifact } = await oc.artifacts.get(first.id, { sessionKey: "main" }); + const download = await oc.artifacts.download(artifact.id, { sessionKey: "main" }); + console.log(download.encoding, download.url); +} +``` + +Approval 輔助函式使用 exec approval RPC: ```typescript const approvals = await oc.approvals.list(); @@ -218,7 +233,7 @@ await oc.approvals.respond("approval-id", { decision: "approve" }); ## 目前明確不支援 -SDK 包含我們想要的產品模型名稱,但不會默默假裝 Gateway RPC 存在。這些呼叫目前會擲回明確的不支援錯誤: +SDK 包含我們想要的產品模型名稱,但不會默默假裝 Gateway RPC 存在。以下呼叫目前會擲出明確的不支援錯誤: ```typescript await oc.tasks.list(); @@ -227,46 +242,42 @@ await oc.tasks.cancel("task-id"); await oc.tools.invoke("tool-name", {}); -await oc.artifacts.list(); -await oc.artifacts.get("artifact-id"); -await oc.artifacts.download("artifact-id"); - await oc.environments.list(); await oc.environments.create({}); await oc.environments.status("environment-id"); await oc.environments.delete("environment-id"); ``` -每次執行的 `workspace`、`runtime`、`environment` 與 `approvals` 欄位會被型別化為未來形狀,但目前的 Gateway 不支援在 `agent` RPC 上使用這些覆寫。如果呼叫端傳入這些欄位,SDK 會在提交執行前擲回錯誤,讓工作不會意外以預設工作區、執行階段、環境或核准行為執行。 +每次執行的 `workspace`、`runtime`、`environment` 與 `approvals` 欄位已依未來形狀建立型別,但目前 Gateway 不支援在 `agent` RPC 上使用這些覆寫。如果呼叫者傳入這些欄位,SDK 會在提交執行前擲出錯誤,避免工作意外以預設 workspace、runtime、environment 或 approval 行為執行。 -## App SDK 與 Plugin SDK 的比較 +## App SDK 與 Plugin SDK 當程式碼位於 OpenClaw 外部時,請使用 App SDK: -- 啟動或觀察代理程式執行的 Node 腳本 +- 啟動或觀察 agent 執行的 Node 指令碼 - 呼叫 Gateway 的 CI 工作 - 儀表板與管理面板 - IDE 擴充功能 -- 不需要成為頻道 plugins 的外部橋接器 +- 不需要成為頻道 plugins 的外部橋接 - 搭配假或真實 Gateway 傳輸的整合測試 當程式碼在 OpenClaw 內部執行時,請使用 Plugin SDK: -- 提供者 plugins -- 頻道 plugins -- 工具或生命週期掛鉤 -- 代理程式繫具 plugins -- 可信任執行階段輔助工具 +- provider plugins +- channel plugins +- 工具或生命週期 hooks +- agent harness plugins +- 受信任的執行階段輔助函式 -App SDK 程式碼應從 `@openclaw/sdk` 匯入。Plugin 程式碼應從文件化的 `openclaw/plugin-sdk/*` 子路徑匯入。不要混用這兩個契約。 +App SDK 程式碼應從 `@openclaw/sdk` 匯入。Plugin 程式碼應從文件化的 `openclaw/plugin-sdk/*` 子路徑匯入。請勿混用這兩份合約。 ## 相關文件 - [OpenClaw App SDK API 設計](/zh-TW/reference/openclaw-sdk-api-design) - [Gateway RPC 參考](/zh-TW/reference/rpc) -- [代理程式迴圈](/zh-TW/concepts/agent-loop) -- [代理程式執行階段](/zh-TW/concepts/agent-runtimes) -- [工作階段](/zh-TW/concepts/session) -- [背景任務](/zh-TW/automation/tasks) -- [ACP 代理程式](/zh-TW/tools/acp-agents) +- [Agent 迴圈](/zh-TW/concepts/agent-loop) +- [Agent 執行階段](/zh-TW/concepts/agent-runtimes) +- [Sessions](/zh-TW/concepts/session) +- [背景 tasks](/zh-TW/automation/tasks) +- [ACP agents](/zh-TW/tools/acp-agents) - [Plugin SDK 概觀](/zh-TW/plugins/sdk-overview) diff --git a/docs/zh-TW/gateway/protocol.md b/docs/zh-TW/gateway/protocol.md index 37f68dd87..6f407de49 100644 --- a/docs/zh-TW/gateway/protocol.md +++ b/docs/zh-TW/gateway/protocol.md @@ -1,26 +1,33 @@ --- read_when: - 實作或更新 Gateway WS 用戶端 - - 偵錯協定不相符或連線失敗 - - 重新產生協定結構描述/模型 -summary: Gateway WebSocket 協定:交握、訊框、版本管理 + - 偵錯協定不一致或連線失敗 + - 正在重新產生通訊協定結構描述/模型 +summary: Gateway WebSocket 協定:握手、訊框、版本管理 title: Gateway 通訊協定 x-i18n: - generated_at: "2026-04-30T03:08:28Z" + generated_at: "2026-05-01T02:44:49Z" model: gpt-5.5 provider: openai - source_hash: c0d922e9b4b778c333873e551498b905461f30f944e809555b45669ae2f5c404 + source_hash: a6da9ce755b941789ae6b9e866247c8bebb86e9a1530fb8cb258fb0650b24b8a source_path: gateway/protocol.md workflow: 16 --- -Gateway WS 協定是 OpenClaw 的**單一控制平面 + 節點傳輸**。所有用戶端(CLI、網頁 UI、macOS app、iOS/Android 節點、無頭節點)都透過 WebSocket 連線,並在握手時宣告其**角色** + **範圍**。 +Gateway WS 通訊協定是 OpenClaw 的**單一控制平面 + Node 傳輸**。 +所有用戶端(CLI、網頁 UI、macOS app、iOS/Android Node、無頭 +Node)都透過 WebSocket 連線,並在握手時宣告其**角色** + **範圍**。 ## 傳輸 -- WebSocket,文字訊框搭配 JSON 承載。 -- 第一個訊框**必須**是 `connect` 請求。 -- 連線前訊框上限為 64 KiB。握手成功後,用戶端應遵循 `hello-ok.policy.maxPayload` 和 `hello-ok.policy.maxBufferedBytes` 限制。啟用診斷時,過大的入站訊框與緩慢的出站緩衝區會在 gateway 關閉或捨棄受影響訊框前發出 `payload.large` 事件。這些事件會保留大小、限制、介面與安全原因代碼。不會保留訊息本文、附件內容、原始訊框本文、權杖、Cookie 或祕密值。 +- WebSocket,使用含 JSON 承載的文字影格。 +- 第一個影格**必須**是 `connect` 請求。 +- 連線前影格上限為 64 KiB。握手成功後,用戶端應遵循 + `hello-ok.policy.maxPayload` 和 + `hello-ok.policy.maxBufferedBytes` 限制。啟用診斷時, + 過大的入站影格和緩慢的出站緩衝區會在 Gateway 關閉或丟棄受影響的影格前發出 + `payload.large` 事件。這些事件會保留大小、限制、表面和安全原因代碼。 + 它們不會保留訊息本文、附件內容、原始影格本文、權杖、Cookie 或祕密值。 ## 握手(connect) @@ -95,11 +102,16 @@ Gateway → 用戶端: } ``` -當 Gateway 仍在完成啟動附屬程序時,`connect` 請求可能會傳回可重試的 `UNAVAILABLE` 錯誤,且 `details.reason` 設為 `"startup-sidecars"` 並包含 `retryAfterMs`。用戶端應在其整體連線預算內重試該回應,而不是將其呈現為終止性的握手失敗。 +當 Gateway 仍在完成啟動 sidecar 時,`connect` 請求可能會回傳可重試的 +`UNAVAILABLE` 錯誤,並將 `details.reason` 設為 +`"startup-sidecars"`,且包含 `retryAfterMs`。用戶端應在其整體連線預算內重試該回應, +而不是將其呈現為終止性的握手失敗。 -`server`、`features`、`snapshot` 和 `policy` 都是 schema(`src/gateway/protocol/schema/frames.ts`)要求的欄位。`auth` 也為必要欄位,並回報協商後的角色/範圍。`canvasHostUrl` 為選用欄位。 +`server`、`features`、`snapshot` 和 `policy` 都是結構描述要求的欄位 +(`src/gateway/protocol/schema/frames.ts`)。`auth` 也是必要欄位,並回報 +協商後的角色/範圍。`canvasHostUrl` 則為選用。 -未簽發裝置權杖時,`hello-ok.auth` 會回報協商後的權限,且不含權杖欄位: +未核發裝置權杖時,`hello-ok.auth` 會回報協商後的權限,不包含權杖欄位: ```json { @@ -110,9 +122,13 @@ Gateway → 用戶端: } ``` -受信任的同行程後端用戶端(`client.id: "gateway-client"`、`client.mode: "backend"`)在使用共用 Gateway 權杖/密碼驗證的直接 loopback 連線上,可以省略 `device`。此路徑保留給內部控制平面 RPC,並避免過期的 CLI/裝置配對基準阻擋本機後端工作,例如子代理工作階段更新。遠端用戶端、瀏覽器來源用戶端、節點用戶端,以及明確的裝置權杖/裝置身分用戶端,仍會使用一般配對與範圍升級檢查。 +受信任的同處理序後端用戶端(`client.id: "gateway-client"`、 +`client.mode: "backend"`)在直接 local loopback 連線上使用共用 Gateway 權杖/密碼驗證時, +可以省略 `device`。此路徑保留給內部控制平面 RPC 使用,並避免過期的 CLI/裝置配對基線阻擋 +本機後端工作,例如子代理工作階段更新。遠端用戶端、瀏覽器來源用戶端、Node 用戶端,以及明確的 +裝置權杖/裝置身分用戶端,仍使用一般的配對和範圍升級檢查。 -簽發裝置權杖時,`hello-ok` 也會包含: +核發裝置權杖時,`hello-ok` 也會包含: ```json { @@ -124,7 +140,7 @@ Gateway → 用戶端: } ``` -在受信任的啟動交接期間,`hello-ok.auth` 也可能在 `deviceTokens` 中包含其他受限角色項目: +在受信任的啟動交接期間,`hello-ok.auth` 也可能在 `deviceTokens` 中包含其他有界角色項目: ```json { @@ -143,7 +159,11 @@ Gateway → 用戶端: } ``` -對於內建節點/操作員啟動流程,主要節點權杖會維持 `scopes: []`,任何交接的操作員權杖則會受限於啟動操作員允許清單(`operator.approvals`、`operator.read`、`operator.talk.secrets`、`operator.write`)。啟動範圍檢查仍以角色前綴為準:操作員項目只會滿足操作員請求,非操作員角色仍需要其自身角色前綴下的範圍。 +對於內建 Node/operator 啟動流程,主要 Node 權杖會維持 +`scopes: []`,且任何交接的 operator 權杖都會維持受限於啟動 +operator 允許清單(`operator.approvals`、`operator.read`、 +`operator.talk.secrets`、`operator.write`)。啟動範圍檢查維持角色前綴: +operator 項目只滿足 operator 請求,而非 operator 角色仍需要其自身角色前綴下的範圍。 ### Node 範例 @@ -180,13 +200,13 @@ Gateway → 用戶端: } ``` -## 訊框格式 +## 影格格式 - **請求**:`{type:"req", id, method, params}` - **回應**:`{type:"res", id, ok, payload|error}` - **事件**:`{type:"event", event, payload, seq?, stateVersion?}` -具有副作用的方法需要**冪等性金鑰**(請參閱 schema)。 +具有副作用的方法需要**冪等鍵**(請參閱結構描述)。 ## 角色 + 範圍 @@ -195,7 +215,7 @@ Gateway → 用戶端: - `operator` = 控制平面用戶端(CLI/UI/自動化)。 - `node` = 能力主機(camera/screen/canvas/system.run)。 -### 範圍(操作員) +### 範圍(operator) 常見範圍: @@ -206,37 +226,47 @@ Gateway → 用戶端: - `operator.pairing` - `operator.talk.secrets` -`talk.config` 搭配 `includeSecrets: true` 時需要 `operator.talk.secrets`(或 `operator.admin`)。 +包含 `includeSecrets: true` 的 `talk.config` 需要 `operator.talk.secrets` +(或 `operator.admin`)。 -由 Plugin 註冊的 Gateway RPC 方法可以要求自己的操作員範圍,但保留的核心管理前綴(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)一律解析為 `operator.admin`。 +Plugin 註冊的 Gateway RPC 方法可以請求自己的 operator 範圍,但 +保留的核心管理前綴(`config.*`、`exec.approvals.*`、`wizard.*`、 +`update.*`)一律解析為 `operator.admin`。 -方法範圍只是第一道關卡。透過 `chat.send` 觸達的部分斜線指令會在其上套用更嚴格的指令層級檢查。例如,持久性 `/config set` 和 `/config unset` 寫入需要 `operator.admin`。 +方法範圍只是第一道門檻。某些透過 `chat.send` 觸及的斜線命令會在其上套用更嚴格的 +命令層級檢查。例如,持久性的 `/config set` 和 `/config unset` 寫入需要 +`operator.admin`。 -`node.pair.approve` 在基本方法範圍之外,還有額外的核准時範圍檢查: +`node.pair.approve` 在基礎方法範圍之上,還有額外的核准時範圍檢查: -- 不含指令的請求:`operator.pairing` -- 帶有非 exec 節點指令的請求:`operator.pairing` + `operator.write` -- 包含 `system.run`、`system.run.prepare` 或 `system.which` 的請求:`operator.pairing` + `operator.admin` +- 無命令請求:`operator.pairing` +- 含非 exec Node 命令的請求:`operator.pairing` + `operator.write` +- 包含 `system.run`、`system.run.prepare` 或 `system.which` 的請求: + `operator.pairing` + `operator.admin` -### 能力/指令/權限(節點) +### 能力/命令/權限(Node) -節點會在連線時宣告能力主張: +Node 會在連線時宣告能力聲明: - `caps`:高階能力類別。 -- `commands`:供呼叫使用的指令允許清單。 -- `permissions`:細粒度開關(例如 `screen.record`、`camera.capture`)。 +- `commands`:用於叫用的命令允許清單。 +- `permissions`:細粒度切換(例如 `screen.record`、`camera.capture`)。 -Gateway 會將這些視為**主張**,並強制執行伺服器端允許清單。 +Gateway 會將這些視為**聲明**,並強制執行伺服器端允許清單。 -## 在線狀態 +## 狀態存在 -- `system-presence` 會傳回以裝置身分為鍵的項目。 -- 在線狀態項目包含 `deviceId`、`roles` 和 `scopes`,因此即使同一裝置同時以**操作員**和**節點**身分連線,介面也能為每個裝置顯示單一列。 -- `node.list` 包含選用的 `lastSeenAtMs` 和 `lastSeenReason` 欄位。已連線節點會將目前連線時間回報為 `lastSeenAtMs`,原因為 `connect`;配對節點也可以在受信任的節點事件更新其配對中繼資料時,回報持久背景在線狀態。 +- `system-presence` 會回傳以裝置身分為鍵的項目。 +- 狀態存在項目包含 `deviceId`、`roles` 和 `scopes`,因此 UI 可以為每個裝置顯示單一列, + 即使它同時以 **operator** 和 **node** 連線。 +- `node.list` 包含選用的 `lastSeenAtMs` 和 `lastSeenReason` 欄位。已連線的 Node 會將其目前連線時間回報為 + `lastSeenAtMs`,原因為 `connect`;已配對的 Node 也可以在受信任的 Node 事件更新其配對中繼資料時, + 回報持久的背景狀態存在。 ### Node 背景存活事件 -Node 可以使用 `event: "node.presence.alive"` 呼叫 `node.event`,以記錄配對節點在背景喚醒期間仍存活,而不將其標記為已連線。 +Node 可以呼叫 `node.event` 並使用 `event: "node.presence.alive"`,以記錄已配對 Node 在背景喚醒期間 +曾經存活,而不將其標記為已連線。 ```json { @@ -245,9 +275,12 @@ Node 可以使用 `event: "node.presence.alive"` 呼叫 `node.event`,以記錄 } ``` -`trigger` 是封閉列舉:`background`、`silent_push`、`bg_app_refresh`、`significant_location`、`manual` 或 `connect`。未知觸發字串會由 gateway 在持久化前正規化為 `background`。此事件只會針對已驗證的節點裝置工作階段持久保存;無裝置或未配對的工作階段會傳回 `handled: false`。 +`trigger` 是封閉列舉:`background`、`silent_push`、`bg_app_refresh`、 +`significant_location`、`manual` 或 `connect`。未知的觸發字串會在持久化前由 Gateway 正規化為 +`background`。此事件僅對已驗證的 Node 裝置工作階段具有持久性;無裝置或未配對的工作階段會回傳 +`handled: false`。 -成功的 Gateway 會傳回結構化結果: +成功的 Gateway 會回傳結構化結果: ```json { @@ -258,150 +291,155 @@ Node 可以使用 `event: "node.presence.alive"` 呼叫 `node.event`,以記錄 } ``` -較舊的 Gateway 對 `node.event` 可能仍會傳回 `{ "ok": true }`;用戶端應將其視為已確認的 RPC,而非在線狀態已持久保存。 +較舊的 Gateway 對 `node.event` 可能仍回傳 `{ "ok": true }`;用戶端應將其視為 +已確認的 RPC,而非持久狀態存在的保存。 -## 廣播事件範圍控管 +## 廣播事件範圍限定 -伺服器推送的 WebSocket 廣播事件會受範圍控管,避免僅具配對範圍或僅節點的工作階段被動收到工作階段內容。 +伺服器推送的 WebSocket 廣播事件會受範圍閘控,因此配對範圍或僅限 Node 的工作階段不會被動接收工作階段內容。 -- **聊天、代理與工具結果訊框**(包括串流的 `agent` 事件與工具呼叫結果)至少需要 `operator.read`。沒有 `operator.read` 的工作階段會完全略過這些訊框。 -- **Plugin 定義的 `plugin.*` 廣播**會依照該 Plugin 的註冊方式,受 `operator.write` 或 `operator.admin` 控管。 -- **狀態與傳輸事件**(`heartbeat`、`presence`、`tick`、連線/斷線生命週期等)維持不受限制,讓每個已驗證工作階段都能觀察傳輸健康狀態。 -- **未知廣播事件族**預設會受範圍控管(預設封閉),除非已註冊處理器明確放寬限制。 +- **聊天、代理和工具結果影格**(包含串流的 `agent` 事件和工具呼叫結果)至少需要 `operator.read`。沒有 `operator.read` 的工作階段會完全略過這些影格。 +- **Plugin 定義的 `plugin.*` 廣播**會依 Plugin 註冊方式,閘控至 `operator.write` 或 `operator.admin`。 +- **狀態和傳輸事件**(`heartbeat`、`presence`、`tick`、連線/中斷連線生命週期等)維持不受限制,因此每個已驗證工作階段都能觀察傳輸健康狀態。 +- **未知的廣播事件家族**預設會受範圍閘控(失敗即關閉),除非已註冊的處理常式明確放寬限制。 -每個用戶端連線都會保有自己的個別用戶端序號,因此即使不同用戶端看到事件串流中不同的範圍過濾子集,廣播也能在該通訊端上保留單調遞增排序。 +每個用戶端連線都會保留自己的每用戶端序號,因此即使不同用戶端看到事件串流中不同的範圍篩選子集,廣播在該 socket 上仍會維持單調排序。 -## 常見 RPC 方法族 +## 常見 RPC 方法家族 -公開 WS 介面比上述握手/驗證範例更廣。這不是自動產生的完整清單;`hello-ok.features.methods` 是從 `src/gateway/server-methods-list.ts` 加上已載入的 Plugin/頻道方法匯出所建立的保守探索清單。請將它視為功能探索,而不是 `src/gateway/server-methods/*.ts` 的完整列舉。 +公開 WS 表面比上方的握手/驗證範例更廣。這不是產生的傾印 — `hello-ok.features.methods` 是一份保守的 +探索清單,由 `src/gateway/server-methods-list.ts` 加上已載入的 +Plugin/通道方法匯出所建構。請將它視為功能探索,而不是 +`src/gateway/server-methods/*.ts` 的完整列舉。 - - `health` 會傳回快取或新偵測的 Gateway 健康狀態快照。 - - `diagnostics.stability` 會傳回近期有界限的診斷穩定性記錄器。它會保留事件名稱、計數、位元組大小、記憶體讀數、佇列/工作階段狀態、頻道/Plugin 名稱與工作階段 ID 等作業中繼資料。不會保留聊天文字、Webhook 本文、工具輸出、原始請求或回應本文、權杖、Cookie 或祕密值。需要操作員讀取範圍。 - - `status` 會傳回 `/status` 風格的 Gateway 摘要;敏感欄位只會包含給具備管理範圍的操作員用戶端。 - - `gateway.identity.get` 會傳回 relay 與配對流程使用的 Gateway 裝置身分。 - - `system-presence` 會傳回已連線操作員/節點裝置目前的在線狀態快照。 - - `system-event` 會附加系統事件,並可更新/廣播在線狀態內容。 - - `last-heartbeat` 會傳回最新持久保存的 Heartbeat 事件。 + - `health` 會回傳快取或新探測的 Gateway 健康快照。 + - `diagnostics.stability` 會回傳最近的有界診斷穩定性記錄器。它保留操作中繼資料,例如事件名稱、計數、位元組大小、記憶體讀數、佇列/工作階段狀態、通道/Plugin 名稱和工作階段 ID。它不會保留聊天文字、Webhook 本文、工具輸出、原始請求或回應本文、權杖、Cookie 或祕密值。需要 operator 讀取範圍。 + - `status` 會回傳 `/status` 風格的 Gateway 摘要;敏感欄位只會包含在具管理範圍的 operator 用戶端中。 + - `gateway.identity.get` 會回傳 relay 和配對流程使用的 Gateway 裝置身分。 + - `system-presence` 會回傳已連線 operator/Node 裝置的目前狀態存在快照。 + - `system-event` 會附加系統事件,並可更新/廣播狀態存在內容。 + - `last-heartbeat` 會回傳最新持久化的 Heartbeat 事件。 - `set-heartbeats` 會切換 Gateway 上的 Heartbeat 處理。 - - - `models.list` 會傳回執行階段允許的模型目錄。傳入 `{ "view": "configured" }` 可取得適合選擇器顯示的已設定模型(先列 `agents.defaults.models`,再列 `models.providers.*.models`),或傳入 `{ "view": "all" }` 取得完整目錄。 - - `usage.status` 會傳回提供者用量時段/剩餘配額摘要。 - - `usage.cost` 會傳回日期範圍內的彙總成本用量摘要。 - - `doctor.memory.status` 會傳回作用中預設代理工作區的向量記憶體/快取嵌入就緒狀態。只有在呼叫者明確想要即時偵測嵌入提供者時,才傳入 `{ "probe": true }` 或 `{ "deep": true }`。 - - `doctor.memory.remHarness` 會為遠端控制平面用戶端傳回有界、唯讀的 REM 測試工具預覽。它可能包含工作區路徑、記憶體片段、已轉譯且具依據的 Markdown,以及深度提升候選項,因此呼叫者需要 `operator.read`。 - - `sessions.usage` 會傳回每個工作階段的用量摘要。 - - `sessions.usage.timeseries` 會傳回單一工作階段的時間序列用量。 - - `sessions.usage.logs` 會傳回單一工作階段的用量記錄項目。 + + - `models.list` 會傳回執行階段允許的模型目錄。傳入 `{ "view": "configured" }` 可取得適合選擇器大小的已設定模型(先是 `agents.defaults.models`,再是 `models.providers.*.models`),或傳入 `{ "view": "all" }` 可取得完整目錄。 + - `usage.status` 會傳回供應商使用量視窗/剩餘配額摘要。 + - `usage.cost` 會傳回日期範圍內的彙總成本使用量摘要。 + - `doctor.memory.status` 會傳回作用中預設代理工作區的向量記憶體/快取嵌入就緒狀態。只有在呼叫端明確想要即時嵌入供應商 ping 時,才傳入 `{ "probe": true }` 或 `{ "deep": true }`。 + - `doctor.memory.remHarness` 會為遠端控制平面用戶端傳回有界、唯讀的 REM harness 預覽。它可能包含工作區路徑、記憶體片段、已轉譯的 grounded markdown,以及深度提升候選項目,因此呼叫端需要 `operator.read`。 + - `sessions.usage` 會傳回每個工作階段的使用量摘要。 + - `sessions.usage.timeseries` 會傳回單一工作階段的時間序列使用量。 + - `sessions.usage.logs` 會傳回單一工作階段的使用量記錄項目。 - - - `channels.status` 會傳回內建與隨附頻道/Plugin 狀態摘要。 - - `channels.logout` 會登出特定頻道/帳號,前提是該頻道支援登出。 - - `web.login.start` 會為目前具備 QR 能力的網頁頻道提供者啟動 QR/網頁登入流程。 - - `web.login.wait` 會等待該 QR/網頁登入流程完成,並在成功時啟動頻道。 - - `push.test` 會向已註冊的 iOS Node 傳送測試 APNs 推播。 + + - `channels.status` 會傳回內建 + 綑綁通道/Plugin 狀態摘要。 + - `channels.logout` 會登出指定通道/帳號,前提是該通道支援登出。 + - `web.login.start` 會為目前支援 QR 的 Web 通道供應商啟動 QR/Web 登入流程。 + - `web.login.wait` 會等待該 QR/Web 登入流程完成,並在成功時啟動通道。 + - `push.test` 會將測試 APNs 推播傳送到已註冊的 iOS Node。 - `voicewake.get` 會傳回已儲存的喚醒詞觸發器。 - `voicewake.set` 會更新喚醒詞觸發器並廣播變更。 - - `send` 是直接對外投遞 RPC,用於在聊天執行器之外進行以頻道/帳號/對話串為目標的傳送。 - - `logs.tail` 會傳回已設定的 Gateway 檔案記錄尾端,並提供游標/限制與最大位元組控制。 + - `send` 是在聊天執行器之外,針對通道/帳號/討論串目標傳送的直接對外遞送 RPC。 + - `logs.tail` 會傳回已設定的 Gateway 檔案記錄尾端,並提供游標/限制與最大位元組控制。 - - `talk.config` 會傳回有效的 Talk 設定承載;`includeSecrets` 需要 `operator.talk.secrets`(或 `operator.admin`)。 - - `talk.mode` 會為 WebChat/Control UI 用戶端設定/廣播目前的 Talk 模式狀態。 - - `talk.speak` 會透過作用中的 Talk 語音提供者合成語音。 - - `tts.status` 會傳回 TTS 啟用狀態、作用中提供者、備援提供者,以及提供者設定狀態。 - - `tts.providers` 會傳回可見的 TTS 提供者清單。 - - `tts.enable` 與 `tts.disable` 會切換 TTS 偏好設定狀態。 - - `tts.setProvider` 會更新偏好的 TTS 提供者。 + - `talk.config` 會傳回有效的 Talk 設定 payload;`includeSecrets` 需要 `operator.talk.secrets`(或 `operator.admin`)。 + - `talk.mode` 會為 WebChat/Control UI 用戶端設定/廣播目前的 Talk 模式狀態。 + - `talk.speak` 會透過作用中的 Talk 語音供應商合成語音。 + - `tts.status` 會傳回 TTS 啟用狀態、作用中供應商、後援供應商,以及供應商設定狀態。 + - `tts.providers` 會傳回可見的 TTS 供應商清單。 + - `tts.enable` 和 `tts.disable` 會切換 TTS 偏好設定狀態。 + - `tts.setProvider` 會更新偏好的 TTS 供應商。 - `tts.convert` 會執行一次性文字轉語音轉換。 - - - `secrets.reload` 會重新解析作用中的 SecretRefs,並且只有在完全成功時才替換執行階段秘密狀態。 - - `secrets.resolve` 會解析特定命令/目標集合的命令目標秘密指派。 + + - `secrets.reload` 會重新解析作用中的 SecretRefs,且只有在完全成功時才會交換執行階段密鑰狀態。 + - `secrets.resolve` 會解析特定命令/目標集合的命令目標密鑰指派。 - `config.get` 會傳回目前的設定快照與雜湊。 - - `config.set` 會寫入已驗證的設定承載。 + - `config.set` 會寫入已驗證的設定 payload。 - `config.patch` 會合併部分設定更新。 - - `config.apply` 會驗證並取代完整設定承載。 - - `config.schema` 會傳回 Control UI 與 CLI 工具使用的即時設定結構描述承載:結構描述、`uiHints`、版本與產生中繼資料,當執行階段可以載入時,還包括 Plugin 與頻道結構描述中繼資料。結構描述包含欄位 `title` / `description` 中繼資料,這些中繼資料衍生自 UI 使用的相同標籤與說明文字;當存在相符欄位文件時,也包含巢狀物件、萬用字元、陣列項目,以及 `anyOf` / `oneOf` / `allOf` 組合分支。 - - `config.schema.lookup` 會為單一設定路徑傳回限定路徑範圍的查詢承載:正規化路徑、淺層結構描述節點、相符提示與 `hintPath`,以及供 UI/CLI 下鑽的直接子項摘要。查詢結構描述節點會保留面向使用者的文件與常見驗證欄位(`title`、`description`、`type`、`enum`、`const`、`format`、`pattern`、數值/字串/陣列/物件邊界,以及像 `additionalProperties`、`deprecated`、`readOnly`、`writeOnly` 這類旗標)。子項摘要會公開 `key`、正規化 `path`、`type`、`required`、`hasChildren`,以及相符的 `hint` / `hintPath`。 + - `config.apply` 會驗證並取代完整設定 payload。 + - `config.schema` 會傳回 Control UI 與 CLI 工具使用的即時設定結構描述 payload:結構描述、`uiHints`、版本與產生中繼資料,包括執行階段可載入時的 Plugin + 通道結構描述中繼資料。此結構描述包含從 UI 使用的相同標籤與說明文字衍生出的欄位 `title` / `description` 中繼資料,包括在存在相符欄位文件時,巢狀物件、萬用字元、陣列項目,以及 `anyOf` / `oneOf` / `allOf` 組合分支。 + - `config.schema.lookup` 會傳回單一設定路徑的路徑範圍查詢 payload:正規化路徑、淺層結構描述節點、相符提示 + `hintPath`,以及用於 UI/CLI 向下鑽研的直接子項摘要。查詢結構描述節點會保留使用者可見的文件與常見驗證欄位(`title`、`description`、`type`、`enum`、`const`、`format`、`pattern`、數值/字串/陣列/物件邊界,以及像 `additionalProperties`、`deprecated`、`readOnly`、`writeOnly` 這類旗標)。子項摘要會公開 `key`、正規化 `path`、`type`、`required`、`hasChildren`,以及相符的 `hint` / `hintPath`。 - `update.run` 會執行 Gateway 更新流程,且只有在更新本身成功時才排程重新啟動。 - - `update.status` 會傳回最新的快取更新重新啟動哨兵,包含可用時重新啟動後正在執行的版本。 - - `wizard.start`、`wizard.next`、`wizard.status` 與 `wizard.cancel` 會透過 WS RPC 公開入門精靈。 + - `update.status` 會傳回最新快取的更新重新啟動 sentinel,包括可用時重新啟動後的執行版本。 + - `wizard.start`、`wizard.next`、`wizard.status` 和 `wizard.cancel` 會透過 WS RPC 公開入門精靈。 - - `agents.list` 會傳回已設定的代理項目,包含有效模型與執行階段中繼資料。 - - `agents.create`、`agents.update` 與 `agents.delete` 會管理代理記錄與工作區接線。 - - `agents.files.list`、`agents.files.get` 與 `agents.files.set` 會管理為代理公開的啟動工作區檔案。 + - `agents.list` 會傳回已設定的代理項目,包括有效模型與執行階段中繼資料。 + - `agents.create`、`agents.update` 和 `agents.delete` 會管理代理記錄與工作區連線。 + - `agents.files.list`、`agents.files.get` 和 `agents.files.set` 會管理為代理公開的啟動工作區檔案。 + - `artifacts.list`、`artifacts.get` 和 `artifacts.download` 會公開明確 `sessionKey`、`runId` 或 `taskId` 範圍中,從逐字稿衍生的成品摘要與下載。執行與任務查詢會在伺服器端解析所屬工作階段,且只傳回具有相符來源的逐字稿媒體;不安全或本機 URL 來源會傳回不支援的下載,而不是在伺服器端擷取。 - `agent.identity.get` 會傳回代理或工作階段的有效助理身分。 - - `agent.wait` 會等待執行完成,並在可用時傳回終端快照。 + - `agent.wait` 會等待一次執行完成,並在可用時傳回終端快照。 - - `sessions.list` 會傳回目前的工作階段索引,當已設定代理執行階段後端時,包含每列的 `agentRuntime` 中繼資料。 - - `sessions.subscribe` 與 `sessions.unsubscribe` 會為目前的 WS 用戶端切換工作階段變更事件訂閱。 - - `sessions.messages.subscribe` 與 `sessions.messages.unsubscribe` 會為單一工作階段切換逐字稿/訊息事件訂閱。 - - `sessions.preview` 會為特定工作階段鍵傳回有界逐字稿預覽。 + - `sessions.list` 會傳回目前的工作階段索引,包括設定代理執行階段後端時每列的 `agentRuntime` 中繼資料。 + - `sessions.subscribe` 和 `sessions.unsubscribe` 會切換目前 WS 用戶端的工作階段變更事件訂閱。 + - `sessions.messages.subscribe` 和 `sessions.messages.unsubscribe` 會切換單一工作階段的逐字稿/訊息事件訂閱。 + - `sessions.preview` 會傳回特定工作階段鍵的有界逐字稿預覽。 - `sessions.resolve` 會解析或正規化工作階段目標。 - `sessions.create` 會建立新的工作階段項目。 - - `sessions.send` 會向現有工作階段傳送訊息。 - - `sessions.steer` 是作用中工作階段的中斷並導向變體。 - - `sessions.abort` 會中止工作階段的作用中工作。呼叫者可以傳入 `key` 加上選用的 `runId`,或針對 Gateway 可解析到工作階段的作用中執行,單獨傳入 `runId`。 - - `sessions.patch` 會更新工作階段中繼資料/覆寫,並回報已解析的正規模型以及有效的 `agentRuntime`。 - - `sessions.reset`、`sessions.delete` 與 `sessions.compact` 會執行工作階段維護。 + - `sessions.send` 會將訊息傳送到現有工作階段。 + - `sessions.steer` 是作用中工作階段的中斷並導引變體。 + - `sessions.abort` 會中止工作階段的作用中工作。呼叫端可以傳入 `key` 加上可選的 `runId`,或只為 Gateway 可解析到工作階段的作用中執行傳入 `runId`。 + - `sessions.patch` 會更新工作階段中繼資料/覆寫,並回報已解析的正規模型與有效的 `agentRuntime`。 + - `sessions.reset`、`sessions.delete` 和 `sessions.compact` 會執行工作階段維護。 - `sessions.get` 會傳回完整儲存的工作階段列。 - - 聊天執行仍使用 `chat.history`、`chat.send`、`chat.abort` 與 `chat.inject`。`chat.history` 會為 UI 用戶端進行顯示正規化:從可見文字移除行內指令標籤、移除純文字工具呼叫 XML 承載(包含 `...`、`...`、`...`、`...` 與被截斷的工具呼叫區塊)以及洩漏的 ASCII/全形模型控制權杖,省略精確為 `NO_REPLY` / `no_reply` 這類純靜默權杖的助理列,且過大的列可替換為預留位置。 + - 聊天執行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 `chat.inject`。`chat.history` 會為 UI 用戶端進行顯示正規化:可見文字中的內嵌指令標籤會被移除,純文字工具呼叫 XML payload(包括 `...`、`...`、`...`、`...`,以及截斷的工具呼叫區塊)與外洩的 ASCII/全形模型控制權杖會被移除,完全由靜默權杖組成的助理列(例如精確的 `NO_REPLY` / `no_reply`)會被省略,而過大的列可以用佔位符取代。 - - `device.pair.list` 會傳回待處理與已核准的配對裝置。 - - `device.pair.approve`、`device.pair.reject` 與 `device.pair.remove` 會管理裝置配對記錄。 - - `device.token.rotate` 會在已核准角色與呼叫者範圍界限內輪替配對裝置權杖。 - - `device.token.revoke` 會在已核准角色與呼叫者範圍界限內撤銷配對裝置權杖。 + - `device.pair.list` 會傳回待處理和已核准的配對裝置。 + - `device.pair.approve`、`device.pair.reject` 和 `device.pair.remove` 會管理裝置配對記錄。 + - `device.token.rotate` 會在其已核准角色與呼叫端範圍界限內輪替配對裝置權杖。 + - `device.token.revoke` 會在其已核准角色與呼叫端範圍界限內撤銷配對裝置權杖。 - - `node.pair.request`、`node.pair.list`、`node.pair.approve`、`node.pair.reject`、`node.pair.remove` 與 `node.pair.verify` 涵蓋 Node 配對與啟動驗證。 - - `node.list` 與 `node.describe` 會傳回已知/已連線的 Node 狀態。 - - `node.rename` 會更新已配對的 Node 標籤。 - - `node.invoke` 會將命令轉送至已連線的 Node。 + - `node.pair.request`、`node.pair.list`、`node.pair.approve`、`node.pair.reject`、`node.pair.remove` 和 `node.pair.verify` 涵蓋 Node 配對與啟動驗證。 + - `node.list` 和 `node.describe` 會傳回已知/已連線的 Node 狀態。 + - `node.rename` 會更新配對 Node 標籤。 + - `node.invoke` 會將命令轉送到已連線的 Node。 - `node.invoke.result` 會傳回叫用請求的結果。 - - `node.event` 會將源自 Node 的事件帶回 Gateway。 - - `node.canvas.capability.refresh` 會重新整理限定範圍的畫布能力權杖。 - - `node.pending.pull` 與 `node.pending.ack` 是已連線 Node 佇列 API。 - - `node.pending.enqueue` 與 `node.pending.drain` 會管理離線/中斷連線 Node 的持久待處理工作。 + - `node.event` 會將 Node 來源事件帶回 Gateway。 + - `node.canvas.capability.refresh` 會重新整理範圍限定的畫布能力權杖。 + - `node.pending.pull` 和 `node.pending.ack` 是已連線 Node 佇列 API。 + - `node.pending.enqueue` 和 `node.pending.drain` 會管理離線/中斷連線 Node 的持久待處理工作。 - - `exec.approval.request`、`exec.approval.get`、`exec.approval.list` 與 `exec.approval.resolve` 涵蓋一次性 exec 核准請求,以及待處理核准查詢/重播。 + - `exec.approval.request`、`exec.approval.get`、`exec.approval.list` 和 `exec.approval.resolve` 涵蓋一次性 exec 核准請求,以及待處理核准查詢/重播。 - `exec.approval.waitDecision` 會等待一個待處理 exec 核准,並傳回最終決策(逾時時為 `null`)。 - - `exec.approvals.get` 與 `exec.approvals.set` 會管理 Gateway exec 核准政策快照。 - - `exec.approvals.node.get` 與 `exec.approvals.node.set` 會透過 Node 中繼命令管理 Node 本機 exec 核准政策。 - - `plugin.approval.request`、`plugin.approval.list`、`plugin.approval.waitDecision` 與 `plugin.approval.resolve` 涵蓋 Plugin 定義的核准流程。 + - `exec.approvals.get` 和 `exec.approvals.set` 會管理 Gateway exec 核准政策快照。 + - `exec.approvals.node.get` 和 `exec.approvals.node.set` 會透過 Node relay 命令管理 Node 本機 exec 核准政策。 + - `plugin.approval.request`、`plugin.approval.list`、`plugin.approval.waitDecision` 和 `plugin.approval.resolve` 涵蓋 Plugin 定義的核准流程。 - - 自動化:`wake` 會排程立即或下一次 Heartbeat 的喚醒文字注入;`cron.list`、`cron.status`、`cron.add`、`cron.update`、`cron.remove`、`cron.run`、`cron.runs` 會管理排程工作。 + - 自動化:`wake` 會排程立即或下一次 Heartbeat 喚醒文字注入;`cron.list`、`cron.status`、`cron.add`、`cron.update`、`cron.remove`、`cron.run`、`cron.runs` 會管理排程工作。 - Skills 與工具:`commands.list`、`skills.*`、`tools.catalog`、`tools.effective`。 @@ -409,15 +447,15 @@ Node 可以使用 `event: "node.presence.alive"` 呼叫 `node.event`,以記錄 ### 常見事件系列 -- `chat`:UI 聊天更新,例如 `chat.inject` 與其他僅逐字稿的聊天 +- `chat`:UI 聊天更新,例如 `chat.inject` 與其他僅限逐字稿的聊天 事件。 -- `session.message` 與 `session.tool`:已訂閱工作階段的逐字稿/事件串流更新。 +- `session.message` 和 `session.tool`:已訂閱工作階段的逐字稿/事件串流更新。 - `sessions.changed`:工作階段索引或中繼資料已變更。 -- `presence`:系統存在狀態快照更新。 -- `tick`:週期性 keepalive/存活事件。 -- `health`:Gateway 健全狀態快照更新。 +- `presence`:系統 presence 快照更新。 +- `tick`:週期性 keepalive / liveness 事件。 +- `health`:Gateway 健康狀態快照更新。 - `heartbeat`:Heartbeat 事件串流更新。 -- `cron`:Cron 執行/工作變更事件。 +- `cron`:Cron 執行/工作變更事件。 - `shutdown`:Gateway 關閉通知。 - `node.pair.requested` / `node.pair.resolved`:Node 配對生命週期。 - `node.invoke.request`:Node 叫用請求廣播。 @@ -430,169 +468,181 @@ Node 可以使用 `event: "node.presence.alive"` 呼叫 `node.event`,以記錄 ### Node 輔助方法 -- Node 可呼叫 `skills.bins` 來擷取目前的技能可執行檔清單,以進行自動允許檢查。 +- Node 可以呼叫 `skills.bins` 來擷取目前的技能可執行檔清單, + 用於自動允許檢查。 -### 操作者輔助方法 +### Operator 輔助方法 -- 操作者可以呼叫 `commands.list`(`operator.read`)來擷取代理程式的執行階段 +- 操作員可以呼叫 `commands.list` (`operator.read`) 來擷取代理程式的執行階段 命令清單。 - `agentId` 為選填;省略即可讀取預設代理程式工作區。 - - `scope` 控制主要 `name` 目標所屬的介面: - - `text` 會傳回不含開頭 `/` 的主要文字命令權杖 - - `native` 與預設的 `both` 路徑會在可用時傳回感知提供者的原生命令名稱 - - `textAliases` 帶有精確的斜線別名,例如 `/model` 和 `/m`。 - - `nativeName` 會在存在時帶有感知提供者的原生命令名稱。 - - `provider` 為選填,且只會影響原生命名以及原生 Plugin + - `scope` 控制主要 `name` 目標是哪個介面: + - `text` 會傳回不含前導 `/` 的主要文字命令權杖 + - `native` 與預設的 `both` 路徑會在可用時傳回可感知提供者的原生命名 + - `textAliases` 會攜帶精確的斜線別名,例如 `/model` 與 `/m`。 + - `nativeName` 會在存在時攜帶可感知提供者的原生命令名稱。 + - `provider` 為選填,且只會影響原生命名與原生 Plugin 命令可用性。 - `includeArgs=false` 會從回應中省略序列化的引數中繼資料。 -- 操作者可以呼叫 `tools.catalog`(`operator.read`)來擷取代理程式的執行階段工具目錄。回應包含分組工具與來源中繼資料: - - `source`:`core` 或 `plugin` - - `pluginId`:當 `source="plugin"` 時的 Plugin 擁有者 - - `optional`:Plugin 工具是否為選用 -- 操作者可以呼叫 `tools.effective`(`operator.read`)來擷取工作階段中執行階段實際生效的工具清單。 +- 操作員可以呼叫 `tools.catalog` (`operator.read`) 來擷取代理程式的執行階段工具目錄。回應包含分組工具與來源中繼資料: + - `source`: `core` 或 `plugin` + - `pluginId`: `source="plugin"` 時的 Plugin擁有者 + - `optional`: Plugin工具是否為選用 +- 操作員可以呼叫 `tools.effective` (`operator.read`) 來擷取工作階段的執行階段有效工具 + 清單。 - `sessionKey` 為必填。 - - Gateway 會從伺服器端的工作階段推導受信任的執行階段脈絡,而不是接受 - 呼叫端提供的驗證或傳遞脈絡。 - - 回應以工作階段為範圍,並反映目前作用中的對話現在可以使用的內容, - 包含核心、Plugin 與頻道工具。 -- 操作者可以呼叫 `skills.status`(`operator.read`)來擷取代理程式可見的 + - Gateway 會在伺服器端從工作階段衍生受信任的執行階段內容,而不是接受 + 呼叫端提供的驗證或傳遞內容。 + - 回應以工作階段為範圍,並反映目前作用中對話現在可使用的內容, + 包括核心、Plugin 與通道工具。 +- 操作員可以呼叫 `skills.status` (`operator.read`) 來擷取代理程式可見的 Skills 清單。 - `agentId` 為選填;省略即可讀取預設代理程式工作區。 - 回應包含資格、缺少的需求、設定檢查,以及 - 已清理的安裝選項,且不會暴露原始秘密值。 -- 操作者可以呼叫 `skills.search` 和 `skills.detail`(`operator.read`)取得 + 不會暴露原始密鑰值的已清理安裝選項。 +- 操作員可以呼叫 `skills.search` 與 `skills.detail` (`operator.read`) 來取得 ClawHub 探索中繼資料。 -- 操作者可以用兩種模式呼叫 `skills.install`(`operator.admin`): +- 操作員可以呼叫 `skills.install` (`operator.admin`),支援兩種模式: - ClawHub 模式:`{ source: "clawhub", slug, version?, force? }` 會將 - Skills 資料夾安裝到預設代理程式工作區的 `skills/` 目錄。 - - Gateway 安裝程式模式:`{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` + skill 資料夾安裝到預設代理程式工作區的 `skills/` 目錄。 + - Gateway 安裝器模式:`{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` 會在 Gateway 主機上執行宣告的 `metadata.openclaw.install` 動作。 -- 操作者可以用兩種模式呼叫 `skills.update`(`operator.admin`): - - ClawHub 模式會更新一個受追蹤的 slug,或更新預設代理程式工作區中所有受追蹤的 ClawHub 安裝項目。 +- 操作員可以呼叫 `skills.update` (`operator.admin`),支援兩種模式: + - ClawHub 模式會更新預設代理程式工作區中一個已追蹤的 slug,或所有已追蹤的 ClawHub 安裝。 - 設定模式會修補 `skills.entries.` 值,例如 `enabled`、 - `apiKey` 和 `env`。 + `apiKey` 與 `env`。 ### `models.list` 檢視 -`models.list` 接受選用的 `view` 參數: +`models.list` 接受選填的 `view` 參數: - 省略或 `"default"`:目前的執行階段行為。如果已設定 `agents.defaults.models`,回應會是允許的目錄;否則回應會是完整的 Gateway 目錄。 - `"configured"`:適合選擇器大小的行為。如果已設定 `agents.defaults.models`,它仍會優先。否則回應會使用明確的 `models.providers.*.models` 項目,只有在沒有已設定的模型列時才會退回完整目錄。 -- `"all"`:完整 Gateway 目錄,略過 `agents.defaults.models`。將此用於診斷與探索 UI,而非一般模型選擇器。 +- `"all"`:完整的 Gateway 目錄,略過 `agents.defaults.models`。這適用於診斷與探索 UI,不適用於一般模型選擇器。 -## Exec 核准 +## 執行核准 -- 當 exec 請求需要核准時,Gateway 會廣播 `exec.approval.requested`。 -- 操作者用戶端透過呼叫 `exec.approval.resolve` 來解析(需要 `operator.approvals` 範圍)。 -- 對於 `host=node`,`exec.approval.request` 必須包含 `systemRunPlan`(標準 `argv`/`cwd`/`rawCommand`/工作階段中繼資料)。缺少 `systemRunPlan` 的請求會被拒絕。 +- 當執行要求需要核准時,Gateway 會廣播 `exec.approval.requested`。 +- 操作員用戶端透過呼叫 `exec.approval.resolve` 來解析(需要 `operator.approvals` 範圍)。 +- 對於 `host=node`,`exec.approval.request` 必須包含 `systemRunPlan`(標準 `argv`/`cwd`/`rawCommand`/工作階段中繼資料)。缺少 `systemRunPlan` 的要求會被拒絕。 - 核准後,轉送的 `node.invoke system.run` 呼叫會重用該標準 - `systemRunPlan` 作為具權威性的命令/cwd/工作階段脈絡。 -- 如果呼叫端在準備和最終核准的 `system.run` 轉送之間變更 `command`、`rawCommand`、`cwd`、`agentId` 或 - `sessionKey`,Gateway 會拒絕該執行,而不是信任已變更的承載。 + `systemRunPlan` 作為權威的命令/cwd/工作階段內容。 +- 如果呼叫端在準備與最終核准的 `system.run` 轉送之間變更 `command`、`rawCommand`、`cwd`、`agentId` 或 + `sessionKey`,Gateway 會拒絕執行,而不是信任已變更的承載。 ## 代理程式傳遞後援 -- `agent` 請求可以包含 `deliver=true` 以要求輸出傳遞。 -- `bestEffortDeliver=false` 會維持嚴格行為:無法解析或僅供內部使用的傳遞目標會傳回 `INVALID_REQUEST`。 -- `bestEffortDeliver=true` 允許在無法解析任何外部可傳遞路由時,後援為僅限工作階段的執行(例如內部/webchat 工作階段或不明確的多頻道設定)。 +- `agent` 要求可以包含 `deliver=true` 以要求對外傳遞。 +- `bestEffortDeliver=false` 保持嚴格行為:無法解析或僅限內部的傳遞目標會傳回 `INVALID_REQUEST`。 +- `bestEffortDeliver=true` 允許在無法解析外部可傳遞路由時退回僅工作階段執行(例如內部/webchat 工作階段或不明確的多通道設定)。 ## 版本控管 - `PROTOCOL_VERSION` 位於 `src/gateway/protocol/schema/protocol-schemas.ts`。 -- 用戶端傳送 `minProtocol` + `maxProtocol`;伺服器會拒絕不相符的版本。 -- 結構描述與模型會從 TypeBox 定義產生: +- 用戶端傳送 `minProtocol` + `maxProtocol`;伺服器會拒絕不相符的情況。 +- 結構描述 + 模型由 TypeBox 定義產生: - `pnpm protocol:gen` - `pnpm protocol:gen:swift` - `pnpm protocol:check` ### 用戶端常數 -`src/gateway/client.ts` 中的參考用戶端使用這些預設值。這些值在協定 v3 中保持穩定,並且是第三方用戶端的預期基準。 +`src/gateway/client.ts` 中的參考用戶端使用這些預設值。這些值在 +協定 v3 中保持穩定,並且是第三方用戶端的預期基準。 | 常數 | 預設值 | 來源 | | ----------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------ | | `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` | -| 請求逾時(每個 RPC) | `30_000` ms | `src/gateway/client.ts`(`requestTimeoutMs`) | -| 預驗證 / 連線挑戰逾時 | `15_000` ms | `src/gateway/handshake-timeouts.ts`(設定/env 可提高成對的伺服器/用戶端預算) | -| 初始重新連線退避 | `1_000` ms | `src/gateway/client.ts`(`backoffMs`) | -| 最大重新連線退避 | `30_000` ms | `src/gateway/client.ts`(`scheduleReconnect`) | +| 要求逾時(每個 RPC) | `30_000` ms | `src/gateway/client.ts` (`requestTimeoutMs`) | +| 預先驗證 / 連線挑戰逾時 | `15_000` ms | `src/gateway/handshake-timeouts.ts`(config/env 可提高配對的伺服器/用戶端預算) | +| 初始重新連線退避 | `1_000` ms | `src/gateway/client.ts` (`backoffMs`) | +| 最大重新連線退避 | `30_000` ms | `src/gateway/client.ts` (`scheduleReconnect`) | | 裝置權杖關閉後的快速重試上限 | `250` ms | `src/gateway/client.ts` | | `terminate()` 前的強制停止寬限 | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` | | `stopAndWait()` 預設逾時 | `1_000` ms | `STOP_AND_WAIT_TIMEOUT_MS` | | 預設 tick 間隔(`hello-ok` 前) | `30_000` ms | `src/gateway/client.ts` | -| tick 逾時關閉 | 當靜默超過 `tickIntervalMs * 2` 時使用代碼 `4000` | `src/gateway/client.ts` | -| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024`(25 MB) | `src/gateway/server-constants.ts` | +| tick 逾時關閉 | 靜默超過 `tickIntervalMs * 2` 時使用代碼 `4000` | `src/gateway/client.ts` | +| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 MB) | `src/gateway/server-constants.ts` | -伺服器會在 `hello-ok` 中公告實際生效的 `policy.tickIntervalMs`、`policy.maxPayload` 和 `policy.maxBufferedBytes`;用戶端應遵循這些值,而不是握手前的預設值。 +伺服器會在 `hello-ok` 中公告有效的 `policy.tickIntervalMs`、`policy.maxPayload` +與 `policy.maxBufferedBytes`;用戶端應遵循這些值, +而不是交握前的預設值。 ## 驗證 -- 共用秘密 Gateway 驗證會使用 `connect.params.auth.token` 或 +- 共享密鑰 Gateway 驗證會使用 `connect.params.auth.token` 或 `connect.params.auth.password`,取決於已設定的驗證模式。 - 帶有身分的模式,例如 Tailscale Serve - (`gateway.auth.allowTailscale: true`)或非 local loopback - `gateway.auth.mode: "trusted-proxy"`,會從請求標頭而非 `connect.params.auth.*` - 滿足連線驗證檢查。 -- 私有入口 `gateway.auth.mode: "none"` 會完全略過共用秘密連線驗證; - 請勿在公開/不受信任的入口暴露該模式。 -- 配對後,Gateway 會發出一個範圍限定為連線角色 + 範圍的**裝置權杖**。 - 它會在 `hello-ok.auth.deviceToken` 中傳回,且用戶端應將其持久保存以供未來連線使用。 -- 用戶端應在任何成功連線後持久保存主要的 `hello-ok.auth.deviceToken`。 + (`gateway.auth.allowTailscale: true`) 或非迴圈 + `gateway.auth.mode: "trusted-proxy"`,會從要求標頭滿足連線驗證檢查, + 而不是使用 `connect.params.auth.*`。 +- 私有入口 `gateway.auth.mode: "none"` 會完全略過共享密鑰連線驗證; + 請勿在公開/不受信任的入口上暴露該模式。 +- 配對後,Gateway 會發行一個範圍限定為連線 + 角色 + 範圍的**裝置權杖**。它會在 `hello-ok.auth.deviceToken` 中傳回,且應由用戶端保存以供未來連線使用。 +- 用戶端應在任何成功連線後保存主要的 `hello-ok.auth.deviceToken`。 - 使用該**已儲存**裝置權杖重新連線時,也應重用該權杖已儲存的 - 已核准範圍集合。這會保留先前已授權的讀取/探測/狀態存取權, - 並避免在不明顯的情況下將重新連線縮減為較窄的隱含僅管理員範圍。 + 已核准範圍集合。這會保留已授予的讀取/探測/狀態存取權, + 並避免重新連線悄悄收斂到較窄的隱含僅管理員範圍。 - 用戶端連線驗證組裝(`src/gateway/client.ts` 中的 `selectConnectAuth`): - - `auth.password` 是正交的,設定時一律會被轉送。 - - `auth.token` 依優先順序填入:明確的共用權杖優先, - 接著是明確的 `deviceToken`,再來是已儲存的每裝置權杖(以 - `deviceId` + `role` 為鍵)。 - - 只有在上述都未解析出 `auth.token` 時,才會傳送 `auth.bootstrapToken`。 - 共用權杖或任何已解析的裝置權杖都會抑制它。 - - 在一次性的 `AUTH_TOKEN_MISMATCH` 重試上,自動提升已儲存裝置權杖僅限於**受信任端點**: - loopback,或具有釘選 `tlsFingerprint` 的 `wss://`。沒有釘選的公開 `wss://` + - `auth.password` 是正交的,設定時一律會轉送。 + - `auth.token` 會依優先順序填入:先是明確的共享權杖, + 接著是明確的 `deviceToken`,再來是已儲存的每裝置權杖(依 + `deviceId` + `role` 作為鍵)。 + - `auth.bootstrapToken` 只有在上述皆未解析出 + `auth.token` 時才會傳送。共享權杖或任何已解析的裝置權杖都會抑制它。 + - 在一次性的 `AUTH_TOKEN_MISMATCH` 重試中自動提升已儲存裝置權杖, + 僅限於**受信任端點**:loopback,或具有已釘選 `tlsFingerprint` 的 `wss://`。未釘選的公開 `wss://` 不符合資格。 -- 額外的 `hello-ok.auth.deviceTokens` 項目是啟動程序交接權杖。 - 只有在連線於受信任傳輸(例如 `wss://` 或 loopback/local 配對)上使用啟動驗證時,才持久保存它們。 -- 如果用戶端提供**明確**的 `deviceToken` 或明確的 `scopes`,該呼叫端要求的範圍集合仍具有權威性;只有在用戶端重用已儲存的每裝置權杖時,才會重用快取的範圍。 -- 裝置權杖可透過 `device.token.rotate` 和 +- 額外的 `hello-ok.auth.deviceTokens` 項目是啟動交接權杖。 + 只有在連線於受信任傳輸(例如 `wss://` 或 loopback/local 配對)上使用啟動驗證時才保存它們。 +- 如果用戶端提供**明確**的 `deviceToken` 或明確的 `scopes`,該 + 呼叫端要求的範圍集合仍具權威性;快取範圍只會在用戶端重用已儲存的每裝置權杖時 + 重用。 +- 裝置權杖可以透過 `device.token.rotate` 與 `device.token.revoke` 輪替/撤銷(需要 `operator.pairing` 範圍)。 -- `device.token.rotate` 會傳回輪替中繼資料。它只會對已使用該裝置權杖完成驗證的同一裝置呼叫回傳替換的持有者權杖,因此僅權杖用戶端可在重新連線前持久保存替換項。共用/管理員輪替不會回傳持有者權杖。 -- 權杖發行、輪替與撤銷仍會被限制在該裝置配對項目中記錄的已核准角色集合內;權杖變更不能擴大或瞄準配對核准從未授予的裝置角色。 -- 對於已配對裝置權杖工作階段,除非呼叫端也擁有 `operator.admin`,否則裝置管理僅限自身範圍:非管理員呼叫端只能移除/撤銷/輪替自己的裝置項目。 -- `device.token.rotate` 和 `device.token.revoke` 也會檢查目標操作者 - 權杖範圍集合是否符合呼叫端目前的工作階段範圍。非管理員呼叫端 - 不能輪替或撤銷比自己已持有範圍更廣的操作者權杖。 +- `device.token.rotate` 會傳回輪替中繼資料。它只會對已使用該裝置權杖完成驗證的同裝置呼叫 + 回顯替代 bearer 權杖,因此僅權杖用戶端可以在 + 重新連線前保存替代權杖。共享/管理員輪替不會回顯 bearer 權杖。 +- 權杖發行、輪替與撤銷都會限制在該裝置配對項目中記錄的已核准角色集合內; + 權杖變更無法擴大或鎖定配對核准從未授予的裝置角色。 +- 對於已配對裝置權杖工作階段,除非呼叫端也有 `operator.admin`, + 否則裝置管理是自我範圍限定的:非管理員呼叫端只能移除/撤銷/輪替 + 自己的裝置項目。 +- `device.token.rotate` 與 `device.token.revoke` 也會根據呼叫端目前的工作階段範圍 + 檢查目標操作員權杖範圍集合。非管理員呼叫端 + 不能輪替或撤銷比自己已持有範圍更廣的操作員權杖。 - 驗證失敗包含 `error.details.code` 加上復原提示: - `error.details.canRetryWithDeviceToken`(布林值) - - `error.details.recommendedNextStep`(`retry_with_device_token`、`update_auth_configuration`、`update_auth_credentials`、`wait_then_retry`、`review_auth_configuration`) + - `error.details.recommendedNextStep` (`retry_with_device_token`, `update_auth_configuration`, `update_auth_credentials`, `wait_then_retry`, `review_auth_configuration`) - `AUTH_TOKEN_MISMATCH` 的用戶端行為: - - 受信任用戶端可以使用快取的每裝置權杖嘗試一次有界重試。 - - 如果該重試失敗,用戶端應停止自動重新連線迴圈,並顯示操作者動作指引。 + - 受信任用戶端可以嘗試一次有界限的重試,並使用快取的每裝置權杖。 + - 如果該重試失敗,用戶端應停止自動重新連線迴圈,並顯示操作員動作指引。 ## 裝置身分 + 配對 -- 節點應包含穩定的裝置身分識別 (`device.id`),並由 - 金鑰組指紋衍生而來。 -- Gateway 會依裝置 + 角色核發權杖。 -- 新裝置 ID 必須獲得配對核准,除非已啟用本機自動核准。 -- 配對自動核准以直接 local loopback 連線為核心。 -- OpenClaw 也有狹窄的後端/容器本機自我連線路徑,用於 - 受信任的共享密鑰輔助流程。 -- 同主機 tailnet 或 LAN 連線在配對時仍會被視為遠端,並且 +- Node 應包含穩定的裝置身分識別(`device.id`),並由 + 金鑰對指紋衍生。 +- Gateway 會依裝置 + 角色發行權杖。 +- 新裝置 ID 必須取得配對核准,除非已啟用本機自動核准。 +- 配對自動核准以直接 local loopback 連線為中心。 +- OpenClaw 也有一條狹窄的後端/容器本機自我連線路徑,供 + 受信任的共享密鑰輔助流程使用。 +- 同主機 tailnet 或 LAN 連線在配對上仍視為遠端,並且 需要核准。 - WS 用戶端通常會在 `connect` 期間包含 `device` 身分識別(操作者 + - 節點)。唯一不含裝置的操作者例外是明確的信任路徑: - - `gateway.controlUi.allowInsecureAuth=true` 用於僅限 localhost 的不安全 HTTP 相容性。 - - 成功的 `gateway.auth.mode: "trusted-proxy"` 操作者控制 UI 驗證。 - - `gateway.controlUi.dangerouslyDisableDeviceAuth=true`(緊急處置,嚴重降低安全性)。 - - 以共享 - Gateway 權杖/密碼驗證的直接 loopback `gateway-client` 後端 RPC。 + node)。唯一不帶裝置的操作者例外是明確的信任路徑: + - `gateway.controlUi.allowInsecureAuth=true`,用於僅限 localhost 的不安全 HTTP 相容性。 + - 成功的 `gateway.auth.mode: "trusted-proxy"` 操作者 Control UI 驗證。 + - `gateway.controlUi.dangerouslyDisableDeviceAuth=true`(緊急破窗,嚴重降低安全性)。 + - 使用共享 + gateway 權杖/密碼驗證的 direct-loopback `gateway-client` 後端 RPC。 - 所有連線都必須簽署伺服器提供的 `connect.challenge` nonce。 ### 裝置驗證遷移診斷 對於仍使用挑戰前簽署行為的舊版用戶端,`connect` 現在會在 -`error.details.code` 下傳回 `DEVICE_AUTH_*` 詳細代碼,並附帶穩定的 `error.details.reason`。 +`error.details.code` 下傳回 `DEVICE_AUTH_*` 詳細代碼,並提供穩定的 `error.details.reason`。 常見遷移失敗: @@ -600,34 +650,34 @@ Node 可以使用 `event: "node.presence.alive"` 呼叫 `node.event`,以記錄 | --------------------------- | -------------------------------- | ------------------------ | -------------------------------------------------- | | `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | 用戶端省略了 `device.nonce`(或傳送空白)。 | | `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | 用戶端使用過期/錯誤的 nonce 簽署。 | -| `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | 簽章酬載與 v2 酬載不相符。 | +| `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | 簽章承載資料與 v2 承載資料不符。 | | `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | 簽署時間戳超出允許的偏差範圍。 | -| `device identity mismatch` | `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch` | `device.id` 與公開金鑰指紋不相符。 | -| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | 公開金鑰格式/標準化失敗。 | +| `device identity mismatch` | `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch` | `device.id` 與公開金鑰指紋不符。 | +| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | 公開金鑰格式/正規化失敗。 | 遷移目標: - 一律等待 `connect.challenge`。 -- 簽署包含伺服器 nonce 的 v2 酬載。 +- 簽署包含伺服器 nonce 的 v2 承載資料。 - 在 `connect.params.device.nonce` 中傳送相同的 nonce。 -- 偏好的簽章酬載是 `v3`,除了裝置/用戶端/角色/範圍/權杖/nonce 欄位外, - 也會綁定 `platform` 和 `deviceFamily`。 -- 舊版 `v2` 簽章仍會因相容性而被接受,但已配對裝置的 +- 偏好的簽章承載資料是 `v3`,除了 device/client/role/scopes/token/nonce 欄位外, + 也會繫結 `platform` 和 `deviceFamily`。 +- 舊版 `v2` 簽章仍會為了相容性而接受,但已配對裝置的 中繼資料釘選仍會控制重新連線時的命令政策。 ## TLS + 釘選 -- WS 連線支援 TLS。 -- 用戶端可選擇釘選 Gateway 憑證指紋(請參閱 `gateway.tls` - 設定,加上 `gateway.remote.tlsFingerprint` 或 CLI `--tls-fingerprint`)。 +- TLS 支援 WS 連線。 +- 用戶端可選擇釘選 gateway 憑證指紋(請參閱 `gateway.tls` + 設定,以及 `gateway.remote.tlsFingerprint` 或 CLI `--tls-fingerprint`)。 ## 範圍 -此協定公開**完整的 Gateway API**(狀態、通道、模型、聊天、 -代理程式、工作階段、節點、核准等)。確切介面由 +此協定公開**完整的 gateway API**(狀態、頻道、模型、聊天、 +agent、sessions、nodes、approvals 等)。確切介面由 `src/gateway/protocol/schema.ts` 中的 TypeBox schema 定義。 ## 相關 - [橋接協定](/zh-TW/gateway/bridge-protocol) -- [Gateway 運行手冊](/zh-TW/gateway) +- [Gateway 操作手冊](/zh-TW/gateway) diff --git a/docs/zh-TW/gateway/troubleshooting.md b/docs/zh-TW/gateway/troubleshooting.md index 29b5ce4dc..01b5e3acc 100644 --- a/docs/zh-TW/gateway/troubleshooting.md +++ b/docs/zh-TW/gateway/troubleshooting.md @@ -1,24 +1,24 @@ --- read_when: - - 疑難排解中心已將您導向此處,以進行更深入的診斷 - - 你需要穩定、以症狀為基礎的操作手冊章節,並包含確切命令 + - 疑難排解中心已將你引導至此,以進行更深入的診斷 + - 你需要穩定且以症狀為基礎的操作手冊章節,並附上精確指令 sidebarTitle: Troubleshooting -summary: Gateway、頻道、自動化、節點與瀏覽器的深度疑難排解操作手冊 +summary: Gateway、通道、自動化、節點與瀏覽器的深入疑難排解執行手冊 title: 疑難排解 x-i18n: - generated_at: "2026-04-30T03:10:00Z" + generated_at: "2026-05-01T02:44:44Z" model: gpt-5.5 provider: openai - source_hash: 48735a68daa92678867a9cafb3ceeb37063bb91dee8c4c94e185f74eb0296fcb + source_hash: a808dcfd8527b041f629cff24308550f961e9eeb4d7d4ce6f1ce84dff6bbef89 source_path: gateway/troubleshooting.md workflow: 16 --- -此頁面是深入執行手冊。如果你想先使用快速分診流程,請從 [/help/troubleshooting](/zh-TW/help/troubleshooting) 開始。 +這個頁面是深入執行手冊。如果想先使用快速分診流程,請從 [/help/troubleshooting](/zh-TW/help/troubleshooting) 開始。 ## 命令階梯 -請先依此順序執行: +請先依照以下順序執行: ```bash openclaw status @@ -31,14 +31,14 @@ openclaw channels status --probe 預期的健康訊號: - `openclaw gateway status` 會顯示 `Runtime: running`、`Connectivity probe: ok`,以及一行 `Capability: ...`。 -- `openclaw doctor` 回報沒有阻塞性的設定/服務問題。 -- `openclaw channels status --probe` 會顯示每個帳戶即時的傳輸狀態,並在支援處顯示探測/稽核結果,例如 `works` 或 `audit ok`。 +- `openclaw doctor` 不會回報阻斷性的設定/服務問題。 +- `openclaw channels status --probe` 會顯示每個帳號的即時傳輸狀態,且在支援的情況下,會顯示探測/稽核結果,例如 `works` 或 `audit ok`。 ## 分裂腦安裝與較新設定防護 -當 Gateway 服務在更新後意外停止,或記錄顯示某個 `openclaw` 二進位檔比最後寫入 `openclaw.json` 的版本更舊時,使用此流程。 +當 Gateway 服務在更新後意外停止,或記錄顯示某個 `openclaw` 二進位檔比最後寫入 `openclaw.json` 的版本還舊時,請使用這一節。 -OpenClaw 會以 `meta.lastTouchedVersion` 標記設定寫入。唯讀命令仍可檢查由較新 OpenClaw 寫入的設定,但處理程序與服務異動會拒絕從較舊二進位檔繼續。遭阻擋的動作包括 Gateway 服務啟動、停止、重新啟動、解除安裝、強制重新安裝服務、服務模式 Gateway 啟動,以及 `gateway --force` 連接埠清理。 +OpenClaw 會使用 `meta.lastTouchedVersion` 標記設定寫入。唯讀命令仍可檢查由較新 OpenClaw 寫入的設定,但程序與服務變更會拒絕從較舊的二進位檔繼續。被阻擋的動作包括 Gateway 服務啟動、停止、重新啟動、解除安裝、強制服務重新安裝、服務模式 Gateway 啟動,以及 `gateway --force` 連接埠清理。 ```bash which openclaw @@ -49,10 +49,10 @@ openclaw config get meta.lastTouchedVersion - 修正 `PATH`,讓 `openclaw` 解析到較新的安裝,然後重新執行該動作。 + 修正 `PATH`,讓 `openclaw` 解析到較新的安裝版本,然後重新執行該動作。 - 從較新的安裝重新安裝預期的 Gateway 服務: + 從較新的安裝版本重新安裝預期的 Gateway 服務: ```bash openclaw gateway install --force @@ -60,18 +60,18 @@ openclaw config get meta.lastTouchedVersion ``` - - 移除仍指向舊 `openclaw` 二進位檔的過期系統套件或舊包裝器項目。 + + 移除仍指向舊 `openclaw` 二進位檔的過時系統套件或舊包裝器項目。 -僅限有意降級或緊急復原時,對單一命令設定 `OPENCLAW_ALLOW_OLDER_BINARY_DESTRUCTIVE_ACTIONS=1`。一般操作請保持未設定。 +僅限有意降版或緊急復原時,才為單一命令設定 `OPENCLAW_ALLOW_OLDER_BINARY_DESTRUCTIVE_ACTIONS=1`。正常操作時請保持未設定。 ## Anthropic 429 長上下文需要額外用量 -當記錄/錯誤包含以下內容時使用:`HTTP 429: rate_limit_error: Extra usage is required for long context requests`。 +當記錄/錯誤包含以下內容時,請使用這一節:`HTTP 429: rate_limit_error: Extra usage is required for long context requests`。 ```bash openclaw logs --follow @@ -79,39 +79,39 @@ openclaw models status openclaw config get agents.defaults.models ``` -檢查: +請檢查: -- 已選取的 Anthropic Opus/Sonnet 模型具有 `params.context1m: true`。 -- 目前的 Anthropic 憑證不符合長上下文使用資格。 -- 請求只在需要 1M beta 路徑的長工作階段/模型執行上失敗。 +- 選取的 Anthropic Opus/Sonnet 模型具有 `params.context1m: true`。 +- 目前的 Anthropic 憑證不符合長上下文用量資格。 +- 請求只會在需要 1M beta 路徑的長工作階段/模型執行中失敗。 修正選項: - 對該模型停用 `context1m`,以退回一般上下文視窗。 + 停用該模型的 `context1m`,以退回正常上下文視窗。 使用符合長上下文請求資格的 Anthropic 憑證,或切換到 Anthropic API 金鑰。 - 設定備援模型,讓 Anthropic 長上下文請求遭拒時仍可繼續執行。 + 設定備援模型,讓 Anthropic 長上下文請求被拒絕時,執行仍能繼續。 相關: - [Anthropic](/zh-TW/providers/anthropic) -- [權杖使用量與成本](/zh-TW/reference/token-use) -- [為什麼我會看到 Anthropic 傳回 HTTP 429?](/zh-TW/help/faq-first-run#why-am-i-seeing-http-429-ratelimiterror-from-anthropic) +- [Token 使用量與成本](/zh-TW/reference/token-use) +- [為什麼我會看到 Anthropic 的 HTTP 429?](/zh-TW/help/faq-first-run#why-am-i-seeing-http-429-ratelimiterror-from-anthropic) ## 本機 OpenAI 相容後端通過直接探測,但代理執行失敗 -在以下情況使用: +適用情況: -- `curl ... /v1/models` 可正常運作 -- 微小的直接 `/v1/chat/completions` 呼叫可正常運作 -- OpenClaw 模型執行只在一般代理回合失敗 +- `curl ... /v1/models` 可運作 +- 極小的直接 `/v1/chat/completions` 呼叫可運作 +- OpenClaw 模型執行只在一般代理輪次失敗 ```bash curl http://127.0.0.1:1234/v1/models @@ -122,28 +122,28 @@ openclaw infer model run --model --prompt "hi" --json openclaw logs --follow ``` -檢查: +請檢查: -- 直接微小呼叫成功,但 OpenClaw 執行只在較大提示上失敗 -- 即使直接 `/v1/chat/completions` 使用相同裸模型 ID 可正常運作,仍出現 `model_not_found` 或 404 錯誤 +- 直接的小型呼叫成功,但 OpenClaw 執行只在較大的提示上失敗 +- 即使直接 `/v1/chat/completions` 使用相同的裸模型 ID 可運作,仍出現 `model_not_found` 或 404 錯誤 - 後端錯誤指出 `messages[].content` 預期為字串 - 使用 OpenAI 相容本機後端時,間歇出現 `incomplete turn detected ... stopReason=stop payloads=0` 警告 -- 後端當機只在較大的提示權杖數或完整代理執行階段提示中出現 +- 只在較大的提示 Token 數或完整代理執行階段提示中出現的後端當機 - - 本機 MLX/vLLM 風格伺服器出現 `model_not_found` → 確認 `baseUrl` 包含 `/v1`、對 `/v1/chat/completions` 後端而言 `api` 是 `"openai-completions"`,且 `models.providers..models[].id` 是供應商本機的裸 ID。選取時加上供應商前綴一次,例如 `mlx/mlx-community/Qwen3-30B-A3B-6bit`;目錄項目維持為 `mlx-community/Qwen3-30B-A3B-6bit`。 - - `messages[...].content: invalid type: sequence, expected a string` → 後端拒絕結構化 Chat Completions 內容片段。修正:設定 `models.providers..models[].compat.requiresStringContent: true`。 - - `incomplete turn detected ... stopReason=stop payloads=0` → 後端完成了 Chat Completions 請求,但該回合未傳回使用者可見的助理文字。OpenClaw 會對可安全重放的空 OpenAI 相容回合重試一次;持續失敗通常表示後端正在輸出空白/非文字內容,或抑制最終答案文字。 - - 直接微小請求成功,但 OpenClaw 代理執行因後端/模型當機而失敗(例如某些 `inferrs` 建置上的 Gemma)→ OpenClaw 傳輸很可能已經正確;後端是在較大的代理執行階段提示形態上失敗。 - - 停用工具後失敗減少但沒有消失 → 工具 schema 是壓力的一部分,但剩餘問題仍是上游模型/伺服器容量或後端錯誤。 + - 本機 MLX/vLLM 風格伺服器出現 `model_not_found` → 確認 `baseUrl` 包含 `/v1`,對於 `/v1/chat/completions` 後端,`api` 是 `"openai-completions"`,且 `models.providers..models[].id` 是裸的供應商本機 ID。選取時加一次供應商前綴,例如 `mlx/mlx-community/Qwen3-30B-A3B-6bit`;目錄項目保持為 `mlx-community/Qwen3-30B-A3B-6bit`。 + - `messages[...].content: invalid type: sequence, expected a string` → 後端拒絕結構化 Chat Completions 內容片段。修正方式:設定 `models.providers..models[].compat.requiresStringContent: true`。 + - `incomplete turn detected ... stopReason=stop payloads=0` → 後端完成了 Chat Completions 請求,但該輪次沒有回傳使用者可見的助理文字。OpenClaw 會對可安全重播的空 OpenAI 相容輪次重試一次;持續失敗通常表示後端正在輸出空/非文字內容,或抑制最終答案文字。 + - 直接的小型請求成功,但 OpenClaw 代理執行因後端/模型當機而失敗(例如某些 `inferrs` 建置上的 Gemma)→ OpenClaw 傳輸很可能已經正確;是後端在較大的代理執行階段提示形狀上失敗。 + - 停用工具後失敗範圍縮小但未消失 → 工具結構描述是壓力的一部分,但剩餘問題仍是上游模型/伺服器容量或後端錯誤。 - 1. 對只支援字串的 Chat Completions 後端設定 `compat.requiresStringContent: true`。 - 2. 對無法可靠處理 OpenClaw 工具 schema 表面的模型/後端設定 `compat.supportsTools: false`。 - 3. 在可行情況下降低提示壓力:較小的工作區啟動、較短的工作階段歷史、較輕量的本機模型,或具備更強長上下文支援的後端。 - 4. 如果微小直接請求持續通過,但 OpenClaw 代理回合仍在後端內當機,請將其視為上游伺服器/模型限制,並帶著已接受的承載形態在該處提交重現案例。 + 1. 針對僅支援字串的 Chat Completions 後端,設定 `compat.requiresStringContent: true`。 + 2. 針對無法可靠處理 OpenClaw 工具結構描述表面的模型/後端,設定 `compat.supportsTools: false`。 + 3. 在可行時降低提示壓力:較小的工作區啟動資料、較短的工作階段歷史、較輕量的本機模型,或具備更強長上下文支援的後端。 + 4. 如果直接的小型請求持續通過,但 OpenClaw 代理輪次仍在後端內部當機,請將其視為上游伺服器/模型限制,並使用已接受的酬載形狀向上游提交重現案例。 @@ -155,7 +155,7 @@ openclaw logs --follow ## 沒有回覆 -如果頻道已啟動但沒有任何回應,請先檢查路由與政策,再重新連線任何項目。 +如果通道已啟用但沒有任何回應,請先檢查路由與政策,再重新連線任何項目。 ```bash openclaw status @@ -165,27 +165,27 @@ openclaw config get channels openclaw logs --follow ``` -檢查: +請檢查: -- DM 傳送者的配對待處理。 +- 私訊寄件者的配對待處理。 - 群組提及閘控(`requireMention`、`mentionPatterns`)。 -- 頻道/群組允許清單不相符。 +- 通道/群組允許清單不相符。 常見特徵: - `drop guild message (mention required` → 群組訊息會被忽略,直到被提及。 -- `pairing request` → 傳送者需要核准。 -- `blocked` / `allowlist` → 傳送者/頻道被政策篩選。 +- `pairing request` → 寄件者需要核准。 +- `blocked` / `allowlist` → 寄件者/通道被政策篩選掉。 相關: -- [頻道疑難排解](/zh-TW/channels/troubleshooting) +- [通道疑難排解](/zh-TW/channels/troubleshooting) - [群組](/zh-TW/channels/groups) - [配對](/zh-TW/channels/pairing) ## 儀表板控制 UI 連線能力 -當儀表板/控制 UI 無法連線時,驗證 URL、驗證模式與安全內容假設。 +當儀表板/控制 UI 無法連線時,請驗證 URL、驗證模式與安全上下文假設。 ```bash openclaw gateway status @@ -195,42 +195,42 @@ openclaw doctor openclaw gateway status --json ``` -檢查: +請檢查: - 正確的探測 URL 與儀表板 URL。 -- 用戶端與 Gateway 之間的驗證模式/權杖不相符。 +- 用戶端與 Gateway 之間的驗證模式/Token 不相符。 - 在需要裝置身分時使用 HTTP。 - - - `device identity required` → 非安全內容或缺少裝置驗證。 - - `origin not allowed` → 瀏覽器 `Origin` 不在 `gateway.controlUi.allowedOrigins` 中(或你正從非 loopback 瀏覽器來源連線,且沒有明確允許清單)。 - - `device nonce required` / `device nonce mismatch` → 用戶端未完成基於挑戰的裝置驗證流程(`connect.challenge` + `device.nonce`)。 - - `device signature invalid` / `device signature expired` → 用戶端針對目前握手簽署了錯誤承載(或過期時間戳)。 - - `AUTH_TOKEN_MISMATCH` 且 `canRetryWithDeviceToken=true` → 用戶端可以使用快取的裝置權杖執行一次受信任重試。 - - 該快取權杖重試會重用與已配對裝置權杖一併儲存的快取範圍集。明確的 `deviceToken` / 明確的 `scopes` 呼叫者則保留其請求的範圍集。 - - 在該重試路徑之外,連線驗證優先順序是先使用明確共享權杖/密碼,再使用明確 `deviceToken`,再使用已儲存裝置權杖,最後使用啟動權杖。 - - 在非同步 Tailscale Serve 控制 UI 路徑上,相同 `{scope, ip}` 的失敗嘗試會在限制器記錄失敗前先序列化。因此,來自同一用戶端的兩次錯誤並行重試,第二次嘗試可能顯示 `retry later`,而不是兩次單純不相符。 - - 瀏覽器來源 loopback 用戶端傳回 `too many failed authentication attempts (retry later)` → 來自相同正規化 `Origin` 的重複失敗會暫時鎖定;另一個 localhost 來源會使用不同 bucket。 - - 之後重複出現 `unauthorized` → 共享權杖/裝置權杖漂移;重新整理權杖設定,並視需要重新核准/輪替裝置權杖。 - - `gateway connect failed:` → 錯誤的主機/連接埠/url 目標。 + + - `device identity required` → 非安全上下文或缺少裝置驗證。 + - `origin not allowed` → 瀏覽器 `Origin` 不在 `gateway.controlUi.allowedOrigins` 中(或你正從非 loopback 瀏覽器來源連線,且未明確設定允許清單)。 + - `device nonce required` / `device nonce mismatch` → 用戶端未完成以挑戰為基礎的裝置驗證流程(`connect.challenge` + `device.nonce`)。 + - `device signature invalid` / `device signature expired` → 用戶端為目前交握簽署了錯誤酬載(或過期時間戳)。 + - `AUTH_TOKEN_MISMATCH` 且 `canRetryWithDeviceToken=true` → 用戶端可使用快取的裝置 Token 進行一次受信任重試。 + - 該快取 Token 重試會重用與已配對裝置 Token 一起儲存的快取範圍集合。明確的 `deviceToken` / 明確的 `scopes` 呼叫者則保留其要求的範圍集合。 + - 在該重試路徑之外,連線驗證優先順序依序為明確的共享 Token/密碼、明確的 `deviceToken`、已儲存的裝置 Token,然後是啟動 Token。 + - 在非同步 Tailscale Serve Control UI 路徑上,針對相同 `{scope, ip}` 的失敗嘗試會在限制器記錄失敗前被序列化。因此,來自同一用戶端的兩次錯誤並行重試,第二次嘗試可能顯示 `retry later`,而不是兩次普通的不相符。 + - 瀏覽器來源 loopback 用戶端出現 `too many failed authentication attempts (retry later)` → 來自同一個正規化 `Origin` 的重複失敗會被暫時鎖定;另一個 localhost 來源會使用獨立的儲存桶。 + - 該重試後仍重複出現 `unauthorized` → 共享 Token/裝置 Token 漂移;重新整理 Token 設定,並視需要重新核准/輪替裝置 Token。 + - `gateway connect failed:` → 主機/連接埠/URL 目標錯誤。 -### 驗證詳細代碼快速對照 +### 驗證詳細代碼快速對照表 使用失敗 `connect` 回應中的 `error.details.code` 來選擇下一步動作: -| 詳細代碼 | 意義 | 建議動作 | +| Detail code | 意義 | 建議動作 | | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `AUTH_TOKEN_MISSING` | 用戶端未傳送必要的共用權杖。 | 在用戶端貼上/設定權杖,然後重試。Dashboard 路徑:`openclaw config get gateway.auth.token`,然後貼到 Control UI 設定。 | -| `AUTH_TOKEN_MISMATCH` | 共用權杖與 Gateway 驗證權杖不符。 | 如果 `canRetryWithDeviceToken=true`,允許一次受信任的重試。快取權杖重試會重用已儲存的核准範圍;明確的 `deviceToken` / `scopes` 呼叫端會保留請求的範圍。如果仍然失敗,請執行[權杖漂移復原檢查清單](/zh-TW/cli/devices#token-drift-recovery-checklist)。 | -| `AUTH_DEVICE_TOKEN_MISMATCH` | 快取的每裝置權杖已過期或遭撤銷。 | 使用[裝置 CLI](/zh-TW/cli/devices)輪替/重新核准裝置權杖,然後重新連線。 | -| `PAIRING_REQUIRED` | 裝置身分需要核准。檢查 `error.details.reason` 是否為 `not-paired`、`scope-upgrade`、`role-upgrade` 或 `metadata-upgrade`,並在存在時使用 `requestId` / `remediationHint`。 | 核准待處理請求:`openclaw devices list`,然後 `openclaw devices approve `。範圍/角色升級會在你檢閱請求的存取權後使用相同流程。 | +| `AUTH_TOKEN_MISSING` | 用戶端未傳送必要的共用權杖。 | 在用戶端貼上/設定權杖,然後重試。對於儀表板路徑:`openclaw config get gateway.auth.token`,然後貼到控制 UI 設定中。 | +| `AUTH_TOKEN_MISMATCH` | 共用權杖與 Gateway 驗證權杖不相符。 | 如果 `canRetryWithDeviceToken=true`,允許一次受信任的重試。快取權杖重試會重用已儲存且核准的範圍;明確的 `deviceToken` / `scopes` 呼叫者會保留要求的範圍。如果仍然失敗,請執行[權杖漂移復原檢查清單](/zh-TW/cli/devices#token-drift-recovery-checklist)。 | +| `AUTH_DEVICE_TOKEN_MISMATCH` | 快取的每裝置權杖已過期或遭撤銷。 | 使用[裝置 CLI](/zh-TW/cli/devices) 輪替/重新核准裝置權杖,然後重新連線。 | +| `PAIRING_REQUIRED` | 裝置身分需要核准。檢查 `error.details.reason` 是否為 `not-paired`、`scope-upgrade`、`role-upgrade` 或 `metadata-upgrade`,並在存在時使用 `requestId` / `remediationHint`。 | 核准待處理的要求:`openclaw devices list`,然後 `openclaw devices approve `。範圍/角色升級會在你審查要求的存取權後使用相同流程。 | -使用共用 Gateway 權杖/密碼驗證的直接 loopback 後端 RPC,不應依賴 CLI 的已配對裝置範圍基準。如果子代理或其他內部呼叫仍因 `scope-upgrade` 失敗,請確認呼叫端使用 `client.id: "gateway-client"` 和 `client.mode: "backend"`,且沒有強制指定明確的 `deviceIdentity` 或裝置權杖。 +使用共用 Gateway 權杖/密碼驗證的直接 loopback 後端 RPC 不應依賴 CLI 的已配對裝置範圍基準。如果子代理程式或其他內部呼叫仍因 `scope-upgrade` 失敗,請確認呼叫者使用 `client.id: "gateway-client"` 和 `client.mode: "backend"`,且沒有強制使用明確的 `deviceIdentity` 或裝置權杖。 裝置驗證 v2 遷移檢查: @@ -244,33 +244,33 @@ openclaw gateway status 如果記錄顯示 nonce/簽章錯誤,請更新連線用戶端並驗證: - + 用戶端等待 Gateway 發出的 `connect.challenge`。 - - 用戶端簽署與 challenge 綁定的承載資料。 + + 用戶端簽署繫結 challenge 的承載。 - - 用戶端使用相同的 challenge nonce 傳送 `connect.params.device.nonce`。 + + 用戶端傳送 `connect.params.device.nonce`,並使用相同的 challenge nonce。 如果 `openclaw devices rotate` / `revoke` / `remove` 意外遭拒: -- 已配對裝置權杖工作階段只能管理**自己的**裝置,除非呼叫端也具有 `operator.admin` -- `openclaw devices rotate --scope ...` 只能請求呼叫端工作階段已持有的操作員範圍 +- 已配對裝置權杖工作階段只能管理**自己的**裝置,除非呼叫者也具有 `operator.admin` +- `openclaw devices rotate --scope ...` 只能要求呼叫者工作階段已持有的操作員範圍 相關: - [設定](/zh-TW/gateway/configuration)(Gateway 驗證模式) -- [Control UI](/zh-TW/web/control-ui) +- [控制 UI](/zh-TW/web/control-ui) - [裝置](/zh-TW/cli/devices) - [遠端存取](/zh-TW/gateway/remote) - [受信任 Proxy 驗證](/zh-TW/gateway/trusted-proxy-auth) ## Gateway 服務未執行 -當服務已安裝但程序無法維持執行時使用。 +服務已安裝但程序無法保持執行時,請使用此項。 ```bash openclaw gateway status @@ -280,22 +280,22 @@ openclaw doctor openclaw gateway status --deep # also scan system-level services ``` -檢查: +尋找: - `Runtime: stopped` 及結束提示。 -- 服務設定不相符(`Config (cli)` vs `Config (service)`)。 +- 服務設定不相符(`Config (cli)` 與 `Config (service)`)。 - 連接埠/監聽器衝突。 - 使用 `--deep` 時出現額外的 launchd/systemd/schtasks 安裝。 - `Other gateway-like services detected (best effort)` 清理提示。 - - - `Gateway start blocked: set gateway.mode=local` 或 `existing config is missing gateway.mode` → 本機 Gateway 模式未啟用,或設定檔被覆寫且遺失 `gateway.mode`。修正:在你的設定中設定 `gateway.mode="local"`,或重新執行 `openclaw onboard --mode local` / `openclaw setup` 以重新標記預期的本機模式設定。如果你透過 Podman 執行 OpenClaw,預設設定路徑是 `~/.openclaw/openclaw.json`。 - - `refusing to bind gateway ... without auth` → 非 loopback 綁定缺少有效的 Gateway 驗證路徑(權杖/密碼,或已設定的受信任 Proxy)。 + + - `Gateway start blocked: set gateway.mode=local` 或 `existing config is missing gateway.mode` → local Gateway 模式未啟用,或設定檔遭覆寫並遺失 `gateway.mode`。修正:在你的設定中設定 `gateway.mode="local"`,或重新執行 `openclaw onboard --mode local` / `openclaw setup` 以重新蓋上預期的 local 模式設定。如果你透過 Podman 執行 OpenClaw,預設設定路徑是 `~/.openclaw/openclaw.json`。 + - `refusing to bind gateway ... without auth` → 沒有有效 Gateway 驗證路徑(權杖/密碼,或已設定的受信任 Proxy)時進行非 loopback 繫結。 - `another gateway instance is already listening` / `EADDRINUSE` → 連接埠衝突。 - - `Other gateway-like services detected (best effort)` → 存在過期或平行的 launchd/systemd/schtasks 單元。大多數設定應讓每台機器只保留一個 Gateway;如果你確實需要多個,請隔離連接埠 + 設定/狀態/工作區。請參閱 [/gateway#multiple-gateways-same-host](/zh-TW/gateway#multiple-gateways-same-host)。 - - doctor 顯示 `System-level OpenClaw gateway service detected` → 使用者層級服務缺失時,存在 systemd 系統單元。在允許 doctor 安裝使用者服務前,請移除或停用重複項;如果系統單元是預期的監督程式,請設定 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。 - - `Gateway service port does not match current gateway config` → 已安裝的監督程式仍固定使用舊的 `--port`。執行 `openclaw doctor --fix` 或 `openclaw gateway install --force`,然後重新啟動 Gateway 服務。 + - `Other gateway-like services detected (best effort)` → 存在過期或平行的 launchd/systemd/schtasks 單元。大多數設定應在每台機器保留一個 Gateway;如果你確實需要多個,請隔離連接埠 + 設定/狀態/工作區。請參閱 [/gateway#multiple-gateways-same-host](/zh-TW/gateway#multiple-gateways-same-host)。 + - Doctor 顯示 `System-level OpenClaw gateway service detected` → 使用者層級服務缺失時,存在 systemd 系統單元。請先移除或停用重複項,再允許 Doctor 安裝使用者服務;如果系統單元是預期的監督器,請設定 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。 + - `Gateway service port does not match current gateway config` → 已安裝的監督器仍固定舊的 `--port`。執行 `openclaw doctor --fix` 或 `openclaw gateway install --force`,然後重新啟動 Gateway 服務。 @@ -306,9 +306,9 @@ openclaw gateway status --deep # also scan system-level services - [設定](/zh-TW/gateway/configuration) - [Doctor](/zh-TW/gateway/doctor) -## Gateway 還原上次已知良好設定 +## Gateway 已還原最後已知良好設定 -當 Gateway 啟動,但記錄表示已還原 `openclaw.json` 時使用。 +Gateway 啟動,但記錄顯示它已還原 `openclaw.json` 時,請使用此項。 ```bash openclaw logs --follow @@ -317,24 +317,24 @@ openclaw config validate openclaw doctor ``` -檢查: +尋找: - `Config auto-restored from last-known-good` - `gateway: invalid config was restored from last-known-good backup` - `config reload restored last-known-good config after invalid-config` -- 作用中設定旁有帶時間戳記的 `openclaw.json.clobbered.*` 檔案 -- 以 `Config recovery warning` 開頭的主代理系統事件 +- 作用中設定旁邊的帶時間戳 `openclaw.json.clobbered.*` 檔案 +- 以 `Config recovery warning` 開頭的主代理程式系統事件 - - - 被拒絕的設定在啟動或熱重新載入期間未通過驗證。 - - OpenClaw 將被拒絕的承載資料保留為 `.clobbered.*`。 - - 作用中設定已從最後驗證過的上次已知良好副本還原。 - - 下一個主代理回合會收到警告,不要盲目重寫被拒絕的設定。 - - 如果所有驗證問題都位於 `plugins.entries....` 之下,OpenClaw 不會還原整個檔案。Plugin 本機失敗會保持明顯,同時不相關的使用者設定會留在作用中設定內。 + + - 遭拒的設定在啟動或熱重新載入期間未通過驗證。 + - OpenClaw 已將遭拒的承載保留為 `.clobbered.*`。 + - 作用中設定已從最後驗證的最後已知良好副本還原。 + - 下一次主代理程式回合會收到警告,不要盲目重寫遭拒的設定。 + - 如果所有驗證問題都位於 `plugins.entries....` 之下,OpenClaw 不會還原整個檔案。Plugin 本機失敗會保持明顯,同時不相關的使用者設定會保留在作用中設定中。 - + ```bash CONFIG="$(openclaw config file)" ls -lt "$CONFIG".clobbered.* "$CONFIG".rejected.* 2>/dev/null | head @@ -343,19 +343,20 @@ openclaw doctor openclaw doctor ``` - + - `.clobbered.*` 存在 → 外部直接編輯或啟動讀取已被還原。 - `.rejected.*` 存在 → OpenClaw 擁有的設定寫入在提交前未通過結構描述或覆寫檢查。 - - `Config write rejected:` → 該寫入嘗試移除必要形狀、讓檔案大幅縮小,或持久化無效設定。 - - `missing-meta-vs-last-good`、`gateway-mode-missing-vs-last-good` 或 `size-drop-vs-last-good:*` → 啟動時將目前檔案視為被覆寫,因為它與上次已知良好備份相比遺失欄位或大小縮減。 - - `Config last-known-good promotion skipped` → 候選項包含已遮蔽的秘密預留位置,例如 `***`。 + - `Config write rejected:` → 該寫入嘗試移除必要結構、大幅縮小檔案,或保留無效設定。 + - `Rejected validation details:` → 復原記錄或主代理程式通知包含導致還原的結構描述路徑,例如 `agents.defaults.execution` 或 `gateway.auth.password.source`。 + - `missing-meta-vs-last-good`、`gateway-mode-missing-vs-last-good` 或 `size-drop-vs-last-good:*` → 啟動將目前檔案視為遭覆寫,因為它相較於最後已知良好備份遺失欄位或大小減少。 + - `Config last-known-good promotion skipped` → 候選項包含已遮蔽的密鑰預留位置,例如 `***`。 - - 1. 如果已還原的作用中設定正確,請保留它。 - 2. 只從 `.clobbered.*` 或 `.rejected.*` 複製預期的鍵,然後使用 `openclaw config set` 或 `config.patch` 套用。 + + 1. 如果還原的作用中設定正確,請保留它。 + 2. 只從 `.clobbered.*` 或 `.rejected.*` 複製預期的金鑰,然後使用 `openclaw config set` 或 `config.patch` 套用。 3. 重新啟動前執行 `openclaw config validate`。 - 4. 如果你手動編輯,請保留完整的 JSON5 設定,而不只是你想變更的部分物件。 + 4. 如果你手動編輯,請保留完整 JSON5 設定,而不是只保留你想變更的部分物件。 @@ -368,7 +369,7 @@ openclaw doctor ## Gateway 探測警告 -當 `openclaw gateway probe` 到達某個目標,但仍列印警告區塊時使用。 +當 `openclaw gateway probe` 觸及某個目標,但仍列印警告區塊時,請使用此項。 ```bash openclaw gateway probe @@ -376,19 +377,19 @@ openclaw gateway probe --json openclaw gateway probe --ssh user@gateway-host ``` -檢查: +尋找: - JSON 輸出中的 `warnings[].code` 和 `primaryTargetId`。 -- 警告是否關於 SSH 後援、多個 Gateway、缺少範圍,或未解析的驗證參照。 +- 警告是關於 SSH 後援、多個 Gateway、缺少範圍,還是未解析的驗證參照。 常見特徵: - `SSH tunnel failed to start; falling back to direct probes.` → SSH 設定失敗,但命令仍嘗試直接設定/loopback 目標。 -- `multiple reachable gateways detected` → 多個目標回應。這通常表示有意的多 Gateway 設定,或過期/重複的監聽器。 -- `Read-probe diagnostics are limited by gateway scopes (missing operator.read)` → 連線成功,但詳細 RPC 受範圍限制;請配對裝置身分,或使用具有 `operator.read` 的認證。 -- `Gateway accepted the WebSocket connection, but follow-up read diagnostics failed` → 連線成功,但完整診斷 RPC 集逾時或失敗。將此視為可到達但診斷降級的 Gateway;比較 `--json` 輸出中的 `connect.ok` 和 `connect.rpcOk`。 -- `Capability: pairing-pending` 或 `gateway closed (1008): pairing required` → Gateway 已回應,但此用戶端在正常操作員存取前仍需要配對/核准。 -- 未解析的 `gateway.auth.*` / `gateway.remote.*` SecretRef 警告文字 → 此命令路徑無法取得失敗目標的驗證材料。 +- `multiple reachable gateways detected` → 超過一個目標回應。這通常表示刻意的多 Gateway 設定,或過期/重複的監聽器。 +- `Read-probe diagnostics are limited by gateway scopes (missing operator.read)` → 連線成功,但詳細 RPC 受到範圍限制;配對裝置身分或使用具有 `operator.read` 的認證。 +- `Gateway accepted the WebSocket connection, but follow-up read diagnostics failed` → 連線成功,但完整診斷 RPC 集合逾時或失敗。將此視為可連線但診斷降級的 Gateway;比較 `--json` 輸出中的 `connect.ok` 和 `connect.rpcOk`。 +- `Capability: pairing-pending` 或 `gateway closed (1008): pairing required` → Gateway 已回應,但此用戶端仍需要配對/核准後才能進行一般操作員存取。 +- 未解析的 `gateway.auth.*` / `gateway.remote.*` SecretRef 警告文字 → 此命令路徑中無法取得失敗目標的驗證材料。 相關: @@ -396,9 +397,9 @@ openclaw gateway probe --ssh user@gateway-host - [同一主機上的多個 Gateway](/zh-TW/gateway#multiple-gateways-same-host) - [遠端存取](/zh-TW/gateway/remote) -## Channel 已連線,但訊息未流動 +## 頻道已連線,但訊息未流動 -如果 Channel 狀態已連線但訊息流程中斷,請聚焦在原則、權限和 Channel 特定的傳遞規則。 +如果頻道狀態為已連線,但訊息流已停滯,請聚焦於政策、權限和頻道特定的傳遞規則。 ```bash openclaw channels status --probe @@ -408,16 +409,16 @@ openclaw logs --follow openclaw config get channels ``` -檢查: +尋找: -- DM 原則(`pairing`、`allowlist`、`open`、`disabled`)。 -- 群組 allowlist 和提及需求。 -- 缺少 Channel API 權限/範圍。 +- DM 政策(`pairing`、`allowlist`、`open`、`disabled`)。 +- 群組允許清單與提及需求。 +- 缺少頻道 API 權限/範圍。 常見特徵: - `mention required` → 訊息因群組提及政策而被忽略。 -- `pairing` / 待核准追蹤記錄 → 傳送者未獲核准。 +- `pairing` / 待核准追蹤 → 寄件者尚未核准。 - `missing_scope`、`not_in_channel`、`Forbidden`、`401/403` → 頻道驗證/權限問題。 相關: @@ -439,21 +440,21 @@ openclaw system heartbeat last openclaw logs --follow ``` -查看: +尋找: - Cron 已啟用且下一次喚醒存在。 -- 作業執行歷史狀態(`ok`、`skipped`、`error`)。 -- Heartbeat 略過原因(`quiet-hours`、`requests-in-flight`、`cron-in-progress`、`lanes-busy`、`alerts-disabled`、`empty-heartbeat-file`、`no-tasks-due`)。 +- 作業執行歷程狀態(`ok`、`skipped`、`error`)。 +- Heartbeat 跳過原因(`quiet-hours`、`requests-in-flight`、`cron-in-progress`、`lanes-busy`、`alerts-disabled`、`empty-heartbeat-file`、`no-tasks-due`)。 - + - `cron: scheduler disabled; jobs will not run automatically` → Cron 已停用。 - - `cron: timer tick failed` → 排程器計時滴答失敗;檢查檔案/記錄/執行階段錯誤。 - - `heartbeat skipped` 並帶有 `reason=quiet-hours` → 位於作用中時段範圍之外。 - - `heartbeat skipped` 並帶有 `reason=empty-heartbeat-file` → `HEARTBEAT.md` 存在,但只包含空白行 / markdown 標題,因此 OpenClaw 會略過模型呼叫。 - - `heartbeat skipped` 並帶有 `reason=no-tasks-due` → `HEARTBEAT.md` 包含 `tasks:` 區塊,但此計時滴答沒有任何到期工作。 + - `cron: timer tick failed` → 排程器 tick 失敗;檢查檔案/日誌/執行階段錯誤。 + - `heartbeat skipped` 搭配 `reason=quiet-hours` → 位於作用中時段之外。 + - `heartbeat skipped` 搭配 `reason=empty-heartbeat-file` → `HEARTBEAT.md` 存在,但只包含空白行 / markdown 標題,因此 OpenClaw 會略過模型呼叫。 + - `heartbeat skipped` 搭配 `reason=no-tasks-due` → `HEARTBEAT.md` 包含 `tasks:` 區塊,但這次 tick 沒有任何到期任務。 - `heartbeat: unknown accountId` → Heartbeat 傳遞目標的帳戶 ID 無效。 - - `heartbeat skipped` 並帶有 `reason=dm-blocked` → Heartbeat 目標解析為 DM 樣式目的地,而 `agents.defaults.heartbeat.directPolicy`(或個別 agent 覆寫)設定為 `block`。 + - `heartbeat skipped` 搭配 `reason=dm-blocked` → Heartbeat 目標解析為 DM 樣式目的地,但 `agents.defaults.heartbeat.directPolicy`(或個別代理覆寫)設為 `block`。 @@ -461,8 +462,8 @@ openclaw logs --follow 相關: - [Heartbeat](/zh-TW/gateway/heartbeat) -- [排程工作](/zh-TW/automation/cron-jobs) -- [排程工作:疑難排解](/zh-TW/automation/cron-jobs#troubleshooting) +- [排程任務](/zh-TW/automation/cron-jobs) +- [排程任務:疑難排解](/zh-TW/automation/cron-jobs#troubleshooting) ## Node 已配對,工具失敗 @@ -476,18 +477,18 @@ openclaw logs --follow openclaw status ``` -查看: +尋找: -- Node 在線且具有預期能力。 -- 相機/麥克風/位置/螢幕的作業系統權限授予。 +- Node 在線上且具備預期能力。 +- 相機/麥克風/位置/螢幕的作業系統權限授權。 - Exec 核准與允許清單狀態。 常見特徵: -- `NODE_BACKGROUND_UNAVAILABLE` → Node app 必須位於前景。 +- `NODE_BACKGROUND_UNAVAILABLE` → Node 應用程式必須位於前景。 - `*_PERMISSION_REQUIRED` / `LOCATION_PERMISSION_REQUIRED` → 缺少作業系統權限。 - `SYSTEM_RUN_DENIED: approval required` → Exec 核准待處理。 -- `SYSTEM_RUN_DENIED: allowlist miss` → 命令遭允許清單封鎖。 +- `SYSTEM_RUN_DENIED: allowlist miss` → 命令被允許清單封鎖。 相關: @@ -497,7 +498,7 @@ openclaw status ## 瀏覽器工具失敗 -當瀏覽器工具動作失敗,但 Gateway 本身健康時,請使用此段。 +當瀏覽器工具動作失敗,但 Gateway 本身健康時,請使用此項。 ```bash openclaw browser status @@ -507,41 +508,41 @@ openclaw logs --follow openclaw doctor ``` -查看: +尋找: -- `plugins.allow` 是否已設定且包含 `browser`。 -- 有效的瀏覽器執行檔路徑。 -- CDP profile 可連線性。 -- `existing-session` / `user` profiles 的本機 Chrome 可用性。 +- `plugins.allow` 是否已設定並包含 `browser`。 +- 有效的瀏覽器可執行檔路徑。 +- CDP 設定檔可連線性。 +- `existing-session` / `user` 設定檔的本機 Chrome 可用性。 - - - `unknown command "browser"` 或 `unknown command 'browser'` → 內建瀏覽器 Plugin 被 `plugins.allow` 排除。 - - 瀏覽器工具遺失 / 無法使用,而 `browser.enabled=true` → `plugins.allow` 排除 `browser`,因此 Plugin 從未載入。 + + - `unknown command "browser"` 或 `unknown command 'browser'` → 內建的 browser Plugin 被 `plugins.allow` 排除。 + - 瀏覽器工具遺失 / 不可用,但 `browser.enabled=true` → `plugins.allow` 排除 `browser`,因此 Plugin 從未載入。 - `Failed to start Chrome CDP on port` → 瀏覽器程序啟動失敗。 - `browser.executablePath not found` → 設定的路徑無效。 - - `browser.cdpUrl must be http(s) or ws(s)` → 設定的 CDP URL 使用不支援的配置,例如 `file:` 或 `ftp:`。 - - `browser.cdpUrl has invalid port` → 設定的 CDP URL 有錯誤或超出範圍的連接埠。 - - `Playwright is not available in this gateway build; '' is unsupported.` → 目前的 Gateway 安裝缺少內建瀏覽器 Plugin 的 `playwright-core` 執行階段相依性;執行 `openclaw doctor --fix`,然後重新啟動 Gateway。ARIA 快照和基本頁面截圖仍可運作,但導覽、AI 快照、CSS 選擇器元素截圖和 PDF 匯出仍無法使用。 + - `browser.cdpUrl must be http(s) or ws(s)` → 設定的 CDP URL 使用不支援的 scheme,例如 `file:` 或 `ftp:`。 + - `browser.cdpUrl has invalid port` → 設定的 CDP URL 具有錯誤或超出範圍的連接埠。 + - `Playwright is not available in this gateway build; '' is unsupported.` → 目前的 Gateway 安裝缺少內建 browser Plugin 的 `playwright-core` 執行階段相依項;請執行 `openclaw doctor --fix`,然後重新啟動 Gateway。ARIA 快照和基本頁面截圖仍可運作,但導覽、AI 快照、CSS 選擇器元素截圖和 PDF 匯出仍不可用。 - - - `Could not find DevToolsActivePort for chrome` → Chrome MCP existing-session 尚無法附加到選取的瀏覽器資料目錄。開啟瀏覽器檢查頁面、啟用遠端偵錯、保持瀏覽器開啟、核准第一次附加提示,然後重試。如果不需要登入狀態,建議使用受管理的 `openclaw` profile。 - - `No Chrome tabs found for profile="user"` → Chrome MCP 附加 profile 沒有開啟任何本機 Chrome 分頁。 + + - `Could not find DevToolsActivePort for chrome` → Chrome MCP existing-session 尚無法附加至所選的瀏覽器資料目錄。開啟瀏覽器檢查頁面、啟用遠端偵錯、保持瀏覽器開啟、核准第一次附加提示,然後重試。如果不需要登入狀態,建議使用受管理的 `openclaw` 設定檔。 + - `No Chrome tabs found for profile="user"` → Chrome MCP 附加設定檔沒有開啟中的本機 Chrome 分頁。 - `Remote CDP for profile "" is not reachable` → 設定的遠端 CDP 端點無法從 Gateway 主機連線。 - - `Browser attachOnly is enabled ... not reachable` 或 `Browser attachOnly is enabled and CDP websocket ... is not reachable` → 僅附加 profile 沒有可連線的目標,或 HTTP 端點有回應,但 CDP WebSocket 仍無法開啟。 + - `Browser attachOnly is enabled ... not reachable` 或 `Browser attachOnly is enabled and CDP websocket ... is not reachable` → 僅附加設定檔沒有可連線的目標,或 HTTP 端點有回應,但仍無法開啟 CDP WebSocket。 - + - `fullPage is not supported for element screenshots` → 截圖要求將 `--full-page` 與 `--ref` 或 `--element` 混用。 - `element screenshots are not supported for existing-session profiles; use ref from snapshot.` → Chrome MCP / `existing-session` 截圖呼叫必須使用頁面擷取或快照 `--ref`,而不是 CSS `--element`。 - - `existing-session file uploads do not support element selectors; use ref/inputRef.` → Chrome MCP 上傳掛鉤需要快照 refs,而不是 CSS 選擇器。 - - `existing-session file uploads currently support one file at a time.` → 在 Chrome MCP profiles 上,每次呼叫傳送一個上傳。 - - `existing-session dialog handling does not support timeoutMs.` → Chrome MCP profiles 上的對話框掛鉤不支援 timeout 覆寫。 - - `existing-session type does not support timeoutMs overrides.` → 對 `profile="user"` / Chrome MCP existing-session profiles 的 `act:type` 省略 `timeoutMs`,或在需要自訂 timeout 時使用受管理/CDP 瀏覽器 profile。 - - `existing-session evaluate does not support timeoutMs overrides.` → 對 `profile="user"` / Chrome MCP existing-session profiles 的 `act:evaluate` 省略 `timeoutMs`,或在需要自訂 timeout 時使用受管理/CDP 瀏覽器 profile。 - - `response body is not supported for existing-session profiles yet.` → `responsebody` 仍需要受管理瀏覽器或原始 CDP profile。 - - 僅附加或遠端 CDP profiles 上的過期 viewport / 深色模式 / locale / 離線覆寫 → 執行 `openclaw browser stop --browser-profile ` 以關閉作用中的控制工作階段並釋放 Playwright/CDP 模擬狀態,而不需重新啟動整個 Gateway。 + - `existing-session file uploads do not support element selectors; use ref/inputRef.` → Chrome MCP 上傳 hook 需要快照 ref,而不是 CSS 選擇器。 + - `existing-session file uploads currently support one file at a time.` → 在 Chrome MCP 設定檔上,每次呼叫只傳送一個上傳。 + - `existing-session dialog handling does not support timeoutMs.` → Chrome MCP 設定檔上的對話方塊 hook 不支援逾時覆寫。 + - `existing-session type does not support timeoutMs overrides.` → 對 `profile="user"` / Chrome MCP existing-session 設定檔的 `act:type` 省略 `timeoutMs`,或在需要自訂逾時時使用受管理/CDP 瀏覽器設定檔。 + - `existing-session evaluate does not support timeoutMs overrides.` → 對 `profile="user"` / Chrome MCP existing-session 設定檔的 `act:evaluate` 省略 `timeoutMs`,或在需要自訂逾時時使用受管理/CDP 瀏覽器設定檔。 + - `response body is not supported for existing-session profiles yet.` → `responsebody` 仍需要受管理瀏覽器或原始 CDP 設定檔。 + - 附加-only 或遠端 CDP 設定檔上的過期 viewport / 深色模式 / locale / 離線覆寫 → 執行 `openclaw browser stop --browser-profile ` 關閉作用中控制工作階段,並釋放 Playwright/CDP 模擬狀態,而不必重新啟動整個 Gateway。 @@ -551,12 +552,12 @@ openclaw doctor - [瀏覽器(OpenClaw 管理)](/zh-TW/tools/browser) - [瀏覽器疑難排解](/zh-TW/tools/browser-linux-troubleshooting) -## 如果你升級後某些東西突然壞掉 +## 如果你升級後某些東西突然故障 -大多數升級後故障都是設定漂移,或現在開始強制執行更嚴格的預設值。 +大多數升級後故障是設定漂移,或現在開始強制執行更嚴格的預設值。 - + ```bash openclaw gateway status openclaw config get gateway.mode @@ -566,8 +567,8 @@ openclaw doctor 要檢查的項目: - - 如果 `gateway.mode=remote`,CLI 呼叫可能會指向遠端,而你的本機服務其實正常。 - - 明確的 `--url` 呼叫不會回退到已儲存的憑證。 + - 如果 `gateway.mode=remote`,CLI 呼叫可能會指向遠端,而你的本機服務是正常的。 + - 明確的 `--url` 呼叫不會退回使用儲存的認證。 常見特徵: @@ -575,7 +576,7 @@ openclaw doctor - `unauthorized` → 端點可連線,但驗證錯誤。 - + ```bash openclaw config get gateway.bind openclaw config get gateway.auth.mode @@ -586,16 +587,16 @@ openclaw doctor 要檢查的項目: - - 非 loopback 綁定(`lan`、`tailnet`、`custom`)需要有效的 Gateway 驗證路徑:共用 token/密碼驗證,或正確設定的非 loopback `trusted-proxy` 部署。 - - 舊鍵如 `gateway.token` 不會取代 `gateway.auth.token`。 + - 非 loopback 綁定(`lan`、`tailnet`、`custom`)需要有效的 Gateway 驗證路徑:共享權杖/密碼驗證,或正確設定的非 loopback `trusted-proxy` 部署。 + - 舊鍵例如 `gateway.token` 不會取代 `gateway.auth.token`。 常見特徵: - `refusing to bind gateway ... without auth` → 非 loopback 綁定缺少有效的 Gateway 驗證路徑。 - - `Connectivity probe: failed` 且執行階段正在執行 → Gateway 存活,但目前 auth/url 無法存取。 + - `Connectivity probe: failed`,但執行階段正在執行 → Gateway 存活,但使用目前驗證/url 無法存取。 - + ```bash openclaw devices list openclaw pairing list --channel [--account ] @@ -605,18 +606,18 @@ openclaw doctor 要檢查的項目: - - 儀表板/Nodes 的待處理裝置核准。 + - 儀表板/Node 的待處理裝置核准。 - 政策或身分變更後的待處理 DM 配對核准。 常見特徵: - - `device identity required` → 裝置驗證未滿足。 - - `pairing required` → 傳送者/裝置必須先獲核准。 + - `device identity required` → 未滿足裝置驗證。 + - `pairing required` → 寄件者/裝置必須核准。 -如果檢查後服務設定與執行階段仍不一致,請從相同 profile/狀態目錄重新安裝服務中繼資料: +如果檢查後服務設定與執行階段仍不一致,請從相同的設定檔/狀態目錄重新安裝服務中繼資料: ```bash openclaw gateway install --force diff --git a/docs/zh-TW/help/testing.md b/docs/zh-TW/help/testing.md index bd2d07126..61774aff6 100644 --- a/docs/zh-TW/help/testing.md +++ b/docs/zh-TW/help/testing.md @@ -2,151 +2,193 @@ read_when: - 在本機或 CI 中執行測試 - 為模型/提供者錯誤新增回歸測試 - - 偵錯 Gateway + 代理行為 -summary: 測試工具套件:unit/e2e/live 套件、Docker 執行器,以及每項測試涵蓋的內容 + - 偵錯 Gateway + 代理程式行為 +summary: 測試工具包:單元/e2e/實際環境套件、Docker 執行器,以及每項測試涵蓋的內容 title: 測試 x-i18n: - generated_at: "2026-04-30T18:38:40Z" + generated_at: "2026-05-01T02:44:51Z" model: gpt-5.5 provider: openai - source_hash: 470a96c6b47c2708950d05adc4a4efba5fe290f0675a131e2888d2d0032d5953 + source_hash: f663a4476a59e4ccc2a6ea5b43eb0079534945eac37374bec891d6cccb1e941c source_path: help/testing.md workflow: 16 --- -OpenClaw 有三組 Vitest 測試套件(單元/整合、e2e、live),以及少量 Docker 執行器。這份文件是「我們如何測試」指南: +OpenClaw 有三組 Vitest 測試套件(單元/整合、e2e、實際測試)以及一小組 +Docker runner。本文件是「我們如何測試」指南: -- 每個套件涵蓋的範圍(以及刻意 _不_ 涵蓋的範圍)。 -- 常見工作流程要執行哪些命令(本機、推送前、除錯)。 -- live 測試如何探索認證資料並選取模型/提供者。 -- 如何為真實世界的模型/提供者問題新增迴歸測試。 +- 每個套件涵蓋哪些內容(以及刻意_不_涵蓋哪些內容)。 +- 常見工作流程(本機、推送前、除錯)該執行哪些指令。 +- 實際測試如何探索認證資料並選取模型/供應商。 +- 如何為真實世界的模型/供應商問題新增迴歸測試。 -**QA 堆疊(qa-lab、qa-channel、live 傳輸通道)**已另行記錄: +**QA 堆疊(qa-lab、qa-channel、實際傳輸通道)**另有文件說明: -- [QA 總覽](/zh-TW/concepts/qa-e2e-automation) — 架構、命令介面、情境撰寫。 -- [Matrix QA](/zh-TW/concepts/qa-matrix) — `pnpm openclaw qa matrix` 的參考。 -- [QA channel](/zh-TW/channels/qa-channel) — 由 repo 支援的情境所使用的合成傳輸 Plugin。 +- [QA 概覽](/zh-TW/concepts/qa-e2e-automation) — 架構、指令介面、情境撰寫。 +- [矩陣 QA](/zh-TW/concepts/qa-matrix) — `pnpm openclaw qa matrix` 的參考資料。 +- [QA channel](/zh-TW/channels/qa-channel) — repo-backed 情境使用的合成傳輸 Plugin。 -本頁涵蓋一般測試套件與 Docker/Parallels 執行器的執行方式。下方的 QA 專用執行器章節([QA 專用執行器](#qa-specific-runners))列出具體的 `qa` 呼叫方式,並指回上述參考。 +本頁涵蓋執行一般測試套件與 Docker/Parallels runner。下方的 QA 專用 runner 區段([QA-specific runners](#qa-specific-runners))列出具體的 `qa` 呼叫方式,並指回上述參考資料。 ## 快速開始 -大多數時候: +多數日子: - 完整閘門(推送前預期執行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test` -- 在資源充足機器上的較快本機完整套件執行:`pnpm test:max` -- 直接 Vitest 監看迴圈:`pnpm test:watch` -- 直接檔案目標現在也會路由擴充功能/通道路徑:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -- 當你正在迭代單一失敗時,優先使用目標式執行。 -- Docker 支援的 QA 站台:`pnpm qa:lab:up` -- Linux VM 支援的 QA 通道:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` +- 在資源充足的機器上較快執行本機完整套件:`pnpm test:max` +- 直接 Vitest watch 迴圈:`pnpm test:watch` +- 直接指定檔案現在也會路由 extension/channel 路徑:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- 當你正在針對單一失敗反覆修改時,優先使用目標式執行。 +- Docker-backed QA 站台:`pnpm qa:lab:up` +- Linux VM-backed QA 通道:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` -當你變更測試或想要額外信心時: +當你碰到測試或想要額外信心時: - 覆蓋率閘門:`pnpm test:coverage` - E2E 套件:`pnpm test:e2e` -當除錯真實提供者/模型時(需要真實認證資料): +當除錯真實供應商/模型時(需要真實認證資料): -- Live 套件(模型 + Gateway 工具/影像探測):`pnpm test:live` -- 安靜地鎖定一個 live 檔案:`pnpm test:live -- src/agents/models.profiles.live.test.ts` -- Docker live 模型掃描:`pnpm test:docker:live-models` - - 每個選取的模型現在會執行一個文字回合,加上一個小型檔案讀取風格探測。 - 中繼資料宣告支援 `image` 輸入的模型也會執行一個小型影像回合。 - 在隔離提供者失敗時,可用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或 +- 實際測試套件(模型 + Gateway 工具/圖片探測):`pnpm test:live` +- 安靜地鎖定一個實際測試檔案:`pnpm test:live -- src/agents/models.profiles.live.test.ts` +- Docker 實際模型掃描:`pnpm test:docker:live-models` + - 每個選取的模型現在都會執行一輪文字對話,加上一個小型檔案讀取風格探測。 + 其 metadata 宣告 `image` 輸入的模型也會執行一個極小的圖片對話。 + 隔離供應商失敗時,可用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或 `OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 停用額外探測。 - - CI 覆蓋:每日 `OpenClaw Scheduled Live And E2E Checks` 與手動 - `OpenClaw Release Checks` 都會以 `include_live_suites: true` 呼叫可重用的 live/E2E workflow,其中包含依提供者分片的獨立 Docker live 模型矩陣 jobs。 - - 若要進行聚焦的 CI 重新執行,請 dispatch `OpenClaw Live And E2E Checks (Reusable)`,並設定 `include_live_suites: true` 與 `live_models_only: true`。 - - 將新的高訊號提供者 secret 新增到 `scripts/ci-hydrate-live-auth.sh`, - 以及 `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 和其排程/發行呼叫端。 -- 原生 Codex 綁定聊天 smoke:`pnpm test:docker:live-codex-bind` - - 針對 Codex app-server 路徑執行 Docker live 通道,使用 `/codex bind` 綁定合成 Slack DM,執行 `/codex fast` 與 - `/codex permissions`,然後驗證純文字回覆與影像附件會經由原生 Plugin 綁定路由,而不是 ACP。 + - CI 覆蓋範圍:每日 `OpenClaw Scheduled Live And E2E Checks` 和手動 + `OpenClaw Release Checks` 都會以 `include_live_suites: true` 呼叫可重用的實際/E2E workflow,其中包含依供應商分片的獨立 Docker 實際模型 + 矩陣 jobs。 + - 若要聚焦 CI 重新執行,請以 `include_live_suites: true` 和 `live_models_only: true` dispatch `OpenClaw Live And E2E Checks (Reusable)`。 + - 將新的高訊號供應商 secrets 加到 `scripts/ci-hydrate-live-auth.sh`, + 以及 `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 和它的 + 排程/發行呼叫端。 +- 原生 Codex bound-chat smoke:`pnpm test:docker:live-codex-bind` + - 針對 Codex app-server 路徑執行一個 Docker 實際通道,使用 `/codex bind` 綁定合成 + Slack DM,執行 `/codex fast` 和 + `/codex permissions`,然後驗證純文字回覆與圖片附件會透過原生 Plugin binding 路由,而不是 ACP。 - Codex app-server harness smoke:`pnpm test:docker:live-codex-harness` - - 透過 Plugin 擁有的 Codex app-server harness 執行 Gateway agent 回合,驗證 `/codex status` 與 `/codex models`,並預設執行影像、cron MCP、子 agent 與 Guardian 探測。隔離其他 Codex app-server 失敗時,可用 - `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 停用子 agent 探測。若要聚焦檢查子 agent,請停用其他探測: + - 透過 Plugin 所有的 Codex app-server harness 執行 Gateway agent turns, + 驗證 `/codex status` 和 `/codex models`,並且預設執行圖片、 + cron MCP、sub-agent 與 Guardian 探測。隔離其他 Codex + app-server 失敗時,可用 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 停用 sub-agent 探測。若要聚焦 sub-agent 檢查,請停用其他探測: `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness`。 - 除非設定 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`,否則這會在子 agent 探測後結束。 -- Crestodian rescue 命令 smoke:`pnpm test:live:crestodian-rescue-channel` - - 針對訊息通道 rescue 命令介面的選擇性雙重保險檢查。它會執行 `/crestodian status`、佇列一個持久模型變更、回覆 `/crestodian yes`,並驗證稽核/設定寫入路徑。 + 除非設定 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`,否則這會在 sub-agent 探測後結束。 +- Crestodian rescue command smoke:`pnpm test:live:crestodian-rescue-channel` + - 針對 message-channel rescue command + 介面的 opt-in belt-and-suspenders 檢查。它會執行 `/crestodian status`、排入持久模型 + 變更、回覆 `/crestodian yes`,並驗證稽核/config 寫入路徑。 - Crestodian planner Docker smoke:`pnpm test:docker:crestodian-planner` - - 在無設定的容器中執行 Crestodian,並在 `PATH` 上放置假的 Claude CLI,驗證 fuzzy planner fallback 會轉譯成已稽核的型別化設定寫入。 + - 在 configless 容器中執行 Crestodian,`PATH` 上有 fake Claude CLI, + 並驗證模糊 planner fallback 會轉換成已稽核的 typed + config 寫入。 - Crestodian first-run Docker smoke:`pnpm test:docker:crestodian-first-run` - - 從空的 OpenClaw 狀態目錄開始,將裸 `openclaw` 路由至 - Crestodian,套用 setup/model/agent/Discord Plugin + SecretRef 寫入,驗證設定,並驗證稽核項目。相同的 Ring 0 設定路徑也由 QA Lab 中的 - `pnpm openclaw qa suite --scenario crestodian-ring-zero-setup` 涵蓋。 -- Moonshot/Kimi 成本 smoke:設定 `MOONSHOT_API_KEY` 後,執行 - `openclaw models list --provider moonshot --json`,接著針對 `moonshot/kimi-k2.6` 執行隔離的 + - 從空的 OpenClaw state dir 開始,將裸 `openclaw` 路由到 + Crestodian,套用 setup/model/agent/Discord Plugin + SecretRef 寫入, + 驗證 config,並驗證稽核項目。同一個 Ring 0 設定路徑 + 也在 QA Lab 中由 + `pnpm openclaw qa suite --scenario crestodian-ring-zero-setup` 覆蓋。 +- Moonshot/Kimi cost smoke:設定 `MOONSHOT_API_KEY` 後,執行 + `openclaw models list --provider moonshot --json`,然後針對 `moonshot/kimi-k2.6` 執行隔離的 `openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json`。 - 驗證 JSON 回報 Moonshot/K2.6,且 assistant transcript 儲存標準化的 `usage.cost`。 + 驗證 JSON 回報 Moonshot/K2.6,且 assistant transcript 儲存正規化的 `usage.cost`。 -當你只需要一個失敗案例時,優先透過下方描述的 allowlist env vars 縮小 live 測試範圍。 +當你只需要一個失敗案例時,優先使用下方描述的 allowlist env vars 縮小實際測試範圍。 -## QA 專用執行器 +## QA 專用 runner -當你需要 QA-lab 真實度時,這些命令會與主要測試套件並列: +當你需要 QA-lab 的真實感時,這些指令位於主要測試套件旁: -CI 會在專用 workflows 中執行 QA Lab。`Parity gate` 會在相符 PR 與手動 dispatch 時使用 mock providers 執行。`QA-Lab - All Lanes` 會每晚在 `main` 上執行,也可手動 dispatch,並將 mock parity gate、live Matrix 通道、Convex 管理的 live Telegram 通道,以及 Convex 管理的 live Discord 通道作為平行 jobs。排程 QA 與發行檢查會明確傳遞 Matrix `--profile fast`,而 Matrix CLI 與手動 workflow input 的預設值維持 -`all`;手動 dispatch 可將 `all` 分片成 `transport`、`media`、`e2ee-smoke`、 -`e2ee-deep` 與 `e2ee-cli` jobs。`OpenClaw Release Checks` 會在發行核准前執行 parity 加上 fast Matrix 與 Telegram 通道,並使用 -`mock-openai/gpt-5.5` 進行發行傳輸檢查,讓它們保持可決定性並避免一般提供者 Plugin 啟動。這些 live 傳輸 Gateway 會停用記憶體搜尋;記憶體行為仍由 QA parity 套件涵蓋。 +CI 在專用 workflow 中執行 QA Lab。`Parity gate` 會在相符 PR 上執行,也可透過手動 dispatch 搭配 mock providers 執行。`QA-Lab - All Lanes` 每晚在 +`main` 上執行,也可由手動 dispatch 執行,並將 mock parity gate、實際 Matrix 通道、 +Convex-managed 實際 Telegram 通道,以及 Convex-managed 實際 Discord 通道作為 +平行 jobs。排程 QA 和發行檢查會明確傳入 Matrix `--profile fast`, +而 Matrix CLI 與手動 workflow input 的預設值仍是 +`all`;手動 dispatch 可將 `all` 分片為 `transport`、`media`、`e2ee-smoke`、 +`e2ee-deep` 和 `e2ee-cli` jobs。`OpenClaw Release Checks` 在發行核准前執行 parity 加上 +快速 Matrix 與 Telegram 通道,並使用 +`mock-openai/gpt-5.5` 做發行傳輸檢查,讓它們保持 deterministic +並避免一般 provider-plugin startup。這些實際傳輸 gateways 會停用 +memory search;memory 行為仍由 QA parity suites 覆蓋。 -完整發行 live media 分片使用 +完整發行實際 media shards 使用 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`,其中已包含 -`ffmpeg` 與 `ffprobe`。Docker live 模型/backend 分片使用共用的 -`ghcr.io/openclaw/openclaw-live-test:` 映像檔,該映像檔會為每個選取 commit 建置一次,之後以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取,而不是在每個分片內重新建置。 +`ffmpeg` 和 `ffprobe`。Docker 實際模型/backend shards 使用共享的 +`ghcr.io/openclaw/openclaw-live-test:` 映像,該映像會針對每個選取的 +commit 建置一次,然後用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取,而不是在每個 shard 裡重新建置。 - `pnpm openclaw qa suite` - - 直接在 host 上執行由 repo 支援的 QA 情境。 - - 預設會使用隔離的 Gateway workers 平行執行多個選取情境。`qa-channel` 預設 concurrency 為 4(受選取情境數量限制)。使用 `--concurrency ` 調整 worker 數量,或使用 `--concurrency 1` 執行較舊的序列通道。 - - 任一情境失敗時會以非零狀態結束。當你想要產物但不想要失敗退出碼時,使用 `--allow-failures`。 - - 支援提供者模式 `live-frontier`、`mock-openai` 與 `aimock`。 - `aimock` 會啟動本機 AIMock 支援的提供者伺服器,用於實驗性 fixture 與 protocol-mock 覆蓋,而不取代情境感知的 + - 直接在 host 上執行 repo-backed QA 情境。 + - 預設以隔離的 gateway workers 平行執行多個選取的情境。 + `qa-channel` 預設 concurrency 為 4(受選取的 scenario count 限制)。使用 `--concurrency ` 調整 worker + 數量,或用 `--concurrency 1` 執行較舊的 serial 通道。 + - 任何情境失敗時以非零狀態結束。當你想要 artifacts 但不想要失敗 exit code 時,使用 `--allow-failures`。 + - 支援 provider modes `live-frontier`、`mock-openai` 和 `aimock`。 + `aimock` 會啟動本機 AIMock-backed provider server,用於實驗性 + fixture 與 protocol-mock 覆蓋範圍,而不取代 scenario-aware `mock-openai` 通道。 - `pnpm test:gateway:cpu-scenarios` - - 執行 Gateway 啟動 bench 加上一小組 mock QA Lab 情境套件 + - 執行 gateway startup bench 加上一小包 mock QA Lab 情境 (`channel-chat-baseline`、`memory-failure-fallback`、 - `gateway-restart-inflight-run`),並在 `.artifacts/gateway-cpu-scenarios/` 下寫入合併的 CPU 觀察摘要。 - - 預設只標記持續性高 CPU 觀察(`--cpu-core-warn` 加上 `--hot-wall-warn-ms`),因此短暫啟動突增會被記錄為指標,而不會看起來像數分鐘 Gateway 滿載迴歸。 - - 使用已建置的 `dist` 產物;當 checkout 尚未有新鮮 runtime 輸出時,請先執行 build。 + `gateway-restart-inflight-run`),並在 `.artifacts/gateway-cpu-scenarios/` 下寫入合併的 CPU observation + summary。 + - 預設只標記持續性的 hot CPU observations(`--cpu-core-warn` + 加上 `--hot-wall-warn-ms`),因此短暫 startup bursts 會被記錄為 metrics, + 不會看起來像是持續數分鐘的 gateway peg regression。 + - 使用已建置的 `dist` artifacts;當 checkout 還沒有新的 runtime output 時,請先執行 build。 - `pnpm openclaw qa suite --runner multipass` - - 在一次性 Multipass Linux VM 中執行相同 QA 套件。 + - 在 disposable Multipass Linux VM 中執行同一組 QA 套件。 - 保持與 host 上 `qa suite` 相同的情境選取行為。 - - 重用與 `qa suite` 相同的提供者/模型選取 flags。 - - Live 執行會轉送對 guest 來說實用的支援 QA auth inputs: - env 型提供者 keys、QA live provider config path,以及存在時的 `CODEX_HOME`。 - - 輸出目錄必須保持在 repo root 下,讓 guest 能透過已掛載 workspace 寫回。 - - 在 `.artifacts/qa-e2e/...` 下寫入一般 QA report + summary 加上 Multipass logs。 + - 重用與 `qa suite` 相同的 provider/model selection flags。 + - 實際執行會 forward 對 guest 實用且受支援的 QA auth inputs: + env-based provider keys、QA live provider config path,以及存在時的 `CODEX_HOME`。 + - Output dirs 必須保持在 repo root 底下,讓 guest 能透過 + mounted workspace 寫回。 + - 在 `.artifacts/qa-e2e/...` 下寫入一般 QA report + summary 以及 Multipass logs。 - `pnpm qa:lab:up` - - 啟動 Docker 支援的 QA 站台,用於 operator 風格 QA 工作。 + - 啟動 Docker-backed QA 站台,用於 operator-style QA 工作。 - `pnpm test:docker:npm-onboard-channel-agent` - - 從目前 checkout 建置 npm tarball,在 Docker 中全域安裝,執行非互動式 OpenAI API key onboarding,預設設定 Telegram,驗證啟用 Plugin 會依需求安裝 runtime dependencies,執行 doctor,並針對 mocked OpenAI endpoint 執行一個本機 agent 回合。 - - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 以 Discord 執行相同的 packaged-install 通道。 + - 從目前 checkout 建置 npm tarball,在 + Docker 中全域安裝它,執行非互動式 OpenAI API-key onboarding,預設設定 Telegram, + 驗證啟用 Plugin 會按需安裝 runtime dependencies,執行 doctor, + 並針對 mocked OpenAI endpoint 執行一次本機 agent turn。 + - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 以 Discord 執行同一個 packaged-install + 通道。 - `pnpm test:docker:session-runtime-context` - - 針對嵌入式 runtime context transcripts 執行可決定性的 built-app Docker smoke。它會驗證隱藏 OpenClaw runtime context 會作為非顯示 custom message 持久化,而不是洩漏到可見 user turn,然後植入受影響的損壞 session JSONL,並驗證 - `openclaw doctor --fix` 會將其改寫到 active branch 並建立備份。 + - 針對 embedded runtime context + transcripts 執行 deterministic built-app Docker smoke。它會驗證隱藏的 OpenClaw runtime context 會以 + non-display custom message 持久化,而不是洩漏到可見的 user turn 中, + 接著植入受影響的 broken session JSONL,並驗證 + `openclaw doctor --fix` 會將它重寫到 active branch 且建立 backup。 - `pnpm test:docker:npm-telegram-live` - - 在 Docker 中安裝 OpenClaw package candidate,執行 installed-package onboarding,透過已安裝 CLI 設定 Telegram,接著重用 live Telegram QA 通道,並將該已安裝 package 作為 SUT Gateway。 + - 在 Docker 中安裝 OpenClaw package candidate,執行 installed-package + onboarding,透過已安裝的 CLI 設定 Telegram,接著重用 + 實際 Telegram QA 通道,並將該已安裝 package 作為 SUT Gateway。 - 預設為 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`;設定 `OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgz` 或 - `OPENCLAW_CURRENT_PACKAGE_TGZ`,可測試已解析的本機 tarball,而不是從 registry 安裝。 - - 使用與 `pnpm openclaw qa telegram` 相同的 Telegram env credentials 或 Convex credential source。對於 CI/發行自動化,設定 - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`,加上 - `OPENCLAW_QA_CONVEX_SITE_URL` 與 role secret。如果 - `OPENCLAW_QA_CONVEX_SITE_URL` 與 Convex role secret 存在於 CI 中, + `OPENCLAW_CURRENT_PACKAGE_TGZ`,即可測試已解析的本機 tarball,而不是 + 從 registry 安裝。 + - 使用與 `pnpm openclaw qa telegram` 相同的 Telegram env credentials 或 Convex credential source。針對 CI/發行自動化,設定 + `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex` 加上 + `OPENCLAW_QA_CONVEX_SITE_URL` 和 role secret。如果 + `OPENCLAW_QA_CONVEX_SITE_URL` 與 Convex role secret 存在於 CI, Docker wrapper 會自動選取 Convex。 - - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 只會針對此通道覆寫共用的 + - `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 只會針對此通道覆寫共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`。 - GitHub Actions 將此通道公開為手動 maintainer workflow `NPM Telegram Beta E2E`。它不會在 merge 時執行。該 workflow 使用 `qa-live-shared` environment 與 Convex CI credential leases。 -- GitHub Actions 也公開 `Package Acceptance`,用於針對一個 candidate package 進行旁路產品證明。它接受受信任 ref、已發布 npm spec、HTTPS tarball URL 加上 SHA-256,或來自另一個 run 的 tarball artifact,將標準化的 `openclaw-current.tgz` 上傳為 `package-under-test`,然後使用 smoke、package、product、full 或 custom 通道 profiles 執行既有 Docker E2E scheduler。設定 `telegram_mode=mock-openai` 或 `live-frontier`,可針對相同的 `package-under-test` artifact 執行 Telegram QA workflow。 - - 最新 beta 產品證明: +- GitHub Actions 也公開 `Package Acceptance`,用於針對一個 candidate package 的 side-run product proof。 + 它接受 trusted ref、published npm spec、 + HTTPS tarball URL 加 SHA-256,或另一個 run 的 tarball artifact,將正規化的 + `openclaw-current.tgz` 上傳為 `package-under-test`,然後以 smoke、package、product、full 或 custom + lane profiles 執行既有的 Docker E2E scheduler。設定 `telegram_mode=mock-openai` 或 `live-frontier`,即可針對相同的 + `package-under-test` artifact 執行 Telegram QA workflow。 + - 最新 beta product proof: ```bash gh workflow run package-acceptance.yml --ref main \ @@ -156,7 +198,7 @@ gh workflow run package-acceptance.yml --ref main \ -f telegram_mode=mock-openai ``` -- 精確 tarball URL 證明需要 digest: +- 精確 tarball URL proof 需要 digest: ```bash gh workflow run package-acceptance.yml --ref main \ @@ -166,7 +208,7 @@ gh workflow run package-acceptance.yml --ref main \ -f suite_profile=package ``` -- Artifact 證明會從另一個 Actions 執行下載 tarball Artifact: +- 成品證明會從另一個 Actions 執行下載 tarball 成品: ```bash gh workflow run package-acceptance.yml --ref main \ @@ -177,74 +219,74 @@ gh workflow run package-acceptance.yml --ref main \ ``` - `pnpm test:docker:bundled-channel-deps` - - 在 Docker 中封裝並安裝目前的 OpenClaw 建置,啟動已設定 OpenAI 的 Gateway,然後透過設定編輯啟用內建通道/Plugin。 - - 驗證設定探索會讓未設定的 Plugin 執行階段相依性保持不存在,第一次設定後的 Gateway 或 doctor 執行會按需安裝每個內建 Plugin 的執行階段相依性,而第二次重新啟動不會重新安裝已啟用的相依性。 - - 也會安裝已知較舊的 npm 基準版本,在執行 `openclaw update --tag ` 前啟用 Telegram,並驗證候選版本的更新後 doctor 會修復內建通道執行階段相依性,而不需要測試框架端的 postinstall 修復。 + - 在 Docker 中封裝並安裝目前的 OpenClaw 建置,啟動已設定 OpenAI 的 Gateway,然後透過設定編輯啟用內建 channel/Plugin。 + - 驗證設定探索會讓未設定的 Plugin 執行階段相依性保持不存在,第一次設定完成的 Gateway 或 doctor 執行會依需求安裝每個內建 Plugin 的執行階段相依性,且第二次重新啟動不會重新安裝已啟用的相依性。 + - 也會安裝已知較舊的 npm 基準版本,在執行 `openclaw update --tag ` 前啟用 Telegram,並驗證候選版本的更新後 doctor 會修復內建 channel 執行階段相依性,而不需要測試框架端的 postinstall 修復。 - `pnpm test:parallels:npm-update` - - 跨 Parallels guest 執行原生封裝安裝更新 smoke。每個選定的平台會先安裝要求的基準套件,然後在同一個 guest 中執行已安裝的 `openclaw update` 命令,並驗證已安裝版本、更新狀態、Gateway 就緒狀態,以及一個本機代理回合。 - - 在針對單一 guest 反覆測試時,使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 取得摘要 Artifact 路徑和每條 lane 狀態。 - - OpenAI lane 預設使用 `openai/gpt-5.5` 作為即時代理回合證明。刻意驗證另一個 OpenAI 模型時,傳入 `--model ` 或設定 `OPENCLAW_PARALLELS_OPENAI_MODEL`。 - - 將長時間本機執行包在主機逾時中,避免 Parallels 傳輸停滯耗盡剩餘測試時段: + - 跨 Parallels 來賓系統執行原生封裝安裝更新 smoke。每個選定的平台會先安裝要求的基準套件,接著在同一個來賓系統中執行已安裝的 `openclaw update` 命令,並驗證已安裝版本、更新狀態、Gateway 就緒狀態,以及一次本機代理回合。 + - 在針對單一來賓系統反覆測試時,使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 取得摘要成品路徑與每個 lane 的狀態。 + - OpenAI lane 預設使用 `openai/gpt-5.5` 作為即時代理回合證明。若刻意驗證另一個 OpenAI 模型,請傳入 `--model ` 或設定 `OPENCLAW_PARALLELS_OPENAI_MODEL`。 + - 以主機逾時包住長時間本機執行,避免 Parallels 傳輸停滯耗盡剩餘測試時段: ```bash timeout --foreground 150m pnpm test:parallels:npm-update -- --json timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json ``` - - 腳本會在 `/tmp/openclaw-parallels-npm-update.*` 下寫入巢狀 lane 記錄。先檢查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`,再判定外層 wrapper 已停住。 - - Windows 更新在冷 guest 上可能會花 10 到 15 分鐘執行更新後 doctor/執行階段相依性修復;只要巢狀 npm 偵錯記錄仍在前進,這仍是健康狀態。 - - 不要將這個聚合 wrapper 與個別 Parallels macOS、Windows 或 Linux smoke lane 並行執行。它們共用 VM 狀態,可能在 snapshot 還原、套件服務或 guest Gateway 狀態上發生衝突。 - - 更新後證明會執行一般內建 Plugin 介面,因為語音、影像生成和媒體理解等能力 facade 會透過內建執行階段 API 載入,即使代理回合本身只檢查簡單文字回應。 + - 此腳本會將巢狀 lane 記錄寫入 `/tmp/openclaw-parallels-npm-update.*` 底下。先檢查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`,再判定外層包裝器是否卡住。 + - 在冷啟動的來賓系統上,Windows 更新可能會在更新後 doctor/執行階段相依性修復花費 10 到 15 分鐘;只要巢狀 npm 偵錯記錄仍在推進,這仍屬正常。 + - 不要將這個聚合包裝器與個別 Parallels macOS、Windows 或 Linux smoke lane 平行執行。它們共享 VM 狀態,可能在快照還原、套件供應或來賓 Gateway 狀態上衝突。 + - 更新後證明會執行一般內建 Plugin 介面,因為語音、影像生成與媒體理解等 capability facade 會透過內建執行階段 API 載入,即使代理回合本身只檢查簡單文字回應。 - `pnpm openclaw qa aimock` - - 僅啟動本機 AIMock provider 伺服器,用於直接 protocol smoke 測試。 + - 只啟動本機 AIMock provider 伺服器,用於直接 protocol smoke 測試。 - `pnpm openclaw qa matrix` - - 針對一次性 Docker 後端的 Tuwunel homeserver 執行 Matrix 即時 QA lane。僅限 source checkout — 封裝安裝不會隨附 `qa-lab`。 - - 完整 CLI、profile/scenario 目錄、環境變數與 Artifact 版面配置:[Matrix QA](/zh-TW/concepts/qa-matrix)。 + - 針對一次性 Docker 支援的 Tuwunel homeserver 執行 Matrix 即時 QA lane。僅限原始碼 checkout —— 封裝安裝不會隨附 `qa-lab`。 + - 完整 CLI、profile/scenario 目錄、env vars 與成品版面配置:[Matrix QA](/zh-TW/concepts/qa-matrix)。 - `pnpm openclaw qa telegram` - - 使用來自環境的 driver 和 SUT bot token,針對真實私人群組執行 Telegram 即時 QA lane。 - - 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。群組 ID 必須是數值型 Telegram chat ID。 - - 支援 `--credential-source convex` 以使用共用集區憑證。預設使用 env 模式,或設定 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以選用集區 lease。 - - 任何 scenario 失敗時會以非零狀態結束。當你想取得 Artifact 而不想要失敗結束碼時,使用 `--allow-failures`。 - - 需要同一個私人群組中的兩個不同 bot,且 SUT bot 必須公開 Telegram 使用者名稱。 - - 為了穩定的 bot 對 bot 觀察,請在 `@BotFather` 中為兩個 bot 啟用 Bot-to-Bot Communication Mode,並確保 driver bot 可以觀察群組 bot 流量。 - - 會在 `.artifacts/qa-e2e/...` 下寫入 Telegram QA 報告、摘要和 observed-messages Artifact。回覆 scenarios 包含從 driver 傳送要求到觀察到 SUT 回覆的 RTT。 + - 使用來自 env 的 driver 與 SUT bot token,針對真實私有群組執行 Telegram 即時 QA lane。 + - 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。group id 必須是數字形式的 Telegram chat id。 + - 支援 `--credential-source convex` 以使用共享集區認證。預設使用 env 模式,或設定 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以選擇使用集區 lease。 + - 任一 scenario 失敗時會以非零狀態結束。若你想要產生成品但不讓結束碼失敗,請使用 `--allow-failures`。 + - 需要同一個私有群組中的兩個不同 bot,且 SUT bot 必須公開 Telegram 使用者名稱。 + - 為了穩定觀察 bot 對 bot 行為,請在 `@BotFather` 中為兩個 bot 啟用 Bot-to-Bot Communication Mode,並確保 driver bot 可以觀察群組 bot 流量。 + - 會在 `.artifacts/qa-e2e/...` 底下寫入 Telegram QA 報告、摘要與 observed-messages 成品。回覆 scenario 會包含從 driver 傳送要求到觀察到 SUT 回覆的 RTT。 -即時傳輸 lane 共用一個標準合約,讓新的傳輸不會偏移;每個 lane 的涵蓋矩陣位於 [QA 概觀 → 即時傳輸涵蓋範圍](/zh-TW/concepts/qa-e2e-automation#live-transport-coverage)。`qa-channel` 是廣泛的合成套件,不屬於該矩陣。 +即時傳輸 lane 共享一個標準合約,使新的傳輸不會偏移;每個 lane 的覆蓋矩陣位於 [QA overview → 即時傳輸覆蓋率](/zh-TW/concepts/qa-e2e-automation#live-transport-coverage)。`qa-channel` 是廣泛的合成套件,不屬於該矩陣的一部分。 -### 透過 Convex 共用 Telegram 憑證 (v1) +### 透過 Convex 共享 Telegram 認證 (v1) -為 `openclaw qa telegram` 啟用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)時,QA lab 會從 Convex 後端集區取得獨佔 lease,在 lane 執行期間對該 lease 傳送 Heartbeat,並在關閉時釋放 lease。 +當為 `openclaw qa telegram` 啟用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)時,QA lab 會從 Convex 支援的集區取得獨占 lease,在 lane 執行期間對該 lease 傳送 heartbeat,並在關閉時釋放 lease。 參考 Convex 專案 scaffold: - `qa/convex-credential-broker/` -必要環境變數: +必要 env vars: - `OPENCLAW_QA_CONVEX_SITE_URL`(例如 `https://your-deployment.convex.site`) - 所選角色的一個 secret: - `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` 用於 `maintainer` - `OPENCLAW_QA_CONVEX_SECRET_CI` 用於 `ci` -- 憑證角色選擇: +- 認證角色選擇: - CLI:`--credential-role maintainer|ci` - Env 預設值:`OPENCLAW_QA_CREDENTIAL_ROLE`(在 CI 中預設為 `ci`,否則為 `maintainer`) -選用環境變數: +選用 env vars: - `OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS`(預設 `1200000`) - `OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS`(預設 `30000`) - `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS`(預設 `90000`) - `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS`(預設 `15000`) - `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX`(預設 `/qa-credentials/v1`) -- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(選用 trace ID) -- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允許 local-only 開發使用 loopback `http://` Convex URL。 +- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(選用 trace id) +- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允許僅限本機開發使用的 loopback `http://` Convex URL。 `OPENCLAW_QA_CONVEX_SITE_URL` 在一般操作中應使用 `https://`。 -Maintainer 管理命令(集區新增/移除/列出)特別需要 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 +維護者管理命令(pool add/remove/list)特別需要 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 -供 maintainer 使用的 CLI helper: +維護者 CLI 輔助工具: ```bash pnpm openclaw qa credentials doctor @@ -253,101 +295,104 @@ pnpm openclaw qa credentials list --kind telegram pnpm openclaw qa credentials remove --credential-id ``` -在即時執行前使用 `doctor` 檢查 Convex site URL、broker secret、endpoint prefix、HTTP 逾時和 admin/list 可達性,且不列印 secret 值。在腳本和 CI 工具中使用 `--json` 取得機器可讀輸出。 +在即時執行前使用 `doctor` 檢查 Convex site URL、broker secrets、endpoint prefix、HTTP timeout 與 admin/list 可達性,而不列印 secret 值。在腳本與 CI 工具中使用 `--json` 取得機器可讀輸出。 預設 endpoint 合約(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): - `POST /acquire` - - Request: `{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }` - - Success: `{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }` - - Exhausted/retryable: `{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` + - 要求:`{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }` + - 成功:`{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }` + - 耗盡/可重試:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` - `POST /heartbeat` - - Request: `{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }` - - Success: `{ status: "ok" }`(或空的 `2xx`) + - 要求:`{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }` + - 成功:`{ status: "ok" }`(或空白 `2xx`) - `POST /release` - - Request: `{ kind, ownerId, actorRole, credentialId, leaseToken }` - - Success: `{ status: "ok" }`(或空的 `2xx`) -- `POST /admin/add`(僅 maintainer secret) - - Request: `{ kind, actorId, payload, note?, status? }` - - Success: `{ status: "ok", credential }` -- `POST /admin/remove`(僅 maintainer secret) - - Request: `{ credentialId, actorId }` - - Success: `{ status: "ok", changed, credential }` - - Active lease guard: `{ status: "error", code: "LEASE_ACTIVE", ... }` -- `POST /admin/list`(僅 maintainer secret) - - Request: `{ kind?, status?, includePayload?, limit? }` - - Success: `{ status: "ok", credentials, count }` + - 要求:`{ kind, ownerId, actorRole, credentialId, leaseToken }` + - 成功:`{ status: "ok" }`(或空白 `2xx`) +- `POST /admin/add`(僅限維護者 secret) + - 要求:`{ kind, actorId, payload, note?, status? }` + - 成功:`{ status: "ok", credential }` +- `POST /admin/remove`(僅限維護者 secret) + - 要求:`{ credentialId, actorId }` + - 成功:`{ status: "ok", changed, credential }` + - 作用中 lease 保護:`{ status: "error", code: "LEASE_ACTIVE", ... }` +- `POST /admin/list`(僅限維護者 secret) + - 要求:`{ kind?, status?, includePayload?, limit? }` + - 成功:`{ status: "ok", credentials, count }` Telegram kind 的 payload 形狀: - `{ groupId: string, driverToken: string, sutToken: string }` -- `groupId` 必須是數值型 Telegram chat ID 字串。 -- `admin/add` 會針對 `kind: "telegram"` 驗證這個形狀,並拒絕格式錯誤的 payload。 +- `groupId` 必須是數字形式的 Telegram chat id 字串。 +- `admin/add` 會針對 `kind: "telegram"` 驗證此形狀,並拒絕格式錯誤的 payload。 -### 將通道加入 QA +### 將 channel 新增到 QA -新通道 adapter 的架構和 scenario-helper 名稱位於 [QA 概觀 → 新增通道](/zh-TW/concepts/qa-e2e-automation#adding-a-channel)。最低標準:在共用 `qa-lab` host seam 上實作 transport runner,在 Plugin manifest 中宣告 `qaRunners`,掛載為 `openclaw qa `,並在 `qa/scenarios/` 下撰寫 scenario。 +新 channel 轉接器的架構與 scenario-helper 名稱位於 [QA overview → 新增 channel](/zh-TW/concepts/qa-e2e-automation#adding-a-channel)。最低門檻:在共享 `qa-lab` host seam 上實作傳輸 runner,在 Plugin manifest 中宣告 `qaRunners`,掛載為 `openclaw qa `,並在 `qa/scenarios/` 底下撰寫 scenario。 -## 測試套件(何處執行什麼) +## 測試套件(在哪裡執行什麼) -將套件視為「真實度逐步提高」(同時 flakiness/成本也逐步提高): +把這些套件視為「真實性遞增」(同時 flakiness/成本也遞增): -### Unit / integration(預設) +### 單元 / 整合(預設) - 命令:`pnpm test` -- 設定:未鎖定目標的執行會使用 `vitest.full-*.config.ts` shard 集合,並可能將多專案 shard 展開為每個專案的設定,以便平行排程 -- 檔案:`src/**/*.test.ts`、`packages/**/*.test.ts` 和 `test/**/*.test.ts` 下的 core/unit inventory;UI unit 測試在專用的 `unit-ui` shard 中執行 +- 設定:未指定目標的執行會使用 `vitest.full-*.config.ts` shard 集合,且可能將多專案 shard 展開為每個專案的設定,以便平行排程 +- 檔案:位於 `src/**/*.test.ts`、`packages/**/*.test.ts` 和 `test/**/*.test.ts` 底下的 core/unit inventory;UI 單元測試會在專用的 `unit-ui` shard 中執行 - 範圍: - - 純 unit 測試 - - 程序內 integration 測試(Gateway auth、routing、tooling、parsing、config) - - 已知 bug 的決定性 regression -- 預期: + - 純單元測試 + - 進程內整合測試(gateway auth、routing、tooling、parsing、config) + - 已知 bug 的決定性回歸測試 +- 期望: - 在 CI 中執行 - - 不需要真實 key - - 應該快速且穩定 - - Resolver 和公開介面 loader 測試必須使用產生的小型 Plugin fixture 證明廣泛的 `api.js` 和 `runtime-api.js` fallback 行為,而不是使用真實內建 Plugin source API。真實 Plugin API 載入屬於 Plugin 擁有的 contract/integration 套件。 + - 不需要真實金鑰 + - 應快速且穩定 + - Resolver 與公開介面 loader 測試必須使用產生的小型 Plugin fixture 證明廣泛的 `api.js` 與 `runtime-api.js` fallback 行為,而不是使用真實內建 Plugin 原始碼 API。真實 Plugin API 載入應放在 Plugin 擁有的合約/整合套件中。 - + - - 未指定目標的 `pnpm test` 會執行十二個較小的分片設定(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是單一巨大的原生根專案程序。這會降低高負載機器上的尖峰 RSS,並避免 auto-reply/extension 工作讓不相關的測試套件挨餓。 - - `pnpm test --watch` 仍使用原生根 `vitest.config.ts` 專案圖,因為多分片的監看迴圈並不實際。 - - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 會先透過作用域車道處理明確的檔案/目錄目標,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可避免付出完整根專案啟動成本。 - - `pnpm test:changed` 預設會把變更的 git 路徑展開成便宜的作用域車道:直接測試編輯、同層 `*.test.ts` 檔案、明確來源對應,以及本機匯入圖相依項。除非你明確使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`,否則 config/setup/package 編輯不會廣泛執行測試。 - - `pnpm check:changed` 是窄範圍工作的標準智慧本機檢查閘門。它會將 diff 分類為 core、core tests、extensions、extension tests、apps、docs、release metadata、live Docker tooling 和 tooling,然後執行相符的 typecheck、lint 與 guard 指令。它不會執行 Vitest 測試;測試證明請呼叫 `pnpm test:changed` 或明確的 `pnpm test `。僅 release metadata 的版本升級會執行目標版本/config/root-dependency 檢查,並有 guard 拒絕頂層 version 欄位以外的 package 變更。 - - Live Docker ACP harness 編輯會執行聚焦檢查:live Docker auth scripts 的 shell 語法,以及 live Docker scheduler dry-run。只有當 diff 限於 `scripts["test:docker:live-*"]` 時,才會包含 `package.json` 變更;dependency、export、version 和其他 package-surface 編輯仍會使用較廣泛的 guard。 - - 來自 agents、commands、plugins、auto-reply helpers、`plugin-sdk` 和類似純工具區域的輕匯入單元測試會走 `unit-fast` 車道,該車道會略過 `test/setup-openclaw-runtime.ts`;有狀態/執行階段較重的檔案則留在現有車道。 - - 選定的 `plugin-sdk` 和 `commands` helper 原始檔也會把 changed-mode 執行對應到那些輕量車道中的明確同層測試,因此 helper 編輯可避免重新執行該目錄完整的重型套件。 - - `auto-reply` 有專用桶,分別處理頂層 core helpers、頂層 `reply.*` 整合測試,以及 `src/auto-reply/reply/**` 子樹。CI 會進一步把 reply 子樹拆成 agent-runner、dispatch 和 commands/state-routing 分片,因此單一匯入較重的桶不會擁有完整的 Node 尾端。 - - 一般 PR/main CI 會刻意略過 extension 批次掃描和僅 release 使用的 `agentic-plugins` 分片。Full Release Validation 會為 release candidates 派發獨立的 `Plugin Prerelease` 子工作流程,以涵蓋這些 plugin/extension-heavy 套件。 + - 非定向的 `pnpm test` 會執行十二個較小的分片設定(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是單一巨大的原生根專案程序。這會降低負載機器上的尖峰 RSS,並避免 auto-reply/extension 工作餓死不相關的套件。 + - `pnpm test --watch` 仍使用原生根 `vitest.config.ts` 專案圖,因為多分片監看迴圈並不實際。 + - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 會先透過作用域車道轉送明確的檔案/目錄目標,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可避免付出完整根專案啟動成本。 + - `pnpm test:changed` 預設會將變更的 git 路徑展開成低成本的作用域車道:直接測試編輯、同層 `*.test.ts` 檔案、明確來源對應,以及本機匯入圖相依項。Config/setup/package 編輯不會廣泛執行測試,除非你明確使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 + - `pnpm check:changed` 是窄範圍工作的正常智慧型本機檢查閘門。它會將 diff 分類為核心、核心測試、extensions、extension 測試、apps、docs、release metadata、live Docker tooling 和 tooling,然後執行相符的 typecheck、lint 和 guard 命令。它不會執行 Vitest 測試;若需要測試證明,請呼叫 `pnpm test:changed` 或明確的 `pnpm test `。僅 release metadata 的版本變更會執行定向的版本/config/root-dependency 檢查,並附帶一個 guard,用來拒絕頂層版本欄位以外的 package 變更。 + - Live Docker ACP harness 編輯會執行聚焦檢查:live Docker auth scripts 的 shell 語法,以及 live Docker scheduler dry-run。只有當 diff 限於 `scripts["test:docker:live-*"]` 時,才會包含 `package.json` 變更;dependency、export、version 和其他 package-surface 編輯仍使用較廣泛的 guard。 + - 來自 agents、commands、plugins、auto-reply helpers、`plugin-sdk` 和類似純 utility 區域的 import-light 單元測試,會透過 `unit-fast` 車道轉送,該車道會跳過 `test/setup-openclaw-runtime.ts`;stateful/runtime-heavy 檔案則維持在既有車道上。 + - 選定的 `plugin-sdk` 和 `commands` helper 原始檔,也會在 changed-mode 執行中對應到這些 light 車道中的明確同層測試,因此 helper 編輯可避免重新執行該目錄的完整 heavy suite。 + - `auto-reply` 有專用 bucket,分別涵蓋頂層核心 helpers、頂層 `reply.*` 整合測試,以及 `src/auto-reply/reply/**` 子樹。CI 進一步將 reply 子樹拆分為 agent-runner、dispatch 和 commands/state-routing 分片,避免由單一 import-heavy bucket 承擔完整 Node 尾端。 + - 一般 PR/main CI 會刻意跳過 extension 批次掃描與僅 release 使用的 `agentic-plugins` 分片。完整 Release Validation 會為 release candidates 分派獨立的 `Plugin Prerelease` 子工作流程,以執行那些 plugin/extension-heavy 套件。 - + - - 當你變更 message-tool 探索輸入或 Compaction 執行階段 + - 變更 message-tool discovery 輸入或 compaction runtime context 時,請保留兩個層級的覆蓋範圍。 - - 為純路由和正規化邊界新增聚焦的 helper 回歸測試。 - - 保持嵌入式執行器整合套件健康: + - 為純 routing 和 normalization + 邊界加入聚焦的 helper regression。 + - 保持嵌入式 runner 整合套件健康: `src/agents/pi-embedded-runner/compact.hooks.test.ts`、 `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` 和 `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`。 - - 這些套件會驗證作用域 id 和 Compaction 行為仍會流經真實的 - `run.ts` / `compact.ts` 路徑;只有 helper 的測試無法充分替代那些整合路徑。 + - 這些套件會驗證 scoped ids 和 compaction 行為仍透過真實的 + `run.ts` / `compact.ts` 路徑流動;僅 helper 的測試 + 不足以取代這些整合路徑。 - + - - 基礎 Vitest 設定預設為 `threads`。 - - 共用 Vitest 設定固定 `isolate: false`,並在根專案、e2e 和 live config 中使用 - 非隔離執行器。 - - 根 UI 車道保留其 `jsdom` 設定和 optimizer,但也在共用的非隔離執行器上執行。 - - 每個 `pnpm test` 分片都會從共用 Vitest 設定繼承相同的 `threads` + `isolate: false` + - 基礎 Vitest config 預設為 `threads`。 + - 共享 Vitest config 固定 `isolate: false`,並在根專案、e2e 和 live configs + 中使用非隔離 runner。 + - 根 UI 車道保留其 `jsdom` setup 和 optimizer,但也在 + 共享的非隔離 runner 上執行。 + - 每個 `pnpm test` 分片都會從共享 Vitest config 繼承相同的 `threads` + `isolate: false` 預設值。 - `scripts/run-vitest.mjs` 預設會為 Vitest 子 Node - 程序加入 `--no-maglev`,以降低大型本機執行期間的 V8 編譯擾動。 - 設定 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可與原生 V8 + 程序加入 `--no-maglev`,以降低大型本機執行期間的 V8 編譯抖動。 + 設定 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可與原版 V8 行為比較。 @@ -355,124 +400,125 @@ Telegram kind 的 payload 形狀: - `pnpm changed:lanes` 會顯示 diff 觸發哪些架構車道。 - - pre-commit hook 只處理格式化。它會重新暫存已格式化的檔案, + - pre-commit hook 僅做格式化。它會重新 stage 已格式化的檔案,且 不會執行 lint、typecheck 或測試。 - - 當你需要智慧本機檢查閘門時,請在 handoff 或 push 前明確執行 `pnpm check:changed`。 - - `pnpm test:changed` 預設會透過便宜的作用域車道處理。只有當 agent - 判斷 harness、config、package 或 contract 編輯確實需要更廣的 - Vitest 覆蓋範圍時,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 - - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由 + - 在 handoff 或 push 前需要智慧型本機檢查閘門時,請明確執行 `pnpm check:changed`。 + - `pnpm test:changed` 預設會透過低成本的作用域車道轉送。只有當 agent + 判定 harness、config、package 或 contract 編輯確實需要更廣的 + Vitest 覆蓋範圍時,才使用 + `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。 + - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的 routing 行為,只是 worker 上限較高。 - - 本機 worker 自動縮放刻意保守,並在主機負載平均值已經偏高時退讓, - 因此多個並行 Vitest 執行預設造成的影響較小。 - - 基礎 Vitest 設定會將 projects/config 檔案標記為 - `forceRerunTriggers`,因此測試 - wiring 變更時,changed-mode 重新執行仍保持正確。 - - 此設定會在支援的主機上保持 `OPENCLAW_VITEST_FS_MODULE_CACHE` 啟用; - 如果你想為直接 profiling 使用一個明確的快取位置,請設定 - `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 + - 本機 worker 自動擴縮刻意保守,並會在主機 load average 已經很高時退讓, + 因此多個並行 + Vitest 執行預設會造成較少損害。 + - 基礎 Vitest config 會將 projects/config files 標記為 + `forceRerunTriggers`,因此當 test + wiring 變更時,changed-mode 重新執行仍會保持正確。 + - config 會在支援的主機上保持啟用 `OPENCLAW_VITEST_FS_MODULE_CACHE`; + 若你想要一個用於直接 profiling 的明確 cache 位置,請設定 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 - - `pnpm test:perf:imports` 會啟用 Vitest 匯入耗時報告,以及 + - `pnpm test:perf:imports` 會啟用 Vitest import-duration reporting 加上 import-breakdown 輸出。 - - `pnpm test:perf:imports:changed` 會將相同的 profiling 視圖限制在 + - `pnpm test:perf:imports:changed` 會將相同的 profiling view 限定到 自 `origin/main` 以來變更的檔案。 - - 分片計時資料會寫入 `.artifacts/vitest-shard-timings.json`。 - 整個 config 執行會使用 config 路徑作為 key;include-pattern CI - 分片會附加分片名稱,讓過濾後的分片可被分開追蹤。 - - 當某個熱點測試仍把大部分時間花在啟動匯入時, - 請把重型相依項保留在狹窄的本機 `*.runtime.ts` 邊界後方,並直接 - mock 該邊界,而不是為了將 runtime helpers 傳入 `vi.mock(...)` - 而深度匯入它們。 - - `pnpm test:perf:changed:bench -- --ref ` 會針對該已提交 - diff,比較已路由的 `test:changed` 與原生根專案路徑,並列印 wall time - 以及 macOS max RSS。 + - 分片 timing data 會寫入 `.artifacts/vitest-shard-timings.json`。 + Whole-config 執行會使用 config path 作為 key;include-pattern CI + 分片會附加分片名稱,以便分別追蹤 filtered shards。 + - 當某個 hot test 仍然將大部分時間花在 startup imports 上時, + 請將 heavy dependencies 保留在窄範圍本機 `*.runtime.ts` seam 後方,並 + 直接 mock 該 seam,而不是 deep-importing runtime helpers 只是為了 + 將它們傳入 `vi.mock(...)`。 + - `pnpm test:perf:changed:bench -- --ref ` 會針對該 committed + diff,比較 routed + `test:changed` 與原生根專案路徑,並列印 wall time 加上 macOS max RSS。 - `pnpm test:perf:changed:bench -- --worktree` 會透過 - `scripts/test-projects.mjs` 和根 Vitest config 路由變更檔案清單, - 來對目前 dirty tree 做 benchmark。 + `scripts/test-projects.mjs` 和根 Vitest config 路由 changed file list, + 對目前的 dirty tree 進行 benchmark。 - `pnpm test:perf:profile:main` 會為 - Vitest/Vite 啟動和 transform 開銷寫入主執行緒 CPU profile。 - - `pnpm test:perf:profile:runner` 會在停用檔案平行化的情況下, - 為單元套件寫入 runner CPU+heap profile。 + Vitest/Vite startup 和 transform overhead 寫入 main-thread CPU profile。 + - `pnpm test:perf:profile:runner` 會在停用 file parallelism 的情況下,為 + unit suite 寫入 runner CPU+heap profiles。 ### 穩定性(gateway) -- 指令:`pnpm test:stability:gateway` -- 設定:`vitest.gateway.config.ts`,強制使用單一 worker +- 命令:`pnpm test:stability:gateway` +- Config:`vitest.gateway.config.ts`,強制使用一個 worker - 範圍: - - 預設啟用診斷,啟動真實的 loopback Gateway - - 透過診斷事件路徑驅動合成 gateway message、memory 和 large-payload churn + - 預設會啟動啟用 diagnostics 的真實 loopback Gateway + - 透過 diagnostic event path 驅動合成 gateway message、memory 和 large-payload churn - 透過 Gateway WS RPC 查詢 `diagnostics.stability` - - 覆蓋診斷穩定性 bundle persistence helpers - - 斷言 recorder 保持有界、合成 RSS samples 維持在壓力預算以下,且每個 session queue depth 都會排空回到零 -- 預期: - - CI-safe 且無需 key - - 用於 stability-regression 後續處理的窄車道,不是完整 Gateway 套件的替代品 + - 涵蓋 diagnostic stability bundle persistence helpers + - 斷言 recorder 保持有界、合成 RSS samples 維持在 pressure budget 之下,且每個 session queue depths 會排空回到零 +- 期望: + - CI-safe 且不需要 key + - 用於 stability-regression follow-up 的窄車道,而不是完整 Gateway 套件的替代品 ### E2E(gateway smoke) -- 指令:`pnpm test:e2e` -- 設定:`vitest.e2e.config.ts` -- 檔案:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的 bundled-plugin E2E tests -- 執行階段預設值: +- 命令:`pnpm test:e2e` +- Config:`vitest.e2e.config.ts` +- 檔案:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的 bundled-plugin E2E 測試 +- Runtime 預設值: - 使用 Vitest `threads` 搭配 `isolate: false`,與 repo 其餘部分一致。 - - 使用自適應 workers(CI:最多 2,本機:預設 1)。 - - 預設以 silent mode 執行,以降低 console I/O 開銷。 -- 實用覆寫: - - `OPENCLAW_E2E_WORKERS=` 可強制 worker 數量(上限 16)。 - - `OPENCLAW_E2E_VERBOSE=1` 可重新啟用詳細 console 輸出。 + - 使用 adaptive workers(CI:最多 2,本機:預設 1)。 + - 預設在 silent mode 執行,以降低 console I/O overhead。 +- 實用 overrides: + - `OPENCLAW_E2E_WORKERS=` 用來強制 worker 數量(上限為 16)。 + - `OPENCLAW_E2E_VERBOSE=1` 用來重新啟用 verbose console output。 - 範圍: - - 多實例 gateway 端到端行為 + - 多 instance gateway end-to-end 行為 - WebSocket/HTTP surfaces、node pairing,以及較重的 networking -- 預期: +- 期望: - 在 CI 中執行(當 pipeline 啟用時) - 不需要真實 keys - 比單元測試有更多 moving parts(可能較慢) -### E2E:OpenShell 後端 smoke +### E2E:OpenShell backend smoke -- 指令:`pnpm test:e2e:openshell` +- 命令:`pnpm test:e2e:openshell` - 檔案:`extensions/openshell/src/backend.e2e.test.ts` - 範圍: - - 透過 Docker 在主機上啟動隔離的 OpenShell gateway - - 從臨時本機 Dockerfile 建立 sandbox - - 透過真實的 `sandbox ssh-config` + SSH exec 測試 OpenClaw 的 OpenShell 後端 - - 透過 sandbox fs bridge 驗證 remote-canonical 檔案系統行為 -- 預期: + - 透過 Docker 在 host 上啟動隔離的 OpenShell gateway + - 從暫時本機 Dockerfile 建立 sandbox + - 透過真實 `sandbox ssh-config` + SSH exec 測試 OpenClaw 的 OpenShell backend + - 透過 sandbox fs bridge 驗證 remote-canonical filesystem 行為 +- 期望: - 僅 opt-in;不屬於預設 `pnpm test:e2e` 執行的一部分 - - 需要本機 `openshell` CLI 以及可運作的 Docker daemon + - 需要本機 `openshell` CLI 加上可運作的 Docker daemon - 使用隔離的 `HOME` / `XDG_CONFIG_HOME`,然後銷毀測試 gateway 和 sandbox -- 實用覆寫: - - `OPENCLAW_E2E_OPENSHELL=1` 可在手動執行較廣 e2e 套件時啟用測試 - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` 可指向非預設 CLI binary 或 wrapper script +- 實用 overrides: + - `OPENCLAW_E2E_OPENSHELL=1` 用於手動執行較廣 e2e 套件時啟用該測試 + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` 用來指向非預設 CLI binary 或 wrapper script ### Live(真實 providers + 真實 models) -- 指令:`pnpm test:live` -- 設定:`vitest.live.config.ts` +- 命令:`pnpm test:live` +- Config:`vitest.live.config.ts` - 檔案:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的 bundled-plugin live tests -- 預設值:由 `pnpm test:live` **啟用**(設定 `OPENCLAW_LIVE_TEST=1`) +- 預設:由 `pnpm test:live` **啟用**(設定 `OPENCLAW_LIVE_TEST=1`) - 範圍: - - 「這個 provider/model 在 _今天_ 使用真實 credentials 是否真的可運作?」 - - 捕捉 provider format changes、tool-calling quirks、auth issues,以及 rate limit behavior -- 預期: - - 按設計並非 CI-stable(真實網路、真實 provider policies、quotas、outages) + - 「這個 provider/model _今天_ 是否真的能搭配真實 creds 運作?」 + - 捕捉 provider format changes、tool-calling quirks、auth issues 和 rate limit 行為 +- 期望: + - 設計上不是 CI-stable(真實網路、真實 provider policies、quotas、outages) - 會花錢 / 使用 rate limits - - 偏好執行較窄的子集,而不是「全部」 -- Live 執行會 source `~/.profile` 以取得缺少的 API keys。 -- 預設情況下,live 執行仍會隔離 `HOME`,並把 config/auth material 複製到暫時測試 home,因此單元 fixtures 無法改動你真實的 `~/.openclaw`。 -- 只有當你刻意需要 live tests 使用真實 home directory 時,才設定 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 -- `pnpm test:live` 現在預設使用較安靜的模式:它保留 `[live] ...` progress output,但會抑制額外的 `~/.profile` notice,並靜音 gateway bootstrap logs/Bonjour chatter。若你想取回完整 startup logs,請設定 `OPENCLAW_LIVE_TEST_QUIET=0`。 -- API key rotation(provider-specific):以逗號/分號格式設定 `*_API_KEYS`,或設定 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),或透過 `OPENCLAW_LIVE_*_KEY` 做 per-live override;測試會在 rate limit responses 時重試。 -- Progress/heartbeat 輸出: - - Live 套件現在會把 progress lines 發到 stderr,因此即使 Vitest console capture 很安靜,長時間 provider calls 也會可見地保持 active。 - - `vitest.live.config.ts` 會停用 Vitest console interception,因此 provider/gateway progress lines 會在 live 執行期間立即串流。 + - 偏好執行縮小範圍的子集,而不是「everything」 +- Live runs 會 source `~/.profile` 以取得缺少的 API keys。 +- 預設情況下,live runs 仍會隔離 `HOME`,並將 config/auth material 複製到暫時 test home,因此 unit fixtures 無法改動你真實的 `~/.openclaw`。 +- 只有在你刻意需要 live tests 使用真實 home directory 時,才設定 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 +- `pnpm test:live` 現在預設採用較安靜的模式:它保留 `[live] ...` progress output,但會抑制額外的 `~/.profile` notice,並靜音 gateway bootstrap logs/Bonjour chatter。若想恢復完整 startup logs,請設定 `OPENCLAW_LIVE_TEST_QUIET=0`。 +- API key rotation(provider-specific):使用逗號/分號格式設定 `*_API_KEYS`,或設定 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),或透過 `OPENCLAW_LIVE_*_KEY` 做 per-live override;測試會在 rate limit responses 時重試。 +- Progress/heartbeat output: + - Live suites 現在會將 progress lines 發送到 stderr,因此即使 Vitest console capture 安靜,長時間 provider calls 仍可看出處於 active 狀態。 + - `vitest.live.config.ts` 會停用 Vitest console interception,因此 provider/gateway progress lines 會在 live runs 期間立即串流。 - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 調整 direct-model heartbeats。 - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 調整 gateway/probe heartbeats。 @@ -480,65 +526,66 @@ Telegram kind 的 payload 形狀: 使用此決策表: -- 編輯邏輯/測試:執行 `pnpm test`(如果你變更了很多內容,也執行 `pnpm test:coverage`) -- 觸及 gateway 網路 / WS 通訊協定 / 配對:加上 `pnpm test:e2e` -- 偵錯「我的 bot 掛了」/ 供應商特定失敗 / 工具呼叫:執行範圍縮小的 `pnpm test:live` +- 編輯邏輯/測試:執行 `pnpm test`(如果你改了很多,也執行 `pnpm test:coverage`) +- 觸及 Gateway 網路 / WS 協定 / 配對:加入 `pnpm test:e2e` +- 偵錯「我的 bot 掛了」/ 供應商特定失敗 / 工具呼叫:執行縮小範圍的 `pnpm test:live` -## 即時(觸及網路)測試 +## Live(會觸及網路)測試 -如需即時模型矩陣、CLI 後端冒煙測試、ACP 冒煙測試、Codex app-server -測試框架,以及所有媒體供應商即時測試(Deepgram、BytePlus、ComfyUI、影像、 -音樂、影片、媒體測試框架)— 以及即時執行的憑證處理 — 請參閱 -[測試 — 即時套件](/zh-TW/help/testing-live)。 +如需 live 模型矩陣、CLI 後端 smoke、ACP smoke、Codex app-server +harness,以及所有媒體供應商 live 測試(Deepgram、BytePlus、ComfyUI、影像、 +音樂、影片、媒體 harness),再加上 live 執行的認證處理,請參閱 +[測試 - live 套件](/zh-TW/help/testing-live)。 -## Docker 執行器(選用的「可在 Linux 運作」檢查) +## Docker 執行器(可選的「可在 Linux 運作」檢查) 這些 Docker 執行器分成兩類: -- 即時模型執行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只會在 repo Docker 映像中執行其對應 profile-key 的即時檔案(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),掛載你的本機設定目錄與工作區(若有掛載,並會載入 `~/.profile`)。對應的本機進入點是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 -- Docker 即時執行器預設使用較小的冒煙上限,讓完整 Docker 掃描維持可行: +- Live 模型執行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只會在 repo Docker 映像中執行各自相符的 profile-key live 檔案(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),並掛載你的本機設定目錄與工作區(如果有掛載,也會 source `~/.profile`)。相符的本機進入點是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 +- Docker live 執行器預設使用較小的 smoke 上限,讓完整 Docker 掃描保持可行: `test:docker:live-models` 預設為 `OPENCLAW_LIVE_MAX_MODELS=12`,而 `test:docker:live-gateway` 預設為 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`、 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`、 `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000`,以及 - `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。只有在你明確想要更大的完整掃描時, + `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。只有在你明確想要較大的完整掃描時, 才覆寫這些 env vars。 -- `test:docker:all` 會先透過 `test:docker:live-build` 建置即時 Docker 映像一次,透過 `scripts/package-openclaw-for-docker.mjs` 將 OpenClaw 封裝成 npm tarball 一次,接著建置/重用兩個 `scripts/e2e/Dockerfile` 映像。裸映像只是用於安裝/更新/Plugin 相依性 lane 的 Node/Git 執行器;這些 lane 會掛載預先建置的 tarball。功能映像會將同一個 tarball 安裝到 `/app`,供已建置 app 的功能 lane 使用。Docker lane 定義位於 `scripts/lib/docker-e2e-scenarios.mjs`;規劃器邏輯位於 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 會執行選定的計畫。彙總流程使用加權本機排程器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制程序 slot,而資源上限會避免繁重的即時、npm-install 和多服務 lane 同時全部啟動。如果單一 lane 比目前上限更重,排程器仍可在 pool 為空時啟動它,並讓它單獨執行到容量再次可用。預設為 10 個 slot、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10`,以及 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有在 Docker 主機有更多餘裕時,才調整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。執行器預設會執行 Docker 前置檢查、移除過期的 OpenClaw E2E 容器、每 30 秒列印狀態、將成功 lane 的耗時儲存在 `.artifacts/docker-tests/lane-timings.json`,並在後續執行時使用這些耗時先啟動較長的 lane。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可列印加權 lane manifest,而不建置或執行 Docker;或使用 `node scripts/test-docker-all.mjs --plan-json` 列印選定 lane、套件/映像需求與憑證的 CI 計畫。 -- `Package Acceptance` 是 GitHub 原生的套件閘門,用來驗證「這個可安裝的 tarball 是否能作為產品運作?」它會從 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 解析一個候選套件,將它上傳為 `package-under-test`,然後對該精確 tarball 執行可重用的 Docker E2E lane,而不是重新封裝選定的 ref。`workflow_ref` 會選擇受信任的 workflow/測試框架 scripts,而 `package_ref` 會在 `source=ref` 時選擇要封裝的來源 commit/branch/tag;這讓目前的驗收邏輯能驗證較舊的受信任 commit。Profile 依涵蓋廣度排序:`smoke` 是快速安裝/channel/agent 加上 gateway/config,`package` 是套件/更新/Plugin 合約加上 keyless upgrade-survivor fixture,並且是大多數 Parallels 套件/更新涵蓋範圍的預設原生替代項,`product` 會加入 MCP channels、cron/subagent 清理、OpenAI web search 和 OpenWebUI,而 `full` 會以 OpenWebUI 執行 release-path Docker 區塊。發布驗證會執行自訂套件差異(`bundled-channel-deps-compat plugins-offline`)加上 Telegram 套件 QA,因為 release-path Docker 區塊已涵蓋重疊的套件/更新/Plugin lane。從 artifact 產生的目標 GitHub Docker 重新執行命令,會在可用時包含先前的套件 artifact 和已準備的映像輸入,因此失敗的 lane 可避免重建套件與映像。 -- 建置與發布檢查會在 tsdown 後執行 `scripts/check-cli-bootstrap-imports.mjs`。該防護會從 `dist/entry.js` 和 `dist/cli/run-main.js` 走訪靜態建置圖,並在命令分派前的啟動流程匯入 Commander、prompt UI、undici 或 logging 等套件相依性時失敗;它也會讓 bundled gateway run chunk 維持在預算內,並拒絕已知 cold gateway 路徑的靜態匯入。封裝後的 CLI 冒煙測試也涵蓋 root help、onboard help、doctor help、status、config schema,以及 model-list 命令。 -- Package Acceptance 舊版相容性上限為 `2026.4.25`(包含 `2026.4.25-beta.*`)。在該截止版本以前,測試框架只容許已出貨套件的中繼資料缺口:省略的私有 QA inventory 項目、缺少 `gateway install --wrapper`、tarball 衍生 git fixture 中缺少 patch 檔、缺少持久化的 `update.channel`、舊版 Plugin install-record 位置、缺少 marketplace install-record 持久化,以及 `plugins update` 期間的 config metadata 遷移。對 `2026.4.25` 之後的套件,這些路徑都是嚴格失敗。 -- 容器冒煙執行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:upgrade-survivor`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 會啟動一個或多個真實容器,並驗證較高層級的整合路徑。 +- `test:docker:all` 會先透過 `test:docker:live-build` 建置 live Docker 映像一次,透過 `scripts/package-openclaw-for-docker.mjs` 將 OpenClaw 打包一次成 npm tarball,然後建置/重用兩個 `scripts/e2e/Dockerfile` 映像。bare 映像只是 install/update/plugin-dependency lanes 的 Node/Git 執行器;這些 lanes 會掛載預先建置的 tarball。functional 映像會將同一個 tarball 安裝到 `/app`,用於 built-app 功能 lanes。Docker lane 定義位於 `scripts/lib/docker-e2e-scenarios.mjs`;規劃器邏輯位於 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 會執行選定的計畫。彙總程序使用加權本機排程器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制程序 slots,而資源上限會避免 heavy live、npm-install 和 multi-service lanes 全部同時啟動。如果單一 lane 比作用中的上限更重,排程器仍可在 pool 為空時啟動它,然後讓它單獨執行,直到容量再次可用。預設為 10 個 slots、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10`,以及 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有在 Docker 主機有更多餘裕時,才調整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。執行器預設會執行 Docker preflight、移除過期的 OpenClaw E2E containers、每 30 秒列印狀態、將成功 lane 的時間記錄儲存在 `.artifacts/docker-tests/lane-timings.json`,並在之後執行時使用這些時間記錄優先啟動較長的 lanes。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可在不建置或執行 Docker 的情況下列印加權 lane manifest,或使用 `node scripts/test-docker-all.mjs --plan-json` 列印所選 lanes、package/image needs,以及 credentials 的 CI 計畫。 +- `Package Acceptance` 是 GitHub 原生的 package gate,用來回答「這個可安裝 tarball 是否能作為產品運作?」它會從 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 解析一個候選 package,將其上傳為 `package-under-test`,然後針對該精確 tarball 執行可重用的 Docker E2E lanes,而不是重新打包選定的 ref。`workflow_ref` 選擇受信任的 workflow/harness scripts,而 `package_ref` 則在 `source=ref` 時選擇要打包的來源 commit/branch/tag;這讓目前的 acceptance 邏輯可以驗證較舊的受信任 commits。Profiles 依涵蓋廣度排序:`smoke` 是快速 install/channel/agent 加上 gateway/config,`package` 是 package/update/plugin contract 加上 keyless upgrade-survivor fixture、published-baseline upgrade survivor lane,以及大多數 Parallels package/update 覆蓋範圍的預設 native 替代項,`product` 加入 MCP channels、cron/subagent cleanup、OpenAI web search 和 OpenWebUI,而 `full` 會執行含 OpenWebUI 的 release-path Docker chunks。Release 驗證會執行自訂 package delta(`bundled-channel-deps-compat plugins-offline`)加上 Telegram package QA,因為 release-path Docker chunks 已涵蓋重疊的 package/update/plugin lanes。從 artifacts 產生的目標式 GitHub Docker 重新執行命令,在可用時會包含先前的 package artifact 和已準備好的 image inputs,因此失敗的 lanes 可以避免重新建置 package 和 images。 +- Build 和 release 檢查會在 tsdown 之後執行 `scripts/check-cli-bootstrap-imports.mjs`。該 guard 會從 `dist/entry.js` 和 `dist/cli/run-main.js` 走訪靜態建置 graph,若 pre-dispatch startup 在命令 dispatch 前匯入 Commander、prompt UI、undici 或 logging 等 package dependencies,就會失敗;它也會讓 bundled gateway run chunk 保持在預算內,並拒絕已知 cold gateway paths 的靜態匯入。Packaged CLI smoke 也涵蓋 root help、onboard help、doctor help、status、config schema,以及 model-list command。 +- Package Acceptance legacy compatibility 上限為 `2026.4.25`(包含 `2026.4.25-beta.*`)。在該截止點以前,harness 只容忍已發布 package 的 metadata gaps:省略的 private QA inventory entries、缺少 `gateway install --wrapper`、tarball-derived git fixture 中缺少 patch files、缺少持久化的 `update.channel`、舊版 plugin install-record 位置、缺少 marketplace install-record persistence,以及 `plugins update` 期間的 config metadata migration。對於 `2026.4.25` 之後的 packages,這些路徑都是嚴格失敗。 +- Container smoke 執行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:upgrade-survivor`、`test:docker:published-upgrade-survivor`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update`,以及 `test:docker:config-reload` 會啟動一個或多個真實 containers,並驗證較高層級的 integration paths。 -即時模型 Docker 執行器也只會 bind-mount 所需的 CLI auth home(或在執行未縮小範圍時掛載所有支援項目),然後在執行前將它們複製到容器 home,讓外部 CLI OAuth 能重新整理權杖,而不會變更主機 auth store: +live 模型 Docker 執行器也只會 bind-mount 所需的 CLI auth homes(或在執行未縮小範圍時掛載所有支援的 homes),接著在執行前將它們複製到 container home,讓 external-CLI OAuth 可以 refresh tokens,而不會修改 host auth store: - 直接模型:`pnpm test:docker:live-models`(指令碼:`scripts/test-live-models-docker.sh`) -- ACP 綁定煙霧測試:`pnpm test:docker:live-acp-bind`(指令碼:`scripts/test-live-acp-bind-docker.sh`;預設涵蓋 Claude、Codex 和 Gemini,並透過 `pnpm test:docker:live-acp-bind:droid` 與 `pnpm test:docker:live-acp-bind:opencode` 嚴格涵蓋 Droid/OpenCode) -- CLI 後端煙霧測試:`pnpm test:docker:live-cli-backend`(指令碼:`scripts/test-live-cli-backend-docker.sh`) -- Codex 應用程式伺服器測試架煙霧測試:`pnpm test:docker:live-codex-harness`(指令碼:`scripts/test-live-codex-harness-docker.sh`) -- Gateway + 開發代理:`pnpm test:docker:live-gateway`(指令碼:`scripts/test-live-gateway-models-docker.sh`) -- 可觀測性煙霧測試:`pnpm qa:otel:smoke` 是私有 QA 原始碼簽出通道。它刻意不屬於套件 Docker 發布通道,因為 npm tarball 省略了 QA Lab。 -- Open WebUI 即時煙霧測試:`pnpm test:docker:openwebui`(指令碼:`scripts/e2e/openwebui-docker.sh`) +- ACP 綁定冒煙測試:`pnpm test:docker:live-acp-bind`(指令碼:`scripts/test-live-acp-bind-docker.sh`;預設涵蓋 Claude、Codex 與 Gemini,並透過 `pnpm test:docker:live-acp-bind:droid` 和 `pnpm test:docker:live-acp-bind:opencode` 提供嚴格的 Droid/OpenCode 覆蓋) +- CLI 後端冒煙測試:`pnpm test:docker:live-cli-backend`(指令碼:`scripts/test-live-cli-backend-docker.sh`) +- Codex app-server harness 冒煙測試:`pnpm test:docker:live-codex-harness`(指令碼:`scripts/test-live-codex-harness-docker.sh`) +- Gateway + dev agent:`pnpm test:docker:live-gateway`(指令碼:`scripts/test-live-gateway-models-docker.sh`) +- 可觀測性冒煙測試:`pnpm qa:otel:smoke` 是私有 QA 原始碼簽出檢查通道。它刻意不屬於套件 Docker 發行通道,因為 npm tarball 會省略 QA Lab。 +- Open WebUI 即時冒煙測試:`pnpm test:docker:openwebui`(指令碼:`scripts/e2e/openwebui-docker.sh`) - 入門精靈(TTY,完整鷹架):`pnpm test:docker:onboard`(指令碼:`scripts/e2e/onboard-docker.sh`) -- Npm tarball 入門/頻道/代理煙霧測試:`pnpm test:docker:npm-onboard-channel-agent` 會在 Docker 中全域安裝已封裝的 OpenClaw tarball,透過 env-ref 入門流程設定 OpenAI,並預設設定 Telegram,驗證 doctor 修復已啟用的 Plugin 執行階段依賴項,並執行一次模擬的 OpenAI 代理回合。使用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 重用預先建置的 tarball,使用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳過主機重建,或使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切換頻道。 -- 更新頻道切換煙霧測試:`pnpm test:docker:update-channel-switch` 會在 Docker 中全域安裝已封裝的 OpenClaw tarball,從套件 `stable` 切換到 git `dev`,驗證持久化頻道與 Plugin 更新後工作正常,然後切回套件 `stable` 並檢查更新狀態。 -- 升級存活煙霧測試:`pnpm test:docker:upgrade-survivor` 會將已封裝的 OpenClaw tarball 安裝到髒污的舊使用者 fixture 上,其中包含代理、頻道設定、Plugin 允許清單、過時的 Plugin 執行階段依賴狀態,以及既有工作區/工作階段檔案。它會在沒有即時提供者或頻道金鑰的情況下執行套件更新與非互動式 doctor,然後啟動一個 loopback Gateway,並檢查設定/狀態保留以及啟動/狀態預算。 -- 工作階段執行階段內容煙霧測試:`pnpm test:docker:session-runtime-context` 會驗證隱藏執行階段內容逐字稿持久化,以及 doctor 對受影響的重複提示重寫分支的修復。 -- Bun 全域安裝煙霧測試:`bash scripts/e2e/bun-global-install-smoke.sh` 會封裝目前樹狀內容,在隔離的 home 中使用 `bun install -g` 安裝,並驗證 `openclaw infer image providers --json` 回傳內建影像提供者,而不是卡住。使用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 重用預先建置的 tarball,使用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳過主機建置,或使用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 從已建置的 Docker 映像複製 `dist/`。 -- 安裝器 Docker 煙霧測試:`bash scripts/test-install-sh-docker.sh` 會在其 root、update 和 direct-npm 容器之間共用一個 npm 快取。更新煙霧測試預設使用 npm `latest` 作為穩定基準,再升級到候選 tarball。在本機使用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆寫,或在 GitHub 上使用 Install Smoke 工作流程的 `update_baseline_version` 輸入覆寫。非 root 安裝器檢查會保留隔離的 npm 快取,因此 root 擁有的快取項目不會掩蓋使用者本機安裝行為。設定 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache`,以便在本機重跑時重用 root/update/direct-npm 快取。 -- Install Smoke CI 會使用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳過重複的 direct-npm 全域更新;需要直接 `npm install -g` 涵蓋時,請在本機不帶該 env 執行指令碼。 -- 代理刪除共用工作區 CLI 煙霧測試:`pnpm test:docker:agents-delete-shared-workspace`(指令碼:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)預設會建置根 Dockerfile 映像,在隔離的容器 home 中植入兩個代理與一個工作區,執行 `agents delete --json`,並驗證有效 JSON 與保留工作區行為。使用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 重用 install-smoke 映像。 -- Gateway 網路(兩個容器,WS 驗證 + 健康狀態):`pnpm test:docker:gateway-network`(指令碼:`scripts/e2e/gateway-network-docker.sh`) -- 瀏覽器 CDP 快照煙霧測試:`pnpm test:docker:browser-cdp-snapshot`(指令碼:`scripts/e2e/browser-cdp-snapshot-docker.sh`)會建置原始碼 E2E 映像加上一層 Chromium,使用原始 CDP 啟動 Chromium,執行 `browser doctor --deep`,並驗證 CDP 角色快照涵蓋連結 URL、游標提升的可點擊項目、iframe 參照與框架中繼資料。 -- OpenAI Responses `web_search` 最小推理迴歸:`pnpm test:docker:openai-web-search-minimal`(指令碼:`scripts/e2e/openai-web-search-minimal-docker.sh`)會透過 Gateway 執行模擬的 OpenAI 伺服器,驗證 `web_search` 將 `reasoning.effort` 從 `minimal` 提升到 `low`,然後強制提供者結構描述拒絕,並檢查原始詳細資訊出現在 Gateway 記錄中。 -- MCP 頻道橋接(已植入的 Gateway + stdio 橋接 + 原始 Claude 通知框架煙霧測試):`pnpm test:docker:mcp-channels`(指令碼:`scripts/e2e/mcp-channels-docker.sh`) -- Pi bundle MCP 工具(真實 stdio MCP 伺服器 + 內嵌 Pi 設定檔允許/拒絕煙霧測試):`pnpm test:docker:pi-bundle-mcp-tools`(指令碼:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`) -- Cron/子代理 MCP 清理(真實 Gateway + 在隔離 Cron 與一次性子代理執行後拆除 stdio MCP 子程序):`pnpm test:docker:cron-mcp-cleanup`(指令碼:`scripts/e2e/cron-mcp-cleanup-docker.sh`) -- Plugin(安裝煙霧測試、ClawHub kitchen-sink 安裝/解除安裝、市集更新,以及 Claude-bundle 啟用/檢查):`pnpm test:docker:plugins`(指令碼:`scripts/e2e/plugins-docker.sh`) - 設定 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳過 ClawHub 區塊,或使用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` 和 `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆寫預設的 kitchen-sink 套件/執行階段組合。若沒有 `OPENCLAW_CLAWHUB_URL`/`CLAWHUB_URL`,測試會使用 hermetic 本機 ClawHub fixture 伺服器。 -- Plugin 更新未變更煙霧測試:`pnpm test:docker:plugin-update`(指令碼:`scripts/e2e/plugin-update-unchanged-docker.sh`) -- 設定重新載入中繼資料煙霧測試:`pnpm test:docker:config-reload`(指令碼:`scripts/e2e/config-reload-source-docker.sh`) -- 內建 Plugin 執行階段依賴項:`pnpm test:docker:bundled-channel-deps` 預設會建置一個小型 Docker 執行器映像,在主機上建置並封裝 OpenClaw 一次,然後將該 tarball 掛載到每個 Linux 安裝情境中。使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 重用映像,在本機新建置後使用 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳過主機重建,或使用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向既有 tarball。完整 Docker 彙總與發布路徑 bundled-channel 區塊會先預先封裝此 tarball 一次,然後將內建頻道檢查分片到獨立通道,包括 Telegram、Discord、Slack、Feishu、memory-lancedb 和 ACPX 的個別更新通道。發布區塊會將頻道煙霧測試、更新目標以及設定/執行階段合約拆分為 `bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-b` 和 `bundled-channels-contracts`;彙總 `bundled-channels` 區塊仍可供手動重跑使用。發布工作流程也會拆分提供者安裝器區塊,以及內建 Plugin 安裝/解除安裝區塊;舊版 `package-update`、`plugins-runtime` 和 `plugins-integrations` 區塊仍保留作為手動重跑的彙總別名。直接執行 bundled 通道時,使用 `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` 縮小頻道矩陣,或使用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` 縮小更新情境。每個情境的 Docker 執行預設為 `OPENCLAW_BUNDLED_CHANNEL_DOCKER_RUN_TIMEOUT=900s`;多目標更新情境預設為 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_DOCKER_RUN_TIMEOUT=2400s`。該通道也會驗證 `channels..enabled=false` 和 `plugins.entries..enabled=false` 會抑制 doctor/執行階段依賴修復。 -- 反覆調整時,可透過停用無關情境來縮小內建 Plugin 執行階段依賴項,例如: +- Npm tarball 入門/通道/agent 冒煙測試:`pnpm test:docker:npm-onboard-channel-agent` 會在 Docker 中全域安裝已封裝的 OpenClaw tarball,透過 env-ref 入門流程設定 OpenAI,預設再設定 Telegram,驗證 doctor 修復已啟用的 Plugin 執行階段相依套件,並執行一次模擬的 OpenAI agent 回合。使用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 重用預先建置的 tarball、用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳過主機重建,或用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切換通道。 +- 更新通道切換冒煙測試:`pnpm test:docker:update-channel-switch` 會在 Docker 中全域安裝已封裝的 OpenClaw tarball,從套件 `stable` 切換到 git `dev`,驗證持久化的通道與 Plugin 更新後運作正常,接著切回套件 `stable` 並檢查更新狀態。 +- 升級存活者冒煙測試:`pnpm test:docker:upgrade-survivor` 會把已封裝的 OpenClaw tarball 安裝到一個髒的舊使用者 fixture 上,該 fixture 含有 agents、通道設定、Plugin allowlist、過期的 Plugin runtime-deps 狀態,以及既有工作區/工作階段檔案。它會執行套件更新與非互動式 doctor,不使用即時提供者或通道金鑰,接著啟動 loopback Gateway,並檢查設定/狀態保留與啟動/狀態預算。 +- 已發布升級存活者冒煙測試:`pnpm test:docker:published-upgrade-survivor` 預設會把 `openclaw@latest` 安裝到同一個髒的舊使用者 fixture 上,將該已發布安裝更新為候選 tarball,執行非互動式 doctor,接著啟動 loopback Gateway,並檢查相同的設定/狀態保留與啟動/狀態預算。用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆寫基準版本。 +- 工作階段執行階段上下文冒煙測試:`pnpm test:docker:session-runtime-context` 會驗證隱藏執行階段上下文逐字稿持久化,以及 doctor 對受影響的重複 prompt-rewrite 分支的修復。 +- Bun 全域安裝冒煙測試:`bash scripts/e2e/bun-global-install-smoke.sh` 會封裝目前樹狀內容,在隔離的 home 中用 `bun install -g` 安裝,並驗證 `openclaw infer image providers --json` 會回傳內建圖片提供者,而不是卡住。使用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 重用預先建置的 tarball、用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳過主機建置,或用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 從已建置的 Docker 映像複製 `dist/`。 +- Installer Docker 冒煙測試:`bash scripts/test-install-sh-docker.sh` 會在其 root、update 與 direct-npm 容器之間共用同一個 npm 快取。更新冒煙測試預設使用 npm `latest` 作為穩定基準,再升級到候選 tarball。可在本機用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆寫,或在 GitHub 上用 Install Smoke 工作流程的 `update_baseline_version` 輸入覆寫。非 root 安裝程式檢查會保留隔離的 npm 快取,避免 root 擁有的快取項目遮蔽使用者本機安裝行為。設定 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache`,即可在本機重新執行時重用 root/update/direct-npm 快取。 +- Install Smoke CI 會用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳過重複的 direct-npm 全域更新;需要直接 `npm install -g` 覆蓋時,請在本機不帶該 env 執行指令碼。 +- Agents 刪除共用工作區 CLI 冒煙測試:`pnpm test:docker:agents-delete-shared-workspace`(指令碼:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)預設會建置 root Dockerfile 映像,在隔離的容器 home 中植入兩個 agents 與一個工作區,執行 `agents delete --json`,並驗證有效 JSON 與保留工作區行為。用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 重用 install-smoke 映像。 +- Gateway 網路(兩個容器,WS 驗證 + 健康檢查):`pnpm test:docker:gateway-network`(指令碼:`scripts/e2e/gateway-network-docker.sh`) +- 瀏覽器 CDP 快照冒煙測試:`pnpm test:docker:browser-cdp-snapshot`(指令碼:`scripts/e2e/browser-cdp-snapshot-docker.sh`)會建置原始碼 E2E 映像加上一層 Chromium,使用原始 CDP 啟動 Chromium,執行 `browser doctor --deep`,並驗證 CDP 角色快照涵蓋連結 URL、游標提升的可點擊項目、iframe refs 與 frame metadata。 +- OpenAI Responses web_search 最小 reasoning 迴歸:`pnpm test:docker:openai-web-search-minimal`(指令碼:`scripts/e2e/openai-web-search-minimal-docker.sh`)會透過 Gateway 執行模擬的 OpenAI 伺服器,驗證 `web_search` 會把 `reasoning.effort` 從 `minimal` 提升到 `low`,接著強制提供者 schema 拒絕,並檢查原始詳細資訊會出現在 Gateway 記錄中。 +- MCP 通道橋接(已植入的 Gateway + stdio bridge + 原始 Claude notification-frame 冒煙測試):`pnpm test:docker:mcp-channels`(指令碼:`scripts/e2e/mcp-channels-docker.sh`) +- Pi bundle MCP 工具(真實 stdio MCP 伺服器 + 內嵌 Pi profile allow/deny 冒煙測試):`pnpm test:docker:pi-bundle-mcp-tools`(指令碼:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`) +- Cron/subagent MCP 清理(真實 Gateway + 在隔離 cron 與 one-shot subagent 執行後拆除 stdio MCP 子程序):`pnpm test:docker:cron-mcp-cleanup`(指令碼:`scripts/e2e/cron-mcp-cleanup-docker.sh`) +- Plugins(安裝冒煙測試、ClawHub kitchen-sink 安裝/解除安裝、市集更新,以及 Claude-bundle 啟用/檢查):`pnpm test:docker:plugins`(指令碼:`scripts/e2e/plugins-docker.sh`) + 設定 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳過 ClawHub 區塊,或用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` 和 `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆寫預設 kitchen-sink package/runtime 組合。若沒有 `OPENCLAW_CLAWHUB_URL`/`CLAWHUB_URL`,測試會使用密封的本機 ClawHub fixture 伺服器。 +- Plugin 更新未變更冒煙測試:`pnpm test:docker:plugin-update`(指令碼:`scripts/e2e/plugin-update-unchanged-docker.sh`) +- 設定重新載入 metadata 冒煙測試:`pnpm test:docker:config-reload`(指令碼:`scripts/e2e/config-reload-source-docker.sh`) +- 內建 Plugin 執行階段相依套件:`pnpm test:docker:bundled-channel-deps` 預設會建置一個小型 Docker runner 映像,並在主機上建置與封裝 OpenClaw 一次,接著把該 tarball 掛載到每個 Linux 安裝情境中。用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 重用映像、在新的本機建置後用 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳過主機重建,或用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向既有 tarball。完整 Docker 彙總與 release-path bundled-channel chunks 會先封裝此 tarball 一次,接著將內建通道檢查分片成獨立通道,包括 Telegram、Discord、Slack、Feishu、memory-lancedb 與 ACPX 的個別更新通道。發行 chunks 會把通道冒煙測試、更新目標與設定/執行階段合約拆成 `bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-b` 與 `bundled-channels-contracts`;彙總 `bundled-channels` chunk 仍可用於手動重新執行。發行工作流程也會拆分提供者安裝程式 chunks 與內建 Plugin 安裝/解除安裝 chunks;舊版 `package-update`、`plugins-runtime` 與 `plugins-integrations` chunks 仍保留為手動重新執行用的彙總別名。直接執行內建通道時,可用 `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` 縮小通道矩陣,或用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` 縮小更新情境。每個情境的 Docker 執行預設為 `OPENCLAW_BUNDLED_CHANNEL_DOCKER_RUN_TIMEOUT=900s`;多目標更新情境預設為 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_DOCKER_RUN_TIMEOUT=2400s`。此通道也會驗證 `channels..enabled=false` 和 `plugins.entries..enabled=false` 會抑制 doctor/runtime-dependency 修復。 +- 迭代時可透過停用無關情境,縮小內建 Plugin 執行階段相依套件範圍,例如: `OPENCLAW_BUNDLED_CHANNEL_SCENARIOS=0 OPENCLAW_BUNDLED_CHANNEL_UPDATE_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_ROOT_OWNED_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_SETUP_ENTRY_SCENARIO=0 pnpm test:docker:bundled-channel-deps`。 若要手動預先建置並重用共用功能映像: @@ -548,172 +595,174 @@ OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local pnpm test:docker: OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels ``` -設定後,套件專用的映像覆寫(例如 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE`)仍會優先。當 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向遠端共用映像時,如果本機尚未存在,指令碼會拉取它。QR 與安裝器 Docker 測試會保留自己的 Dockerfile,因為它們驗證的是套件/安裝行為,而不是共用已建置應用程式執行階段。 +設定 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 等特定套件的映像覆寫時,仍會優先生效。當 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向遠端共用映像時,若該映像尚未存在於本機,指令碼會拉取它。QR 與安裝程式 Docker 測試保留自己的 Dockerfiles,因為它們驗證的是套件/安裝行為,而不是共用的已建置 app 執行階段。 -即時模型 Docker 執行器也會以唯讀方式綁定掛載目前的 checkout,並 -將其暫存到容器內的暫存工作目錄。這可讓執行階段 -映像保持精簡,同時仍能針對你確切的本機原始碼/設定執行 Vitest。 -暫存步驟會略過大型的僅限本機快取和應用程式建置輸出,例如 -`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及應用程式本機的 `.build` 或 -Gradle 輸出目錄,因此 Docker 即時執行不會花費數分鐘複製 +即時模型 Docker 執行器也會以唯讀方式 bind-mount 目前的 checkout,並 +將其 stage 到容器內的臨時 workdir。這會讓 runtime +映像保持精簡,同時仍針對你確切的本機來源碼/config 執行 Vitest。 +staging 步驟會略過大型的僅本機快取與 app 建置輸出,例如 +`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及 app-local `.build` 或 +Gradle 輸出目錄,讓 Docker 即時執行不會花費數分鐘複製 特定機器的成品。 -它們也會設定 `OPENCLAW_SKIP_CHANNELS=1`,因此 Gateway 即時探測不會在 -容器內啟動真正的 Telegram/Discord/等頻道 worker。 -`test:docker:live-models` 仍會執行 `pnpm test:live`,因此在需要縮小或排除該 Docker lane 中的 Gateway -即時覆蓋範圍時,也要傳入 +它們也會設定 `OPENCLAW_SKIP_CHANNELS=1`,因此 gateway 即時探測不會在容器內啟動 +實際的 Telegram/Discord 等 channel worker。 +`test:docker:live-models` 仍會執行 `pnpm test:live`,因此當你需要從該 Docker lane +縮小或排除 gateway 即時覆蓋範圍時,也請傳入 `OPENCLAW_LIVE_GATEWAY_*`。 `test:docker:openwebui` 是較高層級的相容性 smoke:它會啟動一個 -啟用 OpenAI 相容 HTTP 端點的 OpenClaw Gateway 容器, -啟動一個針對該 Gateway 的固定版本 Open WebUI 容器,透過 -Open WebUI 登入,驗證 `/api/models` 暴露 `openclaw/default`,接著透過 Open WebUI 的 `/api/chat/completions` proxy 傳送一個 -真正的聊天請求。 -第一次執行可能會明顯較慢,因為 Docker 可能需要拉取 -Open WebUI 映像,而 Open WebUI 可能需要完成自己的冷啟動設定。 -這個 lane 需要可用的即時模型 key,而 `OPENCLAW_PROFILE_FILE` +已啟用 OpenAI 相容 HTTP endpoint 的 OpenClaw gateway 容器, +啟動一個 pinned Open WebUI 容器並連到該 Gateway,透過 +Open WebUI 登入,驗證 `/api/models` 會公開 `openclaw/default`,然後透過 +Open WebUI 的 `/api/chat/completions` proxy 傳送一個 +真實聊天請求。 +第一次執行可能明顯較慢,因為 Docker 可能需要拉取 +Open WebUI 映像,而 Open WebUI 也可能需要完成自己的冷啟動設定。 +此 lane 需要可用的即時模型 key,而 `OPENCLAW_PROFILE_FILE` (預設為 `~/.profile`)是在 Docker 化執行中提供它的主要方式。 -成功執行會列印一小段 JSON payload,例如 `{ "ok": true, "model": -"openclaw/default", ... }`。 -`test:docker:mcp-channels` 是刻意設計為確定性的,且不需要 -真正的 Telegram、Discord 或 iMessage 帳號。它會啟動一個已植入種子的 Gateway -容器,啟動第二個會產生 `openclaw mcp serve` 的容器,接著 -驗證路由後的對話探索、逐字稿讀取、附件中繼資料、 -即時事件佇列行為、對外傳送路由,以及透過真正 stdio MCP bridge 傳遞的 Claude 風格頻道 + -權限通知。通知檢查會直接檢查原始 stdio MCP frame,因此該 smoke 驗證的是 -bridge 實際發出的內容,而不只是特定 client SDK 恰好暴露的內容。 -`test:docker:pi-bundle-mcp-tools` 是確定性的,且不需要即時 -模型 key。它會建置 repo Docker 映像,在容器內啟動真正的 stdio MCP probe server, -透過內嵌 Pi bundle -MCP runtime 具現化該 server,執行 tool,接著驗證 `coding` 和 `messaging` 保留 -`bundle-mcp` tools,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 會將其篩除。 -`test:docker:cron-mcp-cleanup` 是確定性的,且不需要即時模型 -key。它會以真正的 stdio MCP probe server 啟動已植入種子的 Gateway,執行 -隔離的 cron turn 和 `/subagents spawn` 一次性 child turn,接著驗證 -MCP child process 在每次執行後都會退出。 +成功執行會列印類似 `{ "ok": true, "model": +"openclaw/default", ... }` 的小型 JSON payload。 +`test:docker:mcp-channels` 是刻意設計為 deterministic,且不需要 +真實的 Telegram、Discord 或 iMessage 帳號。它會啟動一個已 seeded 的 Gateway +容器,啟動第二個容器來 spawn `openclaw mcp serve`,然後 +驗證 routed conversation discovery、transcript reads、attachment metadata、 +live event queue behavior、outbound send routing,以及透過真實 stdio MCP bridge +傳遞的 Claude-style channel + permission notifications。notification check +會直接檢查原始 stdio MCP frames,因此該 smoke 驗證的是 +bridge 實際發出的內容,而不只是某個特定 client SDK 剛好 surfaced 的內容。 +`test:docker:pi-bundle-mcp-tools` 是 deterministic,且不需要即時 +模型 key。它會建置 repo Docker 映像,在容器內啟動真實的 stdio MCP probe server, +透過 embedded Pi bundle +MCP runtime materialize 該 server,執行 tool,然後驗證 `coding` 與 `messaging` 會保留 +`bundle-mcp` tools,而 `minimal` 與 `tools.deny: ["bundle-mcp"]` 會將它們過濾掉。 +`test:docker:cron-mcp-cleanup` 是 deterministic,且不需要即時模型 +key。它會啟動一個 seeded Gateway 與真實 stdio MCP probe server,執行 +隔離的 Cron turn 和 `/subagents spawn` one-shot child turn,然後驗證 +MCP child process 會在每次執行後退出。 -手動 ACP 白話 thread smoke(非 CI): +手動 ACP plain-language thread smoke(非 CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- 保留此 script 供迴歸/除錯工作流程使用。ACP thread 路由驗證未來可能再次需要它,因此不要刪除。 +- 保留此 script 供 regression/debug workflows 使用。ACP thread routing 驗證日後可能仍會再次需要它,因此請勿刪除。 -實用的 env vars: +實用 env vars: - `OPENCLAW_CONFIG_DIR=...`(預設:`~/.openclaw`)掛載到 `/home/node/.openclaw` - `OPENCLAW_WORKSPACE_DIR=...`(預設:`~/.openclaw/workspace`)掛載到 `/home/node/.openclaw/workspace` - `OPENCLAW_PROFILE_FILE=...`(預設:`~/.profile`)掛載到 `/home/node/.profile`,並在執行測試前 source -- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 僅驗證從 `OPENCLAW_PROFILE_FILE` source 的 env vars,使用暫存設定/工作區目錄,且不掛載外部 CLI auth +- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 僅驗證從 `OPENCLAW_PROFILE_FILE` source 的 env vars,使用臨時 config/workspace dirs,且不掛載外部 CLI auth - `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(預設:`~/.cache/openclaw/docker-cli-tools`)掛載到 `/home/node/.npm-global`,用於 Docker 內快取 CLI 安裝 -- `$HOME` 底下的外部 CLI auth 目錄/檔案會以唯讀方式掛載到 `/host-auth...` 底下,然後在測試開始前複製到 `/home/node/...` - - 預設目錄:`.minimax` - - 預設檔案:`~/.codex/auth.json`、`~/.codex/config.toml`、`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json` - - 縮小範圍的 provider 執行只會掛載從 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推斷出的必要目錄/檔案 - - 使用 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none` 或類似 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` 的逗號清單手動覆寫 -- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用於縮小執行範圍 -- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用於篩選容器內的 providers -- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用於在不需要重新建置的重跑中重用既有的 `openclaw:local-live` 映像 -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用於確保 creds 來自 profile store(而不是 env) -- `OPENCLAW_OPENWEBUI_MODEL=...` 用於選擇 Gateway 暴露給 Open WebUI smoke 的模型 -- `OPENCLAW_OPENWEBUI_PROMPT=...` 用於覆寫 Open WebUI smoke 使用的 nonce 檢查 prompt -- `OPENWEBUI_IMAGE=...` 用於覆寫固定的 Open WebUI 映像 tag +- `$HOME` 底下的外部 CLI auth dirs/files 會以唯讀方式掛載到 `/host-auth...` 底下,然後在測試開始前複製到 `/home/node/...` + - 預設 dirs:`.minimax` + - 預設 files:`~/.codex/auth.json`、`~/.codex/config.toml`、`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json` + - 縮小範圍的 provider runs 只會掛載從 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推斷出的必要 dirs/files + - 可用 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none`,或像 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` 這樣的 comma list 手動覆寫 +- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用來縮小執行範圍 +- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用來在容器內篩選 providers +- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用來在不需要重新建置的 reruns 中重用現有的 `openclaw:local-live` 映像 +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用來確保 creds 來自 profile store(而非 env) +- `OPENCLAW_OPENWEBUI_MODEL=...` 用來選擇 Gateway 為 Open WebUI smoke 公開的 model +- `OPENCLAW_OPENWEBUI_PROMPT=...` 用來覆寫 Open WebUI smoke 使用的 nonce-check prompt +- `OPENWEBUI_IMAGE=...` 用來覆寫 pinned Open WebUI image tag -## 文件健全性 +## 文件 sanity 文件編輯後執行文件檢查:`pnpm check:docs`。 -當你也需要頁面內 heading 檢查時,執行完整的 Mintlify anchor 驗證:`pnpm docs:check-links:anchors`。 +當你也需要 in-page heading checks 時,執行完整的 Mintlify anchor validation:`pnpm docs:check-links:anchors`。 -## 離線迴歸(CI-safe) +## Offline regression(CI-safe) -這些是不使用真正 providers 的「真實 pipeline」迴歸: +這些是不使用真實 providers 的「real pipeline」regressions: -- Gateway tool calling(mock OpenAI,真正的 gateway + agent loop):`src/gateway/gateway.test.ts`(case:「透過 gateway agent loop 端對端執行 mock OpenAI tool call」) -- Gateway wizard(WS `wizard.start`/`wizard.next`,寫入 config + 強制 auth):`src/gateway/gateway.test.ts`(case:「透過 ws 執行 wizard 並寫入 auth token config」) +- Gateway tool calling(mock OpenAI、真實 gateway + agent loop):`src/gateway/gateway.test.ts`(case: "runs a mock OpenAI tool call end-to-end via gateway agent loop") +- Gateway wizard(WS `wizard.start`/`wizard.next`,寫入 config + auth enforced):`src/gateway/gateway.test.ts`(case: "runs wizard over ws and writes auth token config") -## Agent 可靠性 evals(skills) +## Agent reliability evals(skills) -我們已經有一些 CI-safe 測試,行為類似「agent 可靠性 evals」: +我們已經有一些 CI-safe tests,其行為類似「agent reliability evals」: -- 透過真正的 gateway + agent loop 進行 mock tool-calling(`src/gateway/gateway.test.ts`)。 -- 驗證 session wiring 和 config effects 的端對端 wizard flows(`src/gateway/gateway.test.ts`)。 +- 透過真實 Gateway + agent loop 進行 mock tool-calling(`src/gateway/gateway.test.ts`)。 +- 驗證 session wiring 與 config effects 的端到端 wizard flows(`src/gateway/gateway.test.ts`)。 -Skills 仍缺少的項目(參見 [Skills](/zh-TW/tools/skills)): +Skills 仍缺少的項目(請參閱 [Skills](/zh-TW/tools/skills)): -- **決策:** 當 prompt 中列出 skills 時,agent 是否選擇正確的 skill(或避開無關的 skill)? -- **遵循:** agent 是否在使用前閱讀 `SKILL.md` 並遵循必要步驟/args? -- **工作流程合約:** 斷言 tool 順序、session history carryover 和 sandbox boundaries 的多輪情境。 +- **決策:** 當 prompt 中列出 Skills 時,agent 是否選擇正確的 skill(或避開不相關的 skill)? +- **合規:** agent 是否在使用前讀取 `SKILL.md`,並遵循必要 steps/args? +- **Workflow contracts:** multi-turn scenarios,用來 assert tool order、session history carryover,以及 sandbox boundaries。 -未來的 evals 應優先保持確定性: +未來的 evals 應優先保持 deterministic: -- 使用 mock providers 的情境 runner,用於斷言 tool calls + 順序、skill 檔案讀取,以及 session wiring。 -- 一小組以 skill 為焦點的情境(使用 vs 避免、gating、prompt injection)。 -- 選用的即時 evals(opt-in、env-gated)僅在 CI-safe suite 到位後再加入。 +- 使用 mock providers 的 scenario runner,用來 assert tool calls + order、skill file reads,以及 session wiring。 +- 一小組以 skill 為重點的 scenarios(use vs avoid、gating、prompt injection)。 +- Optional live evals(opt-in、env-gated)只應在 CI-safe suite 就位後加入。 -## 合約測試(plugin 與 channel 形狀) +## Contract tests(Plugin 與 channel shape) -合約測試會驗證每個已註冊的 plugin 和 channel 都符合其 -interface contract。它們會迭代所有探索到的 plugins,並執行一組 -形狀與行為斷言。預設的 `pnpm test` unit lane 會刻意 -略過這些共享 seam 和 smoke 檔案;當你觸及共享 channel 或 provider surface 時, -請明確執行合約命令。 +Contract tests 會驗證每個已註冊的 Plugin 與 channel 是否符合其 +interface contract。它們會逐一處理所有 discovered plugins,並執行一組 +shape 與 behavior assertions。預設的 `pnpm test` unit lane 會刻意 +跳過這些 shared seam 與 smoke files;當你觸及 shared channel 或 provider surfaces 時, +請明確執行 contract commands。 -### 命令 +### Commands -- 所有合約:`pnpm test:contracts` -- 僅 channel 合約:`pnpm test:contracts:channels` -- 僅 provider 合約:`pnpm test:contracts:plugins` +- 所有 contracts:`pnpm test:contracts` +- 僅 channel contracts:`pnpm test:contracts:channels` +- 僅 provider contracts:`pnpm test:contracts:plugins` -### Channel 合約 +### Channel contracts 位於 `src/channels/plugins/contracts/*.contract.test.ts`: -- **plugin** - 基本 plugin 形狀(id、name、capabilities) -- **setup** - 設定 wizard 合約 -- **session-binding** - Session binding 行為 -- **outbound-payload** - Message payload 結構 -- **inbound** - Inbound message 處理 +- **Plugin** - 基本 Plugin shape(id、name、capabilities) +- **setup** - Setup wizard contract +- **session-binding** - Session binding behavior +- **outbound-payload** - Message payload structure +- **inbound** - Inbound message handling - **actions** - Channel action handlers -- **threading** - Thread ID 處理 +- **threading** - Thread ID handling - **directory** - Directory/roster API - **group-policy** - Group policy enforcement -### Provider status 合約 +### Provider status contracts 位於 `src/plugins/contracts/*.contract.test.ts`。 - **status** - Channel status probes -- **registry** - Plugin registry 形狀 +- **registry** - Plugin registry shape -### Provider 合約 +### Provider contracts 位於 `src/plugins/contracts/*.contract.test.ts`: -- **auth** - Auth flow 合約 +- **auth** - Auth flow contract - **auth-choice** - Auth choice/selection - **catalog** - Model catalog API - **discovery** - Plugin discovery - **loader** - Plugin loading - **runtime** - Provider runtime - **shape** - Plugin shape/interface -- **wizard** - 設定 wizard +- **wizard** - Setup wizard ### 何時執行 - 變更 plugin-sdk exports 或 subpaths 後 -- 新增或修改 channel 或 provider plugin 後 -- 重構 plugin registration 或 discovery 後 +- 新增或修改 channel 或 provider Plugin 後 +- 重構 Plugin registration 或 discovery 後 -合約測試會在 CI 中執行,且不需要真正的 API keys。 +Contract tests 會在 CI 中執行,且不需要真實 API keys。 -## 新增迴歸(指引) +## 新增 regressions(guidance) -當你修復在即時環境中發現的 provider/model 問題時: +當你修復在 live 中發現的 provider/model issue 時: -- 盡可能新增 CI-safe 迴歸(mock/stub provider,或擷取確切的 request-shape transformation) -- 如果本質上只能即時測試(rate limits、auth policies),請保持即時測試範圍狹窄,並透過 env vars opt-in -- 優先鎖定能捕捉該 bug 的最小層級: +- 盡可能新增 CI-safe regression(mock/stub provider,或 capture exact request-shape transformation) +- 如果本質上只能 live-only(rate limits、auth policies),請讓 live test 保持 narrow,並透過 env vars opt-in +- 偏好鎖定能抓到該 bug 的最小 layer: - provider request conversion/replay bug → direct models test - gateway session/history/tool pipeline bug → gateway live smoke 或 CI-safe gateway mock test - SecretRef traversal guardrail: - - `src/secrets/exec-secret-ref-id-parity.test.ts` 會從 registry metadata(`listSecretTargetRegistryEntries()`)為每個 SecretRef class 衍生一個 sampled target,然後斷言 traversal-segment exec ids 會被拒絕。 - - 如果你在 `src/secrets/target-registry-data.ts` 新增新的 `includeInPlan` SecretRef target family,請更新該測試中的 `classifyTargetClass`。該測試會刻意在未分類的 target ids 上失敗,因此新的 classes 不會被靜默略過。 + - `src/secrets/exec-secret-ref-id-parity.test.ts` 會從 registry metadata(`listSecretTargetRegistryEntries()`)為每個 SecretRef class derive 一個 sampled target,然後 assert traversal-segment exec ids 會被 rejected。 + - 如果你在 `src/secrets/target-registry-data.ts` 新增新的 `includeInPlan` SecretRef target family,請更新該 test 中的 `classifyTargetClass`。該 test 會刻意在 unclassified target ids 上失敗,讓 new classes 無法被 silently skipped。 ## 相關 diff --git a/docs/zh-TW/plugins/codex-harness.md b/docs/zh-TW/plugins/codex-harness.md index aebe9c015..bea407b6b 100644 --- a/docs/zh-TW/plugins/codex-harness.md +++ b/docs/zh-TW/plugins/codex-harness.md @@ -1,197 +1,32 @@ --- read_when: - - 您想使用隨附的 Codex app-server 執行框架 + - 您想使用隨附的 Codex app-server 測試框架 - 你需要 Codex 執行框架設定範例 - 你希望僅限 Codex 的部署失敗,而不是回退到 PI -summary: 透過隨附的 Codex app-server 執行框架執行 OpenClaw 內嵌代理回合 -title: Codex 測試框架 +summary: 透過隨附的 Codex app-server 測試框架執行 OpenClaw 嵌入式代理回合 +title: Codex 執行框架 x-i18n: - generated_at: "2026-04-30T20:05:39Z" + generated_at: "2026-05-01T02:45:01Z" model: gpt-5.5 provider: openai - source_hash: 335ec60cbdb76579db833eccb5151ffc5bcd28b370ca2e99587abdb578eeee4f + source_hash: 740e8fa9e6f4a737dfd250fe26b85865a7f7e40839b41e879e9224a45cbe8d72 source_path: plugins/codex-harness.md workflow: 16 --- -隨附的 `codex` Plugin 可讓 OpenClaw 透過 -Codex app-server 執行內嵌代理回合,而不是使用內建 PI harness。 +內建的 `codex` Plugin 讓 OpenClaw 透過 Codex app-server 執行嵌入式代理回合,而不是使用內建的 PI harness。 -當你希望 Codex 擁有低階代理工作階段時,請使用這個 Plugin:模型 -探索、原生執行緒續接、原生 Compaction,以及 app-server 執行。 -OpenClaw 仍然負責聊天頻道、工作階段檔案、模型選擇、工具、 -核准、媒體傳送,以及可見的逐字稿鏡像。 +當你希望由 Codex 擁有底層代理工作階段時,請使用此功能:模型探索、原生執行緒恢復、原生壓縮,以及 app-server 執行。OpenClaw 仍然擁有聊天頻道、工作階段檔案、模型選擇、工具、核准、媒體傳遞,以及可見的逐字稿鏡像。 -如果你正在嘗試定位概念,請從 -[代理執行環境](/zh-TW/concepts/agent-runtimes)開始。簡短版本是: -`openai/gpt-5.5` 是模型參照,`codex` 是執行環境,而 Telegram、 -Discord、Slack 或其他頻道仍然是通訊介面。 +如果你正在嘗試掌握方向,請從 +[代理執行階段](/zh-TW/concepts/agent-runtimes)開始。簡短版本是: +`openai/gpt-5.5` 是模型參照,`codex` 是執行階段,而 Telegram、Discord、Slack 或其他頻道仍然是通訊介面。 -## 這個 Plugin 會改變什麼 +## 快速設定 -隨附的 `codex` Plugin 提供多個獨立能力: - -| 能力 | 使用方式 | 作用 | -| --------------------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------- | -| 原生內嵌執行環境 | `agentRuntime.id: "codex"` | 透過 Codex app-server 執行 OpenClaw 內嵌代理回合。 | -| 原生聊天控制命令 | `/codex bind`, `/codex resume`, `/codex steer`, ... | 從訊息對話綁定並控制 Codex app-server 執行緒。 | -| Codex app-server 提供者/目錄 | `codex` 內部機制,透過 harness 公開 | 讓執行環境探索並驗證 app-server 模型。 | -| Codex 媒體理解路徑 | `codex/*` 影像模型相容性路徑 | 針對支援的影像理解模型執行有界限的 Codex app-server 回合。 | -| 原生 hook 中繼 | Codex 原生事件周圍的 Plugin hooks | 讓 OpenClaw 觀察/阻擋支援的 Codex 原生工具/完成事件。 | - -啟用此 Plugin 會讓這些能力可用。它**不會**: - -- 開始對每個 OpenAI 模型使用 Codex -- 將 `openai-codex/*` 模型參照轉換成原生執行環境 -- 讓 ACP/acpx 成為預設 Codex 路徑 -- 熱切換已經記錄 PI 執行環境的現有工作階段 -- 取代 OpenClaw 頻道傳送、工作階段檔案、驗證設定檔儲存或 - 訊息路由 - -同一個 Plugin 也擁有原生 `/codex` 聊天控制命令介面。如果 -Plugin 已啟用,且使用者要求從聊天綁定、續接、引導、停止或檢查 -Codex 執行緒,代理應優先使用 `/codex ...` 而不是 ACP。當使用者要求 -ACP/acpx,或正在測試 ACP Codex 轉接器時,ACP 仍是明確的後援。 - -原生 Codex 回合會保留 OpenClaw Plugin hooks 作為公開相容層。 -這些是處理程序內的 OpenClaw hooks,不是 Codex `hooks.json` 命令 hooks: - -- `before_prompt_build` -- `before_compaction`, `after_compaction` -- `llm_input`, `llm_output` -- `before_tool_call`, `after_tool_call` -- `before_message_write` 用於鏡像逐字稿記錄 -- 透過 Codex `Stop` 中繼的 `before_agent_finalize` -- `agent_end` - -Plugins 也可以註冊執行環境中立的工具結果中介軟體,在 OpenClaw -執行工具之後、結果回傳給 Codex 之前,改寫 OpenClaw 動態工具結果。 -這不同於公開的 `tool_result_persist` Plugin hook,後者會轉換 -OpenClaw 擁有的逐字稿工具結果寫入。 - -如需 Plugin hook 語意本身,請參閱 [Plugin hooks](/zh-TW/plugins/hooks) -與 [Plugin guard behavior](/zh-TW/tools/plugin)。 - -harness 預設為關閉。新設定應將 OpenAI 模型參照維持為標準的 -`openai/gpt-*`,並在需要原生 app-server 執行時,明確強制使用 -`agentRuntime.id: "codex"` 或 `OPENCLAW_AGENT_RUNTIME=codex`。舊版 -`codex/*` 模型參照仍會為了相容性自動選取 harness,但由執行環境支援的 -舊版提供者前綴不會顯示為一般模型/提供者選項。 - -如果 `codex` Plugin 已啟用,但主要模型仍是 `openai-codex/*`, -`openclaw doctor` 會發出警告,而不是變更路由。這是刻意設計: -`openai-codex/*` 仍是 PI Codex OAuth/訂閱路徑,而原生 app-server -執行仍是明確的執行環境選擇。 - -## 路由對照表 - -變更設定前請使用此表: - -| 期望行為 | 模型參照 | 執行環境設定 | Plugin 需求 | 預期狀態標籤 | -| ------------------------------------------- | -------------------------- | -------------------------------------- | -------------------------- | ------------------------------ | -| 透過一般 OpenClaw runner 使用 OpenAI API | `openai/gpt-*` | 省略或 `runtime: "pi"` | OpenAI 提供者 | `Runtime: OpenClaw Pi Default` | -| 透過 PI 使用 Codex OAuth/訂閱 | `openai-codex/gpt-*` | 省略或 `runtime: "pi"` | OpenAI Codex OAuth 提供者 | `Runtime: OpenClaw Pi Default` | -| 原生 Codex app-server 內嵌回合 | `openai/gpt-*` | `agentRuntime.id: "codex"` | `codex` Plugin | `Runtime: OpenAI Codex` | -| 使用保守自動模式的混合提供者 | 提供者特定參照 | `agentRuntime.id: "auto"` | 選用 Plugin 執行環境 | 取決於選定的執行環境 | -| 明確的 Codex ACP 轉接器工作階段 | 依 ACP 提示/模型而定 | `sessions_spawn` 搭配 `runtime: "acp"` | 健康的 `acpx` 後端 | ACP 任務/工作階段狀態 | - -重要的區分是提供者與執行環境: - -- `openai-codex/*` 回答「PI 應使用哪個提供者/驗證路由?」 -- `agentRuntime.id: "codex"` 回答「哪個迴圈應執行這個 - 內嵌回合?」 -- `/codex ...` 回答「這個聊天應綁定或控制哪個原生 Codex 對話?」 -- ACP 回答「acpx 應啟動哪個外部 harness 程序?」 - -## 選擇正確的模型前綴 - -OpenAI 系列路由依前綴區分。當你想透過 PI 使用 Codex OAuth 時,請使用 -`openai-codex/*`;當你想直接存取 OpenAI API,或正在強制使用原生 -Codex app-server harness 時,請使用 `openai/*`: - -| 模型參照 | 執行環境路徑 | 使用時機 | -| --------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------- | -| `openai/gpt-5.4` | 透過 OpenClaw/PI 管線使用 OpenAI 提供者 | 你想使用目前以 `OPENAI_API_KEY` 直接存取的 OpenAI Platform API。 | -| `openai-codex/gpt-5.5` | 透過 OpenClaw/PI 使用 OpenAI Codex OAuth | 你想以預設 PI runner 使用 ChatGPT/Codex 訂閱驗證。 | -| `openai/gpt-5.5` + `agentRuntime.id: "codex"` | Codex app-server harness | 你想為內嵌代理回合使用原生 Codex app-server 執行。 | - -GPT-5.5 目前在 OpenClaw 中僅支援訂閱/OAuth。PI OAuth 請使用 -`openai-codex/gpt-5.5`,或將 `openai/gpt-5.5` 搭配 Codex -app-server harness 使用。一旦 OpenAI 在公開 API 上啟用 GPT-5.5, -`openai/gpt-5.5` 的直接 API 金鑰存取即受支援。 - -舊版 `codex/gpt-*` 參照仍作為相容別名被接受。Doctor 相容性遷移會將 -舊版主要執行環境參照改寫為標準模型參照,並分開記錄執行環境政策; -而僅作為後援的舊版參照會保持不變,因為執行環境是針對整個代理容器設定。 -新的 PI Codex OAuth 設定應使用 `openai-codex/gpt-*`;新的原生 -app-server harness 設定應使用 `openai/gpt-*` 加上 -`agentRuntime.id: "codex"`。 - -`agents.defaults.imageModel` 遵循相同的前綴區分。當影像理解應透過 -OpenAI Codex OAuth 提供者路徑執行時,請使用 `openai-codex/gpt-*`。 -當影像理解應透過有界限的 Codex app-server 回合執行時,請使用 -`codex/gpt-*`。Codex app-server 模型必須宣告支援影像輸入;純文字 -Codex 模型會在媒體回合開始前失敗。 - -使用 `/status` 確認目前工作階段的有效 harness。如果選擇結果令人意外, -請為 `agents/harness` 子系統啟用偵錯記錄,並檢查 Gateway 的結構化 -`agent harness selected` 記錄。它包含選定的 harness id、選擇原因、 -執行環境/後援政策,以及在 `auto` 模式中每個 Plugin 候選項目的支援結果。 - -### Doctor 警告代表什麼 - -當以下條件全都成立時,`openclaw doctor` 會發出警告: - -- 隨附的 `codex` Plugin 已啟用或允許 -- 某個代理的主要模型是 `openai-codex/*` -- 該代理的有效執行環境不是 `codex` - -此警告存在,是因為使用者常預期「Codex Plugin 已啟用」代表 -「原生 Codex app-server 執行環境」。OpenClaw 不會做這個跳躍。 -此警告表示: - -- 如果你原本就打算透過 PI 使用 ChatGPT/Codex OAuth,則**不需要變更**。 -- 如果你原本打算使用原生 app-server 執行,請將模型變更為 - `openai/`,並設定 `agentRuntime.id: "codex"`。 -- 執行環境變更後,現有工作階段仍需要 `/new` 或 `/reset`, - 因為工作階段執行環境釘選是黏著的。 - -harness 選擇不是即時工作階段控制。當內嵌回合執行時,OpenClaw -會在該工作階段上記錄選定的 harness id,並在同一個工作階段 id 的後續回合繼續使用它。 -若希望未來工作階段使用其他 harness,請變更 `agentRuntime` 設定或 -`OPENCLAW_AGENT_RUNTIME`;在現有對話於 PI 與 Codex 之間切換前,請使用 -`/new` 或 `/reset` 啟動新的工作階段。這可避免透過兩套不相容的原生工作階段系統 -重播同一份逐字稿。 - -在 harness 釘選出現前建立的舊版工作階段,一旦已有逐字稿歷史,就會被視為 -PI 釘選。變更設定後,請使用 `/new` 或 `/reset` 將該對話改用 Codex。 - -`/status` 會顯示有效的模型執行環境。預設 PI harness 會顯示為 -`Runtime: OpenClaw Pi Default`,Codex app-server harness 會顯示為 -`Runtime: OpenAI Codex`。 - -## 需求 - -- OpenClaw 可使用隨附的 `codex` Plugin。 -- Codex app-server `0.125.0` 或更新版本。隨附的 Plugin 預設會管理相容的 - Codex app-server 二進位檔,因此 `PATH` 上的本機 `codex` 命令不會影響 - 一般 harness 啟動。 -- app-server 程序或 OpenClaw 的 Codex 驗證橋接器可使用 Codex 驗證。 - 本機 stdio app-server 啟動會為每個代理使用 OpenClaw 管理的 Codex home, - 以及隔離的子程序 `HOME`,因此預設不會讀取你的個人 - `~/.codex` 帳號、Skills、Plugins、設定、執行緒狀態或原生 - `$HOME/.agents/skills`。 - -此 Plugin 會阻擋較舊或無版本的 app-server 交握。這可讓 OpenClaw 維持在 -已測試過的協定介面上。 - -對於即時與 Docker smoke tests,驗證通常來自 Codex CLI 帳號或 OpenClaw -`openai-codex` 驗證設定檔。當沒有帳號存在時,本機 stdio app-server 啟動也可以後援使用 -`CODEX_API_KEY` / `OPENAI_API_KEY`。 - -## 最小設定 - -使用 `openai/gpt-5.5`,啟用隨附的 Plugin,並強制使用 `codex` harness: +若要將 Codex harness 用於 GPT 代理回合,請將模型參照保持為標準的 +`openai/gpt-*`,啟用內建的 `codex` Plugin,並設定 +`agentRuntime.id: "codex"`: ```json5 { @@ -207,6 +42,7 @@ PI 釘選。變更設定後,請使用 `/new` 或 `/reset` 將該對話改用 C model: "openai/gpt-5.5", agentRuntime: { id: "codex", + fallback: "none", }, }, }, @@ -228,21 +64,127 @@ PI 釘選。變更設定後,請使用 `/new` 或 `/reset` 將該對話改用 C } ``` -將 `agents.defaults.model` 或某個代理模型設定為 `codex/` 的舊版設定, -仍會自動啟用隨附的 `codex` Plugin。新設定應優先使用 `openai/`, -並加上上方明確的 `agentRuntime` 項目。 +不要在這條路徑中使用 `openai-codex/gpt-*`。除非你另外強制指定執行階段,否則這會透過一般 PI runner 選擇 Codex OAuth。設定變更會套用到新的或重設後的工作階段;既有工作階段會保留其已記錄的執行階段。 -## 與其他模型並列加入 Codex +## 這個 Plugin 會改變什麼 -如果同一個 agent 應該能在 Codex 與非 Codex 提供者模型之間自由切換,請不要全域設定 `agentRuntime.id: "codex"`。強制指定的 runtime 會套用到該 agent 或 session 的每一個嵌入式回合。如果你在強制使用該 runtime 時選擇 Anthropic 模型,OpenClaw 仍會嘗試 Codex harness,並以封閉方式失敗,而不是悄悄將該回合透過 Pi 路由。 +內建的 `codex` Plugin 提供多種獨立能力: + +| 能力 | 使用方式 | 作用 | +| --------------------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------- | +| 原生嵌入式執行階段 | `agentRuntime.id: "codex"` | 透過 Codex app-server 執行 OpenClaw 嵌入式代理回合。 | +| 原生聊天控制命令 | `/codex bind`, `/codex resume`, `/codex steer`, ... | 從訊息對話繫結並控制 Codex app-server 執行緒。 | +| Codex app-server 供應器/目錄 | `codex` 內部功能,透過 harness 顯示 | 讓執行階段探索並驗證 app-server 模型。 | +| Codex 媒體理解路徑 | `codex/*` 影像模型相容性路徑 | 對支援的影像理解模型執行有界的 Codex app-server 回合。 | +| 原生掛鉤轉送 | Codex 原生事件周圍的 Plugin 掛鉤 | 讓 OpenClaw 觀察/封鎖支援的 Codex 原生工具/完成事件。 | + +啟用 Plugin 會讓這些能力可用。它**不會**: + +- 開始對每個 OpenAI 模型使用 Codex +- 將 `openai-codex/*` 模型參照轉換為原生執行階段 +- 讓 ACP/acpx 成為預設 Codex 路徑 +- 熱切換已經記錄 PI 執行階段的既有工作階段 +- 取代 OpenClaw 頻道傳遞、工作階段檔案、auth-profile 儲存,或訊息路由 + +同一個 Plugin 也擁有原生 `/codex` 聊天控制命令介面。如果 Plugin 已啟用,且使用者要求從聊天中繫結、恢復、導向、停止或檢查 Codex 執行緒,代理應優先使用 `/codex ...`,而不是 ACP。當使用者要求 ACP/acpx 或正在測試 ACP Codex 轉接器時,ACP 仍然是明確的後備方案。 + +原生 Codex 回合會保留 OpenClaw Plugin 掛鉤作為公開相容層。這些是處理程序內的 OpenClaw 掛鉤,不是 Codex `hooks.json` 命令掛鉤: + +- `before_prompt_build` +- `before_compaction`, `after_compaction` +- `llm_input`, `llm_output` +- `before_tool_call`, `after_tool_call` +- `before_message_write` 用於鏡像逐字稿記錄 +- `before_agent_finalize` 透過 Codex `Stop` 轉送 +- `agent_end` + +Plugins 也可以註冊執行階段中立的工具結果中介軟體,在 OpenClaw 執行工具之後、結果傳回 Codex 之前,重寫 OpenClaw 動態工具結果。這不同於公開的 `tool_result_persist` Plugin 掛鉤,後者會轉換 OpenClaw 擁有的逐字稿工具結果寫入。 + +如需 Plugin 掛鉤語意本身,請參閱 [Plugin 掛鉤](/zh-TW/plugins/hooks)和 [Plugin guard 行為](/zh-TW/tools/plugin)。 + +harness 預設為關閉。新設定應將 OpenAI 模型參照保持為標準的 `openai/gpt-*`,並在需要原生 app-server 執行時明確強制使用 `agentRuntime.id: "codex"` 或 `OPENCLAW_AGENT_RUNTIME=codex`。舊版 `codex/*` 模型參照仍會為了相容性自動選擇 harness,但以執行階段為後盾的舊版供應器前綴不會顯示為一般模型/供應器選項。 + +如果 `codex` Plugin 已啟用,但主要模型仍是 `openai-codex/*`,`openclaw doctor` 會發出警告,而不是變更路由。這是刻意設計:`openai-codex/*` 仍然是 PI Codex OAuth/訂閱路徑,而原生 app-server 執行仍是明確的執行階段選擇。 + +## 路由對照表 + +變更設定前請使用此表: + +| 期望行為 | 模型參照 | 執行階段設定 | Plugin 需求 | 預期狀態標籤 | +| ------------------------------------------- | -------------------------- | -------------------------------------- | --------------------------- | ------------------------------ | +| 透過一般 OpenClaw runner 使用 OpenAI API | `openai/gpt-*` | 省略或 `runtime: "pi"` | OpenAI 供應器 | `Runtime: OpenClaw Pi Default` | +| 透過 PI 使用 Codex OAuth/訂閱 | `openai-codex/gpt-*` | 省略或 `runtime: "pi"` | OpenAI Codex OAuth 供應器 | `Runtime: OpenClaw Pi Default` | +| 原生 Codex app-server 嵌入式回合 | `openai/gpt-*` | `agentRuntime.id: "codex"` | `codex` Plugin | `Runtime: OpenAI Codex` | +| 以保守自動模式混用供應器 | 供應器專屬參照 | `agentRuntime.id: "auto"` | 選用 Plugin 執行階段 | 取決於選定的執行階段 | +| 明確的 Codex ACP 轉接器工作階段 | 取決於 ACP 提示/模型 | `sessions_spawn` 搭配 `runtime: "acp"` | 健康的 `acpx` 後端 | ACP 任務/工作階段狀態 | + +重要的區分是供應器與執行階段: + +- `openai-codex/*` 回答「PI 應使用哪個供應器/auth 路由?」 +- `agentRuntime.id: "codex"` 回答「哪個迴圈應執行這個嵌入式回合?」 +- `/codex ...` 回答「此聊天應繫結或控制哪個原生 Codex 對話?」 +- ACP 回答「acpx 應啟動哪個外部 harness 程序?」 + +## 選擇正確的模型前綴 + +OpenAI 系列路由依前綴區分。當你想透過 PI 使用 Codex OAuth 時,使用 `openai-codex/*`;當你想直接存取 OpenAI API,或正在強制使用原生 Codex app-server harness 時,使用 `openai/*`: + +| 模型參照 | 執行階段路徑 | 使用時機 | +| --------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------- | +| `openai/gpt-5.4` | 透過 OpenClaw/PI 管線的 OpenAI 供應器 | 你想用 `OPENAI_API_KEY` 取得目前直接的 OpenAI Platform API 存取權。 | +| `openai-codex/gpt-5.5` | 透過 OpenClaw/PI 的 OpenAI Codex OAuth | 你想使用 ChatGPT/Codex 訂閱驗證搭配預設 PI runner。 | +| `openai/gpt-5.5` + `agentRuntime.id: "codex"` | Codex app-server harness | 你想對嵌入式代理回合使用原生 Codex app-server 執行。 | + +GPT-5.5 目前在 OpenClaw 中僅支援訂閱/OAuth。PI OAuth 請使用 `openai-codex/gpt-5.5`,或搭配 Codex app-server harness 使用 `openai/gpt-5.5`。一旦 OpenAI 在公開 API 上啟用 GPT-5.5,即支援 `openai/gpt-5.5` 的直接 API 金鑰存取。 + +舊版 `codex/gpt-*` 參照仍會作為相容性別名被接受。Doctor 相容性遷移會將舊版主要執行階段參照重寫為標準模型參照,並分開記錄執行階段政策,而僅作為後備的舊版參照會保持不變,因為執行階段是為整個代理容器設定。新的 PI Codex OAuth 設定應使用 `openai-codex/gpt-*`;新的原生 app-server harness 設定應使用 `openai/gpt-*` 加上 `agentRuntime.id: "codex"`。 + +`agents.defaults.imageModel` 遵循相同的前綴區分。當影像理解應透過 OpenAI Codex OAuth 供應器路徑執行時,使用 `openai-codex/gpt-*`。當影像理解應透過有界的 Codex app-server 回合執行時,使用 `codex/gpt-*`。Codex app-server 模型必須宣告支援影像輸入;純文字 Codex 模型會在媒體回合開始前失敗。 + +使用 `/status` 確認目前工作階段的有效 harness。如果選擇結果令人意外,請啟用 `agents/harness` 子系統的偵錯記錄,並檢查 Gateway 的結構化 `agent harness selected` 記錄。它包含選定的 harness id、選擇原因、執行階段/後備政策,以及在 `auto` 模式中每個 Plugin 候選項的支援結果。 + +### Doctor 警告的意思 + +當以下全部為真時,`openclaw doctor` 會發出警告: + +- 內建的 `codex` Plugin 已啟用或允許 +- 代理的主要模型是 `openai-codex/*` +- 該代理的有效執行階段不是 `codex` + +這個警告存在,是因為使用者經常預期「已啟用 Codex Plugin」就代表「原生 Codex app-server 執行階段」。OpenClaw 不會做出這個跳躍。此警告表示: + +- 如果你本來就打算透過 PI 使用 ChatGPT/Codex OAuth,則**不需要變更**。 +- 如果你打算使用原生 app-server 執行,請將模型改為 `openai/`,並設定 + `agentRuntime.id: "codex"`。 +- 執行階段變更後,既有工作階段仍需要 `/new` 或 `/reset`,因為工作階段執行階段釘選是黏著的。 + +Harness 選擇不是即時工作階段控制。當嵌入式回合執行時,OpenClaw 會在該工作階段上記錄選定的 harness id,並在相同工作階段 id 的後續回合中持續使用它。當你希望未來工作階段使用另一個 harness 時,請變更 `agentRuntime` 設定或 `OPENCLAW_AGENT_RUNTIME`;在既有對話於 PI 與 Codex 之間切換前,使用 `/new` 或 `/reset` 啟動全新的工作階段。這可避免透過兩個不相容的原生工作階段系統重播同一份逐字稿。 + +在 harness 釘選出現前建立的舊版工作階段,一旦有逐字稿歷史,就會被視為已釘選到 PI。變更設定後,使用 `/new` 或 `/reset` 將該對話選入 Codex。 + +`/status` 會顯示有效模型執行階段。預設 PI harness 會顯示為 `Runtime: OpenClaw Pi Default`,而 Codex app-server harness 會顯示為 `Runtime: OpenAI Codex`。 + +## 需求 + +- 可用內建 `codex` Plugin 的 OpenClaw。 +- Codex app-server `0.125.0` 或更新版本。內建 Plugin 預設會管理相容的 Codex app-server 二進位檔,因此 `PATH` 上的本機 `codex` 命令不會影響一般 harness 啟動。 +- app-server 程序或 OpenClaw 的 Codex auth bridge 可使用 Codex auth。本機 app-server 啟動會為每個代理使用 OpenClaw 管理的 Codex home,以及隔離的子程序 `HOME`,因此預設不會讀取你的個人 `~/.codex` 帳號、Skills、Plugins、設定、執行緒狀態,或原生 `$HOME/.agents/skills`。 + +Plugin 會封鎖較舊或未帶版本的 app-server 交握。這能讓 OpenClaw 保持在已測試過的協定介面上。 + +對於即時和 Docker 煙霧測試,auth 通常來自 Codex CLI 帳號或 OpenClaw `openai-codex` auth profile。本機 stdio app-server 啟動在沒有帳號時,也可以後備使用 `CODEX_API_KEY` / `OPENAI_API_KEY`。 + +## 將 Codex 與其他模型一起加入 + +如果同一個 agent 應該能在 Codex 與非 Codex 供應商模型之間自由切換,請勿全域設定 `agentRuntime.id: "codex"`。強制 runtime 會套用到該 agent 或 session 的每一個嵌入式回合。如果你在強制使用該 runtime 時選取 Anthropic 模型,OpenClaw 仍會嘗試 Codex harness,並以封閉失敗結束,而不是默默將該回合透過 PI 路由。 請改用下列其中一種形式: -- 將 Codex 放在專用 agent 上,並設定 `agentRuntime.id: "codex"`。 -- 讓預設 agent 維持 `agentRuntime.id: "auto"`,並使用 Pi fallback 供一般混合提供者使用情境。 -- 只為相容性使用舊版 `codex/*` 參照。新設定應優先使用 `openai/*`,並搭配明確的 Codex runtime policy。 +- 將 Codex 放在使用 `agentRuntime.id: "codex"` 的專用 agent 上。 +- 將預設 agent 保持在 `agentRuntime.id: "auto"`,並使用 PI fallback 來處理一般混合供應商用法。 +- 舊版 `codex/*` refs 僅供相容性使用。新設定應優先使用 `openai/*`,並搭配明確的 Codex runtime policy。 -例如,這會讓預設 agent 使用一般自動選擇,並新增一個獨立的 Codex agent: +例如,以下會讓預設 agent 使用一般自動選取,並加入獨立的 Codex agent: ```json5 { @@ -281,31 +223,31 @@ PI 釘選。變更設定後,請使用 `/new` 或 `/reset` 將該對話改用 C 使用這種形式時: -- 預設的 `main` agent 會使用一般提供者路徑與 Pi 相容性 fallback。 +- 預設的 `main` agent 會使用一般供應商路徑與 PI 相容性 fallback。 - `codex` agent 會使用 Codex app-server harness。 -- 如果 `codex` agent 缺少 Codex 或不受支援,該回合會失敗,而不是悄悄使用 Pi。 +- 如果 `codex` agent 缺少 Codex 或不支援 Codex,該回合會失敗,而不是悄悄使用 PI。 ## Agent 命令路由 -Agents 應依意圖路由使用者請求,而不是只依「Codex」這個詞: +Agents 應依意圖路由使用者請求,而不是只看「Codex」這個字: -| 使用者要求... | Agent 應使用... | +| 使用者要求... | Agent 應使用... | | -------------------------------------------------------- | ------------------------------------------------ | -|「將此 chat 綁定到 Codex」 | `/codex bind` | -|「在這裡繼續 Codex thread ``」 | `/codex resume ` | -|「顯示 Codex threads」 | `/codex threads` | -|「為失敗的 Codex 執行提交支援報告」 | `/diagnostics [note]` | -|「只針對這個附加的 thread 傳送 Codex feedback」 | `/codex diagnostics [note]` | -|「使用 Codex 作為此 agent 的 runtime」 | 將設定變更為 `agentRuntime.id` | -|「用我的 ChatGPT/Codex 訂閱搭配一般 OpenClaw」 | `openai-codex/*` 模型參照 | -|「透過 ACP/acpx 執行 Codex」 | ACP `sessions_spawn({ runtime: "acp", ... })` | -|「在 thread 中啟動 Claude Code/Gemini/OpenCode/Cursor」 | ACP/acpx,而不是 `/codex`,也不是原生 sub-agents | +| 「將此對話綁定到 Codex」 | `/codex bind` | +| 「在這裡繼續 Codex thread ``」 | `/codex resume ` | +| 「顯示 Codex threads」 | `/codex threads` | +| 「為一次異常的 Codex run 提交支援報告」 | `/diagnostics [note]` | +| 「只針對這個附加的 thread 傳送 Codex feedback」 | `/codex diagnostics [note]` | +| 「將 Codex 用作此 agent 的 runtime」 | 將設定變更為 `agentRuntime.id` | +| 「在一般 OpenClaw 中使用我的 ChatGPT/Codex 訂閱」 | `openai-codex/*` model refs | +| 「透過 ACP/acpx 執行 Codex」 | ACP `sessions_spawn({ runtime: "acp", ... })` | +| 「在 thread 中啟動 Claude Code/Gemini/OpenCode/Cursor」 | ACP/acpx,而非 `/codex`,也不是原生 sub-agents | -只有在 ACP 已啟用、可分派,並由已載入的 runtime backend 支援時,OpenClaw 才會向 agents 宣告 ACP spawn 指引。如果 ACP 不可用,system prompt 與 Plugin skills 不應教 agent ACP 路由。 +OpenClaw 只會在 ACP 已啟用、可派送,且有已載入的 runtime 後端支援時,才向 agents 宣告 ACP spawn 指引。如果 ACP 無法使用,系統提示與 plugin skills 不應教導 agent 關於 ACP 路由。 -## 僅 Codex 的部署 +## 僅限 Codex 的部署 -當你需要證明每個嵌入式 agent 回合都使用 Codex 時,請強制使用 Codex harness。明確的 Plugin runtime 預設沒有 Pi fallback,因此 `fallback: "none"` 是選用的,但通常可作為有用的文件說明: +當你需要證明每個嵌入式 agent 回合都使用 Codex 時,請強制使用 Codex harness。明確的 Plugin runtimes 預設沒有 PI fallback,因此 `fallback: "none"` 是選用的,但通常很適合作為文件化說明: ```json5 { @@ -327,11 +269,11 @@ Agents 應依意圖路由使用者請求,而不是只依「Codex」這個詞 OPENCLAW_AGENT_RUNTIME=codex openclaw gateway run ``` -強制使用 Codex 時,如果 Codex Plugin 已停用、app-server 太舊,或 app-server 無法啟動,OpenClaw 會提早失敗。只有在你有意讓 Pi 處理缺少 harness 選擇時,才設定 `OPENCLAW_AGENT_HARNESS_FALLBACK=pi`。 +強制使用 Codex 時,如果 Codex Plugin 已停用、app-server 太舊,或 app-server 無法啟動,OpenClaw 會提早失敗。只有在你刻意想讓 PI 處理缺少 harness 選取的情況時,才設定 `OPENCLAW_AGENT_HARNESS_FALLBACK=pi`。 ## 每個 agent 的 Codex -你可以讓某個 agent 僅使用 Codex,同時讓預設 agent 保持一般自動選擇: +你可以讓某個 agent 僅使用 Codex,同時讓預設 agent 保持一般自動選取: ```json5 { @@ -362,11 +304,11 @@ OPENCLAW_AGENT_RUNTIME=codex openclaw gateway run } ``` -使用一般 session 命令切換 agents 與模型。`/new` 會建立新的 OpenClaw session,而 Codex harness 會視需要建立或繼續其 sidecar app-server thread。`/reset` 會清除該 thread 的 OpenClaw session 綁定,並讓下一個回合再次從目前設定解析 harness。 +使用一般 session 命令切換 agents 與模型。`/new` 會建立新的 OpenClaw session,而 Codex harness 會依需要建立或繼續它的 sidecar app-server thread。`/reset` 會清除此 thread 的 OpenClaw session 綁定,並讓下一個回合再次從目前設定解析 harness。 ## 模型探索 -預設情況下,Codex Plugin 會向 app-server 詢問可用模型。如果探索失敗或逾時,它會使用內建 fallback catalog: +預設情況下,Codex Plugin 會向 app-server 詢問可用模型。如果探索失敗或逾時,它會對下列項目使用內建 fallback catalog: - GPT-5.5 - GPT-5.4 mini @@ -392,7 +334,7 @@ OPENCLAW_AGENT_RUNTIME=codex openclaw gateway run } ``` -當你希望啟動時避免探測 Codex,並固定使用 fallback catalog,請停用探索: +當你希望啟動時避免探查 Codex,並固定使用 fallback catalog 時,請停用探索: ```json5 { @@ -411,19 +353,19 @@ OPENCLAW_AGENT_RUNTIME=codex openclaw gateway run } ``` -## App-server 連線與 policy +## App-server 連線與政策 -預設情況下,Plugin 會在本機啟動 OpenClaw 管理的 Codex binary: +預設情況下,Plugin 會以本機方式啟動 OpenClaw 管理的 Codex binary: ```bash codex app-server --listen stdio:// ``` -受管理的 binary 會宣告為內建 Plugin runtime dependency,並與其餘 `codex` Plugin dependencies 一起 staged。這會讓 app-server 版本與內建 Plugin 綁定,而不是使用本機剛好安裝的另一個 Codex CLI。只有在你有意執行不同 executable 時,才設定 `appServer.command`。 +受管理的 binary 會宣告為內建 Plugin runtime 相依項,並與其餘 `codex` Plugin 相依項一起暫存。這會讓 app-server 版本與內建 Plugin 綁定,而不是使用本機剛好安裝的其他 Codex CLI。只有在你刻意想執行不同可執行檔時,才設定 `appServer.command`。 -預設情況下,OpenClaw 會以 YOLO 模式啟動本機 Codex harness sessions:`approvalPolicy: "never"`、`approvalsReviewer: "user"`,以及 `sandbox: "danger-full-access"`。這是自主 heartbeats 使用的受信任本機 operator 姿態:Codex 可以使用 shell 與網路工具,而不會因無人在場回答的原生核准提示而停下。 +預設情況下,OpenClaw 會以 YOLO 模式啟動本機 Codex harness sessions:`approvalPolicy: "never"`、`approvalsReviewer: "user"`,以及 `sandbox: "danger-full-access"`。這是自主 Heartbeats 使用的受信任本機操作者姿態:Codex 可以使用 shell 與網路工具,而不會因為沒有人能回覆的原生核准提示而停止。 -若要選擇使用 Codex guardian-reviewed approvals,請設定 `appServer.mode: +若要選擇使用 Codex guardian 審查核准,請設定 `appServer.mode: "guardian"`: ```json5 @@ -444,11 +386,11 @@ codex app-server --listen stdio:// } ``` -Guardian 模式會使用 Codex 的原生 auto-review approval path。當 Codex 要求離開 sandbox、寫入 workspace 外部,或新增網路存取等權限時,Codex 會將該核准請求路由到原生 reviewer,而不是人類提示。reviewer 會套用 Codex 的風險框架,並核准或拒絕該特定請求。當你想要比 YOLO 模式更多 guardrails,但仍需要無人值守的 agents 持續推進時,請使用 Guardian。 +Guardian 模式使用 Codex 的原生自動審查核准路徑。當 Codex 要求離開 sandbox、寫入 workspace 外部,或新增網路存取等權限時,Codex 會將該核准請求路由到原生 reviewer,而不是 human prompt。reviewer 會套用 Codex 的風險框架,並核准或拒絕該特定請求。當你想要比 YOLO 模式更多 guardrails,但仍需要無人值守的 agents 能持續推進時,請使用 Guardian。 -`guardian` preset 會展開為 `approvalPolicy: "on-request"`、`approvalsReviewer: "auto_review"`,以及 `sandbox: "workspace-write"`。個別 policy 欄位仍會覆寫 `mode`,因此進階部署可以混合使用 preset 與明確選項。舊版 `guardian_subagent` reviewer 值仍會作為相容性 alias 被接受,但新設定應使用 `auto_review`。 +`guardian` preset 會展開為 `approvalPolicy: "on-request"`、`approvalsReviewer: "auto_review"`,以及 `sandbox: "workspace-write"`。個別政策欄位仍會覆寫 `mode`,因此進階部署可以將 preset 與明確選項混用。較舊的 `guardian_subagent` reviewer 值仍可作為相容性別名接受,但新設定應使用 `auto_review`。 -對於已在執行的 app-server,請使用 WebSocket transport: +若 app-server 已在執行,請使用 WebSocket 傳輸: ```json5 { @@ -470,27 +412,27 @@ Guardian 模式會使用 Codex 的原生 auto-review approval path。當 Codex } ``` -Stdio app-server launches 預設會繼承 OpenClaw 的 process environment,但 OpenClaw 會擁有 Codex app-server account bridge,並將 `CODEX_HOME` 與 `HOME` 都設為該 agent 的 OpenClaw state 下的每個 agent 目錄。Codex 自己的 skill loader 會讀取 `$CODEX_HOME/skills` 與 `$HOME/.agents/skills`,因此這兩個值都會針對本機 app-server launches 隔離。這會讓 Codex-native skills、plugins、config、accounts 與 thread state 限定在 OpenClaw agent 範圍內,而不是從 operator 個人的 Codex CLI home 洩漏進來。 +Stdio app-server 啟動預設會繼承 OpenClaw 的處理程序環境,但 OpenClaw 擁有 Codex app-server 帳戶 bridge,並將 `CODEX_HOME` 與 `HOME` 都設定為該 agent 的 OpenClaw state 底下的每 agent 目錄。Codex 自身的 skill loader 會讀取 `$CODEX_HOME/skills` 與 `$HOME/.agents/skills`,因此這兩個值都會對本機 app-server 啟動進行隔離。這會讓 Codex 原生 skills、plugins、設定、帳戶與 thread state 限定在 OpenClaw agent 範圍內,而不是從操作者的個人 Codex CLI home 外洩進來。 -OpenClaw plugins 與 OpenClaw skill snapshots 仍會透過 OpenClaw 自己的 Plugin registry 與 skill loader 流動。個人 Codex CLI assets 不會。如果你有實用的 Codex CLI skills 或 plugins 應成為 OpenClaw agent 的一部分,請明確 inventory 它們: +OpenClaw plugins 與 OpenClaw skill snapshots 仍會透過 OpenClaw 自己的 Plugin registry 與 skill loader 流動。個人 Codex CLI assets 不會。如果你有實用的 Codex CLI skills 或 plugins 應成為 OpenClaw agent 的一部分,請明確盤點它們: ```bash openclaw migrate codex --dry-run openclaw migrate apply codex --yes ``` -Codex migration provider 會將 skills 複製到目前的 OpenClaw agent workspace。Codex native plugins、hooks 與 config files 會被報告或封存以供手動審查,而不是自動啟用,因為它們可以執行命令、公開 MCP servers,或攜帶 credentials。 +Codex migration provider 會將 skills 複製到目前的 OpenClaw agent workspace。Codex 原生 plugins、hooks 與設定檔會被回報或封存以供人工審查,而不是自動啟用,因為它們可以執行命令、公開 MCP servers,或攜帶憑證。 -Auth 會依下列順序選擇: +Auth 會依此順序選取: 1. 該 agent 的明確 OpenClaw Codex auth profile。 -2. app-server 在該 agent 的 Codex home 中既有的 account。 -3. 僅限本機 stdio app-server launches,當沒有 app-server account 且仍需要 OpenAI auth 時,使用 `CODEX_API_KEY`,接著使用 +2. 該 agent 的 Codex home 中 app-server 既有的帳戶。 +3. 僅限本機 stdio app-server 啟動,在沒有 app-server 帳戶且仍需要 OpenAI auth 時,使用 `CODEX_API_KEY`,接著使用 `OPENAI_API_KEY`。 -當 OpenClaw 看到 ChatGPT 訂閱式 Codex auth profile 時,會從產生的 Codex child process 移除 `CODEX_API_KEY` 與 `OPENAI_API_KEY`。這會讓 Gateway 層級的 API keys 仍可用於 embeddings 或直接 OpenAI models,而不會讓原生 Codex app-server 回合意外透過 API 計費。明確的 Codex API-key profiles 與本機 stdio env-key fallback 會使用 app-server login,而不是繼承的 child-process env。WebSocket app-server connections 不會收到 Gateway env API-key fallback;請使用明確 auth profile 或 remote app-server 自己的 account。 +當 OpenClaw 看到 ChatGPT 訂閱樣式的 Codex auth profile 時,會從產生的 Codex child process 移除 `CODEX_API_KEY` 與 `OPENAI_API_KEY`。這會讓 Gateway 層級 API keys 可用於 embeddings 或直接 OpenAI models,而不會意外讓原生 Codex app-server 回合透過 API 計費。明確的 Codex API-key profiles 與本機 stdio env-key fallback 會使用 app-server login,而不是繼承 child-process env。WebSocket app-server 連線不會收到 Gateway env API-key fallback;請使用明確的 auth profile 或遠端 app-server 自己的帳戶。 -如果部署需要額外的環境隔離,請將那些 variables 加到 `appServer.clearEnv`: +如果部署需要額外的環境隔離,請將那些變數加入 `appServer.clearEnv`: ```json5 { @@ -515,28 +457,27 @@ Auth 會依下列順序選擇: | 欄位 | 預設值 | 意義 | | ------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `transport` | `"stdio"` | `"stdio"` 會產生 Codex;`"websocket"` 會連線到 `url`。 | -| `command` | 受管理的 Codex 二進位檔 | stdio 傳輸使用的可執行檔。保留未設定即可使用受管理的二進位檔;只有在明確覆寫時才設定。 | -| `args` | `["app-server", "--listen", "stdio://"]` | stdio 傳輸使用的引數。 | +| `transport` | `"stdio"` | `"stdio"` 會啟動 Codex;`"websocket"` 會連線到 `url`。 | +| `command` | 受管理的 Codex binary | stdio 傳輸的可執行檔。保留未設定即可使用受管理的 binary;只有在明確覆寫時才設定。 | +| `args` | `["app-server", "--listen", "stdio://"]` | stdio 傳輸的引數。 | | `url` | 未設定 | WebSocket app-server URL。 | -| `authToken` | 未設定 | WebSocket 傳輸使用的 Bearer token。 | +| `authToken` | 未設定 | WebSocket 傳輸的 Bearer token。 | | `headers` | `{}` | 額外的 WebSocket 標頭。 | -| `clearEnv` | `[]` | OpenClaw 建立繼承環境後,從產生的 stdio app-server 程序中移除的額外環境變數名稱。`CODEX_HOME` 和 `HOME` 保留給 OpenClaw 在本機啟動時用於每個代理程式的 Codex 隔離。 | +| `clearEnv` | `[]` | 在 OpenClaw 建立其繼承環境後,會從產生的 stdio app-server 程序移除的額外環境變數名稱。`CODEX_HOME` 和 `HOME` 保留供 OpenClaw 在本機啟動時進行每代理 Codex 隔離使用。 | | `requestTimeoutMs` | `60000` | app-server 控制平面呼叫的逾時時間。 | -| `mode` | `"yolo"` | YOLO 或 guardian 審查執行的預設組態。 | -| `approvalPolicy` | `"never"` | 傳送到執行緒開始/恢復/回合的原生 Codex 核准政策。 | -| `sandbox` | `"danger-full-access"` | 傳送到執行緒開始/恢復的原生 Codex 沙箱模式。 | +| `mode` | `"yolo"` | YOLO 或 guardian-reviewed 執行的預設集。 | +| `approvalPolicy` | `"never"` | 傳送到執行緒開始/恢復/回合的原生 Codex 核准政策。 | +| `sandbox` | `"danger-full-access"` | 傳送到執行緒開始/恢復的原生 Codex 沙盒模式。 | | `approvalsReviewer` | `"user"` | 使用 `"auto_review"` 讓 Codex 審查原生核准提示。`guardian_subagent` 仍是舊版別名。 | | `serviceTier` | 未設定 | 選用的 Codex app-server 服務層級:`"fast"`、`"flex"` 或 `null`。無效的舊版值會被忽略。 | OpenClaw 擁有的動態工具呼叫會獨立於 -`appServer.requestTimeoutMs` 受限制:每個 Codex `item/tool/call` 要求都必須在 +`appServer.requestTimeoutMs` 受到界定:每個 Codex `item/tool/call` 請求都必須在 30 秒內收到 OpenClaw 回應。逾時時,OpenClaw 會在支援的情況下中止工具 -訊號,並向 Codex 回傳失敗的動態工具回應,讓該回合可以繼續,而不是讓工作階段停留在 -`processing`。 +訊號,並向 Codex 傳回失敗的動態工具回應,讓該回合可以繼續,而不是讓工作階段停留在 `processing`。 -OpenClaw 回應 Codex 回合範圍的 app-server 要求後,測試框架 -也預期 Codex 以 `turn/completed` 完成原生回合。如果 +OpenClaw 回應 Codex 回合範圍的 app-server 請求後,harness +也會預期 Codex 以 `turn/completed` 完成原生回合。如果 app-server 在該回應後靜默 60 秒,OpenClaw 會盡力 中斷 Codex 回合、記錄診斷逾時,並釋放 OpenClaw 工作階段通道,讓後續聊天訊息不會排在過期的 @@ -550,29 +491,28 @@ OpenClaw 工作階段通道,讓後續聊天訊息不會排在過期的 - `OPENCLAW_CODEX_APP_SERVER_APPROVAL_POLICY` - `OPENCLAW_CODEX_APP_SERVER_SANDBOX` -當 `appServer.command` 未設定時,`OPENCLAW_CODEX_APP_SERVER_BIN` 會略過受管理的二進位檔。 +當 `appServer.command` 未設定時,`OPENCLAW_CODEX_APP_SERVER_BIN` 會略過受管理的 binary。 `OPENCLAW_CODEX_APP_SERVER_GUARDIAN=1` 已移除。請改用 `plugins.entries.codex.config.appServer.mode: "guardian"`,或針對一次性本機測試使用 -`OPENCLAW_CODEX_APP_SERVER_MODE=guardian`。可重複部署時偏好使用設定, -因為它會讓 Plugin 行為與其餘 Codex 測試框架設定保留在同一個 -已審查的檔案中。 +`OPENCLAW_CODEX_APP_SERVER_MODE=guardian`。可重複部署時 +建議使用設定,因為它會將 Plugin 行為保留在與其餘 Codex harness 設定相同的 +已審查檔案中。 ## 電腦使用 -電腦使用在自己的設定指南中說明: +電腦使用有自己的設定指南: [Codex 電腦使用](/zh-TW/plugins/codex-computer-use)。 -簡短版本:OpenClaw 不會內建桌面控制應用程式,也不會自行執行 -桌面動作。它會準備 Codex app-server、驗證 +簡短版:OpenClaw 不會 vend 桌面控制 app,也不會自行執行 +桌面動作。它會準備 Codex app-server,確認 `computer-use` MCP 伺服器可用,然後讓 Codex 在 Codex 模式回合期間處理原生 MCP 工具呼叫。 -若要在 Codex marketplace 流程之外直接存取 TryCua 驅動程式,請使用 +若要在 Codex marketplace 流程之外直接存取 TryCua driver,請用 `openclaw mcp set cua-driver '{"command":"cua-driver","args":["mcp"]}'` 註冊 -`cua-driver mcp`。 -請參閱 [Codex 電腦使用](/zh-TW/plugins/codex-computer-use),了解 Codex 擁有的電腦使用 -與直接 MCP 註冊之間的差異。 +`cua-driver mcp`。請參閱 [Codex 電腦使用](/zh-TW/plugins/codex-computer-use),了解 +Codex 擁有的電腦使用與直接 MCP 註冊之間的差異。 最小設定: @@ -602,27 +542,27 @@ MCP 工具呼叫。 } ``` -可以從命令介面檢查或安裝設定: +可從命令介面檢查或安裝設定: - `/codex computer-use status` - `/codex computer-use install` - `/codex computer-use install --source ` - `/codex computer-use install --marketplace-path ` -電腦使用為 macOS 專用,且在 -Codex MCP 伺服器可以控制應用程式前,可能需要本機作業系統權限。如果 `computerUse.enabled` 為 true 且 MCP -伺服器不可用,Codex 模式回合會在執行緒開始前失敗,而不是在沒有原生電腦使用工具的情況下 +電腦使用僅適用於 macOS,且在 Codex MCP 伺服器能控制 app 前,可能需要本機 OS 權限。如果 `computerUse.enabled` 為 true 且 MCP +伺服器無法使用,Codex 模式回合會在執行緒開始前失敗,而不是在沒有原生電腦使用工具的情況下 靜默執行。請參閱 [Codex 電腦使用](/zh-TW/plugins/codex-computer-use),了解 marketplace 選項、 -遠端目錄限制、狀態原因和疑難排解。 +遠端目錄限制、狀態原因與疑難排解。 當 `computerUse.autoInstall` 為 true 時,如果 Codex -尚未探索到本機 marketplace,OpenClaw 可以從 +尚未發現本機 marketplace,OpenClaw 可以從 `/Applications/Codex.app/Contents/Resources/plugins/openai-bundled` 註冊標準 -內建 Codex Desktop marketplace。變更執行階段或電腦使用設定後,請使用 `/new` 或 `/reset`, -讓既有工作階段不會保留舊的 PI 或 Codex 執行緒繫結。 +內建 Codex Desktop marketplace。變更 runtime 或電腦使用設定後,請使用 `/new` 或 `/reset`, +以免既有工作階段保留舊的 +PI 或 Codex 執行緒繫結。 -## 常用配方 +## 常見配方 使用預設 stdio 傳輸的本機 Codex: @@ -638,7 +578,7 @@ Codex MCP 伺服器可以控制應用程式前,可能需要本機作業系統 } ``` -僅 Codex 的測試框架驗證: +僅限 Codex 的 harness 驗證: ```json5 { @@ -660,7 +600,7 @@ Codex MCP 伺服器可以控制應用程式前,可能需要本機作業系統 } ``` -guardian 審查的 Codex 核准: +Guardian-reviewed Codex 核准: ```json5 { @@ -682,7 +622,7 @@ guardian 審查的 Codex 核准: } ``` -具有明確標頭的遠端 app-server: +帶有明確標頭的遠端 app-server: ```json5 { @@ -706,164 +646,164 @@ guardian 審查的 Codex 核准: ``` 模型切換仍由 OpenClaw 控制。當 OpenClaw 工作階段附加到 -既有 Codex 執行緒時,下一個回合會再次將目前選取的 -OpenAI 模型、供應商、核准政策、沙箱和服務層級傳送到 +既有 Codex 執行緒時,下一回合會再次將目前選取的 +OpenAI 模型、provider、核准政策、沙盒與服務層級傳送到 app-server。從 `openai/gpt-5.5` 切換到 `openai/gpt-5.2` 會保留 執行緒繫結,但要求 Codex 使用新選取的模型繼續。 ## Codex 命令 -內建 Plugin 會將 `/codex` 註冊為授權的斜線命令。它是 -通用命令,適用於任何支援 OpenClaw 文字命令的頻道。 +內建 Plugin 會將 `/codex` 註冊為已授權的斜線命令。它是 +通用的,適用於任何支援 OpenClaw 文字命令的 channel。 -常用形式: +常見形式: -- `/codex status` 顯示即時 app-server 連線能力、模型、帳戶、速率限制、MCP 伺服器和 skills。 +- `/codex status` 顯示即時 app-server 連線能力、模型、帳戶、速率限制、MCP 伺服器與 Skills。 - `/codex models` 列出即時 Codex app-server 模型。 - `/codex threads [filter]` 列出最近的 Codex 執行緒。 - `/codex resume ` 將目前的 OpenClaw 工作階段附加到既有 Codex 執行緒。 - `/codex compact` 要求 Codex app-server 壓縮附加的執行緒。 - `/codex review` 為附加的執行緒啟動 Codex 原生審查。 -- `/codex diagnostics [note]` 在傳送附加執行緒的 Codex 診斷回饋前先詢問。 +- `/codex diagnostics [note]` 會在傳送附加執行緒的 Codex 診斷回饋前先詢問。 - `/codex computer-use status` 檢查已設定的電腦使用 Plugin 和 MCP 伺服器。 - `/codex computer-use install` 安裝已設定的電腦使用 Plugin 並重新載入 MCP 伺服器。 - `/codex account` 顯示帳戶和速率限制狀態。 - `/codex mcp` 列出 Codex app-server MCP 伺服器狀態。 - `/codex skills` 列出 Codex app-server skills。 -### 常用偵錯工作流程 +### 常見偵錯工作流程 -當 Codex 支援的代理程式在 Telegram、Discord、Slack -或其他頻道中出現意外行為時,請從發生問題的對話開始: +當 Codex 支援的代理在 Telegram、Discord、Slack +或其他 channel 中做出意外行為時,請從問題發生的對話開始: -1. 執行 `/diagnostics bad tool choice after image upload` 或另一個描述你所見情況的簡短註記。 -2. 核准診斷要求一次。該核准會建立本機 Gateway - 診斷 zip,並且因為工作階段正在使用 Codex 測試框架,也會 - 將相關的 Codex 回饋套件傳送到 OpenAI 伺服器。 -3. 將完成的診斷回覆複製到錯誤報告或支援討論串中。 - 其中包含本機套件路徑、隱私摘要、OpenClaw 工作階段 ID、 +1. 執行 `/diagnostics bad tool choice after image upload`,或另一則描述你所見情況的簡短註記。 +2. 核准一次診斷請求。該核准會建立本機 Gateway + 診斷 zip,並且因為工作階段使用 Codex harness,也會 + 將相關的 Codex 回饋 bundle 傳送到 OpenAI 伺服器。 +3. 將完成的診斷回覆複製到錯誤報告或支援討論串。 + 它包含本機 bundle 路徑、隱私摘要、OpenClaw 工作階段 ID、 Codex 執行緒 ID,以及每個 Codex 執行緒的 `Inspect locally` 行。 -4. 如果想自行偵錯該次執行,請在終端機中執行列印出的 `Inspect locally` +4. 如果你想自行偵錯該次執行,請在終端機中執行列印出的 `Inspect locally` 命令。它看起來像 `codex resume `,並會開啟 原生 Codex 執行緒,讓你檢查對話、在本機繼續, 或詢問 Codex 為何選擇特定工具或計畫。 -只有在你特別想要目前附加執行緒的 Codex 意見回饋上傳,而不需要完整 OpenClaw Gateway 診斷套件時,才使用 `/codex diagnostics [note]`。對大多數支援回報來說,`/diagnostics [note]` 是更好的起點,因為它會在同一則回覆中把本機 Gateway 狀態與 Codex 執行緒 ID 串在一起。完整的隱私模型與群組聊天行為請參閱[診斷匯出](/zh-TW/gateway/diagnostics)。 +只有當你特別想要針對目前附加的執行緒上傳 Codex 回饋,而不需要完整的 OpenClaw Gateway 診斷套件時,才使用 `/codex diagnostics [note]`。對於大多數支援回報,`/diagnostics [note]` 是更好的起點,因為它會在同一則回覆中把本機 Gateway 狀態與 Codex 執行緒 ID 串在一起。完整的隱私模型與群組聊天行為,請參閱[診斷匯出](/zh-TW/gateway/diagnostics)。 -核心 OpenClaw 也會將僅限擁有者使用的 `/diagnostics [note]` 暴露為一般 Gateway 診斷命令。它的核准提示會顯示敏感資料前言、連結到[診斷匯出](/zh-TW/gateway/diagnostics),並且每次都透過明確的 exec 核准請求 `openclaw gateway diagnostics export --json`。不要用 allow-all 規則核准診斷。核准後,OpenClaw 會傳送一份可貼上的報告,其中包含本機套件路徑與 manifest 摘要。當作用中的 OpenClaw 工作階段正在使用 Codex harness 時,同一個核准也會授權將相關的 Codex 意見回饋套件傳送到 OpenAI 伺服器。核准提示會說明將會傳送 Codex 意見回饋,但在核准前不會列出 Codex 工作階段或執行緒 ID。 +核心 OpenClaw 也公開僅限擁有者使用的 `/diagnostics [note]`,作為一般 Gateway 診斷命令。其核准提示會顯示敏感資料前言、連結到[診斷匯出](/zh-TW/gateway/diagnostics),並且每次都透過明確的 exec 核准請求執行 `openclaw gateway diagnostics export --json`。不要以允許所有項目的規則核准診斷。核准後,OpenClaw 會傳送一份可貼上的報告,其中包含本機套件路徑與資訊清單摘要。當作用中的 OpenClaw 工作階段正在使用 Codex harness 時,同一個核准也會授權將相關的 Codex 回饋套件傳送到 OpenAI 伺服器。核准提示會說明 Codex 回饋將會被傳送,但不會在核准前列出 Codex 工作階段或執行緒 ID。 -如果擁有者在群組聊天中呼叫 `/diagnostics`,OpenClaw 會保持共享頻道簡潔:群組只會收到一則短通知,而診斷前言、核准提示,以及 Codex 工作階段/執行緒 ID 會透過私人核准路由傳送給擁有者。如果沒有私人擁有者路由,OpenClaw 會拒絕群組請求,並要求擁有者從 DM 執行。 +如果 `/diagnostics` 是由擁有者在群組聊天中叫用,OpenClaw 會保持共享頻道乾淨:群組只會收到一則簡短通知,而診斷前言、核准提示,以及 Codex 工作階段/執行緒 ID 會透過私人核准路徑傳送給擁有者。如果沒有私人擁有者路徑,OpenClaw 會拒絕群組請求,並要求擁有者從 DM 執行。 -已核准的 Codex 上傳會呼叫 Codex app-server `feedback/upload`,並要求 app-server 在可用時包含每個列出執行緒與衍生 Codex 子執行緒的記錄。上傳會透過 Codex 的一般意見回饋路徑傳送到 OpenAI 伺服器;如果該 app-server 停用了 Codex 意見回饋,命令會回傳 app-server 錯誤。完成的診斷回覆會列出已傳送執行緒的頻道、OpenClaw 工作階段 ID、Codex 執行緒 ID,以及本機 `codex resume ` 命令。如果你拒絕或忽略核准,OpenClaw 不會列印那些 Codex ID。這項上傳不會取代本機 Gateway 診斷匯出。 +已核准的 Codex 上傳會呼叫 Codex app-server `feedback/upload`,並要求 app-server 在可用時為每個列出的執行緒與衍生的 Codex 子執行緒納入記錄。上傳會透過 Codex 一般回饋路徑傳送到 OpenAI 伺服器;如果該 app-server 中停用了 Codex 回饋,此命令會回傳 app-server 錯誤。完成的診斷回覆會列出已傳送執行緒的頻道、OpenClaw 工作階段 ID、Codex 執行緒 ID,以及本機 `codex resume ` 命令。如果你拒絕或忽略核准,OpenClaw 不會列印那些 Codex ID。此上傳不會取代本機 Gateway 診斷匯出。 -`/codex resume` 會寫入 harness 在一般回合中使用的同一個 sidecar 綁定檔。下一則訊息時,OpenClaw 會恢復該 Codex 執行緒,將目前選取的 OpenClaw 模型傳入 app-server,並保持延伸歷史記錄啟用。 +`/codex resume` 會寫入與 harness 在一般回合中使用的相同 sidecar 繫結檔。下一則訊息時,OpenClaw 會恢復該 Codex 執行緒,將目前選取的 OpenClaw 模型傳入 app-server,並保持延伸歷史記錄啟用。 ### 從 CLI 檢查 Codex 執行緒 -了解有問題的 Codex 執行時,最快的方式通常是直接開啟原生 Codex 執行緒: +理解不良 Codex 執行的最快方式,通常是直接開啟原生 Codex 執行緒: ```sh codex resume ``` -當你在頻道對話中注意到錯誤,並且想檢查有問題的 Codex 工作階段、在本機繼續它,或詢問 Codex 為何做出特定工具或推理選擇時,請使用這個方式。最簡單的路徑通常是先執行 `/diagnostics [note]`:核准後,完成的報告會列出每個 Codex 執行緒,並列印一個 `Inspect locally` 命令,例如 `codex resume `。你可以直接把該命令複製到終端機。 +當你在頻道對話中注意到錯誤,並想要檢查有問題的 Codex 工作階段、在本機繼續它,或詢問 Codex 為何做出特定工具或推理選擇時,請使用此命令。最簡單的路徑通常是先執行 `/diagnostics [note]`:在你核准後,完成的報告會列出每個 Codex 執行緒,並列印一個 `Inspect locally` 命令,例如 `codex resume `。你可以直接將該命令複製到終端機。 -你也可以從目前聊天的 `/codex binding`,或最近 Codex app-server 執行緒的 `/codex threads [filter]` 取得執行緒 ID,然後在 shell 中執行同一個 `codex resume` 命令。 +你也可以從目前聊天的 `/codex binding`,或最近 Codex app-server 執行緒的 `/codex threads [filter]` 取得執行緒 ID,然後在 shell 中執行相同的 `codex resume` 命令。 -命令介面需要 Codex app-server `0.125.0` 或更新版本。如果未來或自訂 app-server 未暴露該 JSON-RPC 方法,個別控制方法會回報為 `unsupported by this Codex app-server`。 +此命令介面需要 Codex app-server `0.125.0` 或更新版本。如果未來或自訂 app-server 未公開該 JSON-RPC 方法,個別控制方法會回報為 `unsupported by this Codex app-server`。 -## Hook 邊界 +## 鉤子邊界 -Codex harness 有三個 Hook 層: +Codex harness 有三層鉤子: -| 層 | 擁有者 | 目的 | +| 層級 | 擁有者 | 用途 | | ------------------------------------- | ------------------------ | ------------------------------------------------------------------- | -| OpenClaw Plugin Hook | OpenClaw | 跨 PI 與 Codex harness 的產品/Plugin 相容性。 | -| Codex app-server 擴充中介軟體 | OpenClaw bundled plugins | 圍繞 OpenClaw 動態工具的逐回合 adapter 行為。 | -| Codex 原生 Hook | Codex | 來自 Codex 設定的底層 Codex 生命週期與原生工具政策。 | +| OpenClaw Plugin 鉤子 | OpenClaw | 跨 PI 與 Codex harness 的產品/Plugin 相容性。 | +| Codex app-server 擴充 middleware | OpenClaw 隨附 Plugin | 圍繞 OpenClaw 動態工具的每回合配接器行為。 | +| Codex 原生鉤子 | Codex | 來自 Codex 設定的低階 Codex 生命週期與原生工具政策。 | -OpenClaw 不使用專案或全域 Codex `hooks.json` 檔案來路由 OpenClaw Plugin 行為。對於受支援的原生工具與權限橋接,OpenClaw 會為 `PreToolUse`、`PostToolUse`、`PermissionRequest` 和 `Stop` 注入逐執行緒 Codex 設定。其他 Codex Hook,例如 `SessionStart` 和 `UserPromptSubmit`,仍然是 Codex 層級的控制;它們不會在 v1 合約中暴露為 OpenClaw Plugin Hook。 +OpenClaw 不會使用專案或全域 Codex `hooks.json` 檔案來路由 OpenClaw Plugin 行為。對於受支援的原生工具與權限橋接,OpenClaw 會為 `PreToolUse`、`PostToolUse`、`PermissionRequest` 與 `Stop` 注入每個執行緒的 Codex 設定。其他 Codex 鉤子,例如 `SessionStart` 與 `UserPromptSubmit`,仍然是 Codex 層級控制;它們不會在 v1 合約中公開為 OpenClaw Plugin 鉤子。 -對於 OpenClaw 動態工具,OpenClaw 會在 Codex 請求呼叫後執行工具,因此 OpenClaw 會在 harness adapter 中觸發它所擁有的 Plugin 與中介軟體行為。對於 Codex 原生工具,Codex 擁有標準工具記錄。OpenClaw 可以鏡像選定事件,但除非 Codex 透過 app-server 或原生 Hook callback 暴露該操作,否則 OpenClaw 無法重寫原生 Codex 執行緒。 +對於 OpenClaw 動態工具,OpenClaw 會在 Codex 要求呼叫後執行該工具,因此 OpenClaw 會在 harness 配接器中觸發其所擁有的 Plugin 與 middleware 行為。對於 Codex 原生工具,Codex 擁有標準工具記錄。OpenClaw 可以鏡像選定事件,但除非 Codex 透過 app-server 或原生鉤子回呼公開該操作,否則它無法改寫原生 Codex 執行緒。 -Compaction 與 LLM 生命週期投影來自 Codex app-server 通知與 OpenClaw adapter 狀態,而不是原生 Codex Hook 命令。OpenClaw 的 `before_compaction`、`after_compaction`、`llm_input` 和 `llm_output` 事件是 adapter 層級觀察結果,不是 Codex 內部請求或 Compaction payload 的逐位元組擷取。 +Compaction 與 LLM 生命週期投影來自 Codex app-server 通知與 OpenClaw 配接器狀態,而不是原生 Codex 鉤子命令。OpenClaw 的 `before_compaction`、`after_compaction`、`llm_input` 與 `llm_output` 事件是配接器層級觀察,不是逐位元組擷取 Codex 內部請求或 Compaction 承載。 -Codex 原生 `hook/started` 和 `hook/completed` app-server 通知會被投影為 `codex_app_server.hook` 代理事件,用於軌跡與除錯。它們不會呼叫 OpenClaw Plugin Hook。 +Codex 原生 `hook/started` 與 `hook/completed` app-server 通知會投影為 `codex_app_server.hook` 代理事件,用於軌跡與除錯。它們不會叫用 OpenClaw Plugin 鉤子。 ## V1 支援合約 -Codex 模式不是在底層換成不同模型呼叫的 PI。Codex 擁有更多原生模型迴圈,而 OpenClaw 會圍繞該邊界調整其 Plugin 與工作階段介面。 +Codex 模式不是在底層換成不同模型呼叫的 PI。Codex 擁有更多原生模型迴圈,而 OpenClaw 會圍繞該邊界配接其 Plugin 與工作階段介面。 Codex runtime v1 支援: | 介面 | 支援 | 原因 | | --------------------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 透過 Codex 的 OpenAI 模型迴圈 | 支援 | Codex app-server 擁有 OpenAI 回合、原生執行緒恢復,以及原生工具延續。 | -| OpenClaw 頻道路由與傳遞 | 支援 | Telegram、Discord、Slack、WhatsApp、iMessage 和其他頻道保持在模型 runtime 之外。 | -| OpenClaw 動態工具 | 支援 | Codex 會要求 OpenClaw 執行這些工具,因此 OpenClaw 仍在執行路徑中。 | -| Prompt 與內容 Plugin | 支援 | OpenClaw 會建立 prompt overlay,並在啟動或恢復執行緒前將內容投影到 Codex 回合中。 | -| 內容引擎生命週期 | 支援 | 組裝、擷取或回合後維護,以及內容引擎 Compaction 協調會針對 Codex 回合執行。 | -| 動態工具 Hook | 支援 | `before_tool_call`、`after_tool_call` 和工具結果中介軟體會圍繞 OpenClaw 擁有的動態工具執行。 | -| 生命週期 Hook | 作為 adapter 觀察結果支援 | `llm_input`、`llm_output`、`agent_end`、`before_compaction` 和 `after_compaction` 會以誠實的 Codex 模式 payload 觸發。 | -| 最終答案修訂閘門 | 透過原生 Hook relay 支援 | Codex `Stop` 會被轉送到 `before_agent_finalize`;`revise` 會在最終化前要求 Codex 再執行一次模型 pass。 | -| 原生 shell、patch 和 MCP 封鎖或觀察 | 透過原生 Hook relay 支援 | Codex `PreToolUse` 和 `PostToolUse` 會針對已承諾的原生工具介面被轉送,包括 Codex app-server `0.125.0` 或更新版本上的 MCP payload。支援封鎖;不支援引數重寫。 | -| 原生權限政策 | 透過原生 Hook relay 支援 | Codex `PermissionRequest` 可以在 runtime 暴露時透過 OpenClaw 政策路由。如果 OpenClaw 沒有回傳決策,Codex 會繼續透過其一般 guardian 或使用者核准路徑。 | +| 透過 Codex 執行 OpenAI 模型迴圈 | 支援 | Codex app-server 擁有 OpenAI 回合、原生執行緒恢復,以及原生工具延續。 | +| OpenClaw 頻道路由與傳遞 | 支援 | Telegram、Discord、Slack、WhatsApp、iMessage 與其他頻道會維持在模型 runtime 之外。 | +| OpenClaw 動態工具 | 支援 | Codex 會要求 OpenClaw 執行這些工具,因此 OpenClaw 仍位於執行路徑中。 | +| 提示與情境 Plugin | 支援 | OpenClaw 會在啟動或恢復執行緒前建立提示覆蓋層,並將情境投影到 Codex 回合中。 | +| 情境引擎生命週期 | 支援 | 組裝、擷取或回合後維護,以及情境引擎 Compaction 協調會針對 Codex 回合執行。 | +| 動態工具鉤子 | 支援 | `before_tool_call`、`after_tool_call` 與工具結果 middleware 會圍繞 OpenClaw 擁有的動態工具執行。 | +| 生命週期鉤子 | 作為配接器觀察支援 | `llm_input`、`llm_output`、`agent_end`、`before_compaction` 與 `after_compaction` 會以誠實的 Codex 模式承載觸發。 | +| 最終答案修訂閘門 | 透過原生鉤子轉送支援 | Codex `Stop` 會轉送至 `before_agent_finalize`;`revise` 會要求 Codex 在最終化前再執行一次模型傳遞。 | +| 原生 shell、patch 與 MCP 封鎖或觀察 | 透過原生鉤子轉送支援 | Codex `PreToolUse` 與 `PostToolUse` 會針對已承諾的原生工具介面轉送,包括 Codex app-server `0.125.0` 或更新版本上的 MCP 承載。支援封鎖;不支援引數改寫。 | +| 原生權限政策 | 透過原生鉤子轉送支援 | 在 runtime 公開時,Codex `PermissionRequest` 可透過 OpenClaw 政策路由。如果 OpenClaw 未回傳決策,Codex 會繼續走其一般 guardian 或使用者核准路徑。 | | App-server 軌跡擷取 | 支援 | OpenClaw 會記錄它傳送給 app-server 的請求,以及它收到的 app-server 通知。 | Codex runtime v1 不支援: -| 表面 | V1 邊界 | 未來路徑 | +| 介面 | V1 邊界 | 未來路徑 | | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -| 原生工具引數變更 | Codex 原生工具前置鉤子可以封鎖,但 OpenClaw 不會重寫 Codex 原生工具引數。 | 需要 Codex 鉤子/架構支援替換工具輸入。 | -| 可編輯的 Codex 原生逐字稿歷史 | Codex 擁有標準原生對話串歷史。OpenClaw 擁有鏡像並可投射未來內容脈絡,但不應變更不受支援的內部項目。 | 如果需要原生對話串手術,請新增明確的 Codex app-server API。 | -| Codex 原生工具記錄的 `tool_result_persist` | 該鉤子會轉換 OpenClaw 擁有的逐字稿寫入,而非 Codex 原生工具記錄。 | 可以鏡像轉換後的記錄,但標準重寫需要 Codex 支援。 | -| 豐富的原生 Compaction 中繼資料 | OpenClaw 會觀察 Compaction 開始與完成,但不會收到穩定的保留/捨棄清單、權杖差異或摘要承載資料。 | 需要更豐富的 Codex Compaction 事件。 | -| Compaction 介入 | 目前在 Codex 模式中,OpenClaw Compaction 鉤子屬於通知層級。 | 如果 plugins 需要否決或重寫原生 Compaction,請新增 Codex Compaction 前置/後置鉤子。 | -| 逐位元組模型 API 請求擷取 | OpenClaw 可以擷取 app-server 請求與通知,但 Codex 核心會在內部建構最終 OpenAI API 請求。 | 需要 Codex 模型請求追蹤事件或除錯 API。 | +| 原生工具引數變更 | Codex 原生工具前置 hook 可以封鎖,但 OpenClaw 不會重寫 Codex 原生工具引數。 | 需要 Codex hook/schema 支援替換工具輸入。 | +| 可編輯的 Codex 原生轉錄歷史 | Codex 擁有標準原生執行緒歷史。OpenClaw 擁有鏡像並可投射未來脈絡,但不應變更未受支援的內部機制。 | 如果需要原生執行緒手術式修改,請加入明確的 Codex app-server API。 | +| Codex 原生工具記錄的 `tool_result_persist` | 該 hook 會轉換 OpenClaw 擁有的轉錄寫入,而不是 Codex 原生工具記錄。 | 可鏡像已轉換記錄,但標準重寫需要 Codex 支援。 | +| 豐富的原生壓縮中繼資料 | OpenClaw 會觀察壓縮開始與完成,但不會收到穩定的保留/丟棄清單、權杖差異或摘要承載。 | 需要更豐富的 Codex 壓縮事件。 | +| 壓縮介入 | 目前 OpenClaw 壓縮 hook 在 Codex 模式中屬於通知層級。 | 如果 plugins 需要否決或重寫原生壓縮,請加入 Codex 壓縮前/後 hook。 | +| 逐位元組相同的模型 API 請求擷取 | OpenClaw 可以擷取 app-server 請求與通知,但 Codex 核心會在內部建構最終 OpenAI API 請求。 | 需要 Codex 模型請求追蹤事件或偵錯 API。 | -## 工具、媒體與 Compaction +## 工具、媒體和壓縮 -Codex harness 只會變更低階嵌入式代理執行器。 +Codex harness 只會變更低階嵌入式 agent 執行器。 -OpenClaw 仍會建構工具清單,並從 harness 接收動態工具結果。文字、影像、影片、音樂、TTS、核准與訊息工具輸出會繼續透過一般 OpenClaw 傳遞路徑。 +OpenClaw 仍會建構工具清單,並從 harness 接收動態工具結果。文字、圖片、影片、音樂、TTS、核准與訊息工具輸出,會繼續透過一般 OpenClaw 傳遞路徑。 -原生鉤子轉送刻意保持通用,但 v1 支援合約僅限於 OpenClaw 測試過的 Codex 原生工具與權限路徑。在 Codex runtime 中,這包括 shell、patch,以及 MCP `PreToolUse`、`PostToolUse` 和 `PermissionRequest` 承載資料。在 runtime 合約明確命名前,請勿假設每個未來 Codex 鉤子事件都是 OpenClaw Plugin 表面。 +原生 hook relay 刻意保持通用,但 v1 支援合約僅限於 OpenClaw 測試過的 Codex 原生工具與權限路徑。在 Codex runtime 中,這包含 shell、patch 和 MCP `PreToolUse`、`PostToolUse` 與 `PermissionRequest` 承載。不要假設每個未來的 Codex hook 事件都是 OpenClaw Plugin 介面,除非 runtime 合約明確命名它。 -對於 `PermissionRequest`,OpenClaw 只會在政策作出判斷時回傳明確的允許或拒絕決策。沒有決策的結果不是允許。Codex 會將其視為沒有鉤子決策,並落入自己的 guardian 或使用者核准路徑。 +對於 `PermissionRequest`,OpenClaw 只有在政策做出決定時才會回傳明確允許或拒絕決定。無決定結果不是允許。Codex 會將其視為沒有 hook 決定,並落回自己的 guardian 或使用者核准路徑。 -當 Codex 將 `_meta.codex_approval_kind` 標記為 `"mcp_tool_call"` 時,Codex MCP 工具核准請求會透過 OpenClaw 的 Plugin 核准流程路由。Codex `request_user_input` 提示會傳回原始聊天,而下一則排隊的後續訊息會回答該原生伺服器請求,而不是被導向為額外內容脈絡。其他 MCP 請求仍會失敗關閉。 +當 Codex 將 `_meta.codex_approval_kind` 標記為 `"mcp_tool_call"` 時,Codex MCP 工具核准徵詢會透過 OpenClaw 的 Plugin 核准流程路由。Codex `request_user_input` 提示會傳回來源聊天,而下一則排入佇列的後續訊息會回答該原生伺服器請求,而不是被導向為額外脈絡。其他 MCP 徵詢請求仍會封閉失敗。 -作用中執行佇列導向會對應到 Codex app-server `turn/steer`。使用預設 `messages.queue.mode: "steer"` 時,OpenClaw 會在已設定的靜默視窗內批次處理排隊的聊天訊息,並依抵達順序將它們作為一個 `turn/steer` 請求傳送。舊版 `queue` 模式會傳送個別 `turn/steer` 請求。Codex 審查與手動 Compaction 回合可能會拒絕同回合導向,在這種情況下,當所選模式允許備援時,OpenClaw 會使用後續佇列。請參閱[導向佇列](/zh-TW/concepts/queue-steering)。 +作用中執行佇列導向會對應到 Codex app-server `turn/steer`。使用預設 `messages.queue.mode: "steer"` 時,OpenClaw 會在已設定的安靜視窗內批次處理排入佇列的聊天訊息,並依抵達順序以單一 `turn/steer` 請求傳送。舊版 `queue` 模式會傳送個別的 `turn/steer` 請求。Codex review 和手動壓縮回合可能會拒絕同回合導向,在這種情況下,當所選模式允許 fallback 時,OpenClaw 會使用後續佇列。請參閱[導向佇列](/zh-TW/concepts/queue-steering)。 -當所選模型使用 Codex harness 時,原生對話串 Compaction 會委派給 Codex app-server。OpenClaw 會保留逐字稿鏡像,用於頻道歷史、搜尋、`/new`、`/reset`,以及未來的模型或 harness 切換。鏡像包含使用者提示、最終助理文字,以及 app-server 發出時的輕量 Codex 推理或計畫記錄。目前,OpenClaw 只記錄原生 Compaction 開始與完成訊號。它尚未公開人類可讀的 Compaction 摘要,也尚未提供可稽核的清單來顯示 Codex 在 Compaction 後保留了哪些項目。 +當所選模型使用 Codex harness 時,原生執行緒壓縮會委派給 Codex app-server。OpenClaw 會保留轉錄鏡像,用於頻道歷史、搜尋、`/new`、`/reset`,以及未來的模型或 harness 切換。當 app-server 發出使用者提示、最終助理文字,以及輕量 Codex reasoning 或 plan 記錄時,鏡像會包含這些內容。目前,OpenClaw 只記錄原生壓縮開始與完成訊號。它尚未公開人類可讀的壓縮摘要,或可稽核的 Codex 在壓縮後保留項目清單。 -因為 Codex 擁有標準原生對話串,`tool_result_persist` 目前不會重寫 Codex 原生工具結果記錄。它只會在 OpenClaw 寫入 OpenClaw 擁有的工作階段逐字稿工具結果時套用。 +因為 Codex 擁有標準原生執行緒,`tool_result_persist` 目前不會重寫 Codex 原生工具結果記錄。它只會在 OpenClaw 寫入 OpenClaw 擁有的工作階段轉錄工具結果時套用。 -媒體生成不需要 PI。影像、影片、音樂、PDF、TTS 與媒體理解會繼續使用相符的供應商/模型設定,例如 `agents.defaults.imageGenerationModel`、`videoGenerationModel`、`pdfModel` 和 `messages.tts`。 +媒體產生不需要 PI。圖片、影片、音樂、PDF、TTS 與媒體理解會繼續使用相符的 provider/model 設定,例如 `agents.defaults.imageGenerationModel`、`videoGenerationModel`、`pdfModel` 和 `messages.tts`。 ## 疑難排解 -**Codex 未顯示為一般 `/model` 供應商:** 對新設定而言,這是預期行為。選取具有 `agentRuntime.id: "codex"` 的 `openai/gpt-*` 模型(或舊版 `codex/*` 參照),啟用 `plugins.entries.codex.enabled`,並檢查 `plugins.allow` 是否排除 `codex`。 +**Codex 不會顯示為一般 `/model` provider:** 這對新設定而言是預期行為。選取含有 `agentRuntime.id: "codex"` 的 `openai/gpt-*` 模型(或舊版 `codex/*` 參照),啟用 `plugins.entries.codex.enabled`,並檢查 `plugins.allow` 是否排除 `codex`。 -**OpenClaw 使用 PI 而非 Codex:** 當沒有 Codex harness 宣告該次執行時,`agentRuntime.id: "auto"` 仍可使用 PI 作為相容性後端。測試時請設定 `agentRuntime.id: "codex"` 以強制選取 Codex。除非你明確設定 `agentRuntime.fallback: "pi"`,否則強制 Codex runtime 現在會失敗,而不是退回 PI。一旦選取 Codex app-server,其失敗會直接浮現,不需要額外的備援設定。 +**OpenClaw 使用 PI 而不是 Codex:** 當沒有 Codex harness 宣告該執行時,`agentRuntime.id: "auto"` 仍可使用 PI 作為相容性後端。測試時請設定 `agentRuntime.id: "codex"` 以強制選擇 Codex。除非你明確設定 `agentRuntime.fallback: "pi"`,否則強制 Codex runtime 現在會失敗,而不是 fallback 到 PI。一旦選取 Codex app-server,其失敗會直接浮現,不需要額外 fallback 設定。 -**app-server 被拒絕:** 升級 Codex,讓 app-server 交握回報版本 `0.125.0` 或更新版本。相同版本的預發布版本或帶有建置後綴的版本,例如 `0.125.0-alpha.2` 或 `0.125.0+custom`,會被拒絕,因為穩定的 `0.125.0` 協定下限才是 OpenClaw 測試的目標。 +**app-server 被拒絕:** 升級 Codex,讓 app-server handshake 回報版本 `0.125.0` 或更新版本。同版本 prerelease 或帶有 build suffix 的版本,例如 `0.125.0-alpha.2` 或 `0.125.0+custom`,會被拒絕,因為 OpenClaw 測試的是穩定版 `0.125.0` 協定下限。 -**模型探索速度很慢:** 降低 `plugins.entries.codex.config.discovery.timeoutMs` 或停用探索。 +**模型探索很慢:** 降低 `plugins.entries.codex.config.discovery.timeoutMs` 或停用探索。 -**WebSocket 傳輸立即失敗:** 檢查 `appServer.url`、`authToken`,以及遠端 app-server 是否使用相同的 Codex app-server 協定版本。 +**WebSocket transport 立即失敗:** 檢查 `appServer.url`、`authToken`,以及遠端 app-server 是否使用相同的 Codex app-server 協定版本。 -**非 Codex 模型使用 PI:** 除非你為該代理強制設定 `agentRuntime.id: "codex"`,或選取舊版 `codex/*` 參照,否則這是預期行為。一般 `openai/gpt-*` 和其他供應商參照在 `auto` 模式中會留在其一般供應商路徑上。如果你強制設定 `agentRuntime.id: "codex"`,該代理的每個嵌入式回合都必須是 Codex 支援的 OpenAI 模型。 +**非 Codex 模型使用 PI:** 除非你已為該 agent 強制設定 `agentRuntime.id: "codex"`,或選取舊版 `codex/*` 參照,否則這是預期行為。一般 `openai/gpt-*` 和其他 provider 參照在 `auto` 模式中會留在其一般 provider 路徑。如果你強制設定 `agentRuntime.id: "codex"`,該 agent 的每個嵌入式回合都必須是 Codex 支援的 OpenAI 模型。 -**Computer Use 已安裝但工具未執行:** 從新的工作階段檢查 `/codex computer-use status`。如果工具回報 `Native hook relay unavailable`,請使用 `/new` 或 `/reset`;如果仍然存在,請重新啟動 gateway 以清除過期的原生鉤子註冊。如果 `computer-use.list_apps` 逾時,請重新啟動 Codex Computer Use 或 Codex Desktop,然後重試。 +**Computer Use 已安裝但工具未執行:** 從全新工作階段檢查 `/codex computer-use status`。如果工具回報 `Native hook relay unavailable`,請使用 `/new` 或 `/reset`;如果仍持續發生,請重新啟動 gateway 以清除過期的原生 hook 註冊。如果 `computer-use.list_apps` 逾時,請重新啟動 Codex Computer Use 或 Codex Desktop,然後重試。 ## 相關 -- [代理 harness plugins](/zh-TW/plugins/sdk-agent-harness) -- [代理 runtimes](/zh-TW/concepts/agent-runtimes) -- [模型供應商](/zh-TW/concepts/model-providers) -- [OpenAI 供應商](/zh-TW/providers/openai) -- [狀態](/zh-TW/cli/status) -- [Plugin 鉤子](/zh-TW/plugins/hooks) -- [組態參考](/zh-TW/gateway/configuration-reference) +- [Agent harness plugins](/zh-TW/plugins/sdk-agent-harness) +- [Agent runtimes](/zh-TW/concepts/agent-runtimes) +- [Model providers](/zh-TW/concepts/model-providers) +- [OpenAI provider](/zh-TW/providers/openai) +- [Status](/zh-TW/cli/status) +- [Plugin hooks](/zh-TW/plugins/hooks) +- [設定參考](/zh-TW/gateway/configuration-reference) - [測試](/zh-TW/help/testing-live#live-codex-app-server-harness-smoke) diff --git a/docs/zh-TW/reference/RELEASING.md b/docs/zh-TW/reference/RELEASING.md index c398dd8e3..5c7fd5edd 100644 --- a/docs/zh-TW/reference/RELEASING.md +++ b/docs/zh-TW/reference/RELEASING.md @@ -1,143 +1,146 @@ --- read_when: - - 正在尋找公開發行通道定義 - - 執行發行驗證或套件驗收 + - 正在尋找公開發布通道定義 + - 執行發布驗證或套件驗收 - 尋找版本命名與發布節奏 -summary: 發布路線、操作員檢查清單、驗證環境、版本命名和節奏 +summary: 發布通道、操作員檢查清單、驗證環境、版本命名與節奏 title: 發布政策 x-i18n: - generated_at: "2026-04-30T03:36:16Z" + generated_at: "2026-05-01T02:45:39Z" model: gpt-5.5 provider: openai - source_hash: 54dc9ad7918ac95ec535a0404bbcbc04461a2b977151db0c2039b91e7e69c15c + source_hash: bb56568bf860ba9eae47df71c5c1ebefe9eb9ae05ac4706dbb425772ff6cdcaa source_path: reference/RELEASING.md workflow: 16 --- -OpenClaw 有三個公開發布通道: +OpenClaw 有三個公開發行通道: -- stable:標記的發布版本,預設發布到 npm `beta`,或在明確要求時發布到 npm `latest` -- beta:發布到 npm `beta` 的預發布標籤 -- dev:`main` 的移動前端 +- stable:帶標籤的發行版本,預設發布到 npm `beta`,或在明確要求時發布到 npm `latest` +- beta:發布到 npm `beta` 的預發行標籤 +- dev:`main` 的移動中最新版本 ## 版本命名 -- 穩定發布版本:`YYYY.M.D` +- 穩定版發行版本:`YYYY.M.D` - Git 標籤:`vYYYY.M.D` -- 穩定修正發布版本:`YYYY.M.D-N` +- 穩定版修正版發行版本:`YYYY.M.D-N` - Git 標籤:`vYYYY.M.D-N` -- Beta 預發布版本:`YYYY.M.D-beta.N` +- Beta 預發行版本:`YYYY.M.D-beta.N` - Git 標籤:`vYYYY.M.D-beta.N` - 月份或日期不要補零 -- `latest` 表示目前已提升的穩定 npm 發布版本 +- `latest` 表示目前已推廣的穩定版 npm 發行版本 - `beta` 表示目前的 beta 安裝目標 -- 穩定與穩定修正發布版本預設發布到 npm `beta`;發布操作人員可以明確指定 `latest`,或稍後提升已審核的 beta 建置 -- 每個穩定 OpenClaw 發布版本都會同時交付 npm 套件與 macOS 應用程式; - beta 發布版本通常會先驗證並發布 npm/套件路徑,而 - Mac 應用程式建置/簽署/公證則保留給穩定版本,除非明確要求 +- 穩定版與穩定版修正版發行預設發布到 npm `beta`;發行操作員可以明確指定 `latest`,或稍後推廣已審核的 beta 建置 +- 每個穩定版 OpenClaw 發行都會同時交付 npm 套件與 macOS 應用程式; + beta 發行通常會先驗證並發布 npm/套件路徑,而 + Mac 應用程式的建置/簽署/公證會保留給穩定版,除非明確要求 -## 發布節奏 +## 發行節奏 -- 發布採 beta 優先 -- 穩定版本只會在最新 beta 通過驗證後跟進 -- 維護者通常會從目前 `main` 建立的 `release/YYYY.M.D` 分支切出發布版本, - 讓發布驗證與修正不會阻塞 `main` 上的新開發 -- 如果 beta 標籤已推送或發布且需要修正,維護者會切出下一個 `-beta.N` 標籤, - 而不是刪除或重新建立舊的 beta 標籤 -- 詳細發布程序、核准、憑證與復原注意事項僅限維護者使用 +- 發行採 beta 優先 +- 只有在最新 beta 驗證完成後才會推出穩定版 +- 維護者通常會從目前 `main` 建立的 `release/YYYY.M.D` 分支切出發行版本, + 讓發行驗證與修正不會阻礙 `main` 上的新開發 +- 如果 beta 標籤已推送或發布且需要修正,維護者會切出下一個 `-beta.N` 標籤,而不是刪除或重新建立舊的 beta 標籤 +- 詳細的發行程序、核准、憑證與復原備註 + 僅限維護者使用 -## 發布操作人員檢查清單 +## 發行操作員檢查清單 -此檢查清單是發布流程的公開形式。私人憑證、 -簽署、公證、dist-tag 復原與緊急復原詳細資訊會保留在 -僅限維護者使用的發布操作手冊中。 +此檢查清單是發行流程的公開形式。私有憑證、 +簽署、公證、dist-tag 復原與緊急回滾細節會保留在 +僅限維護者使用的發行執行手冊中。 1. 從目前 `main` 開始:拉取最新內容,確認目標提交已推送, - 並確認目前 `main` CI 的綠燈程度足以從中建立分支。 + 並確認目前 `main` 的 CI 狀態足以從它建立分支。 2. 使用 `/changelog` 依據真實提交歷史重寫最上方的 `CHANGELOG.md` 區段, - 保持項目面向使用者,提交、推送,並在建立分支前再 rebase/pull 一次。 + 保持項目面向使用者,提交、推送,並在建立分支前再次 rebase/pull。 3. 檢閱 `src/plugins/compat/registry.ts` 與 - `src/commands/doctor/shared/deprecation-compat.ts` 中的發布相容性記錄。只有在升級路徑仍受涵蓋時才移除已過期的相容性, - 或記錄為何有意繼續保留。 -4. 從目前 `main` 建立 `release/YYYY.M.D`;不要直接在 `main` 上進行一般發布工作。 -5. 針對預定標籤更新所有必要版本位置,然後執行本機確定性預檢: + `src/commands/doctor/shared/deprecation-compat.ts` 中的發行相容性記錄。只有在升級路徑仍有涵蓋時才移除過期相容性, + 或記錄為何刻意保留。 +4. 從目前 `main` 建立 `release/YYYY.M.D`;不要直接在 `main` 上進行一般發行工作。 +5. 針對預定標籤更新所有必要的版本位置,然後執行 + 本機確定性預檢: `pnpm check:test-types`、`pnpm check:architecture`、 - `pnpm build && pnpm ui:build`,以及 `pnpm release:check`。 -6. 以 `preflight_only=true` 執行 `OpenClaw NPM Release`。在標籤存在之前, - 可使用完整 40 字元的發布分支 SHA 進行僅驗證的預檢。儲存成功的 `preflight_run_id`。 -7. 對發布分支、標籤或完整提交 SHA 啟動 `Full Release Validation`,執行所有發布前測試。這是四個大型發布測試盒的唯一手動入口點:Vitest、Docker、QA Lab 與 Package。 -8. 如果驗證失敗,請在發布分支上修正,並重新執行可證明修正的最小失敗檔案、通道、工作流程作業、套件設定檔、Provider 或模型允許清單。只有在變更範圍使既有證據失效時,才重新執行完整總括流程。 -9. 對 beta,標記 `vYYYY.M.D-beta.N`,使用 npm dist-tag `beta` 發布,然後針對已發布的 `openclaw@YYYY.M.D-beta.N` + `pnpm build && pnpm ui:build` 和 `pnpm release:check`。 +6. 使用 `preflight_only=true` 執行 `OpenClaw NPM Release`。在標籤存在之前, + 可使用完整 40 字元的發行分支 SHA 進行僅驗證的 + 預檢。保存成功的 `preflight_run_id`。 +7. 使用 `Full Release Validation` 針對 + 發行分支、標籤或完整提交 SHA 啟動所有預發行測試。這是四個大型發行測試箱的唯一手動入口點: + Vitest、Docker、QA Lab 和 Package。 +8. 如果驗證失敗,請在發行分支上修正,並重新執行能證明修正的最小失敗 + 檔案、通道、工作流程作業、套件設定檔、Provider 或模型允許清單。 + 只有在變更範圍使先前證據失效時,才重新執行完整總括流程。 +9. 對於 beta,標記 `vYYYY.M.D-beta.N`,以 npm dist-tag `beta` 發布,然後針對已發布的 `openclaw@YYYY.M.D-beta.N` 或 `openclaw@beta` 套件執行發布後套件驗收。如果已推送或已發布的 beta 需要修正, 請切出下一個 `-beta.N`;不要刪除或重寫舊的 beta。 -10. 對穩定版本,只有在已審核的 beta 或候選發布版本具備所需驗證證據後才繼續。 - 穩定 npm 發布會透過 `preflight_run_id` 重用成功的預檢成品;穩定 macOS 發布就緒狀態 - 也需要 `main` 上已有封裝的 `.zip`、`.dmg`、`.dSYM.zip` 與更新後的 +10. 對於穩定版,只有在已審核的 beta 或 release candidate 具備 + 所需驗證證據後才繼續。穩定版 npm 發布會透過 `preflight_run_id` 重用成功的 + 預檢成品;穩定版 macOS 發行準備狀態 + 也需要在 `main` 上具備已封裝的 `.zip`、`.dmg`、`.dSYM.zip` 與更新後的 `appcast.xml`。 -11. 發布後,執行 npm 發布後驗證器;在需要發布後通道證據時,可選擇執行獨立的 - 已發布 npm Telegram E2E;視需要進行 dist-tag 提升;依據完整相符的 `CHANGELOG.md` 區段撰寫 GitHub 發布/預發布說明;並執行發布公告 +11. 發布後,執行 npm 發布後驗證器、需要發布後通道證明時可選的獨立 + 已發布 npm Telegram E2E、 + 必要時的 dist-tag 推廣、來自完整相符 `CHANGELOG.md` 區段的 GitHub release/prerelease notes,以及發行公告 步驟。 -## 發布預檢 +## 發行預檢 -- 在 release preflight 前執行 `pnpm check:test-types`,讓測試 TypeScript 在較快的本機 `pnpm check` gate 外仍受到涵蓋 -- 在 release preflight 前執行 `pnpm check:architecture`,讓較廣泛的 import cycle 與架構邊界檢查在較快的本機 gate 外維持綠燈 -- 在 `pnpm release:check` 前執行 `pnpm build && pnpm ui:build`,讓預期的 `dist/*` 發行成品與控制 UI bundle 存在,可供 pack 驗證步驟使用 -- 在 release 核准前執行手動 `Full Release Validation` workflow,以從單一進入點啟動所有 pre-release test boxes。它接受 branch、tag 或完整 commit SHA,會 dispatch 手動 `CI`,並 dispatch `OpenClaw Release Checks`,涵蓋 install smoke、package acceptance、Docker release-path suites、live/E2E、OpenWebUI、QA Lab parity、Matrix 與 Telegram lanes。只有在 package 已發布且 post-publish Telegram E2E 也應執行時,才提供 `npm_telegram_package_spec`。當 private evidence report 應證明該驗證符合已發布的 npm package,但不強制執行 Telegram E2E 時,提供 `evidence_package_spec`。 - 範例: - `gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D` -- 當你想在 release 工作繼續時,為 package candidate 取得 side-channel proof,請執行手動 `Package Acceptance` workflow。針對 `openclaw@beta`、`openclaw@latest` 或精確 release version 使用 `source=npm`;使用 `source=ref` 搭配目前 `workflow_ref` harness 來 pack 受信任的 `package_ref` branch/tag/SHA;針對需要 SHA-256 的 HTTPS tarball 使用 `source=url`;或針對由另一個 GitHub Actions run 上傳的 tarball 使用 `source=artifact`。workflow 會將 candidate 解析為 `package-under-test`,針對該 tarball 重複使用 Docker E2E release scheduler,並可使用 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier` 對同一個 tarball 執行 Telegram QA。 - 範例:`gh workflow run package-acceptance.yml --ref main -f workflow_ref=main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product -f telegram_mode=mock-openai` - 常見 profiles: - - `smoke`:install/channel/agent、gateway network 與 config reload lanes - - `package`:artifact-native package/update/plugin lanes,不含 OpenWebUI 或 live ClawHub - - `product`:package profile 加上 MCP channels、cron/subagent cleanup、OpenAI web search 與 OpenWebUI - - `full`:含 OpenWebUI 的 Docker release-path chunks - - `custom`:針對聚焦 rerun 的精確 `docker_lanes` 選擇 -- 當你只需要 release candidate 的完整一般 CI 覆蓋時,直接執行手動 `CI` workflow。手動 CI dispatch 會繞過 changed scoping,並強制執行 Linux Node shards、bundled-plugin shards、channel contracts、Node 22 compatibility、`check`、`check-additional`、build smoke、docs checks、Python skills、Windows、macOS、Android 與控制 UI i18n lanes。 - 範例:`gh workflow run ci.yml --ref release/YYYY.M.D` -- 驗證 release telemetry 時執行 `pnpm qa:otel:smoke`。它會透過本機 OTLP/HTTP receiver exercise QA-lab,並驗證匯出的 trace span names、bounded attributes 與 content/identifier redaction,不需要 Opik、Langfuse 或其他外部 collector。 -- 每次 tagged release 前執行 `pnpm release:check` -- Release checks 現在會在獨立的手動 workflow 中執行: - `OpenClaw Release Checks` -- `OpenClaw Release Checks` 也會在 release approval 前執行 QA Lab mock parity gate,加上快速 live Matrix profile 與 Telegram QA lane。live lanes 使用 `qa-live-shared` environment;Telegram 也使用 Convex CI credential leases。當你想平行取得完整 Matrix transport、media 與 E2EE inventory 時,使用 `matrix_profile=all` 與 `matrix_shards=true` 執行手動 `QA-Lab - All Lanes` workflow。 -- Cross-OS install 與 upgrade runtime validation 是公開 `OpenClaw Release Checks` 與 `Full Release Validation` 的一部分,它們會直接呼叫 reusable workflow `.github/workflows/openclaw-cross-os-release-checks-reusable.yml` -- 這種拆分是有意的:保持真正的 npm release path 短小、deterministic 且專注於 artifact,同時讓較慢的 live checks 留在自己的 lane 中,避免拖慢或阻塞 publish -- 帶有 secret 的 release checks 應透過 `Full Release Validation` dispatch,或從 `main`/release workflow ref dispatch,讓 workflow logic 與 secrets 維持受控 -- 只要 resolved commit 可從 OpenClaw branch 或 release tag 抵達,`OpenClaw Release Checks` 就接受 branch、tag 或完整 commit SHA -- `OpenClaw NPM Release` validation-only preflight 也接受目前完整 40 字元 workflow-branch commit SHA,不需要 pushed tag -- 該 SHA path 只供 validation 使用,不能提升為真正 publish -- 在 SHA mode 中,workflow 只會為 package metadata check 合成 `v`;真正 publish 仍需要真正的 release tag -- 兩個 workflow 都讓真正 publish 與 promotion path 留在 GitHub-hosted runners 上,而 non-mutating validation path 可使用較大的 Blacksmith Linux runners +- 在發行預檢前執行 `pnpm check:test-types`,讓測試 TypeScript 在較快的本機 `pnpm check` 門檻之外仍保持涵蓋 +- 在發行預檢前執行 `pnpm check:architecture`,讓更廣泛的匯入循環與架構邊界檢查在較快的本機門檻之外也能維持綠燈 +- 在 `pnpm release:check` 前執行 `pnpm build && pnpm ui:build`,讓預期的 `dist/*` 發行成品與 Control UI bundle 存在,以供打包驗證步驟使用 +- 在核准發行前執行手動 `Full Release Validation` workflow,從單一入口點啟動所有發行前測試盒。它接受分支、標籤或完整 commit SHA,會派發手動 `CI`,並派發 `OpenClaw Release Checks` 以涵蓋安裝 smoke、套件驗收、Docker 發行路徑套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 與 Telegram lanes。只有在套件已發布且也應執行發布後 Telegram E2E 時,才提供 `npm_telegram_package_spec`。當私有證據報告應證明該驗證符合已發布的 npm 套件,但不強制執行 Telegram E2E 時,請提供 `evidence_package_spec`。範例:`gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D` +- 當你想在發行工作繼續進行時,為套件候選版本取得旁路證明,請執行手動 `Package Acceptance` workflow。對 `openclaw@beta`、`openclaw@latest` 或精確發行版本使用 `source=npm`;使用 `source=ref` 以目前的 `workflow_ref` harness 打包受信任的 `package_ref` 分支/標籤/SHA;使用 `source=url` 處理需要 SHA-256 的 HTTPS tarball;或使用 `source=artifact` 處理由另一個 GitHub Actions run 上傳的 tarball。此 workflow 會將候選版本解析為 `package-under-test`,對該 tarball 重用 Docker E2E 發行排程器,並可用 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier` 對同一 tarball 執行 Telegram QA。範例:`gh workflow run package-acceptance.yml --ref main -f workflow_ref=main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product -f telegram_mode=mock-openai` + 常見 profile: + - `smoke`:安裝/channel/agent、Gateway 網路與設定重新載入 lanes + - `package`:artifact 原生的套件/更新/Plugin lanes,不含 OpenWebUI 或 live ClawHub + - `product`:package profile 加上 MCP channels、cron/subagent 清理、OpenAI 網頁搜尋與 OpenWebUI + - `full`:含 OpenWebUI 的 Docker 發行路徑分塊 + - `custom`:用於聚焦重跑的精確 `docker_lanes` 選擇 +- 當你只需要發行候選版本的完整一般 CI 涵蓋時,請直接執行手動 `CI` workflow。手動 CI 派發會略過 changed scoping,並強制執行 Linux Node shards、bundled-Plugin shards、channel contracts、Node 22 相容性、`check`、`check-additional`、build smoke、文件檢查、Python skills、Windows、macOS、Android 與 Control UI i18n lanes。範例:`gh workflow run ci.yml --ref release/YYYY.M.D` +- 驗證發行遙測時執行 `pnpm qa:otel:smoke`。它會透過本機 OTLP/HTTP receiver 演練 QA-lab,並驗證匯出的 trace span 名稱、受限屬性,以及內容/識別碼遮蔽,不需要 Opik、Langfuse 或其他外部 collector。 +- 每次標記發行前執行 `pnpm release:check` +- 發行檢查現在在獨立的手動 workflow 中執行:`OpenClaw Release Checks` +- `OpenClaw Release Checks` 也會在核准發行前執行 QA Lab mock parity gate,加上快速 live Matrix profile 與 Telegram QA lane。live lanes 使用 `qa-live-shared` environment;Telegram 也使用 Convex CI credential leases。當你想平行取得完整 Matrix 傳輸、媒體與 E2EE inventory 時,請使用 `matrix_profile=all` 與 `matrix_shards=true` 執行手動 `QA-Lab - All Lanes` workflow。 +- 跨作業系統安裝與升級執行階段驗證是公開 `OpenClaw Release Checks` 與 `Full Release Validation` 的一部分,兩者會直接呼叫 reusable workflow `.github/workflows/openclaw-cross-os-release-checks-reusable.yml` +- 這項拆分是刻意設計的:讓真正的 npm 發行路徑保持短小、可決定且以 artifact 為中心,同時讓較慢的 live 檢查留在自己的 lane 中,避免拖慢或阻擋發布 +- 帶有 secret 的發行檢查應透過 `Full Release Validation` 派發,或從 `main`/release workflow ref 派發,讓 workflow 邏輯與 secrets 保持受控 +- `OpenClaw Release Checks` 接受分支、標籤或完整 commit SHA,只要解析後的 commit 可從 OpenClaw 分支或發行標籤到達 +- `OpenClaw NPM Release` 僅驗證預檢也接受目前完整 40 字元的 workflow 分支 commit SHA,不需要已推送標籤 +- 該 SHA 路徑僅限驗證,不能升級為真正發布 +- 在 SHA 模式中,workflow 只會為套件 metadata 檢查合成 `v`;真正發布仍需要真正的發行標籤 +- 兩個 workflow 都會讓真正的發布與推廣路徑保留在 GitHub-hosted runners 上,而非變更性驗證路徑可以使用較大的 Blacksmith Linux runners - 該 workflow 會使用 `OPENAI_API_KEY` 與 `ANTHROPIC_API_KEY` workflow secrets 執行 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache` -- npm release preflight 不再等待獨立的 release checks lane -- 核准前執行 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`(或對應的 beta/correction tag) -- npm publish 後,執行 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(或對應的 beta/correction version),在全新 temp prefix 中驗證已發布的 registry install path -- beta publish 後,執行 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`,使用 shared leased Telegram credential pool,針對已發布的 npm package 驗證 installed-package onboarding、Telegram setup 與真實 Telegram E2E。本機 maintainer 一次性操作可省略 Convex vars,並直接傳入三個 `OPENCLAW_QA_TELEGRAM_*` env credentials。 -- Maintainers 可透過手動 `NPM Telegram Beta E2E` workflow,從 GitHub Actions 執行相同的 post-publish check。它刻意只允許手動執行,不會在每次 merge 時執行。 -- Maintainer release automation 現在使用 preflight-then-promote: - - 真正的 npm publish 必須通過成功的 npm `preflight_run_id` - - 真正的 npm publish 必須從與成功 preflight run 相同的 `main` 或 `release/YYYY.M.D` branch dispatch - - stable npm releases 預設為 `beta` - - stable npm publish 可透過 workflow input 明確指定 `latest` - - token-based npm dist-tag mutation 現在位於 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`,以提升安全性,因為 `npm dist-tag add` 仍需要 `NPM_TOKEN`,而 public repo 保持 OIDC-only publish - - public `macOS Release` 僅供 validation - - 真正的 private mac publish 必須通過成功的 private mac `preflight_run_id` 與 `validate_run_id` - - 真正的 publish paths 會 promote prepared artifacts,而不是再次 rebuild 它們 -- 對於 `YYYY.M.D-N` 這類 stable correction releases,post-publish verifier 也會檢查從 `YYYY.M.D` 到 `YYYY.M.D-N` 的相同 temp-prefix upgrade path,讓 release corrections 不會悄悄讓較舊的 global installs 停留在 base stable payload -- npm release preflight 會 fail closed,除非 tarball 同時包含 `dist/control-ui/index.html` 與非空的 `dist/control-ui/assets/` payload,這樣我們才不會再次發布空的瀏覽器 dashboard -- Post-publish verification 也會檢查已發布的 registry install 是否在 root `dist/*` layout 下包含非空的 bundled plugin runtime deps。若 release 發布時缺少或空的 bundled plugin dependency payloads,postpublish verifier 會失敗,且不能 promote 至 `latest`。 -- `pnpm test:install:smoke` 也會對 candidate update tarball 強制執行 npm pack `unpackedSize` budget,因此 installer e2e 會在 release publish path 前捕捉意外的 pack bloat -- 如果 release 工作碰到 CI planning、extension timing manifests 或 extension test matrices,請在 approval 前重新生成並審查 planner-owned 的 `plugin-prerelease-extension-shard` matrix outputs,來源為 `.github/workflows/plugin-prerelease.yml`,讓 release notes 不會描述過期的 CI layout -- Stable macOS release readiness 也包含 updater surfaces: - - GitHub release 最終必須包含 packaged `.zip`、`.dmg` 與 `.dSYM.zip` - - publish 後,`main` 上的 `appcast.xml` 必須指向新的 stable zip - - packaged app 必須維持 non-debug bundle id、非空 Sparkle feed URL,以及高於或等於該 release version canonical Sparkle build floor 的 `CFBundleVersion` +- npm 發行預檢不再等待獨立的發行檢查 lane +- 核准前執行 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`(或相符的 beta/correction 標籤) +- npm 發布後,執行 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(或相符的 beta/correction 版本),以在全新的暫存 prefix 中驗證已發布 registry 的安裝路徑 +- beta 發布後,執行 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`,使用共用的租用 Telegram credential pool,針對已發布的 npm 套件驗證已安裝套件的 onboarding、Telegram 設定,以及真實 Telegram E2E。本機 maintainer 的一次性作業可以省略 Convex vars,並直接傳入三個 `OPENCLAW_QA_TELEGRAM_*` env credentials。 +- Maintainer 可以透過手動 `NPM Telegram Beta E2E` workflow,在 GitHub Actions 中執行相同的發布後檢查。它刻意設為僅手動執行,不會在每次 merge 時執行。 +- Maintainer 發行自動化現在使用 preflight-then-promote: + - 真正的 npm 發布必須通過成功的 npm `preflight_run_id` + - 真正的 npm 發布必須從與成功預檢 run 相同的 `main` 或 `release/YYYY.M.D` 分支派發 + - stable npm 發行預設為 `beta` + - stable npm 發布可透過 workflow input 明確指定 `latest` + - 基於 token 的 npm dist-tag 變更現在位於 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`,以提升安全性,因為 `npm dist-tag add` 仍需要 `NPM_TOKEN`,而公開 repo 保持僅 OIDC 發布 + - 公開 `macOS Release` 僅供驗證;當標籤只存在於發行分支,但 workflow 從 `main` 派發時,請設定 `public_release_branch=release/YYYY.M.D` + - 真正的私有 mac 發布必須通過成功的私有 mac `preflight_run_id` 與 `validate_run_id` + - 真正的發布路徑會推廣已準備好的 artifact,而不是再次重建 +- 對於像 `YYYY.M.D-N` 這類 stable correction 發行,發布後 verifier 也會檢查從 `YYYY.M.D` 到 `YYYY.M.D-N` 的相同暫存 prefix 升級路徑,讓發行修正不會在無聲中讓較舊的全域安裝停留在基礎 stable payload +- npm 發行預檢會 fail closed,除非 tarball 同時包含 `dist/control-ui/index.html` 與非空的 `dist/control-ui/assets/` payload,這樣我們才不會再次發布空的瀏覽器 dashboard +- 發布後驗證也會檢查已發布 registry 安裝是否在 root `dist/*` 佈局下包含非空的 bundled Plugin runtime deps。若發行缺少或帶有空的 bundled Plugin dependency payload,postpublish verifier 會失敗,且不能推廣到 `latest`。 +- `pnpm test:install:smoke` 也會對候選更新 tarball 強制執行 npm pack `unpackedSize` 預算,因此 installer e2e 會在發行發布路徑前抓到意外的打包膨脹 +- 如果發行工作觸及 CI 規劃、extension timing manifests 或 extension test matrices,請在核准前重新產生並檢閱 planner 擁有的 `plugin-prerelease-extension-shard` matrix outputs,來源為 `.github/workflows/plugin-prerelease.yml`,讓發行說明不會描述過時的 CI 佈局 +- Stable macOS 發行就緒度也包含 updater surfaces: + - GitHub release 最終必須包含已打包的 `.zip`、`.dmg` 與 `.dSYM.zip` + - `appcast.xml` 在 `main` 上必須在發布後指向新的 stable zip + - 已打包的 app 必須維持非 debug bundle id、非空的 Sparkle feed URL,以及等於或高於該發行版本 canonical Sparkle build floor 的 `CFBundleVersion` -## Release test boxes +## 發行測試盒 -`Full Release Validation` 是 operators 從單一進入點啟動所有 pre-release tests 的方式。請從受信任的 `main` workflow ref 執行,並將 release branch、tag 或完整 commit SHA 作為 `ref` 傳入: +`Full Release Validation` 是 operators 從單一入口點啟動所有發行前測試的方式。從受信任的 `main` workflow ref 執行它,並將發行分支、標籤或完整 commit SHA 作為 `ref` 傳入: ```bash gh workflow run full-release-validation.yml \ @@ -145,23 +148,22 @@ gh workflow run full-release-validation.yml \ -f ref=release/YYYY.M.D \ -f provider=openai \ -f mode=both \ - -f release_profile=full \ + -f release_profile=stable \ -f evidence_package_spec=openclaw@YYYY.M.D-beta.N ``` -workflow 會解析 target ref,dispatch 帶有 `target_ref=` 的手動 `CI`,dispatch `OpenClaw Release Checks`,並在設定 `npm_telegram_package_spec` 時,選擇性 dispatch standalone post-publish Telegram E2E。`OpenClaw Release Checks` 接著會展開 install smoke、cross-OS release checks、live/E2E Docker release-path coverage、含 Telegram package QA 的 Package Acceptance、QA Lab parity、live Matrix 與 live Telegram。只有當 `Full Release Validation` summary 顯示 `normal_ci` 與 `release_checks` 成功,且任何選用的 `npm_telegram` child 成功或刻意略過時,full run 才可接受。最終 verifier summary 會包含每個 child run 的 slowest-job tables,讓 release manager 不必下載 logs 就能看見目前的 critical path。 -Child workflows 會從執行 `Full Release Validation` 的受信任 ref dispatch,通常是 `--ref main`,即使 target `ref` 指向較舊的 release branch 或 tag。沒有獨立的 Full Release Validation workflow-ref input;請透過選擇 workflow run ref 來選擇受信任的 harness。 +該 workflow 會解析目標 ref,使用 `target_ref=` 派發手動 `CI`,派發 `OpenClaw Release Checks`,並在設定 `npm_telegram_package_spec` 時選擇性派發獨立的發布後 Telegram E2E。`OpenClaw Release Checks` 接著會展開安裝 smoke、跨作業系統發行檢查、live/E2E Docker 發行路徑涵蓋、含 Telegram 套件 QA 的 Package Acceptance、QA Lab parity、live Matrix 與 live Telegram。只有當 `Full Release Validation` 摘要顯示 `normal_ci` 與 `release_checks` 成功,且任何選用的 `npm_telegram` child 成功或刻意略過時,完整 run 才可接受。最終 verifier 摘要包含每個 child run 的最慢 job 表格,讓 release manager 不必下載 logs 就能看到目前的關鍵路徑。完整 stage matrix、精確 workflow job 名稱、stable 與 full profile 差異、artifacts 與聚焦重跑 handles,請參閱[完整發行驗證](/zh-TW/reference/full-release-validation)。 +Child workflows 會從執行 `Full Release Validation` 的受信任 ref 派發,通常是 `--ref main`,即使目標 `ref` 指向較舊的發行分支或標籤。沒有獨立的 Full Release Validation workflow-ref input;請透過選擇 workflow run ref 來選擇受信任的 harness。 -使用 `release_profile` 選擇 live/provider breadth: +使用 `release_profile` 選擇 live/provider 廣度: -- `minimum`:最快的 release-critical OpenAI/core live 與 Docker path -- `stable`:minimum 加上 release approval 所需的 stable provider/backend coverage -- `full`:stable 加上廣泛 advisory provider/media coverage +- `minimum`:最快的發行關鍵 OpenAI/core live 與 Docker 路徑 +- `stable`:minimum 加上用於發行核准的 stable provider/backend 涵蓋 +- `full`:stable 加上廣泛的 advisory provider/media 涵蓋 -`OpenClaw Release Checks` 使用受信任 workflow ref,將 target ref 解析一次為 `release-package-under-test`,並在 release-path Docker checks 與 Package Acceptance 中重複使用該 artifact。這會讓所有 package-facing boxes 使用相同 bytes,並避免重複 package builds。 -當 repo/org variable 已設定時,cross-OS OpenAI install smoke 會使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否則使用 `openai/gpt-5.4-mini`,因為此 lane 是在證明 package install、onboarding、gateway startup 與一次 live agent turn,而不是 benchmark 最慢的 default model。較廣泛的 live provider matrix 仍是 model-specific coverage 的位置。 +`OpenClaw Release Checks` 使用受信任的 workflow ref,將目標 ref 解析一次為 `release-package-under-test`,並在發行路徑 Docker 檢查與 Package Acceptance 中重用該 artifact。這讓所有面向套件的 boxes 都使用相同 bytes,並避免重複建置套件。跨作業系統 OpenAI 安裝 smoke 在 repo/org 變數已設定時使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否則使用 `openai/gpt-5.4-mini`,因為此 lane 是在證明套件安裝、onboarding、Gateway 啟動與一次 live agent turn,而不是 benchmark 最慢的預設模型。更廣泛的 live provider matrix 仍然是模型特定涵蓋的所在位置。 -依 release stage 使用這些 variants: +請依發行階段使用這些變體: ```bash # Validate an unpublished release candidate branch. @@ -190,22 +192,22 @@ gh workflow run full-release-validation.yml \ -f npm_telegram_provider_mode=mock-openai ``` -不要在專注修正後的第一次重新執行時使用完整總括流程。如果其中一個方塊失敗,請使用失敗的子工作流程、作業、Docker 通道、套件設定檔、模型提供者或 QA 通道作為下一個驗證。只有當修正變更了共用發布編排,或使先前的全方塊證據過期時,才再次執行完整總括流程。總括流程的最終驗證器會重新檢查已記錄的子工作流程執行 ID,因此在子工作流程成功重新執行後,只需重新執行失敗的 `Verify full validation` 父作業。 +不要把完整總控流程用作專注修正後的第一次重新執行。如果某個檢查箱失敗,下一次驗證請使用失敗的子工作流程、作業、Docker lane、套件設定檔、模型提供者或 QA lane。只有在修正變更了共用發布編排,或讓先前的全檢查箱證據過期時,才再次執行完整總控流程。總控流程的最終驗證器會重新檢查記錄的子工作流程執行 ID,因此子工作流程成功重新執行後,只需重新執行失敗的 `Verify full validation` 父作業。 -若要進行有界復原,請將 `rerun_group` 傳給總括流程。`all` 是實際的發布候選執行,`ci` 只執行一般 CI 子項,`plugin-prerelease` 只執行僅限發布的 Plugin 子項,`release-checks` 會執行每個發布方塊,而較窄的發布群組則是 `install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live`,以及在提供獨立套件 Telegram 通道時使用的 `npm-telegram`。 +若要進行有界復原,請將 `rerun_group` 傳給總控流程。`all` 是真正的發布候選執行,`ci` 只執行一般 CI 子流程,`plugin-prerelease` 只執行僅發布用的 Plugin 子流程,`release-checks` 會執行每個發布檢查箱,而更窄的發布群組是 `install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live`,以及在提供獨立套件 Telegram lane 時的 `npm-telegram`。 ### Vitest -Vitest 方塊是手動 `CI` 子工作流程。手動 CI 會刻意略過變更範圍判定,並強制對發布候選執行一般測試圖:Linux Node 分片、內建 Plugin 分片、頻道合約、Node 22 相容性、`check`、`check-additional`、建置冒煙、文件檢查、Python Skills、Windows、macOS、Android,以及 Control UI i18n。 +Vitest 檢查箱是手動 `CI` 子工作流程。手動 CI 會刻意略過變更範圍限定,並針對發布候選強制執行一般測試圖:Linux Node 分片、 bundled-Plugin 分片、頻道合約、Node 22 相容性、`check`、`check-additional`、建置 smoke、文件檢查、Python Skills、Windows、macOS、Android,以及 Control UI i18n。 -使用此方塊回答「原始碼樹是否通過完整的一般測試套件?」它不等同於發布路徑產品驗證。要保留的證據: +使用此檢查箱回答「原始碼樹是否通過完整的一般測試套件?」它不同於發布路徑的產品驗證。需保留的證據: -- 顯示已分派 `CI` 執行 URL 的 `Full Release Validation` 摘要 -- `CI` 在確切目標 SHA 上通過 +- `Full Release Validation` 摘要,顯示已派發的 `CI` 執行 URL +- `CI` 在精確目標 SHA 上通過 - 調查迴歸時,來自 CI 作業的失敗或緩慢分片名稱 -- 當執行需要效能分析時,Vitest 計時成品,例如 `.artifacts/vitest-shard-timings.json` +- 需要效能分析時的 Vitest 計時成品,例如 `.artifacts/vitest-shard-timings.json` -只有當發布需要決定性的一般 CI,但不需要 Docker、QA Lab、即時、跨 OS 或套件方塊時,才直接執行手動 CI: +只有在發布需要確定性的一般 CI,但不需要 Docker、QA Lab、live、跨 OS 或套件檢查箱時,才直接執行手動 CI: ```bash gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D @@ -213,50 +215,50 @@ gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D ### Docker -Docker 方塊位於 `OpenClaw Release Checks` 中,透過 `openclaw-live-and-e2e-checks-reusable.yml`,再加上發布模式的 `install-smoke` 工作流程。它會透過封裝後的 Docker 環境驗證發布候選,而不只是原始碼層級測試。 +Docker 檢查箱位於 `OpenClaw Release Checks` 中,透過 `openclaw-live-and-e2e-checks-reusable.yml` 加上發布模式的 `install-smoke` 工作流程。它會透過封裝後的 Docker 環境驗證發布候選,而不只是原始碼層級測試。 -發布 Docker 覆蓋範圍包含: +發布 Docker 覆蓋範圍包括: -- 啟用緩慢 Bun 全域安裝冒煙的完整安裝冒煙 -- 依目標 SHA 準備/重用根 Dockerfile 冒煙映像,並以個別 install-smoke 分片執行 QR、root/gateway,以及 installer/Bun 冒煙作業 -- 儲存庫 E2E 通道 +- 啟用緩慢 Bun 全域安裝 smoke 的完整安裝 smoke +- 依目標 SHA 準備/重用 root Dockerfile smoke 映像,並將 QR、root/Gateway,以及安裝器/Bun smoke 作業作為獨立的 install-smoke 分片執行 +- 儲存庫 E2E lane - 發布路徑 Docker 區塊:`core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a`、`plugins-runtime-install-b`、`plugins-runtime-install-c`、`plugins-runtime-install-d`、`plugins-runtime-install-e`、`plugins-runtime-install-f`、`plugins-runtime-install-g`、`plugins-runtime-install-h`、`bundled-channels-core`、`bundled-channels-update-a`、`bundled-channels-update-discord`、`bundled-channels-update-b`,以及 `bundled-channels-contracts` -- 請求時,在 `plugins-runtime-services` 區塊內的 OpenWebUI 覆蓋範圍 -- 將內建頻道相依性通道拆分為 channel-smoke、update-target,以及 setup/runtime 合約區塊,而不是一個大型內建頻道作業 -- 拆分內建 Plugin 安裝/解除安裝通道 `bundled-plugin-install-uninstall-0` 到 `bundled-plugin-install-uninstall-23` -- 當發布檢查包含即時套件時的即時/E2E 提供者套件與 Docker 即時模型覆蓋範圍 +- 要求時,`plugins-runtime-services` 區塊內的 OpenWebUI 覆蓋 +- 將 bundled-channel 依賴 lane 拆分到 channel-smoke、update-target,以及設定/執行階段合約區塊,而不是一個大型 bundled-channel 作業 +- 拆分 bundled Plugin 安裝/解除安裝 lane,從 `bundled-plugin-install-uninstall-0` 到 `bundled-plugin-install-uninstall-23` +- 當發布檢查包含 live 套件時,包含 live/E2E 提供者套件與 Docker live 模型覆蓋 -重新執行前先使用 Docker 成品。發布路徑排程器會上傳 `.artifacts/docker-tests/`,其中包含通道記錄、`summary.json`、`failures.json`、階段計時、排程器計畫 JSON,以及重新執行命令。若要進行專注復原,請在可重用即時/E2E 工作流程上使用 `docker_lanes=`,而不是重新執行所有發布區塊。產生的重新執行命令會在可用時包含先前的 `package_artifact_run_id` 和已準備的 Docker 映像輸入,因此失敗的通道可以重用相同的 tarball 和 GHCR 映像。 +重新執行前先使用 Docker 成品。發布路徑排程器會上傳 `.artifacts/docker-tests/`,其中包含 lane 日誌、`summary.json`、`failures.json`、階段計時、排程器計畫 JSON,以及重新執行命令。若要專注復原,請在可重用 live/E2E 工作流程上使用 `docker_lanes=`,而不是重新執行所有發布區塊。產生的重新執行命令會在可用時包含先前的 `package_artifact_run_id` 和已準備的 Docker 映像輸入,因此失敗 lane 可重用相同 tarball 和 GHCR 映像。 ### QA Lab -QA Lab 方塊也是 `OpenClaw Release Checks` 的一部分。它是代理行為與頻道層級的發布閘門,獨立於 Vitest 和 Docker 套件機制。 +QA Lab 檢查箱也是 `OpenClaw Release Checks` 的一部分。它是代理式行為與頻道層級的發布閘門,獨立於 Vitest 和 Docker 套件機制。 -發布 QA Lab 覆蓋範圍包含: +發布 QA Lab 覆蓋範圍包括: -- 使用代理同等性套件,比較 OpenAI 候選通道與 Opus 4.6 基準線的模擬同等性閘門 -- 使用 `qa-live-shared` 環境的快速即時 Matrix QA 設定檔 -- 使用 Convex CI 認證租約的即時 Telegram QA 通道 -- 當發布遙測需要明確本機證據時的 `pnpm qa:otel:smoke` +- 使用代理式 parity pack,比較 OpenAI 候選 lane 與 Opus 4.6 基準的 mock parity gate +- 使用 `qa-live-shared` 環境的快速 live Matrix QA 設定檔 +- 使用 Convex CI 憑證租約的 live Telegram QA lane +- 當發布遙測需要明確本機證據時,執行 `pnpm qa:otel:smoke` -使用此方塊回答「發布在 QA 情境和即時頻道流程中是否行為正確?」核准發布時,請保留同等性、Matrix 和 Telegram 通道的成品 URL。完整 Matrix 覆蓋範圍仍可作為手動分片 QA-Lab 執行使用,而不是預設的發布關鍵通道。 +使用此檢查箱回答「此發布在 QA 情境和 live 頻道流程中是否行為正確?」核准發布時,請保留 parity、Matrix 和 Telegram lane 的成品 URL。完整 Matrix 覆蓋仍可作為手動分片 QA-Lab 執行使用,而不是預設的發布關鍵 lane。 ### 套件 -套件方塊是可安裝產品閘門。它由 `Package Acceptance` 和解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支援。解析器會將候選正規化為 Docker E2E 使用的 `package-under-test` tarball、驗證套件清單、記錄套件版本與 SHA-256,並讓工作流程工具參考與套件來源參考保持分離。 +套件檢查箱是可安裝產品的閘門。它由 `Package Acceptance` 與解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支援。解析器會將候選正規化為 Docker E2E 使用的 `package-under-test` tarball、驗證套件清單、記錄套件版本與 SHA-256,並讓工作流程 harness ref 與套件原始碼 ref 保持分離。 支援的候選來源: -- `source=npm`:`openclaw@beta`、`openclaw@latest`,或確切的 OpenClaw 發布版本 -- `source=ref`:使用所選的 `workflow_ref` 工具封裝受信任的 `package_ref` 分支、標籤或完整提交 SHA +- `source=npm`:`openclaw@beta`、`openclaw@latest`,或精確的 OpenClaw 發布版本 +- `source=ref`:使用選定的 `workflow_ref` harness 封裝受信任的 `package_ref` 分支、標籤或完整 commit SHA - `source=url`:下載需要 `package_sha256` 的 HTTPS `.tgz` -- `source=artifact`:重用另一個 GitHub Actions 執行所上傳的 `.tgz` +- `source=artifact`:重用另一個 GitHub Actions 執行上傳的 `.tgz` -`OpenClaw Release Checks` 會以 `source=ref`、`package_ref=`、`suite_profile=custom`、`docker_lanes=bundled-channel-deps-compat plugins-offline`,以及 `telegram_mode=mock-openai` 執行 Package Acceptance。發布路徑 Docker 區塊涵蓋重疊的安裝、更新和 Plugin 更新通道;Package Acceptance 會針對相同解析後的 tarball 保留成品原生的內建頻道相容性、離線 Plugin 夾具,以及 Telegram 套件 QA。它是大多數先前需要 Parallels 的套件/更新覆蓋範圍的 GitHub 原生替代方案。跨 OS 發布檢查對 OS 特定的上線、安裝程式和平台行為仍然重要,但套件/更新產品驗證應優先使用 Package Acceptance。 +`OpenClaw Release Checks` 會以 `source=ref`、`package_ref=`、`suite_profile=custom`、`docker_lanes=bundled-channel-deps-compat plugins-offline`,以及 `telegram_mode=mock-openai` 執行 Package Acceptance。發布路徑 Docker 區塊會涵蓋重疊的安裝、更新與 Plugin 更新 lane;Package Acceptance 會保留成品原生 bundled-channel 相容性、離線 Plugin 夾具,以及針對同一個已解析 tarball 的 Telegram 套件 QA。它是先前大多需要 Parallels 的套件/更新覆蓋之 GitHub 原生替代方案。跨 OS 發布檢查對於 OS 特定的 onboarding、安裝器與平台行為仍然重要,但套件/更新產品驗證應優先使用 Package Acceptance。 -舊版 package-acceptance 寬容度是刻意限時的。到 `2026.4.25` 為止的套件,可針對已發布到 npm 的中繼資料缺口使用相容性路徑:tarball 中缺少私有 QA 清單項目、缺少 `gateway install --wrapper`、tarball 衍生 git 夾具中缺少修補檔、缺少持久化的 `update.channel`、舊版 Plugin 安裝記錄位置、缺少市集安裝記錄持久化,以及 `plugins update` 期間的設定中繼資料遷移。已發布的 `2026.4.26` 套件可能會針對已出貨的本機建置中繼資料戳記檔發出警告。之後的套件必須符合現代套件合約;相同缺口會導致發布驗證失敗。 +舊版 package-acceptance 寬容性刻意有時間限制。到 `2026.4.25` 為止的套件,可針對已發布到 npm 的中繼資料缺口使用相容路徑:tarball 中缺少私有 QA 清單項目、缺少 `gateway install --wrapper`、tarball 衍生 git 夾具中缺少 patch 檔案、缺少已保存的 `update.channel`、舊版 Plugin 安裝記錄位置、缺少 marketplace 安裝記錄持久化,以及 `plugins update` 期間的設定中繼資料遷移。已發布的 `2026.4.26` 套件可針對已出貨的本機建置中繼資料戳記檔案發出警告。較新的套件必須滿足現代套件合約;那些相同缺口會導致發布驗證失敗。 -當發布問題關於實際可安裝套件時,請使用較廣的 Package Acceptance 設定檔: +當發布問題與實際可安裝套件有關時,使用更廣的 Package Acceptance 設定檔: ```bash gh workflow run package-acceptance.yml \ @@ -269,56 +271,54 @@ gh workflow run package-acceptance.yml \ 常見套件設定檔: -- `smoke`:快速套件安裝/頻道/代理、Gateway 網路,以及設定重新載入通道 -- `package`:不含即時 ClawHub 的安裝/更新/Plugin 套件合約;這是 release-check 預設值 -- `product`:`package` 加上 MCP 頻道、cron/子代理清理、OpenAI 網頁搜尋,以及 OpenWebUI +- `smoke`:快速套件安裝/頻道/代理、Gateway 網路,以及設定重新載入 lane +- `package`:不含 live ClawHub 的安裝/更新/Plugin 套件合約;這是 release-check 預設值 +- `product`:`package` 加上 MCP 頻道、cron/subagent 清理、OpenAI 網頁搜尋,以及 OpenWebUI - `full`:含 OpenWebUI 的 Docker 發布路徑區塊 -- `custom`:用於專注重新執行的確切 `docker_lanes` 清單 +- `custom`:用於專注重新執行的精確 `docker_lanes` 清單 -若要提供套件候選 Telegram 證據,請在 Package Acceptance 上啟用 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier`。工作流程會將解析後的 `package-under-test` tarball 傳入 Telegram 通道;獨立 Telegram 工作流程仍接受已發布的 npm 規格,用於發布後檢查。 +若要進行套件候選 Telegram 驗證,請在 Package Acceptance 上啟用 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier`。工作流程會將已解析的 `package-under-test` tarball 傳入 Telegram lane;獨立 Telegram 工作流程仍接受已發布的 npm 規格用於發布後檢查。 ## NPM 工作流程輸入 `OpenClaw NPM Release` 接受以下由操作者控制的輸入: -- `tag`:必要的發布標籤,例如 `v2026.4.2`、`v2026.4.2-1` 或 `v2026.4.2-beta.1`;當 `preflight_only=true` 時,也可以是目前完整 40 字元工作流程分支提交 SHA,用於僅驗證的預檢 -- `preflight_only`:`true` 表示僅驗證/建置/套件,`false` 表示實際發布路徑 -- `preflight_run_id`:在實際發布路徑上為必要,讓工作流程重用成功預檢執行所準備的 tarball +- `tag`:必要發布標籤,例如 `v2026.4.2`、`v2026.4.2-1` 或 `v2026.4.2-beta.1`;當 `preflight_only=true` 時,也可以是目前完整 40 字元工作流程分支 commit SHA,用於僅驗證的預檢 +- `preflight_only`:`true` 代表只進行驗證/建置/套件,`false` 代表真正發布路徑 +- `preflight_run_id`:真正發布路徑上必填,讓工作流程重用成功預檢執行中準備的 tarball - `npm_dist_tag`:發布路徑的 npm 目標標籤;預設為 `beta` `OpenClaw Release Checks` 接受以下由操作者控制的輸入: -- `ref`:要驗證的分支、標籤或完整提交 SHA。帶有密鑰的檢查要求解析後的提交可從 OpenClaw 分支或發布標籤到達。 +- `ref`:要驗證的分支、標籤或完整 commit SHA。帶有祕密的檢查要求已解析 commit 必須可從 OpenClaw 分支或發布標籤到達。 規則: -- 穩定版與修正版標籤可以發布到 `beta` 或 `latest` +- 穩定版和修正版標籤可發布到 `beta` 或 `latest` - Beta 預發布標籤只能發布到 `beta` -- 對於 `OpenClaw NPM Release`,只有在 `preflight_only=true` 時才允許完整提交 SHA 輸入 -- `OpenClaw Release Checks` 和 `Full Release Validation` 永遠僅用於驗證 -- 實際發布路徑必須使用預檢期間所用的相同 `npm_dist_tag`;工作流程會驗證發布前中繼資料仍然一致 +- 對於 `OpenClaw NPM Release`,只有在 `preflight_only=true` 時才允許完整 commit SHA 輸入 +- `OpenClaw Release Checks` 和 `Full Release Validation` 永遠只用於驗證 +- 真正發布路徑必須使用預檢期間使用的相同 `npm_dist_tag`;工作流程會在發布前驗證該中繼資料仍然延續 -## 穩定 npm 發布順序 +## 穩定版 npm 發布順序 -切出穩定 npm 發布時: +切穩定版 npm 發布時: -1. 以 `preflight_only=true` 執行 `OpenClaw NPM Release` - - 標籤存在之前,你可以使用目前完整工作流程分支提交 SHA,對預檢工作流程進行僅驗證的試執行 -2. 一般 beta 優先流程請選擇 `npm_dist_tag=beta`,只有在你刻意想直接發布穩定版時才選擇 `latest` -3. 當你想從單一手動工作流程取得一般 CI 加上即時提示快取、Docker、QA Lab、Matrix 和 Telegram 覆蓋範圍時,請在發布分支、發布標籤或完整提交 SHA 上執行 `Full Release Validation` -4. 如果你刻意只需要決定性的一般測試圖,請改在發布參考上執行手動 `CI` 工作流程 -5. 儲存成功的 `preflight_run_id` -6. 再次執行 `OpenClaw NPM Release`,並使用 `preflight_only=false`、相同的 `tag`、相同的 `npm_dist_tag`,以及已儲存的 `preflight_run_id` -7. 如果發布落在 `beta`,請使用私有 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` 工作流程,將該穩定版本從 `beta` 推進到 `latest` -8. 如果發布刻意直接發布到 `latest`,且 `beta` 應立即跟隨相同穩定版建置,請使用相同的私有工作流程,將兩個 dist-tag 都指向該穩定版本,或讓其排程的自我修復同步稍後移動 `beta` +1. 使用 `preflight_only=true` 執行 `OpenClaw NPM Release` + - 在標籤存在前,你可以使用目前完整工作流程分支 commit SHA,對預檢工作流程進行僅驗證的 dry run +2. 一般 beta-first 流程請選擇 `npm_dist_tag=beta`,只有在你刻意要直接發布穩定版時才選擇 `latest` +3. 當你想從一個手動工作流程取得一般 CI 加上 live prompt cache、Docker、QA Lab、Matrix 和 Telegram 覆蓋時,請在發布分支、發布標籤或完整 commit SHA 上執行 `Full Release Validation` +4. 如果你刻意只需要確定性的一般測試圖,請改在發布 ref 上執行手動 `CI` 工作流程 +5. 保存成功的 `preflight_run_id` +6. 再次執行 `OpenClaw NPM Release`,使用 `preflight_only=false`、相同的 `tag`、相同的 `npm_dist_tag`,以及已保存的 `preflight_run_id` +7. 如果發布落在 `beta`,請使用私有 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` 工作流程,將該穩定版本從 `beta` 提升到 `latest` +8. 如果發布刻意直接發布到 `latest`,而 `beta` 應立即跟隨相同穩定版建置,請使用同一個私有工作流程,將兩個 dist-tag 都指向該穩定版本,或讓其排程的自我修復同步稍後移動 `beta` -dist-tag 變更位於私有 repo 中是基於安全性,因為它仍然需要 `NPM_TOKEN`,而公開 repo 保持僅使用 OIDC 發布。 +dist-tag 變更位於私有 repo 以確保安全,因為它仍需要 `NPM_TOKEN`,而公開 repo 則維持只使用 OIDC 發布。 -這讓直接發布路徑和 beta 優先推進路徑都保持文件化,並且對操作者可見。 +這讓直接發布路徑與 beta-first 推廣路徑都保持已文件化,且操作者可見。 -如果維護者必須改用本機 npm 驗證,請只在專用 tmux 工作階段內執行任何 1Password -CLI (`op`) 命令。不要直接從主要代理 shell 呼叫 `op`;將它保留在 tmux 內,可讓提示、 -警示和 OTP 處理可被觀察,並防止重複的主機警示。 +如果維護者必須回退到本機 npm 驗證,請只在專用的 tmux 工作階段內執行任何 1Password CLI (`op`) 命令。不要直接從主要代理程式 shell 呼叫 `op`;將其保留在 tmux 內可讓提示、警示和 OTP 處理可觀察,並防止重複的主機警示。 ## 公開參考資料 @@ -332,10 +332,10 @@ CLI (`op`) 命令。不要直接從主要代理 shell 呼叫 `op`;將它保留 - [`scripts/package-mac-dist.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/package-mac-dist.sh) - [`scripts/make_appcast.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/make_appcast.sh) -維護者使用 +維護者會使用 [`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md) -中的私人發行文件作為實際操作手冊。 +中的私人發布文件作為實際的執行手冊。 ## 相關 -- [發行通道](/zh-TW/install/development-channels) +- [發布通道](/zh-TW/install/development-channels) diff --git a/docs/zh-TW/reference/full-release-validation.md b/docs/zh-TW/reference/full-release-validation.md new file mode 100644 index 000000000..08aac6d43 --- /dev/null +++ b/docs/zh-TW/reference/full-release-validation.md @@ -0,0 +1,156 @@ +--- +read_when: + - 執行或重新執行完整發布驗證 + - 比較穩定版與完整發行驗證設定檔 + - 排解發行驗證階段的失敗 +summary: 完整發布驗證階段、子工作流程、發布設定檔、重新執行控制代碼與佐證資料 +title: 完整版本發布驗證 +x-i18n: + generated_at: "2026-05-01T02:45:45Z" + model: gpt-5.5 + provider: openai + source_hash: dcbfafd744437c160c09a9c508a639781549193669b300e5249023f9f5dd4afe + source_path: reference/full-release-validation.md + workflow: 16 +--- + +`Full Release Validation` 是發行驗證總入口。它是發行前證明的單一手動 +進入點,但大多數工作會在子工作流程中執行,因此失敗的執行環境可重新執行, +而不必重新啟動整個發行流程。 + +請從受信任的工作流程參照執行,通常是 `main`,並將發行分支、 +標籤或完整提交 SHA 作為 `ref` 傳入: + +```bash +gh workflow run full-release-validation.yml \ + --ref main \ + -f ref=release/YYYY.M.D \ + -f provider=openai \ + -f mode=both \ + -f release_profile=stable +``` + +子工作流程會使用受信任的工作流程參照作為測試框架,並使用輸入的 +`ref` 作為受測候選版本。這可在驗證較舊的發行分支或標籤時, +仍使用新的驗證邏輯。 + +## 頂層階段 + +| 階段 | 詳細資料 | +| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 目標解析 | **Job:** `Resolve target ref`
**子工作流程:** 無
**證明:** 解析發行分支、標籤或完整提交 SHA,並記錄選取的輸入。
**重新執行:** 如果此項失敗,重新執行總流程。 | +| Vitest 和一般 CI | **Job:** `Run normal full CI`
**子工作流程:** `CI`
**證明:** 針對目標參照手動執行完整 CI 圖,包含 Linux Node 路徑、內建 Plugin 分片、通道契約、Node 22 相容性、`check`、`check-additional`、建置煙霧測試、文件檢查、Python Skills、Windows、macOS、Control UI i18n,以及透過總流程執行 Android。
**重新執行:** `rerun_group=ci` | +| Plugin 預發行 | **Job:** `Run plugin prerelease validation`
**子工作流程:** `Plugin Prerelease`
**證明:** 僅發行使用的 Plugin 靜態檢查、代理式 Plugin 覆蓋率、完整 extension 批次分片,以及 Plugin 預發行 Docker 路徑。
**重新執行:** `rerun_group=plugin-prerelease` | +| 發行檢查 | **Job:** `Run release/live/Docker/QA validation`
**子工作流程:** `OpenClaw Release Checks`
**證明:** 安裝煙霧測試、跨作業系統套件檢查、live/E2E 套件、Docker 發行路徑區塊、套件驗收、QA Lab 同等性、live Matrix,以及 live Telegram。
**重新執行:** `rerun_group=release-checks` 或較窄的發行檢查控制代碼。 | +| 發布後 Telegram | **Job:** `Run post-publish Telegram E2E`
**子工作流程:** `NPM Telegram Beta E2E`
**證明:** 設定 `npm_telegram_package_spec` 時,執行選用的已發布套件 Telegram 證明。
**重新執行:** `rerun_group=npm-telegram` | +| 總流程驗證器 | **Job:** `Verify full validation`
**子工作流程:** 無
**證明:** 重新檢查已記錄的子執行結論,並附加來自子工作流程的最慢工作表格。
**重新執行:** 在重新執行失敗子項並轉綠後,只重新執行此工作。 | + +對於 `ref=main` 和 `rerun_group=all`,較新的總流程會取代較舊的總流程。 +當父流程被取消時,它的監控器會取消已分派的任何子工作流程。發行分支 +和標籤驗證執行預設不會彼此取消。 + +## 發行檢查階段 + +`OpenClaw Release Checks` 是最大的子工作流程。它會解析一次目標, +並在套件或 Docker 面向的階段需要時,準備共用的 +`release-package-under-test` 成品。 + +| 階段 | 詳細資料 | +| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 發行目標 | **Job:** `Resolve target ref`
**支援工作流程:** 無
**測試:** 選取的參照、選用的預期 SHA、設定檔、重新執行群組,以及聚焦的 live 套件篩選器。
**重新執行:** `rerun_group=release-checks` | +| 套件成品 | **Job:** `Prepare release package artifact`
**支援工作流程:** 無
**測試:** 打包或解析一個候選 tarball,並上傳 `release-package-under-test` 供下游套件面向檢查使用。
**重新執行:** 受影響的套件、跨作業系統或 live/E2E 群組。 | +| 安裝煙霧測試 | **Job:** `Run install smoke`
**支援工作流程:** `Install Smoke`
**測試:** 使用根 Dockerfile 煙霧測試映像重用的完整安裝路徑、QR 套件安裝、根與 Gateway Docker 煙霧測試、安裝程式 Docker 測試、Bun 全域安裝 image-provider 煙霧測試,以及快速內建 Plugin Docker E2E。
**重新執行:** `rerun_group=install-smoke` | +| 跨作業系統 | **Job:** `cross_os_release_checks`
**支援工作流程:** `OpenClaw Cross-OS Release Checks (Reusable)`
**測試:** 在 Linux、Windows 和 macOS 上,針對選取的提供者和模式執行全新安裝與升級路徑,使用候選 tarball 加上基準套件。
**重新執行:** `rerun_group=cross-os` | +| Repo 和 live E2E | **Job:** `Run repo/live E2E validation`
**支援工作流程:** `OpenClaw Live And E2E Checks (Reusable)`
**測試:** repository E2E、live cache、OpenAI websocket 串流、原生 live 提供者與 Plugin 分片,以及由 `release_profile` 選取的 Docker 支援 live 模型/backend/Gateway 測試框架。
**重新執行:** `rerun_group=live-e2e`,可選擇搭配 `live_suite_filter`。 | +| Docker 發行路徑 | **Job:** `Run Docker release-path validation`
**支援工作流程:** `OpenClaw Live And E2E Checks (Reusable)`
**測試:** 針對共用套件成品執行發行路徑 Docker 區塊。
**重新執行:** `rerun_group=live-e2e` | +| 套件驗收 | **Job:** `Run package acceptance`
**支援工作流程:** `Package Acceptance`
**測試:** 成品原生的內建通道相依性相容性、離線 Plugin 套件 fixtures,以及針對相同 tarball 的 mock-OpenAI Telegram 套件驗收。
**重新執行:** `rerun_group=package` | +| QA 同等性 | **Job:** `Run QA Lab parity lane` 和 `Run QA Lab parity report`
**支援工作流程:** 直接工作
**測試:** 候選版本與基準代理式同等性套件,接著執行同等性報告。
**重新執行:** `rerun_group=qa-parity` 或 `rerun_group=qa` | +| QA live Matrix | **Job:** `Run QA Lab live Matrix lane`
**支援工作流程:** 直接工作
**測試:** `qa-live-shared` 環境中的快速 live Matrix QA 設定檔。
**重新執行:** `rerun_group=qa-live` 或 `rerun_group=qa` | +| QA live Telegram | **Job:** `Run QA Lab live Telegram lane`
**支援工作流程:** 直接工作
**測試:** 使用 Convex CI 認證租約的 live Telegram QA。
**重新執行:** `rerun_group=qa-live` 或 `rerun_group=qa` | +| 發行驗證器 | **Job:** `Verify release checks`
**支援工作流程:** 無
**測試:** 選取的重新執行群組所需的發行檢查工作。
**重新執行:** 在聚焦的子工作通過後重新執行。 | + +## Docker 發行路徑區塊 + +當 `live_suite_filter` 為空時,Docker 發行路徑階段會執行這些區塊: + +| 區塊 | 覆蓋範圍 | +| ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | +| `core` | 核心 Docker 發行路徑煙霧測試路徑。 | +| `package-update-openai` | OpenAI 套件安裝與更新行為。 | +| `package-update-anthropic` | Anthropic 套件安裝與更新行為。 | +| `package-update-core` | 提供者中立的套件與更新行為。 | +| `plugins-runtime-plugins` | 演練 Plugin 行為的 Plugin runtime 路徑。 | +| `plugins-runtime-services` | 服務支援的 Plugin runtime 路徑;要求時包含 OpenWebUI。 | +| `plugins-runtime-install-a` through `plugins-runtime-install-h` | 為平行發行驗證拆分的 Plugin 安裝/runtime 批次。 | +| `bundled-channels-core` | 內建通道 Docker 行為。 | +| `bundled-channels-update-a`, `bundled-channels-update-discord`, `bundled-channels-update-b` | 內建通道更新行為。 | +| `bundled-channels-contracts` | Docker 發行路徑中的內建通道契約檢查。 | + +當只有一個 Docker lane 失敗時,請在可重用的即時/E2E workflow 上使用目標式的 `docker_lanes=`。release 成品會在可用時包含每個 lane 的重新執行命令,並附上 package 成品與映像重用輸入。 + +## release 設定檔 + +`release_profile` 只控制 release 檢查內的即時/provider 覆蓋範圍。它不會移除一般的完整 CI、Plugin Prerelease、安裝 smoke、package acceptance、QA Lab,或 Docker release-path 區塊。 + +| 設定檔 | 預期用途 | 包含的即時/provider 覆蓋範圍 | +| --------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `minimum` | 最快的 release 關鍵 smoke。 | OpenAI/core 即時路徑、OpenAI 的 Docker 即時模型、原生 Gateway core、原生 OpenAI Gateway 設定檔、原生 OpenAI Plugin,以及 Docker 即時 Gateway OpenAI。 | +| `stable` | 預設 release 核准設定檔。 | `minimum` 加上 Anthropic、Google、MiniMax、backend、原生即時測試 harness、Docker 即時 CLI backend、Docker ACP bind、Docker Codex harness,以及一個 OpenCode Go smoke shard。 | +| `full` | 廣泛的 advisory 掃描。 | `stable` 加上 advisory providers、Plugin 即時 shards,以及媒體即時 shards。 | + +## 僅 full 新增項目 + +這些套件會被 `stable` 略過,並由 `full` 包含: + +| 區域 | 僅 full 覆蓋範圍 | +| -------------------------------- | -------------------------------------------------------------------------------- | +| Docker 即時模型 | OpenCode Go、OpenRouter、xAI、Z.ai,以及 Fireworks。 | +| Docker 即時 Gateway | DeepSeek、Fireworks、OpenCode Go、OpenRouter、xAI,以及 Z.ai 的 advisory shard。 | +| 原生 Gateway provider 設定檔 | Fireworks、DeepSeek、完整 OpenCode Go 模型 shards、OpenRouter、xAI,以及 Z.ai。 | +| 原生 Plugin 即時 shards | Plugins A-K、L-N、O-Z 其他、Moonshot,以及 xAI。 | +| 原生媒體即時 shards | 音訊、Google 音樂、MiniMax 音樂,以及影片群組 A-D。 | + +`stable` 包含 `native-live-src-gateway-profiles-opencode-go-smoke`;`full` 則改用更廣泛的 OpenCode Go 模型 shards。 + +## 聚焦重新執行 + +使用 `rerun_group` 以避免重複執行不相關的 release boxes: + +| 控制代碼 | 範圍 | +| ------------------- | ------------------------------------------------- | +| `all` | 所有 Full Release Validation 階段。 | +| `ci` | 僅手動完整 CI 子項。 | +| `plugin-prerelease` | 僅 Plugin Prerelease 子項。 | +| `release-checks` | 所有 OpenClaw Release Checks 階段。 | +| `install-smoke` | 安裝 Smoke 到 release checks。 | +| `cross-os` | Cross-OS release checks。 | +| `live-e2e` | repo/即時 E2E 與 Docker release-path 驗證。 | +| `package` | Package Acceptance。 | +| `qa` | QA parity 加上 QA 即時 lanes。 | +| `qa-parity` | 僅 QA parity lanes 與報告。 | +| `qa-live` | 僅 QA 即時 Matrix 與 Telegram。 | +| `npm-telegram` | 僅選用的發布後 Telegram E2E。 | + +當一個即時套件失敗時,搭配 `rerun_group=live-e2e` 使用 `live_suite_filter`。有效的 filter id 定義於可重用的即時/E2E workflow,包括 `docker-live-models`、`live-gateway-docker`、`live-gateway-anthropic-docker`、`live-gateway-google-docker`、`live-gateway-minimax-docker`、`live-gateway-advisory-docker`、`live-cli-backend-docker`、`live-acp-bind-docker`,以及 `live-codex-harness-docker`。 + +## 要保留的證據 + +保留 `Full Release Validation` 摘要作為 release 層級索引。它會連結子執行 id,並包含最慢 job 表格。若發生失敗,請先檢查子 workflow,然後重新執行上方最小的相符 handle。 + +實用成品: + +- `OpenClaw Release Checks` 中的 `release-package-under-test` +- `.artifacts/docker-tests/` 下的 Docker release-path 成品 +- Package Acceptance `package-under-test` 與 Docker acceptance 成品 +- 每個 OS 與套件的 Cross-OS release-check 成品 +- QA parity、Matrix,以及 Telegram 成品 + +## Workflow 檔案 + +- `.github/workflows/full-release-validation.yml` +- `.github/workflows/openclaw-release-checks.yml` +- `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` +- `.github/workflows/plugin-prerelease.yml` +- `.github/workflows/install-smoke.yml` +- `.github/workflows/openclaw-cross-os-release-checks-reusable.yml` +- `.github/workflows/package-acceptance.yml` diff --git a/docs/zh-TW/reference/test.md b/docs/zh-TW/reference/test.md index 67a1d69dd..e4c3c379c 100644 --- a/docs/zh-TW/reference/test.md +++ b/docs/zh-TW/reference/test.md @@ -1,59 +1,60 @@ --- read_when: - 執行或修復測試 -summary: 如何在本機執行測試 (vitest),以及何時使用 force/coverage 模式 +summary: 如何在本機執行測試(vitest),以及何時使用強制/覆蓋率模式 title: 測試 x-i18n: - generated_at: "2026-04-30T18:38:26Z" + generated_at: "2026-05-01T02:45:39Z" model: gpt-5.5 provider: openai - source_hash: 131f2bad3b2806d28394213cec38d632d106ddbf8ff04d06345ab8046fb8bcf2 + source_hash: de18ac7d822055ee34885e5e897eff0fe7dde57c945a6b7f2c4bb2a29445c859 source_path: reference/test.md workflow: 16 --- - 完整測試工具組(套件、即時、Docker):[測試](/zh-TW/help/testing) -- `pnpm test:force`:終止任何仍占用預設控制連接埠的 Gateway 程序,然後以隔離的 Gateway 連接埠執行完整 Vitest 套件,避免伺服器測試與執行中的實例衝突。當先前的 Gateway 執行留下連接埠 18789 被占用時使用。 -- `pnpm test:coverage`:使用 V8 覆蓋率執行單元套件(透過 `vitest.unit.config.ts`)。這是已載入檔案的單元覆蓋率閘門,不是整個 repo 的全檔案覆蓋率。門檻為 70% 行數/函式/陳述式與 55% 分支。由於 `coverage.all` 為 false,此閘門會測量單元覆蓋率套件載入的檔案,而不是將每個分割 lane 原始檔視為未覆蓋。 +- `pnpm test:force`:終止任何仍占用預設控制埠的 Gateway 行程,接著以隔離的 Gateway 埠執行完整 Vitest 套件,讓伺服器測試不會與執行中的實例衝突。當先前的 Gateway 執行讓埠 18789 被占用時,請使用此指令。 +- `pnpm test:coverage`:使用 V8 覆蓋率執行單元套件(透過 `vitest.unit.config.ts`)。這是已載入檔案的單元覆蓋率閘門,不是整個儲存庫的全檔案覆蓋率。門檻為行數/函式/陳述式 70%,分支 55%。因為 `coverage.all` 為 false,此閘門會衡量單元覆蓋率套件載入的檔案,而不是把每個分割車道的原始碼檔案都視為未覆蓋。 - `pnpm test:coverage:changed`:只針對自 `origin/main` 以來變更的檔案執行單元覆蓋率。 -- `pnpm test:changed`:便宜的智慧變更測試執行。它會從直接測試編輯、同層 `*.test.ts` 檔案、明確原始碼對應,以及本機匯入圖執行精準目標。寬泛/config/package 變更會被略過,除非它們能對應到精準測試。 -- `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`:明確的寬泛變更測試執行。當測試 harness/config/package 編輯應退回到 Vitest 較寬泛的變更測試行為時使用。 -- `pnpm changed:lanes`:顯示相對於 `origin/main` 的 diff 觸發的架構 lane。 -- `pnpm check:changed`:針對相對於 `origin/main` 的 diff 執行智慧變更檢查閘門。它會為受影響的架構 lane 執行 typecheck、lint 與 guard 命令,但不會執行 Vitest 測試。測試證明請使用 `pnpm test:changed` 或明確的 `pnpm test `。 -- `pnpm test`:透過有範圍的 Vitest lane 路由明確的檔案/目錄目標。未指定目標的執行使用固定 shard 群組,並展開為 leaf config 以進行本機平行執行;extension 群組一律展開為各 extension 的 shard config,而不是單一巨大的 root-project 程序。 -- 測試 wrapper 執行會以簡短的 `[test] passed|failed|skipped ... in ...` 摘要結尾。Vitest 自己的耗時行仍保留每個 shard 的細節。 -- 共用 OpenClaw 測試狀態:當測試需要隔離的 `HOME`、`OPENCLAW_STATE_DIR`、`OPENCLAW_CONFIG_PATH`、config fixture、workspace、agent dir 或 auth-profile store 時,從 Vitest 使用 `src/test-utils/openclaw-test-state.ts`。 -- 程序 E2E helper:當 Vitest 程序層級 E2E 測試需要執行中的 Gateway、CLI env、log capture 與集中清理時,使用 `test/helpers/openclaw-test-instance.ts`。 -- Docker/Bash E2E helper:source `scripts/lib/docker-e2e-image.sh` 的 lane 可將 `docker_e2e_test_state_shell_b64