@xgjktech/xg-openclaw-harness-tools 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -171
- package/dist/plan-prompt.js +1 -1
- package/dist/plan-view.d.ts +2 -2
- package/dist/plan-view.js +5 -5
- package/dist/plan-write-tool.js +1 -1
- package/openclaw.plugin.json +14 -14
- package/package.json +57 -57
package/README.md
CHANGED
|
@@ -1,171 +1,171 @@
|
|
|
1
|
-
# @xgjktech/xg-openclaw-harness-tools
|
|
2
|
-
|
|
3
|
-
OpenClaw 第三方工具插件:企业计划工具 `xg_plan_write` / `xg_plan_view`。
|
|
4
|
-
|
|
5
|
-
用一份持久化的计划(SQLite 落盘)取代内置 `update_plan`(无状态、只回显、不落库),
|
|
6
|
-
`xg_plan_write` 整张维护草稿计划,`xg_plan_view` 只读查看计划或最近摘要。
|
|
7
|
-
|
|
8
|
-
## 架构裁决:实时事件当前处于事实性休眠(务必先读)
|
|
9
|
-
|
|
10
|
-
**当前 OpenClaw 2026.6.10 版本下,实时事件推送链路休眠**:工具 execute/factory 期没有
|
|
11
|
-
正当途径获取真实 runId(详见 `docs/notes-plugin-entry.md` N2),且 0.3.0 已移除工具侧
|
|
12
|
-
`notify.ts`。`xg_plan_write` 落库后不发事件,`xg_plan_view` 全程只读。
|
|
13
|
-
|
|
14
|
-
**因此 IM 侧(或任何下游消费方)不得依赖实时事件感知计划进度。** 当前唯一可靠的主感知路径是:
|
|
15
|
-
|
|
16
|
-
1. **SQLite 读取**——IM 用 `openPlanStoreReadonly(dbPath)` 按 origin 只读反查
|
|
17
|
-
`<stateDir>/xgjktech/plans.sqlite` 并推送全量快照,这是权威状态源。
|
|
18
|
-
2. **agent 最终回复**——agent 完成任务后的文本回复本身会体现进度。
|
|
19
|
-
|
|
20
|
-
事件契约(`PlanEventPayload` / `isPlanEventPayload` / `planEventStream`)在 shared 中原样保留,
|
|
21
|
-
仅用于下游编译兼容。未来恢复实时事件需要重新实现工具侧生产与 IM 侧消费,并单独发布。
|
|
22
|
-
|
|
23
|
-
## 环境要求
|
|
24
|
-
|
|
25
|
-
- **Node ≥ 22.19.0**(依赖 `node:sqlite`,与 OpenClaw 自身 `engines` 一致)。
|
|
26
|
-
- monorepo 用 npm workspaces。
|
|
27
|
-
|
|
28
|
-
## 安装与构建
|
|
29
|
-
|
|
30
|
-
本仓库是包含 `@xgjktech/xg-openclaw-shared`(存储层+事件契约层)和
|
|
31
|
-
`@xgjktech/xg-openclaw-harness-tools`(本插件)两个 workspace 的 monorepo。**`xg-shared` 必须先于
|
|
32
|
-
本插件构建**(本插件依赖它的编译产物);npm workspaces 拓扑已保证顺序,直接在仓库根执行:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npm install
|
|
36
|
-
npm run build
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
产物:`packages/xg-harness-tools/dist/`(含 `index.js` 与 `.d.ts`)。
|
|
40
|
-
|
|
41
|
-
将本插件安装到 OpenClaw 的具体命令/目录约定,请对照 OpenClaw 的第三方插件安装机制
|
|
42
|
-
(global / workspace / config origin,本插件按非 bundled 第三方路径运行)以及
|
|
43
|
-
`package.json` 里的 `openclaw.*` 字段块(`extensions`/`install.localPath` 等)。
|
|
44
|
-
P1 阶段不锁死具体安装命令,避免与实际安装流程漂移(详见 `docs/05-部署文档.md` §3.3)。
|
|
45
|
-
|
|
46
|
-
## 配置
|
|
47
|
-
|
|
48
|
-
### 1. 屏蔽内置 update_plan(deny,唯一权威路径)
|
|
49
|
-
|
|
50
|
-
```jsonc
|
|
51
|
-
{
|
|
52
|
-
"tools": {
|
|
53
|
-
"deny": ["update_plan"]
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
无论生产 profile / allowlist 取何值(包括 `allow:["*"]`),`deny` 都一票否决,
|
|
59
|
-
与 profile 取值解耦。
|
|
60
|
-
|
|
61
|
-
### 2. 启用本插件两个工具(allow)
|
|
62
|
-
|
|
63
|
-
本插件两个工具都以 `optional:true` 注册,**默认不启用**,必须 allowlist 显式命中才会注册:
|
|
64
|
-
|
|
65
|
-
```jsonc
|
|
66
|
-
{
|
|
67
|
-
"tools": {
|
|
68
|
-
"allow": ["xg_plan_write", "xg_plan_view"],
|
|
69
|
-
"deny": ["update_plan"]
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
可直接套用的完整样例见仓库根 [`deploy/tools.config.sample.jsonc`](../../deploy/tools.config.sample.jsonc)(带注释)。
|
|
75
|
-
|
|
76
|
-
### 3. stateDir 与数据库路径
|
|
77
|
-
|
|
78
|
-
插件运行时数据库路径固定为:
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
<stateDir>/xgjktech/plans.sqlite
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
`stateDir` 取自 OpenClaw 全局状态目录(`api.runtime.state.resolveStateDir()`,默认
|
|
85
|
-
`~/.openclaw/`,`OPENCLAW_STATE_DIR` 覆盖时同步),插件首次运行时通过 `resolvePlanDbPath`
|
|
86
|
-
自动 `mkdir -p` 出 `xgjktech/` 子目录,无需手动创建。IM 插件若要接入同一份数据,应复用
|
|
87
|
-
同一个 `resolvePlanDbPath` 以保证路径约定一致。
|
|
88
|
-
|
|
89
|
-
## 两个工具说明
|
|
90
|
-
|
|
91
|
-
### `xg_plan_write`
|
|
92
|
-
|
|
93
|
-
整张创建或覆盖一份草稿计划(goal + tasks[])并写入 SQLite。更新时必须重交所有要保留的
|
|
94
|
-
task;写入 schema 不接受 steps,但读取旧计划仍兼容旧 steps 数据。
|
|
95
|
-
|
|
96
|
-
### `xg_plan_view`
|
|
97
|
-
|
|
98
|
-
只读查看计划,**不会执行任何任务**。带 planId 返回完整紧凑 view;不带 planId 返回最近 10 条
|
|
99
|
-
计划摘要,用于跨会话找回 planId。更新进度统一使用 `xg_plan_write` 整张重交。
|
|
100
|
-
|
|
101
|
-
> 工具名用 `view` 而非 `execute` 是有意的:`plan_view`/`plan_write` 都只是台账,不执行、不调度、
|
|
102
|
-
> 无后台运行。二者 description 均明确"保存/查看 ≠ 执行",且结果带 `reminder` 字段引导模型
|
|
103
|
-
> 继续逐项实际执行任务——避免模型调用计划工具后误以为工作已在后台完成而停住。
|
|
104
|
-
|
|
105
|
-
两个工具的完整参数 schema 见 `src/plan-write-tool.ts` / `src/plan-view-tool.ts`
|
|
106
|
-
中的 `PLAN_WRITE_DESCRIPTION` / `PLAN_VIEW_DESCRIPTION`。
|
|
107
|
-
|
|
108
|
-
## 主动计划提示词注入(before_prompt_build)
|
|
109
|
-
|
|
110
|
-
插件在 `register` 时挂载 `before_prompt_build` hook,用 `appendSystemContext` 向每个 agent 的
|
|
111
|
-
system prompt 追加一段"主动工作计划"纪律(`src/plan-prompt.ts`):多步工作先建计划、逐项整张回写、
|
|
112
|
-
blocked 带 note、台账≠执行。内容与工具 description 一致,仅抬升"主动触发"的优先级。
|
|
113
|
-
|
|
114
|
-
- **与其他注入不冲突**:IM 通道的 `GroupSystemPrompt` 落在 base system prompt,本段追加在其后,
|
|
115
|
-
纯叠加不覆盖;对内置 runtime 与 Codex runtime 均生效。
|
|
116
|
-
- **如需关闭**:在部署配置里对该插件入口设 `hooks.allowPromptInjection: false`(默认放行):
|
|
117
|
-
|
|
118
|
-
```jsonc
|
|
119
|
-
{
|
|
120
|
-
"plugins": {
|
|
121
|
-
"entries": {
|
|
122
|
-
"xg-harness-tools": { "hooks": { "allowPromptInjection": false } }
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
- 若部署方同时手工把 `docs/09-plan-usage-guide.md` 的 System Prompt 模版写进 AGENTS.md/频道
|
|
129
|
-
systemPrompt,会与本段叠加——冗余无害,可按需取舍。
|
|
130
|
-
|
|
131
|
-
## 部署 checklist
|
|
132
|
-
|
|
133
|
-
- [ ] Node ≥ 22.19.0
|
|
134
|
-
- [ ] monorepo 构建成功(`xg-shared` 先于本插件构建,workspaces 拓扑自动保证)
|
|
135
|
-
- [ ] 插件已安装且被 OpenClaw 识别为已加载的第三方插件(非 bundled)
|
|
136
|
-
- [ ] `tools.deny` 含 `update_plan`
|
|
137
|
-
- [ ] `tools.allow` 含 `xg_plan_write` + `xg_plan_view`(或经 `group:plugins` / `*` 放行)
|
|
138
|
-
- [ ] 实拉一个 agent,验证工具清单**有本插件两工具、无 update_plan**(步骤见下节)
|
|
139
|
-
- [ ] `<stateDir>/xgjktech/` 可写,首次运行能生成 `plans.sqlite`
|
|
140
|
-
- [ ] (互通)IM 侧已依赖 `@xgjktech/xg-openclaw-shared` 并按 `docs/04-互通设计.md` 接入只读反查
|
|
141
|
-
|
|
142
|
-
## 实机验证步骤(可复现)+ 当前实际执行情况说明
|
|
143
|
-
|
|
144
|
-
**验收标准要求部署方按 checklist 实拉一个 agent,确认工具清单里有 `xg_plan_write`/
|
|
145
|
-
`xg_plan_view`、没有 `update_plan`。以下是可复现的验证步骤:**
|
|
146
|
-
|
|
147
|
-
1. 按上文"配置"章节把 `tools.deny`/`tools.allow` 写入生产 agent/profile 配置。
|
|
148
|
-
2. 安装并加载本插件(确认加载日志/插件列表里出现 `xg-harness-tools`,origin 为第三方非 bundled)。
|
|
149
|
-
3. 拉起一个真实 agent 会话,触发一次会列出可用工具的动作(例如让 agent 描述自己有哪些工具,
|
|
150
|
-
或查看 gateway/日志里该次 attempt 实际注册的工具名列表)。
|
|
151
|
-
4. 核对该工具列表:应包含 `xg_plan_write` 与 `xg_plan_view`,**不应包含** `update_plan`。
|
|
152
|
-
5. 调用一次 `xg_plan_write` 建一份最小计划,确认返回 `planId + view`;再用该 planId 调
|
|
153
|
-
`xg_plan_view`,确认只读 view 一致。用 `openPlanStoreReadonly` 反查并核对落盘内容。
|
|
154
|
-
|
|
155
|
-
**本项在本次交付中未在真实 OpenClaw gateway 环境实机执行**——本仓库当前开发环境没有可用的
|
|
156
|
-
真实 OpenClaw gateway/agent 运行环境,因此无法诚实地报告"已实拉 agent 验证通过"。以下是
|
|
157
|
-
已经做过、可以作为间接佐证的验证,但**明确说明这不等于实机验证**:
|
|
158
|
-
|
|
159
|
-
- 当前 factory 集成测试用**手工构造的 mock `api`**捕获 2 个工具的注册工厂,并提供带
|
|
160
|
-
`sessionKey`/`deliveryContext` 的 `toolContext`:`xg_plan_write` 写入后通过只读存储反查
|
|
161
|
-
`origin`,`xg_plan_view` 校验指定计划的 view 与最近计划列表。**这验证的是插件代码本身
|
|
162
|
-
可以被正确加载、注册并贯通当前契约**,但 mock `api` 不是真实 OpenClaw gateway 的
|
|
163
|
-
`tools.allow`/`deny` 策略引擎,**不能**佐证"生产 deny/allow 配置生效后工具清单精确符合
|
|
164
|
-
预期"这一条——那一条必须在真实 gateway 环境按上面 5 步实测。
|
|
165
|
-
- T6 阶段(`packages/xg-harness-tools/src/integration.test.ts`)用真实的 `SqlitePlanStore`
|
|
166
|
-
(临时目录)+ 真实工具函数(`buildPlanWriteTool`/`buildPlanViewTool`)跑通了完整的
|
|
167
|
-
写入→整张重交→execute 只读查看→SQLite 只读反查链路,但同样不经过 OpenClaw 的工具
|
|
168
|
-
allowlist/deny 策略引擎。
|
|
169
|
-
|
|
170
|
-
**结论:部署方在生产环境落实上述配置后,必须按"实机验证步骤"重新执行一次实拉 agent 验证,
|
|
171
|
-
不能以本仓库现有的 mock/集成测试结果代替。**
|
|
1
|
+
# @xgjktech/xg-openclaw-harness-tools
|
|
2
|
+
|
|
3
|
+
OpenClaw 第三方工具插件:企业计划工具 `xg_plan_write` / `xg_plan_view`。
|
|
4
|
+
|
|
5
|
+
用一份持久化的计划(SQLite 落盘)取代内置 `update_plan`(无状态、只回显、不落库),
|
|
6
|
+
`xg_plan_write` 整张维护草稿计划,`xg_plan_view` 只读查看计划或最近摘要。
|
|
7
|
+
|
|
8
|
+
## 架构裁决:实时事件当前处于事实性休眠(务必先读)
|
|
9
|
+
|
|
10
|
+
**当前 OpenClaw 2026.6.10 版本下,实时事件推送链路休眠**:工具 execute/factory 期没有
|
|
11
|
+
正当途径获取真实 runId(详见 `docs/notes-plugin-entry.md` N2),且 0.3.0 已移除工具侧
|
|
12
|
+
`notify.ts`。`xg_plan_write` 落库后不发事件,`xg_plan_view` 全程只读。
|
|
13
|
+
|
|
14
|
+
**因此 IM 侧(或任何下游消费方)不得依赖实时事件感知计划进度。** 当前唯一可靠的主感知路径是:
|
|
15
|
+
|
|
16
|
+
1. **SQLite 读取**——IM 用 `openPlanStoreReadonly(dbPath)` 按 origin 只读反查
|
|
17
|
+
`<stateDir>/xgjktech/plans.sqlite` 并推送全量快照,这是权威状态源。
|
|
18
|
+
2. **agent 最终回复**——agent 完成任务后的文本回复本身会体现进度。
|
|
19
|
+
|
|
20
|
+
事件契约(`PlanEventPayload` / `isPlanEventPayload` / `planEventStream`)在 shared 中原样保留,
|
|
21
|
+
仅用于下游编译兼容。未来恢复实时事件需要重新实现工具侧生产与 IM 侧消费,并单独发布。
|
|
22
|
+
|
|
23
|
+
## 环境要求
|
|
24
|
+
|
|
25
|
+
- **Node ≥ 22.19.0**(依赖 `node:sqlite`,与 OpenClaw 自身 `engines` 一致)。
|
|
26
|
+
- monorepo 用 npm workspaces。
|
|
27
|
+
|
|
28
|
+
## 安装与构建
|
|
29
|
+
|
|
30
|
+
本仓库是包含 `@xgjktech/xg-openclaw-shared`(存储层+事件契约层)和
|
|
31
|
+
`@xgjktech/xg-openclaw-harness-tools`(本插件)两个 workspace 的 monorepo。**`xg-shared` 必须先于
|
|
32
|
+
本插件构建**(本插件依赖它的编译产物);npm workspaces 拓扑已保证顺序,直接在仓库根执行:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install
|
|
36
|
+
npm run build
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
产物:`packages/xg-harness-tools/dist/`(含 `index.js` 与 `.d.ts`)。
|
|
40
|
+
|
|
41
|
+
将本插件安装到 OpenClaw 的具体命令/目录约定,请对照 OpenClaw 的第三方插件安装机制
|
|
42
|
+
(global / workspace / config origin,本插件按非 bundled 第三方路径运行)以及
|
|
43
|
+
`package.json` 里的 `openclaw.*` 字段块(`extensions`/`install.localPath` 等)。
|
|
44
|
+
P1 阶段不锁死具体安装命令,避免与实际安装流程漂移(详见 `docs/05-部署文档.md` §3.3)。
|
|
45
|
+
|
|
46
|
+
## 配置
|
|
47
|
+
|
|
48
|
+
### 1. 屏蔽内置 update_plan(deny,唯一权威路径)
|
|
49
|
+
|
|
50
|
+
```jsonc
|
|
51
|
+
{
|
|
52
|
+
"tools": {
|
|
53
|
+
"deny": ["update_plan"]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
无论生产 profile / allowlist 取何值(包括 `allow:["*"]`),`deny` 都一票否决,
|
|
59
|
+
与 profile 取值解耦。
|
|
60
|
+
|
|
61
|
+
### 2. 启用本插件两个工具(allow)
|
|
62
|
+
|
|
63
|
+
本插件两个工具都以 `optional:true` 注册,**默认不启用**,必须 allowlist 显式命中才会注册:
|
|
64
|
+
|
|
65
|
+
```jsonc
|
|
66
|
+
{
|
|
67
|
+
"tools": {
|
|
68
|
+
"allow": ["xg_plan_write", "xg_plan_view"],
|
|
69
|
+
"deny": ["update_plan"]
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
可直接套用的完整样例见仓库根 [`deploy/tools.config.sample.jsonc`](../../deploy/tools.config.sample.jsonc)(带注释)。
|
|
75
|
+
|
|
76
|
+
### 3. stateDir 与数据库路径
|
|
77
|
+
|
|
78
|
+
插件运行时数据库路径固定为:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
<stateDir>/xgjktech/plans.sqlite
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`stateDir` 取自 OpenClaw 全局状态目录(`api.runtime.state.resolveStateDir()`,默认
|
|
85
|
+
`~/.openclaw/`,`OPENCLAW_STATE_DIR` 覆盖时同步),插件首次运行时通过 `resolvePlanDbPath`
|
|
86
|
+
自动 `mkdir -p` 出 `xgjktech/` 子目录,无需手动创建。IM 插件若要接入同一份数据,应复用
|
|
87
|
+
同一个 `resolvePlanDbPath` 以保证路径约定一致。
|
|
88
|
+
|
|
89
|
+
## 两个工具说明
|
|
90
|
+
|
|
91
|
+
### `xg_plan_write`
|
|
92
|
+
|
|
93
|
+
整张创建或覆盖一份草稿计划(goal + tasks[])并写入 SQLite。更新时必须重交所有要保留的
|
|
94
|
+
task;写入 schema 不接受 steps,但读取旧计划仍兼容旧 steps 数据。
|
|
95
|
+
|
|
96
|
+
### `xg_plan_view`
|
|
97
|
+
|
|
98
|
+
只读查看计划,**不会执行任何任务**。带 planId 返回完整紧凑 view;不带 planId 返回最近 10 条
|
|
99
|
+
计划摘要,用于跨会话找回 planId。更新进度统一使用 `xg_plan_write` 整张重交。
|
|
100
|
+
|
|
101
|
+
> 工具名用 `view` 而非 `execute` 是有意的:`plan_view`/`plan_write` 都只是台账,不执行、不调度、
|
|
102
|
+
> 无后台运行。二者 description 均明确"保存/查看 ≠ 执行",且结果带 `reminder` 字段引导模型
|
|
103
|
+
> 继续逐项实际执行任务——避免模型调用计划工具后误以为工作已在后台完成而停住。
|
|
104
|
+
|
|
105
|
+
两个工具的完整参数 schema 见 `src/plan-write-tool.ts` / `src/plan-view-tool.ts`
|
|
106
|
+
中的 `PLAN_WRITE_DESCRIPTION` / `PLAN_VIEW_DESCRIPTION`。
|
|
107
|
+
|
|
108
|
+
## 主动计划提示词注入(before_prompt_build)
|
|
109
|
+
|
|
110
|
+
插件在 `register` 时挂载 `before_prompt_build` hook,用 `appendSystemContext` 向每个 agent 的
|
|
111
|
+
system prompt 追加一段"主动工作计划"纪律(`src/plan-prompt.ts`):多步工作先建计划、逐项整张回写、
|
|
112
|
+
blocked 带 note、台账≠执行。内容与工具 description 一致,仅抬升"主动触发"的优先级。
|
|
113
|
+
|
|
114
|
+
- **与其他注入不冲突**:IM 通道的 `GroupSystemPrompt` 落在 base system prompt,本段追加在其后,
|
|
115
|
+
纯叠加不覆盖;对内置 runtime 与 Codex runtime 均生效。
|
|
116
|
+
- **如需关闭**:在部署配置里对该插件入口设 `hooks.allowPromptInjection: false`(默认放行):
|
|
117
|
+
|
|
118
|
+
```jsonc
|
|
119
|
+
{
|
|
120
|
+
"plugins": {
|
|
121
|
+
"entries": {
|
|
122
|
+
"xg-harness-tools": { "hooks": { "allowPromptInjection": false } }
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- 若部署方同时手工把 `docs/09-plan-usage-guide.md` 的 System Prompt 模版写进 AGENTS.md/频道
|
|
129
|
+
systemPrompt,会与本段叠加——冗余无害,可按需取舍。
|
|
130
|
+
|
|
131
|
+
## 部署 checklist
|
|
132
|
+
|
|
133
|
+
- [ ] Node ≥ 22.19.0
|
|
134
|
+
- [ ] monorepo 构建成功(`xg-shared` 先于本插件构建,workspaces 拓扑自动保证)
|
|
135
|
+
- [ ] 插件已安装且被 OpenClaw 识别为已加载的第三方插件(非 bundled)
|
|
136
|
+
- [ ] `tools.deny` 含 `update_plan`
|
|
137
|
+
- [ ] `tools.allow` 含 `xg_plan_write` + `xg_plan_view`(或经 `group:plugins` / `*` 放行)
|
|
138
|
+
- [ ] 实拉一个 agent,验证工具清单**有本插件两工具、无 update_plan**(步骤见下节)
|
|
139
|
+
- [ ] `<stateDir>/xgjktech/` 可写,首次运行能生成 `plans.sqlite`
|
|
140
|
+
- [ ] (互通)IM 侧已依赖 `@xgjktech/xg-openclaw-shared` 并按 `docs/04-互通设计.md` 接入只读反查
|
|
141
|
+
|
|
142
|
+
## 实机验证步骤(可复现)+ 当前实际执行情况说明
|
|
143
|
+
|
|
144
|
+
**验收标准要求部署方按 checklist 实拉一个 agent,确认工具清单里有 `xg_plan_write`/
|
|
145
|
+
`xg_plan_view`、没有 `update_plan`。以下是可复现的验证步骤:**
|
|
146
|
+
|
|
147
|
+
1. 按上文"配置"章节把 `tools.deny`/`tools.allow` 写入生产 agent/profile 配置。
|
|
148
|
+
2. 安装并加载本插件(确认加载日志/插件列表里出现 `xg-harness-tools`,origin 为第三方非 bundled)。
|
|
149
|
+
3. 拉起一个真实 agent 会话,触发一次会列出可用工具的动作(例如让 agent 描述自己有哪些工具,
|
|
150
|
+
或查看 gateway/日志里该次 attempt 实际注册的工具名列表)。
|
|
151
|
+
4. 核对该工具列表:应包含 `xg_plan_write` 与 `xg_plan_view`,**不应包含** `update_plan`。
|
|
152
|
+
5. 调用一次 `xg_plan_write` 建一份最小计划,确认返回 `planId + view`;再用该 planId 调
|
|
153
|
+
`xg_plan_view`,确认只读 view 一致。用 `openPlanStoreReadonly` 反查并核对落盘内容。
|
|
154
|
+
|
|
155
|
+
**本项在本次交付中未在真实 OpenClaw gateway 环境实机执行**——本仓库当前开发环境没有可用的
|
|
156
|
+
真实 OpenClaw gateway/agent 运行环境,因此无法诚实地报告"已实拉 agent 验证通过"。以下是
|
|
157
|
+
已经做过、可以作为间接佐证的验证,但**明确说明这不等于实机验证**:
|
|
158
|
+
|
|
159
|
+
- 当前 factory 集成测试用**手工构造的 mock `api`**捕获 2 个工具的注册工厂,并提供带
|
|
160
|
+
`sessionKey`/`deliveryContext` 的 `toolContext`:`xg_plan_write` 写入后通过只读存储反查
|
|
161
|
+
`origin`,`xg_plan_view` 校验指定计划的 view 与最近计划列表。**这验证的是插件代码本身
|
|
162
|
+
可以被正确加载、注册并贯通当前契约**,但 mock `api` 不是真实 OpenClaw gateway 的
|
|
163
|
+
`tools.allow`/`deny` 策略引擎,**不能**佐证"生产 deny/allow 配置生效后工具清单精确符合
|
|
164
|
+
预期"这一条——那一条必须在真实 gateway 环境按上面 5 步实测。
|
|
165
|
+
- T6 阶段(`packages/xg-harness-tools/src/integration.test.ts`)用真实的 `SqlitePlanStore`
|
|
166
|
+
(临时目录)+ 真实工具函数(`buildPlanWriteTool`/`buildPlanViewTool`)跑通了完整的
|
|
167
|
+
写入→整张重交→execute 只读查看→SQLite 只读反查链路,但同样不经过 OpenClaw 的工具
|
|
168
|
+
allowlist/deny 策略引擎。
|
|
169
|
+
|
|
170
|
+
**结论:部署方在生产环境落实上述配置后,必须按"实机验证步骤"重新执行一次实拉 agent 验证,
|
|
171
|
+
不能以本仓库现有的 mock/集成测试结果代替。**
|
package/dist/plan-prompt.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export const PLAN_FIRST_SYSTEM_CONTEXT = [
|
|
7
7
|
"## 主动工作计划(xg-harness-tools)",
|
|
8
|
-
"- 工具调用前置规则:只要本轮需要产生任何 tool call,第一个 tool call 必须是 xg_plan_write,用它建立或更新当前 todo;xg_plan_write
|
|
8
|
+
"- 工具调用前置规则:只要本轮需要产生任何 tool call,第一个 tool call 必须是 xg_plan_write,用它建立或更新当前 todo;xg_plan_write 这一次调用本身无需再次建计划;跨会话恢复旧计划但记不清 planId 时,先用 xg_plan_view 找回。",
|
|
9
9
|
"- 计划触发不依赖任务数量:即使只有一个动作,只要需要调用工具,也必须先记录 todo;纯文字问答且不调用工具时无需建计划。",
|
|
10
10
|
"- 建立 todo 后再调用其他工具;可以连续执行多个 tool call,不必每个 tool call 后都回写。",
|
|
11
11
|
"- 关键节点必须回写:任务开始、完成、暂停、阻塞、方向变化或发现新工作项时,用 xg_plan_write 整张重交更新状态。",
|
package/dist/plan-view.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type Plan } from "@xgjktech/xg-openclaw-shared";
|
|
2
2
|
export declare function renderPlanView(plan: Plan): string;
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* 规则:优先 in_progress(继续手头任务)→ 其次 pending
|
|
4
|
+
* 生成"下一步该做什么"的命令式提醒,喂给模型防止其只记录不执行。
|
|
5
|
+
* 规则:优先 in_progress(继续手头任务)→ 其次 pending(开新任务,并先标 in_progress)→ 只剩 blocked 时提示等待/取消;
|
|
6
6
|
* 全部完成或已取消则返回 undefined。
|
|
7
7
|
*/
|
|
8
8
|
export declare function buildPlanReminder(plan: Plan): string | undefined;
|
package/dist/plan-view.js
CHANGED
|
@@ -28,8 +28,8 @@ export function renderPlanView(plan) {
|
|
|
28
28
|
return lines.join("\n");
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
* 规则:优先 in_progress(继续手头任务)→ 其次 pending
|
|
31
|
+
* 生成"下一步该做什么"的命令式提醒,喂给模型防止其只记录不执行。
|
|
32
|
+
* 规则:优先 in_progress(继续手头任务)→ 其次 pending(开新任务,并先标 in_progress)→ 只剩 blocked 时提示等待/取消;
|
|
33
33
|
* 全部完成或已取消则返回 undefined。
|
|
34
34
|
*/
|
|
35
35
|
export function buildPlanReminder(plan) {
|
|
@@ -40,15 +40,15 @@ export function buildPlanReminder(plan) {
|
|
|
40
40
|
return undefined;
|
|
41
41
|
const inProgress = unfinished.find((task) => task.status === "in_progress");
|
|
42
42
|
if (inProgress !== undefined) {
|
|
43
|
-
return
|
|
43
|
+
return `下一步:继续执行「${singleLine(inProgress.title)}」,完成后用 xg_plan_write 回写状态`;
|
|
44
44
|
}
|
|
45
45
|
const pending = unfinished.find((task) => task.status === "pending");
|
|
46
46
|
if (pending !== undefined) {
|
|
47
|
-
return
|
|
47
|
+
return `下一步:开始执行「${singleLine(pending.title)}」,并先把其状态更新为 in_progress`;
|
|
48
48
|
}
|
|
49
49
|
const blockedCount = unfinished.filter((task) => task.status === "blocked").length;
|
|
50
50
|
if (blockedCount > 0) {
|
|
51
|
-
return
|
|
51
|
+
return `当前有 ${blockedCount} 项 blocked,等待 note 中记录的条件满足后再推进;若不再推进请取消计划`;
|
|
52
52
|
}
|
|
53
53
|
return undefined;
|
|
54
54
|
}
|
package/dist/plan-write-tool.js
CHANGED
|
@@ -37,7 +37,7 @@ export const PLAN_WRITE_DESCRIPTION = [
|
|
|
37
37
|
"",
|
|
38
38
|
"【主动建计划:不要等用户要求】",
|
|
39
39
|
"识别到以下任一情形,都应主动调用本工具建立计划,而不是仅用文字回复或直接闷头推进:",
|
|
40
|
-
"- 本轮需要产生任何 tool call:第一个 tool call 必须是 xg_plan_write;xg_plan_write
|
|
40
|
+
"- 本轮需要产生任何 tool call:第一个 tool call 必须是 xg_plan_write;xg_plan_write 这一次调用本身无需再次建计划;跨会话恢复旧计划但记不清 planId 时,先用 xg_plan_view 找回。",
|
|
41
41
|
"- 目标需要两个或更多连续动作才能完成。",
|
|
42
42
|
"- 预计需要多轮推进,或可能中断后继续(跨回合/跨天)。",
|
|
43
43
|
"- 需要等待人的回复、审批或外部系统。",
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "xg-harness-tools",
|
|
3
|
-
"name": "XG Harness Tools",
|
|
4
|
-
"description": "企业工具插件:计划管理与通用动作分发(plan_write / plan_view / action_dispatch)",
|
|
5
|
-
"version": "0.4.4",
|
|
6
|
-
"configSchema": {
|
|
7
|
-
"type": "object",
|
|
8
|
-
"additionalProperties": true,
|
|
9
|
-
"properties": {}
|
|
10
|
-
},
|
|
11
|
-
"contracts": {
|
|
12
|
-
"tools": ["xg_plan_write", "xg_plan_view", "xg_action_dispatch"]
|
|
13
|
-
}
|
|
14
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"id": "xg-harness-tools",
|
|
3
|
+
"name": "XG Harness Tools",
|
|
4
|
+
"description": "企业工具插件:计划管理与通用动作分发(plan_write / plan_view / action_dispatch)",
|
|
5
|
+
"version": "0.4.4",
|
|
6
|
+
"configSchema": {
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": true,
|
|
9
|
+
"properties": {}
|
|
10
|
+
},
|
|
11
|
+
"contracts": {
|
|
12
|
+
"tools": ["xg_plan_write", "xg_plan_view", "xg_action_dispatch"]
|
|
13
|
+
}
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@xgjktech/xg-openclaw-harness-tools",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "企业工具插件:plan_write / plan_view / action_dispatch(OpenClaw 第三方工具插件)",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"engines": {
|
|
8
|
-
"node": ">=22.19.0"
|
|
9
|
-
},
|
|
10
|
-
"main": "dist/index.js",
|
|
11
|
-
"types": "dist/index.d.ts",
|
|
12
|
-
"files": [
|
|
13
|
-
"dist/**/*",
|
|
14
|
-
"!dist/*.test.*",
|
|
15
|
-
"openclaw.plugin.json"
|
|
16
|
-
],
|
|
17
|
-
"publishConfig": {
|
|
18
|
-
"access": "public",
|
|
19
|
-
"registry": "https://registry.npmjs.org/"
|
|
20
|
-
},
|
|
21
|
-
"scripts": {
|
|
22
|
-
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
23
|
-
"prebuild": "npm run clean",
|
|
24
|
-
"build": "tsc -p tsconfig.json",
|
|
25
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
26
|
-
"pretest": "npm run build",
|
|
27
|
-
"test": "node --test dist/*.test.js",
|
|
28
|
-
"prepublishOnly": "npm run build && npm run test"
|
|
29
|
-
},
|
|
30
|
-
"dependencies": {
|
|
31
|
-
"typebox": "1.1.39",
|
|
32
|
-
"@xgjktech/xg-openclaw-shared": "^0.2.2"
|
|
33
|
-
},
|
|
34
|
-
"devDependencies": {
|
|
35
|
-
"@types/node": "^22.19.0",
|
|
36
|
-
"openclaw": "2026.6.10",
|
|
37
|
-
"typescript": "^5.6.0"
|
|
38
|
-
},
|
|
39
|
-
"peerDependencies": {
|
|
40
|
-
"openclaw": ">=2026.6.10"
|
|
41
|
-
},
|
|
42
|
-
"peerDependenciesMeta": {
|
|
43
|
-
"openclaw": {
|
|
44
|
-
"optional": true
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"openclaw": {
|
|
48
|
-
"extensions": [
|
|
49
|
-
"./dist/index.js"
|
|
50
|
-
],
|
|
51
|
-
"installDependencies": false,
|
|
52
|
-
"install": {
|
|
53
|
-
"localPath": ".",
|
|
54
|
-
"defaultChoice": "local"
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@xgjktech/xg-openclaw-harness-tools",
|
|
3
|
+
"version": "0.4.5",
|
|
4
|
+
"description": "企业工具插件:plan_write / plan_view / action_dispatch(OpenClaw 第三方工具插件)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.19.0"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/index.js",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/**/*",
|
|
14
|
+
"!dist/*.test.*",
|
|
15
|
+
"openclaw.plugin.json"
|
|
16
|
+
],
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public",
|
|
19
|
+
"registry": "https://registry.npmjs.org/"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
23
|
+
"prebuild": "npm run clean",
|
|
24
|
+
"build": "tsc -p tsconfig.json",
|
|
25
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
26
|
+
"pretest": "npm run build",
|
|
27
|
+
"test": "node --test dist/*.test.js",
|
|
28
|
+
"prepublishOnly": "npm run build && npm run test"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"typebox": "1.1.39",
|
|
32
|
+
"@xgjktech/xg-openclaw-shared": "^0.2.2"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^22.19.0",
|
|
36
|
+
"openclaw": "2026.6.10",
|
|
37
|
+
"typescript": "^5.6.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"openclaw": ">=2026.6.10"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"openclaw": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"openclaw": {
|
|
48
|
+
"extensions": [
|
|
49
|
+
"./dist/index.js"
|
|
50
|
+
],
|
|
51
|
+
"installDependencies": false,
|
|
52
|
+
"install": {
|
|
53
|
+
"localPath": ".",
|
|
54
|
+
"defaultChoice": "local"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|