@xdarkicex/openclaw-memory-libravdb 1.4.6 → 1.4.7
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/HOOK.md +14 -0
- package/README.md +32 -2
- package/dist/cli.d.ts +39 -0
- package/dist/cli.js +208 -0
- package/dist/context-engine.d.ts +56 -0
- package/dist/context-engine.js +125 -0
- package/dist/dream-promotion.d.ts +47 -0
- package/dist/dream-promotion.js +363 -0
- package/dist/dream-routing.d.ts +6 -0
- package/dist/dream-routing.js +31 -0
- package/dist/durable-namespace.d.ts +6 -0
- package/dist/durable-namespace.js +24 -0
- package/dist/grpc-client.d.ts +23 -0
- package/dist/grpc-client.js +104 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +40 -0
- package/dist/lifecycle-hooks.d.ts +4 -0
- package/dist/lifecycle-hooks.js +64 -0
- package/dist/markdown-hash.d.ts +3 -0
- package/dist/markdown-hash.js +82 -0
- package/dist/markdown-ingest.d.ts +43 -0
- package/dist/markdown-ingest.js +464 -0
- package/dist/memory-provider.d.ts +4 -0
- package/dist/memory-provider.js +13 -0
- package/dist/memory-runtime.d.ts +118 -0
- package/dist/memory-runtime.js +217 -0
- package/dist/plugin-runtime.d.ts +28 -0
- package/dist/plugin-runtime.js +127 -0
- package/dist/proto/intelligence_kernel/v1/kernel.proto +378 -0
- package/dist/recall-cache.d.ts +2 -0
- package/dist/recall-cache.js +30 -0
- package/dist/rpc-protobuf-codecs.d.ts +70 -0
- package/dist/rpc-protobuf-codecs.js +77 -0
- package/dist/rpc.d.ts +14 -0
- package/dist/rpc.js +121 -0
- package/dist/sidecar.d.ts +34 -0
- package/dist/sidecar.js +535 -0
- package/dist/types.d.ts +163 -0
- package/dist/types.js +1 -0
- package/docs/contributing.md +14 -13
- package/docs/install.md +7 -9
- package/docs/installation.md +23 -16
- package/docs/uninstall.md +1 -1
- package/index.js +2 -0
- package/openclaw.plugin.json +2 -2
- package/package.json +39 -16
- package/packaging/README.md +0 -71
- package/packaging/homebrew/libravdbd.rb.tmpl +0 -224
- package/packaging/launchd/com.xdarkicex.libravdbd.plist +0 -32
- package/packaging/systemd/libravdbd.service +0 -12
- package/src/cli.ts +0 -299
- package/src/comparison-experiments.ts +0 -128
- package/src/context-engine.ts +0 -1645
- package/src/continuity.ts +0 -93
- package/src/dream-promotion.ts +0 -492
- package/src/dream-routing.ts +0 -40
- package/src/durable-namespace.ts +0 -34
- package/src/index.ts +0 -47
- package/src/lifecycle-hooks.ts +0 -96
- package/src/markdown-hash.ts +0 -104
- package/src/markdown-ingest.ts +0 -627
- package/src/memory-provider.ts +0 -25
- package/src/memory-runtime.ts +0 -283
- package/src/openclaw-plugin-sdk.d.ts +0 -59
- package/src/plugin-runtime.ts +0 -119
- package/src/recall-cache.ts +0 -34
- package/src/recall-utils.ts +0 -131
- package/src/rpc.ts +0 -92
- package/src/scoring.ts +0 -632
- package/src/sidecar.ts +0 -583
- package/src/temporal.ts +0 -1031
- package/src/tokens.ts +0 -52
- package/src/types.ts +0 -278
- package/tsconfig.json +0 -20
- package/tsconfig.tests.json +0 -12
package/HOOK.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: libravdb-memory
|
|
3
|
+
description: Compatibility metadata for OpenClaw production installation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# LibraVDB Memory Hook Metadata
|
|
7
|
+
|
|
8
|
+
This package ships a native OpenClaw plugin with a compiled JavaScript runtime
|
|
9
|
+
under `dist/`.
|
|
10
|
+
|
|
11
|
+
`HOOK.md` is included so OpenClaw installation flows that validate hook-pack
|
|
12
|
+
metadata do not reject the published package for missing compatibility files.
|
|
13
|
+
It does not bootstrap the daemon or change the plugin's connect-only install
|
|
14
|
+
model.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# LibraVDB Memory for OpenClaw
|
|
2
2
|
|
|
3
|
-
[](
|
|
3
|
+
[](https://github.com/xDarkicex/libravdbd)
|
|
4
4
|
[](./package.json)
|
|
5
5
|
[](./openclaw.plugin.json)
|
|
6
6
|
|
|
@@ -22,6 +22,9 @@ the daemon handles embeddings, retrieval, storage, and compaction.
|
|
|
22
22
|
On newer OpenClaw builds, it also bridges the built-in `memory_search` runtime
|
|
23
23
|
to the same libraVDB sidecar instead of leaving that tool inert.
|
|
24
24
|
|
|
25
|
+
For local development, this repo can target a running daemon or a manual local
|
|
26
|
+
daemon binary.
|
|
27
|
+
|
|
25
28
|
## Why This Exists
|
|
26
29
|
|
|
27
30
|
The stock "single memory bucket" pattern is good for simple persistence, but it
|
|
@@ -65,7 +68,7 @@ These are the core differentiators the project is built around:
|
|
|
65
68
|
The supported install flow is:
|
|
66
69
|
|
|
67
70
|
```bash
|
|
68
|
-
brew tap xDarkicex/openclaw-libravdb-memory
|
|
71
|
+
brew tap xDarkicex/homebrew-openclaw-libravdb-memory
|
|
69
72
|
brew install libravdbd
|
|
70
73
|
brew services start libravdbd
|
|
71
74
|
openclaw plugins install @xdarkicex/openclaw-memory-libravdb
|
|
@@ -394,3 +397,30 @@ supported user path today is:
|
|
|
394
397
|
|
|
395
398
|
That tradeoff is intentional. It keeps the plugin installation surface simple
|
|
396
399
|
and auditable while preserving the full local memory engine at runtime.
|
|
400
|
+
|
|
401
|
+
## Generated Contract Types
|
|
402
|
+
|
|
403
|
+
TypeScript code in this plugin imports generated LibraVDB IPC types via the
|
|
404
|
+
`@xdarkicex/libravdb-contracts` package:
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
import { RpcRequest, RpcResponse } from "@xdarkicex/libravdb-contracts";
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
The generated types live in `libravdb-contracts/gen/ts/` and are produced by
|
|
411
|
+
`buf generate` in that repository. A local `paths` alias in `tsconfig.json`
|
|
412
|
+
wires the package name to that directory, so imports resolve without a
|
|
413
|
+
`node_modules` install in the contracts repo.
|
|
414
|
+
|
|
415
|
+
To regenerate after a proto change:
|
|
416
|
+
|
|
417
|
+
```bash
|
|
418
|
+
cd ../libravdb-contracts && buf generate
|
|
419
|
+
# or from this repo:
|
|
420
|
+
pnpm run generate:contracts
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
The alias is configured in both `tsconfig.json` (type-checking) and
|
|
424
|
+
`tsconfig.build.json` (declaration emission). The generated `.ts` files use
|
|
425
|
+
`@bufbuild/protobuf` at runtime, which must be available in the plugin's
|
|
426
|
+
`node_modules`.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
|
|
2
|
+
import type { PluginRuntime } from "./plugin-runtime.js";
|
|
3
|
+
import type { LoggerLike, PluginConfig } from "./types.js";
|
|
4
|
+
type CliOptionBag = {
|
|
5
|
+
dreamFile?: string;
|
|
6
|
+
userId?: string;
|
|
7
|
+
sessionKey?: string;
|
|
8
|
+
sessionId?: string;
|
|
9
|
+
limit?: string | number;
|
|
10
|
+
yes?: boolean;
|
|
11
|
+
};
|
|
12
|
+
type CliCommand = {
|
|
13
|
+
commands?: CliCommand[];
|
|
14
|
+
command(name: string): CliCommand;
|
|
15
|
+
description(text: string): CliCommand;
|
|
16
|
+
option(flags: string, description: string): CliCommand;
|
|
17
|
+
requiredOption?(flags: string, description: string): CliCommand;
|
|
18
|
+
action(handler: (opts?: CliOptionBag) => unknown): CliCommand;
|
|
19
|
+
name?(): string;
|
|
20
|
+
};
|
|
21
|
+
type CliProgram = CliCommand;
|
|
22
|
+
export declare function registerMemoryCli(api: OpenClawPluginApi, runtime: PluginRuntime, cfg: PluginConfig, logger?: LoggerLike): void;
|
|
23
|
+
type CliRegistrar = {
|
|
24
|
+
registerCli?(builder: (ctx: {
|
|
25
|
+
program: CliProgram;
|
|
26
|
+
}) => void, opts?: {
|
|
27
|
+
commands?: string[];
|
|
28
|
+
descriptors?: Array<{
|
|
29
|
+
name: string;
|
|
30
|
+
description: string;
|
|
31
|
+
hasSubcommands: boolean;
|
|
32
|
+
}>;
|
|
33
|
+
}): void;
|
|
34
|
+
};
|
|
35
|
+
declare module "openclaw/plugin-sdk/plugin-entry" {
|
|
36
|
+
interface OpenClawPluginApi extends CliRegistrar {
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export {};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { createInterface } from "node:readline/promises";
|
|
2
|
+
import { stdin, stdout } from "node:process";
|
|
3
|
+
import { resolveDurableNamespace } from "./durable-namespace.js";
|
|
4
|
+
import { promoteDreamDiaryFile } from "./dream-promotion.js";
|
|
5
|
+
export function registerMemoryCli(api, runtime, cfg, logger = console) {
|
|
6
|
+
if (!api.registerCli) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
api.registerCli(({ program }) => {
|
|
10
|
+
const root = ensureCommand(program, "memory")
|
|
11
|
+
.description("Manage LibraVDB memory");
|
|
12
|
+
ensureCommand(root, "status")
|
|
13
|
+
.description("Show sidecar health, record counts, and active thresholds")
|
|
14
|
+
.action(() => void runStatus(runtime, cfg, logger));
|
|
15
|
+
const flush = ensureCommand(root, "flush")
|
|
16
|
+
.description("Wipe a durable memory namespace after confirmation");
|
|
17
|
+
if (flush.requiredOption) {
|
|
18
|
+
flush.requiredOption("--user-id <userId>", "User id whose durable memory should be deleted");
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
flush.option("--user-id <userId>", "User id whose durable memory should be deleted");
|
|
22
|
+
}
|
|
23
|
+
flush.option("--session-key <sessionKey>", "Session key whose derived durable namespace should be deleted");
|
|
24
|
+
flush
|
|
25
|
+
.option("--yes", "Skip the confirmation prompt")
|
|
26
|
+
.action((opts) => void runFlush(runtime, opts, logger));
|
|
27
|
+
const exportCmd = ensureCommand(root, "export")
|
|
28
|
+
.description("Stream stored memories as newline-delimited JSON");
|
|
29
|
+
exportCmd.option("--user-id <userId>", "Restrict export to a single user namespace");
|
|
30
|
+
exportCmd.option("--session-key <sessionKey>", "Restrict export to a derived session-key namespace");
|
|
31
|
+
exportCmd.action((opts) => void runExport(runtime, opts, logger));
|
|
32
|
+
const journal = ensureCommand(root, "journal")
|
|
33
|
+
.description("Inspect internal lifecycle journal hints");
|
|
34
|
+
journal.option("--session-id <sessionId>", "Restrict journal entries to one session id");
|
|
35
|
+
journal.option("--limit <limit>", "Maximum journal entries to show");
|
|
36
|
+
journal.action((opts) => void runJournal(runtime, opts, logger));
|
|
37
|
+
const dreamPromote = ensureCommand(root, "dream-promote")
|
|
38
|
+
.description("Promote vetted dream diary entries into the dedicated dream collection");
|
|
39
|
+
if (dreamPromote.requiredOption) {
|
|
40
|
+
dreamPromote.requiredOption("--user-id <userId>", "User id whose dream collection should receive the promotion");
|
|
41
|
+
dreamPromote.requiredOption("--dream-file <path>", "Dream diary markdown file to promote from");
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
dreamPromote.option("--user-id <userId>", "User id whose dream collection should receive the promotion");
|
|
45
|
+
dreamPromote.option("--dream-file <path>", "Dream diary markdown file to promote from");
|
|
46
|
+
}
|
|
47
|
+
dreamPromote.action((opts) => void runDreamPromote(runtime, opts, logger));
|
|
48
|
+
}, {
|
|
49
|
+
descriptors: [
|
|
50
|
+
{
|
|
51
|
+
name: "memory",
|
|
52
|
+
description: "Manage LibraVDB memory",
|
|
53
|
+
hasSubcommands: true,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function ensureCommand(parent, name) {
|
|
59
|
+
const existing = parent.commands?.find((command) => {
|
|
60
|
+
if (typeof command.name === "function") {
|
|
61
|
+
return command.name() === name;
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
});
|
|
65
|
+
if (existing) {
|
|
66
|
+
return existing;
|
|
67
|
+
}
|
|
68
|
+
return parent.command(name);
|
|
69
|
+
}
|
|
70
|
+
async function runStatus(runtime, cfg, logger) {
|
|
71
|
+
try {
|
|
72
|
+
const rpc = await runtime.getRpc();
|
|
73
|
+
const status = await rpc.call("status", {});
|
|
74
|
+
console.table({
|
|
75
|
+
Sidecar: status.ok ? "running" : "down",
|
|
76
|
+
"Turns stored": status.turnCount ?? 0,
|
|
77
|
+
"Memories stored": status.memoryCount ?? 0,
|
|
78
|
+
"Lifecycle hints": status.lifecycleHintCount ?? 0,
|
|
79
|
+
"Gate threshold": status.gatingThreshold ?? cfg.ingestionGateThreshold ?? 0.35,
|
|
80
|
+
"Abstractive model": status.abstractiveReady ? "ready" : "not provisioned",
|
|
81
|
+
"Embedding profile": status.embeddingProfile ?? "unknown",
|
|
82
|
+
Message: status.message ?? (status.ok ? "ok" : "unavailable"),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logger.error(`LibraVDB status unavailable: ${formatError(error)}`);
|
|
87
|
+
console.table({
|
|
88
|
+
Sidecar: "down",
|
|
89
|
+
"Turns stored": "n/a",
|
|
90
|
+
"Memories stored": "n/a",
|
|
91
|
+
"Lifecycle hints": "n/a",
|
|
92
|
+
"Gate threshold": cfg.ingestionGateThreshold ?? 0.35,
|
|
93
|
+
"Abstractive model": "unknown",
|
|
94
|
+
"Embedding profile": "unknown",
|
|
95
|
+
Message: formatError(error),
|
|
96
|
+
});
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function runFlush(runtime, opts, logger) {
|
|
101
|
+
const namespace = resolveCliNamespace(opts);
|
|
102
|
+
if (!namespace) {
|
|
103
|
+
logger.error("LibraVDB flush requires --user-id <userId> or --session-key <sessionKey>.");
|
|
104
|
+
process.exitCode = 1;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (!opts?.yes) {
|
|
108
|
+
const confirmed = await confirm(`Delete durable memory namespace ${namespace}? [y/N] `);
|
|
109
|
+
if (!confirmed) {
|
|
110
|
+
console.log("Aborted.");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const rpc = await runtime.getRpc();
|
|
116
|
+
await rpc.call("flush_namespace", { namespace });
|
|
117
|
+
console.log(`Deleted durable memory namespace ${namespace}.`);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
logger.error(`LibraVDB flush failed: ${formatError(error)}`);
|
|
121
|
+
process.exitCode = 1;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function runExport(runtime, opts, logger) {
|
|
125
|
+
try {
|
|
126
|
+
const rpc = await runtime.getRpc();
|
|
127
|
+
const result = await rpc.call("export_memory", {
|
|
128
|
+
namespace: resolveCliNamespace(opts),
|
|
129
|
+
});
|
|
130
|
+
for (const record of result.records ?? []) {
|
|
131
|
+
stdout.write(`${JSON.stringify(record)}\n`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
logger.error(`LibraVDB export failed: ${formatError(error)}`);
|
|
136
|
+
process.exitCode = 1;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async function runJournal(runtime, opts, logger) {
|
|
140
|
+
try {
|
|
141
|
+
const rpc = await runtime.getRpc();
|
|
142
|
+
const result = await rpc.call("list_lifecycle_journal", {
|
|
143
|
+
sessionId: opts?.sessionId?.trim() || undefined,
|
|
144
|
+
limit: normalizeLimit(opts?.limit),
|
|
145
|
+
});
|
|
146
|
+
for (const record of result.results ?? []) {
|
|
147
|
+
stdout.write(`${JSON.stringify(record)}\n`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
logger.error(`LibraVDB journal lookup failed: ${formatError(error)}`);
|
|
152
|
+
process.exitCode = 1;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function runDreamPromote(runtime, opts, logger) {
|
|
156
|
+
const userId = opts?.userId?.trim();
|
|
157
|
+
const dreamFile = opts?.dreamFile?.trim();
|
|
158
|
+
if (!userId || !dreamFile) {
|
|
159
|
+
logger.error("LibraVDB dream-promote requires --user-id <userId> and --dream-file <path>.");
|
|
160
|
+
process.exitCode = 1;
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const rpc = await runtime.getRpc();
|
|
165
|
+
const result = await promoteDreamDiaryFile(rpc, { userId, diaryPath: dreamFile });
|
|
166
|
+
console.log(`Promoted ${result.promoted ?? 0} dream entr${(result.promoted ?? 0) === 1 ? "y" : "ies"}; rejected ${result.rejected ?? 0}.`);
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
logger.error(`LibraVDB dream promotion failed: ${formatError(error)}`);
|
|
170
|
+
process.exitCode = 1;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function confirm(prompt) {
|
|
174
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
175
|
+
try {
|
|
176
|
+
const answer = await rl.question(prompt);
|
|
177
|
+
return answer.trim().toLowerCase() === "y";
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
rl.close();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function formatError(error) {
|
|
184
|
+
if (error instanceof Error && error.message.trim()) {
|
|
185
|
+
return error.message;
|
|
186
|
+
}
|
|
187
|
+
return String(error);
|
|
188
|
+
}
|
|
189
|
+
function normalizeLimit(limit) {
|
|
190
|
+
if (typeof limit === "number" && Number.isFinite(limit) && limit > 0) {
|
|
191
|
+
return Math.floor(limit);
|
|
192
|
+
}
|
|
193
|
+
if (typeof limit === "string") {
|
|
194
|
+
const parsed = Number.parseInt(limit, 10);
|
|
195
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
196
|
+
return parsed;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
function resolveCliNamespace(opts) {
|
|
202
|
+
const userId = opts?.userId?.trim();
|
|
203
|
+
const sessionKey = opts?.sessionKey?.trim();
|
|
204
|
+
if (!userId && !sessionKey) {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
return resolveDurableNamespace({ userId, sessionKey });
|
|
208
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { PluginRuntime } from "./plugin-runtime.js";
|
|
2
|
+
import type { LoggerLike, PluginConfig, RecallCache, SearchResult } from "./types.js";
|
|
3
|
+
import { AssembleContextInternalResponse } from "@xdarkicex/libravdb-contracts";
|
|
4
|
+
export declare function buildContextEngineFactory(runtime: PluginRuntime, cfg: PluginConfig, recallCache: RecallCache<SearchResult>, logger?: LoggerLike): {
|
|
5
|
+
info: {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
ownsCompaction: boolean;
|
|
9
|
+
};
|
|
10
|
+
ownsCompaction: boolean;
|
|
11
|
+
bootstrap(args: {
|
|
12
|
+
sessionId: string;
|
|
13
|
+
sessionKey?: string;
|
|
14
|
+
userId?: string;
|
|
15
|
+
}): Promise<any>;
|
|
16
|
+
ingest(args: {
|
|
17
|
+
sessionId: string;
|
|
18
|
+
sessionKey?: string;
|
|
19
|
+
userId?: string;
|
|
20
|
+
message: {
|
|
21
|
+
role: string;
|
|
22
|
+
content: string;
|
|
23
|
+
id?: string;
|
|
24
|
+
};
|
|
25
|
+
isHeartbeat?: boolean;
|
|
26
|
+
}): Promise<any>;
|
|
27
|
+
assemble(args: {
|
|
28
|
+
sessionId: string;
|
|
29
|
+
sessionKey?: string;
|
|
30
|
+
userId?: string;
|
|
31
|
+
messages: Array<{
|
|
32
|
+
role: string;
|
|
33
|
+
content: string;
|
|
34
|
+
id?: string;
|
|
35
|
+
}>;
|
|
36
|
+
tokenBudget: number;
|
|
37
|
+
prompt?: string;
|
|
38
|
+
}): Promise<AssembleContextInternalResponse>;
|
|
39
|
+
compact(args: {
|
|
40
|
+
sessionId: string;
|
|
41
|
+
force?: boolean;
|
|
42
|
+
targetSize?: number;
|
|
43
|
+
}): Promise<any>;
|
|
44
|
+
afterTurn(args: {
|
|
45
|
+
sessionId: string;
|
|
46
|
+
sessionKey?: string;
|
|
47
|
+
userId?: string;
|
|
48
|
+
messages: Array<{
|
|
49
|
+
role: string;
|
|
50
|
+
content: string;
|
|
51
|
+
id?: string;
|
|
52
|
+
}>;
|
|
53
|
+
prePromptMessageCount?: number;
|
|
54
|
+
isHeartbeat?: boolean;
|
|
55
|
+
}): Promise<any>;
|
|
56
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export function buildContextEngineFactory(runtime, cfg, recallCache, logger = console) {
|
|
2
|
+
return {
|
|
3
|
+
info: { id: "libravdb-memory", name: "LibraVDB Memory", ownsCompaction: true },
|
|
4
|
+
ownsCompaction: true,
|
|
5
|
+
async bootstrap(args) {
|
|
6
|
+
const kernel = runtime.getKernel();
|
|
7
|
+
if (kernel) {
|
|
8
|
+
try {
|
|
9
|
+
await kernel.initializeSession({
|
|
10
|
+
clientId: "openclaw-ts-wrapper",
|
|
11
|
+
clientCapabilities: [{ name: "grpc", version: "1.0" }]
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
// Proceed even if initialize session fails or doesn't return nonce if secret optional
|
|
16
|
+
}
|
|
17
|
+
return await kernel.bootstrapSession({
|
|
18
|
+
sessionId: args.sessionId,
|
|
19
|
+
sessionKey: args.sessionKey,
|
|
20
|
+
userId: args.userId,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const rpc = await runtime.getRpc();
|
|
24
|
+
return await rpc.call("bootstrap_session_kernel", args);
|
|
25
|
+
},
|
|
26
|
+
async ingest(args) {
|
|
27
|
+
const kernel = runtime.getKernel();
|
|
28
|
+
if (kernel) {
|
|
29
|
+
return await kernel.ingestMessage({
|
|
30
|
+
sessionId: args.sessionId,
|
|
31
|
+
sessionKey: args.sessionKey,
|
|
32
|
+
userId: args.userId,
|
|
33
|
+
message: args.message,
|
|
34
|
+
isHeartbeat: args.isHeartbeat,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const rpc = await runtime.getRpc();
|
|
38
|
+
return await rpc.call("ingest_message_kernel", args);
|
|
39
|
+
},
|
|
40
|
+
async assemble(args) {
|
|
41
|
+
const kernel = runtime.getKernel();
|
|
42
|
+
if (kernel) {
|
|
43
|
+
return await kernel.assembleContext({
|
|
44
|
+
sessionId: args.sessionId,
|
|
45
|
+
sessionKey: args.sessionKey,
|
|
46
|
+
userId: args.userId,
|
|
47
|
+
queryText: args.prompt ?? "",
|
|
48
|
+
visibleMessages: args.messages,
|
|
49
|
+
tokenBudget: args.tokenBudget,
|
|
50
|
+
config: {},
|
|
51
|
+
emitDebug: true
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const rpc = await runtime.getRpc();
|
|
55
|
+
const resp = await rpc.call("assemble_context_internal", {
|
|
56
|
+
sessionId: args.sessionId,
|
|
57
|
+
sessionKey: args.sessionKey,
|
|
58
|
+
userId: args.userId,
|
|
59
|
+
messages: args.messages,
|
|
60
|
+
tokenBudget: args.tokenBudget,
|
|
61
|
+
prompt: args.prompt,
|
|
62
|
+
emitDebug: true,
|
|
63
|
+
config: {
|
|
64
|
+
useSessionRecallProjection: cfg.useSessionRecallProjection,
|
|
65
|
+
useSessionSummarySearchExperiment: cfg.useSessionSummarySearchExperiment,
|
|
66
|
+
tokenBudgetFraction: cfg.tokenBudgetFraction,
|
|
67
|
+
authoredHardBudgetFraction: cfg.authoredHardBudgetFraction,
|
|
68
|
+
authoredSoftBudgetFraction: cfg.authoredSoftBudgetFraction,
|
|
69
|
+
elevatedGuidanceBudgetFraction: cfg.elevatedGuidanceBudgetFraction,
|
|
70
|
+
topK: cfg.topK,
|
|
71
|
+
continuityMinTurns: cfg.continuityMinTurns,
|
|
72
|
+
continuityTailBudgetTokens: cfg.continuityTailBudgetTokens,
|
|
73
|
+
continuityPriorContextTokens: cfg.continuityPriorContextTokens,
|
|
74
|
+
compactThreshold: cfg.compactThreshold,
|
|
75
|
+
compactSessionTokenBudget: cfg.compactSessionTokenBudget,
|
|
76
|
+
section7Theta1: cfg.section7Theta1,
|
|
77
|
+
section7Kappa: cfg.section7Kappa,
|
|
78
|
+
section7HopEta: cfg.section7HopEta,
|
|
79
|
+
section7HopThreshold: cfg.section7HopThreshold,
|
|
80
|
+
section7CoarseTopK: cfg.section7CoarseTopK,
|
|
81
|
+
section7SecondPassTopK: cfg.section7SecondPassTopK,
|
|
82
|
+
section7AuthorityRecencyLambda: cfg.section7AuthorityRecencyLambda,
|
|
83
|
+
section7AuthorityRecencyWeight: cfg.section7AuthorityRecencyWeight,
|
|
84
|
+
section7AuthorityFrequencyWeight: cfg.section7AuthorityFrequencyWeight,
|
|
85
|
+
section7AuthorityAuthoredWeight: cfg.section7AuthorityAuthoredWeight,
|
|
86
|
+
recoveryFloorScore: cfg.recoveryFloorScore,
|
|
87
|
+
recoveryMinTopK: cfg.recoveryMinTopK,
|
|
88
|
+
recoveryMinConfidenceMean: cfg.recoveryMinConfidenceMean,
|
|
89
|
+
recencyLambdaSession: cfg.recencyLambdaSession,
|
|
90
|
+
recencyLambdaUser: cfg.recencyLambdaUser,
|
|
91
|
+
recencyLambdaGlobal: cfg.recencyLambdaGlobal,
|
|
92
|
+
ingestionGateThreshold: cfg.ingestionGateThreshold,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
return resp;
|
|
96
|
+
},
|
|
97
|
+
async compact(args) {
|
|
98
|
+
const kernel = runtime.getKernel();
|
|
99
|
+
if (kernel) {
|
|
100
|
+
return await kernel.compactSession({
|
|
101
|
+
sessionId: args.sessionId,
|
|
102
|
+
force: args.force,
|
|
103
|
+
targetSize: args.targetSize,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const rpc = await runtime.getRpc();
|
|
107
|
+
return await rpc.call("compact_session", args);
|
|
108
|
+
},
|
|
109
|
+
async afterTurn(args) {
|
|
110
|
+
const kernel = runtime.getKernel();
|
|
111
|
+
if (kernel) {
|
|
112
|
+
return await kernel.afterTurn({
|
|
113
|
+
sessionId: args.sessionId,
|
|
114
|
+
sessionKey: args.sessionKey,
|
|
115
|
+
userId: args.userId,
|
|
116
|
+
messages: args.messages,
|
|
117
|
+
prePromptMessageCount: args.prePromptMessageCount,
|
|
118
|
+
isHeartbeat: args.isHeartbeat,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const rpc = await runtime.getRpc();
|
|
122
|
+
return await rpc.call("after_turn_kernel", args);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { LoggerLike, PluginConfig } from "./types.js";
|
|
2
|
+
type Disposable = {
|
|
3
|
+
close(): void;
|
|
4
|
+
};
|
|
5
|
+
interface RpcLike {
|
|
6
|
+
call<T>(method: string, params: unknown): Promise<T>;
|
|
7
|
+
}
|
|
8
|
+
type RpcGetterLike = () => Promise<RpcLike>;
|
|
9
|
+
interface FsWatcherLike extends Disposable {
|
|
10
|
+
on(event: "error", handler: (error: Error) => void): void;
|
|
11
|
+
}
|
|
12
|
+
interface FsApi {
|
|
13
|
+
readFile(file: string): Promise<Uint8Array>;
|
|
14
|
+
stat(file: string): Promise<{
|
|
15
|
+
size: number;
|
|
16
|
+
mtimeMs: number;
|
|
17
|
+
}>;
|
|
18
|
+
watch(dir: string, onChange: (event: string, filename: string | Buffer | null) => void): FsWatcherLike;
|
|
19
|
+
}
|
|
20
|
+
export interface DreamPromotionHandle {
|
|
21
|
+
start(): Promise<void>;
|
|
22
|
+
refresh(): Promise<void>;
|
|
23
|
+
stop(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
export interface DreamPromotionCandidate {
|
|
26
|
+
text: string;
|
|
27
|
+
score: number;
|
|
28
|
+
recallCount: number;
|
|
29
|
+
uniqueQueries: number;
|
|
30
|
+
section: string;
|
|
31
|
+
line: number;
|
|
32
|
+
}
|
|
33
|
+
interface DreamPromotionResult {
|
|
34
|
+
promoted?: number;
|
|
35
|
+
rejected?: number;
|
|
36
|
+
}
|
|
37
|
+
export declare function createDreamPromotionHandle(cfg: PluginConfig, getRpc: RpcGetterLike, logger?: LoggerLike, fsApi?: FsApi): DreamPromotionHandle;
|
|
38
|
+
export declare function promoteDreamDiaryFile(rpc: RpcLike, opts: {
|
|
39
|
+
userId: string;
|
|
40
|
+
diaryPath: string;
|
|
41
|
+
text?: string;
|
|
42
|
+
fileHash?: string;
|
|
43
|
+
sourceSize?: number;
|
|
44
|
+
sourceMtimeMs?: number;
|
|
45
|
+
}): Promise<DreamPromotionResult>;
|
|
46
|
+
export declare function parseDreamPromotionCandidates(text: string): DreamPromotionCandidate[];
|
|
47
|
+
export {};
|