chore(i18n): refresh zh-TW translations
This commit is contained in:
parent
4b9fa9cdff
commit
009b227883
336
docs/zh-TW/ci.md
336
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-30T09:35:01Z"
|
||||
generated_at: "2026-04-30T18:38:35Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: a9c18f0801864ca1030aac9ea81117b011bd7936388984a1809ce3ae6e906e62
|
||||
source_hash: a24afc27606ac7f4e9ead89acdd319bffa23336610f8a6cd8b576ea1a5b233dd
|
||||
source_path: ci.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw CI 會在每次推送到 `main` 以及每個 pull request 上執行。`preflight` 作業會分類差異,並在只有不相關區域變更時關閉昂貴的執行路徑。手動 `workflow_dispatch` 執行會刻意略過智慧範圍界定,並展開完整圖形,以供發行候選版本和廣泛驗證使用。Android 路徑透過 `include_android` 維持選用。僅限發行的 Plugin 覆蓋範圍位於獨立的 [`Plugin 預發行`](#plugin-prerelease) 工作流程中,且只會從 [`完整發行驗證`](#full-release-validation) 或明確的手動派發執行。
|
||||
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 執行。
|
||||
|
||||
## 管線概觀
|
||||
## 管線概覽
|
||||
|
||||
| 作業 | 用途 | 執行時機 |
|
||||
| 工作 | 目的 | 執行時機 |
|
||||
| -------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------- |
|
||||
| `preflight` | 偵測僅文件變更、已變更範圍、已變更擴充功能,並建置 CI manifest | 一律在非草稿推送和 PR 上執行 |
|
||||
| `security-scm-fast` | 透過 `zizmor` 偵測私密金鑰並稽核工作流程 | 一律在非草稿推送和 PR 上執行 |
|
||||
| `security-dependency-audit` | 針對 npm advisories 進行不需相依性的正式環境 lockfile 稽核 | 一律在非草稿推送和 PR 上執行 |
|
||||
| `security-fast` | 快速安全性作業的必要彙總 | 一律在非草稿推送和 PR 上執行 |
|
||||
| `check-dependencies` | 僅針對正式環境 Knip 相依性的檢查,加上未使用檔案 allowlist 防護 | Node 相關變更 |
|
||||
| `build-artifacts` | 建置 `dist/`、Control UI、已建置 artifact 檢查,以及可重複使用的下游 artifact | 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 和 extension 路徑 | Node 相關變更 |
|
||||
| `check` | 分片的主要本機 gate 對等項:正式環境型別、lint、防護、測試型別與嚴格 smoke | Node 相關變更 |
|
||||
| `check-additional` | 架構、邊界、extension-surface 防護、package-boundary 與 gateway-watch 分片 | Node 相關變更 |
|
||||
| `build-smoke` | 已建置 CLI 的 smoke 測試與啟動記憶體 smoke | Node 相關變更 |
|
||||
| `checks` | 已建置 artifact channel 測試的驗證器 | Node 相關變更 |
|
||||
| `checks-node-compat-node22` | Node 22 相容性建置與 smoke 路徑 | 發行用手動 CI 派發 |
|
||||
| `check-docs` | 文件格式化、lint 與斷裂連結檢查 | 文件已變更 |
|
||||
| `skills-python` | Python 支援 skills 的 Ruff + pytest | Python skill 相關變更 |
|
||||
| `checks-windows` | Windows 專用 process/path 測試,加上共用 runtime import specifier 回歸 | Windows 相關變更 |
|
||||
| `macos-node` | 使用共用已建置 artifact 的 macOS TypeScript 測試路徑 | macOS 相關變更 |
|
||||
| `macos-swift` | macOS app 的 Swift lint、建置與測試 | macOS 相關變更 |
|
||||
| `android` | 兩種 flavor 的 Android 單元測試,加上一個 debug APK 建置 | Android 相關變更 |
|
||||
| `test-performance-agent` | 受信任活動後的每日 Codex 慢速測試最佳化 | Main CI 成功或手動派發 |
|
||||
| `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 |
|
||||
|
||||
## 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 路徑重疊,讓下游消費者能在共用建置完成後立即開始。
|
||||
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` 會快速失敗,不等待較重的 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`。
|
||||
|
||||
當同一個 PR 或 `main` ref 上有較新的推送進來時,GitHub 可能會將被取代的作業標記為 `cancelled`。除非同一 ref 的最新執行也失敗,否則請將其視為 CI 雜訊。彙總分片檢查使用 `!cancelled() && always()`,因此它們仍會回報正常的分片失敗,但不會在整個工作流程已被取代後繼續排隊。自動 CI concurrency key 已版本化(`CI-v7-*`),因此 GitHub 端舊佇列群組中的僵屍項目無法無限期阻擋較新的 main 執行。手動完整套件執行使用 `CI-manual-v1-*`,且不會取消進行中的執行。
|
||||
當較新的 push 落在同一個 PR 或 `main` ref 上時,GitHub 可能會將被取代的工作標記為 `cancelled`。除非同一 ref 的最新執行也失敗,否則將其視為 CI 雜訊。彙總分片檢查使用 `!cancelled() && always()`,因此仍會回報一般分片失敗,但不會在整個 workflow 已被取代後繼續排隊。自動 CI concurrency key 已版本化(`CI-v7-*`),因此 GitHub 端舊佇列群組中的 zombie 不會無限期封鎖較新的 main 執行。手動 full-suite 執行使用 `CI-manual-v1-*`,且不會取消進行中的執行。
|
||||
|
||||
## 範圍與路由
|
||||
|
||||
範圍邏輯位於 `scripts/ci-changed-scope.mjs`,並由 `src/scripts/ci-changed-scope.test.ts` 中的單元測試涵蓋。手動派發會略過 changed-scope 偵測,並讓 preflight manifest 表現得像每個有範圍的區域都已變更。
|
||||
範圍邏輯位於 `scripts/ci-changed-scope.mjs`,並由 `src/scripts/ci-changed-scope.test.ts` 中的 unit tests 涵蓋。手動 dispatch 會略過 changed-scope detection,並讓 preflight manifest 表現得像每個 scoped area 都已變更。
|
||||
|
||||
- **CI 工作流程編輯** 會驗證 Node CI 圖形加上工作流程 linting,但本身不會強制執行 Windows、Android 或 macOS 原生建置;這些平台路徑仍只限於平台原始碼變更。
|
||||
- **僅 CI 路由編輯、選定的便宜 core-test fixture 編輯,以及狹窄的 Plugin contract helper/test-routing 編輯** 會使用快速的 Node-only manifest 路徑:`preflight`、security,以及單一 `checks-fast-core` 工作。當變更僅限於快速工作直接涵蓋的路由或 helper 表面時,該路徑會略過 build artifacts、Node 22 相容性、channel contracts、完整 core 分片、bundled-plugin 分片,以及額外的 guard 矩陣。
|
||||
- **Windows Node 檢查** 會限定於 Windows 專用 process/path wrapper、npm/pnpm/UI runner helper、package manager config,以及執行該路徑的 CI 工作流程表面;不相關的原始碼、Plugin、install-smoke 和僅測試變更會留在 Linux Node 路徑上。
|
||||
- **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 執行路徑。
|
||||
|
||||
最慢的 Node 測試家族會被拆分或平衡,讓每個作業維持小型而不過度保留 runner:channel contracts 以三個加權分片執行,小型 core unit 路徑會配對,auto-reply 以四個平衡 worker 執行(reply 子樹拆成 agent-runner、dispatch 與 commands/state-routing 分片),而 agentic gateway/plugin config 會分散到既有的 source-only agentic Node 作業中,不需等待已建置 artifact。廣泛的瀏覽器、QA、媒體與雜項 Plugin 測試會使用各自專用的 Vitest config,而不是共用的 Plugin catch-all。Include-pattern 分片會使用 CI 分片名稱記錄計時項目,因此 `.artifacts/vitest-shard-timings.json` 可以區分整個 config 與已過濾分片。`check-additional` 會將 package-boundary compile/canary 工作放在一起,並將 runtime topology architecture 與 gateway watch 覆蓋範圍分開;boundary guard 分片會在單一作業內並行執行其小型獨立防護。Gateway watch、channel 測試與 core support-boundary 分片會在 `dist/` 和 `dist-runtime/` 已建置後,於 `build-artifacts` 內並行執行。
|
||||
最慢的 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` 內並行執行。
|
||||
|
||||
Android CI 會同時執行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,接著建置 Play debug APK。third-party flavor 沒有獨立 source set 或 manifest;其單元測試路徑仍會使用 SMS/call-log BuildConfig 旗標編譯該 flavor,同時避免在每次 Android 相關推送上重複執行 debug APK packaging 作業。
|
||||
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。
|
||||
|
||||
`check-dependencies` 分片會執行 `pnpm deadcode:dependencies`(一個針對正式環境的 Knip dependency-only pass,固定使用最新 Knip 版本,且針對 `dlx` 安裝停用 pnpm 的最低發行年齡限制)以及 `pnpm deadcode:unused-files`,後者會將 Knip 的正式環境未使用檔案發現與 `scripts/deadcode-unused-files.allowlist.mjs` 比較。當 PR 新增未經審查的未使用檔案,或留下過時的 allowlist 項目時,未使用檔案防護會失敗,同時保留 Knip 無法靜態解析的刻意動態 Plugin、generated、build、live-test 與 package bridge 表面。
|
||||
`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。
|
||||
|
||||
## 手動派發
|
||||
## 手動 Dispatch
|
||||
|
||||
手動 CI 派發會執行與一般 CI 相同的作業圖形,但會強制開啟每個非 Android 範圍路徑:Linux Node 分片、bundled-plugin 分片、channel contracts、Node 22 相容性、`check`、`check-additional`、build smoke、文件檢查、Python skills、Windows、macOS 與 Control UI i18n。獨立的手動 CI 派發只有在 `include_android=true` 時才會執行 Android;完整發行 umbrella 會透過傳遞 `include_android=true` 啟用 Android。Plugin 預發行靜態檢查、僅限發行的 `agentic-plugins` 分片、完整 extension 批次掃描,以及 Plugin 預發行 Docker 路徑皆排除於 CI 之外。Docker 預發行套件只會在 `Full Release Validation` 以啟用 release-validation gate 的方式派發獨立 `Plugin Prerelease` 工作流程時執行。
|
||||
手動 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 時執行。
|
||||
|
||||
手動執行會使用唯一的 concurrency group,因此發行候選版本的完整套件不會被同一 ref 上的另一個推送或 PR 執行取消。選用的 `target_ref` 輸入可讓受信任的呼叫端針對 branch、tag 或完整 commit SHA 執行該圖形,同時使用所選派發 ref 的工作流程檔案。
|
||||
手動執行使用唯一的 concurrency group,因此 release-candidate full suite 不會被同一 ref 上的另一個 push 或 PR run 取消。選用的 `target_ref` input 讓受信任的 caller 可以針對 branch、tag 或完整 commit SHA 執行該圖,同時使用所選 dispatch ref 的 workflow file。
|
||||
|
||||
```bash
|
||||
gh workflow run ci.yml --ref release/YYYY.M.D
|
||||
@ -81,15 +81,15 @@ gh workflow run full-release-validation.yml --ref main -f ref=<branch-or-sha>
|
||||
|
||||
| 執行器 | 作業 |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `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`、較低負載的 extension 分片、`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 佇列時間的成本高於節省的時間) |
|
||||
| `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 的佇列時間成本高過省下的時間) |
|
||||
| `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,23 +117,23 @@ pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifac
|
||||
|
||||
## 完整發行驗證
|
||||
|
||||
`Full Release Validation` 是「在發行前執行所有項目」的手動總括工作流程。它接受分支、標籤或完整 commit SHA,使用該目標派送手動 `CI` 工作流程、派送 `Plugin Prerelease` 以進行僅限發行的 Plugin/套件/靜態/Docker 證明,並派送 `OpenClaw Release Checks` 以進行安裝 smoke、套件驗收、Docker 發行路徑套件、即時/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道。提供已發布套件規格時,它也可以執行發布後的 `NPM Telegram Beta E2E` 工作流程。
|
||||
`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` 工作流程。
|
||||
|
||||
`release_profile` 控制傳入發行檢查的即時/供應商廣度:
|
||||
`release_profile` 控制傳入發行檢查的 live/供應商涵蓋範圍:
|
||||
|
||||
- `minimum` 保留最快的 OpenAI/核心發行關鍵通道。
|
||||
- `stable` 加入穩定的供應商/後端集合。
|
||||
- `full` 執行廣泛的建議供應商/媒體矩陣。
|
||||
- `stable` 加入穩定供應商/後端集合。
|
||||
- `full` 執行廣泛的諮詢供應商/媒體矩陣。
|
||||
|
||||
總括工作流程會記錄已派送的子執行 ID,而最終的 `Verify full validation` 作業會重新檢查目前子執行結論,並為每個子執行附加最慢作業表。如果子工作流程重新執行後變為綠燈,只需重新執行父驗證器作業,即可重新整理總括結果與時間摘要。
|
||||
總括流程會記錄已派送的子執行 ID,而最終的 `Verify full validation` 作業會重新檢查目前子執行結論,並為每個子執行附加最慢作業表。如果子工作流程重新執行後轉為綠燈,只需重新執行父驗證器作業,即可重新整理總括結果與時間摘要。
|
||||
|
||||
為了復原,`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`。這會讓失敗的發行盒在焦點修復後,重新執行範圍維持受限。
|
||||
若要復原,`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`。這會讓失敗的發行盒在針對性修復後,重新執行範圍保持有界。
|
||||
|
||||
`OpenClaw Release Checks` 使用受信任的工作流程 ref,將所選 ref 解析一次成 `release-package-under-test` tarball,然後將該 artifact 傳給即時/E2E 發行路徑 Docker 工作流程與套件驗收分片。這會讓套件位元組在各個發行盒之間保持一致,並避免在多個子作業中重新打包同一個候選版本。
|
||||
`OpenClaw Release Checks` 使用受信任的工作流程 ref,將所選 ref 解析一次為 `release-package-under-test` tarball,然後將該成品傳給 live/E2E 發行路徑 Docker 工作流程和套件接受度分片。這能讓套件位元組在各發行盒之間保持一致,並避免在多個子作業中重新打包同一個候選版本。
|
||||
|
||||
## 即時與 E2E 分片
|
||||
## Live 和 E2E 分片
|
||||
|
||||
發行即時/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`
|
||||
@ -145,57 +145,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`
|
||||
- 分割的媒體音訊/影片分片,以及依供應商篩選的音樂分片
|
||||
- 拆分的媒體音訊/視訊分片,以及依供應商篩選的音樂分片
|
||||
|
||||
這會維持相同的檔案覆蓋範圍,同時讓緩慢的即時供應商失敗更容易重新執行與診斷。彙總的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名稱仍可用於手動一次性重新執行。
|
||||
這會保留相同的檔案涵蓋範圍,同時讓緩慢的 live 供應商失敗更容易重新執行與診斷。彙總的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名稱仍可用於手動一次性重新執行。
|
||||
|
||||
原生即時媒體分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中執行,該映像由 `Live Media Runner Image` 工作流程建置。該映像預先安裝 `ffmpeg` 和 `ffprobe`;媒體作業只會在設定前驗證二進位檔。請將 Docker 支援的即時套件保留在一般 Blacksmith 執行器上,因為容器作業不適合啟動巢狀 Docker 測試。
|
||||
原生 live 媒體分片在 `Live Media Runner Image` 工作流程建置的 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中執行。該映像已預先安裝 `ffmpeg` 和 `ffprobe`;媒體作業只會在設定前驗證二進位檔。請將 Docker 支援的 live 套件放在一般 Blacksmith 執行器上,container 作業不是啟動巢狀 Docker 測試的合適位置。
|
||||
|
||||
Docker 支援的即時模型/後端分片會針對每個選取的 commit 使用個別共享的 `ghcr.io/openclaw/openclaw-live-test:<sha>` 映像。即時發行工作流程會建置並推送該映像一次,然後 Docker 即時模型、Gateway、CLI 後端、ACP bind 和 Codex harness 分片會使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行。如果這些分片各自重新建置完整來源 Docker 目標,表示發行執行設定錯誤,並會在重複映像建置上浪費實際時間。
|
||||
Docker 支援的 live 模型/後端分片會對每個所選 commit 使用個別共用的 `ghcr.io/openclaw/openclaw-live-test:<sha>` 映像。live 發行工作流程會建置並推送該映像一次,接著 Docker live 模型、Gateway、CLI 後端、ACP bind 和 Codex harness 分片會以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行。如果這些分片各自重新建置完整原始碼 Docker 目標,表示發行執行設定錯誤,會在重複映像建置上浪費牆鐘時間。
|
||||
|
||||
## 套件驗收
|
||||
## 套件接受度
|
||||
|
||||
當問題是「這個可安裝的 OpenClaw 套件是否能像產品一樣運作?」時,請使用 `Package Acceptance`。它與一般 CI 不同:一般 CI 會驗證來源樹,而套件驗收會透過使用者在安裝或更新後執行的相同 Docker E2E harness,驗證單一 tarball。
|
||||
當問題是「這個可安裝的 OpenClaw 套件是否能作為產品運作?」時,請使用 `Package Acceptance`。它不同於一般 CI:一般 CI 驗證原始碼樹,而套件接受度會透過使用者在安裝或更新後實際執行的同一套 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` artifact 上傳,並在 GitHub 步驟摘要中列印來源、工作流程 ref、套件 ref、版本、SHA-256 和設定檔。
|
||||
2. `docker_acceptance` 會以 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 呼叫 `openclaw-live-and-e2e-checks-reusable.yml`。可重用工作流程會下載該 artifact、驗證 tarball 清單、在需要時準備 package-digest Docker 映像,並針對該套件執行所選的 Docker 通道,而不是打包工作流程 checkout。當設定檔選取多個目標 `docker_lanes` 時,可重用工作流程會準備套件與共享映像一次,然後將這些通道展開為平行的目標 Docker 作業,且各自使用唯一 artifact。
|
||||
3. `package_telegram` 可選擇性呼叫 `NPM Telegram Beta E2E`。當 `telegram_mode` 不是 `none` 時會執行;若 Package Acceptance 已解析套件,則安裝相同的 `package-under-test` artifact;獨立 Telegram 派送仍可安裝已發布的 npm 規格。
|
||||
4. 如果套件解析、Docker 驗收或可選的 Telegram 通道失敗,`summary` 會讓工作流程失敗。
|
||||
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` 會使工作流程失敗。
|
||||
|
||||
### 候選來源
|
||||
|
||||
- `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/穩定版的驗收。
|
||||
- `source=ref` 會封裝受信任的 `package_ref` 分支、標籤或完整 commit SHA。解析器會擷取 OpenClaw 分支/標籤、驗證所選 commit 可從儲存庫分支歷史或發行標籤到達、在分離的 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` 是選用,但外部共享的 artifact 應提供。
|
||||
|
||||
請將 `workflow_ref` 與 `package_ref` 分開。`workflow_ref` 是執行測試的受信任 workflow/harness 程式碼。`package_ref` 是在 `source=ref` 時會被封裝的來源 commit。這讓目前的測試 harness 可以驗證較舊的受信任來源 commit,而不必執行舊的 workflow 邏輯。
|
||||
請將 `workflow_ref` 和 `package_ref` 分開。`workflow_ref` 是執行測試的受信任 workflow/harness 程式碼。`package_ref` 是在 `source=ref` 時會被封裝的來源 commit。這讓目前的測試 harness 可以驗證較舊的受信任來源 commit,而不必執行舊的 workflow 邏輯。
|
||||
|
||||
### 套件組合設定檔
|
||||
|
||||
- `smoke` — `npm-onboard-channel-agent`、`gateway-network`、`config-reload`
|
||||
- `package` — `npm-onboard-channel-agent`、`doctor-switch`、`update-channel-switch`、`bundled-channel-deps-compat`、`plugins-offline`、`plugin-update`
|
||||
- `product` — `package` 加上 `mcp-channels`、`cron-mcp-cleanup`、`openai-web-search-minimal`、`openwebui`
|
||||
- `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`
|
||||
- `product` — `package` 加上 `mcp-channels`, `cron-mcp-cleanup`, `openai-web-search-minimal`, `openwebui`
|
||||
- `full` — 含 OpenWebUI 的完整 Docker 發行路徑區塊
|
||||
- `custom` — 精確的 `docker_lanes`;當 `suite_profile=custom` 時必填
|
||||
|
||||
`package` 設定檔使用離線 Plugin 覆蓋範圍,因此已發布套件驗證不會受即時 ClawHub 可用性阻擋。選用的 Telegram lane 會在 `NPM Telegram Beta E2E` 中重用 `package-under-test` artifact,並保留已發布 npm 規格路徑供獨立派送使用。
|
||||
`package` 設定檔使用離線 Plugin 覆蓋範圍,因此已發布套件驗證不會受限於即時 ClawHub 可用性。選用的 Telegram lane 會在 `NPM Telegram Beta E2E` 中重用 `package-under-test` artifact,並保留已發布 npm 規格路徑供獨立 dispatch 使用。
|
||||
|
||||
發行檢查會以 `source=ref`、`package_ref=<release-ref>`、`workflow_ref=<release 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 原生的 bundled-channel 相容性、離線 Plugin 與 Telegram 證明。跨 OS 發行檢查仍涵蓋 OS 特定的 onboarding、installer 與平台行為;package/update 產品驗證應從 Package Acceptance 開始。Windows 封裝與 installer fresh 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=<release-ref>`、`workflow_ref=<release 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 證明會保持快速且具決定性。
|
||||
|
||||
### 舊版相容性期間
|
||||
|
||||
Package Acceptance 對已發布套件設有有限的舊版相容性期間。到 `2026.4.25` 為止的套件,包括 `2026.4.25-beta.*`,可以使用相容性路徑:
|
||||
Package Acceptance 對已發布套件有有限的舊版相容性期間。到 `2026.4.25` 為止的套件,包括 `2026.4.25-beta.*`,可以使用相容性路徑:
|
||||
|
||||
- `dist/postinstall-inventory.json` 中已知的私有 QA 項目可以指向 tarball 省略的檔案;
|
||||
- 當套件未公開該 flag 時,`doctor-switch` 可以略過 `gateway install --wrapper` 持久化子案例;
|
||||
- `update-channel-switch` 可以從 tarball 衍生的假 git fixture 中修剪缺少的 `pnpm.patchedDependencies`,並可記錄缺少持久化的 `update.channel`;
|
||||
- Plugin smoke 可以讀取舊版 install-record 位置,或接受缺少 marketplace install-record 持久化;
|
||||
- `plugin-update` 可以允許設定中繼資料遷移,同時仍要求 install record 與 no-reinstall 行為保持不變。
|
||||
- 當套件未公開該旗標時,`doctor-switch` 可以略過 `gateway install --wrapper` 持久化子案例;
|
||||
- `update-channel-switch` 可以從 tarball 衍生的假 git fixture 中剪除缺失的 `pnpm.patchedDependencies`,並可記錄缺失的持久化 `update.channel`;
|
||||
- Plugin smoke 可以讀取舊版安裝記錄位置,或接受缺失的 marketplace 安裝記錄持久化;
|
||||
- `plugin-update` 可以允許 config metadata 遷移,但仍要求安裝記錄和無重新安裝行為保持不變。
|
||||
|
||||
已發布的 `2026.4.26` 套件也可以針對已出貨的本機建置中繼資料戳記檔提出警告。後續套件必須符合現代合約;相同條件會失敗,而不是警告或略過。
|
||||
已發布的 `2026.4.26` 套件也可以對已出貨的本機 build metadata stamp 檔案發出警告。後續套件必須滿足現代合約;相同條件會失敗,而不是警告或略過。
|
||||
|
||||
### 範例
|
||||
|
||||
@ -238,152 +238,152 @@ gh workflow run package-acceptance.yml \
|
||||
-f docker_lanes='install-e2e plugin-update'
|
||||
```
|
||||
|
||||
偵錯失敗的 package acceptance 執行時,請從 `resolve_package` 摘要開始,確認套件來源、版本與 SHA-256。接著檢查 `docker_acceptance` 子執行與其 Docker artifact:`.artifacts/docker-tests/**/summary.json`、`failures.json`、lane 記錄、階段耗時與重新執行命令。請優先重新執行失敗的套件設定檔或精確 Docker lane,而不是重新執行完整發行驗證。
|
||||
偵錯失敗的 package acceptance 執行時,請從 `resolve_package` 摘要開始,確認套件來源、版本和 SHA-256。接著檢查 `docker_acceptance` 子執行及其 Docker artifacts:`.artifacts/docker-tests/**/summary.json`、`failures.json`、lane 記錄、階段計時,以及重新執行命令。請優先重新執行失敗的 package 設定檔或精確的 Docker lanes,而不是重新執行完整發行驗證。
|
||||
|
||||
## 安裝 smoke
|
||||
|
||||
獨立的 `Install Smoke` workflow 會透過自己的 `preflight` job 重用相同的範圍腳本。它將 smoke 覆蓋範圍拆分為 `run_fast_install_smoke` 與 `run_full_install_smoke`。
|
||||
獨立的 `Install Smoke` workflow 會透過自己的 `preflight` job 重用相同的範圍腳本。它會將 smoke 覆蓋範圍拆分為 `run_fast_install_smoke` 和 `run_full_install_smoke`。
|
||||
|
||||
- **快速路徑** 會在 pull request 觸及 Docker/package 表面、bundled Plugin package/manifest 變更,或 Docker smoke job 會演練的核心 Plugin/channel/gateway/Plugin SDK 表面時執行。僅來源的 bundled Plugin 變更、僅測試編輯與僅文件編輯不會保留 Docker worker。快速路徑會建置一次根 Dockerfile 映像、檢查 CLI、執行 agents delete shared-workspace CLI smoke、執行 container gateway-network e2e、驗證 bundled extension build arg,並在 240 秒彙總命令逾時內執行有界限的 bundled-plugin Docker 設定檔(每個情境的 Docker 執行會分別設上限)。
|
||||
- **完整路徑** 保留 QR package install 與 installer Docker/update 覆蓋範圍,用於夜間排程執行、手動派送、workflow-call 發行檢查,以及真正觸及 installer/package/Docker 表面的 pull request。在完整模式中,install-smoke 會準備或重用一個 target-SHA GHCR 根 Dockerfile smoke 映像,然後將 QR package install、根 Dockerfile/gateway smoke、installer/update smoke,以及快速 bundled-plugin Docker E2E 作為獨立 job 執行,因此 installer 工作不必等在根映像 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。
|
||||
|
||||
`main` 推送(包含 merge commit)不會強制使用完整路徑;當變更範圍邏輯在 push 上要求完整覆蓋時,workflow 會保留快速 Docker smoke,並將完整 install smoke 留給夜間或發行驗證。
|
||||
`main` push(包括 merge commit)不會強制完整路徑;當變更範圍邏輯會在 push 上要求完整覆蓋範圍時,workflow 會保留快速 Docker smoke,並將完整 install smoke 留給夜間或發行驗證。
|
||||
|
||||
較慢的 Bun 全域安裝 image-provider smoke 由 `run_bun_global_install_smoke` 另行控管。它會在夜間排程與發行檢查 workflow 中執行,手動 `Install Smoke` 派送也可以選擇加入,但 pull request 與 `main` 推送不會執行。QR 與 installer Docker 測試保留各自聚焦於安裝的 Dockerfile。
|
||||
慢速的 Bun 全域安裝 image-provider smoke 由 `run_bun_global_install_smoke` 另行控管。它會在夜間排程和發行檢查 workflow 中執行,手動 `Install Smoke` dispatch 可以選擇加入,但 pull request 和 `main` push 不會。QR 和安裝程式 Docker 測試保留各自專注於安裝的 Dockerfile。
|
||||
|
||||
## 本機 Docker E2E
|
||||
|
||||
`pnpm test:docker:all` 會預先建置一個共用 live-test 映像,將 OpenClaw 封裝一次為 npm tarball,並建置兩個共用 `scripts/e2e/Dockerfile` 映像:
|
||||
`pnpm test:docker:all` 會預先建置一個共享 live-test image、將 OpenClaw 封裝一次為 npm tarball,並建置兩個共享 `scripts/e2e/Dockerfile` images:
|
||||
|
||||
- 用於 installer/update/plugin-dependency lane 的裸 Node/Git runner;
|
||||
- 將相同 tarball 安裝到 `/app` 的功能性映像,用於一般功能 lane。
|
||||
- 用於安裝程式/update/Plugin 相依性 lane 的裸 Node/Git runner;
|
||||
- 將相同 tarball 安裝到 `/app` 的功能 image,用於一般功能 lane。
|
||||
|
||||
Docker lane 定義位於 `scripts/lib/docker-e2e-scenarios.mjs`,規劃器邏輯位於 `scripts/lib/docker-e2e-plan.mjs`,runner 只會執行選定的計畫。排程器會使用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 與 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 為每個 lane 選擇映像,然後以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行 lane。
|
||||
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。
|
||||
|
||||
### 可調整項目
|
||||
### 可調參數
|
||||
|
||||
| 變數 | 預設值 | 目的 |
|
||||
| 變數 | 預設值 | 用途 |
|
||||
| -------------------------------------- | ------- | --------------------------------------------------------------------------------------------- |
|
||||
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 一般 lane 的主 pool slot 數量。 |
|
||||
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 對 provider 敏感的 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 | 同時執行的多服務 lane 上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | lane 啟動之間的錯開時間,用於避免 Docker daemon 建立風暴;設為 `0` 表示不錯開。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每個 lane 的備援逾時(120 分鐘);選定的 live/tail lane 使用更嚴格的上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` 會列印排程器計畫而不執行 lane。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANES` | unset | 以逗號分隔的精確 lane 清單;略過清理 smoke,讓 agent 可以重現單一失敗 lane。 |
|
||||
| `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。 |
|
||||
|
||||
比有效上限更重的 lane 仍可從空 pool 啟動,然後單獨執行直到釋放容量。本機彙總流程會預檢 Docker、移除過時的 OpenClaw E2E 容器、輸出作用中 lane 狀態、保存 lane 耗時供 longest-first 排序使用,且預設在第一次失敗後停止排程新的 pooled lane。
|
||||
比有效上限更重的 lane 仍可從空 pool 啟動,然後單獨執行直到釋放容量。本機彙總會 preflight Docker、移除過期的 OpenClaw E2E 容器、發出 active-lane 狀態、保存 lane 計時以便 longest-first 排序,並預設在第一次失敗後停止排程新的 pooled lane。
|
||||
|
||||
### 可重用 live/E2E workflow
|
||||
### 可重用的 live/E2E workflow
|
||||
|
||||
可重用 live/E2E workflow 會詢問 `scripts/test-docker-all.mjs --plan-json` 需要哪些套件、映像種類、live 映像、lane 與憑證覆蓋範圍。`scripts/docker-e2e.mjs` 接著會將該計畫轉換為 GitHub 輸出與摘要。它會透過 `scripts/package-openclaw-for-docker.mjs` 封裝 OpenClaw、下載目前執行的套件 artifact,或從 `package_artifact_run_id` 下載套件 artifact;驗證 tarball 清單;在計畫需要已安裝套件的 lane 時,透過 Blacksmith 的 Docker layer cache 建置並推送以套件 digest 標記的裸/功能性 GHCR Docker E2E 映像;並重用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 輸入或既有套件 digest 映像,而非重新建置。Docker 映像 pull 會以有界限的每次嘗試 180 秒逾時重試,因此卡住的 registry/cache stream 會快速重試,而不是耗盡大部分 CI 關鍵路徑。
|
||||
可重用的 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 關鍵路徑。
|
||||
|
||||
### 發行路徑區塊
|
||||
|
||||
發行 Docker 覆蓋範圍會以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行較小的分塊 job,因此每個區塊只會 pull 它需要的映像種類,並透過相同加權排程器執行多個 lane:
|
||||
發行 Docker 覆蓋範圍會以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行較小的分塊 jobs,因此每個區塊只會 pull 它需要的 image kind,並透過相同的加權排程器執行多個 lanes:
|
||||
|
||||
- `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` 通道別名仍是兩個供應商安裝程式通道的彙總手動重新執行別名。`bundled-channels` 分塊會執行拆分的 `bundled-channel-*` 和 `bundled-channel-update-*` 通道,而不是序列式全包的 `bundled-channel-deps` 通道。
|
||||
|
||||
當完整發行路徑涵蓋範圍要求時,OpenWebUI 會併入 `plugins-runtime-services`,且只有在僅限 OpenWebUI 的分派中才保留獨立的 `openwebui` 區塊。Bundled-channel 更新通道會對暫時性 npm 網路失敗重試一次。
|
||||
當完整發行路徑涵蓋範圍要求時,OpenWebUI 會併入 `plugins-runtime-services`,並且只在僅限 OpenWebUI 的派送中保留獨立的 `openwebui` 分塊。內建通道更新通道會針對暫時性 npm 網路失敗重試一次。
|
||||
|
||||
每個區塊都會上傳 `.artifacts/docker-tests/`,其中包含通道記錄、計時、`summary.json`、`failures.json`、階段計時、排程器計畫 JSON、慢速通道表格,以及每個通道的重新執行命令。工作流程 `docker_lanes` 輸入會針對已準備好的映像執行選取的通道,而不是區塊作業,這會將失敗通道的偵錯限制在單一目標 Docker 作業中,並為該次執行準備、下載或重用套件成品;如果選取的通道是即時 Docker 通道,目標作業會為該次重新執行在本機建置即時測試映像。產生的每通道 GitHub 重新執行命令會在這些值存在時包含 `package_artifact_run_id`、`package_artifact_name` 和已準備映像輸入,因此失敗通道可以重用失敗執行中的確切套件與映像。
|
||||
每個分塊都會上傳 `.artifacts/docker-tests/`,其中包含通道記錄、計時、`summary.json`、`failures.json`、階段計時、排程器計畫 JSON、慢速通道表格,以及每個通道的重新執行命令。工作流程的 `docker_lanes` 輸入會針對已準備的映像執行所選通道,而不是分塊作業,這會將失敗通道的偵錯限制在一個目標 Docker 作業內,並為該次執行準備、下載或重用套件成品;如果所選通道是即時 Docker 通道,目標作業會在本機建置即時測試映像以供該次重新執行使用。產生的每個通道 GitHub 重新執行命令會在這些值存在時包含 `package_artifact_run_id`、`package_artifact_name` 和已準備映像輸入,因此失敗的通道可以重用失敗執行中的確切套件與映像。
|
||||
|
||||
```bash
|
||||
pnpm test:docker:rerun <run-id> # download Docker artifacts and print combined/per-lane targeted rerun commands
|
||||
pnpm test:docker:timings <summary> # slow-lane and phase critical-path summaries
|
||||
```
|
||||
|
||||
排程的即時/E2E 工作流程會每日執行完整發行路徑 Docker 套件。
|
||||
排程的即時/E2E 工作流程會每日執行完整的發行路徑 Docker 套件。
|
||||
|
||||
## Plugin 預發行
|
||||
|
||||
`Plugin Prerelease` 是成本較高的產品/套件涵蓋範圍,因此它是由 `Full Release Validation` 或明確操作員分派的獨立工作流程。一般 pull request、`main` 推送,以及獨立的手動 CI 分派都不會啟用該套件。它會在八個 extension worker 之間平衡 bundled Plugin 測試;這些 extension shard 作業一次最多執行兩個 Plugin 設定群組,每個群組使用一個 Vitest worker,並使用較大的 Node heap,因此匯入量大的 Plugin 批次不會建立額外的 CI 作業。
|
||||
`Plugin Prerelease` 是成本較高的產品/套件涵蓋範圍,因此它是由 `Full Release Validation` 或明確的操作員派送的獨立工作流程。一般 pull request、`main` 推送,以及獨立的手動 CI 派送會保持該套件關閉。它會在八個擴充工作器之間平衡內建 Plugin 測試;這些擴充分片作業每次最多執行兩個 Plugin 設定群組,每個群組使用一個 Vitest 工作器和較大的 Node heap,讓匯入量大的 Plugin 批次不會建立額外的 CI 作業。
|
||||
|
||||
## QA Lab
|
||||
|
||||
QA Lab 在主要智慧範圍工作流程之外有專用 CI 通道。
|
||||
QA Lab 在主要的智慧範圍工作流程之外有專用的 CI 通道。
|
||||
|
||||
- `Parity gate` 工作流程會在符合的 PR 變更和手動分派時執行;它會建置私有 QA runtime,並比較 mock GPT-5.5 與 Opus 4.6 agentic packs。
|
||||
- `QA-Lab - All Lanes` 工作流程會每晚在 `main` 上和手動分派時執行;它會將 mock parity gate、即時 Matrix 通道,以及即時 Telegram 和 Discord 通道展開為平行作業。即時作業使用 `qa-live-shared` 環境,而 Telegram/Discord 使用 Convex leases。
|
||||
- `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 租約。
|
||||
|
||||
發行檢查會使用確定性的 mock 供應商和 mock 限定模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)執行 Matrix 與 Telegram 即時傳輸通道,因此通道合約會與即時模型延遲和一般供應商 Plugin 啟動隔離。即時傳輸 Gateway 會停用記憶體搜尋,因為 QA parity 會另外涵蓋記憶體行為;供應商連線能力則由獨立的即時模型、原生供應商和 Docker 供應商套件涵蓋。
|
||||
發行檢查會使用確定性的模擬供應商和符合模擬資格的模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)執行 Matrix 和 Telegram 即時傳輸通道,因此通道合約會與即時模型延遲和一般供應商 Plugin 啟動隔離。即時傳輸 Gateway 會停用記憶搜尋,因為 QA 同位會另外涵蓋記憶行為;供應商連線能力由獨立的即時模型、原生供應商和 Docker 供應商套件涵蓋。
|
||||
|
||||
Matrix 對排程和發行 gate 使用 `--profile fast`,只有在簽出的 CLI 支援時才加入 `--fail-fast`。CLI 預設值與手動工作流程輸入仍為 `all`;手動 `matrix_profile=all` 分派一律會將完整 Matrix 涵蓋範圍分片為 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作業。
|
||||
Matrix 會在排程和發行閘門使用 `--profile fast`,並且只在簽出的 CLI 支援時加入 `--fail-fast`。CLI 預設值和手動工作流程輸入仍為 `all`;手動 `matrix_profile=all` 派送一律會將完整 Matrix 涵蓋範圍分片為 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作業。
|
||||
|
||||
`OpenClaw Release Checks` 也會在發行核准前執行發行關鍵的 QA Lab 通道;其 QA parity gate 會將候選與基準 packs 作為平行通道作業執行,然後將兩個成品下載到小型報告作業中,進行最終 parity 比較。
|
||||
`OpenClaw Release Checks` 也會在發行核准前執行發行關鍵的 QA Lab 通道;它的 QA 同位閘門會將候選與基準套件作為平行通道作業執行,接著將兩個成品下載到一個小型報告作業中進行最終同位比較。
|
||||
|
||||
除非變更實際觸及 QA runtime、model-pack parity,或 parity 工作流程擁有的表面,否則不要把 PR landing path 放在 `Parity gate` 後方。對於一般通道、設定、文件或單元測試修正,請將它視為選用訊號,並遵循範圍化的 CI/檢查證據。
|
||||
除非變更實際觸及 QA runtime、模型套件同位,或同位工作流程擁有的表面,否則不要將 PR 合併路徑置於 `Parity gate` 之後。對於一般通道、設定、文件或單元測試修正,請將其視為選用訊號,並遵循範圍化 CI/檢查證據。
|
||||
|
||||
## CodeQL
|
||||
|
||||
`CodeQL` 工作流程有意作為窄範圍的第一道安全掃描器,而不是完整儲存庫掃描。每日、手動和非草稿 pull request guard 執行會掃描 Actions 工作流程程式碼,加上最高風險的 JavaScript/TypeScript 表面,並使用高信心安全查詢篩選到高/重大 `security-severity`。
|
||||
`CodeQL` 工作流程刻意作為狹窄的第一輪安全掃描器,而不是完整儲存庫掃描。每日、手動和非草稿 pull request 守門執行會掃描 Actions 工作流程程式碼,以及最高風險的 JavaScript/TypeScript 表面,並使用高信心安全查詢,篩選為高/嚴重 `security-severity`。
|
||||
|
||||
pull request guard 保持輕量:它只會針對 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 底下的變更啟動,並執行與排程工作流程相同的高信心安全矩陣。Android 和 macOS CodeQL 不屬於 PR 預設值。
|
||||
pull request 守門保持輕量:它只會在 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 底下的變更啟動,並執行與排程工作流程相同的高信心安全矩陣。Android 和 macOS CodeQL 不包含在 PR 預設值中。
|
||||
|
||||
### 安全性類別
|
||||
### 安全類別
|
||||
|
||||
| 類別 | 表面 |
|
||||
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/codeql-security-high/core-auth-secrets` | 驗證、密鑰、沙箱、Cron 和 Gateway 基準 |
|
||||
| `/codeql-security-high/channel-runtime-boundary` | 核心通道實作合約,加上通道 Plugin runtime、Gateway、Plugin SDK、密鑰、稽核接觸點 |
|
||||
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、網路 guard、web-fetch,以及 Plugin SDK SSRF 政策表面 |
|
||||
| `/codeql-security-high/mcp-process-tool-boundary` | MCP 伺服器、程序執行 helper、對外傳遞,以及 agent tool-execution gates |
|
||||
| `/codeql-security-high/plugin-trust-boundary` | Plugin 安裝、loader、manifest、registry、runtime-dependency staging、source-loading,以及 Plugin SDK 套件合約信任表面 |
|
||||
| `/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 Android Critical Security` — 排程的 Android 安全性分片。為 CodeQL 在 workflow sanity 接受的最小 Blacksmith Linux runner 上手動建置 Android app。上傳到 `/codeql-critical-security/android`。
|
||||
- `CodeQL macOS Critical Security` — 每週/手動 macOS 安全性分片。為 CodeQL 在 Blacksmith macOS 上手動建置 macOS app,從上傳的 SARIF 中篩除相依性建置結果,並上傳到 `/codeql-critical-security/macos`。因為即使乾淨時 macOS 建置也主導 runtime,所以保留在每日預設值之外。
|
||||
- `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,所以保留在每日預設值之外。
|
||||
|
||||
### Critical Quality 類別
|
||||
### 關鍵品質類別
|
||||
|
||||
`CodeQL Critical Quality` 是對應的非安全性分片。它只會在較小的 Blacksmith Linux runner 上,對窄範圍高價值表面執行錯誤嚴重度、非安全性 JavaScript/TypeScript 品質查詢。它的 pull request guard 有意比排程設定檔更小:非草稿 PR 只會針對 agent 命令/模型/工具執行與回覆分派程式碼、設定 schema/migration/IO 程式碼、驗證/密鑰/沙箱/安全性程式碼、核心通道與 bundled 通道 Plugin runtime、Gateway 協定/server-method、記憶體 runtime/SDK glue、MCP/process/outbound delivery、供應商 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` 是對應的非安全分片。它只在較小的 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 品質分片。
|
||||
|
||||
手動分派接受:
|
||||
手動派送接受:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
窄範圍設定檔是用於隔離執行單一品質分片的教學/迭代 hook。
|
||||
狹窄設定檔是用於單獨執行一個品質分片的教學/迭代掛鉤。
|
||||
|
||||
| 類別 | 涵蓋範圍 |
|
||||
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/codeql-critical-quality/core-auth-secrets` | Auth、secrets、sandbox、Cron,以及 Gateway 安全邊界程式碼 |
|
||||
| `/codeql-critical-quality/config-boundary` | 設定結構描述、遷移、正規化,以及 IO 合約 |
|
||||
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 協定結構描述與伺服器方法合約 |
|
||||
| `/codeql-critical-quality/channel-runtime-boundary` | 核心 channel 與內建 channel 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 傳入回覆分派、回覆酬載/分塊/執行階段輔助工具、channel 回覆選項、傳遞佇列,以及工作階段/thread 繫結輔助工具 |
|
||||
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目錄正規化、提供者驗證與探索、提供者執行階段註冊、提供者預設值/目錄,以及 web/search/fetch/embedding 登錄表 |
|
||||
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 啟動、本機持久化、Gateway 控制流程,以及任務控制平面執行階段合約 |
|
||||
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 web fetch/search、媒體 IO、媒體理解、影像生成,以及媒體生成執行階段合約 |
|
||||
| `/codeql-critical-quality/plugin-boundary` | 載入器、登錄表、公用表面,以及 Plugin SDK 進入點合約 |
|
||||
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已發布套件端 Plugin SDK 原始碼與 Plugin 套件合約輔助工具 |
|
||||
| 類別 | 介面 |
|
||||
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `/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/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 套件合約輔助工具 |
|
||||
|
||||
品質與安全維持分離,讓品質發現可以排程、量測、停用或擴充,而不會掩蓋安全訊號。Swift、Python,以及內建 Plugin 的 CodeQL 擴充,應只在狹窄設定檔具備穩定執行階段與訊號之後,再作為有範圍或分片的後續工作加回。
|
||||
品質會與安全性分開,因此品質發現可以排程、衡量、停用或擴充,而不會掩蓋安全性訊號。Swift、Python 與隨附 Plugin 的 CodeQL 擴充,應只在窄範圍設定檔具備穩定執行階段與訊號之後,作為具範圍或分片的後續工作加回。
|
||||
|
||||
## 維護工作流程
|
||||
|
||||
### 文件 Agent
|
||||
|
||||
`Docs Agent` 工作流程是一條事件驅動的 Codex 維護路徑,用於讓現有文件與最近落地的變更保持一致。它沒有純排程:`main` 上成功的非 bot push CI 執行可以觸發它,也可以透過手動分派直接執行。當 `main` 已經前進,或過去一小時內已有另一個未略過的 Docs Agent 執行被建立時,workflow-run 呼叫會略過。執行時,它會檢視從上一個未略過的 Docs Agent 來源 SHA 到目前 `main` 的提交範圍,因此每小時一次的執行可以涵蓋自上次文件檢查以來累積的所有 main 變更。
|
||||
`Docs Agent` 工作流程是一條事件驅動的 Codex 維護通道,用於讓現有文件與最近落地的變更保持一致。它沒有純排程:在 `main` 上成功的非機器人推送 CI 執行可以觸發它,手動派送也可以直接執行它。當 `main` 已前進,或上一小時內已建立另一個未略過的 Docs Agent 執行時,工作流程執行叫用會略過。執行時,它會審查從前一個未略過的 Docs Agent 來源 SHA 到目前 `main` 的提交範圍,因此一次每小時執行可以涵蓋自上次文件巡檢以來累積的所有 main 變更。
|
||||
|
||||
### 測試效能 Agent
|
||||
|
||||
`Test Performance Agent` 工作流程是一條事件驅動的 Codex 維護路徑,用於處理慢速測試。它沒有純排程:`main` 上成功的非 bot push CI 執行可以觸發它,但如果另一個 workflow-run 呼叫在該 UTC 日已經執行或正在執行,它會略過。手動分派會繞過每日活動閘門。這條路徑會建立完整套件分組 Vitest 效能報告,讓 Codex 只進行小型且保留覆蓋率的測試效能修正,而不是大範圍重構,接著重新執行完整套件報告,並拒絕會降低通過基準測試數量的變更。如果基準有失敗測試,Codex 只能修正明顯的失敗,且 agent 後的完整套件報告必須通過後才會提交任何內容。當 bot push 落地前 `main` 又前進時,這條路徑會 rebase 已驗證的 patch、重新執行 `pnpm check:changed`,並重試 push;有衝突的過期 patch 會被略過。它使用 GitHub 託管的 Ubuntu,因此 Codex action 可以維持與 docs agent 相同的 drop-sudo 安全姿態。
|
||||
`Test Performance Agent` 工作流程是一條事件驅動的 Codex 維護通道,用於處理緩慢測試。它沒有純排程:在 `main` 上成功的非機器人推送 CI 執行可以觸發它,但如果另一個工作流程執行叫用在該 UTC 日已經執行或正在執行,它就會略過。手動派送會略過該每日活動閘門。此通道會建立完整套件分組 Vitest 效能報告,讓 Codex 只進行小型且保留覆蓋率的測試效能修正,而不是大範圍重構,接著重新執行完整套件報告,並拒絕會降低通過基準測試數量的變更。如果基準有失敗測試,Codex 只能修正明顯的失敗,而且 Agent 後的完整套件報告必須通過,才會提交任何內容。當 `main` 在機器人推送落地前前進時,此通道會將已驗證的修補重新基底化、重新執行 `pnpm check:changed`,並重試推送;有衝突的過期修補會被略過。它使用 GitHub 託管的 Ubuntu,因此 Codex 動作可以維持與文件 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 \
|
||||
@ -394,27 +394,27 @@ gh workflow run duplicate-after-merge.yml \
|
||||
|
||||
## 本機檢查閘門與變更路由
|
||||
|
||||
本機 changed-lane 邏輯位於 `scripts/changed-lanes.mjs`,並由 `scripts/check-changed.mjs` 執行。該本機檢查閘門對架構邊界的要求比廣泛 CI 平台範圍更嚴格:
|
||||
本機變更通道邏輯位於 `scripts/changed-lanes.mjs`,並由 `scripts/check-changed.mjs` 執行。該本機檢查閘門對架構邊界比廣泛 CI 平台範圍更嚴格:
|
||||
|
||||
- 核心 production 變更會執行核心 prod 與核心 test 型別檢查,加上核心 lint/guards;
|
||||
- 僅核心測試的變更只會執行核心 test 型別檢查,加上核心 lint;
|
||||
- extension production 變更會執行 extension prod 與 extension test 型別檢查,加上 extension lint;
|
||||
- 僅 extension 測試的變更會執行 extension test 型別檢查,加上 extension lint;
|
||||
- 公用 Plugin SDK 或 Plugin 合約變更會擴展到 extension 型別檢查,因為 extensions 依賴這些核心合約(Vitest extension 掃描仍然是明確的測試工作);
|
||||
- 僅 release metadata 的版本 bump 會執行目標式版本/設定/root-dependency 檢查;
|
||||
- 未知的 root/config 變更會 fail safe 到所有檢查路徑。
|
||||
- 核心生產變更會執行核心生產與核心測試型別檢查,加上核心 lint/guard;
|
||||
- 僅核心測試變更只會執行核心測試型別檢查,加上核心 lint;
|
||||
- 擴充功能生產變更會執行擴充功能生產與擴充功能測試型別檢查,加上擴充功能 lint;
|
||||
- 僅擴充功能測試變更會執行擴充功能測試型別檢查,加上擴充功能 lint;
|
||||
- 公開 Plugin SDK 或 Plugin 合約變更會擴大到擴充功能型別檢查,因為擴充功能依賴這些核心合約(Vitest 擴充功能掃描仍是明確的測試工作);
|
||||
- 僅發布中繼資料的版本升級會執行目標式版本/設定/根相依性檢查;
|
||||
- 未知根目錄/設定變更會以安全失敗方式進入所有檢查通道。
|
||||
|
||||
本機 changed-test 路由位於 `scripts/test-projects.test-support.mjs`,刻意比 `check:changed` 更便宜:直接測試編輯會執行自身,原始碼編輯會優先使用明確映射,接著是同層測試與 import graph 相依項。共享 group-room 傳遞設定是明確映射之一:對 group visible-reply 設定、source reply delivery mode,或 message-tool system prompt 的變更,會透過核心回覆測試加上 Discord 與 Slack 傳遞回歸測試進行路由,因此共享預設值變更會在第一次 PR push 前失敗。只有當變更的範圍廣到便宜映射集合不再是可信代理時,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
本機變更測試路由位於 `scripts/test-projects.test-support.mjs`,且刻意比 `check:changed` 更便宜:直接測試編輯會執行自身,原始碼編輯優先使用明確對應,接著是同層測試與匯入圖相依項。共用群組房間傳遞設定是其中一個明確對應:群組可見回覆設定、來源回覆傳遞模式,或訊息工具系統提示的變更,會透過核心回覆測試加上 Discord 與 Slack 傳遞回歸測試路由,因此共用預設值變更會在第一次 PR 推送前失敗。只有在變更的範圍涵蓋整個測試框架,使得便宜的對應集合不是可信代理時,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
|
||||
## Testbox 驗證
|
||||
|
||||
從 repo root 執行 Testbox,並優先為廣泛證明使用新的已暖機 box。在把慢速閘門花在重複使用、過期,或剛回報非預期大量同步的 box 之前,先在 box 內執行 `pnpm testbox:sanity`。
|
||||
從 repo 根目錄執行 Testbox,並優先使用全新預熱的 box 進行廣泛證明。在把緩慢閘門花在已重用、過期,或剛回報異常大量同步的 box 之前,先在 box 內執行 `pnpm testbox:sanity`。
|
||||
|
||||
當必要 root 檔案如 `pnpm-lock.yaml` 消失,或 `git status --short` 顯示至少 200 個已追蹤刪除時,sanity check 會快速失敗。這通常代表遠端同步狀態不是 PR 的可信副本;請停止該 box 並暖機新的 box,而不是偵錯產品測試失敗。對於刻意的大量刪除 PR,為該 sanity 執行設定 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。
|
||||
當必要根目錄檔案(例如 `pnpm-lock.yaml`)消失,或 `git status --short` 顯示至少 200 個已追蹤刪除時,健全性檢查會快速失敗。這通常代表遠端同步狀態不是 PR 的可信副本;請停止該 box 並預熱新的,而不是偵錯產品測試失敗。對於刻意的大量刪除 PR,請為該健全性執行設定 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。
|
||||
|
||||
`pnpm testbox:run` 也會終止停留在同步階段超過五分鐘且沒有同步後輸出的本機 Blacksmith CLI 呼叫。設定 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可停用該保護,或針對異常大的本機 diff 使用較大的毫秒值。
|
||||
`pnpm testbox:run` 也會終止本機 Blacksmith CLI 叫用,如果它停留在同步階段超過五分鐘且沒有同步後輸出。設定 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可停用該 guard,或針對異常大的本機 diff 使用更大的毫秒值。
|
||||
|
||||
## 相關
|
||||
|
||||
- [安裝概覽](/zh-TW/install)
|
||||
- [開發 channel](/zh-TW/install/development-channels)
|
||||
- [開發通道](/zh-TW/install/development-channels)
|
||||
|
||||
@ -1,48 +1,48 @@
|
||||
---
|
||||
read_when:
|
||||
- 您需要 agent 迴圈或生命週期事件的精確逐步解說
|
||||
- 你正在變更工作階段佇列、逐字稿寫入或工作階段寫入鎖定行為
|
||||
- 你需要代理迴圈或生命週期事件的精確逐步說明
|
||||
- 你正在變更工作階段佇列處理、對話紀錄寫入,或工作階段寫入鎖定行為
|
||||
summary: 代理程式迴圈生命週期、串流與等待語意
|
||||
title: 代理程式迴圈
|
||||
title: 代理迴圈
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T02:57:55Z"
|
||||
generated_at: "2026-04-30T18:38:37Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 902d543bd71dd517a810d825cbe92e244fe89230f47eeada72477c657a2bec32
|
||||
source_hash: 5466893253e1f82482284ff82db56f4c3fca018bf12e4114fad76d37cad954df
|
||||
source_path: concepts/agent-loop.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
代理式迴圈是代理的完整「真實」執行流程:接收 → 組裝脈絡 → 模型推論 →
|
||||
工具執行 → 串流回覆 → 持久化。它是將訊息轉換成動作與最終回覆的權威路徑,
|
||||
代理式迴圈是代理的完整「真實」執行流程:接收 → 組裝內容脈絡 → 模型推論 →
|
||||
工具執行 → 串流回覆 → 持久化。這是將訊息轉換為動作與最終回覆的權威路徑,
|
||||
同時保持工作階段狀態一致。
|
||||
|
||||
在 OpenClaw 中,迴圈是每個工作階段一次單一、序列化的執行,會在模型思考、
|
||||
呼叫工具並串流輸出時發出生命週期與串流事件。本文件說明這個真實迴圈如何
|
||||
端到端串接。
|
||||
在 OpenClaw 中,迴圈是每個工作階段一次單一、序列化的執行,會在模型思考、呼叫工具
|
||||
並串流輸出時發出生命週期與串流事件。本文件說明這個真實迴圈如何從端到端串接。
|
||||
|
||||
## 進入點
|
||||
|
||||
- Gateway RPC:`agent` 與 `agent.wait`。
|
||||
- Gateway RPC:`agent` 和 `agent.wait`。
|
||||
- CLI:`agent` 指令。
|
||||
|
||||
## 運作方式(高階)
|
||||
## 運作方式(高層次)
|
||||
|
||||
1. `agent` RPC 會驗證參數、解析工作階段(sessionKey/sessionId)、持久化工作階段中繼資料,並立即回傳 `{ runId, acceptedAt }`。
|
||||
2. `agentCommand` 執行代理:
|
||||
2. `agentCommand` 會執行代理:
|
||||
- 解析模型 + thinking/verbose/trace 預設值
|
||||
- 載入 Skills 快照
|
||||
- 呼叫 `runEmbeddedPiAgent`(pi-agent-core 執行階段)
|
||||
- 如果內嵌迴圈未發出生命週期結束/錯誤,則發出 **lifecycle end/error**
|
||||
- 如果嵌入式迴圈沒有發出生命週期結束/錯誤,則發出 **lifecycle end/error**
|
||||
3. `runEmbeddedPiAgent`:
|
||||
- 透過每工作階段 + 全域佇列序列化執行
|
||||
- 解析模型 + 驗證設定檔並建立 pi 工作階段
|
||||
- 訂閱 pi 事件並串流 assistant/tool 增量
|
||||
- 強制執行逾時 -> 若超過則中止執行
|
||||
- 回傳 payload + 用量中繼資料
|
||||
4. `subscribeEmbeddedPiSession` 將 pi-agent-core 事件橋接到 OpenClaw `agent` 串流:
|
||||
- 透過每個工作階段 + 全域佇列序列化執行
|
||||
- 解析模型 + 驗證設定檔,並建立 Pi 工作階段
|
||||
- 訂閱 Pi 事件,並串流 assistant/tool 增量
|
||||
- 強制執行逾時 -> 若超過時間則中止執行
|
||||
- 針對 Codex app-server 回合,在終端事件前,如果已接受的回合停止產生 app-server 進度,則中止該回合
|
||||
- 回傳 payload + 使用量中繼資料
|
||||
4. `subscribeEmbeddedPiSession` 會將 pi-agent-core 事件橋接到 OpenClaw `agent` 串流:
|
||||
- 工具事件 => `stream: "tool"`
|
||||
- 助理增量 => `stream: "assistant"`
|
||||
- assistant 增量 => `stream: "assistant"`
|
||||
- 生命週期事件 => `stream: "lifecycle"`(`phase: "start" | "end" | "error"`)
|
||||
5. `agent.wait` 使用 `waitForAgentRun`:
|
||||
- 等待 `runId` 的 **lifecycle end/error**
|
||||
@ -50,79 +50,82 @@ x-i18n:
|
||||
|
||||
## 佇列 + 並行
|
||||
|
||||
- 執行會依工作階段金鑰(工作階段通道)序列化,並可選擇經由全域通道。
|
||||
- 執行會依工作階段鍵(工作階段通道)序列化,並可選擇透過全域通道序列化。
|
||||
- 這可防止工具/工作階段競態,並保持工作階段歷史一致。
|
||||
- 訊息通道可以選擇佇列模式(collect/steer/followup),以輸入這套通道系統。
|
||||
- 訊息通道可以選擇佇列模式(collect/steer/followup),並將其送入此通道系統。
|
||||
請參閱[指令佇列](/zh-TW/concepts/queue)。
|
||||
- 轉錄寫入也會受到工作階段檔案上的工作階段寫入鎖保護。該鎖具有程序感知能力且以檔案為基礎,
|
||||
因此能捕捉到繞過程序內佇列或來自其他程序的寫入者。
|
||||
- 工作階段寫入鎖預設不可重入。如果某個輔助程式刻意在保留單一邏輯寫入者的同時,
|
||||
巢狀取得相同鎖,則必須以 `allowReentrant: true` 明確選擇加入。
|
||||
- Transcript 寫入也受到工作階段檔案上的工作階段寫入鎖保護。該鎖具備
|
||||
程序感知能力且以檔案為基礎,因此能捕捉繞過程序內佇列或來自
|
||||
其他程序的寫入者。
|
||||
- 工作階段寫入鎖預設不可重入。如果輔助工具刻意巢狀取得
|
||||
同一把鎖,同時保留一個邏輯寫入者,則必須使用
|
||||
`allowReentrant: true` 明確選擇加入。
|
||||
|
||||
## 工作階段 + 工作區準備
|
||||
|
||||
- 工作區會被解析並建立;沙盒化執行可能會重新導向到沙盒工作區根目錄。
|
||||
- Skills 會被載入(或從快照重用),並注入到環境與提示中。
|
||||
- Bootstrap/脈絡檔案會被解析,並注入到系統提示報告中。
|
||||
- 會取得工作階段寫入鎖;`SessionManager` 會在串流前開啟並準備好。任何
|
||||
後續轉錄重寫、Compaction 或截斷路徑,都必須在開啟或變更轉錄檔前取得相同鎖。
|
||||
- 會解析並建立工作區;沙盒化執行可能會重新導向到沙盒工作區根目錄。
|
||||
- 會載入 Skills(或重用快照),並注入 env 與提示詞。
|
||||
- 會解析 bootstrap/context 檔案,並注入系統提示詞報告。
|
||||
- 會取得工作階段寫入鎖;`SessionManager` 會在串流前開啟並準備完成。任何
|
||||
後續的 transcript 重寫、Compaction 或截斷路徑,都必須在開啟或
|
||||
修改 transcript 檔案前取得同一把鎖。
|
||||
|
||||
## 提示組裝 + 系統提示
|
||||
## 提示詞組裝 + 系統提示詞
|
||||
|
||||
- 系統提示會由 OpenClaw 的基礎提示、Skills 提示、bootstrap 脈絡與每次執行覆寫建立。
|
||||
- 會強制套用模型特定限制與 Compaction 保留 token。
|
||||
- 請參閱[系統提示](/zh-TW/concepts/system-prompt),了解模型會看到什麼。
|
||||
- 系統提示詞由 OpenClaw 的基礎提示詞、Skills 提示詞、bootstrap 內容脈絡,以及每次執行的覆寫組成。
|
||||
- 會強制執行模型特定限制與 Compaction 保留 token。
|
||||
- 請參閱[系統提示詞](/zh-TW/concepts/system-prompt),了解模型會看到的內容。
|
||||
|
||||
## 掛鉤點(可攔截的位置)
|
||||
## Hook 點(你可以攔截的位置)
|
||||
|
||||
OpenClaw 有兩套掛鉤系統:
|
||||
OpenClaw 有兩套 Hook 系統:
|
||||
|
||||
- **內部掛鉤**(Gateway 掛鉤):用於指令與生命週期事件的事件驅動腳本。
|
||||
- **Plugin 掛鉤**:代理/工具生命週期與 Gateway 管線內的擴充點。
|
||||
- **內部 Hook**(Gateway Hook):針對指令與生命週期事件的事件驅動腳本。
|
||||
- **Plugin Hook**:代理/工具生命週期與 gateway 管線中的擴充點。
|
||||
|
||||
### 內部掛鉤(Gateway 掛鉤)
|
||||
### 內部 Hook(Gateway Hook)
|
||||
|
||||
- **`agent:bootstrap`**:在系統提示完成前,建立 bootstrap 檔案時執行。
|
||||
使用這個掛鉤新增/移除 bootstrap 脈絡檔案。
|
||||
- **指令掛鉤**:`/new`、`/reset`、`/stop`,以及其他指令事件(請參閱 Hooks 文件)。
|
||||
- **`agent:bootstrap`**:在系統提示詞完成前,建置 bootstrap 檔案時執行。
|
||||
使用此 Hook 來新增/移除 bootstrap 內容脈絡檔案。
|
||||
- **指令 Hook**:`/new`、`/reset`、`/stop`,以及其他指令事件(請參閱 Hook 文件)。
|
||||
|
||||
請參閱[掛鉤](/zh-TW/automation/hooks)取得設定與範例。
|
||||
請參閱 [Hook](/zh-TW/automation/hooks) 了解設定與範例。
|
||||
|
||||
### Plugin 掛鉤(代理 + Gateway 生命週期)
|
||||
### Plugin Hook(代理 + gateway 生命週期)
|
||||
|
||||
這些掛鉤會在代理迴圈或 Gateway 管線內執行:
|
||||
這些 Hook 會在代理迴圈或 gateway 管線內執行:
|
||||
|
||||
- **`before_model_resolve`**:在工作階段前執行(沒有 `messages`),以便在模型解析前以決定性方式覆寫供應商/模型。
|
||||
- **`before_prompt_build`**:在工作階段載入後執行(含 `messages`),以便在提交提示前注入 `prependContext`、`systemPrompt`、`prependSystemContext` 或 `appendSystemContext`。將 `prependContext` 用於每回合動態文字,將系統脈絡欄位用於應位於系統提示空間中的穩定指引。
|
||||
- **`before_agent_start`**:舊版相容掛鉤,可能在任一階段執行;建議使用上方明確的掛鉤。
|
||||
- **`before_agent_reply`**:在行內動作之後、LLM 呼叫之前執行,讓 Plugin 可接管該回合並回傳合成回覆,或完全靜默該回合。
|
||||
- **`before_model_resolve`**:在工作階段前執行(沒有 `messages`),用於在模型解析前確定性地覆寫供應商/模型。
|
||||
- **`before_prompt_build`**:在工作階段載入後執行(含 `messages`),用於在提交提示詞前注入 `prependContext`、`systemPrompt`、`prependSystemContext` 或 `appendSystemContext`。將 `prependContext` 用於每回合動態文字,並將 system-context 欄位用於應位於系統提示詞空間中的穩定指引。
|
||||
- **`before_agent_start`**:舊版相容性 Hook,可能在任一階段執行;建議使用上方明確的 Hook。
|
||||
- **`before_agent_reply`**:在 inline 動作之後、LLM 呼叫之前執行,讓 Plugin 接管該回合並回傳合成回覆,或完全靜音該回合。
|
||||
- **`agent_end`**:在完成後檢查最終訊息清單與執行中繼資料。
|
||||
- **`before_compaction` / `after_compaction`**:觀察或註記 Compaction 週期。
|
||||
- **`before_compaction` / `after_compaction`**:觀察或標註 Compaction 週期。
|
||||
- **`before_tool_call` / `after_tool_call`**:攔截工具參數/結果。
|
||||
- **`before_install`**:檢查內建掃描發現項目,並可選擇封鎖 Skill 或 Plugin 安裝。
|
||||
- **`tool_result_persist`**:在工具結果寫入 OpenClaw 擁有的工作階段轉錄前,同步轉換工具結果。
|
||||
- **`message_received` / `message_sending` / `message_sent`**:傳入 + 傳出訊息掛鉤。
|
||||
- **`before_install`**:檢查內建掃描發現項目,並可選擇封鎖 skill 或 Plugin 安裝。
|
||||
- **`tool_result_persist`**:在工具結果寫入 OpenClaw 所有的工作階段 transcript 前,同步轉換工具結果。
|
||||
- **`message_received` / `message_sending` / `message_sent`**:輸入 + 輸出訊息 Hook。
|
||||
- **`session_start` / `session_end`**:工作階段生命週期邊界。
|
||||
- **`gateway_start` / `gateway_stop`**:Gateway 生命週期事件。
|
||||
- **`gateway_start` / `gateway_stop`**:gateway 生命週期事件。
|
||||
|
||||
傳出/工具防護的掛鉤決策規則:
|
||||
輸出/工具防護的 Hook 決策規則:
|
||||
|
||||
- `before_tool_call`:`{ block: true }` 是終止性決策,會停止較低優先順序的處理常式。
|
||||
- `before_tool_call`:`{ block: false }` 是無操作,且不會清除先前的封鎖。
|
||||
- `before_install`:`{ block: true }` 是終止性決策,會停止較低優先順序的處理常式。
|
||||
- `before_install`:`{ block: false }` 是無操作,且不會清除先前的封鎖。
|
||||
- `message_sending`:`{ cancel: true }` 是終止性決策,會停止較低優先順序的處理常式。
|
||||
- `message_sending`:`{ cancel: false }` 是無操作,且不會清除先前的取消。
|
||||
- `before_tool_call`:`{ block: true }` 是終端決策,會停止較低優先權的處理器。
|
||||
- `before_tool_call`:`{ block: false }` 是無操作,不會清除先前的封鎖。
|
||||
- `before_install`:`{ block: true }` 是終端決策,會停止較低優先權的處理器。
|
||||
- `before_install`:`{ block: false }` 是無操作,不會清除先前的封鎖。
|
||||
- `message_sending`:`{ cancel: true }` 是終端決策,會停止較低優先權的處理器。
|
||||
- `message_sending`:`{ cancel: false }` 是無操作,不會清除先前的取消。
|
||||
|
||||
請參閱 [Plugin 掛鉤](/zh-TW/plugins/hooks)取得掛鉤 API 與註冊詳細資訊。
|
||||
請參閱 [Plugin Hook](/zh-TW/plugins/hooks),了解 Hook API 與註冊細節。
|
||||
|
||||
測試框架可能會以不同方式調整這些掛鉤。Codex app-server 測試框架會將
|
||||
OpenClaw Plugin 掛鉤作為文件化鏡像介面的相容性合約,而 Codex 原生掛鉤仍是
|
||||
另一套較低階的 Codex 機制。
|
||||
Harness 可能會以不同方式調整這些 Hook。Codex app-server harness 會保留
|
||||
OpenClaw Plugin Hook,作為已記載映射介面的相容性合約,
|
||||
而 Codex 原生 Hook 仍是獨立的較低層級 Codex 機制。
|
||||
|
||||
## 串流 + 部分回覆
|
||||
|
||||
- 助理增量會從 pi-agent-core 串流,並作為 `assistant` 事件發出。
|
||||
- Assistant 增量會從 pi-agent-core 串流,並作為 `assistant` 事件發出。
|
||||
- 區塊串流可在 `text_end` 或 `message_end` 發出部分回覆。
|
||||
- 推理串流可作為獨立串流或區塊回覆發出。
|
||||
- 請參閱[串流](/zh-TW/concepts/streaming),了解分塊與區塊回覆行為。
|
||||
@ -130,26 +133,26 @@ OpenClaw Plugin 掛鉤作為文件化鏡像介面的相容性合約,而 Codex
|
||||
## 工具執行 + 訊息工具
|
||||
|
||||
- 工具 start/update/end 事件會在 `tool` 串流上發出。
|
||||
- 工具結果會在記錄/發出前,依大小與圖片 payload 進行清理。
|
||||
- 會追蹤訊息工具傳送,以抑制重複的助理確認。
|
||||
- 工具結果會在記錄/發出前,針對大小與圖片 payload 進行清理。
|
||||
- 訊息工具傳送會被追蹤,以抑制重複的 assistant 確認。
|
||||
|
||||
## 回覆塑形 + 抑制
|
||||
|
||||
- 最終 payload 由以下內容組裝:
|
||||
- 助理文字(以及可選的推理)
|
||||
- 行內工具摘要(當 verbose + 允許時)
|
||||
- 模型出錯時的助理錯誤文字
|
||||
- 精確靜默 token `NO_REPLY` / `no_reply` 會從傳出
|
||||
payload 中過濾。
|
||||
- 最終 payload 會由以下內容組裝:
|
||||
- assistant 文字(以及可選的推理)
|
||||
- inline 工具摘要(當 verbose + 允許時)
|
||||
- 模型發生錯誤時的 assistant 錯誤文字
|
||||
- 精確的靜默 token `NO_REPLY` / `no_reply` 會從輸出
|
||||
payload 中濾除。
|
||||
- 訊息工具重複項會從最終 payload 清單中移除。
|
||||
- 如果沒有剩餘可渲染的 payload 且工具出錯,則會發出備援工具錯誤回覆
|
||||
- 如果沒有剩餘可算繪的 payload,且工具發生錯誤,則會發出備援工具錯誤回覆
|
||||
(除非訊息工具已經傳送使用者可見的回覆)。
|
||||
|
||||
## Compaction + 重試
|
||||
|
||||
- 自動 Compaction 會發出 `compaction` 串流事件,且可觸發重試。
|
||||
- 自動 Compaction 會發出 `compaction` 串流事件,並可觸發重試。
|
||||
- 重試時,記憶體內緩衝區與工具摘要會重設,以避免重複輸出。
|
||||
- 請參閱 [Compaction](/zh-TW/concepts/compaction) 了解 Compaction 管線。
|
||||
- 請參閱 [Compaction](/zh-TW/concepts/compaction),了解 Compaction 管線。
|
||||
|
||||
## 事件串流(目前)
|
||||
|
||||
@ -159,29 +162,29 @@ OpenClaw Plugin 掛鉤作為文件化鏡像介面的相容性合約,而 Codex
|
||||
|
||||
## 聊天通道處理
|
||||
|
||||
- 助理增量會緩衝成聊天 `delta` 訊息。
|
||||
- Assistant 增量會緩衝成聊天 `delta` 訊息。
|
||||
- 聊天 `final` 會在 **lifecycle end/error** 時發出。
|
||||
|
||||
## 逾時
|
||||
|
||||
- `agent.wait` 預設:30 秒(僅等待)。`timeoutMs` 參數可覆寫。
|
||||
- 代理執行階段:`agents.defaults.timeoutSeconds` 預設為 172800 秒(48 小時);由 `runEmbeddedPiAgent` 中止計時器強制執行。
|
||||
- Cron 執行階段:隔離的代理回合 `timeoutSeconds` 由 cron 擁有。排程器在執行開始時啟動該計時器,在設定的期限中止底層執行,接著執行有界清理,再記錄逾時,避免過時的子工作階段讓通道卡住。
|
||||
- 卡住工作階段復原:啟用診斷後,`diagnostics.stuckSessionWarnMs` 會偵測長時間 `processing` 的工作階段。作用中的內嵌執行、作用中的回覆操作,以及作用中的工作階段通道任務,預設只會警告;如果診斷顯示該工作階段沒有作用中的工作,監視器會釋放受影響的工作階段通道,讓已排入佇列的啟動工作可以清空。
|
||||
- 模型閒置逾時:當閒置視窗內沒有回應區塊抵達時,OpenClaw 會中止模型請求。`models.providers.<id>.timeoutSeconds` 會為較慢的本機/自架供應商延長這個閒置監視器;否則 OpenClaw 會在已設定時使用 `agents.defaults.timeoutSeconds`,預設上限為 120 秒。沒有明確模型或代理逾時的 Cron 觸發執行會停用閒置監視器,並依賴 cron 外層逾時。
|
||||
- 供應商 HTTP 請求逾時:`models.providers.<id>.timeoutSeconds` 會套用到該供應商的模型 HTTP 擷取,包括連線、標頭、本文、SDK 請求逾時、總體受防護 fetch 中止處理,以及模型串流閒置監視器。對於 Ollama 這類較慢的本機/自架供應商,請先使用此設定,再提高整個代理執行階段逾時。
|
||||
- `agent.wait` 預設值:30 秒(僅等待)。`timeoutMs` 參數可覆寫。
|
||||
- 代理執行階段:`agents.defaults.timeoutSeconds` 預設值為 172800 秒(48 小時);由 `runEmbeddedPiAgent` 中止計時器強制執行。
|
||||
- Cron 執行階段:隔離的代理回合 `timeoutSeconds` 由 cron 擁有。排程器會在執行開始時計時,在設定的期限中止底層執行,接著在記錄逾時前執行有界清理,避免過期的子工作階段讓通道卡住。
|
||||
- 卡住工作階段復原:啟用診斷時,`diagnostics.stuckSessionWarnMs` 會偵測長時間處於 `processing` 的工作階段。作用中的嵌入式執行、作用中的回覆操作,以及作用中的工作階段通道任務預設仍僅發出警告;如果診斷顯示該工作階段沒有作用中的工作,watchdog 會釋放受影響的工作階段通道,讓佇列中的啟動工作可以清空。
|
||||
- 模型閒置逾時:當閒置視窗前沒有回應區塊抵達時,OpenClaw 會中止模型請求。`models.providers.<id>.timeoutSeconds` 會為緩慢的本機/自架供應商延長此閒置 watchdog;否則 OpenClaw 會在已設定時使用 `agents.defaults.timeoutSeconds`,預設上限為 120 秒。沒有明確模型或代理逾時的 Cron 觸發執行會停用閒置 watchdog,並依賴 cron 外層逾時。
|
||||
- 供應商 HTTP 請求逾時:`models.providers.<id>.timeoutSeconds` 會套用至該供應商的模型 HTTP fetch,包括連線、標頭、本文、SDK 請求逾時、完整 guarded-fetch 中止處理,以及模型串流閒置 watchdog。對於 Ollama 等緩慢的本機/自架供應商,請先使用此設定,再提高整個代理執行階段逾時。
|
||||
|
||||
## 可能提早結束的位置
|
||||
|
||||
- 代理逾時(中止)
|
||||
- AbortSignal(取消)
|
||||
- Gateway 中斷連線或 RPC 逾時
|
||||
- Gateway 斷線或 RPC 逾時
|
||||
- `agent.wait` 逾時(僅等待,不會停止代理)
|
||||
|
||||
## 相關
|
||||
|
||||
- [工具](/zh-TW/tools) — 可用的代理工具
|
||||
- [掛鉤](/zh-TW/automation/hooks) — 由代理生命週期事件觸發的事件驅動腳本
|
||||
- [Compaction](/zh-TW/concepts/compaction) — 長對話如何被摘要
|
||||
- [Exec 核准](/zh-TW/tools/exec-approvals) — shell 指令的核准閘門
|
||||
- [Hook](/zh-TW/automation/hooks) — 由代理生命週期事件觸發的事件驅動腳本
|
||||
- [Compaction](/zh-TW/concepts/compaction) — 長對話如何摘要
|
||||
- [Exec Approvals](/zh-TW/tools/exec-approvals) — shell 指令的核准閘門
|
||||
- [Thinking](/zh-TW/tools/thinking) — thinking/reasoning 層級設定
|
||||
|
||||
@ -1,36 +1,36 @@
|
||||
---
|
||||
read_when:
|
||||
- 變更自動回覆的執行或並行處理
|
||||
- 變更自動回覆執行或並行性
|
||||
- 說明 /queue 模式或訊息導向行為
|
||||
summary: 自動回覆佇列模式、預設值與各工作階段覆寫設定
|
||||
summary: 自動回覆佇列模式、預設值與逐工作階段覆寫
|
||||
title: 命令佇列
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T03:02:05Z"
|
||||
generated_at: "2026-04-30T18:38:36Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 2ac0c0ded9558b080714fa4b8be0d552f985911bf19b427020f9654ae4955b2d
|
||||
source_hash: fbf1bb1ffd4ce06fa138f63e31651b8821226d9c95dd6b93d68326a5fb91fdd0
|
||||
source_path: concepts/queue.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
我們會透過一個小型的程序內佇列,序列化入站自動回覆執行(所有頻道),以避免多個代理執行互相碰撞,同時仍允許跨工作階段的安全平行處理。
|
||||
我們透過極小型的處理序內佇列序列化傳入的自動回覆執行作業(所有通道),以防止多個代理程式執行作業互相衝突,同時仍允許跨工作階段的安全平行處理。
|
||||
|
||||
## 原因
|
||||
|
||||
- 自動回覆執行可能成本高昂(LLM 呼叫),且當多個入站訊息接近同時抵達時可能會互相碰撞。
|
||||
- 序列化可避免競爭共享資源(工作階段檔案、記錄、CLI stdin),並降低觸發上游速率限制的機率。
|
||||
- 自動回覆執行作業可能成本很高(LLM 呼叫),而且當多則傳入訊息在短時間內抵達時可能會互相衝突。
|
||||
- 序列化可避免競爭共用資源(工作階段檔案、記錄、CLI stdin),並降低觸發上游速率限制的機率。
|
||||
|
||||
## 運作方式
|
||||
|
||||
- 具執行線感知能力的 FIFO 佇列,會以可設定的並行上限排空每個執行線(未設定執行線預設為 1;main 預設為 4,subagent 為 8)。
|
||||
- `runEmbeddedPiAgent` 會依 **工作階段鍵**(執行線 `session:<key>`)排入佇列,以保證每個工作階段同時只有一個作用中的執行。
|
||||
- 接著每個工作階段執行會再排入 **全域執行線**(預設為 `main`),因此整體平行度會受 `agents.defaults.maxConcurrent` 限制。
|
||||
- 啟用詳細記錄時,排隊的執行若在啟動前等待超過約 2 秒,會輸出簡短通知。
|
||||
- 輸入指示器仍會在排入佇列時立即觸發(若該頻道支援),因此在等待輪到我們執行時,使用者體驗不會改變。
|
||||
- 具備通道感知能力的 FIFO 佇列會以可設定的並行上限清空每個通道(未設定通道預設為 1;main 預設為 4,subagent 為 8)。
|
||||
- `runEmbeddedPiAgent` 會依 **工作階段鍵**(通道 `session:<key>`)入列,以保證每個工作階段一次只有一個作用中的執行作業。
|
||||
- 接著,每個工作階段執行作業會被排入 **全域通道**(預設為 `main`),因此整體平行度會由 `agents.defaults.maxConcurrent` 設定上限。
|
||||
- 啟用詳細記錄時,如果已入列的執行作業在開始前等待超過約 2 秒,會發出簡短通知。
|
||||
- 輸入中指示器仍會在入列時立即觸發(若通道支援),因此在等待輪到我們處理時,使用者體驗不會改變。
|
||||
|
||||
## 預設值
|
||||
|
||||
未設定時,所有入站頻道介面都會使用:
|
||||
未設定時,所有傳入通道介面都使用:
|
||||
|
||||
- `mode: "steer"`
|
||||
- `debounceMs: 500`
|
||||
@ -38,29 +38,28 @@ x-i18n:
|
||||
- `drop: "summarize"`
|
||||
|
||||
`steer` 是預設值,因為它能讓作用中的模型回合保持回應性,而不會
|
||||
啟動第二個工作階段執行。它會排空在下一個模型邊界前抵達的所有 steering 訊息。
|
||||
如果目前執行無法接受 steering,
|
||||
OpenClaw 會退回到一個 followup 佇列項目。
|
||||
啟動第二個工作階段執行作業。它會清空所有在下一個模型邊界之前抵達的引導訊息。
|
||||
如果目前的執行作業無法接受引導,OpenClaw 會退回到後續佇列項目。
|
||||
|
||||
## 佇列模式
|
||||
|
||||
入站訊息可以 steering 目前執行、等待後續回合,或兩者並行:
|
||||
傳入訊息可以引導目前的執行作業、等待後續回合,或兩者都做:
|
||||
|
||||
- `steer`:將 steering 訊息排入作用中的執行階段。Pi 會在**目前助理回合完成工具呼叫執行後**、下一次 LLM 呼叫前,傳遞所有待處理的 steering 訊息;Codex app-server 會接收一個批次的 `turn/steer`。如果執行未處於作用中串流狀態,或 steering 不可用,OpenClaw 會退回到一個 followup 佇列項目。
|
||||
- `queue`(舊版):舊的一次一則 steering。Pi 會在每個模型邊界傳遞一則已排隊的 steering 訊息;Codex app-server 會接收個別的 `turn/steer` 請求。除非你需要先前的序列化行為,否則請優先使用 `steer`。
|
||||
- `followup`:在目前執行結束後,將每則訊息排入稍後的代理回合。
|
||||
- `collect`:在靜默視窗後,將已排隊訊息合併成**單一**後續回合。如果訊息指向不同頻道/執行緒,會個別排空以保留路由。
|
||||
- `steer-backlog`(又稱 `steer+backlog`):立即 steering,**並且**保留同一則訊息供後續回合使用。
|
||||
- `interrupt`(舊版):中止該工作階段的作用中執行,然後執行最新訊息。
|
||||
- `steer`:將引導訊息排入作用中執行階段。Pi 會在**目前助理回合完成其工具呼叫的執行之後**、下一次 LLM 呼叫之前,遞送所有待處理的引導訊息;Codex app-server 會收到一個批次化的 `turn/steer`。如果執行作業沒有正在主動串流,或無法使用引導,OpenClaw 會退回到後續佇列項目。
|
||||
- `queue`(舊版):舊的一次一則引導。Pi 會在每個模型邊界遞送一則已入列的引導訊息;Codex app-server 會收到個別的 `turn/steer` 要求。除非你需要先前的序列化行為,否則建議使用 `steer`。
|
||||
- `followup`:將每則訊息排入佇列,在目前執行作業結束後供稍後的代理程式回合使用。
|
||||
- `collect`:在靜默視窗之後,將已入列的訊息合併成**單一**後續回合。如果訊息指向不同通道/執行緒,會個別清空以保留路由。
|
||||
- `steer-backlog`(又稱 `steer+backlog`):立即引導,**並且**保留同一則訊息供後續回合使用。
|
||||
- `interrupt`(舊版):中止該工作階段的作用中執行作業,然後執行最新訊息。
|
||||
|
||||
Steer-backlog 表示你可能會在被 steered 的執行後收到後續回應,因此
|
||||
串流介面看起來可能像重複回應。如果你想要
|
||||
每則入站訊息只產生一個回應,請優先使用 `collect`/`steer`。
|
||||
Steer-backlog 代表你可能會在已引導的執行作業之後取得後續回應,因此
|
||||
串流介面看起來可能像重複。若你希望每則傳入訊息只產生一個回應,
|
||||
請優先使用 `collect`/`steer`。
|
||||
|
||||
如需執行階段特定的時序與相依性行為,請參閱
|
||||
[Steering 佇列](/zh-TW/concepts/queue-steering)。
|
||||
如需執行階段特定的時序與依賴行為,請參閱
|
||||
[引導佇列](/zh-TW/concepts/queue-steering)。
|
||||
|
||||
透過 `messages.queue` 進行全域或每個頻道設定:
|
||||
透過 `messages.queue` 進行全域或每個通道設定:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -78,53 +77,53 @@ Steer-backlog 表示你可能會在被 steered 的執行後收到後續回應,
|
||||
|
||||
## 佇列選項
|
||||
|
||||
選項會套用到 `followup`、`collect` 和 `steer-backlog`(以及 steering 退回到 followup 時的 `steer` 或舊版 `queue`):
|
||||
選項適用於 `followup`、`collect` 和 `steer-backlog`(以及當引導退回到後續時的 `steer` 或舊版 `queue`):
|
||||
|
||||
- `debounceMs`:排空已排隊 followups 前的靜默視窗。單純數字代表毫秒;`/queue` 選項接受單位 `ms`、`s`、`m`、`h` 和 `d`。
|
||||
- `cap`:每個工作階段可排隊的訊息上限。低於 `1` 的值會被忽略。
|
||||
- `drop: "summarize"`:預設值。視需要丟棄最舊的佇列項目,保留精簡摘要,並將其注入為合成的 followup 提示。
|
||||
- `drop: "old"`:視需要丟棄最舊的佇列項目,不保留摘要。
|
||||
- `drop: "new"`:當佇列已滿時拒絕最新訊息。
|
||||
- `debounceMs`:清空已入列後續項目前的靜默視窗。純數字代表毫秒;`/queue` 選項接受單位 `ms`、`s`、`m`、`h` 和 `d`。
|
||||
- `cap`:每個工作階段最多可入列的訊息數。低於 `1` 的值會被忽略。
|
||||
- `drop: "summarize"`:預設值。視需要丟棄最舊的已入列項目,保留精簡摘要,並將其注入為合成的後續提示。
|
||||
- `drop: "old"`:視需要丟棄最舊的已入列項目,不保留摘要。
|
||||
- `drop: "new"`:佇列已滿時拒絕最新訊息。
|
||||
|
||||
預設值:`debounceMs: 500`、`cap: 20`、`drop: summarize`。
|
||||
|
||||
## 優先順序
|
||||
|
||||
針對模式選擇,OpenClaw 會依序解析:
|
||||
在模式選擇上,OpenClaw 會依序解析:
|
||||
|
||||
1. 內嵌或已儲存的每工作階段 `/queue` 覆寫。
|
||||
1. 行內或已儲存的每工作階段 `/queue` 覆寫。
|
||||
2. `messages.queue.byChannel.<channel>`。
|
||||
3. `messages.queue.mode`。
|
||||
4. 預設 `steer`。
|
||||
|
||||
針對選項,內嵌或已儲存的 `/queue` 選項優先於設定。接著會套用
|
||||
頻道特定 debounce(`messages.queue.debounceMsByChannel`)、Plugin
|
||||
對於選項,行內或已儲存的 `/queue` 選項優先於設定。接著會套用
|
||||
通道特定的 debounce(`messages.queue.debounceMsByChannel`)、Plugin
|
||||
debounce 預設值、全域 `messages.queue` 選項,以及內建預設值。
|
||||
`cap` 和 `drop` 是全域/工作階段選項,不是每頻道設定
|
||||
鍵。
|
||||
`cap` 和 `drop` 是全域/工作階段選項,不是每通道設定鍵。
|
||||
|
||||
## 每工作階段覆寫
|
||||
|
||||
- 以獨立命令傳送 `/queue <mode>`,即可儲存目前工作階段的模式。
|
||||
- 選項可以合併使用:`/queue collect debounce:0.5s cap:25 drop:summarize`
|
||||
- 將 `/queue <mode>` 作為獨立命令傳送,以儲存目前工作階段的模式。
|
||||
- 選項可以合併:`/queue collect debounce:0.5s cap:25 drop:summarize`
|
||||
- `/queue default` 或 `/queue reset` 會清除工作階段覆寫。
|
||||
|
||||
## 範圍與保證
|
||||
|
||||
- 適用於所有使用 Gateway 回覆管線的入站頻道上的自動回覆代理執行(WhatsApp web、Telegram、Slack、Discord、Signal、iMessage、webchat 等)。
|
||||
- 預設執行線(`main`)在程序範圍內供入站 + main heartbeats 使用;設定 `agents.defaults.maxConcurrent` 可允許多個工作階段平行執行。
|
||||
- 可能存在其他執行線(例如 `cron`、`cron-nested`、`nested`、`subagent`),因此背景工作可以平行執行,而不會阻塞入站回覆。隔離的 cron 代理回合會持有一個 `cron` 槽位,而其內部代理執行會使用 `cron-nested`;兩者都使用 `cron.maxConcurrentRuns`。共享的非 cron `nested` 流程會保留自己的執行線行為。這些分離執行會被追蹤為[背景任務](/zh-TW/automation/tasks)。
|
||||
- 每工作階段執行線保證同一時間只有一個代理執行會觸碰指定工作階段。
|
||||
- 沒有外部相依性或背景工作執行緒;純 TypeScript + promises。
|
||||
- 適用於所有使用 Gateway 回覆管線的傳入通道上的自動回覆代理程式執行作業(WhatsApp web、Telegram、Slack、Discord、Signal、iMessage、webchat 等)。
|
||||
- 預設通道(`main`)在處理序範圍內供傳入訊息 + 主要 Heartbeat 共用;設定 `agents.defaults.maxConcurrent` 可允許多個工作階段平行執行。
|
||||
- 可能存在其他通道(例如 `cron`、`cron-nested`、`nested`、`subagent`),因此背景工作可以平行執行,而不會阻塞傳入回覆。隔離的 Cron 代理程式回合會在其內部代理程式執行使用 `cron-nested` 時持有一個 `cron` 槽位;兩者都使用 `cron.maxConcurrentRuns`。共用的非 Cron `nested` 流程會保留自身的通道行為。這些分離的執行作業會被追蹤為[背景工作](/zh-TW/automation/tasks)。
|
||||
- 每工作階段通道保證一次只有一個代理程式執行作業會觸及指定工作階段。
|
||||
- 沒有外部依賴或背景工作執行緒;純 TypeScript + promises。
|
||||
|
||||
## 疑難排解
|
||||
|
||||
- 如果命令看似卡住,請啟用詳細記錄,並尋找「queued for …ms」這類行,以確認佇列正在排空。
|
||||
- 如果命令看似卡住,請啟用詳細記錄,並尋找「queued for …ms」行以確認佇列正在清空。
|
||||
- 如果你需要佇列深度,請啟用詳細記錄並觀察佇列時序行。
|
||||
- 啟用診斷時,工作階段若在超過 `diagnostics.stuckSessionWarnMs` 後仍停留在 `processing`,會記錄卡住工作階段警告。作用中的嵌入式執行、作用中的回覆操作,以及作用中的執行線任務,預設仍只會警告;若啟動時的陳舊簿記沒有作用中的工作階段工作,則可釋放受影響的工作階段執行線,讓已排隊工作繼續排空。
|
||||
- 接受一個回合後停止發出進度的 Codex app-server 執行作業,會由 Codex 配接器中斷,因此作用中的工作階段通道可以釋放,而不是等待外層執行作業逾時。
|
||||
- 啟用診斷時,在超過 `diagnostics.stuckSessionWarnMs` 後仍維持在 `processing` 的工作階段會記錄卡住工作階段警告。作用中的嵌入式執行作業、作用中的回覆操作,以及作用中的通道工作預設仍只會警告;沒有作用中工作階段工作的過時啟動帳務記錄,可以釋放受影響的工作階段通道,使已入列工作得以清空。
|
||||
|
||||
## 相關
|
||||
|
||||
- [工作階段管理](/zh-TW/concepts/session)
|
||||
- [Steering 佇列](/zh-TW/concepts/queue-steering)
|
||||
- [引導佇列](/zh-TW/concepts/queue-steering)
|
||||
- [重試政策](/zh-TW/concepts/retry)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,58 +1,59 @@
|
||||
---
|
||||
read_when:
|
||||
- 執行或修復測試
|
||||
summary: 如何在本機執行測試(vitest),以及何時使用強制/涵蓋率模式
|
||||
summary: 如何在本機執行測試 (vitest),以及何時使用 force/coverage 模式
|
||||
title: 測試
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T03:38:59Z"
|
||||
generated_at: "2026-04-30T18:38:26Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 9328d6f0383b5067fa8bb5d0f1bf22a3b9048a267908bf85167842ddc3d12e42
|
||||
source_hash: 131f2bad3b2806d28394213cec38d632d106ddbf8ff04d06345ab8046fb8bcf2
|
||||
source_path: reference/test.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
- 完整測試工具包(套件、即時、Docker):[測試](/zh-TW/help/testing)
|
||||
- 完整測試工具組(套件、即時、Docker):[測試](/zh-TW/help/testing)
|
||||
|
||||
- `pnpm test:force`:終止任何仍占用預設控制埠的殘留 Gateway 行程,接著使用隔離的 Gateway 埠執行完整 Vitest 套件,讓伺服器測試不會與執行中的實例衝突。當先前的 Gateway 執行讓埠 18789 被占用時,使用此指令。
|
||||
- `pnpm test:coverage`:使用 V8 覆蓋率執行單元套件(透過 `vitest.unit.config.ts`)。這是已載入檔案的單元覆蓋率關卡,不是整個儲存庫的全檔案覆蓋率。閾值為 70% 行數/函式/陳述式,以及 55% 分支。因為 `coverage.all` 為 false,這個關卡會測量單元覆蓋率套件載入的檔案,而不是把每個分割 lane 的原始碼檔案都視為未覆蓋。
|
||||
- `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:coverage:changed`:只針對自 `origin/main` 以來變更的檔案執行單元覆蓋率。
|
||||
- `pnpm test:changed`:便宜的智慧變更測試執行。它會從直接測試編輯、相鄰的 `*.test.ts` 檔案、明確的原始碼對應,以及本機匯入圖執行精確目標。寬泛/設定/套件變更會被略過,除非它們對應到精確測試。
|
||||
- `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`:明確的寬泛變更測試執行。當測試工具/設定/套件編輯應該退回 Vitest 較寬泛的變更測試行為時使用。
|
||||
- `pnpm changed:lanes`:顯示相對於 `origin/main` 的差異所觸發的架構 lanes。
|
||||
- `pnpm check:changed`:針對相對於 `origin/main` 的差異執行智慧變更檢查關卡。它會為受影響的架構 lanes 執行型別檢查、lint 與守衛指令,但不會執行 Vitest 測試。測試證明請使用 `pnpm test:changed` 或明確的 `pnpm test <target>`。
|
||||
- `pnpm test`:透過作用域化的 Vitest lanes 路由明確的檔案/目錄目標。未指定目標的執行會使用固定 shard 群組,並展開為 leaf 設定以便本機平行執行;extension 群組一律展開為每個 extension 的 shard 設定,而不是一個巨大的根專案行程。
|
||||
- 測試包裝器執行會以簡短的 `[test] passed|failed|skipped ... in ...` 摘要結束。Vitest 自己的持續時間行會保留為每個 shard 的細節。
|
||||
- 共享的 OpenClaw 測試狀態:當測試需要隔離的 `HOME`、`OPENCLAW_STATE_DIR`、`OPENCLAW_CONFIG_PATH`、設定 fixture、工作區、agent 目錄或 auth-profile 存放區時,從 Vitest 使用 `src/test-utils/openclaw-test-state.ts`。
|
||||
- 行程 E2E 輔助工具:當 Vitest 行程層級 E2E 測試需要執行中的 Gateway、CLI env、日誌擷取與清理集中在一處時,使用 `test/helpers/openclaw-test-instance.ts`。
|
||||
- Docker/Bash E2E 輔助工具:source `scripts/lib/docker-e2e-image.sh` 的 lanes 可以把 `docker_e2e_test_state_shell_b64 <label> <scenario>` 傳入容器,並用 `scripts/lib/openclaw-e2e-instance.sh` 解碼;多 home 腳本可以傳入 `docker_e2e_test_state_function_b64`,並在每個流程中呼叫 `openclaw_test_state_create <label> <scenario>`。較低階呼叫端可以使用 `scripts/lib/openclaw-test-state.mjs shell --label <name> --scenario <name>` 產生容器內 shell 片段,或使用 `node scripts/lib/openclaw-test-state.mjs -- create --label <name> --scenario <name> --env-file <path> --json` 產生可 source 的主機 env 檔案。`create` 前面的 `--` 會避免較新的 Node runtime 把 `--env-file` 視為 Node 旗標。啟動 Gateway 的 Docker/Bash lanes 可以在容器內 source `scripts/lib/openclaw-e2e-instance.sh`,用於 entrypoint 解析、模擬 OpenAI 啟動、Gateway 前景/背景啟動、就緒探測、狀態 env 匯出、日誌傾印與行程清理。
|
||||
- 完整、extension 與 include-pattern shard 執行會更新 `.artifacts/vitest-shard-timings.json` 中的本機計時資料;後續的 whole-config 執行會使用這些計時來平衡慢速與快速 shard。Include-pattern CI shards 會把 shard 名稱附加到計時 key,這會讓篩選後的 shard 計時保持可見,而不會取代 whole-config 計時資料。設定 `OPENCLAW_TEST_PROJECTS_TIMINGS=0` 可忽略本機計時 artifact。
|
||||
- 選定的 `plugin-sdk` 與 `commands` 測試檔案現在會透過專用輕量 lanes 路由,這些 lanes 只保留 `test/setup.ts`,並把 runtime-heavy 案例留在既有 lanes 上。
|
||||
- 有相鄰測試的原始碼檔案會先對應到該相鄰測試,再退回較寬的目錄 globs。`src/channels/plugins/contracts/test-helpers`、`src/plugin-sdk/test-helpers` 與 `src/plugins/contracts` 下的輔助工具編輯,會使用本機匯入圖來執行匯入它們的測試,而不是在依賴路徑精確時寬泛執行每個 shard。
|
||||
- `auto-reply` 現在也分成三個專用設定(`core`、`top-level`、`reply`),因此 reply harness 不會主導較輕量的頂層狀態/token/輔助工具測試。
|
||||
- 基礎 Vitest 設定現在預設為 `pool: "threads"` 與 `isolate: false`,並在整個儲存庫設定中啟用共享的非隔離 runner。
|
||||
- `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 <target>`。
|
||||
- `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 <label> <scenario>` 傳入容器,並用 `scripts/lib/openclaw-e2e-instance.sh` 解碼;多 home 腳本可傳入 `docker_e2e_test_state_function_b64`,並在每個流程中呼叫 `openclaw_test_state_create <label> <scenario>`。較低層呼叫端可使用 `scripts/lib/openclaw-test-state.mjs shell --label <name> --scenario <name>` 產生容器內 shell snippet,或用 `node scripts/lib/openclaw-test-state.mjs -- create --label <name> --scenario <name> --env-file <path> --json` 產生可 source 的 host env file。`create` 前的 `--` 會避免較新的 Node runtime 將 `--env-file` 視為 Node flag。啟動 Gateway 的 Docker/Bash lane 可在容器內 source `scripts/lib/openclaw-e2e-instance.sh`,用於 entrypoint 解析、mock OpenAI 啟動、Gateway 前景/背景啟動、readiness probe、狀態 env 匯出、log dump 與程序清理。
|
||||
- 完整、extension 與 include-pattern shard 執行會更新 `.artifacts/vitest-shard-timings.json` 中的本機 timing data;之後的 whole-config 執行會用這些 timing 平衡慢速與快速 shard。Include-pattern CI shard 會將 shard 名稱附加到 timing key,讓 filtered shard timing 可見而不取代 whole-config timing data。設定 `OPENCLAW_TEST_PROJECTS_TIMINGS=0` 可忽略本機 timing artifact。
|
||||
- 選定的 `plugin-sdk` 與 `commands` 測試檔案現在會透過專用 light lane 路由,這些 lane 只保留 `test/setup.ts`,並讓 runtime-heavy case 留在既有 lane 上。
|
||||
- 具有同層測試的原始檔會先對應到該同層測試,再退回到較寬的目錄 glob。`src/channels/plugins/contracts/test-helpers`、`src/plugin-sdk/test-helpers` 與 `src/plugins/contracts` 下的 helper 編輯會使用本機匯入圖來執行匯入它們的測試,而不是在 dependency path 精準時寬泛執行每個 shard。
|
||||
- `auto-reply` 現在也分割為三個專用 config(`core`、`top-level`、`reply`),因此 reply harness 不會主導較輕的 top-level status/token/helper 測試。
|
||||
- Base Vitest config 現在預設為 `pool: "threads"` 與 `isolate: false`,並在整個 repo config 啟用共用的非隔離 runner。
|
||||
- `pnpm test:channels` 執行 `vitest.channels.config.ts`。
|
||||
- `pnpm test:extensions` 與 `pnpm test extensions` 會執行所有 extension/Plugin shards。重型 channel plugins、瀏覽器 Plugin 與 OpenAI 會作為專用 shards 執行;其他 Plugin 群組會保持批次處理。針對單一 bundled Plugin lane,請使用 `pnpm test extensions/<id>`。
|
||||
- `pnpm test:perf:imports`:啟用 Vitest 匯入持續時間與匯入分解報告,同時仍針對明確的檔案/目錄目標使用作用域化 lane 路由。
|
||||
- `pnpm test:perf:imports:changed`:相同的匯入 profiling,但只針對自 `origin/main` 以來變更的檔案。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 會用相同已提交 git diff,將 routed changed-mode 路徑與原生 root-project 執行進行基準測試。
|
||||
- `pnpm test:perf:changed:bench -- --worktree` 會在不先提交的情況下,對目前 worktree 變更集進行基準測試。
|
||||
- `pnpm test:perf:profile:main`:為 Vitest 主執行緒寫入 CPU profile(`.artifacts/vitest-main-profile`)。
|
||||
- `pnpm test:perf:profile:runner`:為單元 runner 寫入 CPU 與 heap profiles(`.artifacts/vitest-runner-profile`)。
|
||||
- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`:序列執行每個 full-suite Vitest leaf config,並寫入分組持續時間資料以及每個 config 的 JSON/log artifacts。Test Performance Agent 會在嘗試修復慢速測試前使用此項作為基準線。
|
||||
- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`:在以效能為重點的變更後比較分組報告。
|
||||
- Gateway 整合:透過 `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` 或 `pnpm test:gateway` 選擇加入。
|
||||
- `pnpm test:e2e`:執行 Gateway 端對端 smoke tests(多實例 WS/HTTP/node pairing)。預設在 `vitest.e2e.config.ts` 中使用 `threads` + `isolate: false` 搭配自適應 workers;使用 `OPENCLAW_E2E_WORKERS=<n>` 調整,並設定 `OPENCLAW_E2E_VERBOSE=1` 取得詳細日誌。
|
||||
- `pnpm test:live`:執行 provider live tests(minimax/zai)。需要 API keys 與 `LIVE=1`(或 provider-specific `*_LIVE_TEST=1`)才會取消略過。
|
||||
- `pnpm test:docker:all`:建置共享 live-test image,將 OpenClaw 一次打包成 npm tarball,建置/重用 bare Node/Git runner image,加上一個會把該 tarball 安裝到 `/app` 的 functional image,接著透過 weighted scheduler 使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行 Docker smoke lanes。bare image(`OPENCLAW_DOCKER_E2E_BARE_IMAGE`)用於 installer/update/plugin-dependency lanes;這些 lanes 會掛載預先建置的 tarball,而不是使用複製的儲存庫原始碼。functional image(`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`)用於一般 built-app functionality lanes。`scripts/package-openclaw-for-docker.mjs` 是唯一的本機/CI package packer,並會在 Docker 消耗前驗證 tarball 與 `dist/postinstall-inventory.json`。Docker lane 定義位於 `scripts/lib/docker-e2e-scenarios.mjs`;planner 邏輯位於 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 會執行選定的 plan。`node scripts/test-docker-all.mjs --plan-json` 會輸出 scheduler 擁有的 CI plan,內容包含選定 lanes、image kinds、package/live-image 需求、狀態 scenarios 與 credential checks,而不建置或執行 Docker。`OPENCLAW_DOCKER_ALL_PARALLELISM=<n>` 控制行程 slots,預設為 10;`OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=<n>` 控制 provider-sensitive tail pool,預設為 10。重型 lane caps 預設為 `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 與 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;provider caps 預設透過 `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`、`OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` 與 `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4`,每個 provider 一個重型 lane。較大的 hosts 請使用 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。如果在低平行度 host 上某個 lane 超過有效 weight 或 resource cap,它仍然可以從空 pool 啟動,並會獨自執行直到釋放 capacity。lane 啟動預設錯開 2 秒,以避免本機 Docker daemon create 風暴;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=<ms>` 覆寫。runner 預設會 preflight Docker、清理陳舊的 OpenClaw E2E containers、每 30 秒輸出 active-lane status、在相容 lanes 之間共享 provider CLI tool caches、預設重試一次暫時性 live-provider failures(`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=<n>`),並將 lane timings 儲存在 `.artifacts/docker-tests/lane-timings.json`,以便後續執行使用 longest-first 排序。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可列印 lane manifest 而不執行 Docker,使用 `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=<ms>` 可調整狀態輸出,或使用 `OPENCLAW_DOCKER_ALL_TIMINGS=0` 停用 timing reuse。只要 deterministic/local lanes,請使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip`;只要 live-provider lanes,請使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=only`;package aliases 為 `pnpm test:docker:local:all` 與 `pnpm test:docker:live:all`。Live-only 模式會把 main 與 tail live lanes 合併到一個 longest-first pool,讓 provider buckets 可以一起打包 Claude、Codex 與 Gemini 工作。除非設定 `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`,否則 runner 會在第一次失敗後停止排程新的 pooled lanes,而且每個 lane 都有 120 分鐘的 fallback timeout,可用 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆寫;選定的 live/tail lanes 使用更嚴格的 per-lane caps。CLI backend Docker setup commands 有自己的 timeout,透過 `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` 設定(預設 180)。每個 lane 的日誌、`summary.json`、`failures.json` 與 phase timings 會寫在 `.artifacts/docker-tests/<run-id>/` 下;使用 `pnpm test:docker:timings <summary.json>` 檢查慢速 lanes,並使用 `pnpm test:docker:rerun <run-id|summary.json|failures.json>` 列印便宜的 targeted rerun commands。
|
||||
- `pnpm test:docker:browser-cdp-snapshot`:建置 Chromium-backed source E2E container,啟動 raw CDP 與隔離的 Gateway,執行 `browser doctor --deep`,並驗證 CDP role snapshots 包含 link URLs、cursor-promoted clickables、iframe refs 與 frame metadata。
|
||||
- CLI backend live Docker probes 可以作為 focused lanes 執行,例如 `pnpm test:docker:live-cli-backend:codex`、`pnpm test:docker:live-cli-backend:codex:resume` 或 `pnpm test:docker:live-cli-backend:codex:mcp`。Claude 與 Gemini 有對應的 `:resume` 與 `:mcp` aliases。
|
||||
- `pnpm test:docker:openwebui`:啟動 Dockerized OpenClaw + Open WebUI,透過 Open WebUI 登入,檢查 `/api/models`,接著透過 `/api/chat/completions` 執行真實的 proxied chat。需要可用的 live model key(例如 `~/.profile` 中的 OpenAI),會拉取外部 Open WebUI image,且不預期像一般 unit/e2e suites 一樣具備 CI 穩定性。
|
||||
- `pnpm test:docker:mcp-channels`:啟動 seeded Gateway container,以及會生成 `openclaw mcp serve` 的第二個 client container,接著透過真實 stdio bridge 驗證 routed conversation discovery、transcript reads、attachment metadata、live event queue behavior、outbound send routing,以及 Claude-style channel + permission notifications。Claude notification assertion 會直接讀取 raw stdio MCP frames,因此 smoke 能反映 bridge 實際發出的內容。
|
||||
- `pnpm test:extensions` 與 `pnpm test extensions` 執行所有 extension/Plugin shard。重型 channel Plugin、browser Plugin 與 OpenAI 會作為專用 shard 執行;其他 Plugin 群組維持批次。針對單一 bundled Plugin lane,使用 `pnpm test extensions/<id>`。
|
||||
- `pnpm test:perf:imports`:啟用 Vitest import-duration 與 import-breakdown 報告,同時仍對明確的檔案/目錄目標使用 scoped lane routing。
|
||||
- `pnpm test:perf:imports:changed`:相同的 import profiling,但只針對自 `origin/main` 以來變更的檔案。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>`:針對相同的已提交 git diff,比較 routed changed-mode path 與 native root-project run 的 benchmark。
|
||||
- `pnpm test:perf:changed:bench -- --worktree`:不先提交,直接對目前 worktree change set 進行 benchmark。
|
||||
- `pnpm test:perf:profile:main`:為 Vitest main thread 寫入 CPU profile(`.artifacts/vitest-main-profile`)。
|
||||
- `pnpm test:perf:profile:runner`:為 unit runner 寫入 CPU 與 heap profile(`.artifacts/vitest-runner-profile`)。
|
||||
- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`:序列執行每個 full-suite Vitest leaf config,並寫入 grouped duration data 加上 per-config JSON/log artifact。Test Performance Agent 會將其用作嘗試修復慢測試前的 baseline。
|
||||
- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`:在效能導向變更後比較 grouped report。
|
||||
- Gateway integration:透過 `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` 或 `pnpm test:gateway` opt-in。
|
||||
- `pnpm test:e2e`:執行 Gateway 端對端 smoke test(multi-instance WS/HTTP/node pairing)。在 `vitest.e2e.config.ts` 中預設為 `threads` + `isolate: false` 搭配 adaptive worker;用 `OPENCLAW_E2E_WORKERS=<n>` 調整,並設定 `OPENCLAW_E2E_VERBOSE=1` 取得詳細 log。
|
||||
- `pnpm test:live`:執行 provider live test(minimax/zai)。需要 API key 與 `LIVE=1`(或 provider-specific `*_LIVE_TEST=1`)才會取消 skip。
|
||||
- `pnpm test:docker:all`:建置共用 live-test image,將 OpenClaw 一次打包為 npm tarball,建置/重用 bare Node/Git runner image 與將該 tarball 安裝到 `/app` 的 functional image,然後透過 weighted scheduler 以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 執行 Docker smoke lane。bare image(`OPENCLAW_DOCKER_E2E_BARE_IMAGE`)用於 installer/update/plugin-dependency lane;這些 lane 會掛載預建 tarball,而不是使用複製的 repo source。functional image(`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`)用於一般 built-app functionality lane。`scripts/package-openclaw-for-docker.mjs` 是單一 local/CI package packer,會在 Docker 使用前驗證 tarball 與 `dist/postinstall-inventory.json`。Docker lane definition 位於 `scripts/lib/docker-e2e-scenarios.mjs`;planner logic 位於 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 執行選定 plan。`node scripts/test-docker-all.mjs --plan-json` 會輸出 scheduler-owned CI plan,內容包含選定 lane、image kind、package/live-image need、state scenario 與 credential check,且不會建置或執行 Docker。`OPENCLAW_DOCKER_ALL_PARALLELISM=<n>` 控制 process slot,預設為 10;`OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=<n>` 控制 provider-sensitive tail pool,預設為 10。Heavy lane cap 預設為 `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 與 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;provider cap 預設為每個 provider 一個 heavy lane,透過 `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`、`OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` 與 `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4`。較大的 host 可使用 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。如果某個 lane 在低平行度 host 上超過有效 weight 或 resource cap,它仍可從空 pool 啟動,並會獨自執行直到釋放 capacity。Lane start 預設錯開 2 秒,以避免本機 Docker daemon create storm;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=<ms>` 覆寫。runner 預設會 preflight Docker、清理過期 OpenClaw E2E container、每 30 秒輸出 active-lane status、在相容 lane 間共用 provider CLI tool cache、預設對 transient live-provider failure 重試一次(`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=<n>`),並將 lane timing 儲存在 `.artifacts/docker-tests/lane-timings.json`,供後續執行採 longest-first ordering。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可列印 lane manifest 而不執行 Docker,`OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=<ms>` 可調整 status output,或用 `OPENCLAW_DOCKER_ALL_TIMINGS=0` 停用 timing reuse。僅執行 deterministic/local lane 時使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip`,僅執行 live-provider lane 時使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=only`;package alias 為 `pnpm test:docker:local:all` 與 `pnpm test:docker:live:all`。Live-only mode 會將 main 與 tail live lane 合併為一個 longest-first pool,讓 provider bucket 能一起打包 Claude、Codex 與 Gemini 工作。除非設定 `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`,runner 會在首次失敗後停止排程新的 pooled lane;每個 lane 都有 120 分鐘 fallback timeout,可用 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆寫;選定的 live/tail lane 會使用更嚴格的 per-lane cap。CLI backend Docker setup command 有自己的 timeout,透過 `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS`(預設 180)。Per-lane log、`summary.json`、`failures.json` 與 phase timing 會寫入 `.artifacts/docker-tests/<run-id>/` 下;使用 `pnpm test:docker:timings <summary.json>` 檢查慢 lane,並用 `pnpm test:docker:rerun <run-id|summary.json|failures.json>` 列印便宜的 targeted rerun command。
|
||||
- `pnpm test:docker:browser-cdp-snapshot`:建置 Chromium-backed source E2E container,啟動 raw CDP 與隔離的 Gateway,執行 `browser doctor --deep`,並驗證 CDP role snapshot 包含 link URL、cursor-promoted clickable、iframe ref 與 frame metadata。
|
||||
- CLI backend live Docker probe 可作為 focused lane 執行,例如 `pnpm test:docker:live-cli-backend:codex`、`pnpm test:docker:live-cli-backend:codex:resume` 或 `pnpm test:docker:live-cli-backend:codex:mcp`。Claude 與 Gemini 具有對應的 `:resume` 與 `:mcp` alias。
|
||||
- `pnpm test:docker:openwebui`:啟動 Dockerized OpenClaw + Open WebUI,透過 Open WebUI 登入,檢查 `/api/models`,接著透過 `/api/chat/completions` 執行真實 proxied chat。需要可用的 live model key(例如 `~/.profile` 中的 OpenAI)、會拉取外部 Open WebUI image,且不像一般 unit/e2e suite 那樣預期具備 CI 穩定性。
|
||||
- `pnpm test:docker:mcp-channels`:啟動 seeded Gateway container 與第二個會 spawn `openclaw mcp serve` 的 client container,接著驗證 routed conversation discovery、transcript read、attachment metadata、live event queue behavior、outbound send routing,以及透過真實 stdio bridge 傳送的 Claude-style channel + permission notification。Claude notification assertion 會直接讀取 raw stdio MCP frame,因此 smoke 反映 bridge 實際 emit 的內容。
|
||||
- `pnpm test:docker:upgrade-survivor`: 將封裝好的 OpenClaw tarball 安裝到髒的舊使用者測試夾具上,執行套件更新以及不使用 live provider 或 channel keys 的非互動式 doctor,接著啟動 loopback Gateway,並檢查 agents、channel config、Plugin allowlists、workspace/session files、過時的 Plugin runtime-deps 狀態、startup,以及 RPC status 都能保留下來。
|
||||
|
||||
## 本機 PR 關卡
|
||||
|
||||
對於本機 PR 合併/閘道檢查,請執行:
|
||||
若要在本機執行 PR 合入/關卡檢查,請執行:
|
||||
|
||||
- `pnpm check:changed`
|
||||
- `pnpm check`
|
||||
@ -61,29 +62,29 @@ x-i18n:
|
||||
- `pnpm test`
|
||||
- `pnpm check:docs`
|
||||
|
||||
如果 `pnpm test` 在負載較高的主機上偶發失敗,先重新執行一次,再將其視為回歸;接著用 `pnpm test <path/to/test>` 隔離問題。對於記憶體受限的主機,請使用:
|
||||
如果 `pnpm test` 在負載較高的主機上偶發失敗,請先重新執行一次,再將其視為回歸問題,然後使用 `pnpm test <path/to/test>` 隔離問題。對於記憶體受限的主機,請使用:
|
||||
|
||||
- `OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test`
|
||||
- `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-cache pnpm test:changed`
|
||||
|
||||
## 模型延遲基準測試(本機金鑰)
|
||||
|
||||
腳本:[`scripts/bench-model.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-model.ts)
|
||||
Script:[`scripts/bench-model.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-model.ts)
|
||||
|
||||
用法:
|
||||
|
||||
- `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10`
|
||||
- 可選環境變數:`MINIMAX_API_KEY`、`MINIMAX_BASE_URL`、`MINIMAX_MODEL`、`ANTHROPIC_API_KEY`
|
||||
- 預設提示詞:「回覆單一單字:ok。不要標點符號或額外文字。」
|
||||
- 選用 env:`MINIMAX_API_KEY`、`MINIMAX_BASE_URL`、`MINIMAX_MODEL`、`ANTHROPIC_API_KEY`
|
||||
- 預設提示:「回覆單一單字:ok。不要標點或額外文字。」
|
||||
|
||||
上次執行(2025-12-31,20 次執行):
|
||||
|
||||
- minimax 中位數 1279ms(最小值 1114,最大值 2431)
|
||||
- opus 中位數 2454ms(最小值 1224,最大值 3170)
|
||||
- minimax 中位數 1279ms(最小 1114,最大 2431)
|
||||
- opus 中位數 2454ms(最小 1224,最大 3170)
|
||||
|
||||
## CLI 啟動基準測試
|
||||
|
||||
腳本:[`scripts/bench-cli-startup.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-cli-startup.ts)
|
||||
Script:[`scripts/bench-cli-startup.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-cli-startup.ts)
|
||||
|
||||
用法:
|
||||
|
||||
@ -103,21 +104,21 @@ x-i18n:
|
||||
- `pnpm tsx scripts/bench-cli-startup.ts --preset real --cpu-prof-dir .artifacts/cli-cpu`
|
||||
- `pnpm tsx scripts/bench-cli-startup.ts --json`
|
||||
|
||||
預設組合:
|
||||
預設集:
|
||||
|
||||
- `startup`:`--version`、`--help`、`health`、`health --json`、`status --json`、`status`
|
||||
- `real`:`health`、`status`、`status --json`、`sessions`、`sessions --json`、`tasks --json`、`tasks list --json`、`tasks audit --json`、`agents list --json`、`gateway status`、`gateway status --json`、`gateway health --json`、`config get gateway.port`
|
||||
- `all`:兩個預設組合
|
||||
- `all`:兩個預設集
|
||||
|
||||
輸出包含每個命令的 `sampleCount`、平均值、p50、p95、最小/最大值、結束碼/訊號分布,以及最大 RSS 摘要。可選的 `--cpu-prof-dir` / `--heap-prof-dir` 會為每次執行寫入 V8 設定檔,讓計時與設定檔擷取使用同一套測試工具。
|
||||
輸出包含每個命令的 `sampleCount`、平均值、p50、p95、最小/最大值、結束碼/signal 分佈,以及最大 RSS 摘要。選用的 `--cpu-prof-dir` / `--heap-prof-dir` 會為每次執行寫入 V8 profiles,因此計時與 profile 擷取會使用相同的測試框架。
|
||||
|
||||
儲存輸出慣例:
|
||||
|
||||
- `pnpm test:startup:bench:smoke` 會將目標煙霧測試產物寫入 `.artifacts/cli-startup-bench-smoke.json`
|
||||
- `pnpm test:startup:bench:save` 會使用 `runs=5` 與 `warmup=1` 將完整套件產物寫入 `.artifacts/cli-startup-bench-all.json`
|
||||
- `pnpm test:startup:bench:update` 會使用 `runs=5` 與 `warmup=1` 重新整理已納入版本控制的基準 fixture,位置為 `test/fixtures/cli-startup-bench.json`
|
||||
- `pnpm test:startup:bench:smoke` 會將目標煙霧測試成品寫入 `.artifacts/cli-startup-bench-smoke.json`
|
||||
- `pnpm test:startup:bench:save` 會使用 `runs=5` 和 `warmup=1` 將完整套件成品寫入 `.artifacts/cli-startup-bench-all.json`
|
||||
- `pnpm test:startup:bench:update` 會使用 `runs=5` 和 `warmup=1` 重新整理已提交的基準 fixture,位置為 `test/fixtures/cli-startup-bench.json`
|
||||
|
||||
已納入版本控制的 fixture:
|
||||
已提交的 fixture:
|
||||
|
||||
- `test/fixtures/cli-startup-bench.json`
|
||||
- 使用 `pnpm test:startup:bench:update` 重新整理
|
||||
@ -125,19 +126,19 @@ x-i18n:
|
||||
|
||||
## Onboarding E2E(Docker)
|
||||
|
||||
Docker 是可選項目;只有容器化 onboarding 煙霧測試才需要。
|
||||
Docker 是選用的;只有在容器化 onboarding 煙霧測試時才需要。
|
||||
|
||||
在乾淨的 Linux 容器中執行完整冷啟動流程:
|
||||
在乾淨 Linux 容器中的完整冷啟動流程:
|
||||
|
||||
```bash
|
||||
scripts/e2e/onboard-docker.sh
|
||||
```
|
||||
|
||||
此腳本會透過 pseudo-tty 驅動互動式精靈,驗證設定/工作區/session 檔案,然後啟動 Gateway 並執行 `openclaw health`。
|
||||
此 script 透過 pseudo-tty 驅動互動式精靈,驗證 config/workspace/session 檔案,然後啟動 gateway 並執行 `openclaw health`。
|
||||
|
||||
## QR 匯入煙霧測試(Docker)
|
||||
|
||||
確保維護中的 QR runtime 輔助工具可在支援的 Docker Node runtime(預設 Node 24,相容 Node 22)下載入:
|
||||
確保維護中的 QR runtime helper 能在受支援的 Docker Node runtime 下載入(Node 24 預設,Node 22 相容):
|
||||
|
||||
```bash
|
||||
pnpm test:docker:qr
|
||||
|
||||
Loading…
Reference in New Issue
Block a user