@soulcraft/brainy 3.20.5 → 3.22.0
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/CHANGELOG.md +93 -0
- package/README.md +112 -2
- package/dist/augmentations/defaultAugmentations.d.ts +6 -0
- package/dist/augmentations/defaultAugmentations.js +12 -0
- package/dist/augmentations/intelligentImport/IntelligentImportAugmentation.d.ts +51 -0
- package/dist/augmentations/intelligentImport/IntelligentImportAugmentation.js +185 -0
- package/dist/augmentations/intelligentImport/handlers/base.d.ts +49 -0
- package/dist/augmentations/intelligentImport/handlers/base.js +149 -0
- package/dist/augmentations/intelligentImport/handlers/csvHandler.d.ts +34 -0
- package/dist/augmentations/intelligentImport/handlers/csvHandler.js +185 -0
- package/dist/augmentations/intelligentImport/handlers/excelHandler.d.ts +31 -0
- package/dist/augmentations/intelligentImport/handlers/excelHandler.js +148 -0
- package/dist/augmentations/intelligentImport/handlers/pdfHandler.d.ts +35 -0
- package/dist/augmentations/intelligentImport/handlers/pdfHandler.js +247 -0
- package/dist/augmentations/intelligentImport/index.d.ts +9 -0
- package/dist/augmentations/intelligentImport/index.js +9 -0
- package/dist/augmentations/intelligentImport/types.d.ts +111 -0
- package/dist/augmentations/intelligentImport/types.js +6 -0
- package/dist/neural/entityExtractionCache.d.ts +111 -0
- package/dist/neural/entityExtractionCache.js +208 -0
- package/dist/neural/entityExtractor.d.ts +33 -1
- package/dist/neural/entityExtractor.js +66 -2
- package/dist/neural/relationshipConfidence.d.ts +79 -0
- package/dist/neural/relationshipConfidence.js +204 -0
- package/dist/types/brainy.types.d.ts +18 -0
- package/dist/types/progress.types.d.ts +107 -0
- package/dist/types/progress.types.js +221 -0
- package/package.json +7 -2
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Neural Entity Extractor using Brainy's NounTypes
|
|
3
3
|
* Uses embeddings and similarity matching for accurate type detection
|
|
4
|
+
*
|
|
5
|
+
* PRODUCTION-READY with caching support
|
|
4
6
|
*/
|
|
5
7
|
import { NounType } from '../types/graphTypes.js';
|
|
6
8
|
import { Vector } from '../coreTypes.js';
|
|
7
9
|
import type { Brainy } from '../brainy.js';
|
|
10
|
+
import { EntityCacheOptions } from './entityExtractionCache.js';
|
|
8
11
|
export interface ExtractedEntity {
|
|
9
12
|
text: string;
|
|
10
13
|
type: NounType;
|
|
@@ -20,19 +23,28 @@ export declare class NeuralEntityExtractor {
|
|
|
20
23
|
private brain;
|
|
21
24
|
private typeEmbeddings;
|
|
22
25
|
private initialized;
|
|
23
|
-
|
|
26
|
+
private cache;
|
|
27
|
+
constructor(brain: Brainy | Brainy<any>, cacheOptions?: EntityCacheOptions);
|
|
24
28
|
/**
|
|
25
29
|
* Initialize type embeddings for neural matching
|
|
26
30
|
*/
|
|
27
31
|
private initializeTypeEmbeddings;
|
|
28
32
|
/**
|
|
29
33
|
* Extract entities from text using neural matching
|
|
34
|
+
* Now with caching support for performance
|
|
30
35
|
*/
|
|
31
36
|
extract(text: string, options?: {
|
|
32
37
|
types?: NounType[];
|
|
33
38
|
confidence?: number;
|
|
34
39
|
includeVectors?: boolean;
|
|
35
40
|
neuralMatching?: boolean;
|
|
41
|
+
path?: string;
|
|
42
|
+
cache?: {
|
|
43
|
+
enabled?: boolean;
|
|
44
|
+
ttl?: number;
|
|
45
|
+
invalidateOn?: 'mtime' | 'hash';
|
|
46
|
+
mtime?: number;
|
|
47
|
+
};
|
|
36
48
|
}): Promise<ExtractedEntity[]>;
|
|
37
49
|
/**
|
|
38
50
|
* Extract candidate entities using patterns
|
|
@@ -62,4 +74,24 @@ export declare class NeuralEntityExtractor {
|
|
|
62
74
|
* Remove duplicate and overlapping entities
|
|
63
75
|
*/
|
|
64
76
|
private deduplicateEntities;
|
|
77
|
+
/**
|
|
78
|
+
* Invalidate cache entry for a specific path or hash
|
|
79
|
+
*/
|
|
80
|
+
invalidateCache(pathOrHash: string): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Invalidate all cache entries matching a prefix
|
|
83
|
+
*/
|
|
84
|
+
invalidateCachePrefix(prefix: string): number;
|
|
85
|
+
/**
|
|
86
|
+
* Clear all cached entities
|
|
87
|
+
*/
|
|
88
|
+
clearCache(): void;
|
|
89
|
+
/**
|
|
90
|
+
* Get cache statistics
|
|
91
|
+
*/
|
|
92
|
+
getCacheStats(): import("./entityExtractionCache.js").EntityCacheStats;
|
|
93
|
+
/**
|
|
94
|
+
* Cleanup expired cache entries
|
|
95
|
+
*/
|
|
96
|
+
cleanupCache(): number;
|
|
65
97
|
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Neural Entity Extractor using Brainy's NounTypes
|
|
3
3
|
* Uses embeddings and similarity matching for accurate type detection
|
|
4
|
+
*
|
|
5
|
+
* PRODUCTION-READY with caching support
|
|
4
6
|
*/
|
|
5
7
|
import { NounType } from '../types/graphTypes.js';
|
|
8
|
+
import { EntityExtractionCache, generateFileCacheKey, generateContentCacheKey, computeContentHash } from './entityExtractionCache.js';
|
|
6
9
|
export class NeuralEntityExtractor {
|
|
7
|
-
constructor(brain) {
|
|
10
|
+
constructor(brain, cacheOptions) {
|
|
8
11
|
// Type embeddings for similarity matching
|
|
9
12
|
this.typeEmbeddings = new Map();
|
|
10
13
|
this.initialized = false;
|
|
11
14
|
this.brain = brain;
|
|
15
|
+
this.cache = new EntityExtractionCache(cacheOptions);
|
|
12
16
|
}
|
|
13
17
|
/**
|
|
14
18
|
* Initialize type embeddings for neural matching
|
|
@@ -60,9 +64,24 @@ export class NeuralEntityExtractor {
|
|
|
60
64
|
}
|
|
61
65
|
/**
|
|
62
66
|
* Extract entities from text using neural matching
|
|
67
|
+
* Now with caching support for performance
|
|
63
68
|
*/
|
|
64
69
|
async extract(text, options) {
|
|
65
70
|
await this.initializeTypeEmbeddings();
|
|
71
|
+
// Check cache if enabled
|
|
72
|
+
if (options?.cache?.enabled !== false && (options?.path || options?.cache?.invalidateOn === 'hash')) {
|
|
73
|
+
const cacheKey = options.path
|
|
74
|
+
? generateFileCacheKey(options.path)
|
|
75
|
+
: generateContentCacheKey(text);
|
|
76
|
+
const cacheOptions = {
|
|
77
|
+
mtime: options.cache?.mtime,
|
|
78
|
+
contentHash: !options.path ? computeContentHash(text) : undefined
|
|
79
|
+
};
|
|
80
|
+
const cached = this.cache.get(cacheKey, cacheOptions);
|
|
81
|
+
if (cached) {
|
|
82
|
+
return cached;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
66
85
|
const entities = [];
|
|
67
86
|
const minConfidence = options?.confidence || 0.6;
|
|
68
87
|
const targetTypes = options?.types || Object.values(NounType);
|
|
@@ -111,7 +130,19 @@ export class NeuralEntityExtractor {
|
|
|
111
130
|
}
|
|
112
131
|
}
|
|
113
132
|
// Remove duplicates and overlaps
|
|
114
|
-
|
|
133
|
+
const deduplicatedEntities = this.deduplicateEntities(entities);
|
|
134
|
+
// Store in cache if enabled
|
|
135
|
+
if (options?.cache?.enabled !== false && (options?.path || options?.cache?.invalidateOn === 'hash')) {
|
|
136
|
+
const cacheKey = options.path
|
|
137
|
+
? generateFileCacheKey(options.path)
|
|
138
|
+
: generateContentCacheKey(text);
|
|
139
|
+
this.cache.set(cacheKey, deduplicatedEntities, {
|
|
140
|
+
ttl: options.cache?.ttl,
|
|
141
|
+
mtime: options.cache?.mtime,
|
|
142
|
+
contentHash: !options.path ? computeContentHash(text) : undefined
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return deduplicatedEntities;
|
|
115
146
|
}
|
|
116
147
|
/**
|
|
117
148
|
* Extract candidate entities using patterns
|
|
@@ -312,5 +343,38 @@ export class NeuralEntityExtractor {
|
|
|
312
343
|
}
|
|
313
344
|
return result;
|
|
314
345
|
}
|
|
346
|
+
/**
|
|
347
|
+
* Invalidate cache entry for a specific path or hash
|
|
348
|
+
*/
|
|
349
|
+
invalidateCache(pathOrHash) {
|
|
350
|
+
const cacheKey = pathOrHash.includes(':')
|
|
351
|
+
? pathOrHash
|
|
352
|
+
: generateFileCacheKey(pathOrHash);
|
|
353
|
+
return this.cache.invalidate(cacheKey);
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Invalidate all cache entries matching a prefix
|
|
357
|
+
*/
|
|
358
|
+
invalidateCachePrefix(prefix) {
|
|
359
|
+
return this.cache.invalidatePrefix(prefix);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Clear all cached entities
|
|
363
|
+
*/
|
|
364
|
+
clearCache() {
|
|
365
|
+
this.cache.clear();
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Get cache statistics
|
|
369
|
+
*/
|
|
370
|
+
getCacheStats() {
|
|
371
|
+
return this.cache.getStats();
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Cleanup expired cache entries
|
|
375
|
+
*/
|
|
376
|
+
cleanupCache() {
|
|
377
|
+
return this.cache.cleanup();
|
|
378
|
+
}
|
|
315
379
|
}
|
|
316
380
|
//# sourceMappingURL=entityExtractor.js.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relationship Confidence Scoring
|
|
3
|
+
*
|
|
4
|
+
* Scores the confidence of detected relationships based on multiple factors:
|
|
5
|
+
* - Entity proximity in text
|
|
6
|
+
* - Entity confidence scores
|
|
7
|
+
* - Pattern matches
|
|
8
|
+
* - Structural analysis
|
|
9
|
+
*
|
|
10
|
+
* PRODUCTION-READY - NO MOCKS, NO STUBS, REAL IMPLEMENTATION
|
|
11
|
+
*/
|
|
12
|
+
import { ExtractedEntity } from './entityExtractor.js';
|
|
13
|
+
import { VerbType } from '../types/graphTypes.js';
|
|
14
|
+
import { RelationEvidence } from '../types/brainy.types.js';
|
|
15
|
+
/**
|
|
16
|
+
* Detected relationship with confidence
|
|
17
|
+
*/
|
|
18
|
+
export interface DetectedRelationship {
|
|
19
|
+
sourceEntity: ExtractedEntity;
|
|
20
|
+
targetEntity: ExtractedEntity;
|
|
21
|
+
verbType: VerbType;
|
|
22
|
+
confidence: number;
|
|
23
|
+
evidence: RelationEvidence;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Configuration for relationship detection
|
|
27
|
+
*/
|
|
28
|
+
export interface RelationshipDetectionConfig {
|
|
29
|
+
minConfidence?: number;
|
|
30
|
+
maxDistance?: number;
|
|
31
|
+
useProximityBoost?: boolean;
|
|
32
|
+
usePatternMatching?: boolean;
|
|
33
|
+
useStructuralAnalysis?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Relationship confidence scorer
|
|
37
|
+
*/
|
|
38
|
+
export declare class RelationshipConfidenceScorer {
|
|
39
|
+
private config;
|
|
40
|
+
constructor(config?: RelationshipDetectionConfig);
|
|
41
|
+
/**
|
|
42
|
+
* Score a potential relationship between two entities
|
|
43
|
+
*/
|
|
44
|
+
scoreRelationship(source: ExtractedEntity, target: ExtractedEntity, verbType: VerbType, context: string): {
|
|
45
|
+
confidence: number;
|
|
46
|
+
evidence: RelationEvidence;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Calculate proximity boost based on distance between entities
|
|
50
|
+
*/
|
|
51
|
+
private calculateProximityBoost;
|
|
52
|
+
/**
|
|
53
|
+
* Check if entities match a verb pattern
|
|
54
|
+
*/
|
|
55
|
+
private checkVerbPattern;
|
|
56
|
+
/**
|
|
57
|
+
* Analyze structural relationship
|
|
58
|
+
*/
|
|
59
|
+
private analyzeStructure;
|
|
60
|
+
/**
|
|
61
|
+
* Get context text between two entities
|
|
62
|
+
*/
|
|
63
|
+
private getContextBetween;
|
|
64
|
+
/**
|
|
65
|
+
* Detect relationships between a list of entities
|
|
66
|
+
*/
|
|
67
|
+
detectRelationships(entities: ExtractedEntity[], context: string, verbHints?: VerbType[]): DetectedRelationship[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Convenience function to score a single relationship
|
|
71
|
+
*/
|
|
72
|
+
export declare function scoreRelationshipConfidence(source: ExtractedEntity, target: ExtractedEntity, verbType: VerbType, context: string, config?: RelationshipDetectionConfig): {
|
|
73
|
+
confidence: number;
|
|
74
|
+
evidence: RelationEvidence;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Convenience function to detect all relationships in text
|
|
78
|
+
*/
|
|
79
|
+
export declare function detectRelationshipsWithConfidence(entities: ExtractedEntity[], context: string, config?: RelationshipDetectionConfig): DetectedRelationship[];
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Relationship Confidence Scoring
|
|
3
|
+
*
|
|
4
|
+
* Scores the confidence of detected relationships based on multiple factors:
|
|
5
|
+
* - Entity proximity in text
|
|
6
|
+
* - Entity confidence scores
|
|
7
|
+
* - Pattern matches
|
|
8
|
+
* - Structural analysis
|
|
9
|
+
*
|
|
10
|
+
* PRODUCTION-READY - NO MOCKS, NO STUBS, REAL IMPLEMENTATION
|
|
11
|
+
*/
|
|
12
|
+
import { VerbType } from '../types/graphTypes.js';
|
|
13
|
+
/**
|
|
14
|
+
* Relationship confidence scorer
|
|
15
|
+
*/
|
|
16
|
+
export class RelationshipConfidenceScorer {
|
|
17
|
+
constructor(config = {}) {
|
|
18
|
+
this.config = {
|
|
19
|
+
minConfidence: config.minConfidence || 0.5,
|
|
20
|
+
maxDistance: config.maxDistance || 50,
|
|
21
|
+
useProximityBoost: config.useProximityBoost !== false,
|
|
22
|
+
usePatternMatching: config.usePatternMatching !== false,
|
|
23
|
+
useStructuralAnalysis: config.useStructuralAnalysis !== false
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Score a potential relationship between two entities
|
|
28
|
+
*/
|
|
29
|
+
scoreRelationship(source, target, verbType, context) {
|
|
30
|
+
let confidence = 0.5; // Base confidence
|
|
31
|
+
// Evidence tracking
|
|
32
|
+
const reasoningParts = [];
|
|
33
|
+
// Factor 1: Proximity boost (closer entities = higher confidence)
|
|
34
|
+
if (this.config.useProximityBoost) {
|
|
35
|
+
const proximityBoost = this.calculateProximityBoost(source, target);
|
|
36
|
+
confidence += proximityBoost;
|
|
37
|
+
if (proximityBoost > 0) {
|
|
38
|
+
reasoningParts.push(`Entities are close together (boost: +${proximityBoost.toFixed(2)})`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Factor 2: Entity confidence boost
|
|
42
|
+
const entityConfidence = (source.confidence + target.confidence) / 2;
|
|
43
|
+
const entityBoost = (entityConfidence - 0.5) * 0.2; // Scale to 0-0.2
|
|
44
|
+
confidence *= (1 + entityBoost);
|
|
45
|
+
if (entityBoost > 0) {
|
|
46
|
+
reasoningParts.push(`High entity confidence (boost: ${entityBoost.toFixed(2)})`);
|
|
47
|
+
}
|
|
48
|
+
// Factor 3: Pattern match boost
|
|
49
|
+
if (this.config.usePatternMatching) {
|
|
50
|
+
const patternBoost = this.checkVerbPattern(source, target, verbType, context);
|
|
51
|
+
confidence += patternBoost;
|
|
52
|
+
if (patternBoost > 0) {
|
|
53
|
+
reasoningParts.push(`Matches relationship pattern (boost: +${patternBoost.toFixed(2)})`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Factor 4: Structural boost (same sentence, clause, etc.)
|
|
57
|
+
if (this.config.useStructuralAnalysis) {
|
|
58
|
+
const structuralBoost = this.analyzeStructure(source, target, context);
|
|
59
|
+
confidence += structuralBoost;
|
|
60
|
+
if (structuralBoost > 0) {
|
|
61
|
+
reasoningParts.push(`Structural relationship (boost: +${structuralBoost.toFixed(2)})`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Cap confidence at 1.0
|
|
65
|
+
confidence = Math.min(confidence, 1.0);
|
|
66
|
+
// Extract source text evidence
|
|
67
|
+
const start = Math.min(source.position.start, target.position.start);
|
|
68
|
+
const end = Math.max(source.position.end, target.position.end);
|
|
69
|
+
const evidence = {
|
|
70
|
+
sourceText: context.substring(start, end),
|
|
71
|
+
position: { start, end },
|
|
72
|
+
method: 'neural',
|
|
73
|
+
reasoning: reasoningParts.join('; ')
|
|
74
|
+
};
|
|
75
|
+
return { confidence, evidence };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Calculate proximity boost based on distance between entities
|
|
79
|
+
*/
|
|
80
|
+
calculateProximityBoost(source, target) {
|
|
81
|
+
const distance = Math.abs(source.position.start - target.position.start);
|
|
82
|
+
if (distance === 0)
|
|
83
|
+
return 0; // Same position, not meaningful
|
|
84
|
+
// Very close (< 20 chars): +0.2
|
|
85
|
+
if (distance < 20)
|
|
86
|
+
return 0.2;
|
|
87
|
+
// Close (< 50 chars): +0.1
|
|
88
|
+
if (distance < 50)
|
|
89
|
+
return 0.1;
|
|
90
|
+
// Medium (< 100 chars): +0.05
|
|
91
|
+
if (distance < 100)
|
|
92
|
+
return 0.05;
|
|
93
|
+
// Far (> 100 chars): no boost
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if entities match a verb pattern
|
|
98
|
+
*/
|
|
99
|
+
checkVerbPattern(source, target, verbType, context) {
|
|
100
|
+
const contextBetween = this.getContextBetween(source, target, context);
|
|
101
|
+
const contextLower = contextBetween.toLowerCase();
|
|
102
|
+
// Verb-specific patterns
|
|
103
|
+
const patterns = {
|
|
104
|
+
[VerbType.Creates]: ['creates', 'made', 'built', 'developed', 'produces'],
|
|
105
|
+
[VerbType.Owns]: ['owns', 'belongs to', 'possessed by', 'has'],
|
|
106
|
+
[VerbType.Contains]: ['contains', 'includes', 'has', 'holds'],
|
|
107
|
+
[VerbType.Requires]: ['requires', 'needs', 'depends on', 'relies on'],
|
|
108
|
+
[VerbType.Uses]: ['uses', 'utilizes', 'employs', 'applies'],
|
|
109
|
+
[VerbType.Supervises]: ['manages', 'oversees', 'supervises', 'controls'],
|
|
110
|
+
[VerbType.Causes]: ['influences', 'affects', 'impacts', 'shapes', 'causes'],
|
|
111
|
+
[VerbType.DependsOn]: ['depends on', 'relies on', 'based on'],
|
|
112
|
+
[VerbType.Modifies]: ['modifies', 'changes', 'alters', 'updates'],
|
|
113
|
+
[VerbType.References]: ['references', 'cites', 'mentions', 'refers to']
|
|
114
|
+
};
|
|
115
|
+
const verbPatterns = patterns[verbType] || [];
|
|
116
|
+
for (const pattern of verbPatterns) {
|
|
117
|
+
if (contextLower.includes(pattern)) {
|
|
118
|
+
return 0.2; // Strong pattern match
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return 0; // No pattern match
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Analyze structural relationship
|
|
125
|
+
*/
|
|
126
|
+
analyzeStructure(source, target, context) {
|
|
127
|
+
const contextBetween = this.getContextBetween(source, target, context);
|
|
128
|
+
// Same sentence (no sentence-ending punctuation between them)
|
|
129
|
+
if (!contextBetween.match(/[.!?]/)) {
|
|
130
|
+
return 0.1;
|
|
131
|
+
}
|
|
132
|
+
// Same paragraph (single newline between them)
|
|
133
|
+
if (!contextBetween.match(/\n\n/)) {
|
|
134
|
+
return 0.05;
|
|
135
|
+
}
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get context text between two entities
|
|
140
|
+
*/
|
|
141
|
+
getContextBetween(source, target, context) {
|
|
142
|
+
const start = Math.min(source.position.end, target.position.end);
|
|
143
|
+
const end = Math.max(source.position.start, target.position.start);
|
|
144
|
+
if (start >= end)
|
|
145
|
+
return '';
|
|
146
|
+
return context.substring(start, end);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Detect relationships between a list of entities
|
|
150
|
+
*/
|
|
151
|
+
detectRelationships(entities, context, verbHints) {
|
|
152
|
+
const relationships = [];
|
|
153
|
+
const verbs = verbHints || [
|
|
154
|
+
VerbType.Creates,
|
|
155
|
+
VerbType.Uses,
|
|
156
|
+
VerbType.Contains,
|
|
157
|
+
VerbType.Requires,
|
|
158
|
+
VerbType.RelatedTo
|
|
159
|
+
];
|
|
160
|
+
// Check all entity pairs
|
|
161
|
+
for (let i = 0; i < entities.length; i++) {
|
|
162
|
+
for (let j = i + 1; j < entities.length; j++) {
|
|
163
|
+
const source = entities[i];
|
|
164
|
+
const target = entities[j];
|
|
165
|
+
// Check distance
|
|
166
|
+
const distance = Math.abs(source.position.start - target.position.start);
|
|
167
|
+
if (distance > this.config.maxDistance) {
|
|
168
|
+
continue; // Too far apart
|
|
169
|
+
}
|
|
170
|
+
// Try each verb type
|
|
171
|
+
for (const verbType of verbs) {
|
|
172
|
+
const { confidence, evidence } = this.scoreRelationship(source, target, verbType, context);
|
|
173
|
+
if (confidence >= this.config.minConfidence) {
|
|
174
|
+
relationships.push({
|
|
175
|
+
sourceEntity: source,
|
|
176
|
+
targetEntity: target,
|
|
177
|
+
verbType,
|
|
178
|
+
confidence,
|
|
179
|
+
evidence
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Sort by confidence (highest first)
|
|
186
|
+
relationships.sort((a, b) => b.confidence - a.confidence);
|
|
187
|
+
return relationships;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Convenience function to score a single relationship
|
|
192
|
+
*/
|
|
193
|
+
export function scoreRelationshipConfidence(source, target, verbType, context, config) {
|
|
194
|
+
const scorer = new RelationshipConfidenceScorer(config);
|
|
195
|
+
return scorer.scoreRelationship(source, target, verbType, context);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Convenience function to detect all relationships in text
|
|
199
|
+
*/
|
|
200
|
+
export function detectRelationshipsWithConfidence(entities, context, config) {
|
|
201
|
+
const scorer = new RelationshipConfidenceScorer(config);
|
|
202
|
+
return scorer.detectRelationships(entities, context);
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=relationshipConfidence.js.map
|
|
@@ -21,6 +21,7 @@ export interface Entity<T = any> {
|
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* Relation representation (replaces GraphVerb)
|
|
24
|
+
* Enhanced with confidence scoring and evidence tracking
|
|
24
25
|
*/
|
|
25
26
|
export interface Relation<T = any> {
|
|
26
27
|
id: string;
|
|
@@ -32,6 +33,20 @@ export interface Relation<T = any> {
|
|
|
32
33
|
service?: string;
|
|
33
34
|
createdAt: number;
|
|
34
35
|
updatedAt?: number;
|
|
36
|
+
confidence?: number;
|
|
37
|
+
evidence?: RelationEvidence;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Evidence for why a relationship was detected
|
|
41
|
+
*/
|
|
42
|
+
export interface RelationEvidence {
|
|
43
|
+
sourceText?: string;
|
|
44
|
+
position?: {
|
|
45
|
+
start: number;
|
|
46
|
+
end: number;
|
|
47
|
+
};
|
|
48
|
+
method: 'neural' | 'pattern' | 'structural' | 'explicit';
|
|
49
|
+
reasoning?: string;
|
|
35
50
|
}
|
|
36
51
|
/**
|
|
37
52
|
* Search result with similarity score
|
|
@@ -76,6 +91,7 @@ export interface UpdateParams<T = any> {
|
|
|
76
91
|
}
|
|
77
92
|
/**
|
|
78
93
|
* Parameters for creating relationships
|
|
94
|
+
* Enhanced with confidence scoring and evidence tracking
|
|
79
95
|
*/
|
|
80
96
|
export interface RelateParams<T = any> {
|
|
81
97
|
from: string;
|
|
@@ -85,6 +101,8 @@ export interface RelateParams<T = any> {
|
|
|
85
101
|
metadata?: T;
|
|
86
102
|
bidirectional?: boolean;
|
|
87
103
|
service?: string;
|
|
104
|
+
confidence?: number;
|
|
105
|
+
evidence?: RelationEvidence;
|
|
88
106
|
}
|
|
89
107
|
/**
|
|
90
108
|
* Parameters for updating relationships
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standardized Progress Reporting
|
|
3
|
+
*
|
|
4
|
+
* Provides unified progress tracking across all long-running operations
|
|
5
|
+
* in Brainy (imports, clustering, large searches, etc.)
|
|
6
|
+
*
|
|
7
|
+
* PRODUCTION-READY - NO MOCKS, NO STUBS, REAL IMPLEMENTATION
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Progress status states
|
|
11
|
+
*/
|
|
12
|
+
export type ProgressStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
13
|
+
/**
|
|
14
|
+
* Standardized progress report
|
|
15
|
+
*/
|
|
16
|
+
export interface BrainyProgress<T = any> {
|
|
17
|
+
status: ProgressStatus;
|
|
18
|
+
progress: number;
|
|
19
|
+
message: string;
|
|
20
|
+
metadata: {
|
|
21
|
+
itemsProcessed: number;
|
|
22
|
+
itemsTotal: number;
|
|
23
|
+
currentItem?: string;
|
|
24
|
+
estimatedTimeRemaining?: number;
|
|
25
|
+
startedAt: number;
|
|
26
|
+
completedAt?: number;
|
|
27
|
+
throughput?: number;
|
|
28
|
+
};
|
|
29
|
+
result?: T;
|
|
30
|
+
error?: Error;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Progress tracker with automatic time estimation
|
|
34
|
+
*/
|
|
35
|
+
export declare class ProgressTracker<T = any> {
|
|
36
|
+
private status;
|
|
37
|
+
private processed;
|
|
38
|
+
private total;
|
|
39
|
+
private startedAt?;
|
|
40
|
+
private completedAt?;
|
|
41
|
+
private currentItem?;
|
|
42
|
+
private result?;
|
|
43
|
+
private error?;
|
|
44
|
+
private processingTimes;
|
|
45
|
+
constructor(total: number);
|
|
46
|
+
/**
|
|
47
|
+
* Factory method for creating progress trackers
|
|
48
|
+
*/
|
|
49
|
+
static create<T>(total: number): ProgressTracker<T>;
|
|
50
|
+
/**
|
|
51
|
+
* Start tracking progress
|
|
52
|
+
*/
|
|
53
|
+
start(): BrainyProgress<T>;
|
|
54
|
+
/**
|
|
55
|
+
* Update progress
|
|
56
|
+
*/
|
|
57
|
+
update(processed: number, currentItem?: string): BrainyProgress<T>;
|
|
58
|
+
/**
|
|
59
|
+
* Increment progress by 1
|
|
60
|
+
*/
|
|
61
|
+
increment(currentItem?: string): BrainyProgress<T>;
|
|
62
|
+
/**
|
|
63
|
+
* Mark as completed
|
|
64
|
+
*/
|
|
65
|
+
complete(result: T): BrainyProgress<T>;
|
|
66
|
+
/**
|
|
67
|
+
* Mark as failed
|
|
68
|
+
*/
|
|
69
|
+
fail(error: Error): BrainyProgress<T>;
|
|
70
|
+
/**
|
|
71
|
+
* Mark as cancelled
|
|
72
|
+
*/
|
|
73
|
+
cancel(): BrainyProgress<T>;
|
|
74
|
+
/**
|
|
75
|
+
* Get current progress state
|
|
76
|
+
*/
|
|
77
|
+
current(): BrainyProgress<T>;
|
|
78
|
+
/**
|
|
79
|
+
* Estimate time remaining based on processing history
|
|
80
|
+
*/
|
|
81
|
+
private estimateTimeRemaining;
|
|
82
|
+
/**
|
|
83
|
+
* Calculate current throughput (items/second)
|
|
84
|
+
*/
|
|
85
|
+
private calculateThroughput;
|
|
86
|
+
/**
|
|
87
|
+
* Get progress statistics
|
|
88
|
+
*/
|
|
89
|
+
getStats(): {
|
|
90
|
+
status: ProgressStatus;
|
|
91
|
+
processed: number;
|
|
92
|
+
total: number;
|
|
93
|
+
remaining: number;
|
|
94
|
+
progress: number;
|
|
95
|
+
elapsed: number;
|
|
96
|
+
estimatedTotal: number | undefined;
|
|
97
|
+
throughput: number | undefined;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Helper to format time duration
|
|
102
|
+
*/
|
|
103
|
+
export declare function formatDuration(ms: number): string;
|
|
104
|
+
/**
|
|
105
|
+
* Helper to format progress percentage
|
|
106
|
+
*/
|
|
107
|
+
export declare function formatProgress(progress: BrainyProgress): string;
|