255 lines
6.5 KiB
Markdown
255 lines
6.5 KiB
Markdown
# Continuity Plugin(MVP)
|
||
|
||
> English version: `README.md`
|
||
|
||
這個套件把目前 approved-plan continuity hard gate 抽離成一個可安裝、可測試、可在 hook 內重用的 OpenClaw plugin MVP。
|
||
|
||
目標不是重新發明規則,而是把既有 continuity 判斷、receipt contract、force-recall adapter 收斂成一個可以被其他 OpenClaw workspace 直接帶走的最小可用包。
|
||
|
||
## 目前能做什麼
|
||
|
||
- 驗證 continuity config
|
||
- 驗證 dispatch receipt contract
|
||
- 寫出 receipt 檔案
|
||
- 評估 approved-plan continuity gate
|
||
- 產生可注入 prompt 的 continuity gate block
|
||
- 透過 `force-recall` adapter,把 hook 端的 wrapper/planner 結果轉成 continuity input
|
||
|
||
## 安裝位置
|
||
|
||
建議直接放在 OpenClaw workspace 內:
|
||
|
||
```text
|
||
<workspace>/plugins/continuity
|
||
```
|
||
|
||
以目前 MVP 慣例,相關檔案位置如下:
|
||
|
||
```text
|
||
<workspace>/
|
||
hooks/
|
||
force-recall/
|
||
handler.ts
|
||
HOOK.md
|
||
plugins/
|
||
continuity/
|
||
README.zh-TW.md
|
||
README.md
|
||
HOOK.md
|
||
package.json
|
||
examples/
|
||
src/
|
||
test/
|
||
scripts/
|
||
test_force_recall_long_task_preflight.mjs
|
||
```
|
||
|
||
## 目錄結構
|
||
|
||
```text
|
||
plugins/continuity/
|
||
README.zh-TW.md
|
||
README.md
|
||
HOOK.md
|
||
package.json
|
||
examples/
|
||
approved-plan-receipt.example.json
|
||
openclaw.continuity.example.json
|
||
src/
|
||
index.mjs
|
||
adapters/
|
||
force-recall.mjs
|
||
config/
|
||
defaults.mjs
|
||
schema.mjs
|
||
continuity/
|
||
evaluator.mjs
|
||
receipt-store.mjs
|
||
receipt-validator.mjs
|
||
types.md
|
||
test/
|
||
continuity.config.test.mjs
|
||
continuity.evaluator.test.mjs
|
||
continuity.plugin.test.mjs
|
||
continuity.receipt-store.test.mjs
|
||
continuity.receipt-validator.test.mjs
|
||
continuity.smoke.test.mjs
|
||
```
|
||
|
||
## 公開介面
|
||
|
||
- `src/config/schema.mjs`
|
||
- `src/config/defaults.mjs`
|
||
- `src/continuity/evaluator.mjs`
|
||
- `src/continuity/receipt-validator.mjs`
|
||
- `src/continuity/receipt-store.mjs`
|
||
- `src/adapters/force-recall.mjs`
|
||
- `src/index.mjs`
|
||
|
||
`src/index.mjs` 目前會 re-export:
|
||
|
||
- `defaultConfig`
|
||
- `cloneDefaultConfig()`
|
||
- `validateContinuityConfig()` / `normalizeContinuityConfig()`
|
||
- `evaluateContinuity()` / `buildContinuityGateBlock()`
|
||
- `validateReceipt()` / `isValidReceipt()`
|
||
- `slugifyReceiptSegment()` / `buildReceiptFilename()` / `writeReceipt()`
|
||
- `buildApprovedPlanContinuityInput()`
|
||
- `createForceRecallContinuityAdapter()` / `runForceRecallContinuityAdapter()`
|
||
|
||
## Example config
|
||
|
||
請從 `examples/openclaw.continuity.example.json` 開始:
|
||
|
||
```json
|
||
{
|
||
"enabled": true,
|
||
"planMatchers": ["approved-plan"],
|
||
"legalTerminalStates": [
|
||
"waiting_user",
|
||
"blocked",
|
||
"pending_verification"
|
||
],
|
||
"receiptDir": "state/approved-plan-continuity",
|
||
"requireRealDispatchReceipt": true,
|
||
"allowReplyClosureWithoutDispatch": false,
|
||
"debug": false,
|
||
"adapter": {
|
||
"forceRecall": {
|
||
"enabled": true,
|
||
"injectBlockLabel": "APPROVED_PLAN_CONTINUITY_GATE"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
預設值定義在 `src/config/defaults.mjs`。
|
||
|
||
## Hook 接法
|
||
|
||
MVP 的主要整合點是 `hooks/force-recall/handler.ts`。
|
||
|
||
目前 hook 端做法是:
|
||
|
||
1. 先完成 long-task preflight / gate lock / auto-chain planner
|
||
2. 再動態載入 `plugins/continuity/src/index.mjs`
|
||
3. 呼叫 `runForceRecallContinuityAdapter({ wrapperResult, autoChainPlanResult, config })`
|
||
4. 把 adapter 產出的 block 注入 `bodyForAgent`
|
||
|
||
`handler.ts` 內已有 plugin 路徑接點,關鍵符號是:
|
||
|
||
- `runForceRecallContinuityAdapter`
|
||
- `[APPROVED_PLAN_CONTINUITY_GATE]`
|
||
|
||
最小接法示意:
|
||
|
||
```js
|
||
import plugin from './plugins/continuity/src/index.mjs';
|
||
|
||
const out = plugin.runForceRecallContinuityAdapter({
|
||
config: plugin.defaultConfig,
|
||
wrapperResult,
|
||
autoChainPlanResult,
|
||
});
|
||
|
||
if (out?.block) {
|
||
context.bodyForAgent = `${out.block}\n${context.bodyForAgent}`;
|
||
}
|
||
```
|
||
|
||
若要覆蓋 block label,可改 `adapter.forceRecall.injectBlockLabel`。
|
||
|
||
## Receipt contract
|
||
|
||
最小 receipt shape 如下:
|
||
|
||
- `planId`
|
||
- `currentTask`
|
||
- `nextDerivedAction`
|
||
- `dispatchedAt`
|
||
- `dispatchRunId`
|
||
- `childSessionKey`
|
||
- `replyClosureState`
|
||
|
||
範例可參考 `examples/approved-plan-receipt.example.json`:
|
||
|
||
```json
|
||
{
|
||
"planId": "example-plan",
|
||
"currentTask": "task-01",
|
||
"nextDerivedAction": {
|
||
"kind": "delegate",
|
||
"target": "subagent",
|
||
"task": "placeholder"
|
||
},
|
||
"dispatchedAt": "2026-04-24T16:43:00+08:00",
|
||
"dispatchRunId": "example-run",
|
||
"childSessionKey": "session-placeholder",
|
||
"replyClosureState": "pending_verification"
|
||
}
|
||
```
|
||
|
||
若要把 receipt 落盤,可用:
|
||
|
||
```js
|
||
import { writeReceipt } from './src/index.mjs';
|
||
|
||
await writeReceipt({
|
||
receiptDir: 'state/approved-plan-continuity',
|
||
receipt,
|
||
});
|
||
```
|
||
|
||
## Smoke test / 驗證
|
||
|
||
至少執行以下驗證:
|
||
|
||
```bash
|
||
cd plugins/continuity
|
||
npm test
|
||
|
||
cd /path/to/workspace
|
||
node scripts/test_force_recall_long_task_preflight.mjs
|
||
node --check hooks/force-recall/handler.ts
|
||
```
|
||
|
||
若只想先做 plugin 本體最小檢查,也可以:
|
||
|
||
```bash
|
||
cd plugins/continuity
|
||
node test/continuity.smoke.test.mjs
|
||
```
|
||
|
||
## 安裝與套用步驟(給其他 OpenClaw 使用者)
|
||
|
||
1. 把 `plugins/continuity` 複製到你的 workspace。
|
||
2. 確認 `hooks/force-recall/handler.ts` 會載入 `plugins/continuity/src/index.mjs`。
|
||
3. 視需要調整 continuity config,至少確認:
|
||
- `planMatchers`
|
||
- `legalTerminalStates`
|
||
- `receiptDir`
|
||
- `adapter.forceRecall.injectBlockLabel`
|
||
4. 若你的 dispatch 流程會產生 child run/session,請同步寫出 receipt。
|
||
5. 跑 smoke test 與 hook preflight 測試。
|
||
6. 確認 agent prompt 內可見 continuity gate block,且 dry-run dispatch 不會被誤判為 pass。
|
||
|
||
## 目前限制
|
||
|
||
- 目前是 **approved-plan continuity hard gate** 的 MVP 抽離,不是通用 workflow engine。
|
||
- 主要 adapter 只有 `force-recall`,尚未抽象成多 hook / 多事件通用介面。
|
||
- config 目前是模組內預設 + 呼叫端傳入,還沒有完整的 OpenClaw plugin 安裝器/註冊流程文件。
|
||
- receipt store 只負責寫檔,不含 retention、cleanup、indexing。
|
||
- receipt validator 目前只檢查最小 contract,不驗證每個 `nextDerivedAction` 子欄位語意。
|
||
- 文件描述的是「依現有 hook 整合」的安裝方式;若未採用 `force-recall` preflight 鏈,仍需自行補 glue code。
|
||
|
||
## 備註
|
||
|
||
- 預設 legal terminal states:`waiting_user`、`blocked`、`pending_verification`
|
||
- evaluator 保留既有行為,包括 `missing_dispatch_receipt` 與 `missing_auto_next_dispatch`
|
||
- adapter 維持與 `hooks/force-recall/handler.ts` 的 continuity input mapping 一致
|
||
- `HOOK.md` 說明的是 plugin/hook adapter 契約定位,不是完整安裝說明
|
||
|
||
## 英文文件
|
||
|
||
英文版請見 `README.md`。
|