@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.
@@ -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
- // Combine node with metadata
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
- ...node,
963
- metadata
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
- ...verb,
1003
- metadata: metadata || {}
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
- ...verb,
1027
- metadata: metadata || {}
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
- ...verb,
1051
- metadata: metadata || {}
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.0.0: Create HNSWNounWithMetadata by combining noun with metadata
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
- metadata: metadata
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.0.0: Clean HNSWVerbWithMetadata construction
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
- metadata: metadata
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.0.0: Clean HNSWVerbWithMetadata construction
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
- metadata: metadata
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
- // Combine node with metadata
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
- metadata: metadata
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
- // Combine verb with metadata
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
- metadata: metadata || {}
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
- if (!metadata)
157
- continue; // Skip if no metadata
158
- // v4.0.0: Create HNSWNounWithMetadata with metadata field
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
- metadata: metadata // Include metadata field
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
- if (!metadata)
362
- continue; // Skip if no metadata
363
- // v4.0.0: Create HNSWVerbWithMetadata with metadata field
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
- // Metadata field
373
- metadata: metadata
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.0.0: Create HNSWNounWithMetadata by combining noun with metadata
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
- metadata: metadata
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.0.0: Create HNSWVerbWithMetadata by combining verb with metadata
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
- metadata: metadata
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.0.0: Create HNSWNounWithMetadata by combining noun with metadata
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
- metadata: metadata
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
- metadata: metadata || {}
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
- // Create HNSWNounWithMetadata
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
- metadata: metadata
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
  }