@soulcraft/brainy 0.35.0 → 0.37.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.
Files changed (34) hide show
  1. package/README.md +190 -20
  2. package/dist/coreTypes.d.ts +27 -2
  3. package/dist/hnsw/distributedSearch.d.ts +118 -0
  4. package/dist/hnsw/distributedSearch.d.ts.map +1 -0
  5. package/dist/hnsw/optimizedHNSWIndex.d.ts +97 -0
  6. package/dist/hnsw/optimizedHNSWIndex.d.ts.map +1 -0
  7. package/dist/hnsw/partitionedHNSWIndex.d.ts +101 -0
  8. package/dist/hnsw/partitionedHNSWIndex.d.ts.map +1 -0
  9. package/dist/hnsw/scaledHNSWSystem.d.ts +142 -0
  10. package/dist/hnsw/scaledHNSWSystem.d.ts.map +1 -0
  11. package/dist/index.d.ts +2 -2
  12. package/dist/storage/adapters/baseStorageAdapter.d.ts +2 -0
  13. package/dist/storage/adapters/baseStorageAdapter.d.ts.map +1 -1
  14. package/dist/storage/adapters/batchS3Operations.d.ts +71 -0
  15. package/dist/storage/adapters/batchS3Operations.d.ts.map +1 -0
  16. package/dist/storage/adapters/fileSystemStorage.d.ts +23 -5
  17. package/dist/storage/adapters/fileSystemStorage.d.ts.map +1 -1
  18. package/dist/storage/adapters/memoryStorage.d.ts +22 -4
  19. package/dist/storage/adapters/memoryStorage.d.ts.map +1 -1
  20. package/dist/storage/adapters/opfsStorage.d.ts +27 -9
  21. package/dist/storage/adapters/opfsStorage.d.ts.map +1 -1
  22. package/dist/storage/adapters/s3CompatibleStorage.d.ts +24 -8
  23. package/dist/storage/adapters/s3CompatibleStorage.d.ts.map +1 -1
  24. package/dist/storage/baseStorage.d.ts +30 -4
  25. package/dist/storage/baseStorage.d.ts.map +1 -1
  26. package/dist/storage/enhancedCacheManager.d.ts +141 -0
  27. package/dist/storage/enhancedCacheManager.d.ts.map +1 -0
  28. package/dist/storage/readOnlyOptimizations.d.ts +133 -0
  29. package/dist/storage/readOnlyOptimizations.d.ts.map +1 -0
  30. package/dist/unified.js +635 -215
  31. package/dist/unified.min.js +991 -991
  32. package/dist/utils/autoConfiguration.d.ts +125 -0
  33. package/dist/utils/autoConfiguration.d.ts.map +1 -0
  34. package/package.json +1 -1
