@xdarkicex/openclaw-memory-libravdb 1.4.53 → 1.4.55
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 +1 -1
- package/dist/context-engine.js +4 -1
- package/dist/dream-promotion.js +30 -3
- package/dist/index.js +40 -10
- package/docs/configuration.md +1 -1
- package/docs/features.md +5 -4
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -154,7 +154,7 @@ openclaw memory search "prior context"
|
|
|
154
154
|
openclaw memory export --user-id <userId>
|
|
155
155
|
openclaw memory flush --user-id <userId>
|
|
156
156
|
openclaw memory journal --limit 50
|
|
157
|
-
openclaw memory dream-promote --user-id <userId> --dream-file
|
|
157
|
+
openclaw memory dream-promote --user-id <userId> --dream-file ~/DREAMS.md
|
|
158
158
|
```
|
|
159
159
|
|
|
160
160
|
Use [Install](./docs/install.md) for service lifecycle commands and
|
package/dist/context-engine.js
CHANGED
|
@@ -312,7 +312,10 @@ function escapeMemoryFactText(text) {
|
|
|
312
312
|
.replaceAll("<", "<")
|
|
313
313
|
.replaceAll(">", ">")
|
|
314
314
|
.replaceAll('"', """)
|
|
315
|
-
.replaceAll("'", "'")
|
|
315
|
+
.replaceAll("'", "'")
|
|
316
|
+
.replaceAll("\r", " ")
|
|
317
|
+
.replaceAll("\n", " ")
|
|
318
|
+
.replaceAll("\t", "	");
|
|
316
319
|
}
|
|
317
320
|
function buildExactRecallFact(result, token) {
|
|
318
321
|
const factText = extractExactRecallFactText(result.text, token);
|
package/dist/dream-promotion.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import fsp from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { getHashBackendName, hashBytes } from "./markdown-hash.js";
|
|
5
6
|
import { formatError } from "./format-error.js";
|
|
@@ -10,9 +11,16 @@ const DEFAULT_MIN_UNIQUE_QUERIES = 2;
|
|
|
10
11
|
const DREAM_PROMOTION_VERSION = 1;
|
|
11
12
|
const DREAM_SOURCE_KIND = "dream";
|
|
12
13
|
export function createDreamPromotionHandle(cfg, getRpc, logger = console, fsApi = createRealFsApi()) {
|
|
13
|
-
const diaryPath = normalizeDiaryPath(cfg.dreamPromotionDiaryPath);
|
|
14
14
|
const userId = cfg.dreamPromotionUserId?.trim() ?? "";
|
|
15
|
-
if (cfg.dreamPromotionEnabled !== true || !
|
|
15
|
+
if (cfg.dreamPromotionEnabled !== true || !userId) {
|
|
16
|
+
return {
|
|
17
|
+
async start() { },
|
|
18
|
+
async refresh() { },
|
|
19
|
+
async stop() { },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const diaryPath = normalizeDiaryPath(cfg.dreamPromotionDiaryPath);
|
|
23
|
+
if (!diaryPath) {
|
|
16
24
|
return {
|
|
17
25
|
async start() { },
|
|
18
26
|
async refresh() { },
|
|
@@ -341,7 +349,26 @@ function normalizeDiaryPath(value) {
|
|
|
341
349
|
if (!trimmed) {
|
|
342
350
|
return "";
|
|
343
351
|
}
|
|
344
|
-
|
|
352
|
+
// Reject traversal components — even though path.resolve collapses them,
|
|
353
|
+
// their presence signals an attempt to escape intended boundaries.
|
|
354
|
+
const segments = trimmed.split(/[/\\]+/);
|
|
355
|
+
if (segments.some((s) => s === "..")) {
|
|
356
|
+
throw new Error(`dream diary path must not contain ".." traversal: ${trimmed}`);
|
|
357
|
+
}
|
|
358
|
+
const resolved = path.resolve(trimmed);
|
|
359
|
+
// Restrict to known-safe locations to prevent arbitrary file reads.
|
|
360
|
+
// Allowed roots: home directory and the configured OpenClaw state dir.
|
|
361
|
+
const allowedRoots = [
|
|
362
|
+
os.homedir(),
|
|
363
|
+
process.env.OPENCLAW_STATE_DIR,
|
|
364
|
+
]
|
|
365
|
+
.filter((r) => typeof r === "string" && r.trim().length > 0)
|
|
366
|
+
.map((root) => path.resolve(root));
|
|
367
|
+
const isAllowed = allowedRoots.some((root) => resolved.startsWith(root + path.sep) || resolved === root);
|
|
368
|
+
if (!isAllowed) {
|
|
369
|
+
throw new Error(`dream diary path must be within an allowed root: ${allowedRoots.join(", ")}. Got: ${resolved}`);
|
|
370
|
+
}
|
|
371
|
+
return resolved;
|
|
345
372
|
}
|
|
346
373
|
function createRealFsApi() {
|
|
347
374
|
return {
|
package/dist/index.js
CHANGED
|
@@ -9467,7 +9467,7 @@ var require_service_config = __commonJS({
|
|
|
9467
9467
|
exports2.validateRetryThrottling = validateRetryThrottling;
|
|
9468
9468
|
exports2.validateServiceConfig = validateServiceConfig;
|
|
9469
9469
|
exports2.extractAndSelectServiceConfig = extractAndSelectServiceConfig;
|
|
9470
|
-
var
|
|
9470
|
+
var os3 = __require("os");
|
|
9471
9471
|
var constants_1 = require_constants();
|
|
9472
9472
|
var DURATION_REGEX = /^\d+(\.\d{1,9})?s$/;
|
|
9473
9473
|
var CLIENT_LANGUAGE_STRING = "node";
|
|
@@ -9766,7 +9766,7 @@ var require_service_config = __commonJS({
|
|
|
9766
9766
|
if (Array.isArray(validatedConfig.clientHostname)) {
|
|
9767
9767
|
let hostnameMatched = false;
|
|
9768
9768
|
for (const hostname2 of validatedConfig.clientHostname) {
|
|
9769
|
-
if (hostname2 ===
|
|
9769
|
+
if (hostname2 === os3.hostname()) {
|
|
9770
9770
|
hostnameMatched = true;
|
|
9771
9771
|
}
|
|
9772
9772
|
}
|
|
@@ -24066,7 +24066,7 @@ var require_subchannel_call = __commonJS({
|
|
|
24066
24066
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
24067
24067
|
exports2.Http2SubchannelCall = void 0;
|
|
24068
24068
|
var http2 = __require("http2");
|
|
24069
|
-
var
|
|
24069
|
+
var os3 = __require("os");
|
|
24070
24070
|
var constants_1 = require_constants();
|
|
24071
24071
|
var metadata_1 = require_metadata();
|
|
24072
24072
|
var stream_decoder_1 = require_stream_decoder();
|
|
@@ -24074,7 +24074,7 @@ var require_subchannel_call = __commonJS({
|
|
|
24074
24074
|
var constants_2 = require_constants();
|
|
24075
24075
|
var TRACER_NAME = "subchannel_call";
|
|
24076
24076
|
function getSystemErrorName(errno) {
|
|
24077
|
-
for (const [name, num] of Object.entries(
|
|
24077
|
+
for (const [name, num] of Object.entries(os3.constants.errno)) {
|
|
24078
24078
|
if (num === errno) {
|
|
24079
24079
|
return name;
|
|
24080
24080
|
}
|
|
@@ -32292,6 +32292,7 @@ function formatError(error) {
|
|
|
32292
32292
|
// src/dream-promotion.ts
|
|
32293
32293
|
import fs from "node:fs";
|
|
32294
32294
|
import fsp from "node:fs/promises";
|
|
32295
|
+
import os from "node:os";
|
|
32295
32296
|
import path from "node:path";
|
|
32296
32297
|
|
|
32297
32298
|
// src/markdown-hash.ts
|
|
@@ -32505,9 +32506,19 @@ var DEFAULT_DEBOUNCE_MS = 150;
|
|
|
32505
32506
|
var DREAM_PROMOTION_VERSION = 1;
|
|
32506
32507
|
var DREAM_SOURCE_KIND = "dream";
|
|
32507
32508
|
function createDreamPromotionHandle(cfg, getRpc, logger = console, fsApi = createRealFsApi()) {
|
|
32508
|
-
const diaryPath = normalizeDiaryPath(cfg.dreamPromotionDiaryPath);
|
|
32509
32509
|
const userId = cfg.dreamPromotionUserId?.trim() ?? "";
|
|
32510
|
-
if (cfg.dreamPromotionEnabled !== true || !
|
|
32510
|
+
if (cfg.dreamPromotionEnabled !== true || !userId) {
|
|
32511
|
+
return {
|
|
32512
|
+
async start() {
|
|
32513
|
+
},
|
|
32514
|
+
async refresh() {
|
|
32515
|
+
},
|
|
32516
|
+
async stop() {
|
|
32517
|
+
}
|
|
32518
|
+
};
|
|
32519
|
+
}
|
|
32520
|
+
const diaryPath = normalizeDiaryPath(cfg.dreamPromotionDiaryPath);
|
|
32521
|
+
if (!diaryPath) {
|
|
32511
32522
|
return {
|
|
32512
32523
|
async start() {
|
|
32513
32524
|
},
|
|
@@ -32836,7 +32847,26 @@ function normalizeDiaryPath(value) {
|
|
|
32836
32847
|
if (!trimmed) {
|
|
32837
32848
|
return "";
|
|
32838
32849
|
}
|
|
32839
|
-
|
|
32850
|
+
const segments = trimmed.split(/[/\\]+/);
|
|
32851
|
+
if (segments.some((s) => s === "..")) {
|
|
32852
|
+
throw new Error(
|
|
32853
|
+
`dream diary path must not contain ".." traversal: ${trimmed}`
|
|
32854
|
+
);
|
|
32855
|
+
}
|
|
32856
|
+
const resolved = path.resolve(trimmed);
|
|
32857
|
+
const allowedRoots = [
|
|
32858
|
+
os.homedir(),
|
|
32859
|
+
process.env.OPENCLAW_STATE_DIR
|
|
32860
|
+
].filter((r) => typeof r === "string" && r.trim().length > 0).map((root) => path.resolve(root));
|
|
32861
|
+
const isAllowed = allowedRoots.some(
|
|
32862
|
+
(root) => resolved.startsWith(root + path.sep) || resolved === root
|
|
32863
|
+
);
|
|
32864
|
+
if (!isAllowed) {
|
|
32865
|
+
throw new Error(
|
|
32866
|
+
`dream diary path must be within an allowed root: ${allowedRoots.join(", ")}. Got: ${resolved}`
|
|
32867
|
+
);
|
|
32868
|
+
}
|
|
32869
|
+
return resolved;
|
|
32840
32870
|
}
|
|
32841
32871
|
function createRealFsApi() {
|
|
32842
32872
|
return {
|
|
@@ -33889,7 +33919,7 @@ function extractExactRecallFactText(text, token) {
|
|
|
33889
33919
|
return factSentence ?? tail.split("\n")[0]?.trim() ?? tail;
|
|
33890
33920
|
}
|
|
33891
33921
|
function escapeMemoryFactText(text) {
|
|
33892
|
-
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
33922
|
+
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'").replaceAll("\r", " ").replaceAll("\n", " ").replaceAll(" ", "	");
|
|
33893
33923
|
}
|
|
33894
33924
|
function buildExactRecallFact(result, token) {
|
|
33895
33925
|
const factText = extractExactRecallFactText(result.text, token);
|
|
@@ -39324,7 +39354,7 @@ var GrpcKernelClient = class {
|
|
|
39324
39354
|
// src/sidecar.ts
|
|
39325
39355
|
import fs3 from "node:fs";
|
|
39326
39356
|
import net from "node:net";
|
|
39327
|
-
import
|
|
39357
|
+
import os2 from "node:os";
|
|
39328
39358
|
import path4 from "node:path";
|
|
39329
39359
|
var STARTUP_CONNECT_MAX_RETRIES = 5;
|
|
39330
39360
|
var STARTUP_CONNECT_BASE_DELAY_MS = 100;
|
|
@@ -39566,7 +39596,7 @@ function resolveConfiguredEndpoint(cfg) {
|
|
|
39566
39596
|
function daemonProvisioningHint() {
|
|
39567
39597
|
return "If you installed the npm package, install and start libravdbd separately; the package does not provision the daemon binary, ONNX Runtime, or model assets.";
|
|
39568
39598
|
}
|
|
39569
|
-
function defaultEndpoint(platform = process.platform, homeDir =
|
|
39599
|
+
function defaultEndpoint(platform = process.platform, homeDir = os2.homedir(), pathExists = fs3.existsSync) {
|
|
39570
39600
|
const envEndpoint = process.env.LIBRAVDB_RPC_ENDPOINT?.trim();
|
|
39571
39601
|
if (envEndpoint && isConfiguredEndpoint(envEndpoint)) {
|
|
39572
39602
|
return envEndpoint;
|
package/docs/configuration.md
CHANGED
|
@@ -103,7 +103,7 @@ The plugin exposes `ingestionGateThreshold` for host-side gating decisions:
|
|
|
103
103
|
| Key | Type | Default | Notes |
|
|
104
104
|
|---|---|---|---|
|
|
105
105
|
| `dreamPromotionEnabled` | boolean | `false` | Enable dream diary promotion |
|
|
106
|
-
| `dreamPromotionDiaryPath` | string | — | Path to dream diary markdown file |
|
|
106
|
+
| `dreamPromotionDiaryPath` | string | — | Path to dream diary markdown file under the operator home directory or `OPENCLAW_STATE_DIR` |
|
|
107
107
|
| `dreamPromotionUserId` | string | — | User ID for dream collection scoping |
|
|
108
108
|
| `dreamPromotionDebounceMs` | number | `150` | Debounce window for dream diary changes |
|
|
109
109
|
|
package/docs/features.md
CHANGED
|
@@ -105,11 +105,12 @@ Automatic diary watching:
|
|
|
105
105
|
Manual run:
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
|
-
openclaw memory dream-promote --user-id <userId> --dream-file
|
|
108
|
+
openclaw memory dream-promote --user-id <userId> --dream-file ~/DREAMS.md
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
Dream diary files must live under the operator's home directory or the configured
|
|
112
|
+
`OPENCLAW_STATE_DIR`. The manual command and watcher both use the same sidecar
|
|
113
|
+
promotion RPC, so admission gates and provenance metadata are identical.
|
|
113
114
|
|
|
114
115
|
## Memory CLI
|
|
115
116
|
|
|
@@ -126,7 +127,7 @@ CLI API.
|
|
|
126
127
|
| `openclaw memory flush --user-id <userId>` | Delete one durable user namespace after confirmation. |
|
|
127
128
|
| `openclaw memory flush --session-key <sessionKey>` | Delete a namespace derived from a session key after confirmation. |
|
|
128
129
|
| `openclaw memory journal --limit 50` | Inspect bounded lifecycle hints recorded by the sidecar. |
|
|
129
|
-
| `openclaw memory dream-promote --user-id <userId> --dream-file <path>` | Promote vetted dream diary bullets
|
|
130
|
+
| `openclaw memory dream-promote --user-id <userId> --dream-file <path>` | Promote vetted dream diary bullets from a file under the operator home directory or `OPENCLAW_STATE_DIR`. |
|
|
130
131
|
|
|
131
132
|
Use `--yes` with `flush` only when you intentionally want to skip the
|
|
132
133
|
confirmation prompt.
|
package/openclaw.plugin.json
CHANGED