@soulcraft/brainy 0.17.0 → 0.19.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/README.md CHANGED
@@ -488,6 +488,32 @@ const backupData = await db.backup()
488
488
  const restoreResult = await db.restore(backupData, {clearExisting: true})
489
489
  ```
490
490
 
491
+ ### Database Statistics
492
+
493
+ Brainy provides a way to get statistics about the current state of the database:
494
+
495
+ ```typescript
496
+ import { BrainyData, getStatistics } from '@soulcraft/brainy'
497
+
498
+ // Create and initialize the database
499
+ const db = new BrainyData()
500
+ await db.init()
501
+
502
+ // Get statistics using the standalone function
503
+ const stats = await getStatistics(db)
504
+ console.log(stats)
505
+ // Output: { nounCount: 0, verbCount: 0, metadataCount: 0, hnswIndexSize: 0 }
506
+
507
+ // Or using the instance method
508
+ const instanceStats = await db.getStatistics()
509
+ ```
510
+
511
+ The statistics include:
512
+ - `nounCount`: Number of nouns (entities) in the database
513
+ - `verbCount`: Number of verbs (relationships) in the database
514
+ - `metadataCount`: Number of metadata entries
515
+ - `hnswIndexSize`: Size of the HNSW index
516
+
491
517
  ### Working with Nouns (Entities)
492
518
 
493
519
  ```typescript
package/dist/brainy.js CHANGED
@@ -4177,6 +4177,30 @@ var embedding = /*#__PURE__*/Object.freeze({
4177
4177
  getDefaultEmbeddingFunction: getDefaultEmbeddingFunction
4178
4178
  });
4179
4179
 
4180
+ /**
4181
+ * Utility functions for retrieving statistics from Brainy
4182
+ */
4183
+ /**
4184
+ * Get statistics about the current state of a BrainyData instance
4185
+ * This function provides access to statistics at the root level of the library
4186
+ *
4187
+ * @param instance A BrainyData instance to get statistics from
4188
+ * @returns Object containing counts of nouns, verbs, metadata entries, and HNSW index size
4189
+ * @throws Error if the instance is not provided or if statistics retrieval fails
4190
+ */
4191
+ async function getStatistics(instance) {
4192
+ if (!instance) {
4193
+ throw new Error('BrainyData instance must be provided to getStatistics');
4194
+ }
4195
+ try {
4196
+ return await instance.getStatistics();
4197
+ }
4198
+ catch (error) {
4199
+ console.error('Failed to get statistics:', error);
4200
+ throw new Error(`Failed to get statistics: ${error}`);
4201
+ }
4202
+ }
4203
+
4180
4204
  /**
4181
4205
  * HNSW (Hierarchical Navigable Small World) Index implementation
4182
4206
  * Based on the paper: "Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs"
@@ -10180,9 +10204,32 @@ class BrainyData {
10180
10204
  metadata: metadata
10181
10205
  });
10182
10206
  }
10207
+ /**
10208
+ * Create a connection between two entities
10209
+ * This is an alias for relate() for backward compatibility
10210
+ */
10211
+ async connect(sourceId, targetId, relationType, metadata) {
10212
+ return this.relate(sourceId, targetId, relationType, metadata);
10213
+ }
10183
10214
  /**
10184
10215
  * Add a verb between two nouns
10185
10216
  * If metadata is provided and vector is not, the metadata will be vectorized using the embedding function
10217
+ *
10218
+ * @param sourceId ID of the source noun
10219
+ * @param targetId ID of the target noun
10220
+ * @param vector Optional vector for the verb
10221
+ * @param options Additional options:
10222
+ * - type: Type of the verb
10223
+ * - weight: Weight of the verb
10224
+ * - metadata: Metadata for the verb
10225
+ * - forceEmbed: Force using the embedding function for metadata even if vector is provided
10226
+ * - id: Optional ID to use instead of generating a new one
10227
+ * - autoCreateMissingNouns: Automatically create missing nouns if they don't exist
10228
+ * - missingNounMetadata: Metadata to use when auto-creating missing nouns
10229
+ *
10230
+ * @returns The ID of the added verb
10231
+ *
10232
+ * @throws Error if source or target nouns don't exist and autoCreateMissingNouns is false or auto-creation fails
10186
10233
  */
