@xdarkicex/openclaw-memory-libravdb 1.8.5 → 1.8.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/README.md +15 -3
- package/dist/context-engine.d.ts +5 -1
- package/dist/context-engine.js +51 -1
- package/dist/index.js +48 -1
- package/docs/yaml/default-gguf.yaml +52 -0
- package/docs/yaml/default-onnx.yaml +47 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -318,12 +318,22 @@ libravdbd migrate --from ~/.libravdbd/data.libravdb --tenant <tenantId>
|
|
|
318
318
|
|
|
319
319
|
## Vector Service Configuration (YAML) & Kubernetes
|
|
320
320
|
|
|
321
|
-
`libravdbd` is
|
|
322
|
-
|
|
321
|
+
`libravdbd` is configured via environment variables or a YAML configuration file. The vector service looks for a config file in this order:
|
|
322
|
+
|
|
323
|
+
1. `LIBRAVDB_CONFIG=/path/to/config.yaml` (env var — set this for custom paths)
|
|
323
324
|
2. `/etc/libravdbd/config.yaml`
|
|
324
325
|
3. `~/.libravdbd/config.yaml`
|
|
325
326
|
|
|
326
|
-
|
|
327
|
+
Env vars override YAML values. All fields are optional — the daemon ships with sensible defaults.
|
|
328
|
+
|
|
329
|
+
**Reference YAML files:**
|
|
330
|
+
|
|
331
|
+
| Backend | File | Description |
|
|
332
|
+
|---------|------|-------------|
|
|
333
|
+
| GGUF (recommended) | [`docs/yaml/default-gguf.yaml`](docs/yaml/default-gguf.yaml) | llama.cpp backend, 3-5x faster on CPU |
|
|
334
|
+
| ONNX (fallback) | [`docs/yaml/default-onnx.yaml`](docs/yaml/default-onnx.yaml) | ONNX Runtime backend, wider platform support |
|
|
335
|
+
|
|
336
|
+
**Kubernetes example** (multi-tenant mode with GGUF):
|
|
327
337
|
|
|
328
338
|
```yaml
|
|
329
339
|
# /etc/libravdbd/config.yaml
|
|
@@ -333,6 +343,7 @@ tenant_max_open: 128
|
|
|
333
343
|
grpc_endpoint: "tcp:0.0.0.0:9090"
|
|
334
344
|
embedding_backend: "gguf"
|
|
335
345
|
embedding_profile: "nomic-embed-text-v1.5"
|
|
346
|
+
llama_lib_path: "/var/lib/libravdbd/models/llama/llama-linux-amd64/lib/libllama.so"
|
|
336
347
|
drain_timeout: "25s" # Must be less than k8s terminationGracePeriodSeconds
|
|
337
348
|
```
|
|
338
349
|
|
|
@@ -480,3 +491,4 @@ service checkout. For the full source workflow, read [Development](./docs/develo
|
|
|
480
491
|
- default data path: `$HOME/.libravdbd/data_nomic-embed-text-v1_5.libravdb`
|
|
481
492
|
- default macOS/Linux endpoint: `unix:$HOME/.libravdbd/run/libravdb.sock`
|
|
482
493
|
- default Windows endpoint: `tcp:127.0.0.1:37421`
|
|
494
|
+
|
package/dist/context-engine.d.ts
CHANGED
|
@@ -124,7 +124,11 @@ export declare function buildContextEngineFactory(runtime: PluginRuntime, cfg: P
|
|
|
124
124
|
isHeartbeat?: boolean;
|
|
125
125
|
tokenBudget?: number;
|
|
126
126
|
runtimeContext?: Record<string, unknown>;
|
|
127
|
-
}): Promise<import("@xdarkicex/libravdb-contracts").AfterTurnKernelResponse
|
|
127
|
+
}): Promise<import("@xdarkicex/libravdb-contracts").AfterTurnKernelResponse | {
|
|
128
|
+
ok: boolean;
|
|
129
|
+
skipped: boolean;
|
|
130
|
+
reason: string;
|
|
131
|
+
}>;
|
|
128
132
|
prepareSubagentSpawn(params: {
|
|
129
133
|
parentSessionKey: string;
|
|
130
134
|
childSessionKey: string;
|
package/dist/context-engine.js
CHANGED
|
@@ -1626,6 +1626,40 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
1626
1626
|
: {}),
|
|
1627
1627
|
};
|
|
1628
1628
|
}
|
|
1629
|
+
async function injectContinuityContext(params) {
|
|
1630
|
+
try {
|
|
1631
|
+
const continuityHits = await params.client.searchTextCollections({
|
|
1632
|
+
collections: [resolveUserCollection(params.userId)],
|
|
1633
|
+
text: "__session_continuity__",
|
|
1634
|
+
k: 1,
|
|
1635
|
+
excludeByCollection: {},
|
|
1636
|
+
});
|
|
1637
|
+
const continuityHit = continuityHits.results?.find((r) => r.id === "__session_continuity__");
|
|
1638
|
+
if (!continuityHit)
|
|
1639
|
+
return null;
|
|
1640
|
+
let meta = {};
|
|
1641
|
+
if (continuityHit.metadataJson && continuityHit.metadataJson.length > 0) {
|
|
1642
|
+
try {
|
|
1643
|
+
meta = JSON.parse(new TextDecoder().decode(continuityHit.metadataJson));
|
|
1644
|
+
}
|
|
1645
|
+
catch { /* metadata parse failed, use empty */ }
|
|
1646
|
+
}
|
|
1647
|
+
const summaryId = meta.summary_id;
|
|
1648
|
+
if (!summaryId)
|
|
1649
|
+
return null;
|
|
1650
|
+
const expanded = await params.client.expandSummary({
|
|
1651
|
+
sessionId: meta.session_id ?? params.sessionId,
|
|
1652
|
+
summaryId,
|
|
1653
|
+
maxDepth: 2,
|
|
1654
|
+
});
|
|
1655
|
+
if (!expanded.text)
|
|
1656
|
+
return null;
|
|
1657
|
+
return '<continuity_context>\nThe following is a summary of the previous session. Use it for context about what was discussed before the reset.\n' + expanded.text + '\n</continuity_context>';
|
|
1658
|
+
}
|
|
1659
|
+
catch {
|
|
1660
|
+
return null;
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1629
1663
|
async function runCompaction(args) {
|
|
1630
1664
|
const request = buildCompactSessionRequest(args);
|
|
1631
1665
|
try {
|
|
@@ -1857,7 +1891,18 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
1857
1891
|
emitDebug: true,
|
|
1858
1892
|
});
|
|
1859
1893
|
const assembled = normalizeAssembleResult(resp, args.messages);
|
|
1860
|
-
|
|
1894
|
+
const continuityContext = await injectContinuityContext({
|
|
1895
|
+
client,
|
|
1896
|
+
userId,
|
|
1897
|
+
sessionId,
|
|
1898
|
+
logger,
|
|
1899
|
+
tokenBudget: args.tokenBudget,
|
|
1900
|
+
systemPromptAddition: assembled.systemPromptAddition,
|
|
1901
|
+
});
|
|
1902
|
+
const withContinuity = continuityContext
|
|
1903
|
+
? { ...assembled, systemPromptAddition: appendSystemPromptAddition(assembled.systemPromptAddition, continuityContext) }
|
|
1904
|
+
: assembled;
|
|
1905
|
+
let enforced = enforceTokenBudgetInvariant(await augmentWithExactRecall(withContinuity, {
|
|
1861
1906
|
queryText: strippedPrompt || (messages[messages.length - 1]?.content ?? ""),
|
|
1862
1907
|
userId,
|
|
1863
1908
|
sessionId,
|
|
@@ -1974,6 +2019,11 @@ export function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
1974
2019
|
`overlapIndex=${overlapIndex} startIndex=${startIndex} ` +
|
|
1975
2020
|
`prePromptMessageCount=${args.prePromptMessageCount ?? "unknown"} ` +
|
|
1976
2021
|
`heartbeat=${args.isHeartbeat ?? false}`);
|
|
2022
|
+
if (newMessages.length === 0) {
|
|
2023
|
+
logger.info?.(`LibraVDB afterTurn skipped sessionId=${sessionId} reason=no-new-messages ` +
|
|
2024
|
+
`messageCount=${messages.length} overlapIndex=${overlapIndex}`);
|
|
2025
|
+
return { ok: true, skipped: true, reason: "no-new-messages" };
|
|
2026
|
+
}
|
|
1977
2027
|
try {
|
|
1978
2028
|
const client = await runtime.getClient();
|
|
1979
2029
|
const currentTokenCount = normalizeCurrentTokenCount(typeof args.runtimeContext?.currentTokenCount === "number"
|
package/dist/index.js
CHANGED
|
@@ -28144,6 +28144,38 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
28144
28144
|
...typeof cfg.continuityPriorContextTokens === "number" ? { continuityPriorContextTokens: cfg.continuityPriorContextTokens } : {}
|
|
28145
28145
|
};
|
|
28146
28146
|
}
|
|
28147
|
+
async function injectContinuityContext(params) {
|
|
28148
|
+
try {
|
|
28149
|
+
const continuityHits = await params.client.searchTextCollections({
|
|
28150
|
+
collections: [resolveUserCollection(params.userId)],
|
|
28151
|
+
text: "__session_continuity__",
|
|
28152
|
+
k: 1,
|
|
28153
|
+
excludeByCollection: {}
|
|
28154
|
+
});
|
|
28155
|
+
const continuityHit = continuityHits.results?.find(
|
|
28156
|
+
(r) => r.id === "__session_continuity__"
|
|
28157
|
+
);
|
|
28158
|
+
if (!continuityHit) return null;
|
|
28159
|
+
let meta = {};
|
|
28160
|
+
if (continuityHit.metadataJson && continuityHit.metadataJson.length > 0) {
|
|
28161
|
+
try {
|
|
28162
|
+
meta = JSON.parse(new TextDecoder().decode(continuityHit.metadataJson));
|
|
28163
|
+
} catch {
|
|
28164
|
+
}
|
|
28165
|
+
}
|
|
28166
|
+
const summaryId = meta.summary_id;
|
|
28167
|
+
if (!summaryId) return null;
|
|
28168
|
+
const expanded = await params.client.expandSummary({
|
|
28169
|
+
sessionId: meta.session_id ?? params.sessionId,
|
|
28170
|
+
summaryId,
|
|
28171
|
+
maxDepth: 2
|
|
28172
|
+
});
|
|
28173
|
+
if (!expanded.text) return null;
|
|
28174
|
+
return "<continuity_context>\nThe following is a summary of the previous session. Use it for context about what was discussed before the reset.\n" + expanded.text + "\n</continuity_context>";
|
|
28175
|
+
} catch {
|
|
28176
|
+
return null;
|
|
28177
|
+
}
|
|
28178
|
+
}
|
|
28147
28179
|
async function runCompaction(args) {
|
|
28148
28180
|
const request3 = buildCompactSessionRequest(args);
|
|
28149
28181
|
try {
|
|
@@ -28376,8 +28408,17 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
28376
28408
|
emitDebug: true
|
|
28377
28409
|
});
|
|
28378
28410
|
const assembled = normalizeAssembleResult(resp, args.messages);
|
|
28411
|
+
const continuityContext = await injectContinuityContext({
|
|
28412
|
+
client,
|
|
28413
|
+
userId,
|
|
28414
|
+
sessionId,
|
|
28415
|
+
logger,
|
|
28416
|
+
tokenBudget: args.tokenBudget,
|
|
28417
|
+
systemPromptAddition: assembled.systemPromptAddition
|
|
28418
|
+
});
|
|
28419
|
+
const withContinuity = continuityContext ? { ...assembled, systemPromptAddition: appendSystemPromptAddition(assembled.systemPromptAddition, continuityContext) } : assembled;
|
|
28379
28420
|
let enforced = enforceTokenBudgetInvariant(
|
|
28380
|
-
await augmentWithExactRecall(
|
|
28421
|
+
await augmentWithExactRecall(withContinuity, {
|
|
28381
28422
|
queryText: strippedPrompt || (messages[messages.length - 1]?.content ?? ""),
|
|
28382
28423
|
userId,
|
|
28383
28424
|
sessionId,
|
|
@@ -28501,6 +28542,12 @@ function buildContextEngineFactory(runtime, cfg, logger = console) {
|
|
|
28501
28542
|
logger.info?.(
|
|
28502
28543
|
`LibraVDB afterTurn sessionId=${sessionId} userId=${userId} messageCount=${messages.length} newMessages=${newMessages.length} overlapIndex=${overlapIndex} startIndex=${startIndex} prePromptMessageCount=${args.prePromptMessageCount ?? "unknown"} heartbeat=${args.isHeartbeat ?? false}`
|
|
28503
28544
|
);
|
|
28545
|
+
if (newMessages.length === 0) {
|
|
28546
|
+
logger.info?.(
|
|
28547
|
+
`LibraVDB afterTurn skipped sessionId=${sessionId} reason=no-new-messages messageCount=${messages.length} overlapIndex=${overlapIndex}`
|
|
28548
|
+
);
|
|
28549
|
+
return { ok: true, skipped: true, reason: "no-new-messages" };
|
|
28550
|
+
}
|
|
28504
28551
|
try {
|
|
28505
28552
|
const client = await runtime.getClient();
|
|
28506
28553
|
const currentTokenCount = normalizeCurrentTokenCount(
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Vector Service — GGUF backend (recommended)
|
|
2
|
+
#
|
|
3
|
+
# Place at /etc/libravdbd/config.yaml, ~/.libravdbd/config.yaml,
|
|
4
|
+
# or any path pointed to by LIBRAVDB_CONFIG.
|
|
5
|
+
#
|
|
6
|
+
# GGUF/llama.cpp is 3-5x faster than ONNX on CPU.
|
|
7
|
+
# Requires libllama.dylib/.so and a .gguf model file.
|
|
8
|
+
# Provision: scripts/provision.sh (shipped with the daemon release).
|
|
9
|
+
#
|
|
10
|
+
# All fields are optional. Env vars override YAML values.
|
|
11
|
+
|
|
12
|
+
# --- storage ---
|
|
13
|
+
db_path: ""
|
|
14
|
+
|
|
15
|
+
# --- transport ---
|
|
16
|
+
grpc_endpoint: "" # unix:/path/to/sock or tcp:host:port
|
|
17
|
+
|
|
18
|
+
# --- embedding ---
|
|
19
|
+
embedding_backend: gguf # gguf only — does not fall back to ONNX
|
|
20
|
+
embedding_profile: nomic-embed-text-v1.5
|
|
21
|
+
fallback_profile: bge-small-en-v1.5
|
|
22
|
+
embedding_normalize: true
|
|
23
|
+
embedding_dimensions: 768
|
|
24
|
+
|
|
25
|
+
# --- gguf ---
|
|
26
|
+
llama_lib_path: "" # path to libllama.dylib/.so (empty = auto-resolve)
|
|
27
|
+
# Linux example: /var/lib/libravdbd/models/llama/llama-linux-amd64/lib/libllama.so
|
|
28
|
+
# macOS example: /opt/homebrew/opt/libravdbd/models/llama/llama-darwin-arm64/lib/libllama.dylib
|
|
29
|
+
|
|
30
|
+
# --- summarizer ---
|
|
31
|
+
summarizer_backend: bundled # bundled (=extractive, always used regardless)
|
|
32
|
+
|
|
33
|
+
# --- gating ---
|
|
34
|
+
gating_threshold: 0.35
|
|
35
|
+
gating_w1c: 0.35
|
|
36
|
+
gating_w2c: 0.40
|
|
37
|
+
gating_w3c: 0.25
|
|
38
|
+
gating_w1t: 0.40
|
|
39
|
+
gating_w2t: 0.35
|
|
40
|
+
gating_w3t: 0.25
|
|
41
|
+
gating_tech_norm: 1.5
|
|
42
|
+
|
|
43
|
+
# --- timeouts ---
|
|
44
|
+
embed_timeout: 5s
|
|
45
|
+
drain_timeout: 25s
|
|
46
|
+
|
|
47
|
+
# --- circuit breaker ---
|
|
48
|
+
circuit_max_failures: 3
|
|
49
|
+
circuit_cooldown: 60s
|
|
50
|
+
|
|
51
|
+
# --- lifecycle ---
|
|
52
|
+
lifecycle_journal_max_entries: 500
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Vector Service — ONNX backend (default fallback)
|
|
2
|
+
#
|
|
3
|
+
# Place at /etc/libravdbd/config.yaml, ~/.libravdbd/config.yaml,
|
|
4
|
+
# or any path pointed to by LIBRAVDB_CONFIG.
|
|
5
|
+
#
|
|
6
|
+
# All fields are optional. Env vars override YAML values.
|
|
7
|
+
|
|
8
|
+
# --- storage ---
|
|
9
|
+
db_path: ""
|
|
10
|
+
|
|
11
|
+
# --- transport ---
|
|
12
|
+
grpc_endpoint: "" # unix:/path/to/sock or tcp:host:port
|
|
13
|
+
|
|
14
|
+
# --- embedding ---
|
|
15
|
+
embedding_backend: bundled # bundled (=gguf-first, onnx fallback), onnx-local, gguf, remote
|
|
16
|
+
embedding_profile: nomic-embed-text-v1.5
|
|
17
|
+
fallback_profile: bge-small-en-v1.5
|
|
18
|
+
embedding_model_path: ""
|
|
19
|
+
embedding_tokenizer_path: ""
|
|
20
|
+
embedding_dimensions: 768
|
|
21
|
+
embedding_normalize: true
|
|
22
|
+
onnx_runtime_path: "" # path to libonnxruntime.dylib/.so (empty = auto-resolve)
|
|
23
|
+
onnx_device: "" # auto, cpu, cuda, coreml, openvino, directml
|
|
24
|
+
|
|
25
|
+
# --- summarizer ---
|
|
26
|
+
summarizer_backend: bundled # bundled (=extractive, always used regardless)
|
|
27
|
+
|
|
28
|
+
# --- gating ---
|
|
29
|
+
gating_threshold: 0.35
|
|
30
|
+
gating_w1c: 0.35
|
|
31
|
+
gating_w2c: 0.40
|
|
32
|
+
gating_w3c: 0.25
|
|
33
|
+
gating_w1t: 0.40
|
|
34
|
+
gating_w2t: 0.35
|
|
35
|
+
gating_w3t: 0.25
|
|
36
|
+
gating_tech_norm: 1.5
|
|
37
|
+
|
|
38
|
+
# --- timeouts ---
|
|
39
|
+
embed_timeout: 5s
|
|
40
|
+
drain_timeout: 25s
|
|
41
|
+
|
|
42
|
+
# --- circuit breaker ---
|
|
43
|
+
circuit_max_failures: 3
|
|
44
|
+
circuit_cooldown: 60s
|
|
45
|
+
|
|
46
|
+
# --- lifecycle ---
|
|
47
|
+
lifecycle_journal_max_entries: 500
|
package/openclaw.plugin.json
CHANGED