@soulcraft/brainy 4.3.0 → 4.3.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.
|
@@ -93,15 +93,22 @@ export class ImportCoordinator {
|
|
|
93
93
|
// Extract entities and relationships
|
|
94
94
|
const extractionResult = await this.extract(normalizedSource, detection.format, options);
|
|
95
95
|
// Set defaults
|
|
96
|
+
// CRITICAL FIX (v4.3.2): Spread options FIRST, then apply defaults
|
|
97
|
+
// Previously: ...options at the end overwrote normalized defaults with undefined
|
|
98
|
+
// Now: Defaults properly override undefined values
|
|
99
|
+
// v4.4.0: Enable AI features by default for smarter imports
|
|
96
100
|
const opts = {
|
|
101
|
+
...options, // Spread first to get all options
|
|
97
102
|
vfsPath: options.vfsPath || `/imports/${Date.now()}`,
|
|
98
103
|
groupBy: options.groupBy || 'type',
|
|
99
104
|
createEntities: options.createEntities !== false,
|
|
100
105
|
createRelationships: options.createRelationships !== false,
|
|
101
106
|
preserveSource: options.preserveSource !== false,
|
|
102
107
|
enableDeduplication: options.enableDeduplication !== false,
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
enableNeuralExtraction: options.enableNeuralExtraction !== false, // v4.4.0: Default true
|
|
109
|
+
enableRelationshipInference: options.enableRelationshipInference !== false, // v4.4.0: Default true
|
|
110
|
+
enableConceptExtraction: options.enableConceptExtraction !== false, // Already defaults to true
|
|
111
|
+
deduplicationThreshold: options.deduplicationThreshold || 0.85
|
|
105
112
|
};
|
|
106
113
|
// Report VFS storage stage
|
|
107
114
|
options.onProgress?.({
|
|
@@ -408,7 +415,10 @@ export class ImportCoordinator {
|
|
|
408
415
|
const relationships = [];
|
|
409
416
|
let mergedCount = 0;
|
|
410
417
|
let newCount = 0;
|
|
411
|
-
|
|
418
|
+
// CRITICAL FIX (v4.3.2): Default to true when undefined
|
|
419
|
+
// Previously: if (!options.createEntities) treated undefined as false
|
|
420
|
+
// Now: Only skip when explicitly set to false
|
|
421
|
+
if (options.createEntities === false) {
|
|
412
422
|
return { entities, relationships, merged: 0, newEntities: 0 };
|
|
413
423
|
}
|
|
414
424
|
// Extract rows/sections/entities from result (unified across formats)
|
|
@@ -129,6 +129,24 @@ export declare class SmartExcelImporter {
|
|
|
129
129
|
* Map type string to NounType
|
|
130
130
|
*/
|
|
131
131
|
private mapTypeString;
|
|
132
|
+
/**
|
|
133
|
+
* Infer entity type from Excel sheet name
|
|
134
|
+
*
|
|
135
|
+
* Uses common naming patterns to suggest appropriate entity types:
|
|
136
|
+
* - "Characters", "People", "Humans" → Person
|
|
137
|
+
* - "Places", "Locations" → Location
|
|
138
|
+
* - "Terms", "Concepts", "Glossary" → Concept
|
|
139
|
+
* - etc.
|
|
140
|
+
*
|
|
141
|
+
* @param sheetName - Excel sheet name
|
|
142
|
+
* @returns Inferred NounType or null if no match
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* inferTypeFromSheetName("Characters") // → NounType.Person
|
|
146
|
+
* inferTypeFromSheetName("Places") // → NounType.Location
|
|
147
|
+
* inferTypeFromSheetName("Animals") // → null (no semantic hint)
|
|
148
|
+
*/
|
|
149
|
+
private inferTypeFromSheetName;
|
|
132
150
|
/**
|
|
133
151
|
* Infer relationship type from context using SmartRelationshipExtractor
|
|
134
152
|
*/
|
|
@@ -107,10 +107,16 @@ export class SmartExcelImporter {
|
|
|
107
107
|
? this.brain.extractConcepts(definition, { limit: 10 }).catch(() => [])
|
|
108
108
|
: Promise.resolve([])
|
|
109
109
|
]);
|
|
110
|
-
// Determine main entity type
|
|
110
|
+
// Determine main entity type with priority order:
|
|
111
|
+
// 1. Explicit "Type" column (highest priority - user specified)
|
|
112
|
+
// 2. Sheet name inference (NEW - semantic hint from Excel structure)
|
|
113
|
+
// 3. AI extraction from related entities
|
|
114
|
+
// 4. Default to Thing (fallback)
|
|
115
|
+
const sheetTypeHint = this.inferTypeFromSheetName(row._sheet || '');
|
|
111
116
|
const mainEntityType = type ?
|
|
112
117
|
this.mapTypeString(type) :
|
|
113
|
-
|
|
118
|
+
sheetTypeHint ||
|
|
119
|
+
(relatedEntities.length > 0 ? relatedEntities[0].type : NounType.Thing);
|
|
114
120
|
// Generate entity ID
|
|
115
121
|
const entityId = this.generateEntityId(term);
|
|
116
122
|
// Create main entity
|
|
@@ -297,6 +303,58 @@ export class SmartExcelImporter {
|
|
|
297
303
|
};
|
|
298
304
|
return mapping[normalized] || NounType.Thing;
|
|
299
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* Infer entity type from Excel sheet name
|
|
308
|
+
*
|
|
309
|
+
* Uses common naming patterns to suggest appropriate entity types:
|
|
310
|
+
* - "Characters", "People", "Humans" → Person
|
|
311
|
+
* - "Places", "Locations" → Location
|
|
312
|
+
* - "Terms", "Concepts", "Glossary" → Concept
|
|
313
|
+
* - etc.
|
|
314
|
+
*
|
|
315
|
+
* @param sheetName - Excel sheet name
|
|
316
|
+
* @returns Inferred NounType or null if no match
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* inferTypeFromSheetName("Characters") // → NounType.Person
|
|
320
|
+
* inferTypeFromSheetName("Places") // → NounType.Location
|
|
321
|
+
* inferTypeFromSheetName("Animals") // → null (no semantic hint)
|
|
322
|
+
*/
|
|
323
|
+
inferTypeFromSheetName(sheetName) {
|
|
324
|
+
if (!sheetName)
|
|
325
|
+
return null;
|
|
326
|
+
const normalized = sheetName.toLowerCase();
|
|
327
|
+
// Person types: characters, people, humans, individuals
|
|
328
|
+
if (normalized.match(/character|people|person|human|individual|npc|cast/)) {
|
|
329
|
+
return NounType.Person;
|
|
330
|
+
}
|
|
331
|
+
// Location types: places, locations, areas, regions
|
|
332
|
+
if (normalized.match(/place|location|area|region|zone|geography|map|world/)) {
|
|
333
|
+
return NounType.Location;
|
|
334
|
+
}
|
|
335
|
+
// Concept types: terms, concepts, ideas, glossary
|
|
336
|
+
if (normalized.match(/term|concept|idea|definition|glossary|vocabulary|lexicon/)) {
|
|
337
|
+
return NounType.Concept;
|
|
338
|
+
}
|
|
339
|
+
// Organization types: groups, factions, companies
|
|
340
|
+
if (normalized.match(/organization|company|group|faction|tribe|guild|clan|corp/)) {
|
|
341
|
+
return NounType.Organization;
|
|
342
|
+
}
|
|
343
|
+
// Event types: events, occurrences, happenings
|
|
344
|
+
if (normalized.match(/event|occurrence|happening|battle|encounter|scene/)) {
|
|
345
|
+
return NounType.Event;
|
|
346
|
+
}
|
|
347
|
+
// Product types: items, equipment, gear
|
|
348
|
+
if (normalized.match(/item|product|equipment|gear|weapon|armor|artifact|treasure/)) {
|
|
349
|
+
return NounType.Product;
|
|
350
|
+
}
|
|
351
|
+
// Project types: quests, missions, campaigns
|
|
352
|
+
if (normalized.match(/project|quest|mission|campaign|task/)) {
|
|
353
|
+
return NounType.Project;
|
|
354
|
+
}
|
|
355
|
+
// No semantic match found - return null to continue to next type determination method
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
300
358
|
/**
|
|
301
359
|
* Infer relationship type from context using SmartRelationshipExtractor
|
|
302
360
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soulcraft/brainy",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.2",
|
|
4
4
|
"description": "Universal Knowledge Protocol™ - World's first Triple Intelligence database unifying vector, graph, and document search in one API. 31 nouns × 40 verbs for infinite expressiveness.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|