@xdarkicex/openclaw-memory-libravdb 1.5.4 → 1.6.0

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/cli.js CHANGED
@@ -156,9 +156,9 @@ async function runStatus(runtime, cfg, logger, opts = {}) {
156
156
  }
157
157
  }
158
158
  try {
159
- const rpc = await runtime.getRpc();
160
- const status = await rpc.call("status", {});
161
- const deep = opts.deep ? await runDeepStatusProbe(rpc, cfg) : undefined;
159
+ const client = await runtime.getClient();
160
+ const status = await client.status({});
161
+ const deep = opts.deep ? await runDeepStatusProbe(client, cfg) : undefined;
162
162
  if (opts.json) {
163
163
  console.log(JSON.stringify({ status, ...(deep ? { deep } : {}) }, null, 2));
164
164
  if (deep && !deep.ok) {
@@ -208,7 +208,7 @@ async function runStatus(runtime, cfg, logger, opts = {}) {
208
208
  }
209
209
  }
210
210
  const AUTHORED_STATUS_COLLECTIONS = ["authored:hard", "authored:soft", "authored:variant"];
211
- async function runDeepStatusProbe(rpc, cfg) {
211
+ async function runDeepStatusProbe(client, cfg) {
212
212
  // Resolve userId without triggering auto-derive file writes.
213
213
  // status --deep should be read-only; if no userId is configured and no
214
214
  // identity file exists, fall back to "default" rather than creating one.
@@ -233,7 +233,7 @@ async function runDeepStatusProbe(rpc, cfg) {
233
233
  const allCollections = [...AUTHORED_STATUS_COLLECTIONS, ...durableCollections];
234
234
  for (const collection of allCollections) {
235
235
  try {
236
- const result = await rpc.call("search_text", {
236
+ const result = await client.searchText({
237
237
  collection,
238
238
  text: "memory",
239
239
  k: 1,
@@ -280,13 +280,11 @@ async function runIndex(runtime, cfg, opts, logger, params = {}) {
280
280
  .map((c) => c.trim())
281
281
  .filter((c) => c.length > 0);
282
282
  try {
283
- const rpc = await runtime.getRpc();
284
- const result = await rpc.call("rebuild_index", {
283
+ const client = await runtime.getClient();
284
+ const result = await client.rebuildIndex({
285
285
  namespace: namespace ?? "",
286
286
  ...(collections?.length ? { collections } : {}),
287
- }, {
288
- timeoutMs: resolveIndexRebuildTimeoutMs(cfg),
289
- });
287
+ }, { timeoutMs: resolveIndexRebuildTimeoutMs(cfg) });
290
288
  if (!params.quiet) {
291
289
  console.log(`Collections processed: ${result.collectionsProcessed ?? 0}`);
292
290
  console.log(`Records reindexed: ${result.recordsReindexed ?? 0}`);
@@ -332,7 +330,7 @@ async function runSearch(runtime, cfg, queryArg, opts, logger) {
332
330
  return;
333
331
  }
334
332
  try {
335
- const bridge = buildMemoryRuntimeBridge(runtime.getRpc, cfg);
333
+ const bridge = buildMemoryRuntimeBridge(runtime.getClient, cfg);
336
334
  const { manager } = await bridge.getMemorySearchManager({
337
335
  agentId: opts?.agent,
338
336
  });
@@ -379,8 +377,8 @@ async function runFlush(runtime, opts, logger) {
379
377
  }
380
378
  }
381
379
  try {
382
- const rpc = await runtime.getRpc();
383
- await rpc.call("flush_namespace", scope.params);
380
+ const client = await runtime.getClient();
381
+ await client.flushNamespace(scope.params);
384
382
  console.log(`Deleted durable memory namespace ${scope.displayName}.`);
385
383
  }
386
384
  catch (error) {
@@ -396,8 +394,8 @@ async function runExport(runtime, opts, logger) {
396
394
  return;
397
395
  }
398
396
  try {
399
- const rpc = await runtime.getRpc();
400
- const result = await rpc.call("export_memory", scope.params);
397
+ const client = await runtime.getClient();
398
+ const result = await client.exportMemory(scope.params);
401
399
  for (const record of result.records ?? []) {
402
400
  stdout.write(`${JSON.stringify(record)}\n`);
403
401
  }
@@ -418,13 +416,13 @@ async function runJournal(runtime, opts, logger) {
418
416
  return;
419
417
  }
420
418
  try {
421
- const rpc = await runtime.getRpc();
422
- const result = await rpc.call("list_lifecycle_journal", {
419
+ const client = await runtime.getClient();
420
+ const result = await client.listLifecycleJournal({
423
421
  sessionId: opts?.sessionId?.trim() || undefined,
424
422
  limit,
425
423
  });
426
- for (const record of result.results ?? []) {
427
- stdout.write(`${JSON.stringify(record)}\n`);
424
+ for (const entry of result.entries) {
425
+ stdout.write(`${entry}\n`);
428
426
  }
429
427
  }
430
428
  catch (error) {
@@ -441,8 +439,8 @@ async function runDreamPromote(runtime, opts, logger) {
441
439
  return;
442
440
  }
443
441
  try {
444
- const rpc = await runtime.getRpc();
445
- const result = await promoteDreamDiaryFile(rpc, { userId, diaryPath: dreamFile });
442
+ const client = await runtime.getClient();
443
+ const result = await promoteDreamDiaryFile(client, { userId, diaryPath: dreamFile });
446
444
  console.log(`Promoted ${result.promoted ?? 0} dream entr${(result.promoted ?? 0) === 1 ? "y" : "ies"}; rejected ${result.rejected ?? 0}.`);
447
445
  }
448
446
  catch (error) {
@@ -61,7 +61,7 @@ export declare function buildContextEngineFactory(runtime: PluginRuntime, cfg: P
61
61
  sessionId: string;
62
62
  sessionKey?: string;
63
63
  userId?: string;
64
- }): Promise<any>;
64
+ }): Promise<import("@xdarkicex/libravdb-contracts").BootstrapSessionKernelResponse>;
65
65
  ingest(args: {
66
66
  sessionId: string;
67
67
  sessionKey?: string;
@@ -72,7 +72,7 @@ export declare function buildContextEngineFactory(runtime: PluginRuntime, cfg: P
72
72
  id?: string;
73
73
  };
74
74
  isHeartbeat?: boolean;
75
- }): Promise<any>;
75
+ }): Promise<import("@xdarkicex/libravdb-contracts").IngestMessageKernelResponse>;
76
76
  assemble(args: {
77
77
  sessionId: string;
78
78
  sessionKey?: string;
@@ -98,6 +98,6 @@ export declare function buildContextEngineFactory(runtime: PluginRuntime, cfg: P
98
98
  isHeartbeat?: boolean;
99
99
  tokenBudget?: number;
100
100
  runtimeContext?: Record<string, unknown>;
101
- }): Promise<any>;
101
+ }): Promise<import("@xdarkicex/libravdb-contracts").AfterTurnKernelResponse>;
102
102
  };
103
103
  export {};
@@ -420,16 +420,6 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
420
420
  return cachedIdentity.userId;
421
421
  }
422
422
  const getDynamicCompactThreshold = (tokenBudget) => resolveDynamicCompactThreshold(tokenBudget, cfg.compactThreshold, cfg.compactionThresholdFraction);
423
- async function getKernelOrNull(phase) {
424
- try {
425
- return await runtime.getKernel();
426
- }
427
- catch (error) {
428
- logger.warn?.(`LibraVDB ${phase} kernel unavailable, falling back to sidecar: ` +
429
- `${error instanceof Error ? error.message : String(error)}`);
430
- return null;
431
- }
432
- }
433
423
  const buildAssemblyConfig = (tokenBudget) => ({
434
424
  useSessionRecallProjection: cfg.useSessionRecallProjection,
435
425
  useSessionSummarySearchExperiment: cfg.useSessionSummarySearchExperiment,
@@ -483,9 +473,9 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
483
473
  const missingTokens = tokens.filter((token) => !existingBlocks.some((block) => isExactRecallFact(block, token)));
484
474
  if (missingTokens.length === 0)
485
475
  return assembled;
486
- let rpc;
476
+ let client;
487
477
  try {
488
- rpc = await runtime.getRpc();
478
+ client = await runtime.getClient();
489
479
  }
490
480
  catch (error) {
491
481
  logger.warn?.(`LibraVDB exact recall skipped sessionId=${args.sessionId}: ` +
@@ -495,7 +485,7 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
495
485
  const injectedFacts = [];
496
486
  for (const token of missingTokens) {
497
487
  try {
498
- const result = await rpc.call("search_text_collections", {
488
+ const result = await client.searchTextCollections({
499
489
  collections: [resolveUserCollection(args.userId), "global"],
500
490
  text: token,
501
491
  k: Math.max(EXACT_RECALL_SEARCH_K, cfg.topK ?? 0),
@@ -559,30 +549,11 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
559
549
  : {}),
560
550
  };
561
551
  }
562
- function isGrpcAuthConfigured() {
563
- return (typeof process.env.LIBRAVDB_AUTH_SECRET === "string" &&
564
- process.env.LIBRAVDB_AUTH_SECRET.trim().length > 0) || (typeof process.env.LIBRAVDB_AUTH_SECRET_FILE === "string" &&
565
- process.env.LIBRAVDB_AUTH_SECRET_FILE.trim().length > 0);
566
- }
567
- function buildGrpcAuthInitializationError(error) {
568
- const code = typeof error?.code === "number" ||
569
- typeof error?.code === "string"
570
- ? ` code=${String(error.code)}`
571
- : "";
572
- return new Error(`LibraVDB gRPC auth initialization failed${code}; ` +
573
- `check LIBRAVDB_AUTH_SECRET and daemon auth configuration`);
574
- }
575
552
  async function runCompaction(args) {
576
553
  const request = buildCompactSessionRequest(args);
577
- const kernel = await getKernelOrNull("compact");
578
554
  try {
579
- if (kernel) {
580
- return normalizeCompactResult(await kernel.compactSession(request), {
581
- tokensBefore: args.currentTokenCount,
582
- });
583
- }
584
- const rpc = await runtime.getRpc();
585
- return normalizeCompactResult(await rpc.call("compact_session", request), {
555
+ const client = await runtime.getClient();
556
+ return normalizeCompactResult(await client.compactSession(request), {
586
557
  tokensBefore: args.currentTokenCount,
587
558
  });
588
559
  }
@@ -648,30 +619,10 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
648
619
  });
649
620
  logger.info?.(`LibraVDB bootstrap sessionId=${sessionId} userId=${userId} ` +
650
621
  `sessionKey=${args.sessionKey ?? "(none)"}`);
651
- const kernel = await getKernelOrNull("bootstrap");
652
- if (kernel) {
653
- try {
654
- await kernel.initializeSession({
655
- clientId: "openclaw-ts-wrapper",
656
- clientCapabilities: [{ name: "grpc", version: "1.0" }]
657
- });
658
- }
659
- catch (error) {
660
- if (isGrpcAuthConfigured()) {
661
- throw buildGrpcAuthInitializationError(error);
662
- }
663
- // Proceed when the kernel does not require auth and the init call is unavailable.
664
- }
665
- return await kernel.bootstrapSession({
666
- sessionId,
667
- sessionKey: args.sessionKey,
668
- userId,
669
- });
670
- }
671
- const rpc = await runtime.getRpc();
672
- return await rpc.call("bootstrap_session_kernel", {
673
- ...args,
622
+ const client = await runtime.getClient();
623
+ return await client.bootstrapSessionKernel({
674
624
  sessionId,
625
+ sessionKey: args.sessionKey,
675
626
  userId,
676
627
  });
677
628
  },
@@ -686,22 +637,13 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
686
637
  `role=${message.role} heartbeat=${args.isHeartbeat ?? false} ` +
687
638
  `contentLen=${message.content.length}`);
688
639
  try {
689
- const kernel = await getKernelOrNull("ingest");
690
- if (kernel) {
691
- return await kernel.ingestMessage({
692
- sessionId,
693
- sessionKey: args.sessionKey,
694
- userId,
695
- message,
696
- isHeartbeat: args.isHeartbeat,
697
- });
698
- }
699
- const rpc = await runtime.getRpc();
700
- return await rpc.call("ingest_message_kernel", {
701
- ...args,
640
+ const client = await runtime.getClient();
641
+ return await client.ingestMessageKernel({
702
642
  sessionId,
643
+ sessionKey: args.sessionKey,
703
644
  userId,
704
645
  message,
646
+ isHeartbeat: args.isHeartbeat,
705
647
  });
706
648
  }
707
649
  catch (error) {
@@ -761,42 +703,17 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
761
703
  return buildBudgetFallbackContext(args.messages, args.tokenBudget);
762
704
  }
763
705
  }
764
- const kernel = await getKernelOrNull("assemble");
765
- if (kernel) {
766
- try {
767
- const assembled = normalizeAssembleResult(await kernel.assembleContext({
768
- sessionId,
769
- sessionKey: args.sessionKey,
770
- userId,
771
- queryText: args.prompt ?? "",
772
- visibleMessages: messages,
773
- tokenBudget: args.tokenBudget,
774
- config: buildAssemblyConfig(args.tokenBudget),
775
- emitDebug: true,
776
- }));
777
- return enforceTokenBudgetInvariant(await augmentWithExactRecall(assembled, {
778
- queryText: args.prompt ?? messages[messages.length - 1]?.content ?? "",
779
- userId,
780
- sessionId,
781
- tokenBudget: args.tokenBudget,
782
- }), args.tokenBudget);
783
- }
784
- catch (error) {
785
- logger.warn?.(`LibraVDB assemble kernel failed, using budget-clamped fallback context: ${error instanceof Error ? error.message : String(error)}`);
786
- return buildBudgetFallbackContext(args.messages, args.tokenBudget);
787
- }
788
- }
789
- const rpc = await runtime.getRpc();
790
706
  try {
791
- const resp = await rpc.call("assemble_context_internal", {
707
+ const client = await runtime.getClient();
708
+ const resp = await client.assembleContextInternal({
792
709
  sessionId,
793
710
  sessionKey: args.sessionKey,
794
711
  userId,
712
+ prompt: args.prompt ?? "",
795
713
  messages,
796
714
  tokenBudget: args.tokenBudget,
797
- prompt: args.prompt,
798
- emitDebug: true,
799
715
  config: buildAssemblyConfig(args.tokenBudget),
716
+ emitDebug: true,
800
717
  });
801
718
  const assembled = normalizeAssembleResult(resp);
802
719
  const enforced = enforceTokenBudgetInvariant(await augmentWithExactRecall(assembled, {
@@ -814,7 +731,7 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
814
731
  return enforced;
815
732
  }
816
733
  catch (error) {
817
- logger.warn?.(`LibraVDB assemble sidecar failed, using budget-clamped fallback context: ${error instanceof Error ? error.message : String(error)}`);
734
+ logger.warn?.(`LibraVDB assemble failed, using budget-clamped fallback context: ${error instanceof Error ? error.message : String(error)}`);
818
735
  return buildBudgetFallbackContext(args.messages, args.tokenBudget);
819
736
  }
820
737
  },
@@ -835,32 +752,11 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
835
752
  `prePromptMessageCount=${args.prePromptMessageCount ?? "unknown"} ` +
836
753
  `heartbeat=${args.isHeartbeat ?? false}`);
837
754
  try {
838
- const kernel = await getKernelOrNull("afterTurn");
755
+ const client = await runtime.getClient();
839
756
  const currentTokenCount = normalizeCurrentTokenCount(typeof args.runtimeContext?.currentTokenCount === "number"
840
757
  ? args.runtimeContext.currentTokenCount
841
758
  : undefined);
842
- if (kernel) {
843
- const result = await kernel.afterTurn({
844
- sessionId,
845
- sessionKey: args.sessionKey,
846
- userId,
847
- messages,
848
- isHeartbeat: args.isHeartbeat,
849
- });
850
- await performAfterTurnPredictiveCompaction({
851
- sessionId,
852
- messages,
853
- tokenBudget: args.tokenBudget,
854
- currentTokenCount,
855
- });
856
- const predictions = result.predictions;
857
- if (Array.isArray(predictions) && predictions.length > 0) {
858
- predictiveContextCache.set(sessionId, predictions);
859
- }
860
- return result;
861
- }
862
- const rpc = await runtime.getRpc();
863
- const result = await rpc.call("after_turn_kernel", {
759
+ const result = await client.afterTurnKernel({
864
760
  sessionId,
865
761
  sessionKey: args.sessionKey,
866
762
  userId,
@@ -1,11 +1,9 @@
1
1
  import type { LoggerLike, PluginConfig } from "./types.js";
2
+ import type { LibravDBClient } from "./libravdb-client.js";
2
3
  type Disposable = {
3
4
  close(): void;
4
5
  };
5
- interface RpcLike {
6
- call<T>(method: string, params: unknown): Promise<T>;
7
- }
8
- type RpcGetterLike = () => Promise<RpcLike>;
6
+ type ClientGetterLike = () => Promise<LibravDBClient>;
9
7
  interface FsWatcherLike extends Disposable {
10
8
  on(event: "error", handler: (error: Error) => void): void;
11
9
  }
@@ -34,8 +32,8 @@ interface DreamPromotionResult {
34
32
  promoted?: number;
35
33
  rejected?: number;
36
34
  }
37
- export declare function createDreamPromotionHandle(cfg: PluginConfig, getRpc: RpcGetterLike, logger?: LoggerLike, fsApi?: FsApi): DreamPromotionHandle;
38
- export declare function promoteDreamDiaryFile(rpc: RpcLike, opts: {
35
+ export declare function createDreamPromotionHandle(cfg: PluginConfig, getClient: ClientGetterLike, logger?: LoggerLike, fsApi?: FsApi): DreamPromotionHandle;
36
+ export declare function promoteDreamDiaryFile(client: LibravDBClient, opts: {
39
37
  userId: string;
40
38
  diaryPath: string;
41
39
  text?: string;
@@ -10,7 +10,7 @@ const DEFAULT_MIN_RECALL_COUNT = 2;
10
10
  const DEFAULT_MIN_UNIQUE_QUERIES = 2;
11
11
  const DREAM_PROMOTION_VERSION = 1;
12
12
  const DREAM_SOURCE_KIND = "dream";
13
- export function createDreamPromotionHandle(cfg, getRpc, logger = console, fsApi = createRealFsApi()) {
13
+ export function createDreamPromotionHandle(cfg, getClient, logger = console, fsApi = createRealFsApi()) {
14
14
  const userId = cfg.dreamPromotionUserId?.trim() ?? "";
15
15
  if (cfg.dreamPromotionEnabled !== true || !userId) {
16
16
  return {
@@ -110,24 +110,28 @@ export function createDreamPromotionHandle(cfg, getRpc, logger = console, fsApi
110
110
  };
111
111
  return;
112
112
  }
113
- const rpc = await getRpc();
114
- const params = {
113
+ const client = await getClient();
114
+ await client.promoteDreamEntries({
115
115
  userId,
116
116
  sourceDoc: diaryPath,
117
117
  sourceRoot: path.dirname(diaryPath),
118
118
  sourcePath: path.basename(diaryPath),
119
119
  sourceKind: DREAM_SOURCE_KIND,
120
120
  fileHash,
121
- sourceSize: stat.size,
122
- sourceMtimeMs: stat.mtimeMs,
121
+ sourceSize: BigInt(stat.size),
122
+ sourceMtimeMs: BigInt(Math.trunc(stat.mtimeMs)),
123
123
  ingestVersion: DREAM_PROMOTION_VERSION,
124
124
  hashBackend: getHashBackendName(),
125
125
  entries: candidates.map((candidate) => ({
126
- ...candidate,
126
+ text: candidate.text,
127
+ score: candidate.score,
128
+ recallCount: candidate.recallCount,
129
+ uniqueQueries: candidate.uniqueQueries,
130
+ section: candidate.section,
131
+ line: candidate.line,
127
132
  sourceLine: candidate.line,
128
133
  })),
129
- };
130
- await rpc.call("promote_dream_entries", params);
134
+ });
131
135
  lastFileState = {
132
136
  size: stat.size,
133
137
  mtimeMs: stat.mtimeMs,
@@ -177,7 +181,7 @@ export function createDreamPromotionHandle(cfg, getRpc, logger = console, fsApi
177
181
  }
178
182
  }
179
183
  }
180
- export async function promoteDreamDiaryFile(rpc, opts) {
184
+ export async function promoteDreamDiaryFile(client, opts) {
181
185
  const diaryPath = normalizeDiaryPath(opts.diaryPath);
182
186
  if (!diaryPath) {
183
187
  throw new Error("dream diary path is required");
@@ -199,19 +203,24 @@ export async function promoteDreamDiaryFile(rpc, opts) {
199
203
  sourceMtimeMs = sourceMtimeMs ?? stat.mtimeMs;
200
204
  }
201
205
  const candidates = parseDreamPromotionCandidates(text);
202
- return await rpc.call("promote_dream_entries", {
206
+ return await client.promoteDreamEntries({
203
207
  userId,
204
208
  sourceDoc: diaryPath,
205
209
  sourceRoot: path.dirname(diaryPath),
206
210
  sourcePath: path.basename(diaryPath),
207
211
  sourceKind: DREAM_SOURCE_KIND,
208
212
  fileHash: fileHash ?? "",
209
- sourceSize: sourceSize ?? 0,
210
- sourceMtimeMs: sourceMtimeMs ?? 0,
213
+ sourceSize: BigInt(sourceSize ?? 0),
214
+ sourceMtimeMs: BigInt(Math.trunc(sourceMtimeMs ?? 0)),
211
215
  ingestVersion: DREAM_PROMOTION_VERSION,
212
216
  hashBackend: getHashBackendName(),
213
217
  entries: candidates.map((candidate) => ({
214
- ...candidate,
218
+ text: candidate.text,
219
+ score: candidate.score,
220
+ recallCount: candidate.recallCount,
221
+ uniqueQueries: candidate.uniqueQueries,
222
+ section: candidate.section,
223
+ line: candidate.line,
215
224
  sourceLine: candidate.line,
216
225
  })),
217
226
  });