@soulcraft/brainy 0.62.2 → 0.63.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.
@@ -0,0 +1,750 @@
1
+ /**
2
+ * Neural Import Augmentation - AI-Powered Data Understanding
3
+ *
4
+ * 🧠 Built-in AI augmentation for intelligent data processing
5
+ * ⚛️ Always free, always included, always enabled
6
+ *
7
+ * This is the default AI-powered augmentation that comes with every Brainy installation.
8
+ * It provides intelligent data understanding, entity detection, and relationship analysis.
9
+ */
10
+ import { NounType, VerbType } from '../types/graphTypes.js';
11
+ import * as fs from '../universal/fs.js';
12
+ import * as path from '../universal/path.js';
13
+ /**
14
+ * Neural Import SENSE Augmentation - The Brain's Perceptual System
15
+ */
16
+ export class NeuralImportAugmentation {
17
+ constructor(brainy, config = {}) {
18
+ this.name = 'neural-import';
19
+ this.description = 'Built-in AI-powered data understanding and entity detection';
20
+ this.enabled = true;
21
+ this.brainy = brainy;
22
+ this.config = {
23
+ confidenceThreshold: 0.7,
24
+ enableWeights: true,
25
+ skipDuplicates: true,
26
+ ...config
27
+ };
28
+ }
29
+ async initialize() {
30
+ // Initialize the cortex analysis system
31
+ console.log('🧠 Neural Import augmentation initialized');
32
+ }
33
+ async shutDown() {
34
+ console.log('🧠 Neural Import SENSE augmentation shut down');
35
+ }
36
+ async getStatus() {
37
+ return this.enabled ? 'active' : 'inactive';
38
+ }
39
+ /**
40
+ * Process raw data into structured nouns and verbs using neural analysis
41
+ */
42
+ async processRawData(rawData, dataType, options) {
43
+ try {
44
+ // Merge options with config
45
+ const mergedConfig = { ...this.config, ...options };
46
+ // Parse the raw data based on type
47
+ const parsedData = await this.parseRawData(rawData, dataType);
48
+ // Perform neural analysis
49
+ const analysis = await this.performNeuralAnalysis(parsedData, mergedConfig);
50
+ // Extract nouns and verbs for the ISenseAugmentation interface
51
+ const nouns = analysis.detectedEntities.map(entity => entity.suggestedId);
52
+ const verbs = analysis.detectedRelationships.map(rel => `${rel.sourceId}->${rel.verbType}->${rel.targetId}`);
53
+ // Store the full analysis for later retrieval
54
+ await this.storeNeuralAnalysis(analysis);
55
+ return {
56
+ success: true,
57
+ data: {
58
+ nouns,
59
+ verbs,
60
+ confidence: analysis.confidence,
61
+ insights: analysis.insights.map((insight) => ({
62
+ type: insight.type,
63
+ description: insight.description,
64
+ confidence: insight.confidence
65
+ })),
66
+ metadata: {
67
+ detectedEntities: analysis.detectedEntities.length,
68
+ detectedRelationships: analysis.detectedRelationships.length,
69
+ timestamp: new Date().toISOString(),
70
+ augmentation: 'neural-import-sense'
71
+ }
72
+ }
73
+ };
74
+ }
75
+ catch (error) {
76
+ return {
77
+ success: false,
78
+ data: { nouns: [], verbs: [] },
79
+ error: error instanceof Error ? error.message : 'Neural analysis failed'
80
+ };
81
+ }
82
+ }
83
+ /**
84
+ * Listen to real-time data feeds and process them
85
+ */
86
+ async listenToFeed(feedUrl, callback) {
87
+ // For file-based feeds, watch for changes
88
+ if (feedUrl.startsWith('file://')) {
89
+ const filePath = feedUrl.replace('file://', '');
90
+ // Watch file for changes using Node.js fs.watch
91
+ const fsWatch = require('fs');
92
+ const watcher = fsWatch.watch(filePath, async (eventType) => {
93
+ if (eventType === 'change') {
94
+ try {
95
+ const fileContent = await fs.readFile(filePath);
96
+ const result = await this.processRawData(fileContent, this.getDataTypeFromPath(filePath));
97
+ if (result.success) {
98
+ callback({
99
+ nouns: result.data.nouns,
100
+ verbs: result.data.verbs,
101
+ confidence: result.data.confidence
102
+ });
103
+ }
104
+ }
105
+ catch (error) {
106
+ console.error('Neural Import feed error:', error);
107
+ }
108
+ }
109
+ });
110
+ return;
111
+ }
112
+ // For other feed types, implement appropriate listeners
113
+ console.log(`🧠 Neural Import listening to feed: ${feedUrl}`);
114
+ }
115
+ /**
116
+ * Analyze data structure without processing (preview mode)
117
+ */
118
+ async analyzeStructure(rawData, dataType, options) {
119
+ try {
120
+ // Parse the raw data
121
+ const parsedData = await this.parseRawData(rawData, dataType);
122
+ // Perform lightweight analysis for structure detection
123
+ const analysis = await this.performNeuralAnalysis(parsedData, { ...this.config, ...options });
124
+ // Summarize entity types
125
+ const entityTypeCounts = new Map();
126
+ analysis.detectedEntities.forEach(entity => {
127
+ const existing = entityTypeCounts.get(entity.nounType) || { count: 0, totalConfidence: 0 };
128
+ entityTypeCounts.set(entity.nounType, {
129
+ count: existing.count + 1,
130
+ totalConfidence: existing.totalConfidence + entity.confidence
131
+ });
132
+ });
133
+ const entityTypes = Array.from(entityTypeCounts.entries()).map(([type, stats]) => ({
134
+ type,
135
+ count: stats.count,
136
+ confidence: stats.totalConfidence / stats.count
137
+ }));
138
+ // Summarize relationship types
139
+ const relationshipTypeCounts = new Map();
140
+ analysis.detectedRelationships.forEach(rel => {
141
+ const existing = relationshipTypeCounts.get(rel.verbType) || { count: 0, totalConfidence: 0 };
142
+ relationshipTypeCounts.set(rel.verbType, {
143
+ count: existing.count + 1,
144
+ totalConfidence: existing.totalConfidence + rel.confidence
145
+ });
146
+ });
147
+ const relationshipTypes = Array.from(relationshipTypeCounts.entries()).map(([type, stats]) => ({
148
+ type,
149
+ count: stats.count,
150
+ confidence: stats.totalConfidence / stats.count
151
+ }));
152
+ // Assess data quality
153
+ const dataQuality = this.assessDataQuality(parsedData, analysis);
154
+ // Generate recommendations
155
+ const recommendations = this.generateRecommendations(parsedData, analysis, entityTypes, relationshipTypes);
156
+ return {
157
+ success: true,
158
+ data: {
159
+ entityTypes,
160
+ relationshipTypes,
161
+ dataQuality,
162
+ recommendations
163
+ }
164
+ };
165
+ }
166
+ catch (error) {
167
+ return {
168
+ success: false,
169
+ data: {
170
+ entityTypes: [],
171
+ relationshipTypes: [],
172
+ dataQuality: { completeness: 0, consistency: 0, accuracy: 0 },
173
+ recommendations: []
174
+ },
175
+ error: error instanceof Error ? error.message : 'Structure analysis failed'
176
+ };
177
+ }
178
+ }
179
+ /**
180
+ * Validate data compatibility with current knowledge base
181
+ */
182
+ async validateCompatibility(rawData, dataType) {
183
+ try {
184
+ // Parse the raw data
185
+ const parsedData = await this.parseRawData(rawData, dataType);
186
+ // Perform neural analysis
187
+ const analysis = await this.performNeuralAnalysis(parsedData);
188
+ const issues = [];
189
+ const suggestions = [];
190
+ // Check for low confidence entities
191
+ const lowConfidenceEntities = analysis.detectedEntities.filter((e) => e.confidence < 0.5);
192
+ if (lowConfidenceEntities.length > 0) {
193
+ issues.push({
194
+ type: 'confidence',
195
+ description: `${lowConfidenceEntities.length} entities have low confidence scores`,
196
+ severity: 'medium'
197
+ });
198
+ suggestions.push('Consider reviewing field names and data structure for better entity detection');
199
+ }
200
+ // Check for missing relationships
201
+ if (analysis.detectedRelationships.length === 0 && analysis.detectedEntities.length > 1) {
202
+ issues.push({
203
+ type: 'relationships',
204
+ description: 'No relationships detected between entities',
205
+ severity: 'low'
206
+ });
207
+ suggestions.push('Consider adding contextual fields that describe entity relationships');
208
+ }
209
+ // Check for data type compatibility
210
+ const supportedTypes = ['json', 'csv', 'yaml', 'text'];
211
+ if (!supportedTypes.includes(dataType.toLowerCase())) {
212
+ issues.push({
213
+ type: 'format',
214
+ description: `Data type '${dataType}' may not be fully supported`,
215
+ severity: 'high'
216
+ });
217
+ suggestions.push(`Convert data to one of: ${supportedTypes.join(', ')}`);
218
+ }
219
+ // Check for data completeness
220
+ const incompleteEntities = analysis.detectedEntities.filter((e) => !e.originalData || Object.keys(e.originalData).length < 2);
221
+ if (incompleteEntities.length > 0) {
222
+ issues.push({
223
+ type: 'completeness',
224
+ description: `${incompleteEntities.length} entities have insufficient data`,
225
+ severity: 'medium'
226
+ });
227
+ suggestions.push('Ensure each entity has multiple descriptive fields');
228
+ }
229
+ const compatible = issues.filter(i => i.severity === 'high').length === 0;
230
+ return {
231
+ success: true,
232
+ data: {
233
+ compatible,
234
+ issues,
235
+ suggestions
236
+ }
237
+ };
238
+ }
239
+ catch (error) {
240
+ return {
241
+ success: false,
242
+ data: {
243
+ compatible: false,
244
+ issues: [{
245
+ type: 'error',
246
+ description: error instanceof Error ? error.message : 'Validation failed',
247
+ severity: 'high'
248
+ }],
249
+ suggestions: []
250
+ },
251
+ error: error instanceof Error ? error.message : 'Compatibility validation failed'
252
+ };
253
+ }
254
+ }
255
+ /**
256
+ * Get the full neural analysis result (custom method for Cortex integration)
257
+ */
258
+ async getNeuralAnalysis(rawData, dataType) {
259
+ const parsedData = await this.parseRawData(rawData, dataType);
260
+ return await this.performNeuralAnalysis(parsedData);
261
+ }
262
+ /**
263
+ * Parse raw data based on type
264
+ */
265
+ async parseRawData(rawData, dataType) {
266
+ const content = typeof rawData === 'string' ? rawData : rawData.toString('utf8');
267
+ switch (dataType.toLowerCase()) {
268
+ case 'json':
269
+ const jsonData = JSON.parse(content);
270
+ return Array.isArray(jsonData) ? jsonData : [jsonData];
271
+ case 'csv':
272
+ return this.parseCSV(content);
273
+ case 'yaml':
274
+ case 'yml':
275
+ // For now, basic YAML support - in full implementation would use yaml parser
276
+ return JSON.parse(content); // Placeholder
277
+ case 'txt':
278
+ case 'text':
279
+ // Split text into sentences/paragraphs for analysis
280
+ return content.split(/\n+/).filter(line => line.trim()).map(line => ({ text: line }));
281
+ default:
282
+ throw new Error(`Unsupported data type: ${dataType}`);
283
+ }
284
+ }
285
+ /**
286
+ * Basic CSV parser
287
+ */
288
+ parseCSV(content) {
289
+ const lines = content.split('\n').filter(line => line.trim());
290
+ if (lines.length < 2)
291
+ return [];
292
+ const headers = lines[0].split(',').map(h => h.trim().replace(/"/g, ''));
293
+ const data = [];
294
+ for (let i = 1; i < lines.length; i++) {
295
+ const values = lines[i].split(',').map(v => v.trim().replace(/"/g, ''));
296
+ const row = {};
297
+ headers.forEach((header, index) => {
298
+ row[header] = values[index] || '';
299
+ });
300
+ data.push(row);
301
+ }
302
+ return data;
303
+ }
304
+ /**
305
+ * Perform neural analysis on parsed data
306
+ */
307
+ async performNeuralAnalysis(parsedData, config = this.config) {
308
+ // Phase 1: Neural Entity Detection
309
+ const detectedEntities = await this.detectEntitiesWithNeuralAnalysis(parsedData, config);
310
+ // Phase 2: Neural Relationship Detection
311
+ const detectedRelationships = await this.detectRelationshipsWithNeuralAnalysis(detectedEntities, parsedData, config);
312
+ // Phase 3: Neural Insights Generation
313
+ const insights = await this.generateNeuralInsights(detectedEntities, detectedRelationships);
314
+ // Phase 4: Confidence Scoring
315
+ const overallConfidence = this.calculateOverallConfidence(detectedEntities, detectedRelationships);
316
+ return {
317
+ detectedEntities,
318
+ detectedRelationships,
319
+ confidence: overallConfidence,
320
+ insights
321
+ };
322
+ }
323
+ /**
324
+ * Neural Entity Detection - The Core AI Engine
325
+ */
326
+ async detectEntitiesWithNeuralAnalysis(rawData, config = this.config) {
327
+ const entities = [];
328
+ const nounTypes = Object.values(NounType);
329
+ for (const [index, dataItem] of rawData.entries()) {
330
+ const mainText = this.extractMainText(dataItem);
331
+ const detections = [];
332
+ // Test against all noun types using semantic similarity
333
+ for (const nounType of nounTypes) {
334
+ const confidence = await this.calculateEntityTypeConfidence(mainText, dataItem, nounType);
335
+ if (confidence >= config.confidenceThreshold - 0.2) { // Allow slightly lower for alternatives
336
+ const reasoning = await this.generateEntityReasoning(mainText, dataItem, nounType);
337
+ detections.push({ type: nounType, confidence, reasoning });
338
+ }
339
+ }
340
+ if (detections.length > 0) {
341
+ // Sort by confidence
342
+ detections.sort((a, b) => b.confidence - a.confidence);
343
+ const primaryType = detections[0];
344
+ const alternatives = detections.slice(1, 3); // Top 2 alternatives
345
+ entities.push({
346
+ originalData: dataItem,
347
+ nounType: primaryType.type,
348
+ confidence: primaryType.confidence,
349
+ suggestedId: this.generateSmartId(dataItem, primaryType.type, index),
350
+ reasoning: primaryType.reasoning,
351
+ alternativeTypes: alternatives
352
+ });
353
+ }
354
+ }
355
+ return entities;
356
+ }
357
+ /**
358
+ * Calculate entity type confidence using AI
359
+ */
360
+ async calculateEntityTypeConfidence(text, data, nounType) {
361
+ // Base semantic similarity using search
362
+ const searchResults = await this.brainy.search(text + ' ' + nounType, 1);
363
+ const textSimilarity = searchResults.length > 0 ? searchResults[0].score : 0.5;
364
+ // Field-based confidence boost
365
+ const fieldBoost = this.calculateFieldBasedConfidence(data, nounType);
366
+ // Pattern-based confidence boost
367
+ const patternBoost = this.calculatePatternBasedConfidence(text, data, nounType);
368
+ // Combine confidences with weights
369
+ const combined = (textSimilarity * 0.5) + (fieldBoost * 0.3) + (patternBoost * 0.2);
370
+ return Math.min(combined, 1.0);
371
+ }
372
+ /**
373
+ * Field-based confidence calculation
374
+ */
375
+ calculateFieldBasedConfidence(data, nounType) {
376
+ const fields = Object.keys(data);
377
+ let boost = 0;
378
+ // Field patterns that boost confidence for specific noun types
379
+ const fieldPatterns = {
380
+ [NounType.Person]: ['name', 'email', 'phone', 'age', 'firstname', 'lastname', 'employee'],
381
+ [NounType.Organization]: ['company', 'organization', 'corp', 'inc', 'ltd', 'department', 'team'],
382
+ [NounType.Project]: ['project', 'task', 'deadline', 'status', 'milestone', 'deliverable'],
383
+ [NounType.Location]: ['address', 'city', 'country', 'state', 'zip', 'location', 'coordinates'],
384
+ [NounType.Product]: ['product', 'price', 'sku', 'inventory', 'category', 'brand'],
385
+ [NounType.Event]: ['date', 'time', 'venue', 'event', 'meeting', 'conference', 'schedule']
386
+ };
387
+ const relevantPatterns = fieldPatterns[nounType] || [];
388
+ for (const field of fields) {
389
+ for (const pattern of relevantPatterns) {
390
+ if (field.toLowerCase().includes(pattern)) {
391
+ boost += 0.1;
392
+ }
393
+ }
394
+ }
395
+ return Math.min(boost, 0.5);
396
+ }
397
+ /**
398
+ * Pattern-based confidence calculation
399
+ */
400
+ calculatePatternBasedConfidence(text, data, nounType) {
401
+ let boost = 0;
402
+ // Content patterns that indicate entity types
403
+ const patterns = {
404
+ [NounType.Person]: [
405
+ /@.*\.com/i, // Email pattern
406
+ /\b[A-Z][a-z]+ [A-Z][a-z]+\b/, // Name pattern
407
+ /Mr\.|Mrs\.|Dr\.|Prof\./i // Title pattern
408
+ ],
409
+ [NounType.Organization]: [
410
+ /\bInc\.|Corp\.|LLC\.|Ltd\./i, // Corporate suffixes
411
+ /Company|Corporation|Enterprise/i
412
+ ],
413
+ [NounType.Location]: [
414
+ /\b\d{5}(-\d{4})?\b/, // ZIP code
415
+ /Street|Ave|Road|Blvd/i
416
+ ]
417
+ };
418
+ const relevantPatterns = patterns[nounType] || [];
419
+ for (const pattern of relevantPatterns) {
420
+ if (pattern.test(text)) {
421
+ boost += 0.15;
422
+ }
423
+ }
424
+ return Math.min(boost, 0.3);
425
+ }
426
+ /**
427
+ * Generate reasoning for entity type selection
428
+ */
429
+ async generateEntityReasoning(text, data, nounType) {
430
+ const reasons = [];
431
+ // Semantic similarity reason
432
+ const searchResults = await this.brainy.search(text + ' ' + nounType, 1);
433
+ const similarity = searchResults.length > 0 ? searchResults[0].score : 0.5;
434
+ if (similarity > 0.7) {
435
+ reasons.push(`High semantic similarity (${(similarity * 100).toFixed(1)}%)`);
436
+ }
437
+ // Field-based reasons
438
+ const relevantFields = this.getRelevantFields(data, nounType);
439
+ if (relevantFields.length > 0) {
440
+ reasons.push(`Contains ${nounType}-specific fields: ${relevantFields.join(', ')}`);
441
+ }
442
+ // Pattern-based reasons
443
+ const matchedPatterns = this.getMatchedPatterns(text, data, nounType);
444
+ if (matchedPatterns.length > 0) {
445
+ reasons.push(`Matches ${nounType} patterns: ${matchedPatterns.join(', ')}`);
446
+ }
447
+ return reasons.length > 0 ? reasons.join('; ') : 'General semantic match';
448
+ }
449
+ /**
450
+ * Neural Relationship Detection
451
+ */
452
+ async detectRelationshipsWithNeuralAnalysis(entities, rawData, config = this.config) {
453
+ const relationships = [];
454
+ const verbTypes = Object.values(VerbType);
455
+ // For each pair of entities, test relationship possibilities
456
+ for (let i = 0; i < entities.length; i++) {
457
+ for (let j = i + 1; j < entities.length; j++) {
458
+ const sourceEntity = entities[i];
459
+ const targetEntity = entities[j];
460
+ // Extract context for relationship detection
461
+ const context = this.extractRelationshipContext(sourceEntity.originalData, targetEntity.originalData, rawData);
462
+ // Test all verb types
463
+ for (const verbType of verbTypes) {
464
+ const confidence = await this.calculateRelationshipConfidence(sourceEntity, targetEntity, verbType, context);
465
+ if (confidence >= config.confidenceThreshold - 0.1) { // Slightly lower threshold for relationships
466
+ const weight = config.enableWeights ?
467
+ this.calculateRelationshipWeight(sourceEntity, targetEntity, verbType, context) :
468
+ 0.5;
469
+ const reasoning = await this.generateRelationshipReasoning(sourceEntity, targetEntity, verbType, context);
470
+ relationships.push({
471
+ sourceId: sourceEntity.suggestedId,
472
+ targetId: targetEntity.suggestedId,
473
+ verbType,
474
+ confidence,
475
+ weight,
476
+ reasoning,
477
+ context,
478
+ metadata: this.extractRelationshipMetadata(sourceEntity.originalData, targetEntity.originalData, verbType)
479
+ });
480
+ }
481
+ }
482
+ }
483
+ }
484
+ // Sort by confidence and remove duplicates/conflicts
485
+ return this.pruneRelationships(relationships);
486
+ }
487
+ /**
488
+ * Calculate relationship confidence
489
+ */
490
+ async calculateRelationshipConfidence(source, target, verbType, context) {
491
+ // Semantic similarity between entities and verb type
492
+ const relationshipText = `${this.extractMainText(source.originalData)} ${verbType} ${this.extractMainText(target.originalData)}`;
493
+ const directResults = await this.brainy.search(relationshipText, 1);
494
+ const directSimilarity = directResults.length > 0 ? directResults[0].score : 0.5;
495
+ // Context-based similarity
496
+ const contextResults = await this.brainy.search(context + ' ' + verbType, 1);
497
+ const contextSimilarity = contextResults.length > 0 ? contextResults[0].score : 0.5;
498
+ // Entity type compatibility
499
+ const typeCompatibility = this.calculateTypeCompatibility(source.nounType, target.nounType, verbType);
500
+ // Combine with weights
501
+ return (directSimilarity * 0.4) + (contextSimilarity * 0.4) + (typeCompatibility * 0.2);
502
+ }
503
+ /**
504
+ * Calculate relationship weight/strength
505
+ */
506
+ calculateRelationshipWeight(source, target, verbType, context) {
507
+ let weight = 0.5; // Base weight
508
+ // Context richness (more descriptive = stronger)
509
+ const contextWords = context.split(' ').length;
510
+ weight += Math.min(contextWords / 20, 0.2);
511
+ // Entity importance (higher confidence entities = stronger relationships)
512
+ const avgEntityConfidence = (source.confidence + target.confidence) / 2;
513
+ weight += avgEntityConfidence * 0.2;
514
+ // Verb type specificity (more specific verbs = stronger)
515
+ const verbSpecificity = this.getVerbSpecificity(verbType);
516
+ weight += verbSpecificity * 0.1;
517
+ return Math.min(weight, 1.0);
518
+ }
519
+ /**
520
+ * Generate Neural Insights - The Intelligence Layer
521
+ */
522
+ async generateNeuralInsights(entities, relationships) {
523
+ const insights = [];
524
+ // Detect hierarchies
525
+ const hierarchies = this.detectHierarchies(relationships);
526
+ hierarchies.forEach(hierarchy => {
527
+ insights.push({
528
+ type: 'hierarchy',
529
+ description: `Detected ${hierarchy.type} hierarchy with ${hierarchy.levels} levels`,
530
+ confidence: hierarchy.confidence,
531
+ affectedEntities: hierarchy.entities,
532
+ recommendation: `Consider visualizing the ${hierarchy.type} structure`
533
+ });
534
+ });
535
+ // Detect clusters
536
+ const clusters = this.detectClusters(entities, relationships);
537
+ clusters.forEach(cluster => {
538
+ insights.push({
539
+ type: 'cluster',
540
+ description: `Found cluster of ${cluster.size} ${cluster.primaryType} entities`,
541
+ confidence: cluster.confidence,
542
+ affectedEntities: cluster.entities,
543
+ recommendation: `These ${cluster.primaryType}s might form a natural grouping`
544
+ });
545
+ });
546
+ // Detect patterns
547
+ const patterns = this.detectPatterns(relationships);
548
+ patterns.forEach(pattern => {
549
+ insights.push({
550
+ type: 'pattern',
551
+ description: `Common relationship pattern: ${pattern.description}`,
552
+ confidence: pattern.confidence,
553
+ affectedEntities: pattern.entities,
554
+ recommendation: pattern.recommendation
555
+ });
556
+ });
557
+ return insights;
558
+ }
559
+ /**
560
+ * Helper methods for the neural system
561
+ */
562
+ extractMainText(data) {
563
+ // Extract the most relevant text from a data object
564
+ const textFields = ['name', 'title', 'description', 'content', 'text', 'label'];
565
+ for (const field of textFields) {
566
+ if (data[field] && typeof data[field] === 'string') {
567
+ return data[field];
568
+ }
569
+ }
570
+ // Fallback: concatenate all string values
571
+ return Object.values(data)
572
+ .filter(v => typeof v === 'string')
573
+ .join(' ')
574
+ .substring(0, 200); // Limit length
575
+ }
576
+ generateSmartId(data, nounType, index) {
577
+ const mainText = this.extractMainText(data);
578
+ const cleanText = mainText.toLowerCase().replace(/[^a-z0-9]/g, '_').substring(0, 20);
579
+ return `${nounType}_${cleanText}_${index}`;
580
+ }
581
+ extractRelationshipContext(source, target, allData) {
582
+ // Extract context for relationship detection
583
+ return [
584
+ this.extractMainText(source),
585
+ this.extractMainText(target),
586
+ // Add more contextual information
587
+ ].join(' ');
588
+ }
589
+ calculateTypeCompatibility(sourceType, targetType, verbType) {
590
+ // Define type compatibility matrix for relationships
591
+ const compatibilityMatrix = {
592
+ [NounType.Person]: {
593
+ [NounType.Organization]: [VerbType.MemberOf, VerbType.WorksWith],
594
+ [NounType.Project]: [VerbType.WorksWith, VerbType.Creates],
595
+ [NounType.Person]: [VerbType.WorksWith, VerbType.Mentors, VerbType.ReportsTo]
596
+ }
597
+ // Add more compatibility rules
598
+ };
599
+ const sourceCompatibility = compatibilityMatrix[sourceType];
600
+ if (sourceCompatibility && sourceCompatibility[targetType]) {
601
+ return sourceCompatibility[targetType].includes(verbType) ? 1.0 : 0.3;
602
+ }
603
+ return 0.5; // Default compatibility
604
+ }
605
+ getVerbSpecificity(verbType) {
606
+ // More specific verbs get higher scores
607
+ const specificityScores = {
608
+ [VerbType.RelatedTo]: 0.1, // Very generic
609
+ [VerbType.WorksWith]: 0.7, // Specific
610
+ [VerbType.Mentors]: 0.9, // Very specific
611
+ [VerbType.ReportsTo]: 0.9, // Very specific
612
+ [VerbType.Supervises]: 0.9 // Very specific
613
+ };
614
+ return specificityScores[verbType] || 0.5;
615
+ }
616
+ getRelevantFields(data, nounType) {
617
+ // Implementation for finding relevant fields
618
+ return [];
619
+ }
620
+ getMatchedPatterns(text, data, nounType) {
621
+ // Implementation for finding matched patterns
622
+ return [];
623
+ }
624
+ pruneRelationships(relationships) {
625
+ // Remove duplicates and low-confidence relationships
626
+ return relationships
627
+ .sort((a, b) => b.confidence - a.confidence)
628
+ .slice(0, 1000); // Limit to top 1000 relationships
629
+ }
630
+ detectHierarchies(relationships) {
631
+ // Detect hierarchical structures
632
+ return [];
633
+ }
634
+ detectClusters(entities, relationships) {
635
+ // Detect entity clusters
636
+ return [];
637
+ }
638
+ detectPatterns(relationships) {
639
+ // Detect relationship patterns
640
+ return [];
641
+ }
642
+ calculateOverallConfidence(entities, relationships) {
643
+ if (entities.length === 0)
644
+ return 0;
645
+ const entityConfidence = entities.reduce((sum, e) => sum + e.confidence, 0) / entities.length;
646
+ if (relationships.length === 0)
647
+ return entityConfidence;
648
+ const relationshipConfidence = relationships.reduce((sum, r) => sum + r.confidence, 0) / relationships.length;
649
+ return (entityConfidence + relationshipConfidence) / 2;
650
+ }
651
+ async storeNeuralAnalysis(analysis) {
652
+ // Store the full analysis result for later retrieval by Neural Import or other systems
653
+ // This could be stored in the brainy instance metadata or a separate analysis store
654
+ }
655
+ getDataTypeFromPath(filePath) {
656
+ const ext = path.extname(filePath).toLowerCase();
657
+ switch (ext) {
658
+ case '.json': return 'json';
659
+ case '.csv': return 'csv';
660
+ case '.yaml':
661
+ case '.yml': return 'yaml';
662
+ case '.txt': return 'text';
663
+ default: return 'text';
664
+ }
665
+ }
666
+ async generateRelationshipReasoning(source, target, verbType, context) {
667
+ return `Neural analysis detected ${verbType} relationship based on semantic context`;
668
+ }
669
+ extractRelationshipMetadata(sourceData, targetData, verbType) {
670
+ return {
671
+ sourceType: typeof sourceData,
672
+ targetType: typeof targetData,
673
+ detectedBy: 'neural-import-sense',
674
+ timestamp: new Date().toISOString()
675
+ };
676
+ }
677
+ /**
678
+ * Assess data quality metrics
679
+ */
680
+ assessDataQuality(parsedData, analysis) {
681
+ // Completeness: ratio of fields with data
682
+ let totalFields = 0;
683
+ let filledFields = 0;
684
+ parsedData.forEach(item => {
685
+ const fields = Object.keys(item);
686
+ totalFields += fields.length;
687
+ filledFields += fields.filter(field => item[field] !== null &&
688
+ item[field] !== undefined &&
689
+ item[field] !== '').length;
690
+ });
691
+ const completeness = totalFields > 0 ? filledFields / totalFields : 0;
692
+ // Consistency: variance in field structure
693
+ const fieldSets = parsedData.map(item => new Set(Object.keys(item)));
694
+ const allFields = new Set(fieldSets.flatMap(set => Array.from(set)));
695
+ let consistencyScore = 0;
696
+ if (fieldSets.length > 0) {
697
+ consistencyScore = Array.from(allFields).reduce((score, field) => {
698
+ const hasField = fieldSets.filter(set => set.has(field)).length;
699
+ return score + (hasField / fieldSets.length);
700
+ }, 0) / allFields.size;
701
+ }
702
+ // Accuracy: average confidence of detected entities
703
+ const accuracy = analysis.detectedEntities.length > 0 ?
704
+ analysis.detectedEntities.reduce((sum, e) => sum + e.confidence, 0) / analysis.detectedEntities.length :
705
+ 0;
706
+ return {
707
+ completeness,
708
+ consistency: consistencyScore,
709
+ accuracy
710
+ };
711
+ }
712
+ /**
713
+ * Generate recommendations based on analysis
714
+ */
715
+ generateRecommendations(parsedData, analysis, entityTypes, relationshipTypes) {
716
+ const recommendations = [];
717
+ // Low entity confidence recommendations
718
+ const lowConfidenceEntities = entityTypes.filter(et => et.confidence < 0.7);
719
+ if (lowConfidenceEntities.length > 0) {
720
+ recommendations.push(`Consider improving field names for ${lowConfidenceEntities.map(e => e.type).join(', ')} entities`);
721
+ }
722
+ // Missing relationships recommendations
723
+ if (relationshipTypes.length === 0 && entityTypes.length > 1) {
724
+ recommendations.push('Add fields that describe how entities relate to each other');
725
+ }
726
+ // Data structure recommendations
727
+ if (parsedData.length > 0) {
728
+ const firstItem = parsedData[0];
729
+ const fieldCount = Object.keys(firstItem).length;
730
+ if (fieldCount < 3) {
731
+ recommendations.push('Consider adding more descriptive fields to each entity');
732
+ }
733
+ if (fieldCount > 20) {
734
+ recommendations.push('Consider grouping related fields or splitting complex entities');
735
+ }
736
+ }
737
+ // Entity distribution recommendations
738
+ const dominantEntityType = entityTypes.reduce((max, current) => current.count > max.count ? current : max, entityTypes[0] || { count: 0 });
739
+ if (dominantEntityType && dominantEntityType.count > parsedData.length * 0.8) {
740
+ recommendations.push(`Consider diversifying entity types - ${dominantEntityType.type} dominates the dataset`);
741
+ }
742
+ // Relationship quality recommendations
743
+ const lowWeightRelationships = relationshipTypes.filter(rt => rt.confidence < 0.6);
744
+ if (lowWeightRelationships.length > 0) {
745
+ recommendations.push('Consider adding more contextual information to strengthen relationship detection');
746
+ }
747
+ return recommendations;
748
+ }
749
+ }
750
+ //# sourceMappingURL=neuralImport.js.map