@soulcraft/brainy 4.7.3 → 4.8.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 +44 -0
- package/dist/api/DataAPI.js +3 -3
- package/dist/brainy.d.ts +7 -2
- package/dist/brainy.js +69 -39
- package/dist/coreTypes.d.ts +64 -14
- package/dist/coreTypes.js +3 -1
- package/dist/graph/graphAdjacencyIndex.js +38 -2
- package/dist/neural/SmartExtractor.js +13 -3
- package/dist/neural/embeddedTypeEmbeddings.d.ts +1 -1
- package/dist/neural/embeddedTypeEmbeddings.js +2 -2
- package/dist/neural/signals/PatternSignal.js +38 -18
- package/dist/storage/adapters/azureBlobStorage.js +69 -11
- package/dist/storage/adapters/fileSystemStorage.js +37 -9
- package/dist/storage/adapters/gcsStorage.js +25 -6
- package/dist/storage/adapters/memoryStorage.js +33 -9
- package/dist/storage/adapters/opfsStorage.js +29 -10
- package/dist/storage/adapters/r2Storage.js +15 -5
- package/dist/storage/adapters/s3CompatibleStorage.js +26 -6
- package/dist/storage/adapters/typeAwareStorageAdapter.js +64 -15
- package/dist/storage/baseStorage.js +43 -6
- package/dist/types/brainy.types.d.ts +4 -0
- package/dist/types/graphTypes.d.ts +1 -0
- package/dist/utils/entityIdMapper.js +3 -2
- package/dist/utils/metadataIndex.d.ts +23 -2
- package/dist/utils/metadataIndex.js +43 -12
- package/package.json +1 -1
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* v4.0.0: Fully compatible with metadata/vector separation architecture
|
|
13
13
|
*/
|
|
14
|
+
import { NounType } from '../../coreTypes.js';
|
|
14
15
|
import { BaseStorage, SYSTEM_DIR, STATISTICS_KEY, getDirectoryPath } from '../baseStorage.js';
|
|
15
16
|
import { BrainyError } from '../../errors/brainyError.js';
|
|
16
17
|
import { CacheManager } from '../cacheManager.js';
|
|
@@ -942,9 +943,8 @@ export class AzureBlobStorage extends BaseStorage {
|
|
|
942
943
|
const node = await this.getNode(id);
|
|
943
944
|
if (!node)
|
|
944
945
|
continue;
|
|
946
|
+
// FIX v4.7.4: Don't skip nouns without metadata - metadata is optional in v4.0.0
|
|
945
947
|
const metadata = await this.getNounMetadata(id);
|
|
946
|
-
if (!metadata)
|
|
947
|
-
continue;
|
|
948
948
|
// Apply filters if provided
|
|
949
949
|
if (options.filter) {
|
|
950
950
|
if (options.filter.nounType) {
|
|
@@ -957,10 +957,23 @@ export class AzureBlobStorage extends BaseStorage {
|
|
|
957
957
|
}
|
|
958
958
|
}
|
|
959
959
|
}
|
|
960
|
-
//
|
|
960
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
961
|
+
const metadataObj = (metadata || {});
|
|
962
|
+
const { noun: nounType, createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
961
963
|
items.push({
|
|
962
|
-
|
|
963
|
-
|
|
964
|
+
id: node.id,
|
|
965
|
+
vector: node.vector,
|
|
966
|
+
connections: node.connections,
|
|
967
|
+
level: node.level || 0,
|
|
968
|
+
type: nounType || NounType.Thing,
|
|
969
|
+
createdAt: createdAt || Date.now(),
|
|
970
|
+
updatedAt: updatedAt || Date.now(),
|
|
971
|
+
confidence: confidence,
|
|
972
|
+
weight: weight,
|
|
973
|
+
service: service,
|
|
974
|
+
data: data,
|
|
975
|
+
createdBy,
|
|
976
|
+
metadata: customMetadata
|
|
964
977
|
});
|
|
965
978
|
count++;
|
|
966
979
|
}
|
|
@@ -998,9 +1011,24 @@ export class AzureBlobStorage extends BaseStorage {
|
|
|
998
1011
|
if (!verb || verb.sourceId !== sourceId)
|
|
999
1012
|
continue;
|
|
1000
1013
|
const metadata = await this.getVerbMetadata(id);
|
|
1014
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
1015
|
+
const metadataObj = (metadata || {});
|
|
1016
|
+
const { createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
1001
1017
|
items.push({
|
|
1002
|
-
|
|
1003
|
-
|
|
1018
|
+
id: verb.id,
|
|
1019
|
+
vector: verb.vector,
|
|
1020
|
+
connections: verb.connections,
|
|
1021
|
+
verb: verb.verb,
|
|
1022
|
+
sourceId: verb.sourceId,
|
|
1023
|
+
targetId: verb.targetId,
|
|
1024
|
+
createdAt: createdAt || Date.now(),
|
|
1025
|
+
updatedAt: updatedAt || Date.now(),
|
|
1026
|
+
confidence: confidence,
|
|
1027
|
+
weight: weight,
|
|
1028
|
+
service: service,
|
|
1029
|
+
data: data,
|
|
1030
|
+
createdBy,
|
|
1031
|
+
metadata: customMetadata
|
|
1004
1032
|
});
|
|
1005
1033
|
}
|
|
1006
1034
|
return items;
|
|
@@ -1022,9 +1050,24 @@ export class AzureBlobStorage extends BaseStorage {
|
|
|
1022
1050
|
if (!verb || verb.targetId !== targetId)
|
|
1023
1051
|
continue;
|
|
1024
1052
|
const metadata = await this.getVerbMetadata(id);
|
|
1053
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
1054
|
+
const metadataObj = (metadata || {});
|
|
1055
|
+
const { createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
1025
1056
|
items.push({
|
|
1026
|
-
|
|
1027
|
-
|
|
1057
|
+
id: verb.id,
|
|
1058
|
+
vector: verb.vector,
|
|
1059
|
+
connections: verb.connections,
|
|
1060
|
+
verb: verb.verb,
|
|
1061
|
+
sourceId: verb.sourceId,
|
|
1062
|
+
targetId: verb.targetId,
|
|
1063
|
+
createdAt: createdAt || Date.now(),
|
|
1064
|
+
updatedAt: updatedAt || Date.now(),
|
|
1065
|
+
confidence: confidence,
|
|
1066
|
+
weight: weight,
|
|
1067
|
+
service: service,
|
|
1068
|
+
data: data,
|
|
1069
|
+
createdBy,
|
|
1070
|
+
metadata: customMetadata
|
|
1028
1071
|
});
|
|
1029
1072
|
}
|
|
1030
1073
|
return items;
|
|
@@ -1046,9 +1089,24 @@ export class AzureBlobStorage extends BaseStorage {
|
|
|
1046
1089
|
if (!verb || verb.verb !== type)
|
|
1047
1090
|
continue;
|
|
1048
1091
|
const metadata = await this.getVerbMetadata(id);
|
|
1092
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
1093
|
+
const metadataObj = (metadata || {});
|
|
1094
|
+
const { createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
1049
1095
|
items.push({
|
|
1050
|
-
|
|
1051
|
-
|
|
1096
|
+
id: verb.id,
|
|
1097
|
+
vector: verb.vector,
|
|
1098
|
+
connections: verb.connections,
|
|
1099
|
+
verb: verb.verb,
|
|
1100
|
+
sourceId: verb.sourceId,
|
|
1101
|
+
targetId: verb.targetId,
|
|
1102
|
+
createdAt: createdAt || Date.now(),
|
|
1103
|
+
updatedAt: updatedAt || Date.now(),
|
|
1104
|
+
confidence: confidence,
|
|
1105
|
+
weight: weight,
|
|
1106
|
+
service: service,
|
|
1107
|
+
data: data,
|
|
1108
|
+
createdBy,
|
|
1109
|
+
metadata: customMetadata
|
|
1052
1110
|
});
|
|
1053
1111
|
}
|
|
1054
1112
|
return items;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* File System Storage Adapter
|
|
3
3
|
* File system storage adapter for Node.js environments
|
|
4
4
|
*/
|
|
5
|
+
import { NounType } from '../../coreTypes.js';
|
|
5
6
|
import { BaseStorage, SYSTEM_DIR, STATISTICS_KEY } from '../baseStorage.js';
|
|
6
7
|
// Node.js modules - dynamically imported to avoid issues in browser environments
|
|
7
8
|
let fs;
|
|
@@ -745,11 +746,10 @@ export class FileSystemStorage extends BaseStorage {
|
|
|
745
746
|
const data = await fs.promises.readFile(this.getNodePath(id), 'utf-8');
|
|
746
747
|
const parsedNoun = JSON.parse(data);
|
|
747
748
|
// v4.0.0: Load metadata from separate storage
|
|
749
|
+
// FIX v4.7.4: Don't skip nouns without metadata - metadata is optional in v4.0.0
|
|
748
750
|
const metadata = await this.getNounMetadata(id);
|
|
749
|
-
if (!metadata)
|
|
750
|
-
continue;
|
|
751
751
|
// Apply filter if provided
|
|
752
|
-
if (options.filter) {
|
|
752
|
+
if (options.filter && metadata) {
|
|
753
753
|
let matches = true;
|
|
754
754
|
for (const [key, value] of Object.entries(options.filter)) {
|
|
755
755
|
if (metadata[key] !== value) {
|
|
@@ -769,13 +769,23 @@ export class FileSystemStorage extends BaseStorage {
|
|
|
769
769
|
}
|
|
770
770
|
connections = connectionsMap;
|
|
771
771
|
}
|
|
772
|
-
// v4.
|
|
772
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
773
|
+
const metadataObj = (metadata || {});
|
|
774
|
+
const { noun: nounType, createdAt, updatedAt, confidence, weight, service, data: dataField, createdBy, ...customMetadata } = metadataObj;
|
|
773
775
|
const nounWithMetadata = {
|
|
774
776
|
id: parsedNoun.id,
|
|
775
777
|
vector: parsedNoun.vector,
|
|
776
778
|
connections: connections,
|
|
777
779
|
level: parsedNoun.level || 0,
|
|
778
|
-
|
|
780
|
+
type: nounType || NounType.Thing,
|
|
781
|
+
createdAt: createdAt || Date.now(),
|
|
782
|
+
updatedAt: updatedAt || Date.now(),
|
|
783
|
+
confidence: confidence,
|
|
784
|
+
weight: weight,
|
|
785
|
+
service: service,
|
|
786
|
+
data: dataField,
|
|
787
|
+
createdBy,
|
|
788
|
+
metadata: customMetadata
|
|
779
789
|
};
|
|
780
790
|
items.push(nounWithMetadata);
|
|
781
791
|
successfullyLoaded++;
|
|
@@ -1139,7 +1149,9 @@ export class FileSystemStorage extends BaseStorage {
|
|
|
1139
1149
|
}
|
|
1140
1150
|
connections = connectionsMap;
|
|
1141
1151
|
}
|
|
1142
|
-
// v4.
|
|
1152
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
1153
|
+
const metadataObj = metadata;
|
|
1154
|
+
const { createdAt, updatedAt, confidence, weight, service, data: dataField, createdBy, ...customMetadata } = metadataObj;
|
|
1143
1155
|
const verbWithMetadata = {
|
|
1144
1156
|
id: edge.id,
|
|
1145
1157
|
vector: edge.vector,
|
|
@@ -1147,7 +1159,14 @@ export class FileSystemStorage extends BaseStorage {
|
|
|
1147
1159
|
verb: edge.verb,
|
|
1148
1160
|
sourceId: edge.sourceId,
|
|
1149
1161
|
targetId: edge.targetId,
|
|
1150
|
-
|
|
1162
|
+
createdAt: createdAt || Date.now(),
|
|
1163
|
+
updatedAt: updatedAt || Date.now(),
|
|
1164
|
+
confidence: confidence,
|
|
1165
|
+
weight: weight,
|
|
1166
|
+
service: service,
|
|
1167
|
+
data: dataField,
|
|
1168
|
+
createdBy,
|
|
1169
|
+
metadata: customMetadata
|
|
1151
1170
|
};
|
|
1152
1171
|
// Apply filters if provided
|
|
1153
1172
|
if (options.filter) {
|
|
@@ -2020,7 +2039,9 @@ export class FileSystemStorage extends BaseStorage {
|
|
|
2020
2039
|
}
|
|
2021
2040
|
connections = connectionsMap;
|
|
2022
2041
|
}
|
|
2023
|
-
// v4.
|
|
2042
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
2043
|
+
const metadataObj = metadata;
|
|
2044
|
+
const { createdAt, updatedAt, confidence, weight, service, data: dataField, createdBy, ...customMetadata } = metadataObj;
|
|
2024
2045
|
const verbWithMetadata = {
|
|
2025
2046
|
id: edge.id,
|
|
2026
2047
|
vector: edge.vector,
|
|
@@ -2028,7 +2049,14 @@ export class FileSystemStorage extends BaseStorage {
|
|
|
2028
2049
|
verb: edge.verb,
|
|
2029
2050
|
sourceId: edge.sourceId,
|
|
2030
2051
|
targetId: edge.targetId,
|
|
2031
|
-
|
|
2052
|
+
createdAt: createdAt || Date.now(),
|
|
2053
|
+
updatedAt: updatedAt || Date.now(),
|
|
2054
|
+
confidence: confidence,
|
|
2055
|
+
weight: weight,
|
|
2056
|
+
service: service,
|
|
2057
|
+
data: dataField,
|
|
2058
|
+
createdBy,
|
|
2059
|
+
metadata: customMetadata
|
|
2032
2060
|
};
|
|
2033
2061
|
// Apply filters
|
|
2034
2062
|
if (options.filter) {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* 3. Service Account Credentials Object
|
|
9
9
|
* 4. HMAC Keys (fallback for backward compatibility)
|
|
10
10
|
*/
|
|
11
|
+
import { NounType } from '../../coreTypes.js';
|
|
11
12
|
import { BaseStorage, SYSTEM_DIR, STATISTICS_KEY, getDirectoryPath } from '../baseStorage.js';
|
|
12
13
|
import { BrainyError } from '../../errors/brainyError.js';
|
|
13
14
|
import { CacheManager } from '../cacheManager.js';
|
|
@@ -804,9 +805,8 @@ export class GcsStorage extends BaseStorage {
|
|
|
804
805
|
// v4.0.0: Combine nodes with metadata to create HNSWNounWithMetadata[]
|
|
805
806
|
const items = [];
|
|
806
807
|
for (const node of result.nodes) {
|
|
808
|
+
// FIX v4.7.4: Don't skip nouns without metadata - metadata is optional in v4.0.0
|
|
807
809
|
const metadata = await this.getNounMetadata(node.id);
|
|
808
|
-
if (!metadata)
|
|
809
|
-
continue;
|
|
810
810
|
// Apply filters if provided
|
|
811
811
|
if (options.filter) {
|
|
812
812
|
// Filter by noun type
|
|
@@ -833,13 +833,23 @@ export class GcsStorage extends BaseStorage {
|
|
|
833
833
|
continue;
|
|
834
834
|
}
|
|
835
835
|
}
|
|
836
|
-
//
|
|
836
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
837
|
+
const metadataObj = (metadata || {});
|
|
838
|
+
const { noun: nounType, createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
837
839
|
const nounWithMetadata = {
|
|
838
840
|
id: node.id,
|
|
839
841
|
vector: [...node.vector],
|
|
840
842
|
connections: new Map(node.connections),
|
|
841
843
|
level: node.level || 0,
|
|
842
|
-
|
|
844
|
+
type: nounType || NounType.Thing,
|
|
845
|
+
createdAt: createdAt || Date.now(),
|
|
846
|
+
updatedAt: updatedAt || Date.now(),
|
|
847
|
+
confidence: confidence,
|
|
848
|
+
weight: weight,
|
|
849
|
+
service: service,
|
|
850
|
+
data: data,
|
|
851
|
+
createdBy,
|
|
852
|
+
metadata: customMetadata
|
|
843
853
|
};
|
|
844
854
|
items.push(nounWithMetadata);
|
|
845
855
|
}
|
|
@@ -1077,7 +1087,9 @@ export class GcsStorage extends BaseStorage {
|
|
|
1077
1087
|
continue;
|
|
1078
1088
|
}
|
|
1079
1089
|
}
|
|
1080
|
-
//
|
|
1090
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
1091
|
+
const metadataObj = (metadata || {});
|
|
1092
|
+
const { createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
1081
1093
|
const verbWithMetadata = {
|
|
1082
1094
|
id: hnswVerb.id,
|
|
1083
1095
|
vector: [...hnswVerb.vector],
|
|
@@ -1085,7 +1097,14 @@ export class GcsStorage extends BaseStorage {
|
|
|
1085
1097
|
verb: hnswVerb.verb,
|
|
1086
1098
|
sourceId: hnswVerb.sourceId,
|
|
1087
1099
|
targetId: hnswVerb.targetId,
|
|
1088
|
-
|
|
1100
|
+
createdAt: createdAt || Date.now(),
|
|
1101
|
+
updatedAt: updatedAt || Date.now(),
|
|
1102
|
+
confidence: confidence,
|
|
1103
|
+
weight: weight,
|
|
1104
|
+
service: service,
|
|
1105
|
+
data: data,
|
|
1106
|
+
createdBy,
|
|
1107
|
+
metadata: customMetadata
|
|
1089
1108
|
};
|
|
1090
1109
|
items.push(verbWithMetadata);
|
|
1091
1110
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Memory Storage Adapter
|
|
3
3
|
* In-memory storage adapter for environments where persistent storage is not available or needed
|
|
4
4
|
*/
|
|
5
|
+
import { NounType } from '../../coreTypes.js';
|
|
5
6
|
import { BaseStorage } from '../baseStorage.js';
|
|
6
7
|
// No type aliases needed - using the original types directly
|
|
7
8
|
/**
|
|
@@ -152,16 +153,28 @@ export class MemoryStorage extends BaseStorage {
|
|
|
152
153
|
if (!noun)
|
|
153
154
|
continue;
|
|
154
155
|
// Get metadata from separate storage
|
|
156
|
+
// FIX v4.7.4: Don't skip nouns without metadata - metadata is optional in v4.0.0
|
|
155
157
|
const metadata = await this.getNounMetadata(id);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
158
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
159
|
+
const metadataObj = (metadata || {});
|
|
160
|
+
const { noun: nounType, createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
161
|
+
// v4.8.0: Create HNSWNounWithMetadata with standard fields at top-level
|
|
159
162
|
const nounWithMetadata = {
|
|
160
163
|
id: noun.id,
|
|
161
164
|
vector: [...noun.vector],
|
|
162
165
|
connections: new Map(),
|
|
163
166
|
level: noun.level || 0,
|
|
164
|
-
|
|
167
|
+
// v4.8.0: Standard fields at top-level
|
|
168
|
+
type: nounType || NounType.Thing,
|
|
169
|
+
createdAt: createdAt || Date.now(),
|
|
170
|
+
updatedAt: updatedAt || Date.now(),
|
|
171
|
+
confidence: confidence,
|
|
172
|
+
weight: weight,
|
|
173
|
+
service: service,
|
|
174
|
+
data: data,
|
|
175
|
+
createdBy,
|
|
176
|
+
// Only custom user fields in metadata
|
|
177
|
+
metadata: customMetadata
|
|
165
178
|
};
|
|
166
179
|
// Copy connections
|
|
167
180
|
for (const [level, connections] of noun.connections.entries()) {
|
|
@@ -357,10 +370,13 @@ export class MemoryStorage extends BaseStorage {
|
|
|
357
370
|
if (!hnswVerb)
|
|
358
371
|
continue;
|
|
359
372
|
// Get metadata from separate storage
|
|
373
|
+
// FIX v4.7.4: Don't skip verbs without metadata - metadata is optional in v4.0.0
|
|
374
|
+
// Core fields (verb, sourceId, targetId) are in HNSWVerb itself
|
|
360
375
|
const metadata = await this.getVerbMetadata(id);
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
376
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
377
|
+
const metadataObj = metadata || {};
|
|
378
|
+
const { createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
379
|
+
// v4.8.0: Create HNSWVerbWithMetadata with standard fields at top-level
|
|
364
380
|
const verbWithMetadata = {
|
|
365
381
|
id: hnswVerb.id,
|
|
366
382
|
vector: [...hnswVerb.vector],
|
|
@@ -369,8 +385,16 @@ export class MemoryStorage extends BaseStorage {
|
|
|
369
385
|
verb: hnswVerb.verb,
|
|
370
386
|
sourceId: hnswVerb.sourceId,
|
|
371
387
|
targetId: hnswVerb.targetId,
|
|
372
|
-
//
|
|
373
|
-
|
|
388
|
+
// v4.8.0: Standard fields at top-level
|
|
389
|
+
createdAt: createdAt || Date.now(),
|
|
390
|
+
updatedAt: updatedAt || Date.now(),
|
|
391
|
+
confidence: confidence,
|
|
392
|
+
weight: weight,
|
|
393
|
+
service: service,
|
|
394
|
+
data: data,
|
|
395
|
+
createdBy,
|
|
396
|
+
// Only custom user fields in metadata
|
|
397
|
+
metadata: customMetadata
|
|
374
398
|
};
|
|
375
399
|
// Copy connections
|
|
376
400
|
for (const [level, connections] of hnswVerb.connections.entries()) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* OPFS (Origin Private File System) Storage Adapter
|
|
3
3
|
* Provides persistent storage for the vector database using the Origin Private File System API
|
|
4
4
|
*/
|
|
5
|
+
import { NounType } from '../../coreTypes.js';
|
|
5
6
|
import { BaseStorage, NOUNS_DIR, VERBS_DIR, METADATA_DIR, NOUN_METADATA_DIR, VERB_METADATA_DIR, INDEX_DIR } from '../baseStorage.js';
|
|
6
7
|
import { getShardIdFromUuid } from '../sharding.js';
|
|
7
8
|
import '../../types/fileSystemTypes.js';
|
|
@@ -1411,11 +1412,10 @@ export class OPFSStorage extends BaseStorage {
|
|
|
1411
1412
|
const noun = await this.getNoun_internal(id);
|
|
1412
1413
|
if (noun) {
|
|
1413
1414
|
// Load metadata for filtering and combining
|
|
1415
|
+
// FIX v4.7.4: Don't skip nouns without metadata - metadata is optional in v4.0.0
|
|
1414
1416
|
const metadata = await this.getNounMetadata(id);
|
|
1415
|
-
if (!metadata)
|
|
1416
|
-
continue;
|
|
1417
1417
|
// Apply filters if provided
|
|
1418
|
-
if (options.filter) {
|
|
1418
|
+
if (options.filter && metadata) {
|
|
1419
1419
|
// Filter by noun type
|
|
1420
1420
|
if (options.filter.nounType) {
|
|
1421
1421
|
const nounTypes = Array.isArray(options.filter.nounType)
|
|
@@ -1447,13 +1447,23 @@ export class OPFSStorage extends BaseStorage {
|
|
|
1447
1447
|
continue;
|
|
1448
1448
|
}
|
|
1449
1449
|
}
|
|
1450
|
-
// v4.
|
|
1450
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
1451
|
+
const metadataObj = (metadata || {});
|
|
1452
|
+
const { noun: nounType, createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
1451
1453
|
const nounWithMetadata = {
|
|
1452
1454
|
id: noun.id,
|
|
1453
1455
|
vector: [...noun.vector],
|
|
1454
1456
|
connections: new Map(noun.connections),
|
|
1455
1457
|
level: noun.level || 0,
|
|
1456
|
-
|
|
1458
|
+
type: nounType || NounType.Thing,
|
|
1459
|
+
createdAt: createdAt || Date.now(),
|
|
1460
|
+
updatedAt: updatedAt || Date.now(),
|
|
1461
|
+
confidence: confidence,
|
|
1462
|
+
weight: weight,
|
|
1463
|
+
service: service,
|
|
1464
|
+
data: data,
|
|
1465
|
+
createdBy,
|
|
1466
|
+
metadata: customMetadata
|
|
1457
1467
|
};
|
|
1458
1468
|
items.push(nounWithMetadata);
|
|
1459
1469
|
}
|
|
@@ -1516,11 +1526,11 @@ export class OPFSStorage extends BaseStorage {
|
|
|
1516
1526
|
const hnswVerb = await this.getVerb_internal(id);
|
|
1517
1527
|
if (hnswVerb) {
|
|
1518
1528
|
// Load metadata for filtering and combining
|
|
1529
|
+
// FIX v4.7.4: Don't skip verbs without metadata - metadata is optional in v4.0.0
|
|
1530
|
+
// Core fields (verb, sourceId, targetId) are in HNSWVerb itself
|
|
1519
1531
|
const metadata = await this.getVerbMetadata(id);
|
|
1520
|
-
if (!metadata)
|
|
1521
|
-
continue;
|
|
1522
1532
|
// Apply filters if provided
|
|
1523
|
-
if (options.filter) {
|
|
1533
|
+
if (options.filter && metadata) {
|
|
1524
1534
|
// Filter by verb type
|
|
1525
1535
|
// v4.0.0: verb field is in HNSWVerb structure (NOT in metadata)
|
|
1526
1536
|
if (options.filter.verbType) {
|
|
@@ -1573,7 +1583,9 @@ export class OPFSStorage extends BaseStorage {
|
|
|
1573
1583
|
continue;
|
|
1574
1584
|
}
|
|
1575
1585
|
}
|
|
1576
|
-
// v4.
|
|
1586
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
1587
|
+
const metadataObj = (metadata || {});
|
|
1588
|
+
const { createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
1577
1589
|
const verbWithMetadata = {
|
|
1578
1590
|
id: hnswVerb.id,
|
|
1579
1591
|
vector: [...hnswVerb.vector],
|
|
@@ -1581,7 +1593,14 @@ export class OPFSStorage extends BaseStorage {
|
|
|
1581
1593
|
verb: hnswVerb.verb,
|
|
1582
1594
|
sourceId: hnswVerb.sourceId,
|
|
1583
1595
|
targetId: hnswVerb.targetId,
|
|
1584
|
-
|
|
1596
|
+
createdAt: createdAt || Date.now(),
|
|
1597
|
+
updatedAt: updatedAt || Date.now(),
|
|
1598
|
+
confidence: confidence,
|
|
1599
|
+
weight: weight,
|
|
1600
|
+
service: service,
|
|
1601
|
+
data: data,
|
|
1602
|
+
createdBy,
|
|
1603
|
+
metadata: customMetadata
|
|
1585
1604
|
};
|
|
1586
1605
|
items.push(verbWithMetadata);
|
|
1587
1606
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Based on latest GCS and S3 implementations with R2-specific enhancements
|
|
13
13
|
*/
|
|
14
|
+
import { NounType } from '../../coreTypes.js';
|
|
14
15
|
import { BaseStorage, SYSTEM_DIR, STATISTICS_KEY, getDirectoryPath } from '../baseStorage.js';
|
|
15
16
|
import { BrainyError } from '../../errors/brainyError.js';
|
|
16
17
|
import { CacheManager } from '../cacheManager.js';
|
|
@@ -883,11 +884,10 @@ export class R2Storage extends BaseStorage {
|
|
|
883
884
|
const noun = await this.getNoun_internal(id);
|
|
884
885
|
if (noun) {
|
|
885
886
|
// v4.0.0: Load metadata and combine with noun to create HNSWNounWithMetadata
|
|
887
|
+
// FIX v4.7.4: Don't skip nouns without metadata - metadata is optional in v4.0.0
|
|
886
888
|
const metadata = await this.getNounMetadata(id);
|
|
887
|
-
if (!metadata)
|
|
888
|
-
continue;
|
|
889
889
|
// Apply filters if provided
|
|
890
|
-
if (options.filter) {
|
|
890
|
+
if (options.filter && metadata) {
|
|
891
891
|
// Filter by noun type
|
|
892
892
|
if (options.filter.nounType) {
|
|
893
893
|
const nounTypes = Array.isArray(options.filter.nounType)
|
|
@@ -919,13 +919,23 @@ export class R2Storage extends BaseStorage {
|
|
|
919
919
|
continue;
|
|
920
920
|
}
|
|
921
921
|
}
|
|
922
|
-
// v4.
|
|
922
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
923
|
+
const metadataObj = (metadata || {});
|
|
924
|
+
const { noun: nounType, createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
923
925
|
const nounWithMetadata = {
|
|
924
926
|
id: noun.id,
|
|
925
927
|
vector: [...noun.vector],
|
|
926
928
|
connections: new Map(noun.connections),
|
|
927
929
|
level: noun.level || 0,
|
|
928
|
-
|
|
930
|
+
type: nounType || NounType.Thing,
|
|
931
|
+
createdAt: createdAt || Date.now(),
|
|
932
|
+
updatedAt: updatedAt || Date.now(),
|
|
933
|
+
confidence: confidence,
|
|
934
|
+
weight: weight,
|
|
935
|
+
service: service,
|
|
936
|
+
data: data,
|
|
937
|
+
createdBy,
|
|
938
|
+
metadata: customMetadata
|
|
929
939
|
};
|
|
930
940
|
items.push(nounWithMetadata);
|
|
931
941
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Uses the AWS S3 client to interact with S3-compatible storage services
|
|
4
4
|
* including Amazon S3, Cloudflare R2, and Google Cloud Storage
|
|
5
5
|
*/
|
|
6
|
+
import { NounType } from '../../coreTypes.js';
|
|
6
7
|
import { BaseStorage, INDEX_DIR, SYSTEM_DIR, STATISTICS_KEY, getDirectoryPath } from '../baseStorage.js';
|
|
7
8
|
import { StorageCompatibilityLayer } from '../backwardCompatibility.js';
|
|
8
9
|
import { StorageOperationExecutors } from '../../utils/operationUtils.js';
|
|
@@ -1479,6 +1480,9 @@ export class S3CompatibleStorage extends BaseStorage {
|
|
|
1479
1480
|
const verbsWithMetadata = [];
|
|
1480
1481
|
for (const hnswVerb of result.edges) {
|
|
1481
1482
|
const metadata = await this.getVerbMetadata(hnswVerb.id);
|
|
1483
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
1484
|
+
const metadataObj = (metadata || {});
|
|
1485
|
+
const { createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
1482
1486
|
const verbWithMetadata = {
|
|
1483
1487
|
id: hnswVerb.id,
|
|
1484
1488
|
vector: [...hnswVerb.vector],
|
|
@@ -1486,7 +1490,14 @@ export class S3CompatibleStorage extends BaseStorage {
|
|
|
1486
1490
|
verb: hnswVerb.verb,
|
|
1487
1491
|
sourceId: hnswVerb.sourceId,
|
|
1488
1492
|
targetId: hnswVerb.targetId,
|
|
1489
|
-
|
|
1493
|
+
createdAt: createdAt || Date.now(),
|
|
1494
|
+
updatedAt: updatedAt || Date.now(),
|
|
1495
|
+
confidence: confidence,
|
|
1496
|
+
weight: weight,
|
|
1497
|
+
service: service,
|
|
1498
|
+
data: data,
|
|
1499
|
+
createdBy,
|
|
1500
|
+
metadata: customMetadata
|
|
1490
1501
|
};
|
|
1491
1502
|
verbsWithMetadata.push(verbWithMetadata);
|
|
1492
1503
|
}
|
|
@@ -2867,11 +2878,10 @@ export class S3CompatibleStorage extends BaseStorage {
|
|
|
2867
2878
|
// v4.0.0: Combine nodes with metadata to create HNSWNounWithMetadata[]
|
|
2868
2879
|
const nounsWithMetadata = [];
|
|
2869
2880
|
for (const node of result.nodes) {
|
|
2881
|
+
// FIX v4.7.4: Don't skip nouns without metadata - metadata is optional in v4.0.0
|
|
2870
2882
|
const metadata = await this.getNounMetadata(node.id);
|
|
2871
|
-
if (!metadata)
|
|
2872
|
-
continue;
|
|
2873
2883
|
// Apply filters if provided
|
|
2874
|
-
if (options.filter) {
|
|
2884
|
+
if (options.filter && metadata) {
|
|
2875
2885
|
// Filter by noun type
|
|
2876
2886
|
if (options.filter.nounType) {
|
|
2877
2887
|
const nounTypes = Array.isArray(options.filter.nounType)
|
|
@@ -2900,13 +2910,23 @@ export class S3CompatibleStorage extends BaseStorage {
|
|
|
2900
2910
|
}
|
|
2901
2911
|
}
|
|
2902
2912
|
}
|
|
2903
|
-
//
|
|
2913
|
+
// v4.8.0: Extract standard fields from metadata to top-level
|
|
2914
|
+
const metadataObj = (metadata || {});
|
|
2915
|
+
const { noun: nounType, createdAt, updatedAt, confidence, weight, service, data, createdBy, ...customMetadata } = metadataObj;
|
|
2904
2916
|
const nounWithMetadata = {
|
|
2905
2917
|
id: node.id,
|
|
2906
2918
|
vector: [...node.vector],
|
|
2907
2919
|
connections: new Map(node.connections),
|
|
2908
2920
|
level: node.level || 0,
|
|
2909
|
-
|
|
2921
|
+
type: nounType || NounType.Thing,
|
|
2922
|
+
createdAt: createdAt || Date.now(),
|
|
2923
|
+
updatedAt: updatedAt || Date.now(),
|
|
2924
|
+
confidence: confidence,
|
|
2925
|
+
weight: weight,
|
|
2926
|
+
service: service,
|
|
2927
|
+
data: data,
|
|
2928
|
+
createdBy,
|
|
2929
|
+
metadata: customMetadata
|
|
2910
2930
|
};
|
|
2911
2931
|
nounsWithMetadata.push(nounWithMetadata);
|
|
2912
2932
|
}
|