@soulcraft/brainy 0.51.2 → 0.53.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/README.md CHANGED
@@ -69,6 +69,160 @@ const results = await brainy.search("AI language models", 5, {
69
69
 
70
70
  **That's it. You just built a knowledge graph with semantic search and faceted filtering in 8 lines.**
71
71
 
72
+ ## ⚙️ Configuration Options
73
+
74
+ Brainy works great with **zero configuration**, but you can customize it for your specific needs:
75
+
76
+ ### 🚀 Quick Start (Recommended)
77
+ ```javascript
78
+ const brainy = new BrainyData() // Auto-detects everything
79
+ await brainy.init() // Zero config needed
80
+ ```
81
+
82
+ ### 🎯 Specialized Configurations
83
+
84
+ #### Writer Service with Deduplication
85
+ Perfect for high-throughput data ingestion with smart caching:
86
+ ```javascript
87
+ const brainy = new BrainyData({
88
+ writeOnly: true, // Skip search index loading
89
+ allowDirectReads: true // Enable ID-based lookups for deduplication
90
+ })
91
+ // ✅ Can: add(), get(), has(), exists(), getMetadata(), getBatch()
92
+ // ❌ Cannot: search(), similar(), query() (saves memory & startup time)
93
+ ```
94
+
95
+ #### Pure Writer Service
96
+ For maximum performance data ingestion only:
97
+ ```javascript
98
+ const brainy = new BrainyData({
99
+ writeOnly: true, // No search capabilities
100
+ allowDirectReads: false // No read operations at all
101
+ })
102
+ // ✅ Can: add(), addBatch(), relate()
103
+ // ❌ Cannot: Any read operations (fastest startup)
104
+ ```
105
+
106
+ #### Read-Only Service
107
+ For search-only applications with immutable data:
108
+ ```javascript
109
+ const brainy = new BrainyData({
110
+ readOnly: true, // Block all write operations
111
+ frozen: true // Block statistics updates and optimizations
112
+ })
113
+ // ✅ Can: All search operations
114
+ // ❌ Cannot: add(), update(), delete()
115
+ ```
116
+
117
+ #### Custom Storage & Performance
118
+ ```javascript
119
+ const brainy = new BrainyData({
120
+ // Storage options
121
+ storage: {
122
+ type: 's3', // 's3', 'memory', 'filesystem'
123
+ requestPersistentStorage: true, // Browser: request persistent storage
124
+ s3Storage: {
125
+ bucketName: 'my-vectors',
126
+ region: 'us-east-1'
127
+ }
128
+ },
129
+
130
+ // Performance tuning
131
+ hnsw: {
132
+ maxConnections: 16, // Higher = better search quality
133
+ efConstruction: 200, // Higher = better index quality
134
+ useOptimized: true // Enable disk-based storage
135
+ },
136
+
137
+ // Embedding customization
138
+ embeddingFunction: myCustomEmbedder,
139
+ distanceFunction: 'euclidean' // 'cosine', 'euclidean', 'manhattan'
140
+ })
141
+ ```
142
+
143
+ #### Distributed Services
144
+ ```javascript
145
+ // Microservice A (Writer)
146
+ const writerService = new BrainyData({
147
+ writeOnly: true,
148
+ allowDirectReads: true, // For deduplication
149
+ defaultService: 'data-ingestion'
150
+ })
151
+
152
+ // Microservice B (Reader)
153
+ const readerService = new BrainyData({
154
+ readOnly: true,
155
+ defaultService: 'search-api'
156
+ })
157
+
158
+ // Full-featured service
159
+ const hybridService = new BrainyData({
160
+ writeOnly: false, // Can read and write
161
+ defaultService: 'full-stack-app'
162
+ })
163
+ ```
164
+
165
+ ### 🔧 All Configuration Options
166
+
167
+ <details>
168
+ <summary>Click to see complete configuration reference</summary>
169
+
170
+ ```javascript
171
+ const brainy = new BrainyData({
172
+ // === Operation Modes ===
173
+ writeOnly?: boolean // Disable search operations, enable fast ingestion
174
+ allowDirectReads?: boolean // Enable ID lookups in writeOnly mode
175
+ readOnly?: boolean // Disable write operations
176
+ frozen?: boolean // Disable all optimizations and statistics
177
+ lazyLoadInReadOnlyMode?: boolean // Load index on-demand
178
+
179
+ // === Storage Configuration ===
180
+ storage?: {
181
+ type?: 'auto' | 'memory' | 'filesystem' | 's3' | 'opfs'
182
+ requestPersistentStorage?: boolean // Browser persistent storage
183
+
184
+ // Cloud storage options
185
+ s3Storage?: {
186
+ bucketName: string
187
+ region?: string
188
+ accessKeyId?: string
189
+ secretAccessKey?: string
190
+ },
191
+
192
+ r2Storage?: { /* Cloudflare R2 options */ },
193
+ gcsStorage?: { /* Google Cloud Storage options */ }
194
+ },
195
+
196
+ // === Performance Tuning ===
197
+ hnsw?: {
198
+ maxConnections?: number // Default: 16
199
+ efConstruction?: number // Default: 200
200
+ efSearch?: number // Default: 50
201
+ useOptimized?: boolean // Default: true
202
+ useDiskBasedIndex?: boolean // Default: auto-detected
203
+ },
204
+
205
+ // === Embedding & Distance ===
206
+ embeddingFunction?: EmbeddingFunction
207
+ distanceFunction?: 'cosine' | 'euclidean' | 'manhattan'
208
+
209
+ // === Service Identity ===
210
+ defaultService?: string // Default service name for operations
211
+
212
+ // === Advanced Options ===
213
+ logging?: {
214
+ verbose?: boolean // Enable detailed logging
215
+ },
216
+
217
+ timeouts?: {
218
+ embedding?: number // Embedding timeout (ms)
219
+ search?: number // Search timeout (ms)
220
+ }
221
+ })
222
+ ```
223
+
224
+ </details>
225
+
72
226
  ## 🔥 MAJOR UPDATES: What's New in v0.51, v0.49 & v0.48
73
227
 
74
228
  ### 🎯 **v0.51: Revolutionary Developer Experience**
@@ -0,0 +1,158 @@
1
+ import { ICognitionAugmentation, AugmentationResponse } from '../types/augmentations.js';
2
+ /**
3
+ * Configuration options for the Intelligent Verb Scoring augmentation
4
+ */
5
+ export interface IVerbScoringConfig {
6
+ /** Enable semantic proximity scoring based on entity embeddings */
7
+ enableSemanticScoring: boolean;
8
+ /** Enable frequency-based weight amplification */
9
+ enableFrequencyAmplification: boolean;
10
+ /** Enable temporal decay for weights */
11
+ enableTemporalDecay: boolean;
12
+ /** Decay rate per day for temporal scoring (0-1) */
13
+ temporalDecayRate: number;
14
+ /** Minimum weight threshold */
15
+ minWeight: number;
16
+ /** Maximum weight threshold */
17
+ maxWeight: number;
18
+ /** Base confidence score for new relationships */
19
+ baseConfidence: number;
20
+ /** Learning rate for adaptive scoring (0-1) */
21
+ learningRate: number;
22
+ }
23
+ /**
24
+ * Default configuration for the Intelligent Verb Scoring augmentation
25
+ */
26
+ export declare const DEFAULT_VERB_SCORING_CONFIG: IVerbScoringConfig;
27
+ /**
28
+ * Relationship statistics for learning and adaptation
29
+ */
30
+ interface RelationshipStats {
31
+ count: number;
32
+ totalWeight: number;
33
+ averageWeight: number;
34
+ lastSeen: Date;
35
+ firstSeen: Date;
36
+ semanticSimilarity?: number;
37
+ }
38
+ /**
39
+ * Intelligent Verb Scoring Cognition Augmentation
40
+ *
41
+ * Automatically generates intelligent weight and confidence scores for verb relationships
42
+ * using semantic analysis, frequency patterns, and temporal factors.
43
+ */
44
+ export declare class IntelligentVerbScoring implements ICognitionAugmentation {
45
+ readonly name = "intelligent-verb-scoring";
46
+ readonly description = "Automatically generates intelligent weight and confidence scores for verb relationships";
47
+ enabled: boolean;
48
+ private config;
49
+ private relationshipStats;
50
+ private brainyInstance;
51
+ private isInitialized;
52
+ constructor(config?: Partial<IVerbScoringConfig>);
53
+ initialize(): Promise<void>;
54
+ shutDown(): Promise<void>;
55
+ getStatus(): Promise<'active' | 'inactive' | 'error'>;
56
+ /**
57
+ * Set reference to the BrainyData instance for accessing graph data
58
+ */
59
+ setBrainyInstance(instance: any): void;
60
+ /**
61
+ * Main reasoning method for generating intelligent verb scores
62
+ */
63
+ reason(query: string, context?: Record<string, unknown>): AugmentationResponse<{
64
+ inference: string;
65
+ confidence: number;
66
+ }>;
67
+ infer(dataSubset: Record<string, unknown>): AugmentationResponse<Record<string, unknown>>;
68
+ executeLogic(ruleId: string, input: Record<string, unknown>): AugmentationResponse<boolean>;
69
+ /**
70
+ * Generate intelligent weight and confidence scores for a verb relationship
71
+ *
72
+ * @param sourceId - ID of the source entity
73
+ * @param targetId - ID of the target entity
74
+ * @param verbType - Type of the relationship
75
+ * @param existingWeight - Existing weight if any
76
+ * @param metadata - Additional metadata about the relationship
77
+ * @returns Computed weight and confidence scores
78
+ */
79
+ computeVerbScores(sourceId: string, targetId: string, verbType: string, existingWeight?: number, metadata?: any): Promise<{
80
+ weight: number;
81
+ confidence: number;
82
+ reasoning: string[];
83
+ }>;
84
+ /**
85
+ * Calculate semantic similarity between two entities using their embeddings
86
+ */
87
+ private calculateSemanticScore;
88
+ /**
89
+ * Calculate frequency-based boost for repeated relationships
90
+ */
91
+ private calculateFrequencyBoost;
92
+ /**
93
+ * Calculate temporal decay factor based on recency
94
+ */
95
+ private calculateTemporalFactor;
96
+ /**
97
+ * Calculate learning-based adjustment using historical patterns
98
+ */
99
+ private calculateLearningAdjustment;
100
+ /**
101
+ * Update relationship statistics for learning
102
+ */
103
+ private updateRelationshipStats;
104
+ /**
105
+ * Blend two scores using a weighted average
106
+ */
107
+ private blendScores;
108
+ /**
109
+ * Get current configuration
110
+ */
111
+ getConfig(): IVerbScoringConfig;
112
+ /**
113
+ * Update configuration
114
+ */
115
+ updateConfig(newConfig: Partial<IVerbScoringConfig>): void;
116
+ /**
117
+ * Get relationship statistics (for debugging/monitoring)
118
+ */
119
+ getRelationshipStats(): Map<string, RelationshipStats>;
120
+ /**
121
+ * Clear relationship statistics
122
+ */
123
+ clearStats(): void;
124
+ /**
125
+ * Provide feedback to improve future scoring
126
+ * This allows the system to learn from user corrections or validation
127
+ *
128
+ * @param sourceId - Source entity ID
129
+ * @param targetId - Target entity ID
130
+ * @param verbType - Relationship type
131
+ * @param feedbackWeight - The corrected/validated weight (0-1)
132
+ * @param feedbackConfidence - The corrected/validated confidence (0-1)
133
+ * @param feedbackType - Type of feedback ('correction', 'validation', 'enhancement')
134
+ */
135
+ provideFeedback(sourceId: string, targetId: string, verbType: string, feedbackWeight: number, feedbackConfidence?: number, feedbackType?: 'correction' | 'validation' | 'enhancement'): Promise<void>;
136
+ /**
137
+ * Get learning statistics for monitoring and debugging
138
+ */
139
+ getLearningStats(): {
140
+ totalRelationships: number;
141
+ averageConfidence: number;
142
+ feedbackCount: number;
143
+ topRelationships: Array<{
144
+ relationship: string;
145
+ count: number;
146
+ averageWeight: number;
147
+ }>;
148
+ };
149
+ /**
150
+ * Export learning data for backup or analysis
151
+ */
152
+ exportLearningData(): string;
153
+ /**
154
+ * Import learning data from backup
155
+ */
156
+ importLearningData(jsonData: string): void;
157
+ }
158
+ export {};
@@ -0,0 +1,377 @@
1
+ import { cosineDistance } from '../utils/distance.js';
2
+ /**
3
+ * Default configuration for the Intelligent Verb Scoring augmentation
4
+ */
5
+ export const DEFAULT_VERB_SCORING_CONFIG = {
6
+ enableSemanticScoring: true,
7
+ enableFrequencyAmplification: true,
8
+ enableTemporalDecay: true,
9
+ temporalDecayRate: 0.01, // 1% decay per day
10
+ minWeight: 0.1,
11
+ maxWeight: 1.0,
12
+ baseConfidence: 0.5,
13
+ learningRate: 0.1
14
+ };
15
+ /**
16
+ * Intelligent Verb Scoring Cognition Augmentation
17
+ *
18
+ * Automatically generates intelligent weight and confidence scores for verb relationships
19
+ * using semantic analysis, frequency patterns, and temporal factors.
20
+ */
21
+ export class IntelligentVerbScoring {
22
+ constructor(config = {}) {
23
+ this.name = 'intelligent-verb-scoring';
24
+ this.description = 'Automatically generates intelligent weight and confidence scores for verb relationships';
25
+ this.enabled = false; // Off by default as requested
26
+ this.relationshipStats = new Map();
27
+ this.isInitialized = false;
28
+ this.config = { ...DEFAULT_VERB_SCORING_CONFIG, ...config };
29
+ }
30
+ async initialize() {
31
+ if (this.isInitialized)
32
+ return;
33
+ this.isInitialized = true;
34
+ }
35
+ async shutDown() {
36
+ this.relationshipStats.clear();
37
+ this.isInitialized = false;
38
+ }
39
+ async getStatus() {
40
+ return this.enabled && this.isInitialized ? 'active' : 'inactive';
41
+ }
42
+ /**
43
+ * Set reference to the BrainyData instance for accessing graph data
44
+ */
45
+ setBrainyInstance(instance) {
46
+ this.brainyInstance = instance;
47
+ }
48
+ /**
49
+ * Main reasoning method for generating intelligent verb scores
50
+ */
51
+ reason(query, context) {
52
+ if (!this.enabled) {
53
+ return {
54
+ success: false,
55
+ data: { inference: 'Augmentation is disabled', confidence: 0 },
56
+ error: 'Intelligent verb scoring is disabled'
57
+ };
58
+ }
59
+ return {
60
+ success: true,
61
+ data: {
62
+ inference: 'Intelligent verb scoring active',
63
+ confidence: 1.0
64
+ }
65
+ };
66
+ }
67
+ infer(dataSubset) {
68
+ return {
69
+ success: true,
70
+ data: dataSubset
71
+ };
72
+ }
73
+ executeLogic(ruleId, input) {
74
+ return {
75
+ success: true,
76
+ data: true
77
+ };
78
+ }
79
+ /**
80
+ * Generate intelligent weight and confidence scores for a verb relationship
81
+ *
82
+ * @param sourceId - ID of the source entity
83
+ * @param targetId - ID of the target entity
84
+ * @param verbType - Type of the relationship
85
+ * @param existingWeight - Existing weight if any
86
+ * @param metadata - Additional metadata about the relationship
87
+ * @returns Computed weight and confidence scores
88
+ */
89
+ async computeVerbScores(sourceId, targetId, verbType, existingWeight, metadata) {
90
+ if (!this.enabled || !this.brainyInstance) {
91
+ return {
92
+ weight: existingWeight ?? 0.5,
93
+ confidence: this.config.baseConfidence,
94
+ reasoning: ['Intelligent scoring disabled']
95
+ };
96
+ }
97
+ const reasoning = [];
98
+ let weight = existingWeight ?? 0.5;
99
+ let confidence = this.config.baseConfidence;
100
+ try {
101
+ // Get relationship key for statistics
102
+ const relationKey = `${sourceId}-${verbType}-${targetId}`;
103
+ // Update relationship statistics
104
+ this.updateRelationshipStats(relationKey, weight, metadata);
105
+ // Apply semantic scoring if enabled
106
+ if (this.config.enableSemanticScoring) {
107
+ const semanticScore = await this.calculateSemanticScore(sourceId, targetId);
108
+ if (semanticScore !== null) {
109
+ weight = this.blendScores(weight, semanticScore, 0.3);
110
+ confidence = Math.min(confidence + semanticScore * 0.2, 1.0);
111
+ reasoning.push(`Semantic similarity: ${semanticScore.toFixed(3)}`);
112
+ }
113
+ }
114
+ // Apply frequency amplification if enabled
115
+ if (this.config.enableFrequencyAmplification) {
116
+ const frequencyBoost = this.calculateFrequencyBoost(relationKey);
117
+ weight = this.blendScores(weight, frequencyBoost, 0.2);
118
+ if (frequencyBoost > 0.5) {
119
+ confidence = Math.min(confidence + 0.1, 1.0);
120
+ reasoning.push(`Frequency boost: ${frequencyBoost.toFixed(3)}`);
121
+ }
122
+ }
123
+ // Apply temporal decay if enabled
124
+ if (this.config.enableTemporalDecay) {
125
+ const temporalFactor = this.calculateTemporalFactor(relationKey);
126
+ weight *= temporalFactor;
127
+ reasoning.push(`Temporal factor: ${temporalFactor.toFixed(3)}`);
128
+ }
129
+ // Apply learning adjustments
130
+ const learningAdjustment = this.calculateLearningAdjustment(relationKey);
131
+ weight = this.blendScores(weight, learningAdjustment, this.config.learningRate);
132
+ // Clamp values to configured bounds
133
+ weight = Math.max(this.config.minWeight, Math.min(this.config.maxWeight, weight));
134
+ confidence = Math.max(0, Math.min(1, confidence));
135
+ reasoning.push(`Final weight: ${weight.toFixed(3)}, confidence: ${confidence.toFixed(3)}`);
136
+ return { weight, confidence, reasoning };
137
+ }
138
+ catch (error) {
139
+ console.warn('Error computing verb scores:', error);
140
+ return {
141
+ weight: existingWeight ?? 0.5,
142
+ confidence: this.config.baseConfidence,
143
+ reasoning: [`Error in scoring: ${error}`]
144
+ };
145
+ }
146
+ }
147
+ /**
148
+ * Calculate semantic similarity between two entities using their embeddings
149
+ */
150
+ async calculateSemanticScore(sourceId, targetId) {
151
+ try {
152
+ if (!this.brainyInstance?.storage)
153
+ return null;
154
+ // Get noun embeddings from storage
155
+ const sourceNoun = await this.brainyInstance.storage.getNoun(sourceId);
156
+ const targetNoun = await this.brainyInstance.storage.getNoun(targetId);
157
+ if (!sourceNoun?.vector || !targetNoun?.vector)
158
+ return null;
159
+ // Calculate cosine similarity (1 - distance)
160
+ const distance = cosineDistance(sourceNoun.vector, targetNoun.vector);
161
+ return Math.max(0, 1 - distance);
162
+ }
163
+ catch (error) {
164
+ console.warn('Error calculating semantic score:', error);
165
+ return null;
166
+ }
167
+ }
168
+ /**
169
+ * Calculate frequency-based boost for repeated relationships
170
+ */
171
+ calculateFrequencyBoost(relationKey) {
172
+ const stats = this.relationshipStats.get(relationKey);
173
+ if (!stats || stats.count <= 1)
174
+ return 0.5;
175
+ // Logarithmic scaling: more occurrences = higher weight, but with diminishing returns
176
+ const boost = Math.log(stats.count + 1) / Math.log(10); // Log base 10
177
+ return Math.min(boost, 1.0);
178
+ }
179
+ /**
180
+ * Calculate temporal decay factor based on recency
181
+ */
182
+ calculateTemporalFactor(relationKey) {
183
+ const stats = this.relationshipStats.get(relationKey);
184
+ if (!stats)
185
+ return 1.0;
186
+ const daysSinceLastSeen = (Date.now() - stats.lastSeen.getTime()) / (1000 * 60 * 60 * 24);
187
+ const decayFactor = Math.exp(-this.config.temporalDecayRate * daysSinceLastSeen);
188
+ return Math.max(0.1, decayFactor); // Minimum 10% of original weight
189
+ }
190
+ /**
191
+ * Calculate learning-based adjustment using historical patterns
192
+ */
193
+ calculateLearningAdjustment(relationKey) {
194
+ const stats = this.relationshipStats.get(relationKey);
195
+ if (!stats || stats.count <= 1)
196
+ return 0.5;
197
+ // Use moving average of weights as learned baseline
198
+ return Math.max(0, Math.min(1, stats.averageWeight));
199
+ }
200
+ /**
201
+ * Update relationship statistics for learning
202
+ */
203
+ updateRelationshipStats(relationKey, weight, metadata) {
204
+ const now = new Date();
205
+ const existing = this.relationshipStats.get(relationKey);
206
+ if (existing) {
207
+ // Update existing stats
208
+ existing.count++;
209
+ existing.totalWeight += weight;
210
+ existing.averageWeight = existing.totalWeight / existing.count;
211
+ existing.lastSeen = now;
212
+ }
213
+ else {
214
+ // Create new stats entry
215
+ this.relationshipStats.set(relationKey, {
216
+ count: 1,
217
+ totalWeight: weight,
218
+ averageWeight: weight,
219
+ lastSeen: now,
220
+ firstSeen: now
221
+ });
222
+ }
223
+ }
224
+ /**
225
+ * Blend two scores using a weighted average
226
+ */
227
+ blendScores(score1, score2, weight2) {
228
+ const weight1 = 1 - weight2;
229
+ return score1 * weight1 + score2 * weight2;
230
+ }
231
+ /**
232
+ * Get current configuration
233
+ */
234
+ getConfig() {
235
+ return { ...this.config };
236
+ }
237
+ /**
238
+ * Update configuration
239
+ */
240
+ updateConfig(newConfig) {
241
+ this.config = { ...this.config, ...newConfig };
242
+ }
243
+ /**
244
+ * Get relationship statistics (for debugging/monitoring)
245
+ */
246
+ getRelationshipStats() {
247
+ return new Map(this.relationshipStats);
248
+ }
249
+ /**
250
+ * Clear relationship statistics
251
+ */
252
+ clearStats() {
253
+ this.relationshipStats.clear();
254
+ }
255
+ /**
256
+ * Provide feedback to improve future scoring
257
+ * This allows the system to learn from user corrections or validation
258
+ *
259
+ * @param sourceId - Source entity ID
260
+ * @param targetId - Target entity ID
261
+ * @param verbType - Relationship type
262
+ * @param feedbackWeight - The corrected/validated weight (0-1)
263
+ * @param feedbackConfidence - The corrected/validated confidence (0-1)
264
+ * @param feedbackType - Type of feedback ('correction', 'validation', 'enhancement')
265
+ */
266
+ async provideFeedback(sourceId, targetId, verbType, feedbackWeight, feedbackConfidence, feedbackType = 'correction') {
267
+ if (!this.enabled)
268
+ return;
269
+ const relationKey = `${sourceId}-${verbType}-${targetId}`;
270
+ const existing = this.relationshipStats.get(relationKey);
271
+ if (existing) {
272
+ // Apply feedback with learning rate
273
+ const newWeight = existing.averageWeight * (1 - this.config.learningRate) +
274
+ feedbackWeight * this.config.learningRate;
275
+ // Update the running average with feedback
276
+ existing.totalWeight = (existing.totalWeight * existing.count + feedbackWeight) / (existing.count + 1);
277
+ existing.averageWeight = existing.totalWeight / existing.count;
278
+ existing.count += 1;
279
+ existing.lastSeen = new Date();
280
+ if (this.brainyInstance?.loggingConfig?.verbose) {
281
+ console.log(`Feedback applied for ${relationKey}: ${feedbackType}, ` +
282
+ `old weight: ${existing.averageWeight.toFixed(3)}, ` +
283
+ `feedback: ${feedbackWeight.toFixed(3)}, ` +
284
+ `new weight: ${newWeight.toFixed(3)}`);
285
+ }
286
+ }
287
+ else {
288
+ // Create new entry with feedback as initial data
289
+ this.relationshipStats.set(relationKey, {
290
+ count: 1,
291
+ totalWeight: feedbackWeight,
292
+ averageWeight: feedbackWeight,
293
+ lastSeen: new Date(),
294
+ firstSeen: new Date()
295
+ });
296
+ }
297
+ }
298
+ /**
299
+ * Get learning statistics for monitoring and debugging
300
+ */
301
+ getLearningStats() {
302
+ const relationships = Array.from(this.relationshipStats.entries());
303
+ const totalRelationships = relationships.length;
304
+ const feedbackCount = relationships.reduce((sum, [, stats]) => sum + stats.count, 0);
305
+ // Calculate average confidence (approximated from weight patterns)
306
+ const averageWeight = relationships.reduce((sum, [, stats]) => sum + stats.averageWeight, 0) / totalRelationships || 0;
307
+ const averageConfidence = Math.min(averageWeight + 0.2, 1.0); // Heuristic: confidence typically higher than weight
308
+ // Get top relationships by count
309
+ const topRelationships = relationships
310
+ .map(([key, stats]) => ({
311
+ relationship: key,
312
+ count: stats.count,
313
+ averageWeight: stats.averageWeight
314
+ }))
315
+ .sort((a, b) => b.count - a.count)
316
+ .slice(0, 10);
317
+ return {
318
+ totalRelationships,
319
+ averageConfidence,
320
+ feedbackCount,
321
+ topRelationships
322
+ };
323
+ }
324
+ /**
325
+ * Export learning data for backup or analysis
326
+ */
327
+ exportLearningData() {
328
+ const data = {
329
+ config: this.config,
330
+ stats: Array.from(this.relationshipStats.entries()).map(([key, stats]) => ({
331
+ relationship: key,
332
+ ...stats,
333
+ firstSeen: stats.firstSeen.toISOString(),
334
+ lastSeen: stats.lastSeen.toISOString()
335
+ })),
336
+ exportedAt: new Date().toISOString(),
337
+ version: '1.0'
338
+ };
339
+ return JSON.stringify(data, null, 2);
340
+ }
341
+ /**
342
+ * Import learning data from backup
343
+ */
344
+ importLearningData(jsonData) {
345
+ try {
346
+ const data = JSON.parse(jsonData);
347
+ if (data.version !== '1.0') {
348
+ console.warn('Learning data version mismatch, importing anyway');
349
+ }
350
+ // Update configuration if provided
351
+ if (data.config) {
352
+ this.config = { ...this.config, ...data.config };
353
+ }
354
+ // Import relationship statistics
355
+ if (data.stats && Array.isArray(data.stats)) {
356
+ for (const stat of data.stats) {
357
+ if (stat.relationship) {
358
+ this.relationshipStats.set(stat.relationship, {
359
+ count: stat.count || 1,
360
+ totalWeight: stat.totalWeight || stat.averageWeight || 0.5,
361
+ averageWeight: stat.averageWeight || 0.5,
362
+ firstSeen: new Date(stat.firstSeen || Date.now()),
363
+ lastSeen: new Date(stat.lastSeen || Date.now()),
364
+ semanticSimilarity: stat.semanticSimilarity
365
+ });
366
+ }
367
+ }
368
+ }
369
+ console.log(`Imported learning data: ${this.relationshipStats.size} relationships`);
370
+ }
371
+ catch (error) {
372
+ console.error('Failed to import learning data:', error);
373
+ throw new Error(`Failed to import learning data: ${error}`);
374
+ }
375
+ }
376
+ }
377
+ //# sourceMappingURL=intelligentVerbScoring.js.map