@soulcraft/brainy 3.37.2 → 3.37.4
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 +5 -0
- package/dist/storage/adapters/fileSystemStorage.js +6 -2
- package/dist/storage/adapters/gcsStorage.js +22 -3
- package/dist/storage/adapters/memoryStorage.js +17 -1
- package/dist/storage/adapters/opfsStorage.js +43 -4
- package/dist/storage/adapters/s3CompatibleStorage.js +45 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [3.37.3](https://github.com/soulcraftlabs/brainy/compare/v3.37.2...v3.37.3) (2025-10-10)
|
|
6
|
+
|
|
7
|
+
- fix: populate totalNodes/totalEdges in ALL storage adapters for HNSW rebuild (a21a845)
|
|
8
|
+
|
|
9
|
+
|
|
5
10
|
### [3.37.2](https://github.com/soulcraftlabs/brainy/compare/v3.37.1...v3.37.2) (2025-10-10)
|
|
6
11
|
|
|
7
12
|
- fix: ensure GCS storage initialization before pagination (2565685)
|
|
@@ -1349,13 +1349,17 @@ export class FileSystemStorage extends BaseStorage {
|
|
|
1349
1349
|
mergeStatistics(storageStats, localStats) {
|
|
1350
1350
|
// Handle null cases
|
|
1351
1351
|
if (!storageStats && !localStats) {
|
|
1352
|
+
// CRITICAL FIX (v3.37.4): Statistics files don't exist yet (first init)
|
|
1353
|
+
// Return minimal stats with counts instead of zeros
|
|
1354
|
+
// This prevents HNSW from seeing entityCount=0 during index rebuild
|
|
1352
1355
|
return {
|
|
1353
1356
|
nounCount: {},
|
|
1354
1357
|
verbCount: {},
|
|
1355
1358
|
metadataCount: {},
|
|
1356
1359
|
hnswIndexSize: 0,
|
|
1357
|
-
totalNodes:
|
|
1358
|
-
totalEdges:
|
|
1360
|
+
totalNodes: this.totalNounCount,
|
|
1361
|
+
totalEdges: this.totalVerbCount,
|
|
1362
|
+
totalMetadata: 0,
|
|
1359
1363
|
lastUpdated: new Date().toISOString()
|
|
1360
1364
|
};
|
|
1361
1365
|
}
|
|
@@ -1177,12 +1177,31 @@ export class GcsStorage extends BaseStorage {
|
|
|
1177
1177
|
const [contents] = await file.download();
|
|
1178
1178
|
const statistics = JSON.parse(contents.toString());
|
|
1179
1179
|
this.logger.trace('Statistics retrieved successfully');
|
|
1180
|
-
|
|
1180
|
+
// CRITICAL FIX: Populate totalNodes and totalEdges from in-memory counts
|
|
1181
|
+
// HNSW rebuild depends on these fields to determine entity count
|
|
1182
|
+
return {
|
|
1183
|
+
...statistics,
|
|
1184
|
+
totalNodes: this.totalNounCount,
|
|
1185
|
+
totalEdges: this.totalVerbCount,
|
|
1186
|
+
lastUpdated: new Date().toISOString()
|
|
1187
|
+
};
|
|
1181
1188
|
}
|
|
1182
1189
|
catch (error) {
|
|
1183
1190
|
if (error.code === 404) {
|
|
1184
|
-
|
|
1185
|
-
|
|
1191
|
+
// CRITICAL FIX (v3.37.4): Statistics file doesn't exist yet (first restart)
|
|
1192
|
+
// Return minimal stats with counts instead of null
|
|
1193
|
+
// This prevents HNSW from seeing entityCount=0 during index rebuild
|
|
1194
|
+
this.logger.trace('Statistics file not found - returning minimal stats with counts');
|
|
1195
|
+
return {
|
|
1196
|
+
nounCount: {},
|
|
1197
|
+
verbCount: {},
|
|
1198
|
+
metadataCount: {},
|
|
1199
|
+
hnswIndexSize: 0,
|
|
1200
|
+
totalNodes: this.totalNounCount,
|
|
1201
|
+
totalEdges: this.totalVerbCount,
|
|
1202
|
+
totalMetadata: 0,
|
|
1203
|
+
lastUpdated: new Date().toISOString()
|
|
1204
|
+
};
|
|
1186
1205
|
}
|
|
1187
1206
|
this.logger.error('Failed to get statistics:', error);
|
|
1188
1207
|
return null;
|
|
@@ -551,7 +551,19 @@ export class MemoryStorage extends BaseStorage {
|
|
|
551
551
|
*/
|
|
552
552
|
async getStatisticsData() {
|
|
553
553
|
if (!this.statistics) {
|
|
554
|
-
|
|
554
|
+
// CRITICAL FIX (v3.37.4): Statistics don't exist yet (first init)
|
|
555
|
+
// Return minimal stats with counts instead of null
|
|
556
|
+
// This prevents HNSW from seeing entityCount=0 during index rebuild
|
|
557
|
+
return {
|
|
558
|
+
nounCount: {},
|
|
559
|
+
verbCount: {},
|
|
560
|
+
metadataCount: {},
|
|
561
|
+
hnswIndexSize: 0,
|
|
562
|
+
totalNodes: this.totalNounCount,
|
|
563
|
+
totalEdges: this.totalVerbCount,
|
|
564
|
+
totalMetadata: 0,
|
|
565
|
+
lastUpdated: new Date().toISOString()
|
|
566
|
+
};
|
|
555
567
|
}
|
|
556
568
|
// Return a deep copy to avoid reference issues
|
|
557
569
|
return {
|
|
@@ -559,6 +571,10 @@ export class MemoryStorage extends BaseStorage {
|
|
|
559
571
|
verbCount: { ...this.statistics.verbCount },
|
|
560
572
|
metadataCount: { ...this.statistics.metadataCount },
|
|
561
573
|
hnswIndexSize: this.statistics.hnswIndexSize,
|
|
574
|
+
// CRITICAL FIX: Populate totalNodes and totalEdges from in-memory counts
|
|
575
|
+
// HNSW rebuild depends on these fields to determine entity count
|
|
576
|
+
totalNodes: this.totalNounCount,
|
|
577
|
+
totalEdges: this.totalVerbCount,
|
|
562
578
|
lastUpdated: this.statistics.lastUpdated,
|
|
563
579
|
// Include serviceActivity if present
|
|
564
580
|
...(this.statistics.serviceActivity && {
|
|
@@ -1125,6 +1125,10 @@ export class OPFSStorage extends BaseStorage {
|
|
|
1125
1125
|
verbCount: { ...this.statistics.verbCount },
|
|
1126
1126
|
metadataCount: { ...this.statistics.metadataCount },
|
|
1127
1127
|
hnswIndexSize: this.statistics.hnswIndexSize,
|
|
1128
|
+
// CRITICAL FIX: Populate totalNodes and totalEdges from in-memory counts
|
|
1129
|
+
// HNSW rebuild depends on these fields to determine entity count
|
|
1130
|
+
totalNodes: this.totalNounCount,
|
|
1131
|
+
totalEdges: this.totalVerbCount,
|
|
1128
1132
|
lastUpdated: this.statistics.lastUpdated
|
|
1129
1133
|
};
|
|
1130
1134
|
}
|
|
@@ -1149,6 +1153,10 @@ export class OPFSStorage extends BaseStorage {
|
|
|
1149
1153
|
verbCount: { ...this.statistics.verbCount },
|
|
1150
1154
|
metadataCount: { ...this.statistics.metadataCount },
|
|
1151
1155
|
hnswIndexSize: this.statistics.hnswIndexSize,
|
|
1156
|
+
// CRITICAL FIX: Populate totalNodes and totalEdges from in-memory counts
|
|
1157
|
+
// HNSW rebuild depends on these fields to determine entity count
|
|
1158
|
+
totalNodes: this.totalNounCount,
|
|
1159
|
+
totalEdges: this.totalVerbCount,
|
|
1152
1160
|
lastUpdated: this.statistics.lastUpdated
|
|
1153
1161
|
};
|
|
1154
1162
|
}
|
|
@@ -1171,6 +1179,10 @@ export class OPFSStorage extends BaseStorage {
|
|
|
1171
1179
|
verbCount: { ...this.statistics.verbCount },
|
|
1172
1180
|
metadataCount: { ...this.statistics.metadataCount },
|
|
1173
1181
|
hnswIndexSize: this.statistics.hnswIndexSize,
|
|
1182
|
+
// CRITICAL FIX: Populate totalNodes and totalEdges from in-memory counts
|
|
1183
|
+
// HNSW rebuild depends on these fields to determine entity count
|
|
1184
|
+
totalNodes: this.totalNounCount,
|
|
1185
|
+
totalEdges: this.totalVerbCount,
|
|
1174
1186
|
lastUpdated: this.statistics.lastUpdated
|
|
1175
1187
|
};
|
|
1176
1188
|
}
|
|
@@ -1191,18 +1203,45 @@ export class OPFSStorage extends BaseStorage {
|
|
|
1191
1203
|
verbCount: { ...this.statistics.verbCount },
|
|
1192
1204
|
metadataCount: { ...this.statistics.metadataCount },
|
|
1193
1205
|
hnswIndexSize: this.statistics.hnswIndexSize,
|
|
1206
|
+
// CRITICAL FIX: Populate totalNodes and totalEdges from in-memory counts
|
|
1207
|
+
// HNSW rebuild depends on these fields to determine entity count
|
|
1208
|
+
totalNodes: this.totalNounCount,
|
|
1209
|
+
totalEdges: this.totalVerbCount,
|
|
1194
1210
|
lastUpdated: this.statistics.lastUpdated
|
|
1195
1211
|
};
|
|
1196
1212
|
}
|
|
1197
1213
|
}
|
|
1198
1214
|
catch (error) {
|
|
1199
|
-
//
|
|
1200
|
-
|
|
1215
|
+
// CRITICAL FIX (v3.37.4): No statistics files exist (first init)
|
|
1216
|
+
// Return minimal stats with counts instead of null
|
|
1217
|
+
// This prevents HNSW from seeing entityCount=0 during index rebuild
|
|
1218
|
+
return {
|
|
1219
|
+
nounCount: {},
|
|
1220
|
+
verbCount: {},
|
|
1221
|
+
metadataCount: {},
|
|
1222
|
+
hnswIndexSize: 0,
|
|
1223
|
+
totalNodes: this.totalNounCount,
|
|
1224
|
+
totalEdges: this.totalVerbCount,
|
|
1225
|
+
totalMetadata: 0,
|
|
1226
|
+
lastUpdated: new Date().toISOString()
|
|
1227
|
+
};
|
|
1201
1228
|
}
|
|
1202
1229
|
}
|
|
1203
1230
|
}
|
|
1204
|
-
// If we get here and statistics is null, return
|
|
1205
|
-
|
|
1231
|
+
// If we get here and statistics is null, return minimal stats with counts
|
|
1232
|
+
if (!this.statistics) {
|
|
1233
|
+
return {
|
|
1234
|
+
nounCount: {},
|
|
1235
|
+
verbCount: {},
|
|
1236
|
+
metadataCount: {},
|
|
1237
|
+
hnswIndexSize: 0,
|
|
1238
|
+
totalNodes: this.totalNounCount,
|
|
1239
|
+
totalEdges: this.totalVerbCount,
|
|
1240
|
+
totalMetadata: 0,
|
|
1241
|
+
lastUpdated: new Date().toISOString()
|
|
1242
|
+
};
|
|
1243
|
+
}
|
|
1244
|
+
return this.statistics;
|
|
1206
1245
|
}
|
|
1207
1246
|
catch (error) {
|
|
1208
1247
|
console.error('Failed to get statistics data:', error);
|
|
@@ -2144,6 +2144,10 @@ export class S3CompatibleStorage extends BaseStorage {
|
|
|
2144
2144
|
verbCount: { ...this.statisticsCache.verbCount },
|
|
2145
2145
|
metadataCount: { ...this.statisticsCache.metadataCount },
|
|
2146
2146
|
hnswIndexSize: this.statisticsCache.hnswIndexSize,
|
|
2147
|
+
// CRITICAL FIX: Populate totalNodes and totalEdges from in-memory counts
|
|
2148
|
+
// HNSW rebuild depends on these fields to determine entity count
|
|
2149
|
+
totalNodes: this.totalNounCount,
|
|
2150
|
+
totalEdges: this.totalVerbCount,
|
|
2147
2151
|
lastUpdated: this.statisticsCache.lastUpdated
|
|
2148
2152
|
};
|
|
2149
2153
|
}
|
|
@@ -2186,6 +2190,26 @@ export class S3CompatibleStorage extends BaseStorage {
|
|
|
2186
2190
|
hnswIndexSize: statistics.hnswIndexSize,
|
|
2187
2191
|
lastUpdated: statistics.lastUpdated
|
|
2188
2192
|
};
|
|
2193
|
+
// CRITICAL FIX: Add totalNodes and totalEdges from in-memory counts
|
|
2194
|
+
// HNSW rebuild depends on these fields to determine entity count
|
|
2195
|
+
return {
|
|
2196
|
+
...statistics,
|
|
2197
|
+
totalNodes: this.totalNounCount,
|
|
2198
|
+
totalEdges: this.totalVerbCount
|
|
2199
|
+
};
|
|
2200
|
+
}
|
|
2201
|
+
// If we get here and statistics is null, return minimal stats with counts
|
|
2202
|
+
if (!statistics) {
|
|
2203
|
+
return {
|
|
2204
|
+
nounCount: {},
|
|
2205
|
+
verbCount: {},
|
|
2206
|
+
metadataCount: {},
|
|
2207
|
+
hnswIndexSize: 0,
|
|
2208
|
+
totalNodes: this.totalNounCount,
|
|
2209
|
+
totalEdges: this.totalVerbCount,
|
|
2210
|
+
totalMetadata: 0,
|
|
2211
|
+
lastUpdated: new Date().toISOString()
|
|
2212
|
+
};
|
|
2189
2213
|
}
|
|
2190
2214
|
// Successfully loaded statistics from storage
|
|
2191
2215
|
return statistics;
|
|
@@ -2193,7 +2217,27 @@ export class S3CompatibleStorage extends BaseStorage {
|
|
|
2193
2217
|
catch (error) {
|
|
2194
2218
|
this.logger.warn('Error getting statistics data, returning cached or null:', error);
|
|
2195
2219
|
// Return cached data if available, even if stale, rather than throwing
|
|
2196
|
-
|
|
2220
|
+
// CRITICAL FIX: Add totalNodes and totalEdges when returning cached data
|
|
2221
|
+
if (this.statisticsCache) {
|
|
2222
|
+
return {
|
|
2223
|
+
...this.statisticsCache,
|
|
2224
|
+
totalNodes: this.totalNounCount,
|
|
2225
|
+
totalEdges: this.totalVerbCount
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
2228
|
+
// CRITICAL FIX (v3.37.4): Statistics file doesn't exist yet (first restart)
|
|
2229
|
+
// Return minimal stats with counts instead of null
|
|
2230
|
+
// This prevents HNSW from seeing entityCount=0 during index rebuild
|
|
2231
|
+
return {
|
|
2232
|
+
nounCount: {},
|
|
2233
|
+
verbCount: {},
|
|
2234
|
+
metadataCount: {},
|
|
2235
|
+
hnswIndexSize: 0,
|
|
2236
|
+
totalNodes: this.totalNounCount,
|
|
2237
|
+
totalEdges: this.totalVerbCount,
|
|
2238
|
+
totalMetadata: 0,
|
|
2239
|
+
lastUpdated: new Date().toISOString()
|
|
2240
|
+
};
|
|
2197
2241
|
}
|
|
2198
2242
|
}
|
|
2199
2243
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soulcraft/brainy",
|
|
3
|
-
"version": "3.37.
|
|
3
|
+
"version": "3.37.4",
|
|
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",
|