package/dist/unified.js CHANGED
@@ -6241,6 +6241,8 @@ class BaseStorageAdapter {
6241
6241
  const NOUNS_DIR = 'nouns';
6242
6242
  const VERBS_DIR = 'verbs';
6243
6243
  const METADATA_DIR = 'metadata';
6244
+ const NOUN_METADATA_DIR = 'noun-metadata';
6245
+ const VERB_METADATA_DIR = 'verb-metadata';
6244
6246
  const INDEX_DIR = 'index';
6245
6247
  const STATISTICS_KEY = 'statistics';
6246
6248
  /**
@@ -6305,14 +6307,84 @@ class BaseStorage extends BaseStorageAdapter {
6305
6307
  */
6306
6308
  async saveVerb(verb) {
6307
6309
  await this.ensureInitialized();
6308
- return this.saveVerb_internal(verb);
6310
+ // Extract the lightweight HNSWVerb data
6311
+ const hnswVerb = {
6312
+ id: verb.id,
6313
+ vector: verb.vector,
6314
+ connections: verb.connections || new Map()
6315
+ };
6316
+ // Extract and save the metadata separately
6317
+ const metadata = {
6318
+ sourceId: verb.sourceId || verb.source,
6319
+ targetId: verb.targetId || verb.target,
6320
+ source: verb.source || verb.sourceId,
6321
+ target: verb.target || verb.targetId,
6322
+ type: verb.type || verb.verb,
6323
+ verb: verb.verb || verb.type,
6324
+ weight: verb.weight,
6325
+ metadata: verb.metadata,
6326
+ data: verb.data,
6327
+ createdAt: verb.createdAt,
6328
+ updatedAt: verb.updatedAt,
6329
+ createdBy: verb.createdBy,
6330
+ embedding: verb.embedding
6331
+ };
6332
+ // Save both the HNSWVerb and metadata
6333
+ await this.saveVerb_internal(hnswVerb);
6334
+ await this.saveVerbMetadata(verb.id, metadata);
6309
6335
  }
6310
6336
  /**
6311
6337
  * Get a verb from storage
6312
6338
  */
6313
6339
  async getVerb(id) {
6314
6340
  await this.ensureInitialized();
6315
- return this.getVerb_internal(id);
6341
+ const hnswVerb = await this.getVerb_internal(id);
6342
+ if (!hnswVerb) {
6343
+ return null;
6344
+ }
6345
+ return this.convertHNSWVerbToGraphVerb(hnswVerb);
6346
+ }
6347
+ /**
6348
+ * Convert HNSWVerb to GraphVerb by combining with metadata
6349
+ */
6350
+ async convertHNSWVerbToGraphVerb(hnswVerb) {
6351
+ try {
6352
+ const metadata = await this.getVerbMetadata(hnswVerb.id);
6353
+ if (!metadata) {
6354
+ return null;
6355
+ }
6356
+ // Create default timestamp if not present
6357
+ const defaultTimestamp = {
6358
+ seconds: Math.floor(Date.now() / 1000),
6359
+ nanoseconds: (Date.now() % 1000) * 1000000
6360
+ };
6361
+ // Create default createdBy if not present
6362
+ const defaultCreatedBy = {
6363
+ augmentation: 'unknown',
6364
+ version: '1.0'
6365
+ };
6366
+ return {
6367
+ id: hnswVerb.id,
6368
+ vector: hnswVerb.vector,
6369
+ sourceId: metadata.sourceId,
6370
+ targetId: metadata.targetId,
6371
+ source: metadata.source,
6372
+ target: metadata.target,
6373
+ verb: metadata.verb,
6374
+ type: metadata.type,
6375
+ weight: metadata.weight || 1.0,
6376
+ metadata: metadata.metadata || {},
6377
+ createdAt: metadata.createdAt || defaultTimestamp,
6378
+ updatedAt: metadata.updatedAt || defaultTimestamp,
6379
+ createdBy: metadata.createdBy || defaultCreatedBy,
6380
+ data: metadata.data,
6381
+ embedding: hnswVerb.vector
6382
+ };
6383
+ }
6384
+ catch (error) {
6385
+ console.error(`Failed to convert HNSWVerb to GraphVerb for ${hnswVerb.id}:`, error);
6386
+ return null;
6387
+ }
6316
6388
  }
6317
6389
  /**
6318
6390
  * Get all verbs from storage
@@ -6322,28 +6394,42 @@ class BaseStorage extends BaseStorageAdapter {
6322
6394
  async getAllVerbs() {
6323
6395
  await this.ensureInitialized();
6324
6396
  console.warn('WARNING: getAllVerbs() is deprecated and will be removed in a future version. Use getVerbs() with pagination instead.');
6325
- return this.getAllVerbs_internal();
6397
+ const hnswVerbs = await this.getAllVerbs_internal();
6398
+ const graphVerbs = [];
6399
+ for (const hnswVerb of hnswVerbs) {
6400
+ const graphVerb = await this.convertHNSWVerbToGraphVerb(hnswVerb);
6401
+ if (graphVerb) {
6402
+ graphVerbs.push(graphVerb);
6403
+ }
6404
+ }
6405
+ return graphVerbs;
6326
6406
  }
6327
6407
  /**
6328
6408
  * Get verbs by source
6329
6409
  */
6330
6410
  async getVerbsBySource(sourceId) {
6331
6411
  await this.ensureInitialized();
6332
- return this.getVerbsBySource_internal(sourceId);
6412
+ // Get all verbs and filter by source
6413
+ const allVerbs = await this.getAllVerbs();
6414
+ return allVerbs.filter(verb => verb.sourceId === sourceId || verb.source === sourceId);
6333
6415
  }
6334
6416
  /**
6335
6417
  * Get verbs by target
6336
6418
  */
6337
6419
  async getVerbsByTarget(targetId) {
6338
6420
  await this.ensureInitialized();
6339
- return this.getVerbsByTarget_internal(targetId);
6421
+ // Get all verbs and filter by target
6422
+ const allVerbs = await this.getAllVerbs();
6423
+ return allVerbs.filter(verb => verb.targetId === targetId || verb.target === targetId);
6340
6424
  }
6341
6425
  /**
6342
6426
  * Get verbs by type
6343
6427
  */
6344
6428
  async getVerbsByType(type) {
6345
6429
  await this.ensureInitialized();
6346
- return this.getVerbsByType_internal(type);
6430
+ // Get all verbs and filter by type
6431
+ const allVerbs = await this.getAllVerbs();
6432
+ return allVerbs.filter(verb => verb.type === type || verb.verb === type);
6347
6433
  }
6348
6434
  /**
6349
6435
  * Get nouns with pagination and filtering
@@ -6640,7 +6726,7 @@ class BaseStorage extends BaseStorageAdapter {
6640
6726
  let allVerbs = [];
6641
6727
  try {
6642
6728
  // Try to get only the verbs we need
6643
- allVerbs = await this.getAllVerbs_internal();
6729
+ allVerbs = await this.getAllVerbs();
6644
6730
  // If we have too many verbs, truncate the array to avoid memory issues
6645
6731
  if (allVerbs.length > maxVerbs) {
6646
6732
  console.warn(`Large number of verbs (${allVerbs.length}), truncating to ${maxVerbs} for filtering`);
@@ -6764,6 +6850,8 @@ class MemoryStorage extends BaseStorage {
6764
6850
  this.nouns = new Map();
6765
6851
  this.verbs = new Map();
6766
6852
  this.metadata = new Map();
6853
+ this.nounMetadata = new Map();
6854
+ this.verbMetadata = new Map();
6767
6855
  this.statistics = null;
6768
6856
  }
6769
6857
  /**
@@ -6941,15 +7029,7 @@ class MemoryStorage extends BaseStorage {
6941
7029
  const verbCopy = {
6942
7030
  id: verb.id,
6943
7031
  vector: [...verb.vector],
6944
- connections: new Map(),
6945
- sourceId: verb.sourceId,
6946
- targetId: verb.targetId,
6947
- source: verb.sourceId || verb.source,
6948
- target: verb.targetId || verb.target,
6949
- verb: verb.type || verb.verb,
6950
- type: verb.type || verb.verb,
6951
- weight: verb.weight,
6952
- metadata: verb.metadata
7032
+ connections: new Map()
6953
7033
  };
6954
7034
  // Copy connections
6955
7035
  for (const [level, connections] of verb.connections.entries()) {
@@ -6968,32 +7048,11 @@ class MemoryStorage extends BaseStorage {
6968
7048
  if (!verb) {
6969
7049
  return null;
6970
7050
  }
6971
- // Create default timestamp if not present
6972
- const defaultTimestamp = {
6973
- seconds: Math.floor(Date.now() / 1000),
6974
- nanoseconds: (Date.now() % 1000) * 1000000
6975
- };
6976
- // Create default createdBy if not present
6977
- const defaultCreatedBy = {
6978
- augmentation: 'unknown',
6979
- version: '1.0'
6980
- };
6981
- // Return a deep copy to avoid reference issues
7051
+ // Return a deep copy of the HNSWVerb
6982
7052
  const verbCopy = {
6983
7053
  id: verb.id,
6984
7054
  vector: [...verb.vector],
6985
- connections: new Map(),
6986
- sourceId: (verb.sourceId || verb.source || ""),
6987
- targetId: (verb.targetId || verb.target || ""),
6988
- source: (verb.sourceId || verb.source || ""),
6989
- target: (verb.targetId || verb.target || ""),
6990
- verb: verb.type || verb.verb,
6991
- type: verb.type || verb.verb, // Ensure type is also set
6992
- weight: verb.weight,
6993
- metadata: verb.metadata,
6994
- createdAt: verb.createdAt || defaultTimestamp,
6995
- updatedAt: verb.updatedAt || defaultTimestamp,
6996
- createdBy: verb.createdBy || defaultCreatedBy
7055
+ connections: new Map()
6997
7056
  };
6998
7057
  // Copy connections
6999
7058
  for (const [level, connections] of verb.connections.entries()) {
@@ -7008,31 +7067,11 @@ class MemoryStorage extends BaseStorage {
7008
7067
  const allVerbs = [];
7009
7068
  // Iterate through all verbs in the verbs map
7010
7069
  for (const [verbId, verb] of this.verbs.entries()) {
7011
- // Create default timestamp if not present
7012
- const defaultTimestamp = {
7013
- seconds: Math.floor(Date.now() / 1000),
7014
- nanoseconds: (Date.now() % 1000) * 1000000
7015
- };
7016
- // Create default createdBy if not present
7017
- const defaultCreatedBy = {
7018
- augmentation: 'unknown',
7019
- version: '1.0'
7020
- };
7021
- // Return a deep copy to avoid reference issues
7070
+ // Create a deep copy of the HNSWVerb
7022
7071
  const verbCopy = {
7023
7072
  id: verb.id,
7024
7073
  vector: [...verb.vector],
7025
- connections: new Map(),
7026
- sourceId: (verb.sourceId || verb.source || ""),
7027
- targetId: (verb.targetId || verb.target || ""),
7028
- source: (verb.sourceId || verb.source || ""),
7029
- target: (verb.targetId || verb.target || ""),
7030
- verb: verb.type || verb.verb,
7031
- weight: verb.weight,
7032
- metadata: verb.metadata,
7033
- createdAt: verb.createdAt || defaultTimestamp,
7034
- updatedAt: verb.updatedAt || defaultTimestamp,
7035
- createdBy: verb.createdBy || defaultCreatedBy
7074
+ connections: new Map()
7036
7075
  };
7037
7076
  // Copy connections
7038
7077
  for (const [level, connections] of verb.connections.entries()) {
@@ -7069,24 +7108,26 @@ class MemoryStorage extends BaseStorage {
7069
7108
  // First, collect all verb IDs that match the filter criteria
7070
7109
  const matchingIds = [];
7071
7110
  // Iterate through all verbs to find matches
7072
- for (const [verbId, verb] of this.verbs.entries()) {
7111
+ for (const [verbId, hnswVerb] of this.verbs.entries()) {
7112
+ // Get the metadata for this verb to do filtering
7113
+ const metadata = this.verbMetadata.get(verbId);
7073
7114
  // Filter by verb type if specified
7074
- if (verbTypes && !verbTypes.includes(verb.type || verb.verb || '')) {
7115
+ if (verbTypes && metadata && !verbTypes.includes(metadata.type || metadata.verb || '')) {
7075
7116
  continue;
7076
7117
  }
7077
7118
  // Filter by source ID if specified
7078
- if (sourceIds && !sourceIds.includes(verb.sourceId || verb.source || '')) {
7119
+ if (sourceIds && metadata && !sourceIds.includes(metadata.sourceId || metadata.source || '')) {
7079
7120
  continue;
7080
7121
  }
7081
7122
  // Filter by target ID if specified
7082
- if (targetIds && !targetIds.includes(verb.targetId || verb.target || '')) {
7123
+ if (targetIds && metadata && !targetIds.includes(metadata.targetId || metadata.target || '')) {
7083
7124
  continue;
7084
7125
  }
7085
7126
  // Filter by metadata fields if specified
7086
- if (filter.metadata && verb.metadata) {
7127
+ if (filter.metadata && metadata && metadata.data) {
7087
7128
  let metadataMatch = true;
7088
7129
  for (const [key, value] of Object.entries(filter.metadata)) {
7089
- if (verb.metadata[key] !== value) {
7130
+ if (metadata.data[key] !== value) {
7090
7131
  metadataMatch = false;
7091
7132
  break;
7092
7133
  }
@@ -7095,8 +7136,8 @@ class MemoryStorage extends BaseStorage {
7095
7136
  continue;
7096
7137
  }
7097
7138
  // Filter by service if specified
7098
- if (services && verb.metadata && verb.metadata.service &&
7099
- !services.includes(verb.metadata.service)) {
7139
+ if (services && metadata && metadata.createdBy && metadata.createdBy.augmentation &&
7140
+ !services.includes(metadata.createdBy.augmentation)) {
7100
7141
  continue;
7101
7142
  }
7102
7143
  // If we got here, the verb matches all filters
@@ -7111,31 +7152,39 @@ class MemoryStorage extends BaseStorage {
7111
7152
  // Fetch the actual verbs for the current page
7112
7153
  const items = [];
7113
7154
  for (const id of paginatedIds) {
7114
- const verb = this.verbs.get(id);
7115
- if (!verb)
7155
+ const hnswVerb = this.verbs.get(id);
7156
+ const metadata = this.verbMetadata.get(id);
7157
+ if (!hnswVerb)
7158
+ continue;
7159
+ if (!metadata) {
7160
+ console.warn(`Verb ${id} found but no metadata - creating minimal GraphVerb`);
7161
+ // Return minimal GraphVerb if metadata is missing
7162
+ items.push({
7163
+ id: hnswVerb.id,
7164
+ vector: hnswVerb.vector,
7165
+ sourceId: '',
7166
+ targetId: ''
7167
+ });
7116
7168
  continue;
7117
- // Create a deep copy to avoid reference issues
7118
- const verbCopy = {
7119
- id: verb.id,
7120
- vector: [...verb.vector],
7121
- connections: new Map(),
7122
- sourceId: verb.sourceId || verb.source || '',
7123
- targetId: verb.targetId || verb.target || '',
7124
- source: verb.sourceId || verb.source || '',
7125
- target: verb.targetId || verb.target || '',
7126
- verb: verb.type || verb.verb,
7127
- type: verb.type || verb.verb,
7128
- weight: verb.weight,
7129
- metadata: verb.metadata ? JSON.parse(JSON.stringify(verb.metadata)) : undefined,
7130
- createdAt: verb.createdAt ? { ...verb.createdAt } : undefined,
7131
- updatedAt: verb.updatedAt ? { ...verb.updatedAt } : undefined,
7132
- createdBy: verb.createdBy ? { ...verb.createdBy } : undefined
7133
- };
7134
- // Copy connections
7135
- for (const [level, connections] of verb.connections.entries()) {
7136
- verbCopy.connections.set(level, new Set(connections));
7137
7169
  }
7138
- items.push(verbCopy);
7170
+ // Create a complete GraphVerb by combining HNSWVerb with metadata
7171
+ const graphVerb = {
7172
+ id: hnswVerb.id,
7173
+ vector: [...hnswVerb.vector],
7174
+ sourceId: metadata.sourceId,
7175
+ targetId: metadata.targetId,
7176
+ source: metadata.source,
7177
+ target: metadata.target,
7178
+ verb: metadata.verb,
7179
+ type: metadata.type,
7180
+ weight: metadata.weight,
7181
+ createdAt: metadata.createdAt,
7182
+ updatedAt: metadata.updatedAt,
7183
+ createdBy: metadata.createdBy,
7184
+ data: metadata.data,
7185
+ metadata: metadata.data // Alias for backward compatibility
7186
+ };
7187
+ items.push(graphVerb);
7139
7188
  }
7140
7189
  return {
7141
7190
  items,
@@ -7203,6 +7252,38 @@ class MemoryStorage extends BaseStorage {
7203
7252
  }
7204
7253
  return JSON.parse(JSON.stringify(metadata));
7205
7254
  }
7255
+ /**
7256
+ * Save noun metadata to storage
7257
+ */
7258
+ async saveNounMetadata(id, metadata) {
7259
+ this.nounMetadata.set(id, JSON.parse(JSON.stringify(metadata)));
7260
+ }
7261
+ /**
7262
+ * Get noun metadata from storage
7263
+ */
7264
+ async getNounMetadata(id) {
7265
+ const metadata = this.nounMetadata.get(id);
7266
+ if (!metadata) {
7267
+ return null;
7268
+ }
7269
+ return JSON.parse(JSON.stringify(metadata));
7270
+ }
7271
+ /**
7272
+ * Save verb metadata to storage
7273
+ */
7274
+ async saveVerbMetadata(id, metadata) {
7275
+ this.verbMetadata.set(id, JSON.parse(JSON.stringify(metadata)));
7276
+ }
7277
+ /**
7278
+ * Get verb metadata from storage
7279
+ */
7280
+ async getVerbMetadata(id) {
7281
+ const metadata = this.verbMetadata.get(id);
7282
+ if (!metadata) {
7283
+ return null;
7284
+ }
7285
+ return JSON.parse(JSON.stringify(metadata));
7286
+ }
7206
7287
  /**
7207
7288
  * Clear all data from storage
7208
7289
  */
@@ -7210,6 +7291,8 @@ class MemoryStorage extends BaseStorage {
7210
7291
  this.nouns.clear();
7211
7292
  this.verbs.clear();
7212
7293
  this.metadata.clear();
7294
+ this.nounMetadata.clear();
7295
+ this.verbMetadata.clear();
7213
7296
  this.statistics = null;
7214
7297
  }
7215
7298
  /**
@@ -7291,6 +7374,8 @@ class OPFSStorage extends BaseStorage {
7291
7374
  this.nounsDir = null;
7292
7375
  this.verbsDir = null;
7293
7376
  this.metadataDir = null;
7377
+ this.nounMetadataDir = null;
7378
+ this.verbMetadataDir = null;
7294
7379
  this.indexDir = null;
7295
7380
  this.isAvailable = false;
7296
7381
  this.isPersistentRequested = false;
@@ -7331,6 +7416,14 @@ class OPFSStorage extends BaseStorage {
7331
7416
  this.metadataDir = await this.rootDir.getDirectoryHandle(METADATA_DIR, {
7332
7417
  create: true
7333
7418
  });
7419
+ // Create or get noun metadata directory
7420
+ this.nounMetadataDir = await this.rootDir.getDirectoryHandle(NOUN_METADATA_DIR, {
7421
+ create: true
7422
+ });
7423
+ // Create or get verb metadata directory
7424
+ this.verbMetadataDir = await this.rootDir.getDirectoryHandle(VERB_METADATA_DIR, {
7425
+ create: true
7426
+ });
7334
7427
  // Create or get index directory
7335
7428
  this.indexDir = await this.rootDir.getDirectoryHandle(INDEX_DIR, {
7336
7429
  create: true
@@ -7620,17 +7713,7 @@ class OPFSStorage extends BaseStorage {
7620
7713
  return {
7621
7714
  id: data.id,
7622
7715
  vector: data.vector,
7623
- connections,
7624
- sourceId: data.sourceId || data.source,
7625
- targetId: data.targetId || data.target,
7626
- source: data.sourceId || data.source,
7627
- target: data.targetId || data.target,
7628
- verb: data.type || data.verb,
7629
- weight: data.weight,
7630
- metadata: data.metadata,
7631
- createdAt: data.createdAt || defaultTimestamp,
7632
- updatedAt: data.updatedAt || defaultTimestamp,
7633
- createdBy: data.createdBy || defaultCreatedBy
7716
+ connections
7634
7717
  };
7635
7718
  }
7636
7719
  catch (error) {
@@ -7677,17 +7760,7 @@ class OPFSStorage extends BaseStorage {
7677
7760
  allEdges.push({
7678
7761
  id: data.id,
7679
7762
  vector: data.vector,
7680
- connections,
7681
- sourceId: data.sourceId || data.source,
7682
- targetId: data.targetId || data.target,
7683
- source: data.sourceId || data.source,
7684
- target: data.targetId || data.target,
7685
- verb: data.type || data.verb,
7686
- weight: data.weight,
7687
- metadata: data.metadata,
7688
- createdAt: data.createdAt || defaultTimestamp,
7689
- updatedAt: data.updatedAt || defaultTimestamp,
7690
- createdBy: data.createdBy || defaultCreatedBy
7763
+ connections
7691
7764
  });
7692
7765
  }
7693
7766
  catch (error) {
@@ -7705,40 +7778,55 @@ class OPFSStorage extends BaseStorage {
7705
7778
  * Get verbs by source (internal implementation)
7706
7779
  */
7707
7780
  async getVerbsBySource_internal(sourceId) {
7708
- return this.getEdgesBySource(sourceId);
7781
+ // This method is deprecated and would require loading metadata for each edge
7782
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
7783
+ console.warn('getVerbsBySource_internal is deprecated and not efficiently supported in new storage pattern');
7784
+ return [];
7709
7785
  }
7710
7786
  /**
7711
7787
  * Get edges by source
7712
7788
  */
7713
7789
  async getEdgesBySource(sourceId) {
7714
- const edges = await this.getAllEdges();
7715
- return edges.filter((edge) => (edge.sourceId || edge.source) === sourceId);
7790
+ // This method is deprecated and would require loading metadata for each edge
7791
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
7792
+ console.warn('getEdgesBySource is deprecated and not efficiently supported in new storage pattern');
7793
+ return [];
7716
7794
  }
7717
7795
  /**
7718
7796
  * Get verbs by target (internal implementation)
7719
7797
  */
7720
7798
  async getVerbsByTarget_internal(targetId) {
7721
- return this.getEdgesByTarget(targetId);
7799
+ // This method is deprecated and would require loading metadata for each edge
7800
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
7801
+ console.warn('getVerbsByTarget_internal is deprecated and not efficiently supported in new storage pattern');
7802
+ return [];
7722
7803
  }
7723
7804
  /**
7724
7805
  * Get edges by target
7725
7806
  */
7726
7807
  async getEdgesByTarget(targetId) {
7727
- const edges = await this.getAllEdges();
7728
- return edges.filter((edge) => (edge.targetId || edge.target) === targetId);
7808
+ // This method is deprecated and would require loading metadata for each edge
7809
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
7810
+ console.warn('getEdgesByTarget is deprecated and not efficiently supported in new storage pattern');
7811
+ return [];
7729
7812
  }
7730
7813
  /**
7731
7814
  * Get verbs by type (internal implementation)
7732
7815
  */
7733
7816
  async getVerbsByType_internal(type) {
7734
- return this.getEdgesByType(type);
7817
+ // This method is deprecated and would require loading metadata for each edge
7818
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
7819
+ console.warn('getVerbsByType_internal is deprecated and not efficiently supported in new storage pattern');
7820
+ return [];
7735
7821
  }
7736
7822
  /**
7737
7823
  * Get edges by type
7738
7824
  */
7739
7825
  async getEdgesByType(type) {
7740
- const edges = await this.getAllEdges();
7741
- return edges.filter((edge) => (edge.type || edge.verb) === type);
7826
+ // This method is deprecated and would require loading metadata for each edge
7827
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
7828
+ console.warn('getEdgesByType is deprecated and not efficiently supported in new storage pattern');
7829
+ return [];
7742
7830
  }
7743
7831
  /**
7744
7832
  * Delete a verb from storage (internal implementation)
@@ -7800,6 +7888,66 @@ class OPFSStorage extends BaseStorage {
7800
7888
  return null;
7801
7889
  }
7802
7890
  }
7891
+ /**
7892
+ * Save verb metadata to storage
7893
+ */
7894
+ async saveVerbMetadata(id, metadata) {
7895
+ await this.ensureInitialized();
7896
+ const fileName = `${id}.json`;
7897
+ const fileHandle = await this.verbMetadataDir.getFileHandle(fileName, { create: true });
7898
+ const writable = await fileHandle.createWritable();
7899
+ await writable.write(JSON.stringify(metadata, null, 2));
7900
+ await writable.close();
7901
+ }
7902
+ /**
7903
+ * Get verb metadata from storage
7904
+ */
7905
+ async getVerbMetadata(id) {
7906
+ await this.ensureInitialized();
7907
+ const fileName = `${id}.json`;
7908
+ try {
7909
+ const fileHandle = await this.verbMetadataDir.getFileHandle(fileName);
7910
+ const file = await safeGetFile(fileHandle);
7911
+ const text = await file.text();
7912
+ return JSON.parse(text);
7913
+ }
7914
+ catch (error) {
7915
+ if (error.name !== 'NotFoundError') {
7916
+ console.error(`Error reading verb metadata ${id}:`, error);
7917
+ }
7918
+ return null;
7919
+ }
7920
+ }
7921
+ /**
7922
+ * Save noun metadata to storage
7923
+ */
7924
+ async saveNounMetadata(id, metadata) {
7925
+ await this.ensureInitialized();
7926
+ const fileName = `${id}.json`;
7927
+ const fileHandle = await this.nounMetadataDir.getFileHandle(fileName, { create: true });
7928
+ const writable = await fileHandle.createWritable();
7929
+ await writable.write(JSON.stringify(metadata, null, 2));
7930
+ await writable.close();
7931
+ }
7932
+ /**
7933
+ * Get noun metadata from storage
7934
+ */
7935
+ async getNounMetadata(id) {
7936
+ await this.ensureInitialized();
7937
+ const fileName = `${id}.json`;
7938
+ try {
7939
+ const fileHandle = await this.nounMetadataDir.getFileHandle(fileName);
7940
+ const file = await safeGetFile(fileHandle);
7941
+ const text = await file.text();
7942
+ return JSON.parse(text);
7943
+ }
7944
+ catch (error) {
7945
+ if (error.name !== 'NotFoundError') {
7946
+ console.error(`Error reading noun metadata ${id}:`, error);
7947
+ }
7948
+ return null;
7949
+ }
7950
+ }
7803
7951
  /**
7804
7952
  * Clear all data from storage
7805
7953
  */
@@ -7825,6 +7973,10 @@ class OPFSStorage extends BaseStorage {
7825
7973
  await removeDirectoryContents(this.verbsDir);
7826
7974
  // Remove all files in the metadata directory
7827
7975
  await removeDirectoryContents(this.metadataDir);
7976
+ // Remove all files in the noun metadata directory
7977
+ await removeDirectoryContents(this.nounMetadataDir);
7978
+ // Remove all files in the verb metadata directory
7979
+ await removeDirectoryContents(this.verbMetadataDir);
7828
7980
  // Remove all files in the index directory
7829
7981
  await removeDirectoryContents(this.indexDir);
7830
7982
  }
@@ -10407,11 +10559,7 @@ class S3CompatibleStorage extends BaseStorage {
10407
10559
  entityType: 'verb',
10408
10560
  entityId: edge.id,
10409
10561
  data: {
10410
- sourceId: edge.sourceId || edge.source,
10411
- targetId: edge.targetId || edge.target,
10412
- type: edge.type || edge.verb,
10413
- vector: edge.vector,
10414
- metadata: edge.metadata
10562
+ vector: edge.vector
10415
10563
  }
10416
10564
  });
