memory-braid 0.2.0 → 0.3.3
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 +250 -8
- package/openclaw.plugin.json +34 -11
- package/package.json +2 -1
- package/src/config.ts +58 -15
- package/src/entities.ts +354 -0
- package/src/extract.ts +155 -28
- package/src/index.ts +176 -2
- package/src/mem0-client.ts +32 -3
- package/src/state.ts +71 -2
package/README.md
CHANGED
|
@@ -7,12 +7,182 @@ Memory Braid is an OpenClaw `kind: "memory"` plugin that augments local memory s
|
|
|
7
7
|
- Hybrid recall: local memory + Mem0, merged with weighted RRF.
|
|
8
8
|
- Install-time bootstrap import: indexes existing `MEMORY.md`, `memory.md`, `memory/**/*.md`, and recent sessions.
|
|
9
9
|
- Periodic reconcile: keeps remote Mem0 chunks updated and deletes stale remote chunks.
|
|
10
|
-
- Capture pipeline:
|
|
10
|
+
- Capture pipeline modes: `local`, `hybrid`, `ml`.
|
|
11
|
+
- Optional entity extraction: multilingual NER with canonical `entity://...` URIs in memory metadata.
|
|
11
12
|
- Structured debug logs for troubleshooting and tuning.
|
|
12
13
|
|
|
13
14
|
## Install
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
### Install from npm (recommended)
|
|
17
|
+
|
|
18
|
+
On the target machine:
|
|
19
|
+
|
|
20
|
+
1. Install from npm:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
openclaw plugins install memory-braid@0.3.3
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
2. Rebuild native dependencies inside the installed extension:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd ~/.openclaw/extensions/memory-braid
|
|
30
|
+
npm rebuild sqlite3 sharp
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Why this step exists:
|
|
34
|
+
- OpenClaw plugin installs run `npm install --omit=dev --ignore-scripts` for safety.
|
|
35
|
+
- This behavior is currently not user-overridable from `openclaw plugins install`.
|
|
36
|
+
- `memory-braid` needs native artifacts for `sqlite3` (required by Mem0 OSS) and `sharp` (used by `@xenova/transformers`).
|
|
37
|
+
|
|
38
|
+
3. Enable and set as active memory slot:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
openclaw plugins enable memory-braid
|
|
42
|
+
openclaw config set plugins.slots.memory memory-braid
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
4. Restart gateway:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
openclaw gateway restart
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
5. Confirm plugin is loaded:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
openclaw plugins info memory-braid
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Expected:
|
|
58
|
+
- `Status: loaded`
|
|
59
|
+
- `Tools: memory_search, memory_get`
|
|
60
|
+
- `Services: memory-braid-service`
|
|
61
|
+
|
|
62
|
+
### Install from local path (development)
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
openclaw plugins install --link /absolute/path/to/memory-braid
|
|
66
|
+
openclaw plugins enable memory-braid
|
|
67
|
+
openclaw config set plugins.slots.memory memory-braid
|
|
68
|
+
openclaw gateway restart
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If you install from npm and see native module errors like:
|
|
72
|
+
|
|
73
|
+
- `Could not locate the bindings file` (sqlite3)
|
|
74
|
+
- `Cannot find module ... sharp-*.node`
|
|
75
|
+
|
|
76
|
+
run:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cd ~/.openclaw/extensions/memory-braid
|
|
80
|
+
npm rebuild sqlite3 sharp
|
|
81
|
+
openclaw gateway restart
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Quick start: hybrid capture + multilingual NER
|
|
85
|
+
|
|
86
|
+
Add this under `plugins.entries["memory-braid"].config` in your OpenClaw config:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mem0": {
|
|
91
|
+
"mode": "oss",
|
|
92
|
+
"ossConfig": {
|
|
93
|
+
"version": "v1.1",
|
|
94
|
+
"embedder": {
|
|
95
|
+
"provider": "openai",
|
|
96
|
+
"config": {
|
|
97
|
+
"apiKey": "${OPENAI_API_KEY}",
|
|
98
|
+
"model": "text-embedding-3-small"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"vectorStore": {
|
|
102
|
+
"provider": "memory",
|
|
103
|
+
"config": {
|
|
104
|
+
"collectionName": "memories",
|
|
105
|
+
"dimension": 1536
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
"llm": {
|
|
109
|
+
"provider": "openai",
|
|
110
|
+
"config": {
|
|
111
|
+
"apiKey": "${OPENAI_API_KEY}",
|
|
112
|
+
"model": "gpt-4o-mini"
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"enableGraph": false
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"capture": {
|
|
119
|
+
"enabled": true,
|
|
120
|
+
"mode": "hybrid",
|
|
121
|
+
"maxItemsPerRun": 6,
|
|
122
|
+
"ml": {
|
|
123
|
+
"provider": "openai",
|
|
124
|
+
"model": "gpt-4o-mini",
|
|
125
|
+
"timeoutMs": 2500
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"entityExtraction": {
|
|
129
|
+
"enabled": true,
|
|
130
|
+
"provider": "multilingual_ner",
|
|
131
|
+
"model": "Xenova/bert-base-multilingual-cased-ner-hrl",
|
|
132
|
+
"minScore": 0.65,
|
|
133
|
+
"maxEntitiesPerMemory": 8,
|
|
134
|
+
"startup": {
|
|
135
|
+
"downloadOnStartup": true,
|
|
136
|
+
"warmupText": "John works at Acme in Berlin."
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"debug": {
|
|
140
|
+
"enabled": true
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Then restart:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
openclaw gateway restart
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Verification checklist
|
|
152
|
+
|
|
153
|
+
1. Check runtime status:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
openclaw plugins info memory-braid
|
|
157
|
+
openclaw gateway status
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
2. Trigger/inspect NER warmup:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
openclaw agent --agent main --message "/memorybraid warmup" --json
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
3. Send a message that should be captured:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
openclaw agent --agent main --message "Remember that Ana works at OpenClaw and likes ramen." --json
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
4. Inspect logs for capture + NER:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
rg -n "memory_braid\\.startup|memory_braid\\.capture|memory_braid\\.entity|memory_braid\\.mem0" ~/.openclaw/logs/gateway.log | tail -n 80
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Expected events:
|
|
179
|
+
- `memory_braid.startup`
|
|
180
|
+
- `memory_braid.entity.model_load`
|
|
181
|
+
- `memory_braid.entity.warmup`
|
|
182
|
+
- `memory_braid.capture.extract`
|
|
183
|
+
- `memory_braid.capture.ml` (for `capture.mode=hybrid|ml`)
|
|
184
|
+
- `memory_braid.entity.extract`
|
|
185
|
+
- `memory_braid.capture.persist`
|
|
16
186
|
|
|
17
187
|
## Self-hosting quick guide
|
|
18
188
|
|
|
@@ -241,14 +411,23 @@ Use this preset when:
|
|
|
241
411
|
},
|
|
242
412
|
"capture": {
|
|
243
413
|
"enabled": true,
|
|
244
|
-
"
|
|
245
|
-
|
|
246
|
-
},
|
|
414
|
+
"mode": "hybrid",
|
|
415
|
+
"maxItemsPerRun": 6,
|
|
247
416
|
"ml": {
|
|
248
417
|
"provider": "openai",
|
|
249
418
|
"model": "gpt-4o-mini",
|
|
250
|
-
"timeoutMs": 2500
|
|
251
|
-
|
|
419
|
+
"timeoutMs": 2500
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
"entityExtraction": {
|
|
423
|
+
"enabled": true,
|
|
424
|
+
"provider": "multilingual_ner",
|
|
425
|
+
"model": "Xenova/bert-base-multilingual-cased-ner-hrl",
|
|
426
|
+
"minScore": 0.65,
|
|
427
|
+
"maxEntitiesPerMemory": 8,
|
|
428
|
+
"startup": {
|
|
429
|
+
"downloadOnStartup": true,
|
|
430
|
+
"warmupText": "John works at Acme in Berlin."
|
|
252
431
|
}
|
|
253
432
|
},
|
|
254
433
|
"dedupe": {
|
|
@@ -266,6 +445,48 @@ Use this preset when:
|
|
|
266
445
|
}
|
|
267
446
|
```
|
|
268
447
|
|
|
448
|
+
## Capture defaults
|
|
449
|
+
|
|
450
|
+
Capture defaults are:
|
|
451
|
+
|
|
452
|
+
- `capture.enabled`: `true`
|
|
453
|
+
- `capture.mode`: `"local"`
|
|
454
|
+
- `capture.maxItemsPerRun`: `6`
|
|
455
|
+
- `capture.ml.provider`: unset
|
|
456
|
+
- `capture.ml.model`: unset
|
|
457
|
+
- `capture.ml.timeoutMs`: `2500`
|
|
458
|
+
|
|
459
|
+
Important behavior:
|
|
460
|
+
|
|
461
|
+
- `capture.mode = "local"`: heuristic-only extraction.
|
|
462
|
+
- `capture.mode = "hybrid"`: heuristic extraction + ML enrichment when ML config is set.
|
|
463
|
+
- `capture.mode = "ml"`: ML-first extraction; falls back to heuristic if ML config/call is unavailable.
|
|
464
|
+
- ML calls run only when both `capture.ml.provider` and `capture.ml.model` are set.
|
|
465
|
+
|
|
466
|
+
## Entity extraction defaults
|
|
467
|
+
|
|
468
|
+
Entity extraction defaults are:
|
|
469
|
+
|
|
470
|
+
- `entityExtraction.enabled`: `false`
|
|
471
|
+
- `entityExtraction.provider`: `"multilingual_ner"`
|
|
472
|
+
- `entityExtraction.model`: `"Xenova/bert-base-multilingual-cased-ner-hrl"`
|
|
473
|
+
- `entityExtraction.minScore`: `0.65`
|
|
474
|
+
- `entityExtraction.maxEntitiesPerMemory`: `8`
|
|
475
|
+
- `entityExtraction.startup.downloadOnStartup`: `true`
|
|
476
|
+
- `entityExtraction.startup.warmupText`: `"John works at Acme in Berlin."`
|
|
477
|
+
|
|
478
|
+
When enabled:
|
|
479
|
+
|
|
480
|
+
- Model cache/download path is `<OPENCLAW_STATE_DIR>/memory-braid/models/entity-extraction` (typically `~/.openclaw/memory-braid/models/entity-extraction`).
|
|
481
|
+
- Captured memories get `metadata.entities` and `metadata.entityUris` (canonical IDs like `entity://person/john-doe`).
|
|
482
|
+
- Startup can pre-download/warm the model (`downloadOnStartup: true`).
|
|
483
|
+
|
|
484
|
+
Warmup command:
|
|
485
|
+
|
|
486
|
+
- `/memorybraid status`
|
|
487
|
+
- `/memorybraid warmup`
|
|
488
|
+
- `/memorybraid warmup --force`
|
|
489
|
+
|
|
269
490
|
## Debugging
|
|
270
491
|
|
|
271
492
|
Set:
|
|
@@ -285,14 +506,35 @@ Set:
|
|
|
285
506
|
Key events:
|
|
286
507
|
|
|
287
508
|
- `memory_braid.startup`
|
|
509
|
+
- `memory_braid.config`
|
|
288
510
|
- `memory_braid.bootstrap.begin|complete|error`
|
|
289
511
|
- `memory_braid.reconcile.begin|progress|complete|error`
|
|
290
|
-
- `memory_braid.search.local|mem0|merge|inject`
|
|
512
|
+
- `memory_braid.search.local|mem0|merge|inject|skip`
|
|
291
513
|
- `memory_braid.capture.extract|ml|persist|skip`
|
|
514
|
+
- `memory_braid.entity.model_load|warmup|extract`
|
|
292
515
|
- `memory_braid.mem0.request|response|error`
|
|
293
516
|
|
|
294
517
|
`debug.includePayloads=true` includes payload fields; otherwise sensitive text fields are omitted.
|
|
295
518
|
|
|
519
|
+
Traceability tips:
|
|
520
|
+
|
|
521
|
+
- Use `runId` to follow one execution end-to-end across capture/search/entity/mem0 events.
|
|
522
|
+
- `memory_braid.capture.persist` includes high-signal counters:
|
|
523
|
+
- `dedupeSkipped`
|
|
524
|
+
- `mem0AddAttempts`
|
|
525
|
+
- `mem0AddWithId`
|
|
526
|
+
- `mem0AddWithoutId`
|
|
527
|
+
- `entityAnnotatedCandidates`
|
|
528
|
+
- `totalEntitiesAttached`
|
|
529
|
+
- `memory_braid.capture.ml` includes `fallbackUsed` and fallback reasons when ML is unavailable.
|
|
530
|
+
- `memory_braid.entity.extract` includes `entityTypes` and `sampleEntityUris`.
|
|
531
|
+
|
|
532
|
+
Example:
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
rg -n "memory_braid\\.|runId\":\"<RUN_ID>\"" ~/.openclaw/logs/gateway.log | tail -n 120
|
|
536
|
+
```
|
|
537
|
+
|
|
296
538
|
## Tests
|
|
297
539
|
|
|
298
540
|
```bash
|
package/openclaw.plugin.json
CHANGED
|
@@ -47,25 +47,48 @@
|
|
|
47
47
|
"additionalProperties": false,
|
|
48
48
|
"properties": {
|
|
49
49
|
"enabled": { "type": "boolean", "default": true },
|
|
50
|
-
"
|
|
50
|
+
"mode": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"enum": ["local", "hybrid", "ml"],
|
|
53
|
+
"default": "local"
|
|
54
|
+
},
|
|
55
|
+
"maxItemsPerRun": { "type": "integer", "minimum": 1, "maximum": 50, "default": 6 },
|
|
56
|
+
"ml": {
|
|
51
57
|
"type": "object",
|
|
52
58
|
"additionalProperties": false,
|
|
53
59
|
"properties": {
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"default": "heuristic"
|
|
58
|
-
}
|
|
60
|
+
"provider": { "type": "string", "enum": ["openai", "anthropic", "gemini"] },
|
|
61
|
+
"model": { "type": "string" },
|
|
62
|
+
"timeoutMs": { "type": "integer", "minimum": 250, "maximum": 30000, "default": 2500 }
|
|
59
63
|
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"entityExtraction": {
|
|
68
|
+
"type": "object",
|
|
69
|
+
"additionalProperties": false,
|
|
70
|
+
"properties": {
|
|
71
|
+
"enabled": { "type": "boolean", "default": false },
|
|
72
|
+
"provider": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"enum": ["multilingual_ner"],
|
|
75
|
+
"default": "multilingual_ner"
|
|
60
76
|
},
|
|
61
|
-
"
|
|
77
|
+
"model": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"default": "Xenova/bert-base-multilingual-cased-ner-hrl"
|
|
80
|
+
},
|
|
81
|
+
"minScore": { "type": "number", "minimum": 0, "maximum": 1, "default": 0.65 },
|
|
82
|
+
"maxEntitiesPerMemory": { "type": "integer", "minimum": 1, "maximum": 50, "default": 8 },
|
|
83
|
+
"startup": {
|
|
62
84
|
"type": "object",
|
|
63
85
|
"additionalProperties": false,
|
|
64
86
|
"properties": {
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
|
|
87
|
+
"downloadOnStartup": { "type": "boolean", "default": true },
|
|
88
|
+
"warmupText": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"default": "John works at Acme in Berlin."
|
|
91
|
+
}
|
|
69
92
|
}
|
|
70
93
|
}
|
|
71
94
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memory-braid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "OpenClaw memory plugin that augments local memory with Mem0, bootstrap import, reconcile, and capture.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"openclaw": ">=2026.2.18"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"@xenova/transformers": "^2.17.2",
|
|
34
35
|
"mem0ai": "^2.2.3"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
package/src/config.ts
CHANGED
|
@@ -20,14 +20,23 @@ export type MemoryBraidConfig = {
|
|
|
20
20
|
};
|
|
21
21
|
capture: {
|
|
22
22
|
enabled: boolean;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
23
|
+
mode: "local" | "hybrid" | "ml";
|
|
24
|
+
maxItemsPerRun: number;
|
|
26
25
|
ml: {
|
|
27
26
|
provider?: "openai" | "anthropic" | "gemini";
|
|
28
27
|
model?: string;
|
|
29
28
|
timeoutMs: number;
|
|
30
|
-
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
entityExtraction: {
|
|
32
|
+
enabled: boolean;
|
|
33
|
+
provider: "multilingual_ner";
|
|
34
|
+
model: string;
|
|
35
|
+
minScore: number;
|
|
36
|
+
maxEntitiesPerMemory: number;
|
|
37
|
+
startup: {
|
|
38
|
+
downloadOnStartup: boolean;
|
|
39
|
+
warmupText: string;
|
|
31
40
|
};
|
|
32
41
|
};
|
|
33
42
|
bootstrap: {
|
|
@@ -84,14 +93,23 @@ const DEFAULTS: MemoryBraidConfig = {
|
|
|
84
93
|
},
|
|
85
94
|
capture: {
|
|
86
95
|
enabled: true,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
},
|
|
96
|
+
mode: "local",
|
|
97
|
+
maxItemsPerRun: 6,
|
|
90
98
|
ml: {
|
|
91
99
|
provider: undefined,
|
|
92
100
|
model: undefined,
|
|
93
101
|
timeoutMs: 2500,
|
|
94
|
-
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
entityExtraction: {
|
|
105
|
+
enabled: false,
|
|
106
|
+
provider: "multilingual_ner",
|
|
107
|
+
model: "Xenova/bert-base-multilingual-cased-ner-hrl",
|
|
108
|
+
minScore: 0.65,
|
|
109
|
+
maxEntitiesPerMemory: 8,
|
|
110
|
+
startup: {
|
|
111
|
+
downloadOnStartup: true,
|
|
112
|
+
warmupText: "John works at Acme in Berlin.",
|
|
95
113
|
},
|
|
96
114
|
},
|
|
97
115
|
bootstrap: {
|
|
@@ -160,7 +178,8 @@ export function parseConfig(raw: unknown): MemoryBraidConfig {
|
|
|
160
178
|
const recall = asRecord(root.recall);
|
|
161
179
|
const merge = asRecord(recall.merge);
|
|
162
180
|
const capture = asRecord(root.capture);
|
|
163
|
-
const
|
|
181
|
+
const entityExtraction = asRecord(root.entityExtraction);
|
|
182
|
+
const entityStartup = asRecord(entityExtraction.startup);
|
|
164
183
|
const ml = asRecord(capture.ml);
|
|
165
184
|
const bootstrap = asRecord(root.bootstrap);
|
|
166
185
|
const reconcile = asRecord(root.reconcile);
|
|
@@ -170,8 +189,11 @@ export function parseConfig(raw: unknown): MemoryBraidConfig {
|
|
|
170
189
|
const debug = asRecord(root.debug);
|
|
171
190
|
|
|
172
191
|
const mode = mem0.mode === "oss" ? "oss" : "cloud";
|
|
173
|
-
const
|
|
174
|
-
|
|
192
|
+
const rawCaptureMode = asString(capture.mode)?.toLowerCase();
|
|
193
|
+
const captureMode =
|
|
194
|
+
rawCaptureMode === "local" || rawCaptureMode === "hybrid" || rawCaptureMode === "ml"
|
|
195
|
+
? rawCaptureMode
|
|
196
|
+
: DEFAULTS.capture.mode;
|
|
175
197
|
|
|
176
198
|
return {
|
|
177
199
|
enabled: asBoolean(root.enabled, DEFAULTS.enabled),
|
|
@@ -195,9 +217,8 @@ export function parseConfig(raw: unknown): MemoryBraidConfig {
|
|
|
195
217
|
},
|
|
196
218
|
capture: {
|
|
197
219
|
enabled: asBoolean(capture.enabled, DEFAULTS.capture.enabled),
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
},
|
|
220
|
+
mode: captureMode,
|
|
221
|
+
maxItemsPerRun: asInt(capture.maxItemsPerRun, DEFAULTS.capture.maxItemsPerRun, 1, 50),
|
|
201
222
|
ml: {
|
|
202
223
|
provider:
|
|
203
224
|
ml.provider === "openai" || ml.provider === "anthropic" || ml.provider === "gemini"
|
|
@@ -205,7 +226,29 @@ export function parseConfig(raw: unknown): MemoryBraidConfig {
|
|
|
205
226
|
: DEFAULTS.capture.ml.provider,
|
|
206
227
|
model: asString(ml.model),
|
|
207
228
|
timeoutMs: asInt(ml.timeoutMs, DEFAULTS.capture.ml.timeoutMs, 250, 30_000),
|
|
208
|
-
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
entityExtraction: {
|
|
232
|
+
enabled: asBoolean(entityExtraction.enabled, DEFAULTS.entityExtraction.enabled),
|
|
233
|
+
provider:
|
|
234
|
+
entityExtraction.provider === "multilingual_ner"
|
|
235
|
+
? "multilingual_ner"
|
|
236
|
+
: DEFAULTS.entityExtraction.provider,
|
|
237
|
+
model: asString(entityExtraction.model) ?? DEFAULTS.entityExtraction.model,
|
|
238
|
+
minScore: asNumber(entityExtraction.minScore, DEFAULTS.entityExtraction.minScore, 0, 1),
|
|
239
|
+
maxEntitiesPerMemory: asInt(
|
|
240
|
+
entityExtraction.maxEntitiesPerMemory,
|
|
241
|
+
DEFAULTS.entityExtraction.maxEntitiesPerMemory,
|
|
242
|
+
1,
|
|
243
|
+
50,
|
|
244
|
+
),
|
|
245
|
+
startup: {
|
|
246
|
+
downloadOnStartup: asBoolean(
|
|
247
|
+
entityStartup.downloadOnStartup,
|
|
248
|
+
DEFAULTS.entityExtraction.startup.downloadOnStartup,
|
|
249
|
+
),
|
|
250
|
+
warmupText:
|
|
251
|
+
asString(entityStartup.warmupText) ?? DEFAULTS.entityExtraction.startup.warmupText,
|
|
209
252
|
},
|
|
210
253
|
},
|
|
211
254
|
bootstrap: {
|