@xdarkicex/openclaw-memory-libravdb 1.4.14 → 1.4.16
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 +1 -0
- package/dist/context-engine.js +135 -25
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/context-engine.d.ts
CHANGED
package/dist/context-engine.js
CHANGED
|
@@ -30,15 +30,6 @@ function normalizeCompactResult(response) {
|
|
|
30
30
|
},
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
function describeUnexpectedContent(value) {
|
|
34
|
-
try {
|
|
35
|
-
const serialized = JSON.stringify(value);
|
|
36
|
-
return serialized === undefined ? String(value) : serialized;
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
return String(value);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
33
|
function stringifyKernelBlock(block) {
|
|
43
34
|
if (!block || typeof block !== "object") {
|
|
44
35
|
return "";
|
|
@@ -69,10 +60,6 @@ function stringifyKernelBlock(block) {
|
|
|
69
60
|
case "image":
|
|
70
61
|
return "[image omitted]";
|
|
71
62
|
default:
|
|
72
|
-
console.warn("[libravdb] unsupported kernel content block", {
|
|
73
|
-
type: record.type,
|
|
74
|
-
block: describeUnexpectedContent(record),
|
|
75
|
-
});
|
|
76
63
|
return typeof record.text === "string" ? record.text : "";
|
|
77
64
|
}
|
|
78
65
|
}
|
|
@@ -81,10 +68,6 @@ function normalizeKernelContent(content) {
|
|
|
81
68
|
return content;
|
|
82
69
|
}
|
|
83
70
|
if (!Array.isArray(content)) {
|
|
84
|
-
console.warn("[libravdb] unexpected kernel content shape", {
|
|
85
|
-
kind: typeof content,
|
|
86
|
-
value: describeUnexpectedContent(content),
|
|
87
|
-
});
|
|
88
71
|
return "";
|
|
89
72
|
}
|
|
90
73
|
return content.map(stringifyKernelBlock).filter((part) => part.length > 0).join("\n");
|
|
@@ -101,6 +84,14 @@ function approximateMessageTokens(message) {
|
|
|
101
84
|
function approximateMessagesTokens(messages) {
|
|
102
85
|
return messages.reduce((sum, message) => sum + approximateMessageTokens(message), 0);
|
|
103
86
|
}
|
|
87
|
+
function normalizeCurrentTokenCount(currentTokenCount) {
|
|
88
|
+
if (typeof currentTokenCount !== "number" ||
|
|
89
|
+
!Number.isFinite(currentTokenCount) ||
|
|
90
|
+
currentTokenCount <= 0) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
return Math.max(1, Math.floor(currentTokenCount));
|
|
94
|
+
}
|
|
104
95
|
function normalizeTokenBudget(tokenBudget) {
|
|
105
96
|
if (typeof tokenBudget !== "number" || !Number.isFinite(tokenBudget) || tokenBudget <= 0) {
|
|
106
97
|
return undefined;
|
|
@@ -128,6 +119,33 @@ function resolveDynamicCompactThreshold(tokenBudget, compactThreshold, compactio
|
|
|
128
119
|
const fraction = normalizeThresholdFraction(compactionThresholdFraction);
|
|
129
120
|
return Math.max(1, Math.floor(normalizedBudget * fraction));
|
|
130
121
|
}
|
|
122
|
+
function resolvePredictiveCompactionTarget(params) {
|
|
123
|
+
const currentTokenCount = normalizeCurrentTokenCount(params.currentTokenCount);
|
|
124
|
+
const threshold = normalizeTokenBudget(params.threshold);
|
|
125
|
+
if (currentTokenCount == null || threshold == null || currentTokenCount < threshold) {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
const belowThresholdTarget = Math.max(1, threshold - 1);
|
|
129
|
+
return belowThresholdTarget < currentTokenCount
|
|
130
|
+
? belowThresholdTarget
|
|
131
|
+
: Math.max(1, currentTokenCount - 1);
|
|
132
|
+
}
|
|
133
|
+
function logPredictiveCompactionAttempt(params) {
|
|
134
|
+
params.logger.info?.(`LibraVDB predictive compaction trigger phase=${params.phase} sessionId=${params.sessionId} ` +
|
|
135
|
+
`currentTokenCount=${params.currentTokenCount} threshold=${params.threshold} ` +
|
|
136
|
+
`targetSize=${params.targetSize} tokenBudget=${params.tokenBudget ?? "unknown"}`);
|
|
137
|
+
}
|
|
138
|
+
function logPredictiveCompactionOutcome(params) {
|
|
139
|
+
const message = `LibraVDB predictive compaction ${params.compacted ? "completed" : "did not compact"} ` +
|
|
140
|
+
`phase=${params.phase} sessionId=${params.sessionId} currentTokenCount=${params.currentTokenCount} ` +
|
|
141
|
+
`threshold=${params.threshold} targetSize=${params.targetSize} tokenBudget=${params.tokenBudget ?? "unknown"}` +
|
|
142
|
+
(params.reason ? ` reason=${params.reason}` : "");
|
|
143
|
+
if (params.compacted) {
|
|
144
|
+
params.logger.info?.(message);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
params.logger.warn?.(message);
|
|
148
|
+
}
|
|
131
149
|
function truncateContentToTokenBudget(content, tokenBudget) {
|
|
132
150
|
if (tokenBudget <= 0)
|
|
133
151
|
return "";
|
|
@@ -191,6 +209,10 @@ function buildBudgetFallbackContext(messages, tokenBudget) {
|
|
|
191
209
|
systemPromptAddition: "",
|
|
192
210
|
};
|
|
193
211
|
}
|
|
212
|
+
function resolvePredictiveCompactionTokenCount(args) {
|
|
213
|
+
return (normalizeCurrentTokenCount(args.currentTokenCount) ??
|
|
214
|
+
approximateMessagesTokens(args.messages) + approximateTokenCount(args.prompt ?? ""));
|
|
215
|
+
}
|
|
194
216
|
export function normalizeKernelMessage(message) {
|
|
195
217
|
return {
|
|
196
218
|
role: message.role,
|
|
@@ -263,7 +285,12 @@ export function buildContextEngineFactory(runtime, cfg, recallCache, logger = co
|
|
|
263
285
|
sessionId: requireSessionId(args.sessionId, "compact"),
|
|
264
286
|
force: args.force,
|
|
265
287
|
...(typeof targetSize === "number" ? { targetSize } : {}),
|
|
266
|
-
...(
|
|
288
|
+
...(() => {
|
|
289
|
+
const normalizedCurrentTokenCount = normalizeCurrentTokenCount(args.currentTokenCount);
|
|
290
|
+
return normalizedCurrentTokenCount != null
|
|
291
|
+
? { currentTokenCount: normalizedCurrentTokenCount }
|
|
292
|
+
: {};
|
|
293
|
+
})(),
|
|
267
294
|
...(typeof cfg.continuityMinTurns === "number"
|
|
268
295
|
? { continuityMinTurns: cfg.continuityMinTurns }
|
|
269
296
|
: {}),
|
|
@@ -293,6 +320,45 @@ export function buildContextEngineFactory(runtime, cfg, recallCache, logger = co
|
|
|
293
320
|
};
|
|
294
321
|
}
|
|
295
322
|
}
|
|
323
|
+
async function performAfterTurnPredictiveCompaction(args) {
|
|
324
|
+
const dynamicCompactThreshold = getDynamicCompactThreshold(args.tokenBudget);
|
|
325
|
+
const predictiveTargetSize = resolvePredictiveCompactionTarget({
|
|
326
|
+
currentTokenCount: args.currentTokenCount,
|
|
327
|
+
threshold: dynamicCompactThreshold,
|
|
328
|
+
});
|
|
329
|
+
if (args.currentTokenCount == null ||
|
|
330
|
+
dynamicCompactThreshold == null ||
|
|
331
|
+
predictiveTargetSize == null) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
logPredictiveCompactionAttempt({
|
|
335
|
+
logger,
|
|
336
|
+
phase: "afterTurn",
|
|
337
|
+
sessionId: args.sessionId,
|
|
338
|
+
currentTokenCount: args.currentTokenCount,
|
|
339
|
+
threshold: dynamicCompactThreshold,
|
|
340
|
+
targetSize: predictiveTargetSize,
|
|
341
|
+
tokenBudget: args.tokenBudget,
|
|
342
|
+
});
|
|
343
|
+
const compactionResult = await runCompaction({
|
|
344
|
+
sessionId: args.sessionId,
|
|
345
|
+
targetSize: predictiveTargetSize,
|
|
346
|
+
tokenBudget: args.tokenBudget,
|
|
347
|
+
force: true,
|
|
348
|
+
currentTokenCount: args.currentTokenCount,
|
|
349
|
+
});
|
|
350
|
+
logPredictiveCompactionOutcome({
|
|
351
|
+
logger,
|
|
352
|
+
phase: "afterTurn",
|
|
353
|
+
sessionId: args.sessionId,
|
|
354
|
+
currentTokenCount: args.currentTokenCount,
|
|
355
|
+
threshold: dynamicCompactThreshold,
|
|
356
|
+
targetSize: predictiveTargetSize,
|
|
357
|
+
tokenBudget: args.tokenBudget,
|
|
358
|
+
compacted: compactionResult.compacted,
|
|
359
|
+
reason: compactionResult.reason,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
296
362
|
return {
|
|
297
363
|
info: { id: "libravdb-memory", name: "LibraVDB Memory", ownsCompaction: true },
|
|
298
364
|
ownsCompaction: true,
|
|
@@ -337,18 +403,47 @@ export function buildContextEngineFactory(runtime, cfg, recallCache, logger = co
|
|
|
337
403
|
},
|
|
338
404
|
async assemble(args) {
|
|
339
405
|
const messages = normalizeKernelMessages(args.messages);
|
|
340
|
-
const currentContextTokens =
|
|
406
|
+
const currentContextTokens = resolvePredictiveCompactionTokenCount({
|
|
407
|
+
currentTokenCount: args.currentTokenCount,
|
|
408
|
+
messages,
|
|
409
|
+
prompt: args.prompt,
|
|
410
|
+
});
|
|
341
411
|
const dynamicCompactThreshold = getDynamicCompactThreshold(args.tokenBudget);
|
|
342
|
-
|
|
343
|
-
currentContextTokens
|
|
412
|
+
const predictiveTargetSize = resolvePredictiveCompactionTarget({
|
|
413
|
+
currentTokenCount: currentContextTokens,
|
|
414
|
+
threshold: dynamicCompactThreshold,
|
|
415
|
+
});
|
|
416
|
+
if (dynamicCompactThreshold != null && predictiveTargetSize != null) {
|
|
417
|
+
logPredictiveCompactionAttempt({
|
|
418
|
+
logger,
|
|
419
|
+
phase: "assemble",
|
|
420
|
+
sessionId: args.sessionId,
|
|
421
|
+
currentTokenCount: currentContextTokens,
|
|
422
|
+
threshold: dynamicCompactThreshold,
|
|
423
|
+
targetSize: predictiveTargetSize,
|
|
424
|
+
tokenBudget: args.tokenBudget,
|
|
425
|
+
});
|
|
344
426
|
const compactionResult = await runCompaction({
|
|
345
427
|
sessionId: args.sessionId,
|
|
428
|
+
targetSize: predictiveTargetSize,
|
|
346
429
|
tokenBudget: args.tokenBudget,
|
|
347
430
|
force: true,
|
|
348
431
|
currentTokenCount: currentContextTokens,
|
|
349
432
|
});
|
|
350
|
-
|
|
351
|
-
logger
|
|
433
|
+
logPredictiveCompactionOutcome({
|
|
434
|
+
logger,
|
|
435
|
+
phase: "assemble",
|
|
436
|
+
sessionId: args.sessionId,
|
|
437
|
+
currentTokenCount: currentContextTokens,
|
|
438
|
+
threshold: dynamicCompactThreshold,
|
|
439
|
+
targetSize: predictiveTargetSize,
|
|
440
|
+
tokenBudget: args.tokenBudget,
|
|
441
|
+
compacted: compactionResult.compacted,
|
|
442
|
+
reason: compactionResult.reason,
|
|
443
|
+
});
|
|
444
|
+
if (!compactionResult.ok) {
|
|
445
|
+
logger.warn?.(`LibraVDB predictive compaction blocked assemble path at ${currentContextTokens} tokens ` +
|
|
446
|
+
`(threshold=${dynamicCompactThreshold}): ${compactionResult.reason ?? "compaction failed"}`);
|
|
352
447
|
return buildBudgetFallbackContext(messages, args.tokenBudget);
|
|
353
448
|
}
|
|
354
449
|
}
|
|
@@ -396,8 +491,11 @@ export function buildContextEngineFactory(runtime, cfg, recallCache, logger = co
|
|
|
396
491
|
async afterTurn(args) {
|
|
397
492
|
const messages = normalizeKernelMessages(args.messages);
|
|
398
493
|
const kernel = runtime.getKernel();
|
|
494
|
+
const currentTokenCount = normalizeCurrentTokenCount(typeof args.runtimeContext?.currentTokenCount === "number"
|
|
495
|
+
? args.runtimeContext.currentTokenCount
|
|
496
|
+
: undefined);
|
|
399
497
|
if (kernel) {
|
|
400
|
-
|
|
498
|
+
const result = await kernel.afterTurn({
|
|
401
499
|
sessionId: args.sessionId,
|
|
402
500
|
sessionKey: args.sessionKey,
|
|
403
501
|
userId: args.userId,
|
|
@@ -405,12 +503,24 @@ export function buildContextEngineFactory(runtime, cfg, recallCache, logger = co
|
|
|
405
503
|
prePromptMessageCount: args.prePromptMessageCount,
|
|
406
504
|
isHeartbeat: args.isHeartbeat,
|
|
407
505
|
});
|
|
506
|
+
await performAfterTurnPredictiveCompaction({
|
|
507
|
+
sessionId: args.sessionId,
|
|
508
|
+
tokenBudget: args.tokenBudget,
|
|
509
|
+
currentTokenCount,
|
|
510
|
+
});
|
|
511
|
+
return result;
|
|
408
512
|
}
|
|
409
513
|
const rpc = await runtime.getRpc();
|
|
410
|
-
|
|
514
|
+
const result = await rpc.call("after_turn_kernel", {
|
|
411
515
|
...args,
|
|
412
516
|
messages,
|
|
413
517
|
});
|
|
518
|
+
await performAfterTurnPredictiveCompaction({
|
|
519
|
+
sessionId: args.sessionId,
|
|
520
|
+
tokenBudget: args.tokenBudget,
|
|
521
|
+
currentTokenCount,
|
|
522
|
+
});
|
|
523
|
+
return result;
|
|
414
524
|
}
|
|
415
525
|
};
|
|
416
526
|
}
|
package/openclaw.plugin.json
CHANGED