openclaw-cortex-memory 0.1.0-Alpha.8 → 0.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.
Files changed (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +347 -299
  3. package/SIGNATURE.md +7 -0
  4. package/SKILL.md +96 -350
  5. package/dist/index.d.ts +93 -23
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1234 -1318
  8. package/dist/index.js.map +1 -1
  9. package/dist/openclaw.plugin.json +377 -18
  10. package/dist/src/dedup/three_stage_deduplicator.d.ts.map +1 -1
  11. package/dist/src/dedup/three_stage_deduplicator.js +13 -3
  12. package/dist/src/dedup/three_stage_deduplicator.js.map +1 -1
  13. package/dist/src/engine/memory_engine.d.ts +6 -1
  14. package/dist/src/engine/memory_engine.d.ts.map +1 -1
  15. package/dist/src/engine/ts_engine.d.ts +208 -0
  16. package/dist/src/engine/ts_engine.d.ts.map +1 -1
  17. package/dist/src/engine/ts_engine.js +1353 -84
  18. package/dist/src/engine/ts_engine.js.map +1 -1
  19. package/dist/src/engine/types.d.ts +27 -0
  20. package/dist/src/engine/types.d.ts.map +1 -1
  21. package/dist/src/graph/ontology.d.ts +87 -15
  22. package/dist/src/graph/ontology.d.ts.map +1 -1
  23. package/dist/src/graph/ontology.js +999 -12
  24. package/dist/src/graph/ontology.js.map +1 -1
  25. package/dist/src/net/http_post.d.ts +17 -0
  26. package/dist/src/net/http_post.d.ts.map +1 -0
  27. package/dist/src/net/http_post.js +56 -0
  28. package/dist/src/net/http_post.js.map +1 -0
  29. package/dist/src/quality/llm_output_validator.d.ts +65 -0
  30. package/dist/src/quality/llm_output_validator.d.ts.map +1 -0
  31. package/dist/src/quality/llm_output_validator.js +635 -0
  32. package/dist/src/quality/llm_output_validator.js.map +1 -0
  33. package/dist/src/reflect/reflector.d.ts.map +1 -1
  34. package/dist/src/reflect/reflector.js +296 -26
  35. package/dist/src/reflect/reflector.js.map +1 -1
  36. package/dist/src/rules/rule_store.d.ts.map +1 -1
  37. package/dist/src/rules/rule_store.js +75 -16
  38. package/dist/src/rules/rule_store.js.map +1 -1
  39. package/dist/src/session/session_end.d.ts +20 -42
  40. package/dist/src/session/session_end.d.ts.map +1 -1
  41. package/dist/src/session/session_end.js +31 -214
  42. package/dist/src/session/session_end.js.map +1 -1
  43. package/dist/src/store/archive_store.d.ts +52 -7
  44. package/dist/src/store/archive_store.d.ts.map +1 -1
  45. package/dist/src/store/archive_store.js +526 -96
  46. package/dist/src/store/archive_store.js.map +1 -1
  47. package/dist/src/store/embedding_utils.d.ts +32 -0
  48. package/dist/src/store/embedding_utils.d.ts.map +1 -0
  49. package/dist/src/store/embedding_utils.js +173 -0
  50. package/dist/src/store/embedding_utils.js.map +1 -0
  51. package/dist/src/store/graph_memory_store.d.ts +115 -0
  52. package/dist/src/store/graph_memory_store.d.ts.map +1 -0
  53. package/dist/src/store/graph_memory_store.js +1061 -0
  54. package/dist/src/store/graph_memory_store.js.map +1 -0
  55. package/dist/src/store/read_store.d.ts +95 -0
  56. package/dist/src/store/read_store.d.ts.map +1 -1
  57. package/dist/src/store/read_store.js +2108 -268
  58. package/dist/src/store/read_store.js.map +1 -1
  59. package/dist/src/store/vector_store.d.ts +15 -0
  60. package/dist/src/store/vector_store.d.ts.map +1 -1
  61. package/dist/src/store/vector_store.js +75 -1
  62. package/dist/src/store/vector_store.js.map +1 -1
  63. package/dist/src/store/write_store.d.ts +46 -0
  64. package/dist/src/store/write_store.d.ts.map +1 -1
  65. package/dist/src/store/write_store.js +399 -50
  66. package/dist/src/store/write_store.js.map +1 -1
  67. package/dist/src/sync/session_sync.d.ts +115 -2
  68. package/dist/src/sync/session_sync.d.ts.map +1 -1
  69. package/dist/src/sync/session_sync.js +2497 -44
  70. package/dist/src/sync/session_sync.js.map +1 -1
  71. package/dist/src/utils/runtime_env.d.ts +4 -0
  72. package/dist/src/utils/runtime_env.d.ts.map +1 -0
  73. package/dist/src/utils/runtime_env.js +51 -0
  74. package/dist/src/utils/runtime_env.js.map +1 -0
  75. package/dist/src/wiki/wiki_linter.d.ts +26 -0
  76. package/dist/src/wiki/wiki_linter.d.ts.map +1 -0
  77. package/dist/src/wiki/wiki_linter.js +339 -0
  78. package/dist/src/wiki/wiki_linter.js.map +1 -0
  79. package/dist/src/wiki/wiki_logger.d.ts +10 -0
  80. package/dist/src/wiki/wiki_logger.d.ts.map +1 -0
  81. package/dist/src/wiki/wiki_logger.js +78 -0
  82. package/dist/src/wiki/wiki_logger.js.map +1 -0
  83. package/dist/src/wiki/wiki_maintainer.d.ts +39 -0
  84. package/dist/src/wiki/wiki_maintainer.d.ts.map +1 -0
  85. package/dist/src/wiki/wiki_maintainer.js +38 -0
  86. package/dist/src/wiki/wiki_maintainer.js.map +1 -0
  87. package/dist/src/wiki/wiki_projector.d.ts +35 -0
  88. package/dist/src/wiki/wiki_projector.d.ts.map +1 -0
  89. package/dist/src/wiki/wiki_projector.js +1151 -0
  90. package/dist/src/wiki/wiki_projector.js.map +1 -0
  91. package/dist/src/wiki/wiki_queue.d.ts +29 -0
  92. package/dist/src/wiki/wiki_queue.d.ts.map +1 -0
  93. package/dist/src/wiki/wiki_queue.js +137 -0
  94. package/dist/src/wiki/wiki_queue.js.map +1 -0
  95. package/openclaw.plugin.json +377 -18
  96. package/package.json +52 -5
  97. package/schema/graph.schema.yaml +330 -0
  98. package/scripts/cli.js +80 -26
  99. package/scripts/repair-memory.js +321 -0
  100. package/scripts/uninstall.js +7 -1
  101. package/skills/cortex-memory/SKILL.md +83 -0
  102. package/skills/cortex-memory/references/agent-manual.md +127 -0
  103. package/skills/cortex-memory/references/configuration.md +109 -0
  104. package/skills/cortex-memory/references/publish-checklist.md +45 -0
  105. package/skills/cortex-memory/references/system-prompt-template.md +27 -0
  106. package/skills/cortex-memory/references/tools.md +191 -0
@@ -0,0 +1,321 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const args = process.argv.slice(2);
7
+ const isDryRun = args.includes('--dry-run');
8
+ const isFix = args.includes('--fix');
9
+ const targetArg = args.find(a => a.startsWith('--target='));
10
+ const target = targetArg ? targetArg.split('=')[1] : 'all';
11
+
12
+ const PROJECT_ROOT = process.cwd();
13
+ const MEMORY_ROOT = path.join(PROJECT_ROOT, 'data', 'memory');
14
+
15
+ const VALID_TARGETS = ['all', 'archive', 'active', 'vector'];
16
+
17
+ function printUsage() {
18
+ console.log(`
19
+ Memory Data Repair Tool
20
+
21
+ Usage: node scripts/repair-memory.js [options]
22
+
23
+ Options:
24
+ --dry-run Scan and report issues without making changes
25
+ --fix Remove invalid records and create quarantine file
26
+ --target=<target> Specify target: all, archive, active, vector (default: all)
27
+
28
+ Examples:
29
+ node scripts/repair-memory.js --dry-run
30
+ node scripts/repair-memory.js --fix --target=archive
31
+ `);
32
+ }
33
+
34
+ if (!VALID_TARGETS.includes(target)) {
35
+ console.error(`Invalid target: ${target}. Valid targets: ${VALID_TARGETS.join(', ')}`);
36
+ printUsage();
37
+ process.exit(1);
38
+ }
39
+
40
+ if (!isDryRun && !isFix) {
41
+ printUsage();
42
+ process.exit(0);
43
+ }
44
+
45
+ function validateJsonlLine(line, lineNumber) {
46
+ const errors = [];
47
+ if (!line || !line.trim()) {
48
+ return { valid: true, errors: [], record: null };
49
+ }
50
+ let record;
51
+ try {
52
+ record = JSON.parse(line);
53
+ } catch (e) {
54
+ errors.push(`JSON parse error: ${e.message}`);
55
+ return { valid: false, errors, record: null };
56
+ }
57
+ if (!record || typeof record !== 'object') {
58
+ errors.push('Record is not an object');
59
+ return { valid: false, errors, record: null };
60
+ }
61
+ if (typeof record.id !== 'string' || !record.id.trim()) {
62
+ errors.push('Missing or invalid id field');
63
+ }
64
+ if (typeof record.timestamp !== 'string' || !record.timestamp.trim()) {
65
+ errors.push('Missing or invalid timestamp field');
66
+ }
67
+ if (record.layer !== 'active' && record.layer !== 'archive') {
68
+ errors.push('Missing or invalid layer field');
69
+ }
70
+ const anomalyPatterns = [
71
+ /\d+\.\d+,\s*"[^"]+"/,
72
+ /"[^"]+"\s+\d+\.\d+/,
73
+ /,\s*\d+\.\d+,/,
74
+ /"\w+\.\w+\.\w+"/,
75
+ /\d+\.\w+\.\d+/,
76
+ ];
77
+ const lineStr = JSON.stringify(record);
78
+ for (const pattern of anomalyPatterns) {
79
+ if (pattern.test(lineStr)) {
80
+ errors.push('Anomaly pattern detected in record');
81
+ break;
82
+ }
83
+ }
84
+ return { valid: errors.length === 0, errors, record };
85
+ }
86
+
87
+ function scanJsonlFile(filePath) {
88
+ const results = {
89
+ path: filePath,
90
+ exists: false,
91
+ totalLines: 0,
92
+ validLines: 0,
93
+ invalidLines: 0,
94
+ emptyLines: 0,
95
+ issues: [],
96
+ };
97
+ if (!fs.existsSync(filePath)) {
98
+ return results;
99
+ }
100
+ results.exists = true;
101
+ const content = fs.readFileSync(filePath, 'utf-8');
102
+ const lines = content.split(/\r?\n/);
103
+ for (let i = 0; i < lines.length; i++) {
104
+ const line = lines[i];
105
+ if (!line.trim()) {
106
+ results.emptyLines++;
107
+ continue;
108
+ }
109
+ results.totalLines++;
110
+ const validation = validateJsonlLine(line, i + 1);
111
+ if (validation.valid) {
112
+ results.validLines++;
113
+ } else {
114
+ results.invalidLines++;
115
+ results.issues.push({
116
+ lineNumber: i + 1,
117
+ errors: validation.errors,
118
+ preview: line.slice(0, 100) + (line.length > 100 ? '...' : ''),
119
+ });
120
+ }
121
+ }
122
+ return results;
123
+ }
124
+
125
+ function repairJsonlFile(filePath, dryRun) {
126
+ const results = {
127
+ path: filePath,
128
+ exists: false,
129
+ totalLines: 0,
130
+ validLines: 0,
131
+ removedLines: 0,
132
+ quarantineLines: [],
133
+ };
134
+ if (!fs.existsSync(filePath)) {
135
+ return results;
136
+ }
137
+ results.exists = true;
138
+ const content = fs.readFileSync(filePath, 'utf-8');
139
+ const lines = content.split(/\r?\n/);
140
+ const validRecords = [];
141
+ for (let i = 0; i < lines.length; i++) {
142
+ const line = lines[i];
143
+ if (!line.trim()) {
144
+ continue;
145
+ }
146
+ results.totalLines++;
147
+ const validation = validateJsonlLine(line, i + 1);
148
+ if (validation.valid) {
149
+ results.validLines++;
150
+ validRecords.push(line);
151
+ } else {
152
+ results.removedLines++;
153
+ results.quarantineLines.push({
154
+ lineNumber: i + 1,
155
+ content: line,
156
+ errors: validation.errors,
157
+ });
158
+ }
159
+ }
160
+ if (!dryRun && results.removedLines > 0) {
161
+ const newContent = validRecords.join('\n') + (validRecords.length > 0 ? '\n' : '');
162
+ fs.writeFileSync(filePath, newContent, 'utf-8');
163
+ const quarantinePath = filePath + '.quarantine.jsonl';
164
+ const quarantineContent = results.quarantineLines.map(q =>
165
+ JSON.stringify({ lineNumber: q.lineNumber, errors: q.errors, content: q.content })
166
+ ).join('\n');
167
+ fs.writeFileSync(quarantinePath, quarantineContent + '\n', 'utf-8');
168
+ }
169
+ return results;
170
+ }
171
+
172
+ function scanVectorFallback(filePath) {
173
+ const results = {
174
+ path: filePath,
175
+ exists: false,
176
+ totalRecords: 0,
177
+ validRecords: 0,
178
+ orphanRecords: 0,
179
+ issues: [],
180
+ };
181
+ if (!fs.existsSync(filePath)) {
182
+ return results;
183
+ }
184
+ results.exists = true;
185
+ const content = fs.readFileSync(filePath, 'utf-8');
186
+ const lines = content.split(/\r?\n/);
187
+ for (let i = 0; i < lines.length; i++) {
188
+ const line = lines[i];
189
+ if (!line.trim()) continue;
190
+ results.totalRecords++;
191
+ try {
192
+ const record = JSON.parse(line);
193
+ if (!record.id || !record.embedding) {
194
+ results.issues.push({
195
+ lineNumber: i + 1,
196
+ error: 'Missing id or embedding',
197
+ });
198
+ } else {
199
+ results.validRecords++;
200
+ }
201
+ } catch (e) {
202
+ results.issues.push({
203
+ lineNumber: i + 1,
204
+ error: `JSON parse error: ${e.message}`,
205
+ });
206
+ }
207
+ }
208
+ return results;
209
+ }
210
+
211
+ console.log('='.repeat(60));
212
+ console.log('Memory Data Repair Tool');
213
+ console.log('='.repeat(60));
214
+ console.log(`Mode: ${isDryRun ? 'DRY RUN (no changes)' : 'FIX (will modify files)'}`);
215
+ console.log(`Target: ${target}`);
216
+ console.log(`Memory Root: ${MEMORY_ROOT}`);
217
+ console.log('='.repeat(60));
218
+
219
+ const archivePath = path.join(MEMORY_ROOT, 'sessions', 'archive', 'archive.jsonl');
220
+ const activePath = path.join(MEMORY_ROOT, 'sessions', 'active', 'sessions.jsonl');
221
+ const vectorFallbackPath = path.join(MEMORY_ROOT, 'vector', 'lancedb_events.jsonl');
222
+
223
+ let totalIssues = 0;
224
+ const report = {
225
+ archive: null,
226
+ active: null,
227
+ vector: null,
228
+ };
229
+
230
+ if (target === 'all' || target === 'archive') {
231
+ console.log('\n[Archive Layer]');
232
+ if (isDryRun) {
233
+ report.archive = scanJsonlFile(archivePath);
234
+ } else {
235
+ report.archive = repairJsonlFile(archivePath, false);
236
+ }
237
+ if (!report.archive.exists) {
238
+ console.log(' File does not exist');
239
+ } else {
240
+ console.log(` Total lines: ${report.archive.totalLines}`);
241
+ console.log(` Valid lines: ${report.archive.validLines}`);
242
+ console.log(` Invalid lines: ${report.archive.invalidLines || report.archive.removedLines}`);
243
+ if (report.archive.issues && report.archive.issues.length > 0) {
244
+ console.log(' Issues found:');
245
+ report.archive.issues.slice(0, 5).forEach(issue => {
246
+ console.log(` Line ${issue.lineNumber}: ${issue.errors.join(', ')}`);
247
+ });
248
+ if (report.archive.issues.length > 5) {
249
+ console.log(` ... and ${report.archive.issues.length - 5} more`);
250
+ }
251
+ }
252
+ totalIssues += report.archive.invalidLines || report.archive.removedLines || 0;
253
+ }
254
+ }
255
+
256
+ if (target === 'all' || target === 'active') {
257
+ console.log('\n[Active Layer]');
258
+ if (isDryRun) {
259
+ report.active = scanJsonlFile(activePath);
260
+ } else {
261
+ report.active = repairJsonlFile(activePath, false);
262
+ }
263
+ if (!report.active.exists) {
264
+ console.log(' File does not exist');
265
+ } else {
266
+ console.log(` Total lines: ${report.active.totalLines}`);
267
+ console.log(` Valid lines: ${report.active.validLines}`);
268
+ console.log(` Invalid lines: ${report.active.invalidLines || report.active.removedLines}`);
269
+ if (report.active.issues && report.active.issues.length > 0) {
270
+ console.log(' Issues found:');
271
+ report.active.issues.slice(0, 5).forEach(issue => {
272
+ console.log(` Line ${issue.lineNumber}: ${issue.errors.join(', ')}`);
273
+ });
274
+ if (report.active.issues.length > 5) {
275
+ console.log(` ... and ${report.active.issues.length - 5} more`);
276
+ }
277
+ }
278
+ totalIssues += report.active.invalidLines || report.active.removedLines || 0;
279
+ }
280
+ }
281
+
282
+ if (target === 'all' || target === 'vector') {
283
+ console.log('\n[Vector Fallback]');
284
+ report.vector = scanVectorFallback(vectorFallbackPath);
285
+ if (!report.vector.exists) {
286
+ console.log(' File does not exist');
287
+ } else {
288
+ console.log(` Total records: ${report.vector.totalRecords}`);
289
+ console.log(` Valid records: ${report.vector.validRecords}`);
290
+ console.log(` Issues: ${report.vector.issues.length}`);
291
+ if (report.vector.issues.length > 0) {
292
+ console.log(' Issues found:');
293
+ report.vector.issues.slice(0, 5).forEach(issue => {
294
+ console.log(` Line ${issue.lineNumber}: ${issue.error}`);
295
+ });
296
+ }
297
+ totalIssues += report.vector.issues.length;
298
+ }
299
+ }
300
+
301
+ console.log('\n' + '='.repeat(60));
302
+ console.log('Summary');
303
+ console.log('='.repeat(60));
304
+ console.log(`Total issues found: ${totalIssues}`);
305
+
306
+ if (isDryRun) {
307
+ if (totalIssues > 0) {
308
+ console.log('\nRun with --fix to repair these issues.');
309
+ } else {
310
+ console.log('\nNo issues found. Memory data is healthy.');
311
+ }
312
+ } else {
313
+ if (totalIssues > 0) {
314
+ console.log('\nRepair completed. Invalid records have been quarantined.');
315
+ console.log('Check .quarantine.jsonl files for removed records.');
316
+ } else {
317
+ console.log('\nNo repairs needed. Memory data is healthy.');
318
+ }
319
+ }
320
+
321
+ process.exit(totalIssues > 0 && isDryRun ? 1 : 0);
@@ -220,4 +220,10 @@ function main() {
220
220
  }
