@xdarkicex/openclaw-memory-libravdb 1.6.15 → 1.6.17
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 +13 -0
- package/dist/context-engine.d.ts +1 -0
- package/dist/context-engine.js +11 -1
- package/dist/index.js +69 -1
- package/dist/libravdb-client.d.ts +4 -0
- package/dist/libravdb-client.js +62 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,6 +33,19 @@ brew install libravdbd
|
|
|
33
33
|
brew services start libravdbd
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
> **After upgrades:** Always restart the daemon so the newly installed binary takes effect:
|
|
37
|
+
> ```bash
|
|
38
|
+
> # macOS (Homebrew)
|
|
39
|
+
> brew services restart libravdbd
|
|
40
|
+
>
|
|
41
|
+
> # Linux (systemd)
|
|
42
|
+
> systemctl --user restart libravdbd
|
|
43
|
+
>
|
|
44
|
+
> # Linux (no systemd — kill and restart manually)
|
|
45
|
+
> killall libravdbd && libravdbd &
|
|
46
|
+
> ```
|
|
47
|
+
> Failing to restart leaves the old process running — it will not auto-replace a live background service. If you see "Protocol error" or connection failures after an upgrade, this is almost always the cause.
|
|
48
|
+
|
|
36
49
|
**Linux (APT)**
|
|
37
50
|
|
|
38
51
|
```bash
|
package/dist/context-engine.d.ts
CHANGED
|
@@ -99,5 +99,6 @@ export declare function buildContextEngineFactory(runtime: PluginRuntime, cfg: P
|
|
|
99
99
|
tokenBudget?: number;
|
|
100
100
|
runtimeContext?: Record<string, unknown>;
|
|
101
101
|
}): Promise<import("@xdarkicex/libravdb-contracts").AfterTurnKernelResponse>;
|
|
102
|
+
dispose(): Promise<void>;
|
|
102
103
|
};
|
|
103
104
|
export {};
|
package/dist/context-engine.js
CHANGED
|
@@ -521,6 +521,7 @@ export function normalizeAssembleResult(result) {
|
|
|
521
521
|
}
|
|
522
522
|
export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
523
523
|
const predictiveContextCache = new Map();
|
|
524
|
+
const PREDICTIVE_CACHE_MAX_SIZE = 100;
|
|
524
525
|
let cachedIdentity = null;
|
|
525
526
|
let cachedSessionKey;
|
|
526
527
|
function resolveUserId(args) {
|
|
@@ -743,6 +744,7 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
743
744
|
ownsCompaction: true,
|
|
744
745
|
async bootstrap(args) {
|
|
745
746
|
const sessionId = requireSessionId(args.sessionId, "bootstrap");
|
|
747
|
+
predictiveContextCache.delete(sessionId);
|
|
746
748
|
const userId = resolveUserId({
|
|
747
749
|
userIdOverride: args.userId,
|
|
748
750
|
sessionKey: args.sessionKey,
|
|
@@ -925,6 +927,11 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
925
927
|
});
|
|
926
928
|
const predictions = result.predictions;
|
|
927
929
|
if (Array.isArray(predictions) && predictions.length > 0) {
|
|
930
|
+
if (predictiveContextCache.size >= PREDICTIVE_CACHE_MAX_SIZE) {
|
|
931
|
+
const oldest = predictiveContextCache.keys().next().value;
|
|
932
|
+
if (oldest !== undefined)
|
|
933
|
+
predictiveContextCache.delete(oldest);
|
|
934
|
+
}
|
|
928
935
|
predictiveContextCache.set(sessionId, predictions);
|
|
929
936
|
}
|
|
930
937
|
return result;
|
|
@@ -934,6 +941,9 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
934
941
|
`${error instanceof Error ? error.message : String(error)}`);
|
|
935
942
|
throw error;
|
|
936
943
|
}
|
|
937
|
-
}
|
|
944
|
+
},
|
|
945
|
+
async dispose() {
|
|
946
|
+
predictiveContextCache.clear();
|
|
947
|
+
},
|
|
938
948
|
};
|
|
939
949
|
}
|
package/dist/index.js
CHANGED
|
@@ -27036,6 +27036,7 @@ function normalizeAssembleResult(result) {
|
|
|
27036
27036
|
}
|
|
27037
27037
|
function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
27038
27038
|
const predictiveContextCache = /* @__PURE__ */ new Map();
|
|
27039
|
+
const PREDICTIVE_CACHE_MAX_SIZE = 100;
|
|
27039
27040
|
let cachedIdentity = null;
|
|
27040
27041
|
let cachedSessionKey;
|
|
27041
27042
|
function resolveUserId(args) {
|
|
@@ -27245,6 +27246,7 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
27245
27246
|
ownsCompaction: true,
|
|
27246
27247
|
async bootstrap(args) {
|
|
27247
27248
|
const sessionId = requireSessionId(args.sessionId, "bootstrap");
|
|
27249
|
+
predictiveContextCache.delete(sessionId);
|
|
27248
27250
|
const userId = resolveUserId({
|
|
27249
27251
|
userIdOverride: args.userId,
|
|
27250
27252
|
sessionKey: args.sessionKey
|
|
@@ -27438,6 +27440,10 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
27438
27440
|
});
|
|
27439
27441
|
const predictions = result.predictions;
|
|
27440
27442
|
if (Array.isArray(predictions) && predictions.length > 0) {
|
|
27443
|
+
if (predictiveContextCache.size >= PREDICTIVE_CACHE_MAX_SIZE) {
|
|
27444
|
+
const oldest = predictiveContextCache.keys().next().value;
|
|
27445
|
+
if (oldest !== void 0) predictiveContextCache.delete(oldest);
|
|
27446
|
+
}
|
|
27441
27447
|
predictiveContextCache.set(sessionId, predictions);
|
|
27442
27448
|
}
|
|
27443
27449
|
return result;
|
|
@@ -27447,6 +27453,9 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
27447
27453
|
);
|
|
27448
27454
|
throw error2;
|
|
27449
27455
|
}
|
|
27456
|
+
},
|
|
27457
|
+
async dispose() {
|
|
27458
|
+
predictiveContextCache.clear();
|
|
27450
27459
|
}
|
|
27451
27460
|
};
|
|
27452
27461
|
}
|
|
@@ -36569,6 +36578,55 @@ function resolveClientEndpoint(configuredEndpoint) {
|
|
|
36569
36578
|
}
|
|
36570
36579
|
return `unix:${path3.join(os3.homedir(), ".libravdbd", "run", sockName)}`;
|
|
36571
36580
|
}
|
|
36581
|
+
function isLegacyJsonRpcHealthResponse(payload) {
|
|
36582
|
+
try {
|
|
36583
|
+
const parsed = JSON.parse(payload.trim());
|
|
36584
|
+
return parsed.jsonrpc === "2.0" && parsed.result?.ok === true;
|
|
36585
|
+
} catch {
|
|
36586
|
+
return false;
|
|
36587
|
+
}
|
|
36588
|
+
}
|
|
36589
|
+
async function detectLegacyJsonRpcDaemon(endpoint, timeoutMs = 500) {
|
|
36590
|
+
if (!endpoint.startsWith("unix:")) {
|
|
36591
|
+
return false;
|
|
36592
|
+
}
|
|
36593
|
+
const socketPath = endpoint.slice(5);
|
|
36594
|
+
if (!socketPath) {
|
|
36595
|
+
return false;
|
|
36596
|
+
}
|
|
36597
|
+
return await new Promise((resolve) => {
|
|
36598
|
+
let settled = false;
|
|
36599
|
+
let response = "";
|
|
36600
|
+
const socket = net.createConnection(socketPath);
|
|
36601
|
+
const finish = (value) => {
|
|
36602
|
+
if (settled) {
|
|
36603
|
+
return;
|
|
36604
|
+
}
|
|
36605
|
+
settled = true;
|
|
36606
|
+
clearTimeout(timer);
|
|
36607
|
+
socket.removeAllListeners();
|
|
36608
|
+
socket.destroy();
|
|
36609
|
+
resolve(value);
|
|
36610
|
+
};
|
|
36611
|
+
const timer = setTimeout(() => finish(false), Math.max(1, timeoutMs));
|
|
36612
|
+
timer.unref?.();
|
|
36613
|
+
socket.setEncoding("utf8");
|
|
36614
|
+
socket.on("connect", () => {
|
|
36615
|
+
socket.write('{"jsonrpc":"2.0","id":1,"method":"health","params":{}}\n');
|
|
36616
|
+
});
|
|
36617
|
+
socket.on("data", (chunk) => {
|
|
36618
|
+
response += chunk;
|
|
36619
|
+
if (isLegacyJsonRpcHealthResponse(response)) {
|
|
36620
|
+
finish(true);
|
|
36621
|
+
} else if (response.length > 4096) {
|
|
36622
|
+
finish(false);
|
|
36623
|
+
}
|
|
36624
|
+
});
|
|
36625
|
+
socket.on("end", () => finish(isLegacyJsonRpcHealthResponse(response)));
|
|
36626
|
+
socket.on("close", () => finish(isLegacyJsonRpcHealthResponse(response)));
|
|
36627
|
+
socket.on("error", () => finish(false));
|
|
36628
|
+
});
|
|
36629
|
+
}
|
|
36572
36630
|
function createRpcMutex() {
|
|
36573
36631
|
return {
|
|
36574
36632
|
current: Promise.resolve(),
|
|
@@ -36627,11 +36685,15 @@ function createAuthInterceptor(state) {
|
|
|
36627
36685
|
var LibravDBClient = class {
|
|
36628
36686
|
client;
|
|
36629
36687
|
secret;
|
|
36688
|
+
endpoint;
|
|
36689
|
+
legacyProbeTimeoutMs;
|
|
36630
36690
|
nonceHex;
|
|
36631
36691
|
closed = false;
|
|
36632
36692
|
constructor(options = {}) {
|
|
36633
36693
|
this.secret = options.secret ?? loadSecretFromEnv();
|
|
36634
36694
|
const rawEndpoint = resolveClientEndpoint(options.endpoint);
|
|
36695
|
+
this.endpoint = rawEndpoint;
|
|
36696
|
+
this.legacyProbeTimeoutMs = Math.min(options.timeoutMs ?? 3e4, 1e3);
|
|
36635
36697
|
const isUnix = rawEndpoint.startsWith("unix:");
|
|
36636
36698
|
const socketPath = isUnix ? rawEndpoint.slice(5) : void 0;
|
|
36637
36699
|
const credMode = resolveCredentialMode(rawEndpoint, options.tlsMode);
|
|
@@ -36687,8 +36749,14 @@ var LibravDBClient = class {
|
|
|
36687
36749
|
}
|
|
36688
36750
|
);
|
|
36689
36751
|
} catch (error2) {
|
|
36752
|
+
const detail = error2 instanceof Error ? error2.message : String(error2);
|
|
36753
|
+
if (detail.includes("Protocol error") && await detectLegacyJsonRpcDaemon(this.endpoint, this.legacyProbeTimeoutMs)) {
|
|
36754
|
+
throw new Error(
|
|
36755
|
+
`LibraVDB: failed to handshake with daemon: ${detail}. The endpoint answered legacy JSON-RPC health; this plugin requires a gRPC-compatible libravdbd daemon. Update or restart libravdbd with gRPC support, or pin the plugin to a daemon-compatible release.`
|
|
36756
|
+
);
|
|
36757
|
+
}
|
|
36690
36758
|
throw new Error(
|
|
36691
|
-
`LibraVDB: failed to handshake with daemon: ${
|
|
36759
|
+
`LibraVDB: failed to handshake with daemon: ${detail}`
|
|
36692
36760
|
);
|
|
36693
36761
|
}
|
|
36694
36762
|
}
|
|
@@ -12,6 +12,8 @@ export interface LibravDBClientOptions {
|
|
|
12
12
|
tlsClientKeyPath?: string;
|
|
13
13
|
}
|
|
14
14
|
export declare function resolveClientEndpoint(configuredEndpoint?: string): string;
|
|
15
|
+
export declare function isLegacyJsonRpcHealthResponse(payload: string): boolean;
|
|
16
|
+
export declare function detectLegacyJsonRpcDaemon(endpoint: string, timeoutMs?: number): Promise<boolean>;
|
|
15
17
|
interface RpcMutex {
|
|
16
18
|
current: Promise<void>;
|
|
17
19
|
lock(): Promise<() => void>;
|
|
@@ -26,6 +28,8 @@ export declare function createAuthInterceptor(state: AuthInterceptorState): Inte
|
|
|
26
28
|
export declare class LibravDBClient {
|
|
27
29
|
private client;
|
|
28
30
|
private readonly secret;
|
|
31
|
+
private readonly endpoint;
|
|
32
|
+
private readonly legacyProbeTimeoutMs;
|
|
29
33
|
private nonceHex;
|
|
30
34
|
private closed;
|
|
31
35
|
constructor(options?: LibravDBClientOptions);
|
package/dist/libravdb-client.js
CHANGED
|
@@ -27,6 +27,57 @@ export function resolveClientEndpoint(configuredEndpoint) {
|
|
|
27
27
|
}
|
|
28
28
|
return `unix:${path.join(os.homedir(), ".libravdbd", "run", sockName)}`;
|
|
29
29
|
}
|
|
30
|
+
export function isLegacyJsonRpcHealthResponse(payload) {
|
|
31
|
+
try {
|
|
32
|
+
const parsed = JSON.parse(payload.trim());
|
|
33
|
+
return parsed.jsonrpc === "2.0" && parsed.result?.ok === true;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export async function detectLegacyJsonRpcDaemon(endpoint, timeoutMs = 500) {
|
|
40
|
+
if (!endpoint.startsWith("unix:")) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const socketPath = endpoint.slice(5);
|
|
44
|
+
if (!socketPath) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
return await new Promise((resolve) => {
|
|
48
|
+
let settled = false;
|
|
49
|
+
let response = "";
|
|
50
|
+
const socket = net.createConnection(socketPath);
|
|
51
|
+
const finish = (value) => {
|
|
52
|
+
if (settled) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
settled = true;
|
|
56
|
+
clearTimeout(timer);
|
|
57
|
+
socket.removeAllListeners();
|
|
58
|
+
socket.destroy();
|
|
59
|
+
resolve(value);
|
|
60
|
+
};
|
|
61
|
+
const timer = setTimeout(() => finish(false), Math.max(1, timeoutMs));
|
|
62
|
+
timer.unref?.();
|
|
63
|
+
socket.setEncoding("utf8");
|
|
64
|
+
socket.on("connect", () => {
|
|
65
|
+
socket.write('{"jsonrpc":"2.0","id":1,"method":"health","params":{}}\n');
|
|
66
|
+
});
|
|
67
|
+
socket.on("data", (chunk) => {
|
|
68
|
+
response += chunk;
|
|
69
|
+
if (isLegacyJsonRpcHealthResponse(response)) {
|
|
70
|
+
finish(true);
|
|
71
|
+
}
|
|
72
|
+
else if (response.length > 4096) {
|
|
73
|
+
finish(false);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
socket.on("end", () => finish(isLegacyJsonRpcHealthResponse(response)));
|
|
77
|
+
socket.on("close", () => finish(isLegacyJsonRpcHealthResponse(response)));
|
|
78
|
+
socket.on("error", () => finish(false));
|
|
79
|
+
});
|
|
80
|
+
}
|
|
30
81
|
function createRpcMutex() {
|
|
31
82
|
return {
|
|
32
83
|
current: Promise.resolve(),
|
|
@@ -92,11 +143,15 @@ export function createAuthInterceptor(state) {
|
|
|
92
143
|
export class LibravDBClient {
|
|
93
144
|
client;
|
|
94
145
|
secret;
|
|
146
|
+
endpoint;
|
|
147
|
+
legacyProbeTimeoutMs;
|
|
95
148
|
nonceHex;
|
|
96
149
|
closed = false;
|
|
97
150
|
constructor(options = {}) {
|
|
98
151
|
this.secret = options.secret ?? loadSecretFromEnv();
|
|
99
152
|
const rawEndpoint = resolveClientEndpoint(options.endpoint);
|
|
153
|
+
this.endpoint = rawEndpoint;
|
|
154
|
+
this.legacyProbeTimeoutMs = Math.min(options.timeoutMs ?? 30000, 1000);
|
|
100
155
|
const isUnix = rawEndpoint.startsWith("unix:");
|
|
101
156
|
const socketPath = isUnix ? rawEndpoint.slice(5) : undefined;
|
|
102
157
|
const credMode = resolveCredentialMode(rawEndpoint, options.tlsMode);
|
|
@@ -151,7 +206,13 @@ export class LibravDBClient {
|
|
|
151
206
|
});
|
|
152
207
|
}
|
|
153
208
|
catch (error) {
|
|
154
|
-
|
|
209
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
210
|
+
if (detail.includes("Protocol error") && await detectLegacyJsonRpcDaemon(this.endpoint, this.legacyProbeTimeoutMs)) {
|
|
211
|
+
throw new Error(`LibraVDB: failed to handshake with daemon: ${detail}. ` +
|
|
212
|
+
"The endpoint answered legacy JSON-RPC health; this plugin requires a gRPC-compatible libravdbd daemon. " +
|
|
213
|
+
"Update or restart libravdbd with gRPC support, or pin the plugin to a daemon-compatible release.");
|
|
214
|
+
}
|
|
215
|
+
throw new Error(`LibraVDB: failed to handshake with daemon: ${detail}`);
|
|
155
216
|
}
|
|
156
217
|
}
|
|
157
218
|
guardOpen() {
|
package/openclaw.plugin.json
CHANGED