@vainplex/openclaw-knowledge-engine 0.1.1 → 0.1.2
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/LICENSE +1 -1
- package/README.md +7 -7
- package/package.json +2 -2
- package/test/entity-extractor.test.ts +7 -7
- package/test/patterns.test.ts +2 -2
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -14,11 +14,11 @@ Every message your OpenClaw agent processes flows through the Knowledge Engine:
|
|
|
14
14
|
6. **Background Maintenance** — Prunes low-relevance facts, compacts storage, runs cleanup
|
|
15
15
|
|
|
16
16
|
```
|
|
17
|
-
User: "We're meeting with
|
|
17
|
+
User: "We're meeting with Alex from Acme Corp next Tuesday"
|
|
18
18
|
│
|
|
19
|
-
├─ Regex → entities: [
|
|
20
|
-
└─ LLM → facts: [
|
|
21
|
-
[Meeting — scheduled-with —
|
|
19
|
+
├─ Regex → entities: [Alex (person), Acme Corp (organization)]
|
|
20
|
+
└─ LLM → facts: [Alex — works-at — Acme Corp]
|
|
21
|
+
[Meeting — scheduled-with — Acme Corp]
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
## Quick Start
|
|
@@ -167,9 +167,9 @@ Facts are stored as structured triples:
|
|
|
167
167
|
```json
|
|
168
168
|
{
|
|
169
169
|
"id": "f-abc123",
|
|
170
|
-
"subject": "
|
|
170
|
+
"subject": "Alex",
|
|
171
171
|
"predicate": "works-at",
|
|
172
|
-
"object": "
|
|
172
|
+
"object": "Acme Corp",
|
|
173
173
|
"source": "extracted-llm",
|
|
174
174
|
"relevance": 0.95,
|
|
175
175
|
"createdAt": 1707123456789,
|
|
@@ -235,7 +235,7 @@ npm test
|
|
|
235
235
|
|
|
236
236
|
Tests cover: config validation, entity extraction, fact CRUD, decay, pruning, LLM batching, HTTP client, embeddings, storage atomicity, maintenance scheduling, hook orchestration.
|
|
237
237
|
|
|
238
|
-
## Part of the
|
|
238
|
+
## Part of the Vainplex Plugin Suite
|
|
239
239
|
|
|
240
240
|
| # | Plugin | Status | Description |
|
|
241
241
|
|---|--------|--------|-------------|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vainplex/openclaw-knowledge-engine",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "An OpenClaw plugin for real-time and batch knowledge extraction from conversational data.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"nlp",
|
|
18
18
|
"entity-extraction"
|
|
19
19
|
],
|
|
20
|
-
"author": "
|
|
20
|
+
"author": "OpenClaw Community",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
|
@@ -34,12 +34,12 @@ describe('EntityExtractor', () => {
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it('should extract multiple different entities', () => {
|
|
37
|
-
const text = 'Contact Atlas via atlas@
|
|
37
|
+
const text = 'Contact Atlas via atlas@acme.com on 2026-02-17.';
|
|
38
38
|
const entities = extractor.extract(text);
|
|
39
39
|
assert.strictEqual(entities.length, 3); // Atlas (proper_noun), email, date
|
|
40
40
|
|
|
41
41
|
const names = entities.map(e => e.value).sort();
|
|
42
|
-
assert.deepStrictEqual(names, ['2026-02-17', 'Atlas', 'atlas@
|
|
42
|
+
assert.deepStrictEqual(names, ['2026-02-17', 'Atlas', 'atlas@acme.com']);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
it('should handle multiple mentions of the same entity', () => {
|
|
@@ -54,14 +54,14 @@ describe('EntityExtractor', () => {
|
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
it('should correctly identify and canonicalize an organization', () => {
|
|
57
|
-
const text = 'I work for
|
|
57
|
+
const text = 'I work for Acme GmbH. It is a German company.';
|
|
58
58
|
const entities = extractor.extract(text);
|
|
59
59
|
const orgEntity = entities.find(e => e.type === 'organization');
|
|
60
60
|
|
|
61
61
|
assert.ok(orgEntity, 'Organization entity should be found');
|
|
62
|
-
assert.strictEqual(orgEntity.value, '
|
|
63
|
-
assert.strictEqual(orgEntity.id, 'organization:
|
|
64
|
-
assert.deepStrictEqual(orgEntity.mentions, ['
|
|
62
|
+
assert.strictEqual(orgEntity.value, 'Acme'); // Canonicalized
|
|
63
|
+
assert.strictEqual(orgEntity.id, 'organization:acme');
|
|
64
|
+
assert.deepStrictEqual(orgEntity.mentions, ['Acme GmbH']);
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
it('should extract dates in various formats', () => {
|
|
@@ -84,7 +84,7 @@ describe('EntityExtractor', () => {
|
|
|
84
84
|
describe('mergeEntities', () => {
|
|
85
85
|
it('should merge two disjoint lists of entities', () => {
|
|
86
86
|
const listA: Entity[] = [{ id: 'person:claude', type: 'person', value: 'Claude', count: 1, importance: 0.7, lastSeen: '2026-01-01', mentions: ['Claude'], source: ['regex'] }];
|
|
87
|
-
const listB: Entity[] = [{ id: 'org:
|
|
87
|
+
const listB: Entity[] = [{ id: 'org:acme', type: 'organization', value: 'Acme', count: 1, importance: 0.8, lastSeen: '2026-01-01', mentions: ['Acme'], source: ['llm'] }];
|
|
88
88
|
|
|
89
89
|
const merged = EntityExtractor.mergeEntities(listA, listB);
|
|
90
90
|
assert.strictEqual(merged.length, 2);
|
package/test/patterns.test.ts
CHANGED
|
@@ -111,11 +111,11 @@ describe('REGEX_PATTERNS', () => {
|
|
|
111
111
|
|
|
112
112
|
it('should match organization names with suffixes', () => {
|
|
113
113
|
const testCases: TestCase[] = [
|
|
114
|
-
['He works at
|
|
114
|
+
['He works at Acme GmbH.', 'Acme GmbH'],
|
|
115
115
|
['The owner of Stark Industries, LLC is Tony Stark.', 'Stark Industries, LLC'],
|
|
116
116
|
['Globex Corp. is another example.', 'Globex Corp.'],
|
|
117
117
|
['This also catches Acme Inc. and Cyberdyne Systems Ltd.', ['Acme Inc.', 'Cyberdyne Systems Ltd.']],
|
|
118
|
-
['No match for
|
|
118
|
+
['No match for Acme alone', null],
|
|
119
119
|
];
|
|
120
120
|
runTestCases(REGEX_PATTERNS.organization_suffix, testCases);
|
|
121
121
|
});
|