221
221
  }
222
222
 
223
- main();
223
+ module.exports = {
224
+ uninstall,
225
+ };
226
+
227
+ if (require.main === module) {
228
+ main();
229
+ }
@@ -0,0 +1,83 @@
1
+ # Openclaw Cortex Memory
2
+
3
+ OpenClaw 长期记忆插件,专为 OpenClaw AI 助手设计的智能记忆系统。
4
+
5
+ 面向 OpenClaw 的长期记忆插件,集成多路检索、事件归档、图谱关系、向量化与反衰减排序,支持历史增量导入、规则反思和可观测诊断,可以将会话中零碎的记忆去噪整理、分层存储,支持对话中自动搜索回忆,吸收了 LLM wiki 的概念,帮助 Agent 在跨会话中持续积累并稳定调用高价值记忆。
6
+
7
+ ## 核心能力
8
+
9
+ ### 1) 语义检索
10
+ - 多路召回:`keyword / BM25 / vector / graph` 混合检索
11
+ - 排序融合:加权打分 + RRF + 可选 reranker
12
+ - 结果融合:可选 `readFusion`,支持权威融合返回
13
+ - 时序建模:`memoryDecay` + 命中反衰减(anti-decay)
14
+
15
+ ### 2) 事件存储
16
+ - 分层写入:`active`(会话)与 `archive`(结构化事件)
17
+ - 摘要优先:归档记录保留 `summary` 与 `source_text`
18
+ - 向量分块:支持 summary/evidence 双通道向量记录
19
+ - 增量同步:按状态文件增量导入历史会话
20
+
21
+ ### 3) 图谱关系
22
+ - 图谱独立层:`graph/memory.jsonl` 独立于 archive 文本层
23
+ - 关系追溯:每条关系可追溯 `source_event_id`
24
+ - 关系查询:`query_graph` 支持方向、关系类型、路径搜索
25
+ - 冲突治理:单值事实冲突进入队列,支持人工 `accept/reject` 闭环
26
+ - 可视化导出:`export_graph_view` 输出状态化图谱快照(含来源证据)
27
+ - 质量门禁:全局 `graphQualityMode` 支持 `off/warn/strict`;历史导入可用 `syncPolicy.graphQualityMode` 单独收紧
28
+
29
+ ### 4) 规则演进
30
+ - 反思沉淀:`reflect_memory` 将事件抽象为规则
31
+ - 去重治理:规则与事件均有去重控制,避免污染
32
+ - 规则复用:规则写入 `CORTEX_RULES.md` 供后续任务复用
33
+
34
+ ### 5) 运维诊断
35
+ - `cortex_diagnostics`:模型连通、层级状态、字段对齐检查
36
+ - `backfill_embeddings`:支持 `incremental / vector_only / full`
37
+ - `lint_memory_wiki`:Wiki/图谱一致性、证据完整性与知识页质量巡检
38
+ - 完整状态文件:便于快速定位同步、回填、质量问题
39
+
40
+ ---
41
+ name: cortex-memory
42
+ description: Independent skill for Cortex Memory operations in OpenClaw. Use when users ask for cross-session memory continuity, prior decisions, preferences, relationship tracing, or memory maintenance. If the memory plugin is not installed, guide users to install and enable openclaw-cortex-memory first, then continue with normal memory workflows.
43
+ homepage: https://github.com/deki18/openclaw-cortex-memory
44
+ metadata: { "openclaw": { "os": ["darwin", "linux", "win32"], "primaryEnv": "EMBEDDING_API_KEY" } }
45
+ ---
46
+
47
+ Use this runtime flow:
48
+
49
+ 1. Check whether plugin `openclaw-cortex-memory` is available.
50
+ 2. If missing or disabled, run the install bootstrap guide in `{baseDir}/references/agent-manual.md` with README-consistent install order.
51
+ 3. After plugin is enabled, run memory retrieval or write operations.
52
+
53
+ After plugin is ready, use this default workflow:
54
+
55
+ 1. Retrieve candidate memory with `search_memory`.
56
+ 2. If the user asks about entity links or dependency paths, use `query_graph`.
57
+ 3. If `query_graph` returns `conflict_hint`, use `list_graph_conflicts` and ask user confirmation before `resolve_graph_conflict`.
58
+ 4. For graph status snapshots or projection consistency checks, use `export_graph_view` and `lint_memory_wiki`.
59
+ 5. Answer with retrieved evidence first, then add reasoning.
60
+ 6. If the turn introduces durable new information, persist it with `store_event`.
61
+ 7. For maintenance windows or session wrap-up, run `sync_memory` and optionally `reflect_memory`.
62
+
63
+ If tool calls fail:
64
+
65
+ 1. Check plugin availability first (`openclaw plugins list` / `openclaw plugins inspect openclaw-cortex-memory`).
66
+ 2. If visible, run `cortex_diagnostics` (or legacy alias `diagnostics`).
67
+ 3. Tell the user the plugin is unavailable or misconfigured.
68
+ 4. Continue with a normal answer without fabricating memory hits.
69
+
70
+ Do not use this skill for:
71
+
72
+ - Real-time web facts (weather, stock, breaking news).
73
+ - One-off temporary context that should not be persisted.
74
+
75
+ Use these local references when needed:
76
+
77
+ - Install and bootstrap playbook: `{baseDir}/references/agent-manual.md`
78
+ - System prompt template: `{baseDir}/references/system-prompt-template.md`
79
+ - Tool details: `{baseDir}/references/tools.md`
80
+ - Config and dependency setup: `{baseDir}/references/configuration.md`
81
+ - Publish and validation checklist: `{baseDir}/references/publish-checklist.md`
82
+
83
+ For environment preflight, use `{baseDir}/references/publish-checklist.md`.
@@ -0,0 +1,127 @@
1
+ # Cortex Memory Agent Manual
2
+
3
+ ## Goal
4
+
5
+ Use Cortex Memory as a long-term memory layer in OpenClaw. This manual is for agents operating from the independent `cortex-memory` skill folder.
6
+
7
+ ## Phase 1: Plugin Availability Check
8
+
9
+ Run:
10
+
11
+ ```bash
12
+ openclaw plugins list
13
+ openclaw plugins inspect openclaw-cortex-memory
14
+ ```
15
+
16
+ If plugin exists and is enabled, continue to Phase 3.
17
+
18
+ If plugin is missing or disabled, go to Phase 2.
19
+
20
+ ## Phase 2: Install and Enable Plugin
21
+
22
+ Preferred install path (README default):
23
+
24
+ ```bash
25
+ openclaw plugins install clawhub:openclaw-cortex-memory
26
+ openclaw plugins enable openclaw-cortex-memory
27
+ ```
28
+
29
+ Fallback install path:
30
+
31
+ ```bash
32
+ npm pack openclaw-cortex-memory@0.1.0-Alpha.34
33
+ openclaw plugins install ./openclaw-cortex-memory-0.1.0-Alpha.34.tgz
34
+ openclaw plugins enable openclaw-cortex-memory
35
+ rm ./openclaw-cortex-memory-0.1.0-Alpha.34.tgz
36
+ ```
37
+
38
+ Then verify:
39
+
40
+ ```bash
41
+ openclaw plugins list
42
+ openclaw plugins inspect openclaw-cortex-memory
43
+ ```
44
+
45
+ If config is not ready, apply the baseline from `configuration.md`.
46
+
47
+ Exclusive memory mode pre-install check (must be completed before running install commands, including `openclaw plugins install ./openclaw-cortex-memory-0.1.0-Alpha.34.tgz`):
48
+
49
+ - Before install, do not manually set `plugins.slots.memory` to `openclaw-cortex-memory`.
50
+ - Before install, disable `memory-core` and `memory-lancedb` under `plugins.entries` to avoid mixed backends.
51
+ - After install, the installer may set `plugins.slots.memory` to `openclaw-cortex-memory` automatically; this is expected.
52
+
53
+ If the user asks for "system prompt rules", use `{baseDir}/references/system-prompt-template.md`.
54
+
55
+ ## Phase 3: Runtime Workflow
56
+
57
+ ### Retrieval-first answers
58
+
59
+ 1. `search_memory` with the user query.
60
+ 2. `query_graph` when relationship/path reasoning is needed.
61
+ 3. If `query_graph` returns `conflict_hint`, run `list_graph_conflicts` and confirm with user before `resolve_graph_conflict`.
62
+ 4. Respond with evidence first, reasoning second.
63
+
64
+ For retrieval debugging, call `search_memory` with `fusion_mode: "candidates"` to keep ranked candidates alongside fusion output. For benchmarks or diagnostics, set `track_hits: false` so the read does not update anti-decay hit statistics.
65
+
66
+ Wiki pages are graph projections, not a second memory store. Treat `wiki_ref` / `wiki_refs` from `search_memory` or `query_graph` as display links; use graph/evidence ids as the fact source.
67
+
68
+ ### Persistence
69
+
70
+ Use `store_event` only for durable information:
71
+
72
+ - stable preferences
73
+ - project decisions
74
+ - long-lived constraints
75
+
76
+ Avoid persisting ephemeral chatter.
77
+
78
+ ### Maintenance
79
+
80
+ - `sync_memory` for historical import
81
+ - `reflect_memory` for rule extraction
82
+ - `backfill_embeddings` for vector repair
83
+ - `export_graph_view` for status-aware graph snapshots
84
+ - `lint_memory_wiki` for projection consistency checks
85
+ - `cortex_diagnostics` (or `diagnostics` alias) when anything looks inconsistent
86
+
87
+ ## Failure Handling
88
+
89
+ If plugin tools are unavailable:
90
+
91
+ 1. Run `openclaw plugins inspect openclaw-cortex-memory` and `openclaw plugins list`.
92
+ 2. If `cortex_diagnostics` is visible, run it for detailed checks.
93
+ 3. Explain the issue clearly (plugin disabled, config incomplete, endpoint unavailable, or API key missing).
94
+ 4. Provide immediate next action with exact command.
95
+
96
+ If install or enable flow reports `memory-core` / `memory-lancedb` requirements, keep both disabled in `plugins.entries`.
97
+ If the host still requests a `memory-lancedb` schema block, add:
98
+
99
+ ```json
100
+ "memory-lancedb": {
101
+ "enabled": false,
102
+ "config": {
103
+ "embedding": {
104
+ "apiKey": "${MEMORY_LANCEDB_API_KEY}",
105
+ "model": "text-embedding-3-small"
106
+ },
107
+ "dbPath": "~/.openclaw/memory/lancedb",
108
+ "autoRecall": true,
109
+ "autoCapture": false,
110
+ "captureMaxChars": 500
111
+ }
112
+ }
113
+ ```
114
+
115
+ ## Operator Commands Cheat Sheet
116
+
117
+ ```bash
118
+ openclaw plugins install clawhub:openclaw-cortex-memory
119
+ openclaw plugins enable openclaw-cortex-memory
120
+ openclaw plugins inspect openclaw-cortex-memory
121
+ npm pack openclaw-cortex-memory@0.1.0-Alpha.34
122
+ openclaw plugins install ./openclaw-cortex-memory-0.1.0-Alpha.34.tgz
123
+ openclaw plugins enable openclaw-cortex-memory
124
+ rm ./openclaw-cortex-memory-0.1.0-Alpha.34.tgz
125
+ openclaw skills info cortex-memory
126
+ openclaw skills check
127
+ ```
@@ -0,0 +1,109 @@
1
+ # Configuration Reference
2
+
3
+ ## Minimum OpenClaw Config
4
+
5
+ Use this as the baseline in `openclaw.json`.
6
+
7
+ ```json
8
+ {
9
+ "plugins": {
10
+ "allow": ["openclaw-cortex-memory"],
11
+ "slots": {
12
+ "memory": "none"
13
+ },
14
+ "entries": {
15
+ "memory-core": {
16
+ "enabled": false
17
+ },
18
+ "memory-lancedb": {
19
+ "enabled": false
20
+ },
21
+ "openclaw-cortex-memory": {
22
+ "enabled": true,
23
+ "config": {
24
+ "autoSync": true,
25
+ "autoReflect": false,
26
+ "graphQualityMode": "warn",
27
+ "syncPolicy": {
28
+ "includeLocalActiveInput": false,
29
+ "graphQualityMode": "strict"
30
+ },
31
+ "wikiProjection": {
32
+ "enabled": true,
33
+ "mode": "incremental",
34
+ "maxBatch": 100
35
+ },
36
+ "embedding": {
37
+ "provider": "api",
38
+ "model": "text-embedding-3-small",
39
+ "apiKey": "${EMBEDDING_API_KEY}",
40
+ "baseURL": "https://your-embedding-endpoint/v1",
41
+ "dimensions": 1536
42
+ },
43
+ "llm": {
44
+ "provider": "api",
45
+ "model": "gpt-4",
46
+ "apiKey": "${LLM_API_KEY}",
47
+ "baseURL": "https://your-llm-endpoint/v1"
48
+ },
49
+ "reranker": {
50
+ "provider": "api",
51
+ "model": "BAAI/bge-reranker-v2-m3",
52
+ "apiKey": "${RERANKER_API_KEY}",
53
+ "baseURL": "https://your-reranker-endpoint/v1/rerank"
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ ```
61
+
62
+ ## Exclusive Mode Rules
63
+
64
+ - Do not set `plugins.slots.memory` to `openclaw-cortex-memory`.
65
+ - Keep `plugins.entries.memory-core.enabled = false`.
66
+ - Keep `plugins.entries.memory-lancedb.enabled = false`.
67
+
68
+ ## Required Environment Variables
69
+
70
+ - `EMBEDDING_API_KEY`
71
+ - `LLM_API_KEY`
72
+ - `RERANKER_API_KEY`
73
+
74
+ ## Required Endpoints
75
+
76
+ - Embedding: OpenAI-compatible `/embeddings`
77
+ - LLM: OpenAI-compatible `/chat/completions`
78
+ - Reranker: `/rerank`
79
+
80
+ ## Troubleshooting: memory backend requirement
81
+
82
+ If `openclaw plugins install/enable` reports `memory-core` or `memory-lancedb` requirement errors, keep both disabled under `plugins.entries`.
83
+ If your host still requires a `memory-lancedb` shape check even when disabled, use:
84
+
85
+ ```json
86
+ "memory-lancedb": {
87
+ "enabled": false,
88
+ "config": {
89
+ "embedding": {
90
+ "apiKey": "${MEMORY_LANCEDB_API_KEY}",
91
+ "model": "text-embedding-3-small"
92
+ },
93
+ "dbPath": "~/.openclaw/memory/lancedb",
94
+ "autoRecall": true,
95
+ "autoCapture": false,
96
+ "captureMaxChars": 500
97
+ }
98
+ }
99
+ ```
100
+
101
+ ## Recommended Validation Commands
102
+
103
+ ```bash
104
+ openclaw plugins list
105
+ openclaw plugins inspect openclaw-cortex-memory
106
+ openclaw skills list
107
+ openclaw skills info cortex-memory
108
+ openclaw skills check
109
+ ```
@@ -0,0 +1,45 @@
1
+ # ClawHub Publish Checklist
2
+
3
+ ## Preflight
4
+
5
+ 1. Confirm skill root contains `SKILL.md`.
6
+ 2. Confirm frontmatter includes:
7
+ - `name`
8
+ - `description`
9
+ 3. Confirm no secret values are hardcoded in skill files.
10
+
11
+ ## Local Validation
12
+
13
+ ```bash
14
+ openclaw skills list
15
+ openclaw skills info cortex-memory
16
+ openclaw skills check
17
+ ```
18
+
19
+ Optional plugin validation:
20
+
21
+ ```bash
22
+ openclaw plugins list
23
+ openclaw plugins inspect openclaw-cortex-memory
24
+ ```
25
+
26
+ ## Publish
27
+
28
+ ```bash
29
+ clawhub login
30
+ clawhub whoami
31
+ clawhub publish ./skills/cortex-memory --slug cortex-memory --name "Cortex Memory" --version 0.1.0 --changelog "Initial ClawHub release" --tags latest
32
+ ```
33
+
34
+ ## Install Test (Clean Workspace)
35
+
36
+ ```bash
37
+ openclaw skills install cortex-memory
38
+ openclaw skills info cortex-memory
39
+ ```
40
+
41
+ ## Post Publish
42
+
43
+ 1. Start a new session.
44
+ 2. Trigger retrieval workflow with a memory-related prompt.
45
+ 3. Verify skill appears and is eligible in `openclaw skills list --eligible`.