@xdarkicex/openclaw-memory-libravdb 1.3.19 → 1.3.20

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
@@ -131,7 +131,7 @@ If your daemon runs elsewhere, set an explicit `sidecarPath`, for example:
131
131
 
132
132
  ```text
133
133
  OpenClaw host
134
- -> memoryPromptSection (durable user/global recall)
134
+ -> memoryPromptSection (static capability header)
135
135
  -> memory runtime bridge (built-in memory_search)
136
136
  -> context engine (bootstrap / ingest / assemble / compact)
137
137
  -> plugin runtime
@@ -10,7 +10,7 @@ repository as of the current `main` branch.
10
10
  flowchart LR
11
11
  Host["OpenClaw host process\n(TypeScript plugin shell)"]
12
12
  CE["Context engine factory\nbootstrap / ingest / assemble / compact"]
13
- MPS["memoryPromptSection\nuser+global recall"]
13
+ MPS["memoryPromptSection\nstatic header"]
14
14
  Runtime["Plugin runtime\nlazy daemon connect + RPC client"]
15
15
  Sidecar["Go daemon process"]
16
16
  RPC["JSON-RPC over newline-delimited frames\nUnix socket or TCP loopback on Windows"]
@@ -28,7 +28,6 @@ flowchart LR
28
28
  Host --> CE
29
29
  Host --> MPS
30
30
  CE --> Runtime
31
- MPS --> Runtime
32
31
  Runtime --> RPC
33
32
  RPC --> Sidecar
34
33
  Sidecar --> Embed
@@ -80,17 +79,12 @@ Important constraints from the current implementation:
80
79
 
81
80
  Implemented in [`src/memory-provider.ts`](../src/memory-provider.ts).
82
81
 
83
- Before the main assembly path runs, the plugin builds a lightweight recall
84
- section:
82
+ Before the main assembly path runs, the plugin returns a lightweight static
83
+ header fragment that tells the host persistent memory is active.
85
84
 
86
- 1. search `user:<userId>`
87
- 2. search `global`
88
- 3. hybrid-rank the combined hits
89
- 4. fit them to a fixed prompt budget of `800` estimated tokens
90
- 5. return a textual header fragment for the host prompt
91
-
92
- This path does not search session memory. Its job is durable context recall, not
93
- active-turn recall.
85
+ This path is intentionally synchronous and does not perform RPC retrieval.
86
+ Durable recall now happens entirely inside `assemble`, which keeps embedded
87
+ prompt construction compatible with OpenClaw's synchronous memory prompt hook.
94
88
 
95
89
  ### 2.3 `assemble`
96
90
 
@@ -107,7 +101,7 @@ For the current query text (last message content), the host:
107
101
 
108
102
  Current implementation details that matter:
109
103
 
110
- - user/global hits may be reused from the earlier prompt-section cache
104
+ - user/global hits are cached within `assemble` and reused on repeated queries
111
105
  - `assemble` falls back to the unmodified message list on RPC failure
112
106
  - `assemble` does not mutate the original `messages` array in place; it returns
113
107
  a new array
@@ -146,7 +140,7 @@ from the original spec phrasing.
146
140
  |---|---|---|
147
141
  | Daemon unavailable on first RPC use | `getRpc()` rejects when first connect or health check fails | That hook fails or falls back, but plugin registration itself does not crash eagerly |
148
142
  | Daemon connection closes mid-session | `SidecarSupervisor` retries with exponential backoff until retry budget is exhausted, then enters degraded mode | Memory becomes unavailable until the daemon is reachable again |
149
- | `memoryPromptSection` RPC failure | individual searches are caught and replaced with empty result sets | Prompt section becomes empty rather than crashing the run |
143
+ | `memoryPromptSection` failure | returns a static header with no RPC dependency | Prompt section stays available and does not block the run |
150
144
  | `assemble` RPC failure | returns original messages, original token count, and empty `systemPromptAddition` | That turn gets no recall augmentation |
151
145
  | `ingest` gating or durable insert failure | session write already happened; durable promotion is skipped | Session memory survives, durable memory may miss that turn |
152
146
  | Compaction summarizer unavailable | extractive summarizer remains required; optional abstractive path is skipped | Compaction still runs extractively when extractive is healthy |
@@ -18,8 +18,8 @@ Why:
18
18
  - `ingest`
19
19
  - `assemble`
20
20
  - `compact`
21
- - the lightweight memory prompt section remains useful as a separate early
22
- durable-recall pass
21
+ - the lightweight memory prompt section remains useful as a synchronous
22
+ capability/header hook while durable recall stays in `assemble`
23
23
 
24
24
  This is why the code registers both `registerContextEngine("libravdb-memory", …)`
25
25
  and `registerMemoryPromptSection(...)` instead of relying on only one hook.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xdarkicex/openclaw-memory-libravdb",
3
- "version": "1.3.19",
3
+ "version": "1.3.20",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1,87 +1,25 @@
1
+ import type { MemoryPromptSectionBuilder } from "openclaw/plugin-sdk/plugin-entry";
1
2
  import type { PluginConfig, RecallCache, SearchResult } from "./types.js";
2
3
  import type { RpcGetter } from "./plugin-runtime.js";
3
- import { scoreCandidates } from "./scoring.js";
4
- import { fitPromptBudget } from "./tokens.js";
5
- import { buildMemoryHeader } from "./recall-utils.js";
6
4
 
7
- const MEMORY_PROMPT_BUDGET = 800;
5
+ const MEMORY_PROMPT_HEADER = [
6
+ "## Memory",
7
+ "LibraVDB persistent memory is configured. Recalled memories may appear",
8
+ "in context via the context-engine assembler when available and relevant.",
9
+ "",
10
+ ] as const;
8
11
 
9
12
  export function buildMemoryPromptSection(
10
- getRpc: RpcGetter,
11
- cfg: PluginConfig,
12
- recallCache: RecallCache<SearchResult>,
13
- ): (params: {
14
- availableTools: Set<string>;
15
- citationsMode?: string;
16
- messages?: Array<{ role: string; content: string }>;
17
- userId?: string;
18
- }) => Promise<string[]> {
19
- return async function memoryPromptSection(params: {
20
- availableTools: Set<string>;
21
- citationsMode?: string;
22
- messages?: Array<{ role: string; content: string }>;
23
- userId?: string;
24
- }): Promise<string[]> {
25
- const queryText = params.messages?.at(-1)?.content ?? "";
26
- const userId = params.userId ?? "default";
27
-
28
- if (!queryText) {
29
- return [
30
- "## Memory",
31
- "LibraVDB persistent memory is active. Recalled memories will appear",
32
- "in context via the context-engine assembler when relevant.",
33
- "",
34
- ];
35
- }
36
-
37
- const rpc = await getRpc();
38
-
39
- const [userHitsResult, globalHitsResult] = await Promise.all([
40
- rpc.call<{ results: SearchResult[] }>("search_text", {
41
- collection: `user:${userId}`,
42
- text: queryText,
43
- k: Math.ceil((cfg.topK ?? 8) / 2),
44
- }),
45
- rpc.call<{ results: SearchResult[] }>("search_text", {
46
- collection: "global",
47
- text: queryText,
48
- k: Math.ceil((cfg.topK ?? 8) / 4),
49
- }),
50
- ]);
51
-
52
- const userHits = userHitsResult.results;
53
- const globalHits = globalHitsResult.results;
54
-
55
- recallCache.put({
56
- userId,
57
- queryText,
58
- durableVariantHits: [],
59
- userHits,
60
- globalHits,
61
- });
62
-
63
- const ranked = scoreCandidates([...userHits, ...globalHits], {
64
- alpha: cfg.alpha,
65
- beta: cfg.beta,
66
- gamma: cfg.gamma,
67
- sessionId: "",
68
- userId,
69
- });
70
-
71
- const selected = fitPromptBudget(ranked, MEMORY_PROMPT_BUDGET);
72
- const recallHeader = buildMemoryHeader(selected);
73
-
74
- const lines: string[] = [
75
- "## Memory",
76
- "LibraVDB persistent memory is active. Recalled memories will appear",
77
- "in context via the context-engine assembler when relevant.",
78
- ];
79
-
80
- if (recallHeader) {
81
- lines.push(...recallHeader.split("\n"));
82
- }
83
-
84
- lines.push("");
85
- return lines;
13
+ _getRpc: RpcGetter,
14
+ _cfg: PluginConfig,
15
+ _recallCache: RecallCache<SearchResult>,
16
+ ): MemoryPromptSectionBuilder {
17
+ return function memoryPromptSection({
18
+ availableTools: _availableTools,
19
+ citationsMode: _citationsMode,
20
+ }): string[] {
21
+ // OpenClaw builds the memory prompt section synchronously for embedded runs.
22
+ // Actual retrieval and ranking happen in the context engine during assemble().
23
+ return [...MEMORY_PROMPT_HEADER];
86
24
  };
87
- }
25
+ }
@@ -1,4 +1,9 @@
1
1
  declare module "openclaw/plugin-sdk/plugin-entry" {
2
+ export type MemoryPromptSectionBuilder = (params: {
3
+ availableTools: Set<string>;
4
+ citationsMode?: string;
5
+ }) => string[];
6
+
2
7
  interface OpenClawCliCommand {
3
8
  commands?: OpenClawCliCommand[];
4
9
  command(name: string): OpenClawCliCommand;
@@ -18,7 +23,7 @@ declare module "openclaw/plugin-sdk/plugin-entry" {
18
23
  warn?(message: string): void;
19
24
  };
20
25
  registerContextEngine(id: string, factory: () => unknown): void;
21
- registerMemoryPromptSection(builder: unknown): void;
26
+ registerMemoryPromptSection(builder: MemoryPromptSectionBuilder): void;
22
27
  registerMemoryFlushPlan?(resolver: unknown): void;
23
28
  registerMemoryRuntime?(runtime: unknown): void;
24
29
  registerMemoryEmbeddingProvider?(provider: unknown): void;