@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 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
@@ -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
- // Matches older annotations, aggressively consuming trailing characters on the same line
1211
- const TOOL_RESULT_ANNOTATION_RE = /\[tool:[^\]]+\][^\n]*/g;
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 resp = await client.assembleContextInternal({
2270
- sessionId,
2271
- sessionKey: args.sessionKey,
2272
- userId,
2273
- prompt: strippedPrompt,
2274
- messages,
2275
- tokenBudget: args.tokenBudget,
2276
- config: buildAssemblyConfig(args.tokenBudget),
2277
- emitDebug: true,
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:[^\]]+\][^\n]*/g;
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 resp = await client.assembleContextInternal({
37458
- sessionId,
37459
- sessionKey: args.sessionKey,
37460
- userId,
37461
- prompt: strippedPrompt,
37462
- messages,
37463
- tokenBudget: args.tokenBudget,
37464
- config: buildAssemblyConfig(args.tokenBudget),
37465
- emitDebug: true
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);
@@ -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 */
@@ -2,7 +2,7 @@
2
2
  "id": "libravdb-memory",
3
3
  "name": "LibraVDB Memory",
4
4
  "description": "Persistent vector memory with three-tier hybrid scoring",
5
- "version": "1.9.4",
5
+ "version": "1.9.6",
6
6
  "kind": [
7
7
  "memory",
8
8
  "context-engine"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xdarkicex/openclaw-memory-libravdb",
3
- "version": "1.9.4",
3
+ "version": "1.9.6",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",