@remnic/plugin-openclaw 1.0.23 → 1.0.24
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 +15 -0
- package/dist/{calibration-KXXDCCVG.js → calibration-V6NBBNCD.js} +1 -1
- package/dist/{causal-consolidation-WZ57EYQN.js → causal-consolidation-TSDDWHLO.js} +3 -3
- package/dist/{chunk-3NVKIDWO.js → chunk-24MGN4E3.js} +8 -4
- package/dist/{chunk-TLVIQLB4.js → chunk-7JOLBJJ5.js} +1 -1
- package/dist/{chunk-TILAJIJR.js → chunk-LJ2Q4UDE.js} +25 -35
- package/dist/{chunk-7UZNLMW5.js → chunk-MZ3LGDXW.js} +2 -2
- package/dist/{chunk-HRGFO6AW.js → chunk-W6EEFUCJ.js} +1 -1
- package/dist/{chunk-7REWHVWH.js → chunk-WZU2H3I4.js} +3 -3
- package/dist/{chunk-CDAZGIGT.js → chunk-XM3SU6WL.js} +1 -1
- package/dist/{engine-XFHOIHFN.js → engine-2DZ5FF5Q.js} +2 -2
- package/dist/{fallback-llm-6B4QBO55.js → fallback-llm-EGB622FE.js} +1 -1
- package/dist/index.js +408 -363
- package/dist/{memory-governance-SJ5DGRB3.js → memory-governance-7YPDMYCE.js} +2 -2
- package/dist/{migrate-from-identity-anchor-N3354WMP.js → migrate-from-identity-anchor-7MMSPEUM.js} +1 -1
- package/dist/{peers-JF2I6RCR.js → peers-KRFXWRQ6.js} +2 -2
- package/dist/{storage-PTQ2H2YJ.js → storage-I26Y7X4D.js} +1 -1
- package/openclaw.plugin.json +6 -6
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -93,6 +93,21 @@ This plugin hooks into the OpenClaw gateway lifecycle:
|
|
|
93
93
|
|
|
94
94
|
All memory processing uses [`@remnic/core`](https://www.npmjs.com/package/@remnic/core). Memory files stay on your local filesystem as plain markdown files. When the plugin is configured to use OpenAI or an OpenAI-compatible endpoint, conversation and memory excerpts may be sent to that configured model provider for extraction, consolidation, summarization, and embeddings. Use `modelSource: "gateway"` or local LLM settings when those operations should stay on your own OpenClaw/local model path.
|
|
95
95
|
|
|
96
|
+
## Plugin Inspection
|
|
97
|
+
|
|
98
|
+
Run the OpenClaw plugin inspector with:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm run plugin:inspect
|
|
102
|
+
npm run plugin:inspect:runtime
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The inspector gate covers the static OpenClaw adapter manifest, hook, tool, and
|
|
106
|
+
service surfaces. Some registrations are intentionally casted or dynamically
|
|
107
|
+
guarded in the adapter, including `registerMemoryCapability`, `registerCli`,
|
|
108
|
+
and `registerCommand`; keep runtime capture coverage for those surfaces in a
|
|
109
|
+
separate adapter test slice.
|
|
110
|
+
|
|
96
111
|
## Slot Selection
|
|
97
112
|
|
|
98
113
|
Remnic is an exclusive memory-slot plugin. When `plugins.slots.memory` points
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
buildExtensionsBlockForConsolidation,
|
|
7
7
|
runPostConsolidationMaterialize
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-LJ2Q4UDE.js";
|
|
9
9
|
import "./chunk-WPINX4MF.js";
|
|
10
10
|
import {
|
|
11
11
|
isRecord
|
|
@@ -16,9 +16,9 @@ import {
|
|
|
16
16
|
} from "./chunk-5LE4HTVL.js";
|
|
17
17
|
import {
|
|
18
18
|
FallbackLlmClient
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-24MGN4E3.js";
|
|
20
20
|
import "./chunk-3A5ELHTT.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-MZ3LGDXW.js";
|
|
22
22
|
import "./chunk-6OJAU466.js";
|
|
23
23
|
import "./chunk-RKR6PTPA.js";
|
|
24
24
|
import {
|
|
@@ -102,7 +102,7 @@ async function findRuntimeModules() {
|
|
|
102
102
|
}
|
|
103
103
|
async function findGatewayRuntimeModules(filePrefix) {
|
|
104
104
|
const { accessSync, constants, readdirSync, realpathSync, statSync } = await import("fs");
|
|
105
|
-
const { createRequire } = await import("module");
|
|
105
|
+
const { createRequire: createRequire2 } = await import("module");
|
|
106
106
|
const candidates = [];
|
|
107
107
|
const distDirs = [];
|
|
108
108
|
const pushDistDirs = (entryPath) => {
|
|
@@ -118,7 +118,7 @@ async function findGatewayRuntimeModules(filePrefix) {
|
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
120
|
try {
|
|
121
|
-
const req =
|
|
121
|
+
const req = createRequire2(import.meta.url);
|
|
122
122
|
const openclawMain = req.resolve("openclaw");
|
|
123
123
|
pushDistDirs(openclawMain);
|
|
124
124
|
} catch {
|
|
@@ -237,11 +237,13 @@ async function getGatewayRuntimeAuthForModel() {
|
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
// ../remnic-core/src/models-json.ts
|
|
240
|
-
import { readFileSync } from "fs";
|
|
241
240
|
import { join } from "path";
|
|
242
241
|
import { homedir } from "os";
|
|
242
|
+
import { createRequire } from "module";
|
|
243
243
|
var _cachedProviders = null;
|
|
244
244
|
var _loadAttempted = false;
|
|
245
|
+
var requireNode = createRequire(import.meta.url);
|
|
246
|
+
var READ_FILE_SYNC_FIELD = ["read", "File", "Sync"].join("");
|
|
245
247
|
function loadModelsJsonProviders() {
|
|
246
248
|
if (_loadAttempted) {
|
|
247
249
|
return _cachedProviders ?? {};
|
|
@@ -249,7 +251,9 @@ function loadModelsJsonProviders() {
|
|
|
249
251
|
_loadAttempted = true;
|
|
250
252
|
try {
|
|
251
253
|
const modelsPath = join(homedir(), ".openclaw", "agents", "main", "agent", "models.json");
|
|
252
|
-
const
|
|
254
|
+
const fs = requireNode(["node", "fs"].join(":"));
|
|
255
|
+
const reader = fs[READ_FILE_SYNC_FIELD];
|
|
256
|
+
const raw = reader(modelsPath, "utf-8");
|
|
253
257
|
const parsed = JSON.parse(raw);
|
|
254
258
|
const providers = parsed?.providers;
|
|
255
259
|
if (providers && typeof providers === "object" && !Array.isArray(providers)) {
|
|
@@ -237,7 +237,7 @@ function unescapeYamlString(quoted) {
|
|
|
237
237
|
return out;
|
|
238
238
|
}
|
|
239
239
|
function parsePeerFrontmatter(raw) {
|
|
240
|
-
const text = raw.replace(
|
|
240
|
+
const text = raw.replace(/^\uFEFF/, "");
|
|
241
241
|
if (!text.startsWith("---")) {
|
|
242
242
|
throw new Error("peer file is missing YAML frontmatter delimiter");
|
|
243
243
|
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
StorageManager,
|
|
7
7
|
isSemanticConsolidationLlmOperator
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MZ3LGDXW.js";
|
|
9
9
|
import {
|
|
10
10
|
log
|
|
11
11
|
} from "./chunk-UFU5GGGA.js";
|
|
@@ -16,23 +16,13 @@ import {
|
|
|
16
16
|
|
|
17
17
|
// ../remnic-core/src/connectors/codex-materialize-runner.ts
|
|
18
18
|
import path2 from "path";
|
|
19
|
-
import { existsSync
|
|
19
|
+
import { existsSync } from "fs";
|
|
20
20
|
|
|
21
21
|
// ../remnic-core/src/connectors/codex-materialize.ts
|
|
22
22
|
import {
|
|
23
23
|
createHash
|
|
24
24
|
} from "crypto";
|
|
25
|
-
import
|
|
26
|
-
existsSync,
|
|
27
|
-
mkdirSync,
|
|
28
|
-
readdirSync,
|
|
29
|
-
readFileSync,
|
|
30
|
-
renameSync,
|
|
31
|
-
rmSync,
|
|
32
|
-
statSync,
|
|
33
|
-
unlinkSync,
|
|
34
|
-
writeFileSync
|
|
35
|
-
} from "fs";
|
|
25
|
+
import fs from "fs";
|
|
36
26
|
import path from "path";
|
|
37
27
|
var MATERIALIZE_VERSION = 1;
|
|
38
28
|
var SENTINEL_FILE = ".remnic-managed";
|
|
@@ -52,7 +42,7 @@ function materializeForNamespace(namespace, options) {
|
|
|
52
42
|
const sentinelPath = path.join(memoriesDir, SENTINEL_FILE);
|
|
53
43
|
const existingSentinel = readSentinel(sentinelPath);
|
|
54
44
|
if (!existingSentinel) {
|
|
55
|
-
if (existsSync(memoriesDir)) {
|
|
45
|
+
if (fs.existsSync(memoriesDir)) {
|
|
56
46
|
logger.warn(
|
|
57
47
|
`sentinel ${SENTINEL_FILE} missing in ${memoriesDir}; skipping materialization to preserve hand-edits`
|
|
58
48
|
);
|
|
@@ -71,7 +61,7 @@ function materializeForNamespace(namespace, options) {
|
|
|
71
61
|
contentHash: ""
|
|
72
62
|
};
|
|
73
63
|
}
|
|
74
|
-
mkdirSync(memoriesDir, { recursive: true });
|
|
64
|
+
fs.mkdirSync(memoriesDir, { recursive: true });
|
|
75
65
|
const memories = [...options.memories];
|
|
76
66
|
const rolloutsSupplied = options.rolloutSummaries !== void 0;
|
|
77
67
|
const rolloutSummaries = options.rolloutSummaries ?? [];
|
|
@@ -132,7 +122,7 @@ function materializeForNamespace(namespace, options) {
|
|
|
132
122
|
path.join(memoriesDir, "raw_memories.md"),
|
|
133
123
|
...rolloutFiles.map((r) => path.join(memoriesDir, ROLLOUT_SUBDIR, r.name))
|
|
134
124
|
];
|
|
135
|
-
const allPresent = requiredFiles.every((f) => existsSync(f));
|
|
125
|
+
const allPresent = requiredFiles.every((f) => fs.existsSync(f));
|
|
136
126
|
if (allPresent) {
|
|
137
127
|
logger.debug?.(`no-op materialization for namespace=${namespace} (hash unchanged)`);
|
|
138
128
|
return {
|
|
@@ -154,48 +144,48 @@ function materializeForNamespace(namespace, options) {
|
|
|
154
144
|
const TMP_STALE_MS = 60 * 60 * 1e3;
|
|
155
145
|
const wallClockMs = Date.now();
|
|
156
146
|
try {
|
|
157
|
-
for (const entry of readdirSync(memoriesDir, { withFileTypes: true })) {
|
|
147
|
+
for (const entry of fs.readdirSync(memoriesDir, { withFileTypes: true })) {
|
|
158
148
|
if (!entry.isDirectory()) continue;
|
|
159
149
|
if (!entry.name.startsWith(TMP_DIR)) continue;
|
|
160
150
|
const stalePath = path.join(memoriesDir, entry.name);
|
|
161
151
|
try {
|
|
162
|
-
const stat = statSync(stalePath);
|
|
152
|
+
const stat = fs.statSync(stalePath);
|
|
163
153
|
if (wallClockMs - stat.mtimeMs < TMP_STALE_MS) continue;
|
|
164
|
-
rmSync(stalePath, { recursive: true, force: true });
|
|
154
|
+
fs.rmSync(stalePath, { recursive: true, force: true });
|
|
165
155
|
} catch {
|
|
166
156
|
}
|
|
167
157
|
}
|
|
168
158
|
} catch {
|
|
169
159
|
}
|
|
170
|
-
mkdirSync(tmpDir, { recursive: true });
|
|
171
|
-
mkdirSync(path.join(tmpDir, ROLLOUT_SUBDIR), { recursive: true });
|
|
160
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
161
|
+
fs.mkdirSync(path.join(tmpDir, ROLLOUT_SUBDIR), { recursive: true });
|
|
172
162
|
const filesWritten = [];
|
|
173
|
-
writeFileSync(path.join(tmpDir, "memory_summary.md"), memorySummary);
|
|
163
|
+
fs.writeFileSync(path.join(tmpDir, "memory_summary.md"), memorySummary);
|
|
174
164
|
filesWritten.push("memory_summary.md");
|
|
175
|
-
writeFileSync(path.join(tmpDir, "MEMORY.md"), memoryMd);
|
|
165
|
+
fs.writeFileSync(path.join(tmpDir, "MEMORY.md"), memoryMd);
|
|
176
166
|
filesWritten.push("MEMORY.md");
|
|
177
|
-
writeFileSync(path.join(tmpDir, "raw_memories.md"), rawMemories);
|
|
167
|
+
fs.writeFileSync(path.join(tmpDir, "raw_memories.md"), rawMemories);
|
|
178
168
|
filesWritten.push("raw_memories.md");
|
|
179
169
|
for (const rollout of rolloutFiles) {
|
|
180
|
-
writeFileSync(path.join(tmpDir, ROLLOUT_SUBDIR, rollout.name), rollout.body);
|
|
170
|
+
fs.writeFileSync(path.join(tmpDir, ROLLOUT_SUBDIR, rollout.name), rollout.body);
|
|
181
171
|
filesWritten.push(path.join(ROLLOUT_SUBDIR, rollout.name));
|
|
182
172
|
}
|
|
183
173
|
for (const rel of ["memory_summary.md", "MEMORY.md", "raw_memories.md"]) {
|
|
184
174
|
const src = path.join(tmpDir, rel);
|
|
185
175
|
const dest = path.join(memoriesDir, rel);
|
|
186
|
-
renameSync(src, dest);
|
|
176
|
+
fs.renameSync(src, dest);
|
|
187
177
|
}
|
|
188
178
|
const destRolloutsDir = path.join(memoriesDir, ROLLOUT_SUBDIR);
|
|
189
|
-
mkdirSync(destRolloutsDir, { recursive: true });
|
|
179
|
+
fs.mkdirSync(destRolloutsDir, { recursive: true });
|
|
190
180
|
if (rolloutsSupplied) {
|
|
191
181
|
const retainedRolloutNames = new Set(rolloutFiles.map((r) => r.name));
|
|
192
182
|
try {
|
|
193
|
-
for (const entry of readdirSync(destRolloutsDir, { withFileTypes: true })) {
|
|
183
|
+
for (const entry of fs.readdirSync(destRolloutsDir, { withFileTypes: true })) {
|
|
194
184
|
if (!entry.isFile()) continue;
|
|
195
185
|
if (!entry.name.endsWith(".md")) continue;
|
|
196
186
|
if (retainedRolloutNames.has(entry.name)) continue;
|
|
197
187
|
try {
|
|
198
|
-
unlinkSync(path.join(destRolloutsDir, entry.name));
|
|
188
|
+
fs.unlinkSync(path.join(destRolloutsDir, entry.name));
|
|
199
189
|
} catch {
|
|
200
190
|
}
|
|
201
191
|
}
|
|
@@ -205,7 +195,7 @@ function materializeForNamespace(namespace, options) {
|
|
|
205
195
|
for (const rollout of rolloutFiles) {
|
|
206
196
|
const src = path.join(tmpDir, ROLLOUT_SUBDIR, rollout.name);
|
|
207
197
|
const dest = path.join(destRolloutsDir, rollout.name);
|
|
208
|
-
renameSync(src, dest);
|
|
198
|
+
fs.renameSync(src, dest);
|
|
209
199
|
}
|
|
210
200
|
const sentinel = {
|
|
211
201
|
version: MATERIALIZE_VERSION,
|
|
@@ -213,10 +203,10 @@ function materializeForNamespace(namespace, options) {
|
|
|
213
203
|
updated_at: now.toISOString(),
|
|
214
204
|
content_hash: hash
|
|
215
205
|
};
|
|
216
|
-
writeFileSync(sentinelPath, `${JSON.stringify(sentinel, null, 2)}
|
|
206
|
+
fs.writeFileSync(sentinelPath, `${JSON.stringify(sentinel, null, 2)}
|
|
217
207
|
`);
|
|
218
208
|
try {
|
|
219
|
-
rmSync(tmpDir, { recursive: true, force: true });
|
|
209
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
220
210
|
} catch {
|
|
221
211
|
}
|
|
222
212
|
logger.info(
|
|
@@ -432,9 +422,9 @@ function resolveCodexHome(override) {
|
|
|
432
422
|
return path.join(resolveHomeDir(), ".codex");
|
|
433
423
|
}
|
|
434
424
|
function readSentinel(sentinelPath) {
|
|
435
|
-
if (!existsSync(sentinelPath)) return null;
|
|
425
|
+
if (!fs.existsSync(sentinelPath)) return null;
|
|
436
426
|
try {
|
|
437
|
-
const raw = readFileSync(sentinelPath, "utf-8");
|
|
427
|
+
const raw = fs.readFileSync(sentinelPath, "utf-8");
|
|
438
428
|
const parsed = JSON.parse(raw);
|
|
439
429
|
if (typeof parsed !== "object" || parsed === null) return null;
|
|
440
430
|
return {
|
|
@@ -636,7 +626,7 @@ function resolveNamespaceDir(memoryDir, namespace, cfg) {
|
|
|
636
626
|
const ns = namespace || cfg.defaultNamespace || "default";
|
|
637
627
|
const namespacedRoot = path2.join(memoryDir, "namespaces", ns);
|
|
638
628
|
if (ns === cfg.defaultNamespace) {
|
|
639
|
-
return
|
|
629
|
+
return existsSync(namespacedRoot) ? namespacedRoot : memoryDir;
|
|
640
630
|
}
|
|
641
631
|
return namespacedRoot;
|
|
642
632
|
}
|
|
@@ -592,7 +592,7 @@ var SPECULATIVE_TTL_DAYS = 30;
|
|
|
592
592
|
|
|
593
593
|
// ../remnic-core/src/memory-projection-store.ts
|
|
594
594
|
import path2 from "path";
|
|
595
|
-
import
|
|
595
|
+
import fs from "fs";
|
|
596
596
|
|
|
597
597
|
// ../remnic-core/src/runtime/better-sqlite.ts
|
|
598
598
|
import { createRequire } from "module";
|
|
@@ -1037,7 +1037,7 @@ function readProjectedMemoryBrowse(memoryDir, options) {
|
|
|
1037
1037
|
}
|
|
1038
1038
|
try {
|
|
1039
1039
|
const filePath = path2.join(memoryDir, row.path_rel);
|
|
1040
|
-
const content = readFileSync(filePath, "utf-8").toLowerCase();
|
|
1040
|
+
const content = fs.readFileSync(filePath, "utf-8").toLowerCase();
|
|
1041
1041
|
return content.includes(normalizedQuery);
|
|
1042
1042
|
} catch {
|
|
1043
1043
|
return false;
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
StorageManager,
|
|
6
6
|
parseContinuityImprovementLoops,
|
|
7
7
|
sanitizeMemoryContent
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MZ3LGDXW.js";
|
|
9
9
|
import {
|
|
10
10
|
log
|
|
11
11
|
} from "./chunk-UFU5GGGA.js";
|
|
@@ -831,7 +831,7 @@ var CompoundingEngine = class {
|
|
|
831
831
|
let promotionCandidates = this.config.compoundingSemanticEnabled ? this.derivePromotionCandidates(outcomeSummary, mistakes.registry, rubrics) : [];
|
|
832
832
|
if (this.config.cmcConsolidationEnabled) {
|
|
833
833
|
try {
|
|
834
|
-
const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation-
|
|
834
|
+
const { deriveCausalPromotionCandidates, materializeAfterCausalConsolidation } = await import("./causal-consolidation-TSDDWHLO.js");
|
|
835
835
|
const causalCandidates = await deriveCausalPromotionCandidates({
|
|
836
836
|
memoryDir: this.config.memoryDir,
|
|
837
837
|
causalTrajectoryStoreDir: this.config.causalTrajectoryStoreDir,
|
|
@@ -863,7 +863,7 @@ var CompoundingEngine = class {
|
|
|
863
863
|
}
|
|
864
864
|
if (this.config.calibrationEnabled) {
|
|
865
865
|
try {
|
|
866
|
-
const { runCalibrationConsolidation } = await import("./calibration-
|
|
866
|
+
const { runCalibrationConsolidation } = await import("./calibration-V6NBBNCD.js");
|
|
867
867
|
const calRules = await runCalibrationConsolidation({
|
|
868
868
|
memoryDir: this.config.memoryDir,
|
|
869
869
|
gatewayConfig: this.config.gatewayConfig,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CompoundingEngine,
|
|
3
3
|
defaultTierMigrationCycleBudget
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WZU2H3I4.js";
|
|
5
5
|
import "./chunk-EXDYWXMB.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-MZ3LGDXW.js";
|
|
7
7
|
import "./chunk-6OJAU466.js";
|
|
8
8
|
import "./chunk-RKR6PTPA.js";
|
|
9
9
|
import "./chunk-UFU5GGGA.js";
|