@huo15/openclaw-enhance 1.0.0 → 1.1.0
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 +31 -5
- package/index.ts +12 -7
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/modules/dashboard.ts +80 -32
- package/src/modules/prompt-enhancer.ts +10 -10
- package/src/modules/structured-memory.ts +141 -120
- package/src/modules/tool-safety.ts +48 -59
- package/src/modules/workflow-hooks.ts +122 -93
- package/src/types.ts +5 -0
- package/src/utils/sqlite-store.ts +102 -35
package/README.md
CHANGED
|
@@ -2,15 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
> 非侵入式增强你的 OpenClaw Agent — 借鉴 Claude Code 的最佳实践
|
|
4
4
|
|
|
5
|
+
## 多 Agent 隔离 (v1.1.0)
|
|
6
|
+
|
|
7
|
+
完全适配 WeCom 插件的**动态 Agent** 功能。每个企微用户/群组拥有独立的:
|
|
8
|
+
- 记忆空间(不同用户的记忆互不可见)
|
|
9
|
+
- 安全审计日志(按 Agent 独立记录)
|
|
10
|
+
- 工作流集合(每个用户可定义自己的工作流)
|
|
11
|
+
- 仪表盘视图(支持按 Agent 筛选)
|
|
12
|
+
|
|
13
|
+
**实现原理**:
|
|
14
|
+
- 工具使用 `OpenClawPluginToolFactory` 模式,从 `ctx.agentId` 获取当前 Agent
|
|
15
|
+
- 钩子从 `ctx.agentId` 获取当前 Agent
|
|
16
|
+
- SQLite 所有表包含 `agent_id` 列,查询时自动按 Agent 过滤
|
|
17
|
+
- v1.0 数据自动迁移(补充 `agent_id = 'main'`)
|
|
18
|
+
|
|
5
19
|
## 功能模块
|
|
6
20
|
|
|
7
21
|
| 模块 | 说明 | 工具 |
|
|
8
22
|
|------|------|------|
|
|
9
|
-
| **结构化记忆** | 按类型分类存储记忆(user/project/feedback/reference/decision
|
|
10
|
-
| **工具安全** | 可配置的工具调用拦截规则 +
|
|
11
|
-
| **提示词增强** |
|
|
12
|
-
| **工作流自动化** |
|
|
13
|
-
| **仪表盘** | Web UI
|
|
23
|
+
| **结构化记忆** | 按类型分类存储记忆(user/project/feedback/reference/decision),按 Agent 隔离 | `enhance_memory_store` `enhance_memory_search` `enhance_memory_review` |
|
|
24
|
+
| **工具安全** | 可配置的工具调用拦截规则 + 按 Agent 隔离的审计日志 | `enhance_safety_log` `enhance_safety_rules` |
|
|
25
|
+
| **提示词增强** | 自动注入任务分类、质量指引、当前 Agent 的记忆上下文 | 自动(通过 hook) |
|
|
26
|
+
| **工作流自动化** | 触发词驱动的行为指令注入,按 Agent 隔离 | `enhance_workflow_define` `enhance_workflow_list` `enhance_workflow_delete` |
|
|
27
|
+
| **仪表盘** | Web UI 查看记忆/安全/工作流状态,支持按 Agent 筛选 | `http://localhost:18789/enhance/` |
|
|
14
28
|
|
|
15
29
|
## 增强技能
|
|
16
30
|
|
|
@@ -62,10 +76,22 @@ openclaw restart
|
|
|
62
76
|
}
|
|
63
77
|
```
|
|
64
78
|
|
|
79
|
+
## 与 WeCom 动态 Agent 配合
|
|
80
|
+
|
|
81
|
+
当 WeCom 插件启用 `dynamicAgents` 后,每个用户/群组会被分配一个独立的 `agentId`(如 `wecom-acct-ws-dm-hidaomax`)。增强包自动:
|
|
82
|
+
|
|
83
|
+
1. **记忆隔离** — 用户 A 存的记忆,用户 B 看不到
|
|
84
|
+
2. **日志隔离** — 每个用户的安全事件独立记录
|
|
85
|
+
3. **工作流隔离** — 用户 A 定义的工作流不会影响用户 B
|
|
86
|
+
4. **上下文隔离** — 提示词增强只注入当前用户的记忆
|
|
87
|
+
|
|
88
|
+
仪表盘支持 `?agent=wecom-acct-ws-dm-hidaomax` 参数查看特定用户数据。
|
|
89
|
+
|
|
65
90
|
## 设计理念
|
|
66
91
|
|
|
67
92
|
- **非侵入**: 不修改 OpenClaw 核心代码,完全通过插件 API
|
|
68
93
|
- **模块化**: 每个模块可独立开关
|
|
94
|
+
- **隔离优先**: 天然适配多 Agent 架构
|
|
69
95
|
- **借鉴但不照搬**: 取 Claude Code 的精华,适配 OpenClaw 的架构
|
|
70
96
|
|
|
71
97
|
## License
|
package/index.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 龙虾增强包 (OpenClaw Enhancement Kit)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* - 模块1:
|
|
6
|
-
* - 模块2:
|
|
7
|
-
* - 模块3:
|
|
8
|
-
* - 模块4:
|
|
9
|
-
* - 模块5:
|
|
4
|
+
* 非侵入式增强插件(v1.1.0 — 多 Agent 隔离):
|
|
5
|
+
* - 模块1: 结构化记忆系统(按 agentId 隔离,借鉴 Claude Code auto-memory)
|
|
6
|
+
* - 模块2: 工具安全守卫(按 agentId 记录日志,借鉴 Claude Code 权限系统)
|
|
7
|
+
* - 模块3: 提示词增强(按 agentId 注入上下文,借鉴 Claude Code systemPromptSections)
|
|
8
|
+
* - 模块4: 工作流自动化(按 agentId 隔离工作流,借鉴 Claude Code hooks 事件驱动)
|
|
9
|
+
* - 模块5: 增强仪表盘(支持按 Agent 筛选)
|
|
10
|
+
*
|
|
11
|
+
* 完全适配 WeCom 插件的动态 Agent 功能:
|
|
12
|
+
* - 工具使用 OpenClawPluginToolFactory 模式,从 ctx.agentId 获取当前 Agent
|
|
13
|
+
* - 钩子从 ctx.agentId 获取当前 Agent
|
|
14
|
+
* - 每个企微用户/群组的数据完全隔离
|
|
10
15
|
*/
|
|
11
16
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
12
17
|
import { registerStructuredMemory } from "./src/modules/structured-memory.js";
|
|
@@ -64,6 +69,6 @@ export default definePluginEntry({
|
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
71
|
|
|
67
|
-
api.logger.info(`[enhance] 龙虾增强包 v1.
|
|
72
|
+
api.logger.info(`[enhance] 龙虾增强包 v1.1.0 已加载(多 Agent 隔离),启用模块: ${loaded.join("、")}`);
|
|
68
73
|
},
|
|
69
74
|
});
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
package/src/modules/dashboard.ts
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 模块5:
|
|
2
|
+
* 模块5: 增强仪表盘(多 Agent 隔离版)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 支持按 agentId 筛选数据,默认显示全局聚合视图。
|
|
5
|
+
* URL 参数: ?agent=<agentId> 查看特定 Agent 数据
|
|
5
6
|
*/
|
|
6
7
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
7
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getDb,
|
|
10
|
+
getMemoryStats,
|
|
11
|
+
getSafetyStats,
|
|
12
|
+
getRecentMemories,
|
|
13
|
+
getRecentSafetyEvents,
|
|
14
|
+
getAllAgentIds,
|
|
15
|
+
} from "../utils/sqlite-store.js";
|
|
8
16
|
import { existsSync, readFileSync } from "node:fs";
|
|
9
17
|
import { join } from "node:path";
|
|
10
|
-
import type
|
|
18
|
+
import { DEFAULT_AGENT_ID, type DashboardConfig, type Workflow } from "../types.js";
|
|
11
19
|
|
|
12
|
-
function
|
|
20
|
+
function loadAllWorkflows(openclawDir: string): Workflow[] {
|
|
13
21
|
const path = join(openclawDir, "memory", "enhance-workflows.json");
|
|
14
22
|
if (!existsSync(path)) return [];
|
|
15
23
|
try {
|
|
@@ -27,31 +35,44 @@ const DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
27
35
|
<title>龙虾增强包 — 仪表盘</title>
|
|
28
36
|
<style>
|
|
29
37
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
30
|
-
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:#0f1117;color:#e0e0e0;padding:24px;max-width:
|
|
38
|
+
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;background:#0f1117;color:#e0e0e0;padding:24px;max-width:1060px;margin:0 auto}
|
|
31
39
|
h1{font-size:1.8em;margin-bottom:8px;color:#ff6b35}
|
|
32
|
-
.subtitle{color:#888;margin-bottom:
|
|
33
|
-
.
|
|
40
|
+
.subtitle{color:#888;margin-bottom:16px;font-size:0.95em}
|
|
41
|
+
.agent-bar{display:flex;align-items:center;gap:12px;margin-bottom:24px;flex-wrap:wrap}
|
|
42
|
+
.agent-bar label{color:#888;font-size:0.9em}
|
|
43
|
+
.agent-bar select{background:#1a1d27;color:#e0e0e0;border:1px solid #2a2d37;border-radius:6px;padding:6px 12px;font-size:0.9em}
|
|
44
|
+
.agent-bar .current{color:#ff6b35;font-size:0.85em;font-weight:600}
|
|
45
|
+
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px;margin-bottom:32px}
|
|
34
46
|
.card{background:#1a1d27;border-radius:12px;padding:20px;border:1px solid #2a2d37}
|
|
35
|
-
.card h3{font-size:0.
|
|
47
|
+
.card h3{font-size:0.8em;color:#888;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px}
|
|
36
48
|
.card .value{font-size:2em;font-weight:700;color:#ff6b35}
|
|
37
|
-
.card .label{font-size:0.
|
|
49
|
+
.card .label{font-size:0.75em;color:#666;margin-top:4px}
|
|
38
50
|
.section{margin-bottom:32px}
|
|
39
51
|
.section h2{font-size:1.2em;margin-bottom:12px;color:#ccc;border-bottom:1px solid #2a2d37;padding-bottom:8px}
|
|
40
52
|
table{width:100%;border-collapse:collapse}
|
|
41
53
|
th,td{text-align:left;padding:8px 12px;border-bottom:1px solid #1a1d27}
|
|
42
|
-
th{color:#888;font-size:0.
|
|
43
|
-
td{font-size:0.
|
|
54
|
+
th{color:#888;font-size:0.75em;text-transform:uppercase;letter-spacing:1px}
|
|
55
|
+
td{font-size:0.85em}
|
|
44
56
|
.badge{display:inline-block;padding:2px 8px;border-radius:4px;font-size:0.75em;font-weight:600}
|
|
45
57
|
.badge-block{background:#ff4444;color:#fff}
|
|
46
58
|
.badge-log{background:#444;color:#ccc}
|
|
47
59
|
.badge-allow{background:#2a5a2a;color:#8f8}
|
|
60
|
+
.agent-tag{background:#2a2d37;color:#ff6b35;padding:1px 6px;border-radius:3px;font-size:0.75em;margin-left:4px}
|
|
48
61
|
.empty{color:#555;font-style:italic;padding:16px 0}
|
|
49
62
|
footer{text-align:center;color:#444;font-size:0.8em;margin-top:40px}
|
|
50
63
|
</style>
|
|
51
64
|
</head>
|
|
52
65
|
<body>
|
|
53
66
|
<h1>🦞 龙虾增强包</h1>
|
|
54
|
-
<p class="subtitle">OpenClaw Enhancement Kit Dashboard</p>
|
|
67
|
+
<p class="subtitle">OpenClaw Enhancement Kit — Multi-Agent Dashboard</p>
|
|
68
|
+
|
|
69
|
+
<div class="agent-bar">
|
|
70
|
+
<label>Agent:</label>
|
|
71
|
+
<select id="agentSelect" onchange="switchAgent(this.value)">
|
|
72
|
+
<option value="">全部 (聚合)</option>
|
|
73
|
+
</select>
|
|
74
|
+
<span class="current" id="currentAgent"></span>
|
|
75
|
+
</div>
|
|
55
76
|
|
|
56
77
|
<div class="grid" id="stats"></div>
|
|
57
78
|
|
|
@@ -70,16 +91,24 @@ const DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
70
91
|
<div id="workflows"></div>
|
|
71
92
|
</div>
|
|
72
93
|
|
|
73
|
-
<footer>龙虾增强包 v1.
|
|
94
|
+
<footer>龙虾增强包 v1.1.0 — 多 Agent 隔离</footer>
|
|
74
95
|
|
|
75
96
|
<script>
|
|
97
|
+
let currentAgent='';
|
|
98
|
+
function switchAgent(v){currentAgent=v;const u=new URL(location.href);if(v)u.searchParams.set('agent',v);else u.searchParams.delete('agent');history.replaceState(null,'',u);load();}
|
|
76
99
|
async function load(){
|
|
77
100
|
try{
|
|
78
|
-
const
|
|
79
|
-
const d=await r.json();
|
|
101
|
+
const u='/enhance/api/status'+(currentAgent?'?agent='+encodeURIComponent(currentAgent):'');
|
|
102
|
+
const r=await fetch(u);const d=await r.json();
|
|
103
|
+
// Populate agent selector
|
|
104
|
+
const sel=document.getElementById('agentSelect');
|
|
105
|
+
const prev=sel.value;
|
|
106
|
+
sel.innerHTML='<option value="">全部 (聚合)</option>'+d.agents.map(a=>'<option value="'+esc(a)+'"'+(a===currentAgent?' selected':'')+'>'+esc(a)+'</option>').join('');
|
|
107
|
+
document.getElementById('currentAgent').textContent=currentAgent?'当前: '+currentAgent:'全部 Agent 聚合视图';
|
|
80
108
|
// Stats cards
|
|
81
109
|
const s=document.getElementById('stats');
|
|
82
110
|
s.innerHTML=[
|
|
111
|
+
card('Agent 数',d.agents.length,'个'),
|
|
83
112
|
card('记忆总数',d.memory.total,'条'),
|
|
84
113
|
card('用户记忆',d.memory.user||0,'条'),
|
|
85
114
|
card('项目记忆',d.memory.project||0,'条'),
|
|
@@ -90,25 +119,27 @@ async function load(){
|
|
|
90
119
|
// Memories table
|
|
91
120
|
const m=document.getElementById('memories');
|
|
92
121
|
if(d.recentMemories.length===0){m.innerHTML='<p class="empty">暂无记忆</p>';} else {
|
|
93
|
-
m.innerHTML='<table><tr><th>ID</th><th>类型</th><th
|
|
94
|
-
d.recentMemories.map(e=>'<tr><td>#'+e.id+'</td><td>'+e.category+'</td><td>'+esc(e.content).slice(0,
|
|
122
|
+
m.innerHTML='<table><tr><th>ID</th><th>Agent</th><th>类型</th><th>���容</th><th>时间</th></tr>'+
|
|
123
|
+
d.recentMemories.map(e=>'<tr><td>#'+e.id+'</td><td><span class="agent-tag">'+esc(e.agent_id)+'</span></td><td>'+e.category+'</td><td>'+esc(e.content).slice(0,50)+'</td><td>'+e.created_at+'</td></tr>').join('')+'</table>';
|
|
95
124
|
}
|
|
96
125
|
// Safety table
|
|
97
126
|
const sf=document.getElementById('safety');
|
|
98
127
|
if(d.recentSafety.length===0){sf.innerHTML='<p class="empty">暂无安全事件</p>';} else {
|
|
99
|
-
sf.innerHTML='<table><tr><th>动作</th><th>工具</th><th>参数</th><th>时间</th></tr>'+
|
|
100
|
-
d.recentSafety.map(e=>'<tr><td><span class="badge badge-'+e.action+'">'+e.action+'</span></td><td>'+e.tool+'</td><td>'+esc(e.params||'').slice(0,
|
|
128
|
+
sf.innerHTML='<table><tr><th>动作</th><th>Agent</th><th>工具</th><th>参数</th><th>时间</th></tr>'+
|
|
129
|
+
d.recentSafety.map(e=>'<tr><td><span class="badge badge-'+e.action+'">'+e.action+'</span></td><td><span class="agent-tag">'+esc(e.agent_id)+'</span></td><td>'+e.tool+'</td><td>'+esc(e.params||'').slice(0,35)+'</td><td>'+e.created_at+'</td></tr>').join('')+'</table>';
|
|
101
130
|
}
|
|
102
131
|
// Workflows
|
|
103
132
|
const w=document.getElementById('workflows');
|
|
104
133
|
if(d.workflows.length===0){w.innerHTML='<p class="empty">暂无工作流</p>';} else {
|
|
105
|
-
w.innerHTML='<table><tr><th>名称</th><th>触发词</th><th>状态</th></tr>'+
|
|
106
|
-
d.workflows.map(e=>'<tr><td>'+esc(e.name)+'</td><td>'+esc(e.trigger)+'</td><td>'+(e.enabled?'✅':'⏸️')+'</td></tr>').join('')+'</table>';
|
|
134
|
+
w.innerHTML='<table><tr><th>名称</th><th>Agent</th><th>触发词</th><th>状态</th></tr>'+
|
|
135
|
+
d.workflows.map(e=>'<tr><td>'+esc(e.name)+'</td><td><span class="agent-tag">'+esc(e.agent_id||'main')+'</span></td><td>'+esc(e.trigger)+'</td><td>'+(e.enabled?'✅':'⏸️')+'</td></tr>').join('')+'</table>';
|
|
107
136
|
}
|
|
108
137
|
}catch(e){document.body.innerHTML+='<p style="color:red">加载失败: '+e.message+'</p>';}
|
|
109
138
|
}
|
|
110
139
|
function card(t,v,l){return '<div class="card"><h3>'+t+'</h3><div class="value">'+v+'</div><div class="label">'+l+'</div></div>';}
|
|
111
|
-
function esc(s){return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');}
|
|
140
|
+
function esc(s){return String(s||'').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');}
|
|
141
|
+
// Init from URL
|
|
142
|
+
const p=new URLSearchParams(location.search);currentAgent=p.get('agent')||'';
|
|
112
143
|
load();
|
|
113
144
|
</script>
|
|
114
145
|
</body>
|
|
@@ -117,7 +148,6 @@ load();
|
|
|
117
148
|
export function registerDashboard(api: OpenClawPluginApi, _config?: DashboardConfig) {
|
|
118
149
|
const openclawDir = api.runtime.paths?.home ?? process.env.HOME + "/.openclaw";
|
|
119
150
|
|
|
120
|
-
// ── HTML 页面 ──
|
|
121
151
|
api.registerHttpRoute({
|
|
122
152
|
path: "/enhance",
|
|
123
153
|
match: "prefix",
|
|
@@ -126,17 +156,36 @@ export function registerDashboard(api: OpenClawPluginApi, _config?: DashboardCon
|
|
|
126
156
|
const url = new URL(req.url, "http://localhost");
|
|
127
157
|
const pathname = url.pathname;
|
|
128
158
|
|
|
129
|
-
// API: 状态数据
|
|
130
159
|
if (pathname === "/enhance/api/status") {
|
|
131
160
|
const db = getDb(openclawDir);
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
const
|
|
136
|
-
const
|
|
161
|
+
const agentFilter = url.searchParams.get("agent") || undefined;
|
|
162
|
+
|
|
163
|
+
const agents = getAllAgentIds(db);
|
|
164
|
+
const memoryStats = getMemoryStats(db, agentFilter);
|
|
165
|
+
const safetyStats = getSafetyStats(db, agentFilter);
|
|
166
|
+
|
|
167
|
+
// 记忆和安全事件:如果指定了 agent 则按 agent 过滤
|
|
168
|
+
const recentMemories = agentFilter
|
|
169
|
+
? getRecentMemories(db, agentFilter, 15)
|
|
170
|
+
: (() => {
|
|
171
|
+
// 聚合模式:取各 agent 最近的记忆
|
|
172
|
+
const all: any[] = [];
|
|
173
|
+
for (const aid of agents) {
|
|
174
|
+
all.push(...getRecentMemories(db, aid, 5));
|
|
175
|
+
}
|
|
176
|
+
return all.sort((a, b) => b.created_at.localeCompare(a.created_at)).slice(0, 15);
|
|
177
|
+
})();
|
|
178
|
+
|
|
179
|
+
const recentSafety = getRecentSafetyEvents(db, agentFilter, 15);
|
|
180
|
+
|
|
181
|
+
const allWorkflows = loadAllWorkflows(openclawDir);
|
|
182
|
+
const workflows = agentFilter
|
|
183
|
+
? allWorkflows.filter((w) => w.agent_id === agentFilter)
|
|
184
|
+
: allWorkflows;
|
|
137
185
|
|
|
138
186
|
return new Response(
|
|
139
187
|
JSON.stringify({
|
|
188
|
+
agents,
|
|
140
189
|
memory: memoryStats,
|
|
141
190
|
safety: safetyStats,
|
|
142
191
|
recentMemories,
|
|
@@ -147,12 +196,11 @@ export function registerDashboard(api: OpenClawPluginApi, _config?: DashboardCon
|
|
|
147
196
|
);
|
|
148
197
|
}
|
|
149
198
|
|
|
150
|
-
// 默认: 仪表盘 HTML
|
|
151
199
|
return new Response(DASHBOARD_HTML, {
|
|
152
200
|
headers: { "Content-Type": "text/html; charset=utf-8" },
|
|
153
201
|
});
|
|
154
202
|
},
|
|
155
203
|
});
|
|
156
204
|
|
|
157
|
-
api.logger.info("[enhance]
|
|
205
|
+
api.logger.info("[enhance] 仪表盘模块已加载(多 Agent 视图),访问 /enhance/");
|
|
158
206
|
}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 模块3:
|
|
2
|
+
* 模块3: 提示词增强(多 Agent 隔离版)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* - systemPromptSections 模式
|
|
6
|
-
* - 任务分类
|
|
7
|
-
* - 响应质量指引
|
|
8
|
-
* - 记忆上下文注入
|
|
4
|
+
* 钩子从 ctx.agentId 获取当前 Agent,注入该 Agent 专属的记忆上下文。
|
|
9
5
|
*/
|
|
10
6
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
11
|
-
import type
|
|
7
|
+
import { DEFAULT_AGENT_ID, type PromptConfig, type PromptSection } from "../types.js";
|
|
12
8
|
|
|
13
9
|
const SECTIONS: Record<PromptSection, string> = {
|
|
14
10
|
taskClassification: [
|
|
@@ -28,7 +24,7 @@ const SECTIONS: Record<PromptSection, string> = {
|
|
|
28
24
|
"- 不要添加请求之外的功能、注释或类型标注",
|
|
29
25
|
"- 不要为不可能发生的场景做错误处理",
|
|
30
26
|
"- 三行相似代码好过一个过早的抽象",
|
|
31
|
-
"-
|
|
27
|
+
"- 失败时先诊断���因,不要盲目重试",
|
|
32
28
|
"- 做破坏性操作前先确认(删除、force push、覆盖未保存的修改)",
|
|
33
29
|
].join("\n"),
|
|
34
30
|
|
|
@@ -46,7 +42,8 @@ const SECTIONS: Record<PromptSection, string> = {
|
|
|
46
42
|
export function registerPromptEnhancer(api: OpenClawPluginApi, config?: PromptConfig) {
|
|
47
43
|
const enabledSections: PromptSection[] = config?.sections ?? ["qualityGuidelines", "memoryContext"];
|
|
48
44
|
|
|
49
|
-
api.on("before_prompt_build", () => {
|
|
45
|
+
api.on("before_prompt_build", (_event, ctx) => {
|
|
46
|
+
const agentId = ctx?.agentId?.trim() || DEFAULT_AGENT_ID;
|
|
50
47
|
const parts: string[] = [];
|
|
51
48
|
|
|
52
49
|
for (const section of enabledSections) {
|
|
@@ -57,7 +54,10 @@ export function registerPromptEnhancer(api: OpenClawPluginApi, config?: PromptCo
|
|
|
57
54
|
if (parts.length === 0) return {};
|
|
58
55
|
|
|
59
56
|
return {
|
|
60
|
-
appendSystemContext:
|
|
57
|
+
appendSystemContext: [
|
|
58
|
+
`\n\n<!-- enhance-prompt agent:${agentId} -->`,
|
|
59
|
+
...parts,
|
|
60
|
+
].join("\n\n"),
|
|
61
61
|
};
|
|
62
62
|
});
|
|
63
63
|
|