10417
10565
  }
@@ -10458,10 +10606,7 @@ class S3CompatibleStorage extends BaseStorage {
10458
10606
  if (!parsedEdge ||
10459
10607
  !parsedEdge.id ||
10460
10608
  !parsedEdge.vector ||
10461
- !parsedEdge.connections ||
10462
- !(parsedEdge.sourceId || parsedEdge.source) ||
10463
- !(parsedEdge.targetId || parsedEdge.target) ||
10464
- !(parsedEdge.type || parsedEdge.verb)) {
10609
+ !parsedEdge.connections) {
10465
10610
  console.error(`Invalid edge data for ${id}:`, parsedEdge);
10466
10611
  return null;
10467
10612
  }
@@ -10470,31 +10615,10 @@ class S3CompatibleStorage extends BaseStorage {
10470
10615
  for (const [level, nodeIds] of Object.entries(parsedEdge.connections)) {
10471
10616
  connections.set(Number(level), new Set(nodeIds));
10472
10617
  }
10473
- // Create default timestamp if not present
10474
- const defaultTimestamp = {
10475
- seconds: Math.floor(Date.now() / 1000),
10476
- nanoseconds: (Date.now() % 1000) * 1000000
10477
- };
10478
- // Create default createdBy if not present
10479
- const defaultCreatedBy = {
10480
- augmentation: 'unknown',
10481
- version: '1.0'
10482
- };
10483
10618
  const edge = {
10484
10619
  id: parsedEdge.id,
10485
10620
  vector: parsedEdge.vector,
10486
- connections,
10487
- sourceId: parsedEdge.sourceId || parsedEdge.source,
10488
- targetId: parsedEdge.targetId || parsedEdge.target,
10489
- source: parsedEdge.sourceId || parsedEdge.source,
10490
- target: parsedEdge.targetId || parsedEdge.target,
10491
- verb: parsedEdge.type || parsedEdge.verb,
10492
- type: parsedEdge.type || parsedEdge.verb,
10493
- weight: parsedEdge.weight || 1.0, // Default weight if not provided
10494
- metadata: parsedEdge.metadata || {},
10495
- createdAt: parsedEdge.createdAt || defaultTimestamp,
10496
- updatedAt: parsedEdge.updatedAt || defaultTimestamp,
10497
- createdBy: parsedEdge.createdBy || defaultCreatedBy
10621
+ connections
10498
10622
  };
10499
10623
  console.log(`Successfully retrieved edge ${id}:`, edge);
10500
10624
  return edge;
@@ -10651,23 +10775,10 @@ class S3CompatibleStorage extends BaseStorage {
10651
10775
  * @returns True if the edge matches the filter, false otherwise
10652
10776
  */
10653
10777
  filterEdge(edge, filter) {
10654
- // If no filter, include all edges
10655
- if (!filter.sourceId && !filter.targetId && !filter.type) {
10656
- return true;
10657
- }
10658
- // Filter by source ID
10659
- if (filter.sourceId && edge.sourceId !== filter.sourceId) {
10660
- return false;
10661
- }
10662
- // Filter by target ID
10663
- if (filter.targetId && edge.targetId !== filter.targetId) {
10664
- return false;
10665
- }
10666
- // Filter by type
10667
- if (filter.type && edge.type !== filter.type) {
10668
- return false;
10669
- }
10670
- return true;
10778
+ // HNSWVerb filtering is not supported since metadata is stored separately
10779
+ // This method is deprecated and should not be used with the new storage pattern
10780
+ console.warn('Edge filtering is deprecated and not supported with the new storage pattern');
10781
+ return true; // Return all edges since filtering requires metadata
10671
10782
  }
10672
10783
  /**
10673
10784
  * Get verbs with pagination
@@ -10705,9 +10816,16 @@ class S3CompatibleStorage extends BaseStorage {
10705
10816
  useCache: true,
10706
10817
  filter: edgeFilter
10707
10818
  });
10708
- // Convert edges to verbs (they're the same in this implementation)
10819
+ // Convert HNSWVerbs to GraphVerbs by combining with metadata
10820
+ const graphVerbs = [];
10821
+ for (const hnswVerb of result.edges) {
10822
+ const graphVerb = await this.convertHNSWVerbToGraphVerb(hnswVerb);
10823
+ if (graphVerb) {
10824
+ graphVerbs.push(graphVerb);
10825
+ }
10826
+ }
10709
10827
  return {
10710
- items: result.edges,
10828
+ items: graphVerbs,
10711
10829
  hasMore: result.hasMore,
10712
10830
  nextCursor: result.nextCursor
10713
10831
  };
@@ -10722,8 +10840,10 @@ class S3CompatibleStorage extends BaseStorage {
10722
10840
  * Get edges by source
10723
10841
  */
10724
10842
  async getEdgesBySource(sourceId) {
10725
- const edges = await this.getAllEdges();
10726
- return edges.filter((edge) => (edge.sourceId || edge.source) === sourceId);
10843
+ // This method is deprecated and would require loading metadata for each edge
10844
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
10845
+ console.warn('getEdgesBySource is deprecated and not efficiently supported in new storage pattern');
10846
+ return [];
10727
10847
  }
10728
10848
  /**
10729
10849
  * Get verbs by target (internal implementation)
@@ -10735,8 +10855,10 @@ class S3CompatibleStorage extends BaseStorage {
10735
10855
  * Get edges by target
10736
10856
  */
10737
10857
  async getEdgesByTarget(targetId) {
10738
- const edges = await this.getAllEdges();
10739
- return edges.filter((edge) => (edge.targetId || edge.target) === targetId);
10858
+ // This method is deprecated and would require loading metadata for each edge
10859
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
10860
+ console.warn('getEdgesByTarget is deprecated and not efficiently supported in new storage pattern');
10861
+ return [];
10740
10862
  }
10741
10863
  /**
10742
10864
  * Get verbs by type (internal implementation)
@@ -10748,8 +10870,10 @@ class S3CompatibleStorage extends BaseStorage {
10748
10870
  * Get edges by type
10749
10871
  */
10750
10872
  async getEdgesByType(type) {
10751
- const edges = await this.getAllEdges();
10752
- return edges.filter((edge) => (edge.type || edge.verb) === type);
10873
+ // This method is deprecated and would require loading metadata for each edge
10874
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
10875
+ console.warn('getEdgesByType is deprecated and not efficiently supported in new storage pattern');
10876
+ return [];
10753
10877
  }
10754
10878
  /**
10755
10879
  * Delete a verb from storage (internal implementation)
@@ -10836,6 +10960,158 @@ class S3CompatibleStorage extends BaseStorage {
10836
10960
  throw new Error(`Failed to save metadata for ${id}: ${error}`);
10837
10961
  }
10838
10962
  }
10963
+ /**
10964
+ * Save verb metadata to storage
10965
+ */
10966
+ async saveVerbMetadata(id, metadata) {
10967
+ await this.ensureInitialized();
10968
+ try {
10969
+ console.log(`Saving verb metadata for ${id} to bucket ${this.bucketName}`);
10970
+ // Import the PutObjectCommand only when needed
10971
+ const { PutObjectCommand } = await import('@aws-sdk/client-s3');
10972
+ const key = `verb-metadata/${id}.json`;
10973
+ const body = JSON.stringify(metadata, null, 2);
10974
+ console.log(`Saving verb metadata to key: ${key}`);
10975
+ console.log(`Verb Metadata: ${body}`);
10976
+ // Save the verb metadata to S3-compatible storage
10977
+ const result = await this.s3Client.send(new PutObjectCommand({
10978
+ Bucket: this.bucketName,
10979
+ Key: key,
10980
+ Body: body,
10981
+ ContentType: 'application/json'
10982
+ }));
10983
+ console.log(`Verb metadata for ${id} saved successfully:`, result);
10984
+ }
10985
+ catch (error) {
10986
+ console.error(`Failed to save verb metadata for ${id}:`, error);
10987
+ throw new Error(`Failed to save verb metadata for ${id}: ${error}`);
10988
+ }
10989
+ }
10990
+ /**
10991
+ * Get verb metadata from storage
10992
+ */
10993
+ async getVerbMetadata(id) {
10994
+ await this.ensureInitialized();
10995
+ try {
10996
+ // Import the GetObjectCommand only when needed
10997
+ const { GetObjectCommand } = await import('@aws-sdk/client-s3');
10998
+ console.log(`Getting verb metadata for ${id} from bucket ${this.bucketName}`);
10999
+ const key = `verb-metadata/${id}.json`;
11000
+ console.log(`Looking for verb metadata at key: ${key}`);
11001
+ // Try to get the verb metadata
11002
+ const response = await this.s3Client.send(new GetObjectCommand({
11003
+ Bucket: this.bucketName,
11004
+ Key: key
11005
+ }));
11006
+ // Check if response is null or undefined
11007
+ if (!response || !response.Body) {
11008
+ console.log(`No verb metadata found for ${id}`);
11009
+ return null;
11010
+ }
11011
+ // Convert the response body to a string
11012
+ const bodyContents = await response.Body.transformToString();
11013
+ console.log(`Retrieved verb metadata body: ${bodyContents}`);
11014
+ // Parse the JSON string
11015
+ try {
11016
+ const parsedMetadata = JSON.parse(bodyContents);
11017
+ console.log(`Successfully retrieved verb metadata for ${id}:`, parsedMetadata);
11018
+ return parsedMetadata;
11019
+ }
11020
+ catch (parseError) {
11021
+ console.error(`Failed to parse verb metadata for ${id}:`, parseError);
11022
+ return null;
11023
+ }
11024
+ }
11025
+ catch (error) {
11026
+ // Check if this is a "NoSuchKey" error (object doesn't exist)
11027
+ if (error.name === 'NoSuchKey' ||
11028
+ (error.message &&
11029
+ (error.message.includes('NoSuchKey') ||
11030
+ error.message.includes('not found') ||
11031
+ error.message.includes('does not exist')))) {
11032
+ console.log(`Verb metadata not found for ${id}`);
11033
+ return null;
11034
+ }
11035
+ // For other types of errors, convert to BrainyError for better classification
11036
+ throw BrainyError.fromError(error, `getVerbMetadata(${id})`);
11037
+ }
11038
+ }
11039
+ /**
11040
+ * Save noun metadata to storage
11041
+ */
11042
+ async saveNounMetadata(id, metadata) {
11043
+ await this.ensureInitialized();
11044
+ try {
11045
+ console.log(`Saving noun metadata for ${id} to bucket ${this.bucketName}`);
11046
+ // Import the PutObjectCommand only when needed
11047
+ const { PutObjectCommand } = await import('@aws-sdk/client-s3');
11048
+ const key = `noun-metadata/${id}.json`;
11049
+ const body = JSON.stringify(metadata, null, 2);
11050
+ console.log(`Saving noun metadata to key: ${key}`);
11051
+ console.log(`Noun Metadata: ${body}`);
11052
+ // Save the noun metadata to S3-compatible storage
11053
+ const result = await this.s3Client.send(new PutObjectCommand({
11054
+ Bucket: this.bucketName,
11055
+ Key: key,
11056
+ Body: body,
11057
+ ContentType: 'application/json'
11058
+ }));
11059
+ console.log(`Noun metadata for ${id} saved successfully:`, result);
11060
+ }
11061
+ catch (error) {
11062
+ console.error(`Failed to save noun metadata for ${id}:`, error);
11063
+ throw new Error(`Failed to save noun metadata for ${id}: ${error}`);
11064
+ }
11065
+ }
11066
+ /**
11067
+ * Get noun metadata from storage
11068
+ */
11069
+ async getNounMetadata(id) {
11070
+ await this.ensureInitialized();
11071
+ try {
11072
+ // Import the GetObjectCommand only when needed
11073
+ const { GetObjectCommand } = await import('@aws-sdk/client-s3');
11074
+ console.log(`Getting noun metadata for ${id} from bucket ${this.bucketName}`);
11075
+ const key = `noun-metadata/${id}.json`;
11076
+ console.log(`Looking for noun metadata at key: ${key}`);
11077
+ // Try to get the noun metadata
11078
+ const response = await this.s3Client.send(new GetObjectCommand({
11079
+ Bucket: this.bucketName,
11080
+ Key: key
11081
+ }));
11082
+ // Check if response is null or undefined
11083
+ if (!response || !response.Body) {
11084
+ console.log(`No noun metadata found for ${id}`);
11085
+ return null;
11086
+ }
11087
+ // Convert the response body to a string
11088
+ const bodyContents = await response.Body.transformToString();
11089
+ console.log(`Retrieved noun metadata body: ${bodyContents}`);
11090
+ // Parse the JSON string
11091
+ try {
11092
+ const parsedMetadata = JSON.parse(bodyContents);
11093
+ console.log(`Successfully retrieved noun metadata for ${id}:`, parsedMetadata);
11094
+ return parsedMetadata;
11095
+ }
11096
+ catch (parseError) {
11097
+ console.error(`Failed to parse noun metadata for ${id}:`, parseError);
11098
+ return null;
11099
+ }
11100
+ }
11101
+ catch (error) {
11102
+ // Check if this is a "NoSuchKey" error (object doesn't exist)
11103
+ if (error.name === 'NoSuchKey' ||
11104
+ (error.message &&
11105
+ (error.message.includes('NoSuchKey') ||
11106
+ error.message.includes('not found') ||
11107
+ error.message.includes('does not exist')))) {
11108
+ console.log(`Noun metadata not found for ${id}`);
11109
+ return null;
11110
+ }
11111
+ // For other types of errors, convert to BrainyError for better classification
11112
+ throw BrainyError.fromError(error, `getNounMetadata(${id})`);
11113
+ }
11114
+ }
10839
11115
  /**
10840
11116
  * Get metadata from storage
10841
11117
  */
@@ -11733,6 +12009,8 @@ class FileSystemStorage extends BaseStorage {
11733
12009
  this.nounsDir = path.join(this.rootDir, NOUNS_DIR);
11734
12010
  this.verbsDir = path.join(this.rootDir, VERBS_DIR);
11735
12011
  this.metadataDir = path.join(this.rootDir, METADATA_DIR);
12012
+ this.nounMetadataDir = path.join(this.rootDir, NOUN_METADATA_DIR);
12013
+ this.verbMetadataDir = path.join(this.rootDir, VERB_METADATA_DIR);
11736
12014
  this.indexDir = path.join(this.rootDir, INDEX_DIR);
11737
12015
  this.lockDir = path.join(this.rootDir, 'locks');
11738
12016
  // Create the root directory if it doesn't exist
@@ -11743,6 +12021,10 @@ class FileSystemStorage extends BaseStorage {
11743
12021
  await this.ensureDirectoryExists(this.verbsDir);
11744
12022
  // Create the metadata directory if it doesn't exist
11745
12023
  await this.ensureDirectoryExists(this.metadataDir);
12024
+ // Create the noun metadata directory if it doesn't exist
12025
+ await this.ensureDirectoryExists(this.nounMetadataDir);
12026
+ // Create the verb metadata directory if it doesn't exist
12027
+ await this.ensureDirectoryExists(this.verbMetadataDir);
11746
12028
  // Create the index directory if it doesn't exist
11747
12029
  await this.ensureDirectoryExists(this.indexDir);
11748
12030
  // Create the locks directory if it doesn't exist
@@ -11927,12 +12209,7 @@ class FileSystemStorage extends BaseStorage {
11927
12209
  return {
11928
12210
  id: parsedEdge.id,
11929
12211
  vector: parsedEdge.vector,
11930
- connections,
11931
- sourceId: parsedEdge.sourceId,
11932
- targetId: parsedEdge.targetId,
11933
- type: parsedEdge.type,
11934
- weight: parsedEdge.weight,
11935
- metadata: parsedEdge.metadata
12212
+ connections
11936
12213
  };
11937
12214
  }
11938
12215
  catch (error) {
@@ -11963,12 +12240,7 @@ class FileSystemStorage extends BaseStorage {
11963
12240
  allEdges.push({
11964
12241
  id: parsedEdge.id,
11965
12242
  vector: parsedEdge.vector,
11966
- connections,
11967
- sourceId: parsedEdge.sourceId,
11968
- targetId: parsedEdge.targetId,
11969
- type: parsedEdge.type,
11970
- weight: parsedEdge.weight,
11971
- metadata: parsedEdge.metadata
12243
+ connections
11972
12244
  });
11973
12245
  }
11974
12246
  }
@@ -11984,22 +12256,28 @@ class FileSystemStorage extends BaseStorage {
11984
12256
  * Get edges by source
11985
12257
  */
11986
12258
  async getEdgesBySource(sourceId) {
11987
- const edges = await this.getAllEdges();
11988
- return edges.filter((edge) => edge.sourceId === sourceId);
12259
+ // This method is deprecated and would require loading metadata for each edge
12260
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
12261
+ console.warn('getEdgesBySource is deprecated and not efficiently supported in new storage pattern');
12262
+ return [];
11989
12263
  }
11990
12264
  /**
11991
12265
  * Get edges by target
11992
12266
  */
11993
12267
  async getEdgesByTarget(targetId) {
11994
- const edges = await this.getAllEdges();
11995
- return edges.filter((edge) => edge.targetId === targetId);
12268
+ // This method is deprecated and would require loading metadata for each edge
12269
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
12270
+ console.warn('getEdgesByTarget is deprecated and not efficiently supported in new storage pattern');
12271
+ return [];
11996
12272
  }
11997
12273
  /**
11998
12274
  * Get edges by type
11999
12275
  */
12000
12276
  async getEdgesByType(type) {
12001
- const edges = await this.getAllEdges();
12002
- return edges.filter((edge) => edge.type === type);
12277
+ // This method is deprecated and would require loading metadata for each edge
12278
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
12279
+ console.warn('getEdgesByType is deprecated and not efficiently supported in new storage pattern');
12280
+ return [];
12003
12281
  }
12004
12282
  /**
12005
12283
  * Delete an edge from storage
@@ -12042,6 +12320,56 @@ class FileSystemStorage extends BaseStorage {
12042
12320
  return null;
12043
12321
  }
12044
12322
  }
12323
+ /**
12324
+ * Save noun metadata to storage
12325
+ */
12326
+ async saveNounMetadata(id, metadata) {
12327
+ await this.ensureInitialized();
12328
+ const filePath = path.join(this.nounMetadataDir, `${id}.json`);
12329
+ await fs.promises.writeFile(filePath, JSON.stringify(metadata, null, 2));
12330
+ }
12331
+ /**
12332
+ * Get noun metadata from storage
12333
+ */
12334
+ async getNounMetadata(id) {
12335
+ await this.ensureInitialized();
12336
+ const filePath = path.join(this.nounMetadataDir, `${id}.json`);
12337
+ try {
12338
+ const data = await fs.promises.readFile(filePath, 'utf-8');
12339
+ return JSON.parse(data);
12340
+ }
12341
+ catch (error) {
12342
+ if (error.code !== 'ENOENT') {
12343
+ console.error(`Error reading noun metadata ${id}:`, error);
12344
+ }
12345
+ return null;
12346
+ }
12347
+ }
12348
+ /**
12349
+ * Save verb metadata to storage
12350
+ */
12351
+ async saveVerbMetadata(id, metadata) {
12352
+ await this.ensureInitialized();
12353
+ const filePath = path.join(this.verbMetadataDir, `${id}.json`);
12354
+ await fs.promises.writeFile(filePath, JSON.stringify(metadata, null, 2));
12355
+ }
12356
+ /**
12357
+ * Get verb metadata from storage
12358
+ */
12359
+ async getVerbMetadata(id) {
12360
+ await this.ensureInitialized();
12361
+ const filePath = path.join(this.verbMetadataDir, `${id}.json`);
12362
+ try {
12363
+ const data = await fs.promises.readFile(filePath, 'utf-8');
12364
+ return JSON.parse(data);
12365
+ }
12366
+ catch (error) {
12367
+ if (error.code !== 'ENOENT') {
12368
+ console.error(`Error reading verb metadata ${id}:`, error);
12369
+ }
12370
+ return null;
12371
+ }
12372
+ }
12045
12373
  /**
12046
12374
  * Clear all data from storage
12047
12375
  */
@@ -12081,6 +12409,10 @@ class FileSystemStorage extends BaseStorage {
12081
12409
  await removeDirectoryContents(this.verbsDir);
12082
12410
  // Remove all files in the metadata directory
12083
12411
  await removeDirectoryContents(this.metadataDir);
12412
+ // Remove all files in the noun metadata directory
12413
+ await removeDirectoryContents(this.nounMetadataDir);
12414
+ // Remove all files in the verb metadata directory
12415
+ await removeDirectoryContents(this.verbMetadataDir);
12084
12416
  // Remove all files in the index directory
12085
12417
  await removeDirectoryContents(this.indexDir);
12086
12418
  }
@@ -12246,19 +12578,28 @@ class FileSystemStorage extends BaseStorage {
12246
12578
  * Get verbs by source
12247
12579
  */
12248
12580
  async getVerbsBySource_internal(sourceId) {
12249
- return this.getEdgesBySource(sourceId);
12581
+ // This method is deprecated and would require loading metadata for each edge
12582
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
12583
+ console.warn('getVerbsBySource_internal is deprecated and not efficiently supported in new storage pattern');
12584
+ return [];
12250
12585
  }
12251
12586
  /**
12252
12587
  * Get verbs by target
12253
12588
  */
12254
12589
  async getVerbsByTarget_internal(targetId) {
12255
- return this.getEdgesByTarget(targetId);
12590
+ // This method is deprecated and would require loading metadata for each edge
12591
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
12592
+ console.warn('getVerbsByTarget_internal is deprecated and not efficiently supported in new storage pattern');
12593
+ return [];
12256
12594
  }
12257
12595
  /**
12258
12596
  * Get verbs by type
12259
12597
  */
12260
12598
  async getVerbsByType_internal(type) {
12261
- return this.getEdgesByType(type);
12599
+ // This method is deprecated and would require loading metadata for each edge
12600
+ // For now, return empty array since this is not efficiently implementable with new storage pattern
12601
+ console.warn('getVerbsByType_internal is deprecated and not efficiently supported in new storage pattern');
12602
+ return [];
12262
12603
  }
12263
12604
  /**
12264
12605
  * Delete a verb from storage
@@ -17053,11 +17394,14 @@ class BrainyData {
17053
17394
  seconds: Math.floor(now.getTime() / 1000),
17054
17395
  nanoseconds: (now.getTime() % 1000) * 1000000
17055
17396
  };
17056
- // Create verb
17057
- const verb = {
17397
+ // Create lightweight verb for HNSW index storage
17398
+ const hnswVerb = {
17058
17399
  id,
17059
17400
  vector: verbVector,
17060
- connections: new Map(),
17401
+ connections: new Map()
17402
+ };
17403
+ // Create complete verb metadata separately
17404
+ const verbMetadata = {
17061
17405
  sourceId: sourceId,
17062
17406
  targetId: targetId,
17063
17407
  source: sourceId,
@@ -17065,13 +17409,13 @@ class BrainyData {
17065
17409
  verb: verbType,
17066
17410
  type: verbType, // Set the type property to match the verb type
17067
17411
  weight: options.weight,
17068
- metadata: options.metadata,
17069
17412
  createdAt: timestamp,
17070
17413
  updatedAt: timestamp,
17071
17414
  createdBy: {
17072
17415
  augmentation: service,
17073
17416
  version: '1.0' // TODO: Get actual version from augmentation
17074
- }
17417
+ },
17418
+ data: options.metadata // Store the original metadata in the data field
17075
17419
  };
17076
17420
  // Add to index
17077
17421
  await this.index.addItem({ id, vector: verbVector });
@@ -17081,9 +17425,28 @@ class BrainyData {
17081
17425
  throw new Error(`Failed to retrieve newly created verb noun with ID ${id}`);
17082
17426
  }
17083
17427
  // Update verb connections from index
17084
- verb.connections = indexNoun.connections;
17085
- // Save verb to storage
17086
- await this.storage.saveVerb(verb);
17428
+ hnswVerb.connections = indexNoun.connections;
17429
+ // Combine HNSWVerb and metadata into a GraphVerb for storage
17430
+ const fullVerb = {
17431
+ id: hnswVerb.id,
17432
+ vector: hnswVerb.vector,
17433
+ connections: hnswVerb.connections,
17434
+ sourceId: verbMetadata.sourceId,
17435
+ targetId: verbMetadata.targetId,
17436
+ source: verbMetadata.source,
17437
+ target: verbMetadata.target,
17438
+ verb: verbMetadata.verb,
17439
+ type: verbMetadata.type,
17440
+ weight: verbMetadata.weight,
17441
+ createdAt: verbMetadata.createdAt,
17442
+ updatedAt: verbMetadata.updatedAt,
17443
+ createdBy: verbMetadata.createdBy,
17444
+ metadata: verbMetadata.data,
17445
+ data: verbMetadata.data,
17446
+ embedding: hnswVerb.vector
17447
+ };
17448
+ // Save the complete verb (BaseStorage will handle the separation)
17449
+ await this.storage.saveVerb(fullVerb);
17087
17450
  // Track verb statistics
17088
17451
  const serviceForStats = this.getServiceName(options);
17089
17452
  await this.storage.incrementStatistic('verb', serviceForStats);
@@ -17102,7 +17465,41 @@ class BrainyData {
17102
17465
  async getVerb(id) {
17103
17466
  await this.ensureInitialized();
17104
17467
  try {
17105
- return await this.storage.getVerb(id);
17468
+ // Get the lightweight verb from storage
17469
+ const hnswVerb = await this.storage.getVerb(id);
17470
+ if (!hnswVerb) {
17471
+ return null;
17472
+ }
17473
+ // Get the verb metadata
17474
+ const metadata = await this.storage.getVerbMetadata(id);
17475
+ if (!metadata) {
17476
+ console.warn(`Verb ${id} found but no metadata - creating minimal GraphVerb`);
17477
+ // Return minimal GraphVerb if metadata is missing
17478
+ return {
17479
+ id: hnswVerb.id,
17480
+ vector: hnswVerb.vector,
17481
+ sourceId: '',
17482
+ targetId: ''
17483
+ };
17484
+ }
17485
+ // Combine into a complete GraphVerb
17486
+ const graphVerb = {
17487
+ id: hnswVerb.id,
17488
+ vector: hnswVerb.vector,
17489
+ sourceId: metadata.sourceId,
17490
+ targetId: metadata.targetId,
17491
+ source: metadata.source,
17492
+ target: metadata.target,
17493
+ verb: metadata.verb,
17494
+ type: metadata.type,
17495
+ weight: metadata.weight,
17496
+ createdAt: metadata.createdAt,
17497
+ updatedAt: metadata.updatedAt,
17498
+ createdBy: metadata.createdBy,
17499
+ data: metadata.data,
17500
+ metadata: metadata.data // Alias for backward compatibility
17501
+ };
17502
+ return graphVerb;
17106
17503
  }
17107
17504
  catch (error) {
17108
17505
  console.error(`Failed to get verb ${id}:`, error);
@@ -17116,13 +17513,36 @@ class BrainyData {
17116
17513
  async getAllVerbs() {
17117
17514
  await this.ensureInitialized();
17118
17515
  try {
17119
- // Use getVerbs with no pagination to get all verbs
17120
- const result = await this.getVerbs({
17121
- pagination: {
17122
- limit: Number.MAX_SAFE_INTEGER // Request all verbs
17516
+ // Get all lightweight verbs from storage
17517
+ const hnswVerbs = await this.storage.getAllVerbs();
17518
+ // Convert each HNSWVerb to GraphVerb by loading metadata
17519
+ const graphVerbs = [];
17520
+ for (const hnswVerb of hnswVerbs) {
17521
+ const metadata = await this.storage.getVerbMetadata(hnswVerb.id);
17522
+ if (metadata) {
17523
+ const graphVerb = {
17524
+ id: hnswVerb.id,
17525
+ vector: hnswVerb.vector,
17526
+ sourceId: metadata.sourceId,
17527
+ targetId: metadata.targetId,
17528
+ source: metadata.source,
17529
+ target: metadata.target,
17530
+ verb: metadata.verb,
17531
+ type: metadata.type,
17532
+ weight: metadata.weight,
17533
+ createdAt: metadata.createdAt,
17534
+ updatedAt: metadata.updatedAt,
17535
+ createdBy: metadata.createdBy,
17536
+ data: metadata.data,
17537
+ metadata: metadata.data // Alias for backward compatibility
17538
+ };
17539
+ graphVerbs.push(graphVerb);
17123
17540
  }
17124
- });
17125
- return result.items;
17541
+ else {
17542
+ console.warn(`Verb ${hnswVerb.id} found but no metadata - skipping`);
17543
+ }
17544
+ }
17545
+ return graphVerbs;
17126
17546
  }
17127
17547
  catch (error) {
17128
17548
  console.error('Failed to get all verbs:', error);