@soulcraft/brainy 0.16.0 → 0.18.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.
@@ -299,6 +299,22 @@ export declare class BrainyData<T = any> implements BrainyDataInterface<T> {
299
299
  /**
300
300
  * Add a verb between two nouns
301
301
  * If metadata is provided and vector is not, the metadata will be vectorized using the embedding function
302
+ *
303
+ * @param sourceId ID of the source noun
304
+ * @param targetId ID of the target noun
305
+ * @param vector Optional vector for the verb
306
+ * @param options Additional options:
307
+ * - type: Type of the verb
308
+ * - weight: Weight of the verb
309
+ * - metadata: Metadata for the verb
310
+ * - forceEmbed: Force using the embedding function for metadata even if vector is provided
311
+ * - id: Optional ID to use instead of generating a new one
312
+ * - autoCreateMissingNouns: Automatically create missing nouns if they don't exist
313
+ * - missingNounMetadata: Metadata to use when auto-creating missing nouns
314
+ *
315
+ * @returns The ID of the added verb
316
+ *
317
+ * @throws Error if source or target nouns don't exist and autoCreateMissingNouns is false or auto-creation fails
302
318
  */
303
319
  addVerb(sourceId: string, targetId: string, vector?: Vector, options?: {
304
320
  type?: string;
@@ -306,6 +322,8 @@ export declare class BrainyData<T = any> implements BrainyDataInterface<T> {
306
322
  metadata?: any;
307
323
  forceEmbed?: boolean;
308
324
  id?: string;
325
+ autoCreateMissingNouns?: boolean;
326
+ missingNounMetadata?: any;
309
327
  }): Promise<string>;
310
328
  /**
311
329
  * Get a verb by ID
@@ -339,6 +357,16 @@ export declare class BrainyData<T = any> implements BrainyDataInterface<T> {
339
357
  * Get the number of vectors in the database
340
358
  */
341
359
  size(): number;
360
+ /**
361
+ * Get statistics about the current state of the database
362
+ * @returns Object containing counts of nouns, verbs, metadata entries, and HNSW index size
363
+ */
364
+ getStatistics(): Promise<{
365
+ nounCount: number;
366
+ verbCount: number;
367
+ metadataCount: number;
368
+ hnswIndexSize: number;
369
+ }>;
342
370
  /**
343
371
  * Check if the database is in read-only mode
344
372
  * @returns True if the database is in read-only mode, false otherwise
package/dist/unified.js CHANGED
@@ -10179,6 +10179,22 @@ class BrainyData {
10179
10179
  /**
10180
10180
  * Add a verb between two nouns
10181
10181
  * If metadata is provided and vector is not, the metadata will be vectorized using the embedding function
10182
+ *
10183
+ * @param sourceId ID of the source noun
10184
+ * @param targetId ID of the target noun
10185
+ * @param vector Optional vector for the verb
10186
+ * @param options Additional options:
10187
+ * - type: Type of the verb
10188
+ * - weight: Weight of the verb
10189
+ * - metadata: Metadata for the verb
10190
+ * - forceEmbed: Force using the embedding function for metadata even if vector is provided
10191
+ * - id: Optional ID to use instead of generating a new one
10192
+ * - autoCreateMissingNouns: Automatically create missing nouns if they don't exist
10193
+ * - missingNounMetadata: Metadata to use when auto-creating missing nouns
10194
+ *
10195
+ * @returns The ID of the added verb
10196
+ *
10197
+ * @throws Error if source or target nouns don't exist and autoCreateMissingNouns is false or auto-creation fails
10182
10198
  */
10183
10199
  async addVerb(sourceId, targetId, vector, options = {}) {
10184
10200
  await this.ensureInitialized();
@@ -10186,8 +10202,51 @@ class BrainyData {
10186
10202
  this.checkReadOnly();
10187
10203
  try {
10188
10204
  // Check if source and target nouns exist
10189
- const sourceNoun = this.index.getNouns().get(sourceId);
10190
- const targetNoun = this.index.getNouns().get(targetId);
10205
+ let sourceNoun = this.index.getNouns().get(sourceId);
10206
+ let targetNoun = this.index.getNouns().get(targetId);
10207
+ // Auto-create missing nouns if option is enabled
10208
+ if (!sourceNoun && options.autoCreateMissingNouns) {
10209
+ try {
10210
+ // Create a placeholder vector for the missing noun
10211
+ const placeholderVector = new Array(this._dimensions).fill(0);
10212
+ // Add metadata if provided
10213
+ const metadata = options.missingNounMetadata || {
10214
+ autoCreated: true,
10215
+ createdAt: new Date().toISOString(),
10216
+ noun: NounType.Concept
10217
+ };
10218
+ // Add the missing noun
10219
+ await this.add(placeholderVector, metadata, { id: sourceId });
10220
+ // Get the newly created noun
10221
+ sourceNoun = this.index.getNouns().get(sourceId);
10222
+ console.warn(`Auto-created missing source noun with ID ${sourceId}`);
10223
+ }
10224
+ catch (createError) {
10225
+ console.error(`Failed to auto-create source noun with ID ${sourceId}:`, createError);
10226
+ throw new Error(`Failed to auto-create source noun with ID ${sourceId}: ${createError}`);
10227
+ }
10228
+ }
10229
+ if (!targetNoun && options.autoCreateMissingNouns) {
10230
+ try {
10231
+ // Create a placeholder vector for the missing noun
10232
+ const placeholderVector = new Array(this._dimensions).fill(0);
10233
+ // Add metadata if provided
10234
+ const metadata = options.missingNounMetadata || {
10235
+ autoCreated: true,
10236
+ createdAt: new Date().toISOString(),
10237
+ noun: NounType.Concept
10238
+ };
10239
+ // Add the missing noun
10240
+ await this.add(placeholderVector, metadata, { id: targetId });
10241
+ // Get the newly created noun
10242
+ targetNoun = this.index.getNouns().get(targetId);
10243
+ console.warn(`Auto-created missing target noun with ID ${targetId}`);
10244
+ }
10245
+ catch (createError) {
10246
+ console.error(`Failed to auto-create target noun with ID ${targetId}:`, createError);
10247
+ throw new Error(`Failed to auto-create target noun with ID ${targetId}: ${createError}`);
10248
+ }
10249
+ }
10191
10250
  if (!sourceNoun) {
10192
10251
  throw new Error(`Source noun with ID ${sourceId} not found`);
10193
10252
  }
@@ -10392,6 +10451,47 @@ class BrainyData {
10392
10451
  size() {
10393
10452
  return this.index.size();
10394
10453
  }
10454
+ /**
10455
+ * Get statistics about the current state of the database
10456
+ * @returns Object containing counts of nouns, verbs, metadata entries, and HNSW index size
10457
+ */
10458
+ async getStatistics() {
10459
+ await this.ensureInitialized();
10460
+ try {
10461
+ // Get noun count from the index
10462
+ const nounCount = this.index.getNouns().size;
10463
+ // Get verb count from storage
10464
+ const allVerbs = await this.storage.getAllVerbs();
10465
+ const verbCount = allVerbs.length;
10466
+ // Count metadata entries by checking each noun for metadata
10467
+ let metadataCount = 0;
10468
+ const nouns = this.index.getNouns();
10469
+ for (const [id] of nouns.entries()) {
10470
+ try {
10471
+ const metadata = await this.storage.getMetadata(id);
10472
+ if (metadata !== null && metadata !== undefined) {
10473
+ metadataCount++;
10474
+ }
10475
+ }
10476
+ catch (error) {
10477
+ // Ignore errors when checking individual metadata entries
10478
+ // This could happen if metadata is corrupted or missing
10479
+ }
10480
+ }
10481
+ // Get HNSW index size
10482
+ const hnswIndexSize = this.index.size();
10483
+ return {
10484
+ nounCount,
10485
+ verbCount,
10486
+ metadataCount,
10487
+ hnswIndexSize
10488
+ };
10489
+ }
10490
+ catch (error) {
10491
+ console.error('Failed to get statistics:', error);
10492
+ throw new Error(`Failed to get statistics: ${error}`);
10493
+ }
10494
+ }
10395
10495
  /**
10396
10496
  * Check if the database is in read-only mode
10397
10497
  * @returns True if the database is in read-only mode, false otherwise