10187
10234
  async addVerb(sourceId, targetId, vector, options = {}) {
10188
10235
  await this.ensureInitialized();
@@ -10190,8 +10237,51 @@ class BrainyData {
10190
10237
  this.checkReadOnly();
10191
10238
  try {
10192
10239
  // Check if source and target nouns exist
10193
- const sourceNoun = this.index.getNouns().get(sourceId);
10194
- const targetNoun = this.index.getNouns().get(targetId);
10240
+ let sourceNoun = this.index.getNouns().get(sourceId);
10241
+ let targetNoun = this.index.getNouns().get(targetId);
10242
+ // Auto-create missing nouns if option is enabled
10243
+ if (!sourceNoun && options.autoCreateMissingNouns) {
10244
+ try {
10245
+ // Create a placeholder vector for the missing noun
10246
+ const placeholderVector = new Array(this._dimensions).fill(0);
10247
+ // Add metadata if provided
10248
+ const metadata = options.missingNounMetadata || {
10249
+ autoCreated: true,
10250
+ createdAt: new Date().toISOString(),
10251
+ noun: NounType.Concept
10252
+ };
10253
+ // Add the missing noun
10254
+ await this.add(placeholderVector, metadata, { id: sourceId });
10255
+ // Get the newly created noun
10256
+ sourceNoun = this.index.getNouns().get(sourceId);
10257
+ console.warn(`Auto-created missing source noun with ID ${sourceId}`);
10258
+ }
10259
+ catch (createError) {
10260
+ console.error(`Failed to auto-create source noun with ID ${sourceId}:`, createError);
10261
+ throw new Error(`Failed to auto-create source noun with ID ${sourceId}: ${createError}`);
10262
+ }
10263
+ }
10264
+ if (!targetNoun && options.autoCreateMissingNouns) {
10265
+ try {
10266
+ // Create a placeholder vector for the missing noun
10267
+ const placeholderVector = new Array(this._dimensions).fill(0);
10268
+ // Add metadata if provided
10269
+ const metadata = options.missingNounMetadata || {
10270
+ autoCreated: true,
10271
+ createdAt: new Date().toISOString(),
10272
+ noun: NounType.Concept
10273
+ };
10274
+ // Add the missing noun
10275
+ await this.add(placeholderVector, metadata, { id: targetId });
10276
+ // Get the newly created noun
10277
+ targetNoun = this.index.getNouns().get(targetId);
10278
+ console.warn(`Auto-created missing target noun with ID ${targetId}`);
10279
+ }
10280
+ catch (createError) {
10281
+ console.error(`Failed to auto-create target noun with ID ${targetId}:`, createError);
10282
+ throw new Error(`Failed to auto-create target noun with ID ${targetId}: ${createError}`);
10283
+ }
10284
+ }
10195
10285
  if (!sourceNoun) {
10196
10286
  throw new Error(`Source noun with ID ${sourceId} not found`);
10197
10287
  }
@@ -10396,6 +10486,56 @@ class BrainyData {
10396
10486
  size() {
10397
10487
  return this.index.size();
10398
10488
  }
10489
+ /**
10490
+ * Get statistics about the current state of the database
10491
+ * @returns Object containing counts of nouns, verbs, metadata entries, and HNSW index size
10492
+ */
10493
+ async getStatistics() {
10494
+ await this.ensureInitialized();
10495
+ try {
10496
+ // Get all verbs from storage
10497
+ const allVerbs = await this.storage.getAllVerbs();
10498
+ const verbCount = allVerbs.length;
10499
+ // Create a set of verb IDs for faster lookup
10500
+ const verbIds = new Set(allVerbs.map(verb => verb.id));
10501
+ // Get all nouns from the index
10502
+ const nouns = this.index.getNouns();
10503
+ // Count nouns that are not verbs
10504
+ let nounCount = 0;
10505
+ for (const [id] of nouns.entries()) {
10506
+ if (!verbIds.has(id)) {
10507
+ nounCount++;
10508
+ }
10509
+ }
10510
+ // Count metadata entries by checking each noun for metadata
10511
+ let metadataCount = 0;
10512
+ for (const [id] of nouns.entries()) {
10513
+ try {
10514
+ const metadata = await this.storage.getMetadata(id);
10515
+ if (metadata !== null && metadata !== undefined) {
10516
+ metadataCount++;
10517
+ }
10518
+ }
10519
+ catch (error) {
10520
+ // Ignore errors when checking individual metadata entries
10521
+ // This could happen if metadata is corrupted or missing
10522
+ }
10523
+ }
10524
+ // Get HNSW index size (excluding verbs)
10525
+ // The test expects this to be the same as the noun count
10526
+ const hnswIndexSize = nounCount;
10527
+ return {
10528
+ nounCount,
10529
+ verbCount,
10530
+ metadataCount,
10531
+ hnswIndexSize
10532
+ };
10533
+ }
10534
+ catch (error) {
10535
+ console.error('Failed to get statistics:', error);
10536
+ throw new Error(`Failed to get statistics: ${error}`);
10537
+ }
10538
+ }
10399
10539
  /**
10400
10540
  * Check if the database is in read-only mode
10401
10541
  * @returns True if the database is in read-only mode, false otherwise
@@ -87321,5 +87461,5 @@ var universalSentenceEncoder_esm = /*#__PURE__*/Object.freeze({
87321
87461
  version: version
87322
87462
  });
87323
87463
 
87324
- export { AugmentationType, BrainyData, BrainyMCPAdapter, BrainyMCPService, ExecutionMode$1 as ExecutionMode, FileSystemStorage, FileSystemStorageAugmentation, HNSWIndex, HNSWIndexOptimized, MCPAugmentationToolset, MCPRequestType, MCP_VERSION, MemoryStorage, MemoryStorageAugmentation, NounType, OPFSStorage, OPFSStorageAugmentation, Pipeline, S3CompatibleStorage as R2Storage, S3CompatibleStorage, SequentialPipeline, ServerSearchActivationAugmentation, ServerSearchConduitAugmentation, StreamlinedExecutionMode, UniversalSentenceEncoder$1 as UniversalSentenceEncoder, VerbType, WebRTCConduitAugmentation, WebSocketConduitAugmentation, addWebSocketSupport, applyTensorFlowPatch, areWebWorkersAvailable, areWorkerThreadsAvailable, areWorkerThreadsAvailableSync, augmentationPipeline$1 as augmentationPipeline, availableAugmentations, cleanupWorkerPools, cosineDistance$1 as cosineDistance, createAugmentationRegistryPlugin, createAugmentationRegistryRollupPlugin, createConduitAugmentation, createEmbeddingFunction, createMemoryAugmentation, createPipeline, createSenseAugmentation, createServerSearchAugmentations, createStorage, createStreamingPipeline, createTensorFlowEmbeddingFunction, createThreadedEmbeddingFunction, defaultEmbeddingFunction, dotProductDistance, environment, euclideanDistance, executeAugmentation, executeByType, executeInThread, executeSingle, executeStreamlined, getAugmentationsByType, initializeAugmentationPipeline, isBrowser$1 as isBrowser, isNode, isThreadingAvailable, isThreadingAvailableAsync, isWebWorker, loadAugmentationModule, loadAugmentationsFromModules, manhattanDistance, pipeline, processStaticData, processStreamingData, registerAugmentation, sequentialPipeline, setAugmentationEnabled };
87464
+ export { AugmentationType, BrainyData, BrainyMCPAdapter, BrainyMCPService, ExecutionMode$1 as ExecutionMode, FileSystemStorage, FileSystemStorageAugmentation, HNSWIndex, HNSWIndexOptimized, MCPAugmentationToolset, MCPRequestType, MCP_VERSION, MemoryStorage, MemoryStorageAugmentation, NounType, OPFSStorage, OPFSStorageAugmentation, Pipeline, S3CompatibleStorage as R2Storage, S3CompatibleStorage, SequentialPipeline, ServerSearchActivationAugmentation, ServerSearchConduitAugmentation, StreamlinedExecutionMode, UniversalSentenceEncoder$1 as UniversalSentenceEncoder, VerbType, WebRTCConduitAugmentation, WebSocketConduitAugmentation, addWebSocketSupport, applyTensorFlowPatch, areWebWorkersAvailable, areWorkerThreadsAvailable, areWorkerThreadsAvailableSync, augmentationPipeline$1 as augmentationPipeline, availableAugmentations, cleanupWorkerPools, cosineDistance$1 as cosineDistance, createAugmentationRegistryPlugin, createAugmentationRegistryRollupPlugin, createConduitAugmentation, createEmbeddingFunction, createMemoryAugmentation, createPipeline, createSenseAugmentation, createServerSearchAugmentations, createStorage, createStreamingPipeline, createTensorFlowEmbeddingFunction, createThreadedEmbeddingFunction, defaultEmbeddingFunction, dotProductDistance, environment, euclideanDistance, executeAugmentation, executeByType, executeInThread, executeSingle, executeStreamlined, getAugmentationsByType, getStatistics, initializeAugmentationPipeline, isBrowser$1 as isBrowser, isNode, isThreadingAvailable, isThreadingAvailableAsync, isWebWorker, loadAugmentationModule, loadAugmentationsFromModules, manhattanDistance, pipeline, processStaticData, processStreamingData, registerAugmentation, sequentialPipeline, setAugmentationEnabled };
87325
87465
  //# sourceMappingURL=brainy.js.map