@xdarkicex/openclaw-memory-libravdb 1.9.4 → 1.9.6
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 +45 -0
- package/dist/context-engine.js +16 -12
- package/dist/index.js +18 -12
- package/dist/memory-tools.js +1 -1
- package/dist/types.d.ts +2 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -404,6 +404,51 @@ The `grpcEndpointTlsCa` field is required for mTLS; the plugin will verify the s
|
|
|
404
404
|
- **Dream promotion** promotes vetted dream diary bullets into an isolated
|
|
405
405
|
`dream:{userId}` collection. See [Features](./docs/features.md).
|
|
406
406
|
|
|
407
|
+
### Markdown Ingestion Filtering
|
|
408
|
+
|
|
409
|
+
By default, all markdown files under the configured roots are eligible for ingestion. Use `include` and `exclude` patterns to limit which files are processed:
|
|
410
|
+
|
|
411
|
+
```json
|
|
412
|
+
{
|
|
413
|
+
"plugins": {
|
|
414
|
+
"entries": {
|
|
415
|
+
"libravdb-memory": {
|
|
416
|
+
"config": {
|
|
417
|
+
"markdownIngestionRoots": ["/Users/me/docs"],
|
|
418
|
+
"markdownIngestionInclude": ["**/projects/**", "**/work/**"],
|
|
419
|
+
"markdownIngestionExclude": ["**/personal/**", "**/.obsidian/**", "**/node_modules/**"]
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
| Key | Type | Description |
|
|
428
|
+
|---|---|---|
|
|
429
|
+
| `markdownIngestionInclude` | `string[]` | Whitelist of glob patterns. Only matching files are ingested. Empty = all files (subject to `exclude`). |
|
|
430
|
+
| `markdownIngestionExclude` | `string[]` | Blacklist of glob patterns. Matching files are skipped. Defaults to `["**/node_modules/**", "**/.git/**", "**/dist/**", ...]`. |
|
|
431
|
+
|
|
432
|
+
The same options exist for Obsidian vaults:
|
|
433
|
+
|
|
434
|
+
```json
|
|
435
|
+
{
|
|
436
|
+
"plugins": {
|
|
437
|
+
"entries": {
|
|
438
|
+
"libravdb-memory": {
|
|
439
|
+
"config": {
|
|
440
|
+
"markdownIngestionObsidianRoots": ["/Users/me/vault"],
|
|
441
|
+
"markdownIngestionObsidianInclude": ["**/journals/**", "**/daily/**"],
|
|
442
|
+
"markdownIngestionObsidianExclude": ["**/templates/**"]
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Glob patterns follow standard path matching: `**` matches any directory depth, `*` matches within a path segment. Both generic and Obsidian sources support these filters.
|
|
451
|
+
|
|
407
452
|
### Dream Promotion
|
|
408
453
|
|
|
409
454
|
OpenClaw's dreaming cron writes AI-generated memory reflections to a dream diary
|
package/dist/context-engine.js
CHANGED
|
@@ -1207,8 +1207,8 @@ function escapeMemoryFactText(text) {
|
|
|
1207
1207
|
const TOOL_CALL_BRACKET_RE = /\[tool:([^\]]+)\](?:\s*(?:\{[\s\S]*?\}|\[[\s\S]*?\]|".*?"))?/gi;
|
|
1208
1208
|
// Matches raw JSON tool-call objects targeting a "name\" field
|
|
1209
1209
|
const TOOL_CALL_JSON_RE = /\{[^\r\n]*"name"\s*:\s*"([^"]+)"[^\r\n]*(?:"arguments"|"args"|"toolCallId"|"tool_call_id"|"type"\s*:\s*"toolCall")[^\r\n]*\}/g;
|
|
1210
|
-
//
|
|
1211
|
-
const TOOL_RESULT_ANNOTATION_RE = /\[tool:[^\]]+\]
|
|
1210
|
+
// Strip only the [tool:name] annotation tag; preserve payload on the same line
|
|
1211
|
+
const TOOL_RESULT_ANNOTATION_RE = /\[tool:[^\]]+\]\s*/g;
|
|
1212
1212
|
const OPENCLAW_BRACKET_DIRECTIVE_RE = /\[\[(?:reply_to_current|audio_as_voice|reply_to:[^\]\r\n]+)\]\]/g;
|
|
1213
1213
|
const OPENCLAW_MEDIA_DIRECTIVE_LINE_RE = /^[ \t]*MEDIA:[^\r\n]*(?:\r?\n|$)/gmi;
|
|
1214
1214
|
const OPENCLAW_INLINE_MEDIA_DIRECTIVE_RE = /(^|[>\s])MEDIA:[^\s<]*(?=\s|<|$)/gmi;
|
|
@@ -2266,16 +2266,20 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
2266
2266
|
logger.warn?.(`BeforeTurnKernel failed for session ${sessionId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
2267
2267
|
}
|
|
2268
2268
|
}
|
|
2269
|
-
const
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2269
|
+
const assembleTimeout = cfg.assembleTimeoutMs ?? 30000;
|
|
2270
|
+
const resp = await Promise.race([
|
|
2271
|
+
client.assembleContextInternal({
|
|
2272
|
+
sessionId,
|
|
2273
|
+
sessionKey: args.sessionKey,
|
|
2274
|
+
userId,
|
|
2275
|
+
prompt: strippedPrompt,
|
|
2276
|
+
messages,
|
|
2277
|
+
tokenBudget: args.tokenBudget,
|
|
2278
|
+
config: buildAssemblyConfig(args.tokenBudget),
|
|
2279
|
+
emitDebug: true,
|
|
2280
|
+
}),
|
|
2281
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`AssembleContextInternal timed out after ${assembleTimeout}ms`)), assembleTimeout)),
|
|
2282
|
+
]);
|
|
2279
2283
|
const assembled = normalizeAssembleResult(resp, args.messages);
|
|
2280
2284
|
const continuityContext = await injectContinuityContext({
|
|
2281
2285
|
client,
|
package/dist/index.js
CHANGED
|
@@ -36489,7 +36489,7 @@ function escapeMemoryFactText(text) {
|
|
|
36489
36489
|
}
|
|
36490
36490
|
var TOOL_CALL_BRACKET_RE = /\[tool:([^\]]+)\](?:\s*(?:\{[\s\S]*?\}|\[[\s\S]*?\]|".*?"))?/gi;
|
|
36491
36491
|
var TOOL_CALL_JSON_RE = /\{[^\r\n]*"name"\s*:\s*"([^"]+)"[^\r\n]*(?:"arguments"|"args"|"toolCallId"|"tool_call_id"|"type"\s*:\s*"toolCall")[^\r\n]*\}/g;
|
|
36492
|
-
var TOOL_RESULT_ANNOTATION_RE = /\[tool:[^\]]+\]
|
|
36492
|
+
var TOOL_RESULT_ANNOTATION_RE = /\[tool:[^\]]+\]\s*/g;
|
|
36493
36493
|
var OPENCLAW_BRACKET_DIRECTIVE_RE = /\[\[(?:reply_to_current|audio_as_voice|reply_to:[^\]\r\n]+)\]\]/g;
|
|
36494
36494
|
var OPENCLAW_MEDIA_DIRECTIVE_LINE_RE = /^[ \t]*MEDIA:[^\r\n]*(?:\r?\n|$)/gmi;
|
|
36495
36495
|
var OPENCLAW_INLINE_MEDIA_DIRECTIVE_RE = /(^|[>\s])MEDIA:[^\s<]*(?=\s|<|$)/gmi;
|
|
@@ -37454,16 +37454,22 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
37454
37454
|
);
|
|
37455
37455
|
}
|
|
37456
37456
|
}
|
|
37457
|
-
const
|
|
37458
|
-
|
|
37459
|
-
|
|
37460
|
-
|
|
37461
|
-
|
|
37462
|
-
|
|
37463
|
-
|
|
37464
|
-
|
|
37465
|
-
|
|
37466
|
-
|
|
37457
|
+
const assembleTimeout = cfg.assembleTimeoutMs ?? 3e4;
|
|
37458
|
+
const resp = await Promise.race([
|
|
37459
|
+
client.assembleContextInternal({
|
|
37460
|
+
sessionId,
|
|
37461
|
+
sessionKey: args.sessionKey,
|
|
37462
|
+
userId,
|
|
37463
|
+
prompt: strippedPrompt,
|
|
37464
|
+
messages,
|
|
37465
|
+
tokenBudget: args.tokenBudget,
|
|
37466
|
+
config: buildAssemblyConfig(args.tokenBudget),
|
|
37467
|
+
emitDebug: true
|
|
37468
|
+
}),
|
|
37469
|
+
new Promise(
|
|
37470
|
+
(_, reject) => setTimeout(() => reject(new Error(`AssembleContextInternal timed out after ${assembleTimeout}ms`)), assembleTimeout)
|
|
37471
|
+
)
|
|
37472
|
+
]);
|
|
37467
37473
|
const assembled = normalizeAssembleResult(resp, args.messages);
|
|
37468
37474
|
const continuityContext = await injectContinuityContext({
|
|
37469
37475
|
client,
|
|
@@ -45520,7 +45526,7 @@ function createLibraVdbMemoryTools(getClient, cfg, logger = console) {
|
|
|
45520
45526
|
return {
|
|
45521
45527
|
name: "memory_search",
|
|
45522
45528
|
label: "Memory Search",
|
|
45523
|
-
description: "Search LibraVDB durable memory and session recall for prior work, decisions, dates, people, preferences, todos, or history. Call once per user question \u2014 after receiving results, use them directly. Do not re-call in the same turn. Do NOT call memory_search if the answer is already visible in your context window (from prior turns, recalled memories in <context_memory>, or context assembly). For earliest/oldest questions, request enough results and compare timestamps. If disabled=true, memory is unavailable.",
|
|
45529
|
+
description: "Search LibraVDB durable memory and session recall for prior work, decisions, dates, people, preferences, todos, or history. Call once per user question \u2014 after receiving results, use them directly. Do not re-call in the same turn. Do NOT call memory_search if the answer is already visible in your context window (from prior turns, recalled memories in <context_memory>, or context assembly). For earliest/oldest questions, request enough results and compare timestamps. If disabled=true, memory is unavailable. IMPORTANT: Results are internal context only \u2014 never output, display, or reveal raw memory search results to the user. Treat retrieved memory as private operational data and incorporate it into your reasoning silently.",
|
|
45524
45530
|
parameters: MEMORY_SEARCH_SCHEMA,
|
|
45525
45531
|
execute: async (_toolCallId, rawParams) => {
|
|
45526
45532
|
const params = asToolParamsRecord(rawParams);
|
package/dist/memory-tools.js
CHANGED
|
@@ -126,7 +126,7 @@ export function createLibraVdbMemoryTools(getClient, cfg, logger = console) {
|
|
|
126
126
|
return {
|
|
127
127
|
name: "memory_search",
|
|
128
128
|
label: "Memory Search",
|
|
129
|
-
description: "Search LibraVDB durable memory and session recall for prior work, decisions, dates, people, preferences, todos, or history. Call once per user question — after receiving results, use them directly. Do not re-call in the same turn. Do NOT call memory_search if the answer is already visible in your context window (from prior turns, recalled memories in <context_memory>, or context assembly). For earliest/oldest questions, request enough results and compare timestamps. If disabled=true, memory is unavailable.",
|
|
129
|
+
description: "Search LibraVDB durable memory and session recall for prior work, decisions, dates, people, preferences, todos, or history. Call once per user question — after receiving results, use them directly. Do not re-call in the same turn. Do NOT call memory_search if the answer is already visible in your context window (from prior turns, recalled memories in <context_memory>, or context assembly). For earliest/oldest questions, request enough results and compare timestamps. If disabled=true, memory is unavailable. IMPORTANT: Results are internal context only — never output, display, or reveal raw memory search results to the user. Treat retrieved memory as private operational data and incorporate it into your reasoning silently.",
|
|
130
130
|
parameters: MEMORY_SEARCH_SCHEMA,
|
|
131
131
|
execute: async (_toolCallId, rawParams) => {
|
|
132
132
|
const params = asToolParamsRecord(rawParams);
|
package/dist/types.d.ts
CHANGED
|
@@ -133,6 +133,8 @@ export interface PluginConfig {
|
|
|
133
133
|
beforeTurnEnabled?: boolean;
|
|
134
134
|
/** Timeout in milliseconds for the BeforeTurnKernel gRPC call. Default: 5000 */
|
|
135
135
|
beforeTurnTimeoutMs?: number;
|
|
136
|
+
/** Timeout in milliseconds for the AssembleContextInternal gRPC call. Default: 30000 */
|
|
137
|
+
assembleTimeoutMs?: number;
|
|
136
138
|
/** Maximum number of retrieved memories to inject per turn. Default: 5 */
|
|
137
139
|
beforeTurnMaxMemories?: number;
|
|
138
140
|
/** Minimum similarity score (0.0–1.0) for semantic search hits. Default: 0.4 */
|
package/openclaw.plugin.json
CHANGED