@xdarkicex/openclaw-memory-libravdb 1.6.16 → 1.6.18
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/dist/context-engine.d.ts +2 -0
- package/dist/context-engine.js +27 -3
- package/dist/index.js +89 -4
- 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/dist/context-engine.d.ts
CHANGED
|
@@ -12,10 +12,12 @@ type OpenClawCompatibleMessage = {
|
|
|
12
12
|
id?: string;
|
|
13
13
|
[key: string]: unknown;
|
|
14
14
|
};
|
|
15
|
+
type OpenClawCompatiblePromptAuthority = "preassembly_may_overflow";
|
|
15
16
|
type OpenClawCompatibleAssembleResult = {
|
|
16
17
|
messages: OpenClawCompatibleMessage[];
|
|
17
18
|
estimatedTokens: number;
|
|
18
19
|
systemPromptAddition: string;
|
|
20
|
+
promptAuthority: OpenClawCompatiblePromptAuthority;
|
|
19
21
|
debug?: AssembleContextInternalResponse["debug"];
|
|
20
22
|
};
|
|
21
23
|
type OpenClawCompatibleCompactResult = {
|
package/dist/context-engine.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resolveIdentity } from "./identity.js";
|
|
2
2
|
import { resolveUserCollection } from "./memory-scopes.js";
|
|
3
3
|
const APPROX_CHARS_PER_TOKEN = 4;
|
|
4
|
+
const PROMPT_AUTHORITY_PREASSEMBLY_MAY_OVERFLOW = "preassembly_may_overflow";
|
|
4
5
|
const ASSEMBLE_BUDGET_HEADROOM_TOKENS = 256;
|
|
5
6
|
const ASSEMBLE_BUDGET_HEADROOM_FRACTION = 0.2;
|
|
6
7
|
const DEFAULT_COMPACTION_THRESHOLD_FRACTION = 0.8;
|
|
@@ -10,6 +11,7 @@ const QUOTED_PHRASE_RE = /"([^"]{4,})"|'([^']{4,})'/g;
|
|
|
10
11
|
const EXACT_RECALL_SEARCH_K = 32;
|
|
11
12
|
const EXACT_RECALL_MAX_TOKENS = 4;
|
|
12
13
|
const RESERVED_CURRENT_TURN_TOKENS = 150;
|
|
14
|
+
const AFTER_TURN_INGEST_MAX_TOKENS = 2048;
|
|
13
15
|
const COMMON_QUERY_WORDS = new Set([
|
|
14
16
|
"what", "does", "mean", "remember", "recall", "about", "this", "that",
|
|
15
17
|
"the", "and", "for", "with", "from", "your", "have", "been", "were",
|
|
@@ -226,6 +228,18 @@ function trimMessagesToBudget(messages, tokenBudget) {
|
|
|
226
228
|
}
|
|
227
229
|
return [{ ...last, content: truncated }];
|
|
228
230
|
}
|
|
231
|
+
function boundAfterTurnMessagesForIngest(messages, logger, sessionId) {
|
|
232
|
+
const estimatedTokens = approximateMessagesTokens(messages);
|
|
233
|
+
if (estimatedTokens <= AFTER_TURN_INGEST_MAX_TOKENS) {
|
|
234
|
+
return messages;
|
|
235
|
+
}
|
|
236
|
+
const bounded = trimMessagesToBudget(messages, AFTER_TURN_INGEST_MAX_TOKENS)
|
|
237
|
+
.map((message) => normalizeKernelMessage(message));
|
|
238
|
+
logger.warn?.(`LibraVDB afterTurn trimmed oversized ingest payload sessionId=${sessionId} ` +
|
|
239
|
+
`estimatedTokens=${estimatedTokens} maxTokens=${AFTER_TURN_INGEST_MAX_TOKENS} ` +
|
|
240
|
+
`forwardedMessages=${bounded.length}`);
|
|
241
|
+
return bounded;
|
|
242
|
+
}
|
|
229
243
|
function enforceTokenBudgetInvariant(result, tokenBudget) {
|
|
230
244
|
if (typeof tokenBudget !== "number" || !Number.isFinite(tokenBudget) || tokenBudget <= 0) {
|
|
231
245
|
return result;
|
|
@@ -262,11 +276,19 @@ function buildBudgetFallbackContext(messages, tokenBudget) {
|
|
|
262
276
|
messages: fallbackMessages,
|
|
263
277
|
estimatedTokens: approximateMessagesTokens(fallbackMessages),
|
|
264
278
|
systemPromptAddition: "",
|
|
279
|
+
promptAuthority: PROMPT_AUTHORITY_PREASSEMBLY_MAY_OVERFLOW,
|
|
265
280
|
};
|
|
266
281
|
}
|
|
267
282
|
function resolvePredictiveCompactionTokenCount(args) {
|
|
268
|
-
|
|
269
|
-
|
|
283
|
+
const currentTokenCount = normalizeCurrentTokenCount(args.currentTokenCount);
|
|
284
|
+
const sourcePressureEstimate = normalizeCurrentTokenCount(approximateMessagesTokens(args.messages) + approximateTokenCount(args.prompt ?? ""));
|
|
285
|
+
if (currentTokenCount == null) {
|
|
286
|
+
return sourcePressureEstimate ?? 1;
|
|
287
|
+
}
|
|
288
|
+
if (sourcePressureEstimate == null) {
|
|
289
|
+
return currentTokenCount;
|
|
290
|
+
}
|
|
291
|
+
return Math.max(currentTokenCount, sourcePressureEstimate);
|
|
270
292
|
}
|
|
271
293
|
function resolveAfterTurnPredictiveCompactionTokenCount(args) {
|
|
272
294
|
const currentTokenCount = normalizeCurrentTokenCount(args.currentTokenCount);
|
|
@@ -516,6 +538,7 @@ export function normalizeAssembleResult(result) {
|
|
|
516
538
|
messages,
|
|
517
539
|
estimatedTokens: typeof result.estimatedTokens === "number" ? result.estimatedTokens : 0,
|
|
518
540
|
systemPromptAddition: typeof result.systemPromptAddition === "string" ? result.systemPromptAddition : "",
|
|
541
|
+
promptAuthority: PROMPT_AUTHORITY_PREASSEMBLY_MAY_OVERFLOW,
|
|
519
542
|
...(result.debug != null ? { debug: result.debug } : {}),
|
|
520
543
|
};
|
|
521
544
|
}
|
|
@@ -902,6 +925,7 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
902
925
|
});
|
|
903
926
|
const afterTurnMessages = selectAfterTurnMessages(args.messages, args.prePromptMessageCount, logger);
|
|
904
927
|
const messages = normalizeKernelMessages(afterTurnMessages);
|
|
928
|
+
const ingestMessages = boundAfterTurnMessagesForIngest(messages, logger, sessionId);
|
|
905
929
|
const msgCount = messages.length;
|
|
906
930
|
logger.info?.(`LibraVDB afterTurn sessionId=${sessionId} userId=${userId} ` +
|
|
907
931
|
`messageCount=${msgCount} totalMessages=${args.messages.length} ` +
|
|
@@ -916,7 +940,7 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
916
940
|
sessionId,
|
|
917
941
|
sessionKey: args.sessionKey,
|
|
918
942
|
userId,
|
|
919
|
-
messages,
|
|
943
|
+
messages: ingestMessages,
|
|
920
944
|
isHeartbeat: args.isHeartbeat,
|
|
921
945
|
});
|
|
922
946
|
await performAfterTurnPredictiveCompaction({
|
package/dist/index.js
CHANGED
|
@@ -26516,6 +26516,7 @@ function resolveCliMemoryOperationScope(opts) {
|
|
|
26516
26516
|
|
|
26517
26517
|
// src/context-engine.ts
|
|
26518
26518
|
var APPROX_CHARS_PER_TOKEN = 4;
|
|
26519
|
+
var PROMPT_AUTHORITY_PREASSEMBLY_MAY_OVERFLOW = "preassembly_may_overflow";
|
|
26519
26520
|
var ASSEMBLE_BUDGET_HEADROOM_TOKENS = 256;
|
|
26520
26521
|
var ASSEMBLE_BUDGET_HEADROOM_FRACTION = 0.2;
|
|
26521
26522
|
var DEFAULT_COMPACTION_THRESHOLD_FRACTION = 0.8;
|
|
@@ -26525,6 +26526,7 @@ var QUOTED_PHRASE_RE = /"([^"]{4,})"|'([^']{4,})'/g;
|
|
|
26525
26526
|
var EXACT_RECALL_SEARCH_K = 32;
|
|
26526
26527
|
var EXACT_RECALL_MAX_TOKENS = 4;
|
|
26527
26528
|
var RESERVED_CURRENT_TURN_TOKENS = 150;
|
|
26529
|
+
var AFTER_TURN_INGEST_MAX_TOKENS = 2048;
|
|
26528
26530
|
var COMMON_QUERY_WORDS = /* @__PURE__ */ new Set([
|
|
26529
26531
|
"what",
|
|
26530
26532
|
"does",
|
|
@@ -26749,6 +26751,17 @@ function trimMessagesToBudget(messages, tokenBudget) {
|
|
|
26749
26751
|
}
|
|
26750
26752
|
return [{ ...last, content: truncated }];
|
|
26751
26753
|
}
|
|
26754
|
+
function boundAfterTurnMessagesForIngest(messages, logger, sessionId) {
|
|
26755
|
+
const estimatedTokens = approximateMessagesTokens(messages);
|
|
26756
|
+
if (estimatedTokens <= AFTER_TURN_INGEST_MAX_TOKENS) {
|
|
26757
|
+
return messages;
|
|
26758
|
+
}
|
|
26759
|
+
const bounded = trimMessagesToBudget(messages, AFTER_TURN_INGEST_MAX_TOKENS).map((message) => normalizeKernelMessage(message));
|
|
26760
|
+
logger.warn?.(
|
|
26761
|
+
`LibraVDB afterTurn trimmed oversized ingest payload sessionId=${sessionId} estimatedTokens=${estimatedTokens} maxTokens=${AFTER_TURN_INGEST_MAX_TOKENS} forwardedMessages=${bounded.length}`
|
|
26762
|
+
);
|
|
26763
|
+
return bounded;
|
|
26764
|
+
}
|
|
26752
26765
|
function enforceTokenBudgetInvariant(result, tokenBudget) {
|
|
26753
26766
|
if (typeof tokenBudget !== "number" || !Number.isFinite(tokenBudget) || tokenBudget <= 0) {
|
|
26754
26767
|
return result;
|
|
@@ -26787,11 +26800,22 @@ function buildBudgetFallbackContext(messages, tokenBudget) {
|
|
|
26787
26800
|
return {
|
|
26788
26801
|
messages: fallbackMessages,
|
|
26789
26802
|
estimatedTokens: approximateMessagesTokens(fallbackMessages),
|
|
26790
|
-
systemPromptAddition: ""
|
|
26803
|
+
systemPromptAddition: "",
|
|
26804
|
+
promptAuthority: PROMPT_AUTHORITY_PREASSEMBLY_MAY_OVERFLOW
|
|
26791
26805
|
};
|
|
26792
26806
|
}
|
|
26793
26807
|
function resolvePredictiveCompactionTokenCount(args) {
|
|
26794
|
-
|
|
26808
|
+
const currentTokenCount = normalizeCurrentTokenCount(args.currentTokenCount);
|
|
26809
|
+
const sourcePressureEstimate = normalizeCurrentTokenCount(
|
|
26810
|
+
approximateMessagesTokens(args.messages) + approximateTokenCount(args.prompt ?? "")
|
|
26811
|
+
);
|
|
26812
|
+
if (currentTokenCount == null) {
|
|
26813
|
+
return sourcePressureEstimate ?? 1;
|
|
26814
|
+
}
|
|
26815
|
+
if (sourcePressureEstimate == null) {
|
|
26816
|
+
return currentTokenCount;
|
|
26817
|
+
}
|
|
26818
|
+
return Math.max(currentTokenCount, sourcePressureEstimate);
|
|
26795
26819
|
}
|
|
26796
26820
|
function resolveAfterTurnPredictiveCompactionTokenCount(args) {
|
|
26797
26821
|
const currentTokenCount = normalizeCurrentTokenCount(args.currentTokenCount);
|
|
@@ -27031,6 +27055,7 @@ function normalizeAssembleResult(result) {
|
|
|
27031
27055
|
messages,
|
|
27032
27056
|
estimatedTokens: typeof result.estimatedTokens === "number" ? result.estimatedTokens : 0,
|
|
27033
27057
|
systemPromptAddition: typeof result.systemPromptAddition === "string" ? result.systemPromptAddition : "",
|
|
27058
|
+
promptAuthority: PROMPT_AUTHORITY_PREASSEMBLY_MAY_OVERFLOW,
|
|
27034
27059
|
...result.debug != null ? { debug: result.debug } : {}
|
|
27035
27060
|
};
|
|
27036
27061
|
}
|
|
@@ -27416,6 +27441,7 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
27416
27441
|
});
|
|
27417
27442
|
const afterTurnMessages = selectAfterTurnMessages(args.messages, args.prePromptMessageCount, logger);
|
|
27418
27443
|
const messages = normalizeKernelMessages(afterTurnMessages);
|
|
27444
|
+
const ingestMessages = boundAfterTurnMessagesForIngest(messages, logger, sessionId);
|
|
27419
27445
|
const msgCount = messages.length;
|
|
27420
27446
|
logger.info?.(
|
|
27421
27447
|
`LibraVDB afterTurn sessionId=${sessionId} userId=${userId} messageCount=${msgCount} totalMessages=${args.messages.length} prePromptMessageCount=${args.prePromptMessageCount ?? "unknown"} heartbeat=${args.isHeartbeat ?? false}`
|
|
@@ -27429,7 +27455,7 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
27429
27455
|
sessionId,
|
|
27430
27456
|
sessionKey: args.sessionKey,
|
|
27431
27457
|
userId,
|
|
27432
|
-
messages,
|
|
27458
|
+
messages: ingestMessages,
|
|
27433
27459
|
isHeartbeat: args.isHeartbeat
|
|
27434
27460
|
});
|
|
27435
27461
|
await performAfterTurnPredictiveCompaction({
|
|
@@ -36578,6 +36604,55 @@ function resolveClientEndpoint(configuredEndpoint) {
|
|
|
36578
36604
|
}
|
|
36579
36605
|
return `unix:${path3.join(os3.homedir(), ".libravdbd", "run", sockName)}`;
|
|
36580
36606
|
}
|
|
36607
|
+
function isLegacyJsonRpcHealthResponse(payload) {
|
|
36608
|
+
try {
|
|
36609
|
+
const parsed = JSON.parse(payload.trim());
|
|
36610
|
+
return parsed.jsonrpc === "2.0" && parsed.result?.ok === true;
|
|
36611
|
+
} catch {
|
|
36612
|
+
return false;
|
|
36613
|
+
}
|
|
36614
|
+
}
|
|
36615
|
+
async function detectLegacyJsonRpcDaemon(endpoint, timeoutMs = 500) {
|
|
36616
|
+
if (!endpoint.startsWith("unix:")) {
|
|
36617
|
+
return false;
|
|
36618
|
+
}
|
|
36619
|
+
const socketPath = endpoint.slice(5);
|
|
36620
|
+
if (!socketPath) {
|
|
36621
|
+
return false;
|
|
36622
|
+
}
|
|
36623
|
+
return await new Promise((resolve) => {
|
|
36624
|
+
let settled = false;
|
|
36625
|
+
let response = "";
|
|
36626
|
+
const socket = net.createConnection(socketPath);
|
|
36627
|
+
const finish = (value) => {
|
|
36628
|
+
if (settled) {
|
|
36629
|
+
return;
|
|
36630
|
+
}
|
|
36631
|
+
settled = true;
|
|
36632
|
+
clearTimeout(timer);
|
|
36633
|
+
socket.removeAllListeners();
|
|
36634
|
+
socket.destroy();
|
|
36635
|
+
resolve(value);
|
|
36636
|
+
};
|
|
36637
|
+
const timer = setTimeout(() => finish(false), Math.max(1, timeoutMs));
|
|
36638
|
+
timer.unref?.();
|
|
36639
|
+
socket.setEncoding("utf8");
|
|
36640
|
+
socket.on("connect", () => {
|
|
36641
|
+
socket.write('{"jsonrpc":"2.0","id":1,"method":"health","params":{}}\n');
|
|
36642
|
+
});
|
|
36643
|
+
socket.on("data", (chunk) => {
|
|
36644
|
+
response += chunk;
|
|
36645
|
+
if (isLegacyJsonRpcHealthResponse(response)) {
|
|
36646
|
+
finish(true);
|
|
36647
|
+
} else if (response.length > 4096) {
|
|
36648
|
+
finish(false);
|
|
36649
|
+
}
|
|
36650
|
+
});
|
|
36651
|
+
socket.on("end", () => finish(isLegacyJsonRpcHealthResponse(response)));
|
|
36652
|
+
socket.on("close", () => finish(isLegacyJsonRpcHealthResponse(response)));
|
|
36653
|
+
socket.on("error", () => finish(false));
|
|
36654
|
+
});
|
|
36655
|
+
}
|
|
36581
36656
|
function createRpcMutex() {
|
|
36582
36657
|
return {
|
|
36583
36658
|
current: Promise.resolve(),
|
|
@@ -36636,11 +36711,15 @@ function createAuthInterceptor(state) {
|
|
|
36636
36711
|
var LibravDBClient = class {
|
|
36637
36712
|
client;
|
|
36638
36713
|
secret;
|
|
36714
|
+
endpoint;
|
|
36715
|
+
legacyProbeTimeoutMs;
|
|
36639
36716
|
nonceHex;
|
|
36640
36717
|
closed = false;
|
|
36641
36718
|
constructor(options = {}) {
|
|
36642
36719
|
this.secret = options.secret ?? loadSecretFromEnv();
|
|
36643
36720
|
const rawEndpoint = resolveClientEndpoint(options.endpoint);
|
|
36721
|
+
this.endpoint = rawEndpoint;
|
|
36722
|
+
this.legacyProbeTimeoutMs = Math.min(options.timeoutMs ?? 3e4, 1e3);
|
|
36644
36723
|
const isUnix = rawEndpoint.startsWith("unix:");
|
|
36645
36724
|
const socketPath = isUnix ? rawEndpoint.slice(5) : void 0;
|
|
36646
36725
|
const credMode = resolveCredentialMode(rawEndpoint, options.tlsMode);
|
|
@@ -36696,8 +36775,14 @@ var LibravDBClient = class {
|
|
|
36696
36775
|
}
|
|
36697
36776
|
);
|
|
36698
36777
|
} catch (error2) {
|
|
36778
|
+
const detail = error2 instanceof Error ? error2.message : String(error2);
|
|
36779
|
+
if (detail.includes("Protocol error") && await detectLegacyJsonRpcDaemon(this.endpoint, this.legacyProbeTimeoutMs)) {
|
|
36780
|
+
throw new Error(
|
|
36781
|
+
`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.`
|
|
36782
|
+
);
|
|
36783
|
+
}
|
|
36699
36784
|
throw new Error(
|
|
36700
|
-
`LibraVDB: failed to handshake with daemon: ${
|
|
36785
|
+
`LibraVDB: failed to handshake with daemon: ${detail}`
|
|
36701
36786
|
);
|
|
36702
36787
|
}
|
|
36703
36788
|
}
|
|
@@ -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