fix: anonymize all examples and test data
- Replaced real names/companies with generic placeholders - Tests: Vainplex GmbH → Acme GmbH - README: Sebastian/Mondo Gate → Alex/Acme Corp - Author: OpenClaw Community - License: OpenClaw Contributors
This commit is contained in:
parent
898b2d9b9d
commit
7ee66dd0d2
5 changed files with 18 additions and 18 deletions
2
LICENSE
2
LICENSE
|
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2026 Vainplex
|
Copyright (c) 2026 OpenClaw Contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
||||||
14
README.md
14
README.md
|
|
@ -14,11 +14,11 @@ Every message your OpenClaw agent processes flows through the Knowledge Engine:
|
||||||
6. **Background Maintenance** — Prunes low-relevance facts, compacts storage, runs cleanup
|
6. **Background Maintenance** — Prunes low-relevance facts, compacts storage, runs cleanup
|
||||||
|
|
||||||
```
|
```
|
||||||
User: "We're meeting with Sebastian from Mondo Gate next Tuesday"
|
User: "We're meeting with Alex from Acme Corp next Tuesday"
|
||||||
│
|
│
|
||||||
├─ Regex → entities: [Sebastian (person), Mondo Gate (organization)]
|
├─ Regex → entities: [Alex (person), Acme Corp (organization)]
|
||||||
└─ LLM → facts: [Sebastian — works-at — Mondo Gate]
|
└─ LLM → facts: [Alex — works-at — Acme Corp]
|
||||||
[Meeting — scheduled-with — Mondo Gate]
|
[Meeting — scheduled-with — Acme Corp]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
@ -167,9 +167,9 @@ Facts are stored as structured triples:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "f-abc123",
|
"id": "f-abc123",
|
||||||
"subject": "Sebastian",
|
"subject": "Alex",
|
||||||
"predicate": "works-at",
|
"predicate": "works-at",
|
||||||
"object": "Mondo Gate",
|
"object": "Acme Corp",
|
||||||
"source": "extracted-llm",
|
"source": "extracted-llm",
|
||||||
"relevance": 0.95,
|
"relevance": 0.95,
|
||||||
"createdAt": 1707123456789,
|
"createdAt": 1707123456789,
|
||||||
|
|
@ -235,7 +235,7 @@ npm test
|
||||||
|
|
||||||
Tests cover: config validation, entity extraction, fact CRUD, decay, pruning, LLM batching, HTTP client, embeddings, storage atomicity, maintenance scheduling, hook orchestration.
|
Tests cover: config validation, entity extraction, fact CRUD, decay, pruning, LLM batching, HTTP client, embeddings, storage atomicity, maintenance scheduling, hook orchestration.
|
||||||
|
|
||||||
## Part of the Darkplex Plugin Suite
|
## Part of the Vainplex Plugin Suite
|
||||||
|
|
||||||
| # | Plugin | Status | Description |
|
| # | Plugin | Status | Description |
|
||||||
|---|--------|--------|-------------|
|
|---|--------|--------|-------------|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
"nlp",
|
"nlp",
|
||||||
"entity-extraction"
|
"entity-extraction"
|
||||||
],
|
],
|
||||||
"author": "Vainplex",
|
"author": "OpenClaw Community",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,12 @@ describe('EntityExtractor', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extract multiple different entities', () => {
|
it('should extract multiple different entities', () => {
|
||||||
const text = 'Contact Atlas via atlas@vainplex.com on 2026-02-17.';
|
const text = 'Contact Atlas via atlas@acme.com on 2026-02-17.';
|
||||||
const entities = extractor.extract(text);
|
const entities = extractor.extract(text);
|
||||||
assert.strictEqual(entities.length, 3); // Atlas (proper_noun), email, date
|
assert.strictEqual(entities.length, 3); // Atlas (proper_noun), email, date
|
||||||
|
|
||||||
const names = entities.map(e => e.value).sort();
|
const names = entities.map(e => e.value).sort();
|
||||||
assert.deepStrictEqual(names, ['2026-02-17', 'Atlas', 'atlas@vainplex.com']);
|
assert.deepStrictEqual(names, ['2026-02-17', 'Atlas', 'atlas@acme.com']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle multiple mentions of the same entity', () => {
|
it('should handle multiple mentions of the same entity', () => {
|
||||||
|
|
@ -54,14 +54,14 @@ describe('EntityExtractor', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should correctly identify and canonicalize an organization', () => {
|
it('should correctly identify and canonicalize an organization', () => {
|
||||||
const text = 'I work for Vainplex GmbH. It is a German company.';
|
const text = 'I work for Acme GmbH. It is a German company.';
|
||||||
const entities = extractor.extract(text);
|
const entities = extractor.extract(text);
|
||||||
const orgEntity = entities.find(e => e.type === 'organization');
|
const orgEntity = entities.find(e => e.type === 'organization');
|
||||||
|
|
||||||
assert.ok(orgEntity, 'Organization entity should be found');
|
assert.ok(orgEntity, 'Organization entity should be found');
|
||||||
assert.strictEqual(orgEntity.value, 'Vainplex'); // Canonicalized
|
assert.strictEqual(orgEntity.value, 'Acme'); // Canonicalized
|
||||||
assert.strictEqual(orgEntity.id, 'organization:vainplex');
|
assert.strictEqual(orgEntity.id, 'organization:acme');
|
||||||
assert.deepStrictEqual(orgEntity.mentions, ['Vainplex GmbH']);
|
assert.deepStrictEqual(orgEntity.mentions, ['Acme GmbH']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extract dates in various formats', () => {
|
it('should extract dates in various formats', () => {
|
||||||
|
|
@ -84,7 +84,7 @@ describe('EntityExtractor', () => {
|
||||||
describe('mergeEntities', () => {
|
describe('mergeEntities', () => {
|
||||||
it('should merge two disjoint lists of entities', () => {
|
it('should merge two disjoint lists of entities', () => {
|
||||||
const listA: Entity[] = [{ id: 'person:claude', type: 'person', value: 'Claude', count: 1, importance: 0.7, lastSeen: '2026-01-01', mentions: ['Claude'], source: ['regex'] }];
|
const listA: Entity[] = [{ id: 'person:claude', type: 'person', value: 'Claude', count: 1, importance: 0.7, lastSeen: '2026-01-01', mentions: ['Claude'], source: ['regex'] }];
|
||||||
const listB: Entity[] = [{ id: 'org:vainplex', type: 'organization', value: 'Vainplex', count: 1, importance: 0.8, lastSeen: '2026-01-01', mentions: ['Vainplex'], source: ['llm'] }];
|
const listB: Entity[] = [{ id: 'org:acme', type: 'organization', value: 'Acme', count: 1, importance: 0.8, lastSeen: '2026-01-01', mentions: ['Acme'], source: ['llm'] }];
|
||||||
|
|
||||||
const merged = EntityExtractor.mergeEntities(listA, listB);
|
const merged = EntityExtractor.mergeEntities(listA, listB);
|
||||||
assert.strictEqual(merged.length, 2);
|
assert.strictEqual(merged.length, 2);
|
||||||
|
|
|
||||||
|
|
@ -111,11 +111,11 @@ describe('REGEX_PATTERNS', () => {
|
||||||
|
|
||||||
it('should match organization names with suffixes', () => {
|
it('should match organization names with suffixes', () => {
|
||||||
const testCases: TestCase[] = [
|
const testCases: TestCase[] = [
|
||||||
['He works at Vainplex GmbH.', 'Vainplex GmbH'],
|
['He works at Acme GmbH.', 'Acme GmbH'],
|
||||||
['The owner of Stark Industries, LLC is Tony Stark.', 'Stark Industries, LLC'],
|
['The owner of Stark Industries, LLC is Tony Stark.', 'Stark Industries, LLC'],
|
||||||
['Globex Corp. is another example.', 'Globex Corp.'],
|
['Globex Corp. is another example.', 'Globex Corp.'],
|
||||||
['This also catches Acme Inc. and Cyberdyne Systems Ltd.', ['Acme Inc.', 'Cyberdyne Systems Ltd.']],
|
['This also catches Acme Inc. and Cyberdyne Systems Ltd.', ['Acme Inc.', 'Cyberdyne Systems Ltd.']],
|
||||||
['No match for Vainplex alone', null],
|
['No match for Acme alone', null],
|
||||||
];
|
];
|
||||||
runTestCases(REGEX_PATTERNS.organization_suffix, testCases);
|
runTestCases(REGEX_PATTERNS.organization_suffix, testCases);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue