@xdarkicex/openclaw-memory-libravdb 1.9.10-beta.10 → 1.9.10-beta.11
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.js +57 -3
- package/dist/index.js +49 -3
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/context-engine.js
CHANGED
|
@@ -16,6 +16,10 @@ const EXACT_RECALL_MAX_TOKENS = 4;
|
|
|
16
16
|
const RESERVED_CURRENT_TURN_TOKENS = 150;
|
|
17
17
|
const AFTER_TURN_INGEST_MAX_TOKENS = 2048;
|
|
18
18
|
const OPENCLAW_LEADING_TIMESTAMP_PREFIX_RE = /^\[[A-Za-z]{3} \d{4}-\d{2}-\d{2} \d{2}:\d{2}[^\]]*\] */;
|
|
19
|
+
const SELECTED_CONTEXT_HEADER = "Conversation context (untrusted, chronological, selected for current message):";
|
|
20
|
+
const RETRIEVAL_QUERY_MAX_CHARS = 1000;
|
|
21
|
+
const SELECTED_CONTEXT_TURN_RE = /^#\d+\s+[A-Za-z]{3}\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}(?::\d{2})?\s+\S+\s+([^:\n]{1,80}):\s*(.*)$/;
|
|
22
|
+
const ASSISTANT_SPEAKER_RE = /\b(?:assistant|openclaw|z3robot|bot)\b/i;
|
|
19
23
|
const OPENCLAW_METADATA_HEADERS = [
|
|
20
24
|
"Conversation info (untrusted metadata):",
|
|
21
25
|
"Sender (untrusted metadata):",
|
|
@@ -196,6 +200,54 @@ function normalizeKernelContent(content, options = {}) {
|
|
|
196
200
|
retainContext: options.retainOpenClawContext === true,
|
|
197
201
|
});
|
|
198
202
|
}
|
|
203
|
+
function normalizeRetrievalQuery(primaryText, fallbackText = "") {
|
|
204
|
+
const primary = normalizeRetrievalCandidate(primaryText);
|
|
205
|
+
if (primary)
|
|
206
|
+
return primary;
|
|
207
|
+
return normalizeRetrievalCandidate(fallbackText);
|
|
208
|
+
}
|
|
209
|
+
function normalizeRetrievalCandidate(text) {
|
|
210
|
+
const normalized = text
|
|
211
|
+
.replace(OPENCLAW_LEADING_TIMESTAMP_PREFIX_RE, "")
|
|
212
|
+
.replace(/\r\n/g, "\n")
|
|
213
|
+
.trim();
|
|
214
|
+
if (!normalized)
|
|
215
|
+
return "";
|
|
216
|
+
const selected = extractLatestSelectedContextUtterance(normalized);
|
|
217
|
+
const candidate = selected || normalized;
|
|
218
|
+
return capRetrievalQuery(candidate.replace(/\s+/g, " ").trim());
|
|
219
|
+
}
|
|
220
|
+
function extractLatestSelectedContextUtterance(text) {
|
|
221
|
+
if (!text.startsWith(SELECTED_CONTEXT_HEADER))
|
|
222
|
+
return "";
|
|
223
|
+
const turns = [];
|
|
224
|
+
for (const rawLine of text.slice(SELECTED_CONTEXT_HEADER.length).split("\n")) {
|
|
225
|
+
const line = rawLine.trim();
|
|
226
|
+
if (!line)
|
|
227
|
+
continue;
|
|
228
|
+
const match = line.match(SELECTED_CONTEXT_TURN_RE);
|
|
229
|
+
if (match) {
|
|
230
|
+
turns.push({ speaker: match[1].trim(), text: [match[2].trim()] });
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (turns.length > 0) {
|
|
234
|
+
turns[turns.length - 1].text.push(line);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
for (let i = turns.length - 1; i >= 0; i--) {
|
|
238
|
+
const turn = turns[i];
|
|
239
|
+
const content = turn.text.join(" ").trim();
|
|
240
|
+
if (content && !ASSISTANT_SPEAKER_RE.test(turn.speaker)) {
|
|
241
|
+
return content;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return "";
|
|
245
|
+
}
|
|
246
|
+
function capRetrievalQuery(text) {
|
|
247
|
+
if (text.length <= RETRIEVAL_QUERY_MAX_CHARS)
|
|
248
|
+
return text;
|
|
249
|
+
return text.slice(text.length - RETRIEVAL_QUERY_MAX_CHARS);
|
|
250
|
+
}
|
|
199
251
|
/**
|
|
200
252
|
* Symbol-keyed hook that drains all pending async ingestion queues.
|
|
201
253
|
* Tests import this symbol to access the drain function. Using a
|
|
@@ -1721,6 +1773,8 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
1721
1773
|
const isPostToolContinuation = lastUserIndex >= 0 && lastUserIndex < messages.length - 1
|
|
1722
1774
|
&& hasLiveToolProtocolAfterLastUser(messages, lastUserIndex);
|
|
1723
1775
|
const lastUserMessage = findLastReplaySafeUserMessage(messages);
|
|
1776
|
+
const latestUserContent = typeof lastUserMessage?.content === "string" ? lastUserMessage.content : "";
|
|
1777
|
+
const retrievalQuery = normalizeRetrievalQuery(strippedPrompt, latestUserContent);
|
|
1724
1778
|
const reservedCurrentTurnTokens = lastUserMessage
|
|
1725
1779
|
? approximateMessageTokens(lastUserMessage)
|
|
1726
1780
|
: RESERVED_CURRENT_TURN_TOKENS;
|
|
@@ -1856,7 +1910,7 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
1856
1910
|
]);
|
|
1857
1911
|
const maxMemories = cfg.beforeTurnMaxMemories ?? 5;
|
|
1858
1912
|
const clamped = btResult.predictions && btResult.predictions.length > maxMemories
|
|
1859
|
-
? selectTopByRelevance(btResult.predictions,
|
|
1913
|
+
? selectTopByRelevance(btResult.predictions, retrievalQuery, maxMemories)
|
|
1860
1914
|
: btResult.predictions;
|
|
1861
1915
|
turnCache.set(sessionId, `${messages.length}:${beforeTurnQueryHint}`, { predictions: clamped });
|
|
1862
1916
|
beforeTurnPredictions = clamped;
|
|
@@ -1873,7 +1927,7 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
1873
1927
|
sessionId,
|
|
1874
1928
|
sessionKey: args.sessionKey,
|
|
1875
1929
|
userId,
|
|
1876
|
-
prompt:
|
|
1930
|
+
prompt: retrievalQuery,
|
|
1877
1931
|
messages,
|
|
1878
1932
|
tokenBudget: args.tokenBudget,
|
|
1879
1933
|
config: buildAssemblyConfig(args.tokenBudget),
|
|
@@ -1894,7 +1948,7 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
1894
1948
|
? { ...assembled, systemPromptAddition: appendSystemPromptAddition(assembled.systemPromptAddition, continuityContext) }
|
|
1895
1949
|
: assembled;
|
|
1896
1950
|
enforced = enforceTokenBudgetInvariant(await augmentWithExactRecall(withContinuity, {
|
|
1897
|
-
queryText:
|
|
1951
|
+
queryText: retrievalQuery,
|
|
1898
1952
|
userId,
|
|
1899
1953
|
sessionId,
|
|
1900
1954
|
tokenBudget: args.tokenBudget,
|
package/dist/index.js
CHANGED
|
@@ -35491,6 +35491,10 @@ var EXACT_RECALL_MAX_TOKENS = 4;
|
|
|
35491
35491
|
var RESERVED_CURRENT_TURN_TOKENS = 150;
|
|
35492
35492
|
var AFTER_TURN_INGEST_MAX_TOKENS = 2048;
|
|
35493
35493
|
var OPENCLAW_LEADING_TIMESTAMP_PREFIX_RE = /^\[[A-Za-z]{3} \d{4}-\d{2}-\d{2} \d{2}:\d{2}[^\]]*\] */;
|
|
35494
|
+
var SELECTED_CONTEXT_HEADER = "Conversation context (untrusted, chronological, selected for current message):";
|
|
35495
|
+
var RETRIEVAL_QUERY_MAX_CHARS = 1e3;
|
|
35496
|
+
var SELECTED_CONTEXT_TURN_RE = /^#\d+\s+[A-Za-z]{3}\s+\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}(?::\d{2})?\s+\S+\s+([^:\n]{1,80}):\s*(.*)$/;
|
|
35497
|
+
var ASSISTANT_SPEAKER_RE = /\b(?:assistant|openclaw|z3robot|bot)\b/i;
|
|
35494
35498
|
var OPENCLAW_METADATA_HEADERS = [
|
|
35495
35499
|
"Conversation info (untrusted metadata):",
|
|
35496
35500
|
"Sender (untrusted metadata):",
|
|
@@ -35656,6 +35660,46 @@ function normalizeKernelContent(content, options = {}) {
|
|
|
35656
35660
|
retainContext: options.retainOpenClawContext === true
|
|
35657
35661
|
});
|
|
35658
35662
|
}
|
|
35663
|
+
function normalizeRetrievalQuery(primaryText, fallbackText = "") {
|
|
35664
|
+
const primary = normalizeRetrievalCandidate(primaryText);
|
|
35665
|
+
if (primary) return primary;
|
|
35666
|
+
return normalizeRetrievalCandidate(fallbackText);
|
|
35667
|
+
}
|
|
35668
|
+
function normalizeRetrievalCandidate(text) {
|
|
35669
|
+
const normalized = text.replace(OPENCLAW_LEADING_TIMESTAMP_PREFIX_RE, "").replace(/\r\n/g, "\n").trim();
|
|
35670
|
+
if (!normalized) return "";
|
|
35671
|
+
const selected = extractLatestSelectedContextUtterance(normalized);
|
|
35672
|
+
const candidate = selected || normalized;
|
|
35673
|
+
return capRetrievalQuery(candidate.replace(/\s+/g, " ").trim());
|
|
35674
|
+
}
|
|
35675
|
+
function extractLatestSelectedContextUtterance(text) {
|
|
35676
|
+
if (!text.startsWith(SELECTED_CONTEXT_HEADER)) return "";
|
|
35677
|
+
const turns = [];
|
|
35678
|
+
for (const rawLine of text.slice(SELECTED_CONTEXT_HEADER.length).split("\n")) {
|
|
35679
|
+
const line = rawLine.trim();
|
|
35680
|
+
if (!line) continue;
|
|
35681
|
+
const match = line.match(SELECTED_CONTEXT_TURN_RE);
|
|
35682
|
+
if (match) {
|
|
35683
|
+
turns.push({ speaker: match[1].trim(), text: [match[2].trim()] });
|
|
35684
|
+
continue;
|
|
35685
|
+
}
|
|
35686
|
+
if (turns.length > 0) {
|
|
35687
|
+
turns[turns.length - 1].text.push(line);
|
|
35688
|
+
}
|
|
35689
|
+
}
|
|
35690
|
+
for (let i = turns.length - 1; i >= 0; i--) {
|
|
35691
|
+
const turn = turns[i];
|
|
35692
|
+
const content = turn.text.join(" ").trim();
|
|
35693
|
+
if (content && !ASSISTANT_SPEAKER_RE.test(turn.speaker)) {
|
|
35694
|
+
return content;
|
|
35695
|
+
}
|
|
35696
|
+
}
|
|
35697
|
+
return "";
|
|
35698
|
+
}
|
|
35699
|
+
function capRetrievalQuery(text) {
|
|
35700
|
+
if (text.length <= RETRIEVAL_QUERY_MAX_CHARS) return text;
|
|
35701
|
+
return text.slice(text.length - RETRIEVAL_QUERY_MAX_CHARS);
|
|
35702
|
+
}
|
|
35659
35703
|
var FLUSH_ASYNC_INGESTION = /* @__PURE__ */ Symbol("flushAsyncIngestion");
|
|
35660
35704
|
var maxOptimizationMemoCacheSize = 5e4;
|
|
35661
35705
|
var metadataEnvelopeCache = /* @__PURE__ */ new Map();
|
|
@@ -36950,6 +36994,8 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
36950
36994
|
const lastUserIndex = findLastUserMessageIndex(messages);
|
|
36951
36995
|
const isPostToolContinuation = lastUserIndex >= 0 && lastUserIndex < messages.length - 1 && hasLiveToolProtocolAfterLastUser(messages, lastUserIndex);
|
|
36952
36996
|
const lastUserMessage = findLastReplaySafeUserMessage(messages);
|
|
36997
|
+
const latestUserContent = typeof lastUserMessage?.content === "string" ? lastUserMessage.content : "";
|
|
36998
|
+
const retrievalQuery = normalizeRetrievalQuery(strippedPrompt, latestUserContent);
|
|
36953
36999
|
const reservedCurrentTurnTokens = lastUserMessage ? approximateMessageTokens(lastUserMessage) : RESERVED_CURRENT_TURN_TOKENS;
|
|
36954
37000
|
const currentContextTokens = resolvePredictiveCompactionTokenCount({
|
|
36955
37001
|
currentTokenCount: args.currentTokenCount,
|
|
@@ -37084,7 +37130,7 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
37084
37130
|
)
|
|
37085
37131
|
]);
|
|
37086
37132
|
const maxMemories = cfg.beforeTurnMaxMemories ?? 5;
|
|
37087
|
-
const clamped = btResult.predictions && btResult.predictions.length > maxMemories ? selectTopByRelevance(btResult.predictions,
|
|
37133
|
+
const clamped = btResult.predictions && btResult.predictions.length > maxMemories ? selectTopByRelevance(btResult.predictions, retrievalQuery, maxMemories) : btResult.predictions;
|
|
37088
37134
|
turnCache.set(sessionId, `${messages.length}:${beforeTurnQueryHint}`, { predictions: clamped });
|
|
37089
37135
|
beforeTurnPredictions = clamped;
|
|
37090
37136
|
clearBeforeTurnCircuit(sessionId);
|
|
@@ -37101,7 +37147,7 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
37101
37147
|
sessionId,
|
|
37102
37148
|
sessionKey: args.sessionKey,
|
|
37103
37149
|
userId,
|
|
37104
|
-
prompt:
|
|
37150
|
+
prompt: retrievalQuery,
|
|
37105
37151
|
messages,
|
|
37106
37152
|
tokenBudget: args.tokenBudget,
|
|
37107
37153
|
config: buildAssemblyConfig(args.tokenBudget),
|
|
@@ -37123,7 +37169,7 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
37123
37169
|
const withContinuity = continuityContext ? { ...assembled, systemPromptAddition: appendSystemPromptAddition(assembled.systemPromptAddition, continuityContext) } : assembled;
|
|
37124
37170
|
enforced = enforceTokenBudgetInvariant(
|
|
37125
37171
|
await augmentWithExactRecall(withContinuity, {
|
|
37126
|
-
queryText:
|
|
37172
|
+
queryText: retrievalQuery,
|
|
37127
37173
|
userId,
|
|
37128
37174
|
sessionId,
|
|
37129
37175
|
tokenBudget: args.tokenBudget,
|
package/openclaw.plugin.json
CHANGED