@nowledge/openclaw-nowledge-mem 0.8.16 → 0.8.19
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/CHANGELOG.md +25 -0
- package/CLAUDE.md +2 -2
- package/README.md +10 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -2
- package/src/context-engine-ids.js +15 -0
- package/src/context-engine.js +16 -4
- package/src/hooks/recall.js +5 -2
- package/src/index.js +45 -21
- package/src/tools/status.js +97 -29
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,31 @@ All notable changes to the Nowledge Mem OpenClaw plugin will be documented in th
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## [0.8.19] - 2026-04-21
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `corpusSupplement` fallback now preserves the user's configured intent when host registration is unavailable. The plugin keeps its own recall path active instead of silently mutating config state.
|
|
12
|
+
- `nowledge_mem_status` now reports `corpusSupplement` as configured vs runtime-active, including fallback reason details when OpenClaw does not expose supplement registration in the current runtime.
|
|
13
|
+
- Context Engine recall now follows **runtime supplement activation** instead of static config. If `corpusSupplement` is configured but host registration fails, prompt-time recall no longer gets skipped.
|
|
14
|
+
- `nowledge_mem_status` no longer claims prompt-time fallback recall when `sessionContext=false`; status text now reflects the real runtime path.
|
|
15
|
+
|
|
16
|
+
## [0.8.18] - 2026-04-20
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- OpenClaw installs no longer break when the installer writes `plugins.slots.contextEngine: "openclaw-nowledge-mem"` instead of the canonical manual id `nowledge-mem`. The plugin now registers a compatibility alias for that slot value, so users do not need to patch local config after install just to activate the Context Engine.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- `nowledge_mem_status` now explains when OpenClaw selected the plugin id as a context-engine compatibility alias, while still treating `nowledge-mem` as the canonical manual config value.
|
|
25
|
+
|
|
26
|
+
## [0.8.17] - 2026-04-16
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- ClawHub installs no longer ship the plugin test suite inside the published code-plugin artifact. The package now uses an explicit `.clawhubignore`, so OpenClaw's security scanner no longer blocks install or update on harmless test-only `child_process` and `process.env + fetch` patterns.
|
|
31
|
+
|
|
7
32
|
## [0.8.16] - 2026-04-15
|
|
8
33
|
|
|
9
34
|
### Fixed
|
package/CLAUDE.md
CHANGED
|
@@ -9,7 +9,7 @@ Continuation guide for `community/nowledge-mem-openclaw-plugin`.
|
|
|
9
9
|
- Memory backend: `nmem` CLI (fallback: `uvx --from nmem-cli nmem`)
|
|
10
10
|
- OpenClaw minimum: `2026.4.5` (`registerMemoryCorpusSupplement` for dreaming integration)
|
|
11
11
|
- Architecture: **CLI-first via OpenClaw runtime** - all CLI execution goes through `api.runtime.system.runCommandWithTimeout`, not direct `child_process`
|
|
12
|
-
- Context engine: registered
|
|
12
|
+
- Context engine: registered under the canonical id `nowledge-mem` plus the compatibility alias `openclaw-nowledge-mem`. Activated when OpenClaw sets either value in `plugins.slots.contextEngine`. Manual config should still prefer `nowledge-mem`. Falls back to hooks when CE is not active.
|
|
13
13
|
- Remote mode: `~/.nowledge-mem/config.json` (shared) or OpenClaw dashboard. Legacy `openclaw.json` still honored.
|
|
14
14
|
- Ambient space lane: prefer plugin config `space` or `spaceTemplate`. Use `NMEM_SPACE` only when OpenClaw is launched in one stable lane and there is no better profile-owned config surface. Legacy `NMEM_SPACE_ID` still works for older setups.
|
|
15
15
|
|
|
@@ -85,7 +85,7 @@ Enable when memory-core is the memory slot and you want cross-tool knowledge to
|
|
|
85
85
|
The plugin is published as a dual-role OpenClaw plugin (`kind: ["memory", "context-engine"]`). These roles remain independent at runtime:
|
|
86
86
|
|
|
87
87
|
- **Memory slot**: provides `memory_search` + `memory_get` and activates OpenClaw's "Memory Recall" system prompt section only when `plugins.slots.memory = "openclaw-nowledge-mem"`. In supplement mode with `memory-core`, these compatibility tools stay off so memory-core keeps owning that surface.
|
|
88
|
-
- **Context engine**: activated when
|
|
88
|
+
- **Context engine**: activated when OpenClaw sets `plugins.slots.contextEngine` to `nowledge-mem` or the compatibility alias `openclaw-nowledge-mem`. Manual config should still use `nowledge-mem`. Replaces hooks with richer CE lifecycle.
|
|
89
89
|
|
|
90
90
|
### CE vs Hooks (dual-path design)
|
|
91
91
|
|
package/README.md
CHANGED
|
@@ -17,7 +17,14 @@ This is not a flat note store. Nowledge Mem links related knowledge into a graph
|
|
|
17
17
|
openclaw plugins install clawhub:@nowledge/openclaw-nowledge-mem
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
OpenClaw's installer writes the install record, enables the plugin, and switches the `memory` slot to `openclaw-nowledge-mem`.
|
|
20
|
+
OpenClaw's installer writes the install record, enables the plugin, and switches the `memory` slot to `openclaw-nowledge-mem`. On current OpenClaw builds, that same install flow may also set `plugins.slots.contextEngine` to `openclaw-nowledge-mem`. Plugin `0.8.18+` accepts that automatically as a compatibility alias, so you do not need to hand-edit the file after install. If you manage config manually, keep using the canonical context engine id `nowledge-mem`.
|
|
21
|
+
|
|
22
|
+
Restart OpenClaw after install to load it.
|
|
23
|
+
|
|
24
|
+
If OpenClaw previously blocked the ClawHub package with a warning about
|
|
25
|
+
`dangerous code patterns detected`, update to `0.8.17+`. That release removes
|
|
26
|
+
test-only files from the published ClawHub artifact, so the installer no longer
|
|
27
|
+
scans harmless development fixtures as if they were runtime plugin code.
|
|
21
28
|
|
|
22
29
|
If you prefer the default resolver path, bare package names also work because OpenClaw resolves external plugins from ClawHub first and then falls back to npm:
|
|
23
30
|
|
|
@@ -560,6 +567,8 @@ If your config enables `plugins.slots.contextEngine: "nowledge-mem"`:
|
|
|
560
567
|
- on `0.8.6+`, Context Engine capture stays active and hooks remain enabled as a safety net
|
|
561
568
|
- on `0.8.5` and earlier, temporarily removing the `contextEngine` slot is a valid isolation step if thread sync stops while tools still work
|
|
562
569
|
|
|
570
|
+
If OpenClaw selected `plugins.slots.contextEngine: "openclaw-nowledge-mem"` during install, plugin `0.8.18+` treats that as the same engine. You only need to rewrite it to `"nowledge-mem"` if you want the config to use the canonical manual id.
|
|
571
|
+
|
|
563
572
|
Remember: OpenClaw applies plugin setting changes after restart. If you turned `sessionDigest` off earlier but had not restarted yet, thread sync could appear to keep working until the next restart, then stop.
|
|
564
573
|
|
|
565
574
|
What healthy OpenClaw thread sync looks like:
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "openclaw-nowledge-mem",
|
|
3
3
|
"name": "Nowledge Mem",
|
|
4
4
|
"description": "Cross-tool knowledge graph memory for OpenClaw with Working Memory, graph search, and session distillation.",
|
|
5
|
-
|
|
5
|
+
"version": "0.8.19",
|
|
6
6
|
"kind": ["memory", "context-engine"],
|
|
7
7
|
"skills": [
|
|
8
8
|
"skills/memory-guide"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nowledge/openclaw-nowledge-mem",
|
|
3
3
|
"displayName": "Nowledge Mem for OpenClaw",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.19",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Nowledge Mem memory plugin for OpenClaw, local-first personal knowledge base",
|
|
7
7
|
"author": {
|
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
"openclaw.plugin.json"
|
|
26
26
|
],
|
|
27
27
|
"openclaw": {
|
|
28
|
-
"extensions": [
|
|
28
|
+
"extensions": [
|
|
29
|
+
"./src/index.js"
|
|
30
|
+
],
|
|
29
31
|
"install": {
|
|
30
32
|
"npmSpec": "@nowledge/openclaw-nowledge-mem"
|
|
31
33
|
},
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const NOWLEDGE_MEM_CONTEXT_ENGINE_ID = "nowledge-mem";
|
|
2
|
+
export const NOWLEDGE_MEM_CONTEXT_ENGINE_COMPAT_ALIAS =
|
|
3
|
+
"openclaw-nowledge-mem";
|
|
4
|
+
|
|
5
|
+
export const NOWLEDGE_MEM_CONTEXT_ENGINE_IDS = [
|
|
6
|
+
NOWLEDGE_MEM_CONTEXT_ENGINE_ID,
|
|
7
|
+
NOWLEDGE_MEM_CONTEXT_ENGINE_COMPAT_ALIAS,
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
export function isNowledgeMemContextEngineSlot(value) {
|
|
11
|
+
return (
|
|
12
|
+
typeof value === "string" &&
|
|
13
|
+
NOWLEDGE_MEM_CONTEXT_ENGINE_IDS.includes(value.trim())
|
|
14
|
+
);
|
|
15
|
+
}
|
package/src/context-engine.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Registers alongside the memory slot (plugin kind includes both "memory" and
|
|
5
5
|
* "context-engine"). When users activate
|
|
6
|
-
* this CE via `plugins.slots.contextEngine: "nowledge-mem"
|
|
6
|
+
* this CE via `plugins.slots.contextEngine: "nowledge-mem"` (or the
|
|
7
|
+
* compatibility alias `openclaw-nowledge-mem` written by current installer
|
|
8
|
+
* builds), it takes over
|
|
7
9
|
* prompt assembly and adds richer lifecycle behavior:
|
|
8
10
|
*
|
|
9
11
|
* assemble() — behavioral guidance + recalled memories via systemPromptAddition
|
|
@@ -164,9 +166,15 @@ function getSessionState(key) {
|
|
|
164
166
|
* @param {import('./client.js').NowledgeMemClient} client
|
|
165
167
|
* @param {object} cfg Parsed plugin config
|
|
166
168
|
* @param {object} logger OpenClaw logger
|
|
169
|
+
* @param {object} runtime Runtime state helpers supplied by register()
|
|
167
170
|
* @returns {() => object} Factory that creates the engine instance
|
|
168
171
|
*/
|
|
169
|
-
export function createNowledgeMemContextEngineFactory(
|
|
172
|
+
export function createNowledgeMemContextEngineFactory(
|
|
173
|
+
client,
|
|
174
|
+
cfg,
|
|
175
|
+
logger,
|
|
176
|
+
runtime = {},
|
|
177
|
+
) {
|
|
170
178
|
return () => {
|
|
171
179
|
ceState.active = true;
|
|
172
180
|
logger.info("nowledge-mem: context engine activated");
|
|
@@ -240,8 +248,12 @@ export function createNowledgeMemContextEngineFactory(client, cfg, logger) {
|
|
|
240
248
|
}
|
|
241
249
|
|
|
242
250
|
// 3. Recalled memories (when sessionContext enabled)
|
|
243
|
-
//
|
|
244
|
-
|
|
251
|
+
// Skip only when corpus supplement is actually active at runtime.
|
|
252
|
+
const corpusSupplementActive =
|
|
253
|
+
typeof runtime.isCorpusSupplementActive === "function"
|
|
254
|
+
? runtime.isCorpusSupplementActive() === true
|
|
255
|
+
: cfg.corpusSupplement === true;
|
|
256
|
+
if (cfg.sessionContext && !corpusSupplementActive) {
|
|
245
257
|
const query = buildAssembleSearchQuery(prompt, messages);
|
|
246
258
|
if (query) {
|
|
247
259
|
try {
|
package/src/hooks/recall.js
CHANGED
|
@@ -177,13 +177,16 @@ export function buildRecalledKnowledgeBlock(
|
|
|
177
177
|
* When the context engine is active, this hook is a no-op —
|
|
178
178
|
* assemble() handles recall via systemPromptAddition.
|
|
179
179
|
*/
|
|
180
|
-
export function buildRecallHandler(client, cfg, logger) {
|
|
180
|
+
export function buildRecallHandler(client, cfg, logger, runtime = {}) {
|
|
181
181
|
const minScore = (cfg.recallMinScore ?? 0) / 100; // config is 0-100, API is 0-1
|
|
182
182
|
|
|
183
183
|
// When corpus supplement is active, memory-core's recall pipeline searches
|
|
184
184
|
// Nowledge Mem via the supplement. We still inject Working Memory (only we
|
|
185
185
|
// know about WM), but skip our own search-based recall to avoid duplicates.
|
|
186
|
-
const skipSearchRecall =
|
|
186
|
+
const skipSearchRecall =
|
|
187
|
+
typeof runtime.skipSearchRecall === "boolean"
|
|
188
|
+
? runtime.skipSearchRecall
|
|
189
|
+
: cfg.corpusSupplement;
|
|
187
190
|
|
|
188
191
|
return async (event) => {
|
|
189
192
|
if (ceState.active) return;
|
package/src/index.js
CHANGED
|
@@ -6,6 +6,10 @@ import {
|
|
|
6
6
|
createRememberCommand,
|
|
7
7
|
} from "./commands/slash.js";
|
|
8
8
|
import { isDefaultApiUrl, parseConfig } from "./config.js";
|
|
9
|
+
import {
|
|
10
|
+
NOWLEDGE_MEM_CONTEXT_ENGINE_ID,
|
|
11
|
+
NOWLEDGE_MEM_CONTEXT_ENGINE_IDS,
|
|
12
|
+
} from "./context-engine-ids.js";
|
|
9
13
|
import { createNowledgeMemContextEngineFactory } from "./context-engine.js";
|
|
10
14
|
import { createNowledgeMemCorpusSupplement } from "./corpus-supplement.js";
|
|
11
15
|
import { buildBehavioralHook } from "./hooks/behavioral.js";
|
|
@@ -76,18 +80,29 @@ export default {
|
|
|
76
80
|
const pluginsAllow = api.config?.plugins?.allow;
|
|
77
81
|
let contextEngineRegistered = false;
|
|
78
82
|
let contextEngineRegistrationError = null;
|
|
83
|
+
let corpusSupplementActive = false;
|
|
84
|
+
let corpusSupplementRegistrationError = null;
|
|
79
85
|
|
|
80
86
|
// --- Context Engine registration ---
|
|
81
|
-
// When the user sets `plugins.slots.contextEngine: "nowledge-mem"
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
//
|
|
87
|
+
// When the user sets `plugins.slots.contextEngine: "nowledge-mem"` —
|
|
88
|
+
// or OpenClaw auto-selects the plugin id compatibility alias
|
|
89
|
+
// `openclaw-nowledge-mem` during install — this CE takes over prompt
|
|
90
|
+
// assembly from the hooks below (assemble replaces behavioral + recall
|
|
91
|
+
// prompt injection). Capture hooks remain enabled as a reliability
|
|
92
|
+
// backstop because thread sync is idempotent. When the CE slot points
|
|
93
|
+
// elsewhere, hooks continue working as before.
|
|
86
94
|
try {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
95
|
+
const contextEngineFactory = createNowledgeMemContextEngineFactory(
|
|
96
|
+
client,
|
|
97
|
+
cfg,
|
|
98
|
+
logger,
|
|
99
|
+
{
|
|
100
|
+
isCorpusSupplementActive: () => corpusSupplementActive,
|
|
101
|
+
},
|
|
90
102
|
);
|
|
103
|
+
for (const contextEngineId of NOWLEDGE_MEM_CONTEXT_ENGINE_IDS) {
|
|
104
|
+
api.registerContextEngine(contextEngineId, contextEngineFactory);
|
|
105
|
+
}
|
|
91
106
|
contextEngineRegistered = true;
|
|
92
107
|
} catch (err) {
|
|
93
108
|
// OpenClaw < CE support — degrade gracefully to hooks-only mode
|
|
@@ -97,16 +112,6 @@ export default {
|
|
|
97
112
|
);
|
|
98
113
|
}
|
|
99
114
|
|
|
100
|
-
api.registerTool(
|
|
101
|
-
createStatusTool(client, logger, cfg, {
|
|
102
|
-
memorySlot,
|
|
103
|
-
contextEngineSlot,
|
|
104
|
-
pluginsAllow,
|
|
105
|
-
contextEngineRegistered,
|
|
106
|
-
contextEngineRegistrationError,
|
|
107
|
-
}),
|
|
108
|
-
);
|
|
109
|
-
|
|
110
115
|
// --- Corpus Supplement (when memory-core is the memory slot) ---
|
|
111
116
|
// Makes Nowledge Mem's knowledge graph searchable through memory-core's
|
|
112
117
|
// recall pipeline and dreaming promotion. Memories participate in
|
|
@@ -116,18 +121,32 @@ export default {
|
|
|
116
121
|
api.registerMemoryCorpusSupplement(
|
|
117
122
|
createNowledgeMemCorpusSupplement(client, cfg, logger),
|
|
118
123
|
);
|
|
124
|
+
corpusSupplementActive = true;
|
|
119
125
|
logger.info(
|
|
120
126
|
"nowledge-mem: registered as MemoryCorpusSupplement for memory-core recall",
|
|
121
127
|
);
|
|
122
128
|
} catch (err) {
|
|
123
129
|
// OpenClaw < corpus supplement support — fall back to normal recall
|
|
124
|
-
|
|
130
|
+
corpusSupplementRegistrationError = String(err);
|
|
125
131
|
logger.info?.(
|
|
126
132
|
`nowledge-mem: corpus supplement unavailable, falling back to normal recall (${err})`,
|
|
127
133
|
);
|
|
128
134
|
}
|
|
129
135
|
}
|
|
130
136
|
|
|
137
|
+
api.registerTool(
|
|
138
|
+
createStatusTool(client, logger, cfg, {
|
|
139
|
+
memorySlot,
|
|
140
|
+
contextEngineSlot,
|
|
141
|
+
contextEngineIds: NOWLEDGE_MEM_CONTEXT_ENGINE_IDS,
|
|
142
|
+
pluginsAllow,
|
|
143
|
+
contextEngineRegistered,
|
|
144
|
+
contextEngineRegistrationError,
|
|
145
|
+
corpusSupplementActive,
|
|
146
|
+
corpusSupplementRegistrationError,
|
|
147
|
+
}),
|
|
148
|
+
);
|
|
149
|
+
|
|
131
150
|
// --- Hooks ---
|
|
132
151
|
// Behavioral + recall hooks defer to the active CE to avoid duplicate
|
|
133
152
|
// prompt injection. Capture hooks remain enabled as a backstop because
|
|
@@ -140,7 +159,12 @@ export default {
|
|
|
140
159
|
|
|
141
160
|
// Session context: inject Working Memory + recalled memories at prompt time.
|
|
142
161
|
if (cfg.sessionContext) {
|
|
143
|
-
api.on(
|
|
162
|
+
api.on(
|
|
163
|
+
"before_prompt_build",
|
|
164
|
+
buildRecallHandler(client, cfg, logger, {
|
|
165
|
+
skipSearchRecall: corpusSupplementActive,
|
|
166
|
+
}),
|
|
167
|
+
);
|
|
144
168
|
}
|
|
145
169
|
|
|
146
170
|
// Session digest: capture threads + LLM distillation at lifecycle events.
|
|
@@ -171,7 +195,7 @@ export default {
|
|
|
171
195
|
|
|
172
196
|
const remoteMode = !isDefaultApiUrl(cfg.apiUrl);
|
|
173
197
|
logger.info(
|
|
174
|
-
`nowledge-mem: initialized (memorySlotSelected=${memorySlotSelected}, context=${cfg.sessionContext}, digest=${cfg.sessionDigest},
|
|
198
|
+
`nowledge-mem: initialized (memorySlotSelected=${memorySlotSelected}, context=${cfg.sessionContext}, digest=${cfg.sessionDigest}, corpusConfigured=${cfg.corpusSupplement}, corpusActive=${corpusSupplementActive}, mode=${remoteMode ? `remote → ${cfg.apiUrl}` : "local"}, contextEngineIds=${NOWLEDGE_MEM_CONTEXT_ENGINE_ID}|${api.id})`,
|
|
175
199
|
);
|
|
176
200
|
},
|
|
177
201
|
};
|
package/src/tools/status.js
CHANGED
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
* Shows where each config value comes from (file, pluginConfig, env, default).
|
|
7
7
|
*/
|
|
8
8
|
import { isDefaultApiUrl } from "../config.js";
|
|
9
|
+
import {
|
|
10
|
+
NOWLEDGE_MEM_CONTEXT_ENGINE_COMPAT_ALIAS,
|
|
11
|
+
NOWLEDGE_MEM_CONTEXT_ENGINE_ID,
|
|
12
|
+
isNowledgeMemContextEngineSlot,
|
|
13
|
+
} from "../context-engine-ids.js";
|
|
9
14
|
|
|
10
15
|
export function createStatusTool(client, _logger, cfg, runtimeInfo = {}) {
|
|
11
16
|
return {
|
|
@@ -62,35 +67,62 @@ export function createStatusTool(client, _logger, cfg, runtimeInfo = {}) {
|
|
|
62
67
|
// 0b. Memory slot check — show current mode and options
|
|
63
68
|
const memorySlot = runtimeInfo.memorySlot;
|
|
64
69
|
const contextEngineSlot = runtimeInfo.contextEngineSlot;
|
|
65
|
-
const contextEngineRegistered =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
const contextEngineRegistered =
|
|
71
|
+
runtimeInfo.contextEngineRegistered === true;
|
|
72
|
+
const contextEngineRegistrationError =
|
|
73
|
+
typeof runtimeInfo.contextEngineRegistrationError === "string" &&
|
|
74
|
+
runtimeInfo.contextEngineRegistrationError.trim()
|
|
75
|
+
? runtimeInfo.contextEngineRegistrationError.trim()
|
|
76
|
+
: null;
|
|
77
|
+
const corpusSupplementConfigured = cfg.corpusSupplement === true;
|
|
78
|
+
const corpusSupplementActive =
|
|
79
|
+
runtimeInfo.corpusSupplementActive === true;
|
|
80
|
+
const corpusSupplementRegistrationError =
|
|
81
|
+
typeof runtimeInfo.corpusSupplementRegistrationError === "string" &&
|
|
82
|
+
runtimeInfo.corpusSupplementRegistrationError.trim()
|
|
83
|
+
? runtimeInfo.corpusSupplementRegistrationError.trim()
|
|
84
|
+
: null;
|
|
85
|
+
details.memorySlot = memorySlot ?? "(unknown)";
|
|
86
|
+
details.corpusSupplementConfigured = corpusSupplementConfigured;
|
|
87
|
+
details.corpusSupplementActive = corpusSupplementActive;
|
|
88
|
+
if (corpusSupplementRegistrationError) {
|
|
89
|
+
details.corpusSupplementRegistrationError =
|
|
90
|
+
corpusSupplementRegistrationError;
|
|
91
|
+
}
|
|
92
|
+
const ceSlot =
|
|
93
|
+
typeof contextEngineSlot === "string" && contextEngineSlot.trim()
|
|
94
|
+
? contextEngineSlot.trim()
|
|
95
|
+
: "legacy";
|
|
96
|
+
details.contextEngineSlot = ceSlot;
|
|
97
|
+
details.contextEngineRegistered = contextEngineRegistered;
|
|
78
98
|
if (memorySlot && memorySlot !== "openclaw-nowledge-mem") {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
lines.push(
|
|
82
|
-
`Memory slot: "${memorySlot}" + corpus supplement active`,
|
|
83
|
-
);
|
|
99
|
+
if (corpusSupplementConfigured && corpusSupplementActive) {
|
|
100
|
+
lines.push(`Memory slot: "${memorySlot}" + corpus supplement active`);
|
|
84
101
|
lines.push(
|
|
85
102
|
" Nowledge Mem feeds into memory-core's recall and dreaming pipeline. All tools available.",
|
|
86
103
|
);
|
|
87
|
-
} else {
|
|
104
|
+
} else if (corpusSupplementConfigured && !corpusSupplementActive) {
|
|
105
|
+
lines.push(`ℹ Memory slot: "${memorySlot}"`);
|
|
88
106
|
lines.push(
|
|
89
|
-
|
|
90
|
-
);
|
|
91
|
-
lines.push(
|
|
92
|
-
" Two options:",
|
|
107
|
+
" corpusSupplement is configured, but host registration is unavailable in this runtime.",
|
|
93
108
|
);
|
|
109
|
+
if (cfg.sessionContext) {
|
|
110
|
+
lines.push(
|
|
111
|
+
" Fallback active: Nowledge Mem still injects Working Memory and uses its own recall path.",
|
|
112
|
+
);
|
|
113
|
+
} else {
|
|
114
|
+
lines.push(
|
|
115
|
+
" Fallback: Nowledge Mem tools remain available. Enable sessionContext for prompt-time Working Memory and recall.",
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
if (corpusSupplementRegistrationError) {
|
|
119
|
+
lines.push(
|
|
120
|
+
` Supplement registration detail: ${corpusSupplementRegistrationError}`,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
lines.push(`ℹ Memory slot: "${memorySlot}"`);
|
|
125
|
+
lines.push(" Two options:");
|
|
94
126
|
lines.push(
|
|
95
127
|
' - Full mode: set plugins.slots.memory to "openclaw-nowledge-mem" for the complete tool surface',
|
|
96
128
|
);
|
|
@@ -104,23 +136,50 @@ export function createStatusTool(client, _logger, cfg, runtimeInfo = {}) {
|
|
|
104
136
|
}
|
|
105
137
|
|
|
106
138
|
// 0c. Capture routing — hooks vs context engine
|
|
107
|
-
const ceActive =
|
|
139
|
+
const ceActive =
|
|
140
|
+
isNowledgeMemContextEngineSlot(ceSlot) && contextEngineRegistered;
|
|
108
141
|
const captureMode = !cfg.sessionDigest
|
|
109
142
|
? "disabled"
|
|
110
|
-
: ceActive
|
|
143
|
+
: ceActive
|
|
144
|
+
? "context-engine+hooks"
|
|
145
|
+
: "hooks";
|
|
111
146
|
details.captureMode = captureMode;
|
|
112
147
|
if (ceActive) {
|
|
113
|
-
|
|
148
|
+
if (ceSlot === NOWLEDGE_MEM_CONTEXT_ENGINE_COMPAT_ALIAS) {
|
|
149
|
+
lines.push(
|
|
150
|
+
`Context Engine slot: ${NOWLEDGE_MEM_CONTEXT_ENGINE_COMPAT_ALIAS} (active via compatibility alias)`,
|
|
151
|
+
);
|
|
152
|
+
lines.push(
|
|
153
|
+
` OpenClaw selected the plugin id for the context-engine slot. ${NOWLEDGE_MEM_CONTEXT_ENGINE_ID} remains the canonical manual setting.`,
|
|
154
|
+
);
|
|
155
|
+
} else {
|
|
156
|
+
lines.push(
|
|
157
|
+
`Context Engine slot: ${NOWLEDGE_MEM_CONTEXT_ENGINE_ID} (active)`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
114
160
|
lines.push(
|
|
115
161
|
" Thread capture runs through Context Engine afterTurn with hook fallback (agent_end, after_compaction, before_reset).",
|
|
116
162
|
);
|
|
117
|
-
} else if (ceSlot
|
|
118
|
-
|
|
163
|
+
} else if (isNowledgeMemContextEngineSlot(ceSlot)) {
|
|
164
|
+
if (ceSlot === NOWLEDGE_MEM_CONTEXT_ENGINE_COMPAT_ALIAS) {
|
|
165
|
+
lines.push(
|
|
166
|
+
`Context Engine slot: ${NOWLEDGE_MEM_CONTEXT_ENGINE_COMPAT_ALIAS} (compatibility alias, fallback to hooks)`,
|
|
167
|
+
);
|
|
168
|
+
lines.push(
|
|
169
|
+
` OpenClaw selected the plugin id for the context-engine slot. ${NOWLEDGE_MEM_CONTEXT_ENGINE_ID} remains the canonical manual setting.`,
|
|
170
|
+
);
|
|
171
|
+
} else {
|
|
172
|
+
lines.push(
|
|
173
|
+
`Context Engine slot: ${NOWLEDGE_MEM_CONTEXT_ENGINE_ID} (configured, fallback to hooks)`,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
119
176
|
lines.push(
|
|
120
177
|
" The slot points to Nowledge Mem, but Context Engine registration is not active in this runtime. Thread capture is using hooks only.",
|
|
121
178
|
);
|
|
122
179
|
if (contextEngineRegistrationError) {
|
|
123
|
-
lines.push(
|
|
180
|
+
lines.push(
|
|
181
|
+
` CE registration detail: ${contextEngineRegistrationError}`,
|
|
182
|
+
);
|
|
124
183
|
}
|
|
125
184
|
} else {
|
|
126
185
|
lines.push(
|
|
@@ -242,6 +301,14 @@ export function createStatusTool(client, _logger, cfg, runtimeInfo = {}) {
|
|
|
242
301
|
lines.push(
|
|
243
302
|
` corpusSupplement: ${cfg.corpusSupplement} (${sources.corpusSupplement || "?"})`,
|
|
244
303
|
);
|
|
304
|
+
if (corpusSupplementConfigured) {
|
|
305
|
+
const fallbackText = cfg.sessionContext
|
|
306
|
+
? "configured but unavailable (fallback to plugin recall)"
|
|
307
|
+
: "configured but unavailable (sessionContext disabled)";
|
|
308
|
+
lines.push(
|
|
309
|
+
` corpusSupplement runtime: ${corpusSupplementActive ? "active" : fallbackText}`,
|
|
310
|
+
);
|
|
311
|
+
}
|
|
245
312
|
|
|
246
313
|
details.config = {
|
|
247
314
|
sessionContext: {
|
|
@@ -271,6 +338,7 @@ export function createStatusTool(client, _logger, cfg, runtimeInfo = {}) {
|
|
|
271
338
|
corpusSupplement: {
|
|
272
339
|
value: cfg.corpusSupplement,
|
|
273
340
|
source: sources.corpusSupplement,
|
|
341
|
+
active: corpusSupplementActive,
|
|
274
342
|
},
|
|
275
343
|
apiUrl: { value: cfg.apiUrl || "(local)", source: sources.apiUrl },
|
|
276
344
|
apiKey: {
|